PAT是Program Association Table的简称,即”节目关联表”. PAT定义了当前TS流中所有的节目,其PID恒为0x00,它是PSI信息的根节点,要查找节目必须从PAT表开始.PAT表描述了当前TS流中包含什么样的PID,主要包括当前流的NIT表格的PID,当前流中有多少个不同类型PMT表,每个PMT表对应的频道号等信息.
参考链接:
http://blog.csdn.net/xioahw/article/details/4093488
http://blog.sina.com.cn/s/blog_487c4377010009vg.html
PAT表格定义如下:
typedef struct TS_PAT_Program { unsigned program_number :16; //节目号 unsigned program_map_PID :13; //节目映射表的PID,节目号大于0时对应的PID,每个节目对应一个 }TS_PAT_Program;
PAT表结构体如下:
typedef struct TS_PAT { unsigned table_id : 8; //固定为0x00 ,标志是该表是PAT unsigned section_syntax_indicator : 1; //段语法标志位,固定为1 unsigned zero : 1; //0 unsigned reserved_1 : 2; // 保留位 unsigned section_length : 12; //表示这个字节后面有用的字节数,包括CRC32 unsigned transport_stream_id : 16; //该传输流的ID,区别于一个网络中其它多路复用的流 unsigned reserved_2 : 2;// 保留位 unsigned version_number : 5; //范围0-31,表示PAT的版本号 unsigned current_next_indicator : 1; //发送的PAT是当前有效还是下一个PAT有效 unsigned section_number : 8; //分段的号码。PAT可能分为多段传输,第一段为00,以后每个分段加1,最多可能有256个分段 unsigned last_section_number : 8; //最后一个分段的号码 std::vector<TS_PAT_Program> program; unsigned reserved_3 : 3; // 保留位 unsigned network_PID : 13; //网络信息表(NIT)的PID,节目号为0时对应的PID为network_PID unsigned CRC_32 : 32; //CRC32校验码 } TS_PAT;
解析代码如下:
HRESULT CTS_Stream_Parse::adjust_PAT_table( TS_PAT * packet, unsigned char * buffer) { packet->table_id = buffer[0]; packet->section_syntax_indicator = buffer[1] >> 7; packet->zero = buffer[1] >> 6 & 0x1; packet->reserved_1 = buffer[1] >> 4 & 0x3; packet->section_length = (buffer[1] & 0x0F) << 8 | buffer[2]; packet->transport_stream_id = buffer[3] << 8 | buffer[4]; packet->reserved_2 = buffer[5] >> 6; packet->version_number = buffer[5] >> 1 & 0x1F; packet->current_next_indicator = (buffer[5] << 7) >> 7; packet->section_number = buffer[6]; packet->last_section_number = buffer[7]; int len = 0; len = 3 + packet->section_length; packet->CRC_32 = (buffer[len-4] & 0x000000FF) << 24 | (buffer[len-3] & 0x000000FF) << 16 | (buffer[len-2] & 0x000000FF) << 8 | (buffer[len-1] & 0x000000FF); int n = 0; for ( n = 0; n < packet->section_length - 12; n += 4 ) { unsigned program_num = buffer[8 + n ] << 8 | buffer[9 + n ]; packet->reserved_3 = buffer[10 + n ] >> 5; packet->network_PID = 0x00; if ( program_num == 0x00) { packet->network_PID = (buffer[10 + n ] & 0x1F) << 8 | buffer[11 + n ]; TS_network_Pid = packet->network_PID; //记录该TS流的网络PID TRACE(" packet->network_PID %0x /n/n", packet->network_PID ); } else { TS_PAT_Program PAT_program; PAT_program.program_map_PID = (buffer[10 + n] & 0x1F) << 8 | buffer[11 + n]; PAT_program.program_number = program_num; packet->program.push_back( PAT_program ); TS_program.push_back( PAT_program );//向全局PAT节目数组中添加PAT节目信息 } } return 0; }
下面分析一段TS流
转自: http://blog.csdn.net/qingkong8832/article/details/6894333
1,第一个包
包头:47 40 00 10
数据: 00 00 b0 11 00 01 c1 00 00 00 00 e0 1f 00 01 e1 00 24 ac48 84
剩余全是ff
同步字节 |
传输错误标识 |
负载单元开始标识 |
传输优先级 |
PID |
传输扰乱控制 |
自适应区域控制 |
连续计数器 |
8 |
1 |
1 |
1 |
13 |
2 |
2 |
4 |
第1个字节 |
第2、3个字节 |
第4个字节 |
同步字节为47
40 00 二进制表示为 01000000 0000 0000
PID为0x000,即为0,表示为PAT(节目关联表)
10 二进制表示为 0001 0000
自适应区域控制为01,表示没有调整字段,仅含有184字节长度的有效净荷。
注意:在payload_unit_start_indicator为1时,在前4个字节后会有一个调整字节。所以实际数据应该为去除第一个字节00后的数据。
即为00 b0 11 00 01 c100 00 00 00 e0 1f 00 01e1 00 24 ac 48 84
table_id |
8 |
第1个字节 |
section_syntax_indicator |
1 |
第2、3个字节 |
0 |
1 |
|
reserved |
2 |
|
section_length |
12 |
|
transport_stream_id |
16 |
第4、5个字节 |
reserved |
2 |
第6个字节 |
version_number |
5 |
|
current_next_indicator |
1 |
|
section_number |
8 |
第7个字节 |
last_section_number |
8 |
第8个字节 |
循环开始 |
||
program_number |
16 |
2个字节 |
reserved |
3 |
2个字节 |
network_id(节目号为0时) program_map_PID(节目号为其他时) |
13 |
|
循环结束 |
||
CRC_32 |
32 |
4个字节 |
00 b0 11 00 01 c1 00 0000 00 e0 1f 00 01 e1 0024 ac 48 84
table_id为00,对于PAT只能是00
b0 11二进制表示为1011 0000 0001 0001
section_syntax_indicator,段语法标志位,固定为1
section_length为0x011,为17
transport_stream_id为00 01
c1二进制表示为1100 0001
version_number为00000,一旦PAT有变化,版本号加1
current_next_indicator为1,表示传送的PAT当前可以使用,若为0表示下一个表有效
section_number为00
last_section_number为00
之后开始循环
00 00 e0 1f
节目号为00 00,表示这是NIT
e0 1f二进制表示为11100000 0001 1111,
PID为0x01f,即为31
00 01 e1 00
节目号为00 01,这个为PMT
e1 00 二进制表示为11100001 0000 0000
PID为0x100,即为2的8次方=256