TSビデオカプセル化プロトコルの詳細な説明

TSカプセル化フォーマットの概要

TS (トランスポート ストリーム) は一般的なビデオ パッケージング形式で、主にデジタル TV やオンライン ビデオ伝送の分野で使用されます。利点と欠点は次のとおりです。
利点:
1. 強力な耐障害性: 送信中にパケット損失またはエラー情報損失が発生した場合、データの完全性を確保するために迅速に回復できます。
2. ランダムアクセスをサポート: TS 形式はデータをセグメント化し、各セグメントに独立してアクセスおよび制御できるため、ビデオへのランダムアクセスが実現します。
3.優れたリアルタイム性能:TSカプセル化形式はセグメント化された伝送方式を採用しており、各データセグメントのサイズが比較的小さいため、遅延を効果的に削減し、リアルタイムデータ伝送を実現できます。
4. 優れた信頼性: TS カプセル化フォーマットは多重化をサポートしており、複数のデータ ストリームを混合してデータ伝送効率と信頼性を向上させることができます。

短所:
1. 複雑なエンコードとデコード: TS カプセル化フォーマットはビデオ データをセグメント化して統合する必要があり、これには高度なオーディオおよびビデオ コーディング技術が必要です 2. より大きなファイル: 特定の
データ ヘッダー情報が導入される TS セグメンテーション メカニズム
3. サポートされていません字幕処理: TS カプセル化形式は字幕データ処理をサポートしていないため、ユーザーは手動で字幕を追加する必要があります

TSパケット

TSカプセル化フォーマットのデータ単位はtsパケットである。各パケットには独自の pid があり、パケット サイズは 188 バイトに固定されています。
ts パッケージは、pat パッケージ、pmt パッケージ、pes パッケージの 3 つのカテゴリに分類されます。

  • PAT (Program Associate Table) パッケージは最初のパッケージであり、ts のエントリであり、その pid は 0x00 に固定されています。pat パッケージには pmt パッケージの pid が含まれており、pmt パッケージは pat パッケージを通じて見つけることができます。
  • PMT (Program Map Table) は、オーディオ、ビデオ、データ情報などのストリームのコンテンツ情報を記述するために使用されます。pmt パケットにはデータ ストリーム パケットの PID が格納され、オーディオ パケットの PID は 0x102、ビデオ パケットの PID は 0x101 です。
  • PES(Packetized Elementary Stream)パケットは、音声や映像などのマルチメディアデータ情報を伝送するために使用される基本的なデータ単位です。

TS ストリームでは、PAT パケットと PMT パケットが繰り返し実装され、リアルタイムのデコードを保証するために 1 つのパケットが約 0.5 秒で現れます。PAT テーブルは TS ストリームの基礎であり、TS ストリームの解析や番組の検索はすべて PAT テーブルから始まります。

TSパケットの構造

ts パケットの固定サイズは 188 バイトで、対応する構造式は次のとおりです。
tsPacket = tsheader + アダプテーション フィールド + ペイロード;

tsheader: ts データ パケットのヘッダー、各データ パケットにそれがあり、ファイル ヘッダーは 4 バイトに固定されています。
アダプテーション フィールド: データ充填フィールド、一部のデータ パケットにはこのフィールドがありますが、一部のデータ パケットにはこのフィールドが存在しません (データとして使用されます) fill)
ペイロード: オーディオとビデオのデータ フィールド。pes データとオーディオとビデオの元のデータを格納するために使用されます。

さまざまなタイプのパケットの構造は次のとおりです。

TS流: 由一个个188字节的数据包组成                      
  +-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  TS   |  =  |  Packet 1 |  Packet 2 |  Packet 3 |    ...    | Packet n-1|  Packet n |
  +-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  
一个Packet:             4bytes             184bytes         
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Packet | =  |    ts header |       Packet data        |
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

PAT/PMT包结构, 只包含tsheader和PMT/PAT, 不包含adaption和pes
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | ts header |    PAT/PMT    |   Stuffing Bytss  |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

PES包结构,可能包含adaption和pes字段
       4 byte         x byte                    184-x byte
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | ts header |  adaptation field |          payload(pes)       |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

tsヘッダのデータ構造

各 TS パケットには ts ヘッダーフィールドが含まれており、そのサイズは 4 バイト固定であり、4 バイト内の各データビットの意味は次のとおりです: 合計 4 バイト (32 ビット
)

sync_byte                       (8bit)  同步字节,固定为0x47
transport_error_indicator	    (1bit)  传输错误指示符, 通常都为'0'
payload_unit_start_indicator    (1bit)  负载单元起始标示符,一个完整的数据包开始时标记为 '1'
transport_priority              (1bit)  传输优先级,0为低优先级,1为高优先级,通常取0
pid	                            (13bit) 传输包的PID, pat包固定为0x0000 
transport_scrambling_control	(2bit)  传输加扰控制,00表示未加密
adaptation_field_control        (2bit)  是否包含自适应区(adaption):00保留;01无自适应域,含有效负载;10含自适应域,无有效负载;11为同时带有自适应域和有效负载
continuity_counter              (4bit)  递增计数器,从0-f,起始值不一定取0,但必须是连续的

PATフィールドのデータ構造

PAT (Program Associate Table) プログラム アソシエート テーブルの構造は次のとおりです。

table_id	                (8bit)	PAT表固定为0x00
section_syntax_indicator	(1bit)	段语法标志位, 固定为1
zero	                    (1bit)	固定为0
reserved	                (2bit)	保留位,固定为11
section_length	            (12bit)	段长度(后面数据的长度),表示从下一个字段开始到CRC32(包含)之间有用的字节数
transport_stream_id	        (16bit)	传输流ID,固定为0x0001, 区别于一个网络中其它多路复用的流
reserved	                (2bit)	固定为11
version_number	            (5bit)	版本号,固定为00000,如果PAT有变化则版本号加1
current_next_indicator	    (1bit)	固定为1,表示这个PAT表可以用,如果为0则要等待下一个PAT表
section_number	            (8bit)	分段的号码. PAT可能分为多段传输, 第一段为00, 以后每个分段加1, 最多可能有256个分段
last_section_number	        (8bit)	固定为0x00, 最后一个分段的号码

开始循环,按顺序可能包含多个下面结构	 	 
program_number	            (16bit)	节目号为0x0000时表示这是NIT,节目号为0x0001,表示这是PAT
reserved	                (3bbit)	固定为111
PID	                        (13bit)	节目号对应内容的PID值0x1000, 也就是pmt的pid
结束循环	

CRC32	                    (32bit)	前面数据的CRC32校验码

PMTフィールドのデータ構造

PMT(Program Map Table)、プログラムマッピングテーブル、パッケージのPIDはPATテーブルから取得できます。

table_id	                (8bit)	PMT表取值随意, 这里给定0x02
section_syntax_indicator	(1bit)	段语法标志位, 固定为1
zero	                    (1bit)	固定为0
reserved	                (2bit)	保留位,固定为11
section_length	            (12bit)	后面数据的长度, 表示从下一个字段开始到CRC32()之间有用的字节数
program_number	            (16bit)	频道号码,表示当前的PMT关联到的频道, 取值0x0001
reserved	                (2bit)	固定为11
version_number	            (5bit)	PMT版本号码,固定为00000,如果PAT有变化则版本号加1
current_next_indicator	    (1bit)	发送的PMT表是当前有效还是下一个PMT有效, 固定为1
section_number	            (8bit)	固定为0x00, PMT可能分为多段传输,第一段为00, 以后每个分段加1, 最多可能有256个分段
last_section_number	        (8bit)	分段数,固定为0x00
reserved	                (3bit)	保留位, 固定为111
PCR_PID	                    (13bit)	PCR(节目参考时钟)所在TS分组的PID,指定为视频PID
reserved	                (4bit)	固定为1111
program_info_length	        (12bit)	节目描述信息,指定为0x000表示没有,2bit为00, 该域指出跟随其后对节目信息的描述的字节数。

开始循环,按顺序可能包含多个	 	 
stream_type	                (8bit)	流类型,标志是Video还是Audio还是其他数据,h.264编码对应0x1b,aac编码对应0x0f,mp3编码对应0x03
reserved	                (3bit)	固定为111
elementary_PID	            (13bit)	与stream_type对应的PID
reserved	                (4bit)	固定为1111
ES_info_length	            (12bit)	描述信息,指定为0x000表示没有
结束循环

reserved_5                  3bit    保留位, 固定为0x07
reserved_6                  4bit    保留位, 固定为0x0F	 	 

CRC32	                    32bit	前面数据的CRC32校验码

アダプテーションフィールドのデータ構造情報

アダプテーションフィールドは、オーディオおよびビデオデータが不十分な場合にデータで埋められます。

adaptation_field_length                 (8bit)    adaption字段的长度(后面的字段不包括当前字段)
discontinuity_indicator                 (1bit)    指示数据流是否存在不连续的情况
randort7_acce55_indicator               (1bit)    指示数据流中是否存在重要的组或关键帧
elementary_stream_priority_indicator    (1bit)    指示数据流的优先级
PCR_flag                                (1bit)    PCR(Programme Clock Reference)字段是否存在
OPCR_flag                               (1bit)    OPCR字段是否存在
splicing_point_flag                     (1bit)    数据流中是否存在插播点 
transport_private_data_flag             (1bit)    是否存在私有数据
adaptation_field_extension_flag         (1bit)    用于指示是否存在ADAPTATION FIELD EXTENSION

//PCR_flag==1 控制TS数据流同步的42位时间戳
program_clock_reference_base            (33bit)
Reserved                                (6bit)
program_clock_reference_extension       (9bit)

//OPCR_flag==1 ( Optional Program Clock Reference)
//用于同步接收到的多个数据流,其在时间戳方面与 PCR 相似,但只在数据流中的某些节目中使用
original_program_clock_reference_base   33bit
Reserved                                6bit
original_program_clock_reference_extension 9bit

//splicing_point_flag==1
splice_countdown                        (8bit)

//transport_private_data_flag==1
transport_private_data_length           (8bit)
for (1=0,i<transport_private_data_length; i++){
    
    
        private data byte               (8bit)
}

//adaptation_field_extension_flag==1
adaptation_field_extension_length       (8bit)
Itw_flag                                (1bit)
piecewise_rate_flag                     (1bit)
seamless_splice_flag                    (1bit)
Reserved                                (5bit)
//Itw_flag==1
ltw_valid_flag                          (1bit)    
ltw_offset                              (15bit)

//piecewise_rate_flag ==1
reserved                                (2bit)
piecewise_rate                          (22bit)

//seamless_splice_flag==1
Splice_type                             (4bit)
DTS_next_AU[32..30]                     (3bit)
marker_bit                              (1bit)
DTS_next_AU[29 ..15]                    (15bit)
marker_bit                              (1bit)
DTS_next_AU[14..0]                      (15bit)
marker_bit                              (1bit)
for (i=0;i<N;i++){
    
    
reserved                                (8bit)
}

//last
for(i=0i<N;i++){
    
    
stuffing_byte                           (8bit)
}

TS ストリームがパッケージ化される場合、PAT テーブルと PMT テーブルには Adaptation フィールドがありません。長さが十分でない場合は、直接 0xff を追加します。ビデオ ストリームとオーディオ ストリームの両方でアダプテーション フィールドを追加する必要があります。これは通常、フレームの最初の ts パケットと最後の ts パケットに追加され、中間の ts パケットは追加されません。
ts ファイルをパッケージ化するときは注意してください。PCR クロックを追加する必要があります。追加しないと、VLC プレーヤーでの再生に失敗します。動画の長さを取得できません。
ここでは、Java 実装を例として、PCR 値の生成方法を紹介します。

void create_adaption_field(AdaptionField  adption_field, long pts, boolean has_pcr)
{
    
    
    int index = 0;
    Arrays.fill(adption_field.adaption_buffer,0,adption_field.adaption_buffer.length, (byte) 0xFF);

    if (has_pcr)
    {
    
    
        //包含pcr
        long pcrValue = pts * 300;
        long PCR_BSE = pcrValue / 300;
        long PCR_EXT = pcrValue % 300;
        后续可能会更新,7个字节
        adption_field.adaption_buffer[index++] = 0x07; 
        //取0x50表示包含PCR
        adption_field.adaption_buffer[index++] = 0x50; 
        adption_field.adaption_buffer[index++] = (byte)((byte)0xff & (PCR_BSE >> 25)); //PCR_BASE的前8位
        adption_field.adaption_buffer[index++] = (byte)((byte)0xff & (PCR_BSE >> 17)); //PCR_BASE的紧跟8位
        adption_field.adaption_buffer[index++] = (byte)((byte)0xff & (PCR_BSE >> 9));  //PCR_BASE的紧跟8位
        adption_field.adaption_buffer[index++] = (byte)((byte)0xff & (PCR_BSE >> 1));  //PCR_BASE的紧跟8位
        adption_field.adaption_buffer[index++] = (byte)((PCR_BSE <<  7 |  PCR_EXT >> 8 | 0x7e) & 0xFF);
        adption_field.adaption_buffer[index++] = (byte)(0xff & PCR_EXT);

    }
    else
    {
    
    
        //不包含pcr
        adption_field.adaption_buffer[index++] = 0x07; //后续可能会更新, 7个字节
        adption_field.adaption_buffer[index++] = 0x00; //0x00都不包含
    }
    adption_field.adaption_field_size = index;
}

PESフィールドのデータ構造

pes 層 (ts 層のペイロード) は、タイムスタンプやその他の情報を各ビデオ/オーディオ フレームに追加します。pes パッケージには多くのコンテンツが含まれていますが、最も一般的に使用されるものだけを残します。
長さは 14 (pts のみを含む)/18 (pts と dts を含む) バイトです。

pes_start_code	    (24bit)        	开始码,固定为0x000001
stream id	        (8bit)	        音频取值(0xc0~0xdf),通常为0xc0,视频取值(0xe0-0xef),通常为0xe0
pes_packet_length	(16bit)	        后面pes数据的长度,0表示长度不限制,只有视频数据长度会超过0xffff
flag	            (8bit)	        是否加密, 通常取值0x80,表示数据不加密、无优先级、备份的数据
flag	            (8bit)          是否包含pts和dts, 取值0x80表示只含有pts,取值0xc0表示含有pts和dts
pes_data_length	    (8bit)        	后面数据的长度,取值510
pts	                (40bit)	        pts显示时间戳
dts	                (40bit)	        dts解码时间戳

pts は表示タイム スタンプ、dts はデコード タイム スタンプです。ビデオ データには両方のタイム スタンプが必要です。オーディオ データでは pts と dts は同じであるため、pts のみが必要です。
B フレームによるタイムスタンプには pts と dts の 2 種類があり、I フレームと P フレームの pts は dts と同じになります。ビデオに B フレームがない場合、pts は常に dts と同じになります。ファイルからビデオ フレームを順番に読み取り、抽出されたフレームの順序は dts の順序と同じになります。

TS データフローのパケット化戦略

ここでは、AAC オーディオ データのフレームを例として、TS カプセル化形式のパケット化戦略を説明します。通常、TS パケットは完全なフレームを送信できず、オーディオおよびビデオ データのフレームを複数のパケットに分割する必要があります。 1. まず
、フローの先頭として PAT パケットと PMT パケットをフローに追加します
2. 次に、アダプションと PES を含むデータ パケットの先頭として最初の PES パケットを追加します。パケットには、フレームの長さ、サンプリング レート、pts/dts などの情報が含まれています。
3. 分割データ PES パケットを中央に追加します。これには tsheader とオーディオおよびビデオ データのみが含まれます。
4. 最後のデータ パケットには、ts ヘッダー、Adaption、最後にオーディオおよびビデオ データが含まれますが、PES フィールドは含まれません。

対応する構造を次の図に示します。

  +-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
  |  TS   |  =  |  PAT包  |  PMT包 |  PES1  |    ...    | PES n | 
  +-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
  
第一个PES包:            4Byte       8Byte     14Byte(pts)  162Btte
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Packet | =  |    ts header | Adaption |  PES |       paylod |
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

中间的PES包, 只包含tsheader和payload, 不包含adaption和pes
                       4Byte             184Byte
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Packet | =  |    ts header |       payload        |
  +-+-+-+-+-+    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

最后一个PES包 包含tsheader、adaption、payload
       4 byte         x byte                    184-x byte
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  | ts header |  adaptation field |          payload        |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

おすすめ

転載: blog.csdn.net/yang1fei2/article/details/130913479