zoukankan      html  css  js  c++  java
  • pmt表解析

    节目映射表提供节目号与组成它们的所有原始码流之间的映射,其PID由所在TS中的PAT表指定,PMT以program_map_section的形式进行TS打包。
        我们知道,单路节目的TS是由具有相同时间基点的PES流复用而成的,典型情况下包含一路视频PES流、多路音频PES
    流,还有teletext、subtitle等PES,各路PES的PID就在这张表中指定。因此,解析这张表就可以知道一路节目是由哪些PES组成的,其PID是多少?这样有利于解码器根据找出相应的PID,进行音视频解码。
        PMT section的header部分为8个字节,由表标识符(以区别于其他table)、section长度、节目号、版本号、section号、最后一个section号组成。紧接着会提供本节目进行收发同步参考的PCR PID,节目信息长度及其描述符(描述符会单独分析),节目所含的基本流信息。

    语法结构
      (略)
    表中:
    Table id:8bit域,在TS流中Program map section将置为0x02。
    Section syntax indicator:1bit域,对于PMT表,设置为1。
    Zero:1bit域,设置为0。
    Reserved:2bit域,预留为11(0x3)。
    Section length:12bit域,首先两位bit置为00,它指示段的byte数,由段长度域开始,包含CRC字段4个字节,因此在写解析代码时需要注意。
    Program number:16bit域,它指出该节目对应于可应用的Program map PID。一个节目定义仅含一个TS流的Progrmn
    map section。这意味着一个节目的定义不超过1016Byte。
    Reserved:2bit域,预留为11(0x3)。
    Version number:5bit域,指出TS流中Program map section的版本号。当段中有关信息发生变化,版本号将以32为
    模加1。版本号是关于一个节目的定义,因此版本号是关于单一段的定义,该字段用于service中各组成部分的信息发生更新,例如当视频PID变化。
    Current next indicator:1bit域,当该位置1时,当前传送的Program map section可用;当该位置0时,指示当前
    传送的Program map section不可用,下一个TS流的Program map section有效。
    Section number:8bit域,总是置为0x00(因为PMT表里表示一个service的信息,一个section的长度足够)。
    Last section number:8bit域,该域的值总是0x000。
    Reserved:3bit域,预留为111(0x7)。
    PCR PID:13bit域,指明TS包的PID值,该TS包含有PCR域,该PCR值对应于由节目号指定的对应节目。如果对于私有
    数据流的节目定义与PCR无关,这个域的值将为0×1FFF。
    Reserved:4bit域,预留为1111(0xF)。
    Program info length:12bit域,前两位bit为00。该域指出跟随其后对节目信息的描述的byte数。
    Stream type:8bit域,指示特定PID的节目元素包的类型。该处PID由elementary PID指定。该域值为0×2时,指示
    ITU-TRECH262|ISO/IEC13818-2video或ISO/IEC11172-2constrained parameter video stream。

    码流示例
      Program_number为0x65的TS包以及PMT如下:





    上面的数据解析如下图:







    下面一段代码用来取得PMT表的头信息,如下:
    ErrorCode_t ParsePMTHead(U8* pSectionData, PMT_HEAD *pHead)
    {
        ErrorCode_t err = NO_ERROR;

        if(NULL == pSectionData || NULL == pHead)
       {
          err = ERROR_FAME;
       }
       else
       {
          pHead->m_uTableID = pSectionData[0];  /*恒为0x02*/
          pHead->m_uSectLen = SECTION_LENGTH(pSectionData[1], pSectionData

              [2]); /*PMT section的长度*/
          pHead->m_uServiceId= USHORT_LENGTH(pSectionData[3], pSectionData

              [4]); /*节目号,program_number*/
          pHead->m_uVersion = (pSectionData[5] & 0x3E) >> 1;

          pHead->m_PCRPID = PID_LENGTH(pSectionData[8] , pSectionData
              [9]); /*PCR PID*/
         //描述符长度,循环
         pHead->m_uProgLen = SECTION_LENGTH(pSectionData[10], pSectionData

              [11]); /*节目信息的长度*/
         pHead->m_pProgData = pSectionData + 12;  /*节目信息循环开始地址*/

        //流信息长度,循环
         pHead->m_uStreamInfoLen = (pHead->m_uSectLen) - (pHead-

             >m_uProgLen) - 13; /*流描述信息长度*/
         /*流描述数据开始地址*/
         pHead->m_pStreamData = (pHead->m_pProgData) + pHead->m_uProgLen;   
       
    err = NO_ERROR;
       }
      return err;
    }


        在取得PMT表头信息后,接下来的代码主要用于获取该节目各组成部分信息,对两处描述符的解析等等,注意要随时与中间件部分的节目管理和频道管理模块联系起来。
        PMT中会包含多种描述符,如CA_descriptor、stream_identifier_descriptor等,至于具体有哪些描述符,往往需要分析实际的码流才能决定。
        此外,需要注意的是,在后一个循环对基本流的描述部分,有时候对于一个视频可能对应几个音频流,这就需要在应用层做相应的处理;此外如果包含CA_descriptor,其中的CA_PID是ECM表的PID。
  • 相关阅读:
    windows下Yarn安装与使用(两种方法)
    git配置公钥---解决码云出现git@gitee.com: Permission denied (publickey)
    npm使用国内镜像的两种方法
    【LeetCode】33. Search in Rotated Sorted Array (4 solutions)
    【LeetCode】83. Remove Duplicates from Sorted List
    【LeetCode】82. Remove Duplicates from Sorted List II
    【LeetCode】85. Maximal Rectangle
    【LeetCode】84. Largest Rectangle in Histogram
    【LeetCode】87. Scramble String
    【LeetCode】162. Find Peak Element (3 solutions)
  • 原文地址:https://www.cnblogs.com/xiatian1071/p/1981073.html
Copyright © 2011-2022 走看看