TS流解析之PMT表格解析

來源:互聯網
上載者:User

 

PMT結構定義:

typedef struct TS_PMT_Stream
{
 unsigned stream_type                    : 8; //指示特定PID的節目元素包的類型。該處PID由elementary PID指定
 unsigned elementary_PID                    : 13; //該域指示TS包的PID值。這些TS包含有相關的節目元素
 unsigned ES_info_length                    : 12; //前兩位bit為00。該域指示跟隨其後的描述相關節目元素的byte數
 unsigned descriptor;
}TS_PMT_Stream;

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

 

解析代碼為:

HRESULT CTS_Stream_Parse::adjust_PMT_table ( TS_PMT * packet, unsigned char * buffer )
{
    packet->table_id                            = buffer[0];
    packet->section_syntax_indicator            = buffer[1] >> 7;
    packet->zero                                = buffer[1] >> 6 & 0x01;
    packet->reserved_1                            = buffer[1] >> 4 & 0x03;
    packet->section_length                        = (buffer[1] & 0x0F) << 8 | buffer[2];   
    packet->program_number                        = 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];
    packet->reserved_3                            = buffer[8] >> 5;
    packet->PCR_PID                                = ((buffer[8] << 8) | buffer[9]) & 0x1FFF;

 PCRID = packet->PCR_PID;

    packet->reserved_4                            = buffer[10] >> 4;
    packet->program_info_length                    = (buffer[10] & 0x0F) << 8 | buffer[11];
    // Get CRC_32
 int len = 0;
    len = packet->section_length + 3;   
    packet->CRC_32                = (buffer[len-4] & 0x000000FF) << 24
  | (buffer[len-3] & 0x000000FF) << 16
  | (buffer[len-2] & 0x000000FF) << 8
  | (buffer[len-1] & 0x000000FF);

 int pos = 12;
    // program info descriptor
    if ( packet->program_info_length != 0 )
        pos += packet->program_info_length;   
    // Get stream type and PID   
    for ( ; pos <= (packet->section_length + 2 ) -  4; )
    {
  TS_PMT_Stream pmt_stream;
  pmt_stream.stream_type =  buffer[pos];
  packet->reserved_5  =   buffer[pos+1] >> 5;
  pmt_stream.elementary_PID =  ((buffer[pos+1] << 8) | buffer[pos+2]) & 0x1FFF;
  packet->reserved_6     =   buffer[pos+3] >> 4;
  pmt_stream.ES_info_length =   (buffer[pos+3] & 0x0F) << 8 | buffer[pos+4];
  
  pmt_stream.descriptor = 0x00;
  if (pmt_stream.ES_info_length != 0)
  {
   pmt_stream.descriptor = buffer[pos + 5];
   
   for( int len = 2; len <= pmt_stream.ES_info_length; len ++ )
   {
    pmt_stream.descriptor = pmt_stream.descriptor<< 8 | buffer[pos + 4 + len];
   }
   pos += pmt_stream.ES_info_length;
  }
  pos += 5;
  packet->PMT_Stream.push_back( pmt_stream );
  TS_Stream_type.push_back( pmt_stream );
    }
 return 0;
}

舉例如下:

0x47 0x43 0xe8 0x12 0x00 0x02 0xb0 0x12 0x00 0x01 0xc1 0x00 0x00 0xe3 0xe9 0xf0 0x00  0x1b 0xe3 0xe9 0xf0 0x00 0xf0 0xaf 0xb4 0x4f 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff

TS頭部

sync_byte   :0x47
transport_error_indicator: 0x00
payload_unit_start_indicator: 0x01
transport_priority  : 0x00

  PID                     :0x03e8
transport_scrambling_control  :0x00
adaptation_field_control  :0x01                                     

continuity_counter   :0x02

 

PMT資料         

table_id     :0x02                          // 8
section_syntax_indicator  :0x01            //  1
'0'                :0x00                   //  1
reserved       :0x03                       //  2
section_length :      0x012                 //  12
program_number    :0x00 01                    //  16
reserved               :0x03               //  2
version_number    :0x00                    //  5
current_next_indicator   0x01             //  1
section_number      :0x00                  //  8
last_section_number    :0x00               //  8
reserved                   0x07           //  3
PCR_PID           :0x03 e9   // PCR(節目參考時鐘)所在TS分組的PID          //  13
reserved       :0x0f                 //4
program_info_length     :0x000              //  12
stream_type       :0x1b                    //  8
reserved            0x07                  //  3
elementary_PID        :0x03 e9    //  13//該節目中包括的視頻流,音頻流等對應的TS分組的PID
reserved                    :0x0f          //  4
ES_info_length         :0x000               //  12
CRC        : 0xf0 af b4 4f

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.