日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

PAT、PMT、SDT详解

發布時間:2023/12/29 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 PAT、PMT、SDT详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

下面針對解復用程序詳細分析一下PAT,PMT和SDT三類表格的格式.

如下圖,四個頻道復用

PAT---Program Association Table,節目關聯表。PAT表攜帶以下信息:
(1)TS流ID--- transport_stream_id,該ID標志唯一的流ID
(2)節目頻道號-- program_number,該號碼標志TS流中的一個頻道,該頻道可以包含很多的節目(即可以包含多個Video PID和Audio PID)
(3)PMT的PID--- program_map_PID,表示本頻道使用的哪個PID做為PMT的PID,因為可以有很多的頻道,因此DVB規定PMT的PID可以由用戶自己定義.

PAT表定義如下:各字段含義如下:

table_id:8 bits,標志本表格的類型,應該是0x00

section_syntax_indicator:1 bit,段語法標志,應該是''1'' ''0'':固定的''0'',這是為了防止和ISO13818Video流格式中的控制字沖突而設置的.

Reserved:保留的2bits,保留位一般都是''0''

section_length:12bits的段大小,單位是Bytes.

transport_stream_id:16bits的當前流ID,DVB內唯一.(事實上很多都是自定義的TS ID)version_number:5bits版本號碼,標注當前節目的版本.這是個非常有用的參數,當檢測到這個字段改變時,說明TS流中的節目已經變化了,程序必須重新搜索節目.

current_next_indicator:1bit:當前還是未來使用標志符,一般情況下為''0''

section_number:8bits當前段號碼

last_section_number:8bits最后段號碼(section_number和last_section_number的功能是當PAT內容>184字節時,PAT表會分成多個段(sections),解復用程序必須在全部接收完成后再進行PAT的分析)

從for()開始,就是描述了當前流中的頻道數目(N),每一個頻道對應的PMT PID是什么.解復用程序需要和上圖類似的循環來接收所有的頻道號碼和對應的PMT PID,并把這些信息在緩沖區中保存起來.在后部的處理中需要使用到PMT PID.

CRC_32:本段的CRC校驗值,一般是會忽略的.N是一個變量,計算方法是N=(section_length-9)/4.

從以上分析我們可以發現,PAT表主要包含頻道號碼和每一個頻道對應的PMT的PID號碼,這些信息我們在處理PAT表格的時候會保存起來,以后會使用到這些數據.例如我們可以定義這樣的數據結構保存這些信息:

typedef struct

{

int channel_number;

int pmt_pid;

}PMT_ITEM;

PMT_ITEM pmt[64];

PMT, Program Map Table,節目影射表如果一個TS流中含有多個頻道,
那么就會包含多個PID不同的PMT表.檢測是否PMT的偽代碼如下:
void Process_Packet(unsigned char*buff)
{ int I;

int PID=GETPID(buff);

if(PID==0x0000)

{

Process_PAT(buff+4);

}

else if(PID==.....)
{ }

else

{ for(i=0;i<64;i++)
{ if(PID==pmt[i].pmt_pid)

{ Process_PMT(buff+4); break; }
} } }
PMT表中包含的數據如下:

(1)當前頻道中包含的所有Video數據的PID

(2)當前頻道中包含的所有Audio數據的PID

(3)和當前頻道關聯在一起的其他數據的PID(如數字廣播,數據通訊等使用的PID)

PMT定義如下:各字段含義如下:

table_id:8bits的ID,應該是0x02

section_syntax_indicator:1bit的段語法標志,應該是''1'' ''0'':固定是''0'',如果不是說明數據有錯.

reserved:2bits保留位,應該是''00''

section_length:16bits段長度,從program_number開始,到CRC_32(包含)的字節總數.program_number:16bits的頻道號碼,表示當前的PMT關聯到的頻道.換句話就是說,當前描述的是program_number頻道的信息.

reserved:2bits保留位,應該是''00''

version_number:版本號碼,如果PMT內容有更新,則version_number會遞增1通知解復用程序需要重新接收節目信息,否則version_number是固定不變的.

current_next_indicator:當前未來標志符,一般是0

section_number:當前段號碼

last_section_number:最后段號碼,含義和PAT中的對應字段相同,請參考PAT部分.reserved:3bits保留位,一般是''000''.

PCR_PID:13bits的PCR PID,具體請參考ISO13818-1,解復用程序不使用該參數.

reserved:4bits保留位,一般是''0000''

program_info_length:節目信息長度(之后的是N個描述符結構,一般可以忽略掉,這個字段就代表描述符總的長度,單位是Bytes)緊接著就是頻道內部包含的節目類型和對應的PID號碼了.

stream_type:8bits流類型,標志是Video還是Audio還是其他數據.

reserved:3 bits保留位.

elementary_PID:13bits對應的數據PID號碼(如果stream_type是Video,那么這個PID就是Video PID,如果stream_type標志是Audio,那么這個PID就是Audio PID)

reserved:4 bits保留位.

ES_info_length:和program_info_length類似的信息長度(其后是N2個描述符號)CRC_32:32bits段末尾是本段的CRC校驗值,一般忽略.

從以上的分析可以看出,只要我們處理了PMT,那么我們就可以獲取頻道中所有的PID信息,例如當前頻道包含多少個Video,共多少個Audio,和其他數據,還能知道每種數據對應的PID分別是什么.這樣如果我們要選擇其中一個Video和Audio收看,那么只需要把要收看的節目的Video PID和Audio PID保存起來,在處理Packet的時候進行過濾即可實現.比較全面實現解復用的偽代碼如下:

int Video_PID=0x07e5,Audio_PID=0x07e6;

void Process_Packet(unsigned char*buff)

{ int I; int PID=GETPID(buff);

if(PID==0x0000) { Process_PAT(buff+4); }

else if(PID==Video_PID) { SaveToVideoBuffer(buff+4); }

else if(PID==Audio_PID) { SaveToAudioBuffer(buff+4); }

else

{ for( i=0;i<64;i++)

{ if(PID==pmt[i].pmt_pid) { Process_PMT(buff+4); Break; }

} } }

以上偽代碼可以實現基本的解復用:檢測所有的頻道,檢測所有stream的PID,選擇特定的節目進行播放.只要讀取每個Packet的188字節的內容,然后每次都調用Process_Packet()即可實現簡單的解復用.介紹到這里,我們就可以總結一下DVB搜臺的原理了.(好!洗耳恭聽!)機頂盒先調整高頻頭到一個固定的頻率(如498MHZ),如果此頻率有數字信號,則COFDM芯片(如MT352)會自動把TS流數據傳送給MPEG- 2 decoder. MPEG-2 decoder先進行數據的同步,也就是等待完整的Packet的到來.然后循環查找是否出現PID== 0x0000的Packet,如果出現了,則馬上進入分析PAT的處理,獲取了所有的PMT的PID.接著循環查找是否出現PMT,如果發現了,則自動進入PMT分析,獲取該頻段所有的頻道數據并保存.如果沒有發現PAT或者沒有發現PMT,說明該頻段沒有信號,進入下一個頻率掃描.從以上描述可以看出,機頂盒搜索頻率是隨機發生的,要使每次機頂盒都能搜索到信號,則要求TS流每隔一段時間就發送一次PAT和PMT.事實上DVB傳輸系統就是這么做的.因此無論何時接入終端系統,系統都能馬上搜索到節目并正確解復用實現播放.不僅僅如此,其他數據也都是交替傳送的.比如第一個Packet可能是PAT,第二個Packet可能是PMT,而第三個Packet可能是Video 1,第四個Packet可能是Video 2,只要系統傳輸速度足夠快(就是稱之為"碼率"的東東),實現實時播放是沒有任何問題的.到這里雖然實現了解復用,但可以看出,使用的PID都是枯燥的數字,如果調臺要用戶自己輸入數字那可是太麻煩了,而且還容易輸入錯誤,操作非常不直觀,即使做成一個菜單讓用戶選擇也是非常的呆板.針對這個問題,DVB系統提出了一個SDT表格,該表格標志一個節目的名稱,并且能和PMT中的PID聯系起來,這樣用戶就可以通過直接選擇節目名稱來選擇節目了.

SDT, Service description section,服務描述段

SDT可以提供的信息包括:

(1)該節目是否在播放中

(2)該節目是否被加密

(3)該節目的名稱

SDT定義如下:各字段定義如下:

table_id:8bits的ID,可以是0x42,表示描述的是當前流的信息,也可以是0x46,表示是其他流的信息(EPG使用此參數)

section_syntax_indicator:段語法標志,一般是''1''

reserved_future_used:2bits保留未來使用

reserved:1bit保留位,防止控制字沖突,一般是''0'',也有可能是''1''

section_length:12bits的段長度,單位是Bytes,從transport_stream_id開始,到CRC_32結束(包含)

transport_stream_id:16bits當前描述的流ID

reserved:2bits保留位

version_number:5bits的版本號碼,如果數據更新則此字段遞增1

current_next_indicator:當前未來標志,一般是''0'',表示當前馬上使用.original_netword_id:16bits的原始網絡ID號

reserved_future_use:8bits保留未來使用位接下來是N個節目信息的循環:

service_id:16 bits的服務器ID,實際上就是PMT段中的program_number.reserved_future_used:6bits保留未來使用位

EIT_schedule_flag:1bit的EIT信息,1表示當前流實現了該節目的EIT傳送EIT_present_following_flag:1bits的EIT信息,1表示當前流實現了該節目的EIT傳送running_status:3bits的運行狀態信息:1-還未播放2-幾分鐘后馬上開始,3-被暫停播出,4-正在播放,其他---保留

free_CA_mode:1bits的加密信息,''1''表示該節目被加密.緊接著的是描述符,一般是Service descriptor,分析此描述符可以獲取servive_id指定的節目的節目名稱.具體格式請參考EN300468中的Service descriptor部分.

分析完畢,則節目名稱和節目號碼已經聯系起來了.機頂盒程序就可以用這些節目名稱代替PID讓用戶選擇,從而實現比較友好的用戶界面!下面參考一下<>中的界面和顯示信息.上圖是<>打開三個不同的碼流文件(*.ts)形成的PID信息和節目名稱.用戶可以通過切換節目名稱的下拉列表框切換節目,也可以通過"視頻流"和"音頻流"下拉列表框切換Video和Audio!這些數據都是通過分析PAT, PMT和SDT得到的.

轉載自http://blog.chinaunix.net/uid-24322243-id-2620180.html

總結

以上是生活随笔為你收集整理的PAT、PMT、SDT详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。