MPEG2-TS標準分析

基本概念

ES流(Elementary Stream):基本碼流,經過編碼後的連續碼流。

PES流(Pakckaged Elementary Stream):將ES流分割成段,加上相應的頭文件打包後的碼流。PES包的長度可變,包頭中最重要的是PTS(Presentation Time Stamp)、和DTS(Decode Time Stamp)時間,再加上參考PCR參考時鐘,播放器便能從PES流中重建音視頻。

TS流(Transport Stream):固定包長度爲188B,將一個或多個PES包組合到一起用於傳輸的單一碼流。

TS分析工具

TSR:不僅可以查看16進制數據信息,且將所有關鍵表都自動解析出來,如PAT、PMT等。

TS簡介

TS的名稱實際上是MPEG2-TS,在iso13818-1文檔中定義,TS是Transport Stream的縮寫,意爲傳輸流,用於傳輸混合後的多媒體數據流。在MPEG2標準中,有兩種不同類型個碼流標準,一是節目碼流(PS即 Program Stream),另外一個就是TS流。在MPEG2標準中,給出兩種不同類型碼流的形成過程。
在這裏插入圖片描述

  1. Video或者Audio原始數據,通過音視頻編碼器編碼後形成ES流。
  2. 通過打包器(Packatizer)添加上PTS、DTS等信息後,打包成PES包。
  3. 分別打包好後的音頻PES包和視頻PES包經過PS/TS複用處理後,分別形成PS流TS流

TS流包含的內容

我們之所以要解析TS流,目的就是從流中獲取我們需要的編碼數據、時鐘等信息從而在接收設備中重建音視頻。而所謂的TS流,實際上就是基於Packet形成的Byte位流,由一個個包形成。

要完成音視頻的重建,首先需要獲取TS流中的Packet,TS的Packet一般固定長度爲188字節(也有204字節的版本,該版本在188字節後加上17字節的CRC校驗數據)。其中包頭4字節,負載184字節。下圖表示一個TS流和包結構信息圖。
在這裏插入圖片描述
一段PS流,必然包含PAT包、PTM包、多個音頻…

PS流和TS流的主要區別

TS流的包結構長度固定爲188字節,而PS流的包長度可變。

TS和PS的包結構差異,使對誤碼的抵抗程度不同,因此適用於不同的環境。TS碼流因爲採用了固定長度的包結構,傳輸誤碼時,接收設備依然可以從固定的位置檢測同步信息,恢復同步。

而PS流如果誤碼,接收設備將無法的值下一個包的同步位置,無法同步甚至無法解碼。

因爲MPEG2-TS流的任何一個片段都可以獨立解碼,因此在傳輸信道不穩定時,傳輸MPEG-2碼流基本都採用TS流,如電視節目。而PS流因爲長度可變,節約空間,通常用在沒有誤碼場景的DVD播放上。

以下是TS流的語法定義:

MPEG_transport_stream() {
	do {
        transport_packet()
    } while (nextbits() == sync_byte)
}

TS頭解析

TS的包頭中,包含關於傳輸相關信息。雖然TS包長度固定,但包頭長度並不固定,除去前4個字節的包頭信息外,可能還會跟有自適應空間,最後纔是包數據。下面看一下在MPEG-2中的定義:

transport_packet(){
    sync_byte                    // 8 bit
    transport_error_indicator    // 1 bit
    payload_unit_start_indicator // 1 bit
    transport_priority           // 1 bit                 包頭部分
    PID                          // 13 bit
    transport_scrambling_control // 2 bit
    adaptation_field_control     // 2 bit
    continuity_counter           // 4 bit
    ===========================================================================
    if(adaptation_field_control == '10' || adaptation_field_control == '11'){
    	adaptation_field()
    }
    if(adaptation_field_control == '01' || adaptation_field_control == '11') {
        for (i = 0; i < N; i++){
        	data_byte            // 8 bit
        }
    }
}

上述註釋部分表示了對應字段做佔據的大小。其中if條件語句之前32bit是TS Packet的包頭部分,包頭各字段含義如下:

  • 同步字節(sync_byte):固定的8bit字段,其值爲“0100 0111”(0x47)。 應避免在爲其他常規字段(例如PID)選擇值時使用sync_byte的固定, 該字段是MPEG-2 TS傳送包標識符。

  • 傳輸誤差指示符(transport_error_indicator):長度爲1bit, 設置爲“1”時,表示相關傳輸流數據包中至少存在1個不可糾正的位錯誤。 該位可以由傳輸層外部的實體設置爲“1”。 設置爲“1”時,除非糾正了錯誤的位值,否則該位不應復位爲“0”。

  • 有效載荷單元起始符(payload_unit_start_indicator):長度爲1bit,對於攜帶PES包或PSI數據的傳輸流包具有規範含義。

    當TS包的有效載荷包含PES數據時,payload_unit_start_indicator具有以下含義:“1”表示該TS包的有效載荷從PES的第一個字節開始,“0”則表示PES包的起始地址並非有效載荷的開始。 如果payload_unit_start_indicator被設置爲’1’,則在該TS包中有且僅有一個PES包。

    當TS包的有效載荷包含PSI數據時,payload_unit_start_indicator具有以下含義:如果TS包攜帶PSI部分的第一個字節,則payload_unit_start_indicator值應爲’1’,表示TS包有效載荷的第一個字節包含pointer_field。 如果TS包不攜帶PSI部分的第一個字節,則payload_unit_start_indicator值應爲’0’,表示有效載荷中沒有pointer_field。

    對於空包,payload_unit_start_indicator應設置爲’0’。這意味着,該TS包只包含了MPEG2-TS規範未定義的用戶自定義數據。

  • 傳輸優先級(transport_priority):長度爲1bit。 當設置爲“1”時,它表示相關包(Packet)的優先級高於具有相同PID但沒有將該位設置爲“1”的其他包。 傳輸優先級機制可以再基本流中對數據進行優先級排序。

  • PID:長度爲13bit,指示存儲在Packet有效載荷中的數據的類型。 PID值0x0000保留給程序關聯表、0x0001保留用於條件訪問表、0x0002 - 0x000F保留。 PID值0x1FFF保留用於空包。對應的PID表如下:

    Value Description
    0x0000 Program Association Table
    0x0001 Conditional Access Table
    0x0002 Transport Stream Description Table
    0x0003~0x000F Reserved
    0x0010~0x1FFE May be assigned as network_PID, Program_map_PID, elementary_PID, or for other purposes
    0x1FFF Null Packet
    注 - 允許PID值爲0x0000,0x0001和0x0010-0x1FFE的傳輸包攜帶PCR
  • 傳輸加擾控制(transport_scrambling_control):長度爲2bit,表示TS包有效載荷是否是加擾模式。 在加擾模式下,TS包頭和可能存在的適配字段不應被加擾。 在空包的情況下,transport_scrambling_control字段的值應設爲’00’。加擾表如下:

    Value Description
    00 Not scrambled
    01 User-defined
    10 User-defined
    11 User-defined
  • 自適應字段控制(adaptation_field_control):長度爲2bit,決定TS包頭,後面是跟適配字段還是負載數據。

    Value Description
    00 Reserved for future use by ISO/IEC
    01 No adaptation_field, payload only
    10 Adaptation_field only, no payload
    11 Adaptation_field followed by payload

    當adaptation_field_control字段值爲’00’是,解碼器應該丟棄該Packet。 空包時,該字段的值應設爲’01’。

  • 連續計數器(continuity_counter):長度爲4bit,連續計數器表示,有多少個TS包具有相同的PID。 當Packet的adaptation_field_control等於’00’或’10’時,continuity_counter不會遞增。空包時,continuity_counter是未定義的。

  • 數據字節(data_byte):載荷部分的有效字節數據,數據字節應是來自PES包、PSI部分的數據的連續字節,PSI部分之後的包填充字節,或者不在這些結構中的私有數據。 在具有PID值0x1FFF的空包的情況下,可以爲data_bytes分配任何值。 data_bytes的數量N由184減去adaptation_field()中的字節數來指定。

TS包調整字段(adaptation_field)

在TS包中,打包後的PES數據,通常並不能滿足188字節的長度,爲了補足188字節,以及在系統層插入插入參考時鐘(program clock reference, PCR),需要在TS包中插入長度可變的調整字段。

調整字段的作用之一是解決編解碼器的音視頻同步問題。一般在視頻幀TS包的調整字段中,每隔一段時間,傳送系統時鐘27MHz的一個抽樣值給接收機,作爲解碼器的時鐘參考即PCR。PCR通常每隔100ms至少被傳輸一次。PCR的數值所表示的是解碼器在讀完這個抽樣值的最後那個字節時,解碼器本地時鐘所應處的狀態。通常情況下,PCR不直接改變解碼器的本地時鐘,而是作爲參考基準來調整本地時鐘,使之與PCR趨於一致。

節目關聯表(Program Association Table,PAT)

下圖通過TSR分析真實TS文件的截圖:
在這裏插入圖片描述
16進制數據區中,我們可以看到,該TS包原始16進制數據爲:47 40 00 10 00 00 b0 0d 00 01 c1 00 00 00 01 ef ff 36 90 e2 3d ff ff ff ff ff ff ff ff ff ff ff …,先來分析包頭。

我們都知道,Packet Header佔每個Packet的頭四個字節,對應47 40 00 10,換成二進制表示:01000111 0100001 00000000 00010000。使用包頭格式解析如下表:

標識 位數 說明
sync_byte 8 bits 固定是0x47
transport_error_indicator 1 bits 值爲0,表示當前包沒有發生傳輸錯誤。
payload_unit_start_indicator 1 bits 值爲1,負載數據從包頭數據1字節後開始
transport_priority 1 bits 值爲0,表示當前包是低優先級。傳輸優先級標誌(1:優先級高)
PID 13 bits PID=0x0000,說明是PAT表。
transport_scrambling_control 2 bits 值爲0x00,表示節目沒有加密。
adaptation_field_control 2 bits 值爲0x01,改Packet區域含控制調整字段
continuity_counter 4 bits 值爲0x00,表示當前傳送的相同類型的包是第0個。

接下來是PAT表數據部分:

00 00 b0 0d 00 01 c1 00 00 00 01 ef ff 36 90 e2 3d ff ff ff ff ff ff ff ff ff ff ff …

因爲payload_unit_start_indicator值爲1字節開始,所以實際上PAT包所含數據爲:

00 b0 0d 00 01 c1 00 00 00 01 ef ff 36 90 e2 3d ff ff ff ff ff ff ff ff ff ff ff …

在這部分數據中,PAT表固定的前8個字節爲頭信息,其它數據組成固定長度的塊,通過循環讀取這些數據塊,可以獲得TS流中的節目和對應的PMT表的PID。

節目映射表(Program Map Table, PMT)

節目映射表,該表的PID是由PAT解析得出。通過該表可以得到一路節目中包含的信息,例如,該路節目由哪些流構成和這些流的類型(視頻,音頻,數據),指定節目中各流對應的PID,以及該節目的PCR所對應的PID。
PMT表中包含的數據如下:

  • 當前節目中所有Video ES流的PID
  • 當前節目所有Audio ES流的PID
  • 當前節目PCR的PID等。

結構如下:

TS_program_map_section() {
    table_id \\ 8 uimsbf
    section_syntax_indicator \\1 bslbf
    '0' \\1 bslbf
    reserved \\2 bslbf
    section_length \\12 uimsbf
    program_number \\16 uimsbf
    reserved \\2 bslbf
    version_number \\5 uimsbf
    current_next_indicator \\1 bslbf
    section_number \\8 uimsbf
    last_section_number \\8 uimsbf
    reserved \\3 bslbf
    PCR_PID \\13 uimsbf
    reserved \\4 bslbf
    program_info_length \\12 uimsbf
    for (i = 0; i < N; i++) {
    	descriptor()
    }
    for (i = 0; i < N1; i++) {
        stream_type \\8 uimsbf
        reserved \\3 bslbf
        elementary_PID \\13 uimsbf
        reserved \\4 bslbf
        ES_info_length \\12 uimsbf
        for (i = 0; i < N2; i++) {
        	descriptor()
        }
    }
    CRC_32 \\32 rpchof
}

解析完PMT後,表可以得到所有包含了編碼數據的音視頻原始數據和同步信息,接受者通過這些同步信息便可以重建視頻。

其它基本概念

scrambling (system): 加擾,以改變視頻,音頻或編碼數據流的特性,防止以明文形式傳輸,使未經授權者接收明文數據。

PCR (system): Program Clock Reference

PTS(system):presentation time-stamp 顯示時間戳,可能存在於PES包頭中的字段,用於指示在系統目標解碼器中顯示幀數據的時間。

DTS(system):decoding time-stamp 解碼時間戳,可能存在於PES包頭中的字段,用於指示在系統目標解碼器中解碼訪問幀數據的時間。

CRC:Cyclic Redundancy Check 循環冗餘檢查,以驗證數據的正確性。

PSI:Program Specific Information 程序特定信息,提供了單個TS流的信息,使接收方能夠對單個TS流中的不同節目進行解碼,這些信息都存在用表的形式提供給,如PAT、PMT、CAT等。但它無法提供多個TS流的相關業務,也不能提供節目的類型、節目名稱、開始時間、節目簡介等信息。

SI:Specific Information 特定信息,PSI中無法提供的相關信息,SI定義了NIT、SDT、EIT和TDT等9張表,方便用戶查看多種信息。

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