打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
TS格式解析
// Program Association Table
typedef struct PAT_Packet_tag
{
    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; //最后一个分段的号码
    // for(i=0; i<N; i++)
    // {
    unsigned program_number                  : 16;
    unsigned reserved_3                      : 3;
    unsigned network_PID                     : 16;  // 或者program_map_PID
    unsigned CRC_32                          : 32;
    // }
} PAT_Packet;
// Parse PAT
int Parse_PAT(unsigned char *pTSBuf, PAT_Packet *packet)
{
    TS_header TSheader;
    if (Parse_TS_packet_header(pTSBuf, &TSheader) != 0)
        return -1;
    if (TSheader.payload_unit_start_indicator == 0x01) // 表示含有PSI或者PES头
    {
        if (TSheader.PID == 0x0)  // 表示PAT
        {
             int iBeginlen = 4;
             int adaptation_field_length = pTSBuf[4];
             switch(TSheader.adaption_field_control)
             {
             case 0x0:                                    // reserved for future use by ISO/IEC
                  return -1;
             case 0x1:                                    // 无调整字段,仅含有效负载      
                  iBeginlen += pTSBuf[iBeginlen] + 1;  // + pointer_field
                  break;
             case 0x2:                                     // 仅含调整字段,无有效负载
                  return -1;
             case 0x3: // 调整字段后含有效负载
                 if (adaptation_field_length > 0)
                 {
                      iBeginlen += 1;                   // adaptation_field_length占8位
                      iBeginlen += adaptation_field_length; // + adaptation_field_length
                 }
                 else
                 {
                      iBeginlen += 1;                       // adaptation_field_length占8位
                 }
                 iBeginlen += pTSBuf[iBeginlen] + 1;           // + pointer_field
                 break;
            default:
                 break;
            }
            unsigned char *pPAT = pTSBuf + iBeginlen;
            packet->table_id                    = pTSBuf[0];
            packet->section_syntax_indicator    = pTSBuf[1] >> 7;
            packet->zero                        = pTSBuf[1] >> 6 & 0x1;
            packet->reserved_1                  = pTSBuf[1] >> 4 & 0x3;
            packet->section_length              = (pTSBuf[1] & 0x0F) << 8 | pTSBuf[2];
            packet->transport_stream_id         = pTSBuf[3] << 8 | pTSBuf[4];
            packet->reserved_2                  = pTSBuf[5] >> 6;
            packet->version_number              = pTSBuf[5] >> 1 &  0x1F;
            packet->current_next_indicator      = (pTSBuf[5] << 7) >> 7;
            packet->section_number              = pTSBuf[6];
            packet->last_section_number         = pTSBuf[7];
            int len = 0;
            len = 3 + packet->section_length;
            packet->CRC_32                      = (pTSBuf[len-4] & 0x000000FF) << 24
                                                | (pTSBuf[len-3] & 0x000000FF) << 16
                                                | (pTSBuf[len-2] & 0x000000FF) << 8
                                                | (pTSBuf[len-1] & 0x000000FF);
            int n = 0;
            for ( n = 0; n < (packet->section_length - 12); n += 4 )
            {
                 packet->program_number = pTSBuf[8 + n ] << 8 | pTSBuf[9 + n ];
                 packet->reserved_3                = pTSBuf[10 + n ] >> 5;
                 if ( packet->program_number == 0x00)
                 {
                     packet->network_PID = (pTSBuf[10 + n ] & 0x1F) << 8 | pTSBuf[11 + n ];
                 }
                 else
                 {
                     // 有效的PMT的PID,然后通过这个PID值去查找PMT包
                     program_map_PID = (pTSBuf[10 + n] & 0x1F) << 8 | pTSBuf[11 + n];
                 }
            }
            return 0;
         }
    }
    return -1;
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
TS数据结构分析
常见视频封装格式(2)
精解PSI-SI(一) - KUDO - 博客园
TS流分析
Program Specific Information
一、TS流概述
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服