分享
 
 
 

Parsing Transport stream PAT and PMT

王朝other·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

//TSStructs.h

#ifndef __TSSTRUCTS_H_LUCKYLIU_H__

#define __TSSTRUCTS_H_LUCKYLIU_H__

#include <list>

#define WW_PATPID (0x0000)

#define WW_PATTABLEID (0x00)

#define WW_PMTTABLEID (0x02)

#define WW_TSPACKET_LEN (188)

#define WW_TSSYNCBYTE (0x47)

//TSPACKET

//One ts packet is contained by TSPacketHeader, adaption field, payload data.

//If there is adaption filed, adaption field length is specified by the first byte after TSPacketHeader.

//Payload bytes length is the remained bytes.

typedef struct WW_TSPACKETHEAD_ //4 BYTES

{

unsigned char ucSyncByte; // First byte

unsigned char PID_hibits : 5; // Second byte - Notice the reverse declaration

unsigned char transport_priority : 1;

unsigned char payload_unit_start_indicator : 1;

unsigned char transport_error_indicator : 1;

unsigned char PID_lobits; // Third byte

unsigned char continuity_counter : 4; // Fourth byte

unsigned char _payload_present_flag : 1;

unsigned char _adaptation_field_present_flag : 1;

unsigned char transport_scrambling_control : 2;

} WW_TSPACKETHEAD, *PWW_TSPACKETHEAD;

//PAT

typedef struct WW_PATSECTIONHEAD_ //8 BYTES

{

unsigned char table_id;

unsigned char section_length_highbits : 4;

unsigned char reserved_twobits : 2;

unsigned char must_be_zero : 1;

unsigned char section_syntax_indicator : 1;

unsigned char section_length_lowbits;

unsigned char transport_stream_id_hi;

unsigned char transport_stream_id_lo;

unsigned char current_next_indicator : 1;

unsigned char version_number : 5;

unsigned char reserved_twobits_2 : 2;

unsigned char section_number;

unsigned char last_section_number;

} WW_PATSECTIONHEAD, *PWW_PATSECTIONHEAD;

typedef struct WW_PATSECTIONPROTRAMMAP_// 4 BYTES

{

unsigned char program_number_hi;

unsigned char program_number_lo;

unsigned char program_map_PID_highbits : 5;

unsigned char reserved : 3;

unsigned char program_map_PID_lo;

} WW_PATSECTIONPROTRAMMAP, *PWW_PATSECTIONPROTRAMMAP;

typedef std::list<WW_PATSECTIONPROTRAMMAP> WW_PATSECTIONPROTRAMMAPLIST;

//PMT

typedef struct WW_PMTSECTIONHEAD_ //12 BYTES

{

unsigned char table_id;

unsigned char section_length_highbits : 4;

unsigned char reserved_twobits : 2;

unsigned char must_be_zero : 1;

unsigned char section_syntax_indicator : 1;

unsigned char section_length_lowbits;

unsigned char program_number_hi;

unsigned char program_number_lo;

unsigned char current_next_indicator : 1;

unsigned char version_number : 5;

unsigned char reserved_twobits_2 : 2;

unsigned char section_number;

unsigned char last_section_number;

unsigned char PCR_PID_highbits : 5;

unsigned char reserved_threebits : 3;

unsigned char PCR_PID_lo;

unsigned char program_info_length_highbits : 4;

unsigned char reserved_fourbits : 4;

unsigned char program_info_length_lo;

}WW_PMTSECTIONHEAD, *PWW_PMTSECTIONHEAD;

typedef struct WW_PMTSECTIONSTREAMMAP_ //5 BYTES

{

unsigned char stream_type; //0x01 mpeg1 video; 0x02 mpeg2 video; 0x03 mpeg1 audio; 0x04 mpeg2 audio;

unsigned char elementary_PID_highbits : 5;

unsigned char reserved : 3;

unsigned char elementary_PID_lo;

unsigned char ES_info_length_hibits : 4;

unsigned char reserved2 : 4;

unsigned char ES_info_length_lo;

}WW_PMTSECTIONSTREAMMAP, *PWW_PMTSECTIONSTREAMMAP;

typedef std::list<WW_PMTSECTIONSTREAMMAP> WW_PMTSECTIONSTREAMMAPLIST;

typedef struct WW_TSPROGRAMSTREAMMAP_

{

WORD wProgramNumber;

WW_PMTSECTIONSTREAMMAPLIST lstStreamMap;

}WW_TSPROGRAMSTREAMMAP, *PWW_TSPROGRAMSTREAMMAP;

typedef std::list<WW_TSPROGRAMSTREAMMAP> WW_TSPROGRAMSTREAMMAPLIST;

typedef struct struWWTSVIDEO_

{

WORD wPID;

WORD wStreamID;

//FORMAT_MPEG2Video videoFmt;

char szFmt[32];

}WWTSVIDEO, *PWWTSVIDEO;

typedef std::list<WWTSVIDEO> WWTSVIDEOLIST;

typedef struct struWWTSAUDIO_

{

WORD wPID;

WORD wStreamID;

//FORMAT_WaveFormatEx audioFmt;

char szFmt[32];

}WWTSAUDIO, *PWWTSAUDIO;

typedef std::list<WWTSAUDIO> WWTSAUDIOLIST;

typedef struct WWTSPROGRAM_

{

WORD wProgramNumber;

WWTSVIDEOLIST lstVideo;

WWTSAUDIOLIST lstAudio;

}WWTSPROGRAM, *PWWTSPROGRAM;

typedef std::list<WWTSPROGRAM> WWTSPROGRAMLIST;

#endif

#ifndef __WWTSPACKET_H_LUCKYLIU_H__

#define __WWTSPACKET_H_LUCKYLIU_H__

#include "TSStructs.h"

class WWTSPacket

{

public:

WWTSPacket(void);

virtual ~WWTSPacket(void);

public:

BOOL Load(BYTE* pBuffer, int nLen);

virtual void Dump();

WORD GetPID();

BYTE GetTransportPriority();

BYTE GetPayloadUnitStartIndicator();

BYTE GetTransportErrorIndicator();

BYTE GetContinuityCounter();

BOOL HasPayload();

BOOL HasAdaptationField();

BYTE GetTransportScramblingControl();

PBYTE GetPayload(WORD *pwLen);

PBYTE GetAdaptationField(WORD *pwLen);

protected:

PBYTE m_pTSPacket;

};

#endif

#include "StdAfx.h"

#include ".\wwtspacket.h"

WWTSPacket::WWTSPacket(void)

{

m_pTSPacket = new BYTE[WW_TSPACKET_LEN];

}

WWTSPacket::~WWTSPacket(void)

{

delete[] m_pTSPacket;

}

BOOL WWTSPacket::Load(BYTE* pBuffer, int nLen)

{

if( nLen<WW_TSPACKET_LEN )

{

return FALSE;

}

if( *pBuffer!=WW_TSSYNCBYTE )

{

return FALSE;

}

memcpy(m_pTSPacket, pBuffer, WW_TSPACKET_LEN);

return TRUE;

}

WORD WWTSPacket::GetPID()

{

PWW_TSPACKETHEAD pTsHeader = (PWW_TSPACKETHEAD)m_pTSPacket;

return MAKEWORD( pTsHeader->PID_lobits, pTsHeader->PID_hibits );

}

BYTE WWTSPacket::GetTransportPriority()

{

PWW_TSPACKETHEAD pTsHeader = (PWW_TSPACKETHEAD)m_pTSPacket;

return pTsHeader->transport_priority;

}

BYTE WWTSPacket::GetPayloadUnitStartIndicator()

{

PWW_TSPACKETHEAD pTsHeader = (PWW_TSPACKETHEAD)m_pTSPacket;

return pTsHeader->payload_unit_start_indicator;

}

BYTE WWTSPacket::GetTransportErrorIndicator()

{

PWW_TSPACKETHEAD pTsHeader = (PWW_TSPACKETHEAD)m_pTSPacket;

return pTsHeader->transport_error_indicator;

}

BYTE WWTSPacket::GetContinuityCounter()

{

PWW_TSPACKETHEAD pTsHeader = (PWW_TSPACKETHEAD)m_pTSPacket;

return pTsHeader->continuity_counter;

}

BOOL WWTSPacket::HasPayload()

{

PWW_TSPACKETHEAD pTsHeader = (PWW_TSPACKETHEAD)m_pTSPacket;

return pTsHeader->_payload_present_flag;

}

BOOL WWTSPacket::HasAdaptationField()

{

PWW_TSPACKETHEAD pTsHeader = (PWW_TSPACKETHEAD)m_pTSPacket;

return pTsHeader->_adaptation_field_present_flag;

}

BYTE WWTSPacket::GetTransportScramblingControl()

{

PWW_TSPACKETHEAD pTsHeader = (PWW_TSPACKETHEAD)m_pTSPacket;

return pTsHeader->transport_scrambling_control;

}

PBYTE WWTSPacket::GetPayload(WORD *pwLen)

{

PBYTE pBuffer = 0;

*pwLen = 0;

PBYTE pAdaptation = 0;

WORD wLenAdaptation = 0;

PWW_TSPACKETHEAD pTsHeader = (PWW_TSPACKETHEAD)m_pTSPacket;

if( pTsHeader->_payload_present_flag )

{

pAdaptation = GetAdaptationField(&wLenAdaptation);

if( pAdaptation )

{

*pwLen = WW_TSPACKET_LEN - sizeof(WW_TSPACKETHEAD) - 1 - wLenAdaptation;

pBuffer = m_pTSPacket + sizeof(WW_TSPACKETHEAD) + 1 + wLenAdaptation;

if( *pwLen==0 )

{

pBuffer = 0;

}

}

else

{

pBuffer = m_pTSPacket + sizeof(WW_TSPACKETHEAD);

*pwLen = WW_TSPACKET_LEN - sizeof(WW_TSPACKETHEAD);

}

}

return pBuffer;

}

PBYTE WWTSPacket::GetAdaptationField(WORD *pwLen)

{

PBYTE pBuffer = 0;

*pwLen = 0;

PWW_TSPACKETHEAD pTsHeader = (PWW_TSPACKETHEAD)m_pTSPacket;

if( pTsHeader->_adaptation_field_present_flag )

{

*pwLen = ( WORD )(* (m_pTSPacket + sizeof(WW_TSPACKETHEAD)) );

pBuffer = m_pTSPacket + 1;

if( *pwLen> WW_TSPACKET_LEN-sizeof(WW_TSPACKETHEAD)-1 )

{

*pwLen = WW_TSPACKET_LEN-sizeof(WW_TSPACKETHEAD)-1;

}

}

return pBuffer;

}

void WWTSPacket::Dump()

{

}

#ifndef __WWPATPACKET_H_LUCKYLIU__

#define __WWPATPACKET_H_LUCKYLIU__

#include "wwtspacket.h"

class WWPatPacket :

public WWTSPacket

{

public:

WWPatPacket(void);

virtual ~WWPatPacket(void);

public:

BOOL Load(BYTE* pBuffer, int nLen);

void GetProgramMapList(WW_PATSECTIONPROTRAMMAPLIST* pLstProgramMap);

virtual void Dump();

protected:

WW_PATSECTIONPROTRAMMAPLIST m_lstProgramMap;

PWW_PATSECTIONHEAD m_pSectionHeader;

};

#endif

#include "StdAfx.h"

#include ".\wwpatpacket.h"

WWPatPacket::WWPatPacket(void):

m_pSectionHeader(0),

WWTSPacket()

{

}

WWPatPacket::~WWPatPacket(void)

{

}

BOOL WWPatPacket::Load(BYTE* pBuffer, int nLen)

{

//load tspacket.

if( !WWTSPacket::Load(pBuffer, nLen) )

{

return FALSE;

}

//check if this pid is pat id.

if( WWTSPacket::GetPID()!=WW_PATPID )

{

return FALSE;

}

PBYTE pPayload = 0;

PBYTE pPatPayload = 0;

WORD wPayload = 0;

WORD wPatPayload = 0;

WORD wDiff = 0;

//get pat payload buffer pointer and pat payload bytes number.

if( !WWTSPacket::HasPayload() )

{

return FALSE;

}

pPayload = WWTSPacket::GetPayload(&wPayload);

if( pPayload==0 || wPayload==0 )

{

return FALSE;

}

wDiff = (WORD)(*pPayload) + 1;//pointer_field

if( wDiff>=wPayload )

{

return FALSE;

}

pPatPayload = pPayload + wDiff;

wPatPayload = wPayload - wDiff;

int nPatPayload = wPatPayload;

//parse every pat section.

m_lstProgramMap.clear();

m_pSectionHeader = (PWW_PATSECTIONHEAD)(pPatPayload);

while( nPatPayload>=sizeof(WW_PATSECTIONHEAD)+4 )

{

PWW_PATSECTIONHEAD pPatHead = (PWW_PATSECTIONHEAD)(pPatPayload);

if( pPatHead->table_id!=0x00 ||

pPatHead->section_syntax_indicator!=0x01 ||

pPatHead->must_be_zero!=0x00 ||

//pPatHead->reserved_twobits!=0x00 ||

//pPatHead->reserved_twobits_2!=0x00 ||

pPatHead->current_next_indicator!=0x01)

{

break;

}

WORD wSecLen = MAKEWORD(pPatHead->section_length_lowbits, pPatHead->section_length_highbits);

if( wSecLen+3 > nPatPayload )

{

break;

}

WORD wPMapCount = (wSecLen - 5 - 4)/sizeof(WW_PATSECTIONPROTRAMMAP);

for( WORD wIndex = 0; wIndex<wPMapCount; wIndex++ )

{

PWW_PATSECTIONPROTRAMMAP pPMap = (PWW_PATSECTIONPROTRAMMAP)(pPatPayload+sizeof(WW_PATSECTIONHEAD)+wIndex*sizeof(WW_PATSECTIONPROTRAMMAP));

m_lstProgramMap.push_back(*pPMap);

}

pPatPayload += (wSecLen + 3);

nPatPayload -= (wSecLen + 3);

}

for( WW_PATSECTIONPROTRAMMAPLIST::iterator it = m_lstProgramMap.begin(); it!=m_lstProgramMap.end(); )

{

if( MAKEWORD(it->program_number_lo, it->program_number_hi)==0 )

{

WW_PATSECTIONPROTRAMMAPLIST::iterator itDel = it;

it++;

m_lstProgramMap.erase(itDel);

}

else

{

it++;

}

}

return TRUE;

}

void WWPatPacket::GetProgramMapList(WW_PATSECTIONPROTRAMMAPLIST* pLstProgramMap)

{

pLstProgramMap->clear();

*pLstProgramMap = m_lstProgramMap;

}

void WWPatPacket::Dump()

{

printf("PAT packet(PID=0x%.4x)\n", WWTSPacket::GetPID());

for( WW_PATSECTIONPROTRAMMAPLIST::iterator it = m_lstProgramMap.begin(); it!=m_lstProgramMap.end(); it++ )

{

printf(" Program Number: 0x%.4x, PMT PID: 0x%.4x\n", MAKEWORD(it->program_number_lo, it->program_number_hi),

MAKEWORD(it->program_map_PID_lo, it->program_map_PID_highbits) );

}

}

#ifndef __WWPMTPACKET_H_LUCKYLIU__

#define __WWPMTPACKET_H_LUCKYLIU__

#include "wwtspacket.h"

class WWPmtPacket :

public WWTSPacket

{

public:

WWPmtPacket(void);

virtual ~WWPmtPacket(void);

public:

BOOL Load(BYTE* pBuffer, int nLen);

void GetProgramStreamMap(WW_TSPROGRAMSTREAMMAPLIST* pProgramStreamMapList);

virtual void Dump();

protected:

WW_TSPROGRAMSTREAMMAPLIST m_lstProgramStreamMap;

};

#endif

#include "StdAfx.h"

#include ".\wwpmtpacket.h"

WWPmtPacket::WWPmtPacket(void):

WWTSPacket()

{

}

WWPmtPacket::~WWPmtPacket(void)

{

}

BOOL WWPmtPacket::Load(BYTE* pBuffer, int nLen)

{

m_lstProgramStreamMap.clear();

if( !WWTSPacket::Load(pBuffer, nLen) )

{

return FALSE;

}

if( !WWTSPacket::HasPayload() )

{

return FALSE;

}

PBYTE pPayload = 0, pPmtPayload = 0;

WORD wPayload = 0, wPmtPayload = 0, wDiff = 0;

pPayload = WWTSPacket::GetPayload(&wPayload);

if( pPayload==NULL || wPayload==0 )

{

return FALSE;

}

wDiff = (WORD)(*pPayload) + 1;

if( wDiff>=wPayload )

{

return FALSE;

}

pPmtPayload = pPayload + wDiff;

wPmtPayload = wPayload - wDiff;

int nPmtPayload = wPmtPayload;

BOOL bSuccessful = TRUE;

while( nPmtPayload >= 12+4 && bSuccessful)//sizeof(WW_PMTSECTIONHEAD)

{

PWW_PMTSECTIONHEAD pHeader = (PWW_PMTSECTIONHEAD)pPmtPayload;

if( pHeader->table_id!=0x02 ||

pHeader->section_syntax_indicator!=0x01 ||

pHeader->must_be_zero!=0x00 ||

pHeader->current_next_indicator!=0x01 )

{

break;

}

WORD wSecLen = MAKEWORD( pHeader->section_length_lowbits, pHeader->section_length_highbits);

WORD wProLen = MAKEWORD( pHeader->program_info_length_lo, pHeader->program_info_length_highbits);

if( wSecLen+3>nPmtPayload )

{

break;

}

if( wProLen+9+4>wSecLen )

{

break;

}

WW_TSPROGRAMSTREAMMAP mapProStrm;

mapProStrm.wProgramNumber = MAKEWORD( pHeader->program_number_lo, pHeader->program_number_hi);

WORD wStreamMapLen = wSecLen - 9 -4 - wProLen;

PBYTE pMap = pPmtPayload + 12 + wProLen;//sizeof(PWW_PMTSECTIONHEAD)

while( wStreamMapLen>=5 )

{

PWW_PMTSECTIONSTREAMMAP pStreamMap = (PWW_PMTSECTIONSTREAMMAP)pMap;

WORD wInfoLen = MAKEWORD( pStreamMap->ES_info_length_lo, pStreamMap->ES_info_length_hibits);

if( wInfoLen+5>wStreamMapLen )

{

bSuccessful = FALSE;

break;

}

mapProStrm.lstStreamMap.push_back( *pStreamMap );

wStreamMapLen = wStreamMapLen - 5 - wInfoLen;

pMap = pMap + 5 + wInfoLen;

}

if( bSuccessful )

{

m_lstProgramStreamMap.push_back( mapProStrm );

pPmtPayload = pPmtPayload + 3 + wSecLen;

nPmtPayload = nPmtPayload - (3 + wSecLen);

}

else

{

break;

}

}

return TRUE;

}

void WWPmtPacket::GetProgramStreamMap(WW_TSPROGRAMSTREAMMAPLIST* pProgramStreamMapList)

{

pProgramStreamMapList->clear();

*pProgramStreamMapList = m_lstProgramStreamMap;

}

void WWPmtPacket::Dump()

{

printf("PMT packet(PID=0x%.4x)\n", WWTSPacket::GetPID());

for( WW_TSPROGRAMSTREAMMAPLIST::iterator it = m_lstProgramStreamMap.begin(); it!=m_lstProgramStreamMap.end(); it++ )

{

printf(" Program number: 0x%.4x\n", it->wProgramNumber);

for( WW_PMTSECTIONSTREAMMAPLIST::iterator itt = it->lstStreamMap.begin(); itt!=it->lstStreamMap.end(); itt++ )

{

printf(" PID: 0x%.4x, Stream Type: 0x%.4x\n", MAKEWORD(itt->elementary_PID_lo, itt->elementary_PID_highbits),

itt->stream_type);

}

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有