FFMpeg之 Mpeg2TS解析



TS流是由一個又一個的188(或204)字節的ts小包組成:4字節的頭和184字節的數據.
4B的頭:

typedef struct
{
  unsigned sync_byte:8;/*8 bits的同步字節,0x47,傳送包標識符*/
  unsigned transport_error_indicator:1;/*1 bit的錯誤指示信息,1表示當前Packet至少有1bit的傳輸錯誤,0表示所有數據都正確*/
  unsigned payload_unit_start_indicator:1;/*負載單元開始標誌,請參考ISO13818-1瞭解該標誌作用,置0,表示ts包不是pes,置1,有效淨荷以pes包的第一個字節開始*/
  unsigned transport_priority:1;/*1 bit的傳輸優先級標誌,1表示高優先級,0表示低優先級*/
  unsigned PID:13;/*13 bits的Packet ID號碼,唯一的號碼對應不同的包,都是什麼類型下面會列出*/
  unsigned transport_scrambling_control:2;/*2 bits的加密標誌,00表示沒有加密,其他表示已被加密*/
  unsigned adaptation_field_control:2;/* 2 bits的附加區域控制,請參考ISO13818-1瞭解該標誌作用*/
  unsigned continuity_counter:4;/*4 bits的包遞增計數器*/
}PACKET_HEADER;

在數據區域就可以存放psi或音視頻數據.

PSI(program specific information)
SI(service information)
實現解複用需要PAT PMT SDT
CA需要CAT
EPG需要NIT EIT TDT TOT

PAT(Program Association Table)節目關聯表

在pat中可以看到這裏只有一個節目,而在pmt中可以看到這個節目更爲詳細的信息

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的分析)

PMT(Program Map Table)節目映射表

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校驗值,一般忽略.

SDT(Service description section)服務描述段

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讓用戶選擇,從而實現比較友好的用戶界面!

  
機頂盒先調整高頻頭到一個固定的頻率(如498MHZ),如果此頻率有數字信號,則COFDM芯片(如MT352)會自動把TS流數據傳送給MPEG- 2 decoder.MPEG-2 decoder先進行數據的同步,也就是等待完整的Packet的到來.然後循環查找是否出現PID== 0x0000的Packet,如果出現了,則馬上進入分析PAT的處理,獲取了所有的PMT的PID.接着循環查找是否出現PMT,如果發現了,則自動進 入PMT分析,獲取該頻段所有的頻道數據並保存.只要我們處理了PMT,那麼我們就可以獲取頻道中所有的PID信息,例如當前頻道包含多少個Video,共多少個Audio,和其他數據,還能知道每種數據對應的PID分別是什麼.這樣如果我們要選擇其中一個Video和Audio收看,那麼只需要把要收看的節目的Video
PID和Audio PID保存起來,在處理Packet的時候進行過濾即可實現.
如果沒有發現PAT或者沒有發現PMT,說明該頻段沒有信號,進入下一個頻率掃描.
從以上描述可以看出,機頂盒搜索頻率是隨機發生的,要使每次機頂盒都能搜索到信號,則要求TS流每隔一段時間就發送一次PAT和PMT.事實上DVB傳輸系統就是這麼做的.因此無論何時接入終端系統,系統都能馬上搜索到節目並正確解複用實現播放.不僅僅如此,其他數據也都是交替傳送的.比如第一個Packet可能是PAT,第二個Packet可能是PMT,而第三個Packet可能是Video 1,第四個Packet可能是Video 2,
只要系統傳輸速度足夠快(就是稱之爲"碼率"的東東),實現實時播放是沒有任何問題的.
到這裏雖然實現瞭解複用,但可以看出,使用的PID都是枯燥的數字,如果調臺要用戶自己輸入數字那可是太麻煩了,而且還容易輸入錯誤,操作非常不直觀,即使做成一個菜單讓用戶選擇也是非常的呆板.針對這個問題,DVB系統提出了一個SDT表格,該表格標誌一個節目的名稱,並且能和PMT中的PID聯繫起來,這樣用戶就可以通過直接選擇節目名稱來選擇節目了.


轉載:http://www.xuebuyuan.com/1489591.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章