TS流解析之PAT表格解析

来源:互联网 发布:js 两个时间相减 编辑:程序博客网 时间:2024/05/22 17:26

from: http://blog.csdn.net/xioahw/article/details/4093488

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;
}

因此,PAT数据解析结果如下:

PAT数据

table_id    :0x00                            //8  
section_syntax_indicator   :0x01           // 1
'0'              :0x00                       // 1
reserved             0x03                // 2
section_length      :0x00d                    // 12
transport_stream_id    :0x0000                 // 16
reserved                        :0x03        // 2
version_number            :0x00              // 5
current_next_indicator   :0x01               // 1
section_number              :0x00            // 8
last_section_number         :0x00            // 8
program_number     :0x0001                    // 16
  reserved                :0x07               // 3
program_map_PID      :0x03e8             // 13
CRC         :0x f0 0b d7 79

由解析结构可知,该PAT表格中没有网络信息包信息,只包含一个节目,其PID为0x03e8

0 0