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