数字电视节目码流中的PAT表分析

        PATProgram 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个字节

23个字节

4个字节

同步字节为47

40 00 二进制表示为 01000000 0000 0000

PID0x000,即为0,表示为PAT(节目关联表)

10  二进制表示为 0001 0000

自适应区域控制为01,表示没有调整字段,仅含有184字节长度的有效净荷。

注意:在payload_unit_start_indicator1时,在前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

 

 

23个字节

0

1

reserved

2

section_length

12

transport_stream_id

16

45个字节

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_id00,对于PAT只能是00

b0 11二进制表示为1011 0000 0001 0001

section_syntax_indicator段语法标志位,固定为1

section_length0x011,为17

transport_stream_id00 01

c1二进制表示为1100 0001

version_number00000,一旦PAT有变化,版本号加1

current_next_indicator1,表示传送的PAT当前可以使用,若为0表示下一个表有效

section_number00

last_section_number00

之后开始循环

00 00 e0 1f

节目号为00 00,表示这是NIT

e0 1f二进制表示为11100000 0001 1111

PID0x01f,即为31

00 01 e1 00

节目号为00 01,这个为PMT

 e1 00 二进制表示为11100001 0000 0000

PID0x100,即为28次方=256

你可能感兴趣的:(Stream,struct,网络,table,buffer,NetWork)