之前把TS基本头信息解析出来,接下去要把TS拓展头部分解析出来
这里是调整字段的语法
然后根据语法定义结构体
ts_adaptation_filed.h
#ifndef __TS_ADAPTATION_FIELD_H__ #define __TS_ADAPTATION_FIELD_H__ #include "ts_base.h" /************************************************************************/ /* Adaptation_field_extension */ /************************************************************************/ typedef struct { bool bLtw_valid_flag; short sLtw_offset; }AFE_LTW_S; typedef struct { char cReserved; int nPiecewise_rate; }AFE_PIECEWISE_RATE_S; typedef struct { char cSplice_type; char cDTS_next_au_one; bool bMarker_bit_one; short sDTS_next_au_two; bool bMarker_bit_two; short sDTS_next_au_three; bool bMarker_bit_three; }AFE_SEAMLESS_SPLICE_S; typedef struct { unsigned char cLength; bool bLtw_flag; bool bPiecewise_rate_flag; bool bSeamless_splice_flag; char cReserved; AFE_LTW_S* pLtw; AFE_PIECEWISE_RATE_S* pPieceWise; AFE_SEAMLESS_SPLICE_S* pSeamless; }ADAPTATION_FIELD_EXTENSION_S; /************************************************************************/ /* Adaptation_field */ /************************************************************************/ typedef struct { unsigned int nPCRbase; bool bPCRbaseTailbit; char cReserved; short nPCRextension; }AF_PCR_S; typedef struct { unsigned int nOPCRbase; bool bOPCRbaseTailbit; char cReserved; short nOPCRextension; }AF_OPCR_S; typedef struct { unsigned char cTSPrivate_data_length; char* pPrivateDataBuffer; }AF_PRIVATEDATA_S; typedef struct { unsigned char cLength; bool bDiscontinuity; bool bRandom_access; bool bElementary_stream_priority; bool bPCR_flag; bool bOPCR_flag; bool bSplicing_point_flag; bool bTransport_private_data_flag; bool bAdaptation_field_extension_flag; AF_PCR_S* pPCR; AF_OPCR_S* pOPCR; char cSplice_countdown; AF_PRIVATEDATA_S* pPrivateData; ADAPTATION_FIELD_EXTENSION_S* pAFExtension; }TS_ADAPTATION_FIELD_HEADER_S; /************************************************************************/ /* Function Declare */ /************************************************************************/ TS_ADAPTATION_FIELD_HEADER_S* ParserAdaptationFieldHeader(const char* pAFBuffer); void FreeAdaptationFieldHeader(TS_ADAPTATION_FIELD_HEADER_S** pHeader); #endif
ts_adaptation_field.cpp
#include "ts_adaptation_filed.h" #pragma warning(disable:4800) /************************************************************************/ /* Local Function Declare */ /************************************************************************/ static AF_PCR_S* GetPCR(const char* pBuffer); static AF_OPCR_S* GetOPCR(const char* pBuffer); static char GetSpliceCountdown(const char* pBuffer); static AF_PRIVATEDATA_S* GetPrivateData(const char* pBuffer); static ADAPTATION_FIELD_EXTENSION_S* GetAFExtension(const char* pBuffer); static void FreeAFExtension(ADAPTATION_FIELD_EXTENSION_S* pAFExtension); static AFE_LTW_S* GetLtw(const char* pBuffer); static AFE_PIECEWISE_RATE_S* GetPiecewise(const char* pBuffer); static AFE_SEAMLESS_SPLICE_S* GetSeamless(const char* pBuffer); /************************************************************************/ /* Interface Implement */ /************************************************************************/ TS_ADAPTATION_FIELD_HEADER_S* ParserAdaptationFieldHeader(const char* pBuffer) { TS_ADAPTATION_FIELD_HEADER_S* pAFHReturn = NULL; do { if(pBuffer == NULL) { break; } pAFHReturn = (TS_ADAPTATION_FIELD_HEADER_S*)malloc(sizeof(TS_ADAPTATION_FIELD_HEADER_S)); pAFHReturn->pPCR = NULL; pAFHReturn->pOPCR = NULL; pAFHReturn->pPrivateData = NULL; pAFHReturn->pAFExtension = NULL; char cByte; int nIndex = 0; pAFHReturn->cLength = pBuffer[0] & 0x00FF; if(pAFHReturn->cLength > 0) { cByte = pBuffer[1]; pAFHReturn->bDiscontinuity = cByte & AND_HIGHFIRSTBIT; pAFHReturn->bRandom_access = cByte & AND_HIGHSECONDBIT; pAFHReturn->bElementary_stream_priority = cByte & AND_HIGHTHIRDBIT; pAFHReturn->bPCR_flag = cByte & AND_HIGHFORTHBIT; pAFHReturn->bOPCR_flag = cByte & AND_LOWFIRSTBIT; pAFHReturn->bSplicing_point_flag = cByte & AND_LOWSECONDBIT; pAFHReturn->bTransport_private_data_flag = cByte & AND_LOWTHIRDBIT; pAFHReturn->bAdaptation_field_extension_flag = cByte & AND_LOWFORTHBIT; } nIndex += 2; if(pAFHReturn->bPCR_flag) { pAFHReturn->pPCR = GetPCR(pBuffer + nIndex); nIndex += 6; } if(pAFHReturn->bOPCR_flag) { pAFHReturn->pOPCR = GetOPCR(pBuffer + nIndex); nIndex += 6; } if(pAFHReturn->bSplicing_point_flag) { pAFHReturn->cSplice_countdown = GetSpliceCountdown(pBuffer + nIndex); nIndex += 1; } if(pAFHReturn->bTransport_private_data_flag) { pAFHReturn->pPrivateData = GetPrivateData(pBuffer + nIndex); if(pAFHReturn->pPrivateData != NULL) { nIndex += pAFHReturn->pPrivateData->cTSPrivate_data_length + 1; } } if(pAFHReturn->bAdaptation_field_extension_flag) { pAFHReturn->pAFExtension = GetAFExtension(pBuffer + nIndex); } } while (0); return pAFHReturn; } void FreeAdaptationFieldHeader(TS_ADAPTATION_FIELD_HEADER_S** pHeader) { if(pHeader != NULL && *pHeader != NULL) { TS_ADAPTATION_FIELD_HEADER_S* pHeaderIndeed = *pHeader; if(pHeaderIndeed->pPCR != NULL) { free(pHeaderIndeed->pPCR); pHeaderIndeed->pPCR = NULL; } if(pHeaderIndeed->pOPCR != NULL) { free(pHeaderIndeed->pOPCR); pHeaderIndeed->pOPCR = NULL; } if(pHeaderIndeed->pPrivateData != NULL) { free(pHeaderIndeed->pPrivateData); pHeaderIndeed->pPrivateData = NULL; } if(pHeaderIndeed->pAFExtension != NULL) { FreeAFExtension(pHeaderIndeed->pAFExtension); free(pHeaderIndeed->pAFExtension); pHeaderIndeed->pAFExtension = NULL; } free(pHeaderIndeed); *pHeader = NULL; } } /************************************************************************/ /* Local Function Implement */ /************************************************************************/ static AF_PCR_S* GetPCR(const char* pBuffer) { AF_PCR_S* pPCRReturn = NULL; do { if(pBuffer == NULL) { break; } pPCRReturn = (AF_PCR_S*)malloc(sizeof(AF_PCR_S)); char cByte = pBuffer[4]; pPCRReturn->nPCRbase = pBuffer[0]; pPCRReturn->nPCRbase = ((pPCRReturn->nPCRbase << 8) & 0x0000FF00) + (pBuffer[1] & 0x00FF); pPCRReturn->nPCRbase = ((pPCRReturn->nPCRbase << 8) & 0x00FFFF00) + (pBuffer[2] & 0x00FF); pPCRReturn->nPCRbase = ((pPCRReturn->nPCRbase << 8) & 0xFFFFFF00) + (pBuffer[3] & 0x00FF); pPCRReturn->bPCRbaseTailbit = cByte & 0x80; pPCRReturn->cReserved = ((cByte & 0x7E) >> 1) & 0x3F; pPCRReturn->nPCRextension = cByte & 0x01; pPCRReturn->nPCRextension = (pPCRReturn->nPCRextension << 8) & 0x0000FF00; pPCRReturn->nPCRextension += (pBuffer[5] & 0x00FF); } while (0); return pPCRReturn; } static AF_OPCR_S* GetOPCR(const char* pBuffer) { AF_OPCR_S* pOPCRReturn = NULL; do { if(pBuffer == NULL) { break; } pOPCRReturn = (AF_OPCR_S*)malloc(sizeof(AF_OPCR_S)); char cByte = pBuffer[4]; pOPCRReturn->nOPCRbase = pBuffer[0]; pOPCRReturn->nOPCRbase = ((pOPCRReturn->nOPCRbase << 8) & 0x0000FF00) + (pBuffer[1] & 0x00FF); pOPCRReturn->nOPCRbase = ((pOPCRReturn->nOPCRbase << 8) & 0x00FFFF00) + (pBuffer[2] & 0x00FF); pOPCRReturn->nOPCRbase = ((pOPCRReturn->nOPCRbase << 8) & 0xFFFFFF00) + (pBuffer[3] & 0x00FF); pOPCRReturn->bOPCRbaseTailbit = cByte & 0x80; pOPCRReturn->cReserved = ((cByte & 0x7E) >> 1) & 0x3F; pOPCRReturn->nOPCRextension = cByte & 0x01; pOPCRReturn->nOPCRextension = (pOPCRReturn->nOPCRextension << 8) & 0x0000FF00; pOPCRReturn->nOPCRextension += (pBuffer[5] & 0x00FF); } while (0); return pOPCRReturn; } static char GetSpliceCountdown(const char* pBuffer) { char cSpliceCountdown = pBuffer[0] & 0x00FF; return cSpliceCountdown; } static AF_PRIVATEDATA_S* GetPrivateData(const char* pBuffer) { AF_PRIVATEDATA_S* pPriavteData = NULL; do { if(pBuffer == NULL) { break; } pPriavteData = (AF_PRIVATEDATA_S*)malloc(sizeof(AF_PRIVATEDATA_S)); pPriavteData->cTSPrivate_data_length = pBuffer[0] & 0x00FF; pPriavteData->pPrivateDataBuffer = (char*)((int)pBuffer + 1); } while (0); return pPriavteData; } /************************************************************************/ /* Adaptation field extension */ /************************************************************************/ static ADAPTATION_FIELD_EXTENSION_S* GetAFExtension(const char* pBuffer) { ADAPTATION_FIELD_EXTENSION_S* pAFExtension = NULL; do { if(pBuffer == NULL) { break; } char cByte = pBuffer[1]; int nIndex = 0; pAFExtension = (ADAPTATION_FIELD_EXTENSION_S*)malloc(sizeof(ADAPTATION_FIELD_EXTENSION_S)); pAFExtension->cLength = pBuffer[0] & 0x00FF; pAFExtension->bLtw_flag = cByte & AND_HIGHFIRSTBIT; pAFExtension->bPiecewise_rate_flag = cByte & AND_HIGHSECONDBIT; pAFExtension->bSeamless_splice_flag = cByte & AND_HIGHTHIRDBIT; pAFExtension->cReserved = cByte & 0x1F; pAFExtension->pLtw = NULL; pAFExtension->pPieceWise = NULL; pAFExtension->pSeamless = NULL; nIndex += 2; if(pAFExtension->bLtw_flag) { pAFExtension->pLtw = GetLtw(pBuffer + nIndex); nIndex += 2; } if(pAFExtension->bPiecewise_rate_flag) { pAFExtension->pPieceWise = GetPiecewise(pBuffer + nIndex); nIndex += 3; } if(pAFExtension->bSeamless_splice_flag) { pAFExtension->pSeamless = GetSeamless(pBuffer + nIndex); } } while (0); return pAFExtension; } static void FreeAFExtension(ADAPTATION_FIELD_EXTENSION_S* pAFExtension) { if(pAFExtension != NULL) { if(pAFExtension->pLtw != NULL) { free(pAFExtension->pLtw); pAFExtension->pLtw = NULL; } if(pAFExtension->pPieceWise != NULL) { free(pAFExtension->pPieceWise); pAFExtension->pPieceWise = NULL; } if(pAFExtension->pSeamless != NULL) { free(pAFExtension->pSeamless); pAFExtension->pSeamless = NULL; } } } static AFE_LTW_S* GetLtw(const char* pBuffer) { AFE_LTW_S* pLtw = NULL; do { if(pBuffer == NULL) { break; } char cByte = pBuffer[0]; pLtw = (AFE_LTW_S*)malloc(sizeof(AFE_LTW_S)); pLtw->bLtw_valid_flag = cByte & AND_HIGHFIRSTBIT; pLtw->sLtw_offset = cByte & 0x7F; pLtw->sLtw_offset = pLtw->sLtw_offset & 0x00FF; pLtw->sLtw_offset = pLtw->sLtw_offset << 8; pLtw->sLtw_offset = pLtw->sLtw_offset + (pBuffer[1] & 0x00FF); } while (0); return pLtw; } static AFE_PIECEWISE_RATE_S* GetPiecewise(const char* pBuffer) { AFE_PIECEWISE_RATE_S* pPicecewise = NULL; do { if(pBuffer == NULL) { break; } char cByte = pBuffer[0]; pPicecewise = (AFE_PIECEWISE_RATE_S*)malloc(sizeof(AFE_PIECEWISE_RATE_S)); pPicecewise->cReserved = cByte & 0xC0; pPicecewise->nPiecewise_rate = cByte & 0x3F; pPicecewise->nPiecewise_rate = pPicecewise->nPiecewise_rate << 8; pPicecewise->nPiecewise_rate = pPicecewise->nPiecewise_rate & 0x0000FF00; pPicecewise->nPiecewise_rate = pPicecewise->nPiecewise_rate + (pBuffer[1] & 0x00FF); pPicecewise->nPiecewise_rate = pPicecewise->nPiecewise_rate << 8; pPicecewise->nPiecewise_rate = pPicecewise->nPiecewise_rate & 0x00FFFF00; pPicecewise->nPiecewise_rate = pPicecewise->nPiecewise_rate + (pBuffer[2] & 0x00FF); } while (0); return pPicecewise; } static AFE_SEAMLESS_SPLICE_S* GetSeamless(const char* pBuffer) { AFE_SEAMLESS_SPLICE_S* pSeamless = NULL; do { if(pBuffer == NULL) { break; } char cByte = pBuffer[0]; pSeamless = (AFE_SEAMLESS_SPLICE_S*)malloc(sizeof(AFE_SEAMLESS_SPLICE_S)); pSeamless->cSplice_type = cByte & 0x00F0; pSeamless->cSplice_type = pSeamless->cSplice_type >> 4; pSeamless->cSplice_type = pSeamless->cSplice_type & 0x000F; pSeamless->cDTS_next_au_one = cByte & 0x0E; pSeamless->cDTS_next_au_one = pSeamless->cDTS_next_au_one >> 1; pSeamless->cDTS_next_au_one = pSeamless->cDTS_next_au_one & 0x07; pSeamless->bMarker_bit_one = cByte & AND_LOWFORTHBIT; cByte = pBuffer[1]; pSeamless->sDTS_next_au_two = cByte & 0x00FF; pSeamless->sDTS_next_au_two = pSeamless->sDTS_next_au_two << 7; cByte = pBuffer[2] & 0x00FE; cByte = cByte >> 1; cByte = cByte & 0x007F; pSeamless->sDTS_next_au_two = pSeamless->sDTS_next_au_two + cByte; pSeamless->bMarker_bit_two = pBuffer[2] & AND_LOWFORTHBIT; cByte = pBuffer[3]; pSeamless->sDTS_next_au_three = cByte & 0x00FF; pSeamless->sDTS_next_au_three = pSeamless->sDTS_next_au_three << 7; cByte = pBuffer[4] & 0x00FE; cByte = cByte >> 1; cByte = cByte & 0x007F; pSeamless->sDTS_next_au_three = pSeamless->sDTS_next_au_three + cByte; pSeamless->bMarker_bit_three = pBuffer[4] & AND_LOWFORTHBIT; } while (0); return pSeamless; } #pragma warning(default:4800)
还是那句话,要小心位运算,而且小心符号位的运算
如果更想做好平台性移植,那么可以将类型封装一下,用自己的类型进行处理
测试包
测试结果
剩下来就是完成pes分组的解析,然后就是对于es包的解析
看着协议,一步步来,做解析工具就是时间问题而已