TS流解析之PMT表格解析
from:http://blog.csdn.net/xioahw/article/details/4093491
PMT結構定義:
typedef struct TS_PMT_Stream
{
?unsigned stream_type??????????????????? : 8; //指示特定PID的節(jié)目元素包的類型。該處PID由elementary PID指定
?unsigned elementary_PID??????????????????? : 13; //該域指示TS包的PID值。這些TS包含有相關的節(jié)目元素
?unsigned ES_info_length??????????????????? : 12; //前兩位bit為00。該域指示跟隨其后的描述相關節(jié)目元素的byte數(shù)
?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數(shù),由段長度域開始,包含CRC。
??? unsigned program_number??????????????????? : 16;// 指出該節(jié)目對應于可應用的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值對應于由節(jié)目號指定的對應節(jié)目。
????????????//如果對于私有數(shù)據(jù)流的節(jié)目定義與PCR無關,這個域的值將為0x1FFF。
??? unsigned reserved_4??????????????????????? : 4; //預留為0x0F
??? unsigned program_info_length??????????? : 12; //前兩位bit為00。該域指出跟隨其后對節(jié)目信息的描述的byte數(shù)。
???
?std::vector<TS_PMT_Stream> PMT_Stream;??//每個元素包含8位, 指示特定PID的節(jié)目元素包的類型。該處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數(shù)據(jù)?????????
table_id?????:0x02????????????????????????? // 8section_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(節(jié)目參考時鐘)所在TS分組的PID????????? //??13
reser ved ??????:0x0f???????????????? //4
program_info_length?????:0x000????????????? //??12
stream_type???????:0x1b??????????????????? //??8
reserved????????????0x07??????????????????//??3
elementary_PID????????:0x03 e9????//??13//該節(jié)目中包括的視頻流,音頻流等對應的TS分組的PID
reserved????????????????????:0x0f??????????//??4
ES_info_length?????????:0x000???????????????//??12
CRC??????? : 0xf0 af b4 4f
總結
以上是生活随笔為你收集整理的TS流解析之PMT表格解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TS流解析之PAT表格解析
- 下一篇: 马尔科夫链和马尔科夫随机场