TS码流:
47 60 00 10 00 00 B0 0D 00 00 C1 00 00 00 01 E0 81 0C 8C BE 32....FF....
一、TS头
4个字节47 60 00 10
0100 0111 0110 0000 0000 0000
sync_byte transport_error_indicator payload_unit_start_indicator transport_priority PID
0001 0000
transport_scrambling_control adaptation_field_control continuity_counter ....adaptation_field(8bit)...
transport_packet()
{
sync_byte // 8
transport_error_indicator //1
payload_unit_start_indicator //1
transport_priority // 1
PID //13
transport_scrambling_control // 2
adaptation_field_control //2
continuity_counter //4
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
}
}
}
前面 32bit 的数据即 TS 分组首部,它指出了这个分组的属性。
sync_byte 同步字节,固定为 0x47 ,表示后面的是一个 TS 分组,当然,后面包中的数
据是不会出现 0x47 的
transport_error_indicator 传输错误标志位,一般传输错误的话就不会处理这个包了
payload_unit_start_indicator 这个位功能有点复杂,字面意思是有效负载的开始标志,
根据后面有效负载的内容不同功能也不同,后面用到的时候再
说。
transport_priority 传输优先级位,1 表示高优先级,传输机制可能用到,解码好像用不
着。
PID 这个比较重要,指出了这个包的有效负载数据的类型,告诉我们这个包传输的是什么
内容。前面已经叙述过。
transport_scrambling_control 加密标志位,表示 TS 分组有效负载的加密模式。TS
分组首部(也就是前面这 32bit)是不应被加密的,00 表示未加 密。
adaption_field_control 翻译为“调整字段控制”,表示 TS 分组首部后面是否跟随有调整
字段和有效负载。01 仅含有效负载,10 仅含调整字段,11 含有调整字段和有效负载。为 00 的话解码器不进行处理。 空分组没有调整字段。
continuity_counter 一个 4bit 的计数器,范围 0-15,具有相同的 PID 的 TS 分组传输时
每次加 1,到 15 后清 0。不过,有些情况下是不计数的。如 下:(1)TS 分组无有效负载
(2)复制的 TS 分组和原分组这个值一样(3)后面讲到的一个标志 discontinuity_indicator 为 1 时
adaptation_field() 调整字段的处理
data_byte 有效负载的剩余部分,可能为 PES 分组,PSI,或一些自定义的数据
二、PAT
00 B0 0D 00 00 C1 00 00 00 01 E0 81 0C 8C BE 32
[0000 0000] 1011 0000 0000 1101
table_id section_syntax_indicator section_length
0000 0000 0000 0000 1100 0001
transport_stream_id version_number current_next_indicator
0000 0000 0000 0000
section_number last_section_number
0000 0000 0000 0001 1110 0000 1000 0001 [0C 8C BE 32]
program_number network_PID/program_map_PID CRC_32
program_association_section() {
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
for (i=0; i<N;i++) {
program_number // 16
reserved // 3
if(program_number == '0') {
network_PID // 13
}
else {
program_map_PID // 13
}
}
CRC_32 // 32
}
table_id 固定为 0x00 ,标志是该表是 PAT
section_syntax_indicator 段语法标志位,固定为 1
section_length 表示这个字节后面有用的字节数,包括 CRC32。假如后面的字节加
上前面的字节数少于 188,后面会用 0XFF 填充。假如这个数值比较大,则 PAT 会分成几部分来传输。
transport_stream_id 该传输流的 ID,区别于一个网络中其它多路复用的流。
version_number 范围 0-31,表示 PAT 的版本号,标注当前节目的版本.这是个非常有
用的参数,当检测到这个字段改变时,说明 TS 流中的节目已经变化了,程序必须重新搜索节目.
current_next_indicator 表示发送的 PAT 是当前有效还是下一个 PAT 有效。
section_number 分段的号码。PAT 可能分为多段传输,第一段为 00,以后每个分段
加 1,最多可能有 256 个分段
last_section_number 最后一个分段的号码 program_number 节目号
network_PID 网络信息表(NIT)的 PID,网络信息表提供了该物理网络的一些信息,和
电视台相关的。节目号为 0 时对应的 PID 为 network_PID
program_map_PID 节目映射表的 PID,节目号大于 0 时对应的 PID,每个节目对应一个
CRC_32 CRC32 校验码
三、PMT
[47 60 81 10] 00 02 B0 17 00 01 C1 00 00 E8 10 F0 00 1B E8 10 F0 00 03 E8 14 F0 00 66 74 A4 2D
0000 0010 1011 0000 0001 0111 0000 0000 0000 0001
table_id section_syntax_indicator section_length program_number
1100 0001 0000 0000 0000 0000 111[0
version_number current_next_indicator section_number last_section_number
1000 0001 0000] 1111 0000 0000 0000 [0001 1011 1110 1000 0001 0000 1111 0000 0000 0000]
PCR_PID program_info_length stream_type elementary_PID ES_info_length
[0000 0011 1110 1000 0001 0100 1111 0000 0000 0000] [66 74 A4 2D]
stream_type elementary_PID ES_info_length
TS_program_map_section() {
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
for (i=0; i<N; i++) {
descriptor()
}
for (i=0;i<N1;i++) {
stream_type //8
reserved //3
elementary_PID //13
reserved //4
ES_info_length //12
for (i=0; i<N2; i++) {
descriptor()
}
}
CRC_32 //32
}
table_id 固定为 0x02 ,标志是该表是 PMT
section_syntax_indicator
section_length
version_number
current_next_indicator 以上四个字段意思和 PAT 相同,可参考上面解释
section_number last_section_number 以上两个字段意思和 PAT 相同,不过值都固定为 0x00,我觉得这样的原因可能是因为 PMT 不需要有先后顺序,因为先定义哪个节目都是
无所谓。
program_number 节目号,表示该 PMT 对应的节目
PCR_PID PCR(节目时钟参考)所在 TS 分组的 PID,根据 PID 可以去搜索相
应的 TS 分组,解出 PCR 信息。
program_info_length 该节目的信息长度,在此字段之后可能会有一些字节描述该节目的信息
stream_type 指示了 PID 为 elementary_PID 的 PES 分组中原始流的类型,比如视
频流,音频流等,见后面的表
elementary_PID 该节目中包括的视频流,音频流等对应的 TS 分组的 PID
ES_info_length 该节目相关原始流的描述符的信息长度。
stream_type 对应的类型:
四、PES 包
[47 48 14 10] [00 00 01 C0 01 88 80 80 05 21 00 01 96
07] FF FD 85 00 33 22 22 11 22 11 11 11 11 11 11
24 82 41 00 90 40 00 00 00 00 00....
PES Header:
[00 00 01] C0 01 88
packet_start_code_prefix stream_id PES_packet_length
1000 0000
PES_scrambling_control PES_priority data_alignment_indicator copyright original_or_copy
1000
PTS_DTS_flags ESCR_flag ES_rate_flag
0000
DSM_trick_mode_flag additional_copy_info_flag PES_CRC_flag PES_extension_flag
0000 0101
PES_header_data_length
[0010 0001 0000 0000 0000 0001 1001 0110 0000 0111]
PTS [32..30] marker_bit PTS [29..15] marker_bit PTS [14..0] marker_bit
PES_packet() {
packet_start_code_prefix // 24 bslbf
stream_id x // 8 uimsbf
PES_packet_length // 16 uimsbf
if (stream_id != program_stream_map
&& stream_id != padding_stream
&& stream_id != private_stream_2
&& stream_id != ECM
&& stream_id != EMM
&& stream_id != program_stream_directory
&& stream_id != DSMCC_stream
&& stream_id != ITU-T H.222.1 建议书类型 E stream) {
'10' // 2 bslbf
PES_scrambling_control // 2 bslbf
PES_priority // 1 bslbf
data_alignment_indicator // 1 bslbf
copyright // 1 bslbf
original_or_copy // 1 bslbf
PTS_DTS_flags // 2 bslbf
ESCR_flag // 1 bslbf
ES_rate_flag // 1 bslbf
DSM_trick_mode_flag // 1 bslbf
additional_copy_info_flag // 1 bslbf
PES_CRC_flag // 1 bslbf
PES_extension_flag // 1 bslbf
PES_header_data_length // 8 uimsbf
if (PTS_DTS_flags == '10') {
'0010' // 4 bslbf
PTS [32..30] // 3 bslbf
marker_bit // 1 bslbf
PTS [29..15] // 15 bslbf
marker_bit // 1 bslbf
PTS [14..0] // 15 bslbf
marker_bit // 1 bslbf
}
if (PTS_DTS_flags == '11') {
'0011' // 4 bslbf
PTS [32..30] // 3 bslbf
marker_bit // 1 bslbf
PTS [29..15] // 15 bslbf
marker_bit // 1 bslbf
PTS [14..0] // 15 bslbf
marker_bit // 1 bslbf
'0001' // 4 bslbf
DTS [32..30] // 3 bslbf
marker_bit // 1 bslbf
DTS [29..15] // 15 bslbf
marker_bit // 1 bslbf
DTS [14..0] // 15 bslbf
marker_bit // 1 bslbf
}
if (ESCR_flag == '1') {
Reserved // 2 bslbf
ESCR_base[32..30] // 3 bslbf
marker_bit // 1 bslbf
ESCR_base[29..15] // 15 bslbf
marker_bit // 1 bslbf
ESCR_base[14..0] // 15 bslbf
marker_bit // 1 bslbf
ESCR_extension // 9 uimsbf
marker_bit // 1 bslbf
}
if (ES_rate_flag == '1') {
marker_bit // 1 bslbf
ES_rate // 22 uimsbf
marker_bit // 1 bslbf
}
if (DSM_trick_mode_flag == '1') {
trick_mode_control // 3 uimsbf
if ( trick_mode_control == fast_forward ) {
field_id // 2 bslbf
intra_slice_refresh // 1 bslbf
frequency_truncation // 2 bslbf
}
else if ( trick_mode_control == slow_motion ) {
rep_cntrl // 5 uimsbf
}
else if ( trick_mode_control == freeze_frame ) {
field_id // 2 uimsbf
Reserved // 3 bslbf
}
else if ( trick_mode_control == fast_reverse ) {
field_id // 2 bslbf
intra_slice_refresh // 1 bslbf
frequency_truncation // 2 bslbf
else if ( trick_mode_control == slow_reverse ) {
rep_cntrl // 5 uimsbf
}
Else
Reserved // 5 bslbf
}
if ( additional_copy_info_flag == '1') {
marker_bit // 1 bslbf
additional_copy_info // 7 bslbf
}
if ( PES_CRC_flag == '1') {
previous_PES_packet_CRC // 16 bslbf
}
if ( PES_extension_flag == '1') {
PES_private_data_flag // 1 bslbf
pack_header_field_flag // 1 bslbf
program_packet_sequence_counter_flag // 1 bslbf
P-STD_buffer_flag // 1 bslbf
Reserved // 3 bslbf
PES_extension_flag_2 // 1 bslbf
if ( PES_private_data_flag == '1') {
PES_private_data // 128 bslbf
}
if (pack_header_field_flag == '1') {
pack_field_length // 8 uimsbf
pack_header()
}
if (program_packet_sequence_counter_flag == '1') {
marker_bit // 1 bslbf
program_packet_sequence_counter // 7 uimsbf
marker_bit // 1 bslbf
MPEG1_MPEG2_identifier // 1 bslbf
original_stuff_length // 6 uimsbf
}
if ( P-STD_buffer_flag == '1') {
'01' // 2 bslbf
P-STD_buffer_scale // 1 bslbf
P-STD_buffer_size // 13 uimsbf
}
if ( PES_extension_flag_2 == '1') {
marker_bit
// 1 bslbf
PES_extension_field_length
// 7 uimsbf
stream_id_extension_flag
// 1 bslbf
If ( stream_id_extension_flag == '0') {
stream_id_extension
// 7 uimsbf
for (i = 0; i < PES_extension_field_length; i
+++){
reserved
// 8 bslbf
}
}
}
}
for (i < 0; i < N1; i++) {
stuffing_byte // 8 bslbf
}
for (i < 0; i < N2; i++) {
PES_packet_data_byte // 8 bslbf
}
}
else if ( stream_id == program_stream_map
|| stream_id == private_stream_2
|| stream_id == ECM
|| stream_id == EMM
|| stream_id == program_stream_directory
|| stream_id == DSMCC_stream
|| stream_id == ITU-T H.222.1 建议书类型 E stream ) {
for (i = 0; i < PES_packet_length; i++) {
PES_packet_data_byte // 8 bslbf
}
}
else if ( stream_id == padding_stream) {
for (i < 0; i < PES_packet_length; i
+++) {
padding_byte // 8 bslbf
}
}
}
五、AAC
FF FD 85 00 33 22 22
11111111 11111101
syncword ID Layer protection_absent
10000101 0000
Profile sampling_frequency_index priveta_bit channel_configuration original_copy home
[0000 00110011 00100010 00100010]
Copyright_identification_bit Copyright_identification_start aac_frame_length adts_buffer_fullness number_of_raw_data_blocks_in_frame
六、H264
1.TS流分析器
2.H264分析器
AUD:
Non-IDR:
SPS:
PPS:
IDR: