PAT PMT 结构

TS_PAT_Program
typedef struct _M_PAT_MAP_TYPE
{
        unsigned program_number:16;
        unsigned reserved:3;
        unsigned program_map_pid:13;
}M_PAT_MAP_TYPE;

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


pat 解析示例代码:buffer[pos+0]是pat数据的开始位置:

                packet->table_id                        = buffer[pos];
                packet->section_syntax_indicator        = buffer[pos+1] >> 7;
              packet->zero                            = buffer[pos+1] >> 6 & 0x1;
            packet->reserved_1                    = buffer[pos+1] >> 4 & 0x3;
              packet->section_length                = ((buffer[pos+1] & 0x0F) << 8) + buffer[pos+2];
 
              packet->transport_stream_id           = buffer[pos+3] << 8 | buffer[pos+4];
 
            packet->reserved_2                    = buffer[pos+5] >> 6;
            packet->version_number                = buffer[pos+5] >> 1 &  0x1F;
            packet->current_next_indicator        = (buffer[pos+5] << 7) >> 7;
            packet->section_number                = buffer[pos+6];
              packet->last_section_number           = buffer[pos+7];
                    
                pos = pos + 8;
                int n = 0;
                for ( n = 0; n < packet->section_length - 12 ; n += 4 )//获取中间所有的pat节目信息
            {
                  unsigned  program_num = buffer[pos+ n ] << 8 | buffer[pos + 1 + n ];//节目号
                    printf("pat_handle 22222222 program_num:%x\n",program_num);
                  if ( program_num == 0x00)
                  {  
                packet->network_PID = (buffer[pos + 2 + n ] & 0x1F) << 8 | buffer[pos + 3 + n ];
                packet->reserved_3 = buffer[pos + 2 + n ] >> 5;
                ts_nit_pid = packet->network_PID;
                  }
            else
            {
                unsigned program_map_pid = (buffer[pos + 2 + n] & 0x1F) << 8 | buffer[pos + 3 + n];
                unsigned program_number = program_num;
                {
                    PAT_program[pat_no].reserved = buffer[pos + 2 + n ] >> 5;
                    PAT_program[pat_no].program_map_pid = (buffer[pos + 2 + n] & 0x1F) << 8 | buffer[pos + 3 + n];
                    printf("========program_map_pid:%d  :%x\n",pat_no,PAT_program[pat_no].program_map_pid);
                    PAT_program[pat_no].program_number = program_num;
                    ts_pmt_pid = PAT_program[pat_no].program_map_pid;
                    pat_no++;
                }
            }
            }





TS_PMT_Stream
typedef struct _M_PMT_MAP_TYPE
{
    unsigned stream_type:8;      /* type of elementary stream */
    unsigned reserved_1:3;
    unsigned elementary_pid:13;            /* elementary stream pid number */
    unsigned reserved_2:4;
    unsigned es_info_length:12;       /* length of descriptor */
                unsigned descriptor;
}M_PMT_MAP_TYPE;

//PMT 表结构体
typedef struct TS_PMT
{
    unsigned table_id                        : 8; //固定为0x02, 表示PMT表
    unsigned section_syntax_indicator        : 1; //固定为0x01
    unsigned zero                            : 1; //0x01
    unsigned reserved_1                      : 2; //0x03
    unsigned section_length                  : 12;//首先两位bit置为00,它指示段的byte数,由段长度域开始,包含CRC。
    unsigned program_number                    : 16;// 指出该节目对应于可应用的Program map PID
    unsigned reserved_2                        : 2; //0x03
    unsigned version_number                    : 5; //指出TS流中Program map section的版本号
    unsigned current_next_indicator            : 1; //当该位置1时,当前传送的Program map section可用;
   //当该位置0时,指示当前传送的Program map section不可用,下一个TS流的Program map section有效。
    unsigned section_number                    : 8; //固定为0x00
    unsigned last_section_number            : 8; //固定为0x00
    unsigned reserved_3                        : 3; //0x07
    unsigned PCR_PID                        : 13; //指明TS包的PID值,该TS包含有PCR域,
            //该PCR值对应于由节目号指定的对应节目。
            //如果对于私有数据流的节目定义与PCR无关,这个域的值将为0x1FFF。
    unsigned reserved_4                        : 4; //预留为0x0F
    unsigned program_info_length            : 12; //前两位bit为00。该域指出跟随其后对节目信息的描述的byte数。
    
 std::vector<TS_PMT_Stream> PMT_Stream;  //每个元素包含8位, 指示特定PID的节目元素包的类型。该处PID由elementary PID指定
    unsigned reserved_5                        : 3; //0x07
    unsigned reserved_6                        : 4; //0x0F
    unsigned CRC_32                            : 32; 
} TS_PMT;


pmt 解析示例代码:buffer[pos+0]是pmt数据的开始位置:

    packet->table_id                            = buffer[pos + 0];
    packet->section_syntax_indicator            = buffer[pos + 1] >> 7;
    packet->zero                                = buffer[pos + 1] >> 6 & 0x01;
    packet->reserved_1                          = buffer[pos + 1] >> 4 & 0x03;
    packet->section_length                      = (buffer[pos + 1] & 0x0F) << 8 | buffer[pos + 2];
    packet->program_number                      = buffer[pos + 3] << 8 | buffer[pos + 4];
    packet->reserved_2                          = buffer[pos + 5] >> 6;
    packet->version_number                      = buffer[pos + 5] >> 1 & 0x1F;
    packet->current_next_indicator              = (buffer[pos + 5] << 7) >> 7;
    packet->section_number                      = buffer[pos + 6];
    packet->last_section_number                 = buffer[pos + 7];
    packet->reserved_3                          = buffer[pos + 8] >> 5;
    packet->pcr_pid                             = ((buffer[pos + 8] << 8) | buffer[pos + 9]) & 0x1FFF;
    
    ts_pcr_pid = packet->pcr_pid;
    
    packet->reserved_4                          = buffer[pos + 10] >> 4;
    packet->program_info_length                 = (buffer[pos + 10] & 0x0F) << 8 | buffer[pos + 11];

                int p = 12;
                if ( packet->program_info_length != 0 )
                    pos += packet->program_info_length;
            
                for ( ; p <= (packet->section_length + 2 ) -  4; )
                {
                    printf("post + p = %d\n", pos + p);
                    unsigned long stream_type =  buffer[pos + p];
                    printf("--- 0x%x    stream type:%x\n",buffer[pos + p],stream_type);
                    //unsigned long elementary_pid =  ((buffer[pos + p+1] << 3) | buffer[pos + p+2]) & 0x1FFF;
                    //unsigned long es_info_length =  (buffer[pos + p+3] & 0x0F) << 8 | buffer[pos + p+4];
                    unsigned long elementary_pid =  ((buffer[pos + p+1] & 0x1F)<<8) + buffer[pos + p+2];
                    unsigned long es_info_length =  ((buffer[pos + p+3] & 0x0F)<<8)+ buffer[pos + p+4];
               }
               p = p + es_info_length ;
                    p += 5;
                    get_pmt = 1;
            }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值