ts header
结构
字段解释
- sync_bye
- 是包中的第一个字节,TS包以固定的8bit的同步字节开始,所有的TS传送包,同步字都是唯一的OX47,用于建立发送端和接收端包的同步。MPEG-2解码器接收到MPEG-2 TS流时,首先检测包结构,在TS流中查找同步字节:总是OX47,总位于TS包开始位置,固定间隔为188字节。同时满足这两个条件,可以确定同步。如果出现一个字节为47hex(OX47),解码器将检测这个字节前后n倍188字节的位置是否也是同步字节。如果是,则当前字节为同步字节;否则,当前字节只是码流中偶尔出现的47hex,不是同步字节。接收端收到5个TS包之后开始同步。丢包3个之后解码器即失步,需重新同步。
- payload_unit_start_indicator
- 对于PES的包,如果PES的包很大,一个ts包的大小固定为188字节,如果188个字节装不下,那么就需要分包,假设总共要分3个包,那么第一包的PUSI就是1,剩下的两个包就是0.然后下一个PES如果又分了三个包,同样第一个ts包的PUSI是1,剩下的两个是0
- 对于PSI的包,如果包很大,同样需要分多个section,一个section分多个ts包,那么类似PES,第一个ts包的PUSI就需要设置为1.同时payload的第一个字节是pointer_field,指示新的section的第一个字节的位置。那么才能够pointer_field的位置到新的section的第一个字节的位置的中间的这些byte,是上一个section的结尾部分。
- 0:有效载荷单元起始符为0,表示不是帧头,不含PES包头数据,只有PES负载(PES负载就是一帧数据)
- continuity_counter
- ffmpeg对continuit count的check是,无论是否一个新的pes开始,它的值总是0-15, 0-15,例如,pes1,最后一个包是12,那么新的一个pes2的第一个包,并不是0,而是13
adaption field
字段解释
- PCR_Flag
- PCR主要用于对时
- stuffing_bytes
- 对于不足188字节的pes,填充0xff使用adaption field,而不是optional pes header的stuffing bytes
- 对于PES包,如果包的大小小于188个字节,那么必须要用自适应区域去填充到188字节
- 对于PSI,可以使用自适应区域,或者在后面填充0xFF,一般是在后面填充0xFF
PAT
字段解释
- program_number
- 该号码标志TS流的一个频道,该频道可包含很多节目(即可以包含多个Video PID和Audio PID),频道和节目的关系,比如我们有中央电视台综合频道,下属CCTV-1 - CCTV14这些节目。一个PMT表格对应一个频道,比如中央电视台综合频道。而一个PMT里面包含所有节目的信息,比如CCTV1~CCTV14。
- pmt里面有个program number,pat里面也有个program number,这两个不匹配,ffplay能播放,但是vlc不能播放,如果pmt的program number和pat的program number不匹配,会导致vlc无法播放
- program_map_PID
- 表示本频道使用哪个PID做为PMT的PID,因为可以有很多的频道,因此DVB规定PMT的PID可以由用户自己定义
- PAT中可能包含多个频道号,也就有多个PMT表格,一个频道有多个节目
- section_length
- 多个PMT具体这个N是多少根据section_length来确定
- 段的大小,表示这个字节后面有用的字节数,包括CRC32.假如后面的字节加上前面的字节数少于188,后面会用0xFF填充,假如这个数值比较大,则PAT会分成几部分来传输。
- section_syntax_indicator
- 固定为1 为了防止和ISO13818Video流格式中的控制字冲突而设置的
- transport_stream_id
- 该传输流的ID,区别于一个网络中其他多路复用的流
- version_number
- 范围0-31,表示PAT的版本号,标注当前节目的版本,这是个非常有用的参数,当检测到这个字段改变时,说明TS流中的节目已经改变了,程序必须重新搜索节目
- current_next_indicator
- 表示发送的PAT是当前有效还是下一个PAT有效
- section_number
- 分段的号码,PAT可能分为多个段传输,第一段为00,以后每个分段加1,最大可能有256个分段
- ISO/IEC13818-1中定义,通过传输流传送PSI表时,PSI应被划分为一个或多个段(SECTION)后, 将SECTION映射到传输流中进行传送,ISO/IEC13818-1 中定义了这种传输段(SECTION)的语法结构,通过这种结构,将PSI的数据填充到传输流中进行传送. 为什么要把PSI划为多个SECTION来传输了,一次传输不就行了? 因为每个TS包的数据负载能力是有限的,即每个TS包的长度是有限的,所以当有些PSI表很长很大时,就需要将表拆分成一个一个SECTION语法数据段,再把这钟结构的SECTION填充到TS包中进行传输【每一个段的长度不一,一个段的开始由TS包的有效负载payload_unit_start_indicator来标识】
- 伪代码
if (adaption_field_control == '10' || adaption_field_control == '11') { adaption_fields() //调整字段的处理 } if (adaption_field_control == '01' || adaption_field_control == '11') { for(i = 0; i < N ; i++) //N值 = 184 - 调整字段的字节数 { } }
- last_section_number
- 最后一个分段的号码
- network_PID
- 网络信息表(NIT)的PID,网络信息表提供了该物理网络的一些信息,和电视台相关的,节目号为0时对应的PID为network_PID
PMT
字段解释
- current_next_indicator
- 当该位置0时,指示当前传送的Program map section不可用,下一个TS流的Program map section有效。
- program_info_length
- 前两位bit为00。该域指出跟随其后对节目信息的描述的byte数。
此为12 比特字段,该字段的头两比特必为‘00’,剩余10 比特指定该分段的字节数,紧随section_length 字段开始,并包括CRC。此字段中的值应不超过1021(0x3FD).段长度,从program_number开始,到CRC_32(含)的字节总数
- 前两位bit为00。该域指出跟随其后对节目信息的描述的byte数。
- program_number
- 为16bit的频道号码,与PAT的program_number相对应,表示当前PMT关联到的频道
- version_number
- 用于通知解复用程序PMT表有更新,如果没有更新版本号不变
- stream_type
- 标志是audio还是video还是其他数据,标志是Video还是Audio还是其他数据,h.264编码对应0x1b,aac编码对应0x0f,mp3编码对应0x03
- elementary_PID
- 如果stream_type是video,那么这个pid就是video的pid,如果stream_type是audio,那么这个pid就是audio的pid
- PCR_PID
- PCR(节目时钟参考)所在TS分组的PID,根据PID可以去搜索相应的TS分组,解出PCR信息。
PES
-
stream_id
- 音频取值(0xc0-0xdf),通常为0xc0,视频取值(0xe0-0xef),通常为0xe0
-
PES_scrambling_control
- 加密模式,00->不加密
-
data_alignment_indicator
- 1表示ES数据紧跟PES头
-
copyright
- 1表示有效负载是有版权的
-
PTS_DTS_flag
- pts也是属于pes头的一部分,所以,如果一个pes很大,只有第一包才有pts
-
PES_packet_length
- 关于PES_packet_length,如果pes包大小大于65535, 那么这个字段就是0,因为这个字段的长度是16个bit,最大值就是65535。如果pes包大小小于0,那么这个字段就不是0.
- A value of zero for the PES packet length can be used only when the PES packet payload is a video elementary stream
- 这个长度是optional pes header加上h264负载总和的长度
-
关于optional_pes_header
if (stream_ id != program_stream_map && stream_ id I= padding_stream && stream_ id != private_stream_2 && stream id I= ECM && stream_ id != EMM && strean_ _id != program_ _stream_ directory && stream_ id != DSMCC_ stream && stream, id I= ITU-T H.222.1 建议书类型 stream) ( optional_pes_geader )