TS简介
MPEG-TS(Transport stream)即Mpeg传输流定义于ITU-T Rec. H.222.0和ISO 13818-1标准中,属于MPEG2的系统层。MPEG2-TS面向的传输介质是网络和卫星等可靠性较低的传输介质,这一点与面向较可靠介质如DVD等的MPEG PS不同。
1. TS数据包
TS流由TS数据包即Transport stream packet组成。TS packet是TS流的基本组成单位。TS packet一般是188个字节长度。TS packet包含4个字节的TS header和其余的TS数据。TS header如表所示:
名称 | 长度(位) |
同步字节(sync_byte) | 8 |
传输错误标记位(transport_error_indicator) | 1 |
载荷单元起始标记位(payload_unit_start_indicator | 1 |
传输优先级(transport_priority) | 1 |
分组ID (PID) | 13 |
传输加扰控制(transport_scrambling_control) | 2 |
适配域控制(adaptation_field_control) | 2 |
连续计数(continuity_counter) | 4 |
同步字节:该值为0x47。用于定位TS包的起始位置。
传输错误标记符:值为1时表明至少有1个错误位存在于关联的TS包中。
负载单元起始标记符:负载单元起始符用于PES包或PSI数据。当TS包的负载为PES数据时该值为1表明TS数据包是PES数据的起始字节,当TS包的负载为PSI数据时该值为1表明TS数据包包含PSI数据的第一个字节且TS数据包负载的第一个字节为pointer_field。
传输优先级:值为1表明该TS包比拥有相同PID的数据包有更高的优先级。
PID: PID用于标识数据包的分组。PID 0保留给PAT表,PID 1保留给CAT表,PID 0X0002-0X000F也是保留值,PID 0X1FFF是空包的保留PID。
传输加扰控制:这两位表明传输流负载的加扰模式。当有适配域存在时传输流包头不应该被加扰。空包的传输加扰控制应该设置为00。
适配域控制:这两位表明传输流包头后是否带有适配域和负载。00是保留值;01没有适配域,只有负载;10只有适配域,没有负载;11适配域后跟随着负载。空包的适配域控制值应该为01。解码器应该将适配域控制值为00的TS包丢弃。
连续计数:连续计数从0到15循环计数。在TS流中,重复包可能被发送两次,并且最大发送两次。重复包和适配域控制为00或10的TS包的连续计数和前一个有相同PID的包相同。当“discontinuity_indicator”设置为1时,连续计数的值可以不连续。
数据字节:数据字节应该是来自PES包,PSI数据段,规范中未定义的私有数据。数据字节的长度应该是184减去适配域的长度。
2. 适配域
适配域如表所示。
名称 | 长度(位) | |||
适配域长度(adaptation_field_length) | 8 | |||
如果适配域长度大于0 | 连续计数标记位(discontinuity_indicator 1) | 1 | ||
随机访问标记位(random_access_indicator) | 1 | |||
ES流优先级标记位(elementary_stream_priority_indicator) | 1 | |||
PCR标记位(PCR_flag) | 1 | |||
OPCR标记位(OPCR_flag) | 1 | |||
拼接点标记(splicing_point_flag) | 1 | |||
传输私有数据标记位(transport_private_data_flag) | 1 | |||
适配域扩展标记位(adaptation_field_extension_flag) | 1 | |||
如果PCR_flag为1 | PCR基本值(program_clock_reference_base) | 33 | ||
保留位 | 6 | |||
PCR扩展值 | 15 | |||
如果OPRC_flag为1 | 原PCR基本值(original_program_clock_reference_base) | 33 | ||
保留位 | 6 | |||
原PCR扩展值 | 9 | |||
如果splicing_point_flag为1 | 拼接倒数计数(splice_countdown) | 8 | ||
如果transport_private_data_flag为1 | 私有数据长度(transport_private_data_length) | 8 | ||
从0到transport_private_data_length | 私有数据 | 8 | ||
如果adaptation_field_extension_flag为1 | 适配域扩展长度 | 8 | ||
ltw_flag | 1 | |||
piecewise_rate_flag | 1 | |||
seamless_splice_flag | 1 | |||
从0到N | 填充数据(stuffing_byte) | 8 | ||
适配域长度:adaptation_field_length给出适配域从该值之后的字节长度。该值为0是在TS包中通过适配域插入填充数据。对于携带PES数据的TS包,如果PES数据长度不够时填充数据被用来补足TS包。
连续计数标记位:当该值为1时表示当前的传输流包处于不连续状态。该值被用来表示系统时间的不连续和continuity_counter的不连续。系统时间的不连续指的是对于被设置为PCR_PID的TS包,下一个PCR包将代表新的系统时钟。在任何TS包中都可以使用discontinuity_indicator表示continuity_counter的不连续。对于包含ES流的TS包continuity_counter的不连续发生后,ES流的第一个字节应该是ES流的访问点。
随机访问点:该值为1时表明该TS包和随后的有相同PID的TS包有对当前点进行随机访问的信息。对于视频下一个PES包的起始字节应该为sequence header,对于音频下一个PES包的字节应该是音频帧的第一个字节。
ES流优先级标记位:该值表示对于有相同PID的TS包,当前TS包所携带ES流数据的优先级。1具有更高的优先级。对于视频如果TS包中包含有帧内编码的数据可以将该值设为1。
PCR标记位:该值为1表示适配域中包含有PCR内容。
原PCR标记位:该值为1表示适配域中包含有OPCR内容。
拼接点标记位:该值为1表示适配域中包含有拼接读秒。
传输私有数据标记位:该值为1表示适配域有1个以上的私有字节。
适配域扩展标记位:该值为1表示有适配域扩展数据。
PCR:PCR有42位,分为两部分。第一部分为基本部分,33位,精度为90KHz,第二部分位扩展部分,9位,精度为27MHz。
PCR = PCR_BASE x 300 + PCR_EXT
OPCR:OPCR用于通过一个传输流重构传输流。当重构传输流时OPCR被复制到PCR域。
3. PSI信息
PSI信息被用来解析节目。PSI不能被加扰。在TS流中,PSI包括4个表:PAT表,PMT表,NIT表和CAT表。PAT表关联节目号和PMT表PID;PMT表给出节目组成流的PID;NIT表给出物理网络参数,诸如FDM频率,发射机编号;CAT表关联1到多个EMM流。
在TS包中通过pointer_field表示PSI分段的开始。Pointer_field是个8位域,其值表示从pointer_field之后到PSI第一个分段的第一个字节间的字节长度。
3.1 PAT表
PAT表列出TS流中所包含的节目号以及节目所对应的PMT PID和NIT PID。节目号是节目的数字标签,节目号0x0000被保留给网络PID。一个PAT表可以被分成多个section。PAT如表所示。
名称 | 长度(位) | ||
表ID(table_id) | 8 | ||
section_syntax_indicator | 1 | ||
‘0’ | 1 | ||
reserved | 2 | ||
section_length | 12 | ||
transport_stream_id | 16 | ||
reserved | 2 | ||
version_number | 5 | ||
current_next_indicator | 1 | ||
section_number | 8 | ||
last_section_number | 8 | ||
重复0到N个节目 | program_number | 16 | |
reserved | 3 | ||
如果节目号为0 | NIT PID | 13 | |
如果节目号不为0 | PMT PID | ||
CRC | 32 |
table_id: 应该被设置为00
section_syntax_indicator:应该被设置为1
section_length: 12位域,前两位应该为00。该值给出了从section_length之后到CRC间(包含CRC)的PAT分段的字节数。Section长度不能超过1021
Transport_stream_id:传输流标签,用于标识该传输流以区别网络内的其它复用流。
Version_number:PAT表的版本号。当PAT表改变时版本号应该加1,到达31后回绕成0。当current_next_indicator是1时版本号用于当前的PAT表,当current_next_indicator为0时版本号用于下一个PAT表。
Current_next_indicator:为1时表示PAT表当前可用,为0时表示下个PAT表可用。
Section_number:给出这个section的序号。PAT表的第一个section的序号应该为0x00。
Last_section_number:给出PAT表的最后一个section序号。
Program_number:给出PMT PID所关联节目的节目号。如果节目号为0x0000,所关联的PID将是网络PID。
Network_PID:给出NIT PID。
Program_map_PID:给出节目所关联的PMT表的PID。
CRC_32:PAT section的CRC校验值。
3.2 PMT表
PMT表提供节目号和节目ES流的映射关系。这个映射关系也就是节目的定义。
PMT如表4所示:
名称 | 长度(位) | |
table_id | 8 | |
section_syntax_indicator | 1 | |
‘0’ | 1 | |
reserved | 2 | |
section_length | 12 | |
program_number | 16 | |
reserved | 2 | |
version_number | 5 | |
current_next_indicator | 1 | |
section_number | 8 | |
last_section_number | 8 | |
reserved | 3 | |
PCR_PID | 13 | |
reserved | 4 | |
program_info_length | 12 | |
重复0到N个descriptor | descriptor |
|
重复0到N1个ES流 | stream_type | 8 |
reserved | 3 | |
elementary_PID | 13 | |
reserved | 4 | |
ES_info_length | 12 | |
重复0到N2个descriptor | descriptor |
|
CRC_32 | 32 |
Table_id:应该被设置成0x02。
Section_syntax_indicator:应该被设置成1。
Section_length:12位域,前两位应该为00。该值给出了从section_length之后到CRC间(包含CRC)的PMT分段的字节数。Section长度不能超过1021。
Program_number:给出PMT表所关联的节目号。一个节目定义只能被包含在一个节目映射section中,这就意味着节目定义不能超过1016个字节。
Version_number:PMT表的版本号。当PMT表改变时版本号应该加1,到达31后回绕成0。当current_next_indicator是1时版本号用于当前的PMT表,当current_next_indicator为0时版本号用于下一个PMT表。
Current_next_indicator:为1时表示PMT表当前可用,为0时表示下个PMT表可用。
Section_number:这个值应该总是为0x00。
Last_section_number:这个值应该总是为0x00。
PCR_PID:指出包含节目PCR的TS分组PID。对于没有PCR的私有流节目这个值应该为0x1FFF。
Program_info_length;12位域,前两位应该为00。给出其后所跟descriptors的字节长度。
Stream_tyep:给出elementary_PID所关联的ES流的类型。
Elementary_PID:给出ES流的PID。
ES_info_length:12位域,前两位应该为00。给出其后所跟descriptors的字节长度。
CRC_32:PMT CRC校验值。
3.3 PES包
PES包的语法定义如表5所示
名称 | 长度(位) | ||
packet_start_code_prefix | 24 | ||
stream_id | 8 | ||
PES_packet_length | 16 | ||
如果stream_id 不是program_stream_map, padding_stream, private_stream_2, ECM, EMM, program_stream_directory, DSMCC_stream, ITU-T Rec. H.222.1 type E_stream | '10' | 2 | |
PES_scrambling_control | 2 | ||
PES_priority | 1 | ||
data_alignment_indicator | 1 | ||
copyright | 1 | ||
original_or_copy | 1 | ||
PTS_DTS_flags | 2 | ||
ESCR_flag | 1 | ||
ES_rate_flag | 1 | ||
DSM_trick_mode_flag | 1 | ||
additional_copy_info_flag | 1 | ||
PES_CRC_flag | 1 | ||
PES_extension_flag | 1 | ||
PES_header_data_length | 8 | ||
如果PTS_DTS_flags 等于'10' | '0010' | 4 | |
PTS [32..30] | 3 | ||
marker_bit | 1 | ||
PTS [29..15] | 15 | ||
marker_bit | 1 | ||
PTS [14..0] | 15 | ||
marker_bit | 1 | ||
如果PTS_DTS_flags 等于'11' | '0011' | 4 | |
PTS [32..30] | 3 | ||
marker_bit | 1 | ||
PTS [29..15] | 15 | ||
marker_bit | 1 | ||
PTS [14..0] | 15 | ||
marker_bit | 1 | ||
'0001' | 4 | ||
DTS [32..30] | 3 | ||
marker_bit | 1 | ||
DTS [29..15] | 15 | ||
marker_bit | 1 | ||
DTS [14..0] | 5 | ||
marker_bit | 1 | ||
从0到N1 | stuffing_byte | 8 | |
从0到N2 | PES_packet_data_byte | 8 | |
如果stream_id 是 program_stream_map, private_stream_2, ECM, EMM, program_stream_directory, DSMCC_stream, ITU-T Rec. H.222.1 type E stream
| 从0到PES_packet_length | PES_packet_data_byte | 8 |
如果stream_id 是 padding_stream | 从0到PES_packet_length | padding_byte | 8 |
packet_start_code_prefix:packet起始码前缀和其后的stream_id共同标识了PES包的起始位置。Packet起始码前缀的值为:0x000001
stream_id:该值给出了所关联ES流的类型和编号。
Pes_packet_length:给出从其后所开始的PES包的字节数。
Pes_scrambling_control:指出PES负载的加扰模式。当加扰位于PES层时,PES包头不应该被加扰。
Pes_priority:指出这个PES包负载的优先级。Pes_priority为1时具有更高的优先级。
Data_alignment_indicator:值为1时表明PES包头后立刻紧跟着视频起始码或音频同步字。
Copyright:该值为1时表明PES包负载有版权保护。
Original_or_copy:该值为1时表明PES包负载是原始的,为0时是复制的。
PTS_DTS_flags:2位域,为10时PES包头中有PTS域,为11时PES包头中有PTS和DTS域。
ESCR_flag:为1时表明PES包头中有ESCR及扩展域。
ES_rate_flag:为1时表明PES包头中有ES_rate域。
DSM_trick_mode_flag:为1时表明有trick mode域。
Additional_copy_info_flag:为1时表明有additional_copy_info域。
PES_CRC_flag:为1时表明CRC域存在于PES包中。
PES_extension_flag:为1时表明扩展域存在于PES包头中。
PES_header_data_length:指出PES包头中所包含的可选域和填充字节的长度。
Marker_bit:该值为1。
PTS:PES包在解码器上的播放时间。PTS有33位,分成3个域。PTS的时间单位为系统时钟频率的300分之一(27000000/300),即90KHz。
DTS:PES包的解码时间。DTS有33位,分成3个域。DTS的时间单位为系统时钟频率的300分之一(27000000/300),即90KHz。
4. TS流的解析过程
- 定位TS包的sync_byte,获得TS包,解析TS包头,根据PID决定TS包的类型(PAT,PMT,PES…)。
- 解析PAT表。对PID为0的TS包进行解析,获取PAT表,从中解析出TS流中所包含的节目号以及节目所对应的NIT PID和PMT PID。
- 解析PMT表。根据已知的PMT PID信息对相应的TS包进行解析,获取PMT表,从中解析出节目的PCR_PID,音视频ES PID。
- 解析PES包。根据已知的ES PID信息对相应的TS包进行解析,获取对应音视频的帧数据,并解析出音视频包帧的PTS,DTS值。
- 解析PCR值。根据PMT表中所获取的PCR_PID,对相应的TS包进行解析,从适配域中获取PCR值。