根据数字电视传输流标准,编写解析工具(二)

之前把TS基本头信息解析出来,接下去要把TS拓展头部分解析出来

根据数字电视传输流标准,编写解析工具(二)_第1张图片

根据数字电视传输流标准,编写解析工具(二)_第2张图片

这里是调整字段的语法

然后根据语法定义结构体

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)


还是那句话,要小心位运算,而且小心符号位的运算

如果更想做好平台性移植,那么可以将类型封装一下,用自己的类型进行处理

测试包

根据数字电视传输流标准,编写解析工具(二)_第3张图片

测试结果

根据数字电视传输流标准,编写解析工具(二)_第4张图片

 

剩下来就是完成pes分组的解析,然后就是对于es包的解析

看着协议,一步步来,做解析工具就是时间问题而已

你可能感兴趣的:(function,struct,header,null,工具,extension)