TS流解析之PMT表格解析(轉)
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
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
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/a31898534/archive/2009/08/01/4399374.aspx
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/24790158/viewspace-1041564/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- TS流解析之PAT表格解析(轉)
- TS流解析之TS包頭解析(轉)
- ffmpeg——TS流解析
- 關於TS流的解析
- JS 位元組流 解析JS
- Dubbo 3 之 Triple 流控反壓原理解析
- ORACLE SQL解析之硬解析和軟解析OracleSQL
- Nginx(六):配置解析之location解析Nginx
- Java中使用Jsoup解析HTML表格教程JavaJSHTML
- 解析static!(轉)
- xml解析之domXML
- CString解析[轉]
- 解析#pragma指令 (轉)
- Dns解析(上) (轉)DNS
- Dns解析(下) (轉)DNS
- java流的中間操作原始碼解析Java原始碼
- DOM4J 解析 XML 之忽略轉義字元XML字元
- 玩轉“網路上的芳鄰”之DNS解析(二)DNS
- python之XML解析PythonXML
- 【node】模組解析之 httpHTTP
- Flutter 之資料解析Flutter
- NoSQL之Redis配置解析SQLRedis
- ISO檔案解析(轉)
- 轉:jQuery Ajax 全解析jQuery
- 硬碟加密--解析二 (轉)硬碟加密
- 硬碟加密----解析三 (轉)硬碟加密
- java實現將excel表格資料解析成JSONArrayJavaExcelJSON
- Burpsuite中protobuf資料流的解析UI
- Node.js Stream(流) 簡單易懂全解析Node.js
- 例項解析防抖動和節流閥
- Flutter之Future原理解析Flutter
- vue之mvvm原理解析VueMVVM
- SpringCloud解析之Zuul(二)SpringGCCloudZuul
- SpringCloud解析之Zuul(一)SpringGCCloudZuul
- jQuery原始碼解析之clone()jQuery原始碼
- jQuery原始碼解析之position()jQuery原始碼
- Vue原始碼解析之parseVue原始碼
- LevelDB 原始碼解析之 Arena原始碼