HEVC熵解码代码分析—重写熵解码(3)

在HM代码中熵解码的部分写得比较复杂,通过分析后,用C代码重写了熵解码的部分,思路会更加清晰一些

数据结构:

typedef struct ContextModel
{
	HEVC_UINT8 State;
	HEVC_UINT32 BinsCoded;
}ContextModel;

typedef struct ContextModel3D
{
	ContextModel* pContextModel; ///< array of context models
	HEVC_UINT32 SizeX;  ///< X size of 3D buffer
	HEVC_UINT32 SizeXY;  ///< X times Y size of 3D buffer
	HEVC_UINT32 SizeXYZ;  ///< total size of 3D buffer
}ContextModel3D;

typedef struct CABACModel {
	ContextModel3D CUSplitFlagSCModel;
	ContextModel3D CUSkipFlagSCModel;
	ContextModel3D CUMergeFlagExtSCModel;
	ContextModel3D CUMergeIdxExtSCModel;
	ContextModel3D CUPartSizeSCModel;
	ContextModel3D CUPredModeSCModel;
	ContextModel3D CUIntraPredSCModel;
	ContextModel3D CUChromaPredSCModel;
	ContextModel3D CUDeltaQpSCModel;
	ContextModel3D CUInterDirSCModel;
	ContextModel3D CURefPicSCModel;
	ContextModel3D CUMvdSCModel;
	ContextModel3D CUQtCbfSCModel;
	ContextModel3D CUTransSubdivFlagSCModel;
	ContextModel3D CUQtRootCbfSCModel;
	ContextModel3D CUSigCoeffGroupSCModel;
	ContextModel3D CUSigSCModel;
	ContextModel3D CuCtxLastXModel;
	ContextModel3D CuCtxLastYModel;
	ContextModel3D CUOneSCModel;
	ContextModel3D CUAbsSCModel;
	ContextModel3D MVPIdxSCModel;
	ContextModel3D SaoMergeSCModel;
	ContextModel3D SaoTypeIdxSCModel;
	ContextModel3D TransformSkipSCModel;
	ContextModel3D CUTransquantBypassFlagSCModel;
	ContextModel3D explicitRdpcmFlagSCModel;
	ContextModel3D explicitRdpcmDirSCModel;
	ContextModel3D IntraBCPredFlagSCModel;
	ContextModel3D CrossComponentPredictionSCModel;
	ContextModel3D ChromaQpAdjFlagSCModel;
	ContextModel3D ChromaQpAdjIdcSCModel;
	ContextModel3D CUColourTransformFlagSCModel;
	ContextModel3D IntraBCBVDSCModel;
	ContextModel3D PLTModeFlagSCModel;
	ContextModel3D SPointSCModel;
	ContextModel3D CopyTopRunSCModel;
	ContextModel3D RunSCModel;
	ContextModel3D PLTSharingModeFlagSCModel;
	ContextModel3D PLTScanRotationModeFlagSCModel;  

}CABACModel;

解码环境:

//<------------------CABAC解码解码环境变量----------------//
typedef struct DecCABACEnviro
{
	HEVC_UINT32 Range;
	HEVC_UINT32 Value;
	HEVC_INT32 BitsNeeded;
}DecCABACEnviro;

上下文模式的数据结构在Slice结构中进行声明:

	<pre name="code" class="cpp">typedef struct sliceInfo{

ContextModel contextModesls[MAX_NUM_CTX_MOD];CABACModel pCABACModel;DecCABACEnviro decCABACEnviro;HEVC_UINT32 GolombRiceAdaptationStatistics[RExt__GOLOMB_RICE_ADAPTATION_STATISTICS_SETS];}SLICEINFO;


在一个slice开始解码的时候进行初始化:

InitCABACModel(pSlice->contextModesls,&pSlice->pCABACModel);

ResetEntropy(pSlice,pImg);

void InitContextModel(ContextModel *pContextModel)
{
	pContextModel->BinsCoded = 0;
	pContextModel->State = 0;
}
void InitContextModel3D(ContextModel3D *pContextModel3D,HEVC_UINT32 SizeZ, HEVC_UINT32 SizeY, HEVC_UINT32 SizeX, ContextModel *basePtr,HEVC_UINT32 *ModelIndex)
{
	pContextModel3D->pContextModel = basePtr;
	InitContextModel(pContextModel3D->pContextModel);
	pContextModel3D->SizeX = SizeX;
	pContextModel3D->SizeXY = SizeX*SizeY;
	pContextModel3D->SizeXYZ = SizeX*SizeY*SizeZ;
	*ModelIndex += pContextModel3D->SizeXYZ;
}
<strong>void InitCABACModel(ContextModel *basePtr,CABACModel * pCABACModel)</strong>
{
	HEVC_UINT32 ModelIndex = 0;
	InitContextModel3D(&pCABACModel->CUSplitFlagSCModel,1,1,NUM_SPLIT_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUSkipFlagSCModel,1,1,NUM_SKIP_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUMergeFlagExtSCModel,1,1,NUM_MERGE_FLAG_EXT_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUMergeIdxExtSCModel,1,1,NUM_MERGE_IDX_EXT_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUPartSizeSCModel,1,1,NUM_PART_SIZE_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUPredModeSCModel,1,1,NUM_PRED_MODE_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUIntraPredSCModel,1,1,NUM_ADI_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUChromaPredSCModel,1,1,NUM_CHROMA_PRED_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUDeltaQpSCModel,1,1,NUM_DELTA_QP_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUInterDirSCModel,1,1,NUM_INTER_DIR_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CURefPicSCModel,1,1,NUM_REF_NO_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUMvdSCModel,1,1,NUM_MV_RES_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUQtCbfSCModel,1,NUM_QT_CBF_CTX_SETS,NUM_QT_CBF_CTX_PER_SET,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUTransSubdivFlagSCModel,1,1,NUM_TRANS_SUBDIV_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUQtRootCbfSCModel,1,1,NUM_QT_ROOT_CBF_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUSigCoeffGroupSCModel,1,2,NUM_SIG_CG_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUSigSCModel,1,1,NUM_SIG_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CuCtxLastXModel,1,NUM_CTX_LAST_FLAG_SETS,NUM_CTX_LAST_FLAG_XY,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CuCtxLastYModel,1,NUM_CTX_LAST_FLAG_SETS,NUM_CTX_LAST_FLAG_XY,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUOneSCModel,1,1,NUM_ONE_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUAbsSCModel,1,1,NUM_ABS_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->MVPIdxSCModel,1,1,NUM_MVP_IDX_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->SaoMergeSCModel,1,1,NUM_SAO_MERGE_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->SaoTypeIdxSCModel,1,1,NUM_SAO_TYPE_IDX_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->TransformSkipSCModel,1,2,NUM_TRANSFORMSKIP_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUTransquantBypassFlagSCModel,1,1,NUM_CU_TRANSQUANT_BYPASS_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->explicitRdpcmFlagSCModel,1,2,NUM_EXPLICIT_RDPCM_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->explicitRdpcmDirSCModel,1,2,NUM_EXPLICIT_RDPCM_DIR_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->IntraBCPredFlagSCModel,1,1,NUM_INTRABC_PRED_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CrossComponentPredictionSCModel,1,1,NUM_CROSS_COMPONENT_PREDICTION_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->ChromaQpAdjFlagSCModel,1,1,NUM_CHROMA_QP_ADJ_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->ChromaQpAdjIdcSCModel,1,1,NUM_CHROMA_QP_ADJ_IDC_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CUColourTransformFlagSCModel,1,1,NUM_COLOUR_TRANS_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->IntraBCBVDSCModel,1,1,NUM_INTRABC_BVD_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->PLTModeFlagSCModel,1,1,NUM_PLTMODE_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->SPointSCModel,1,1,NUM_SPOINT_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->CopyTopRunSCModel,1,1,NUM_TOP_RUN_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->RunSCModel,1,1,NUM_LEFT_RUN_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->PLTSharingModeFlagSCModel,1,1,NUM_PLT_REUSE_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
	InitContextModel3D(&pCABACModel->PLTScanRotationModeFlagSCModel,1,1,NUM_SCAN_ROTATION_FLAG_CTX,basePtr+ModelIndex,&ModelIndex);
}
<strong>void ResetEntropy(SLICEINFO *pSlice,IMGINFO *pImg)</strong>
{
	SliceType sliceType = pSlice->sliceType;
	HEVC_UINT8 sliceQP = pSlice->iSliceQp;
	HEVC_UINT32 i = 0;
	if (pImg->pps.cabacInitPresentFlag && pSlice->cabacInitFlag)
	{
		switch (sliceType)
		{
		case B_SLICE: // change initialization table to P_SLICE initialization
			sliceType = P_SLICE;
			break;
		case P_SLICE:// change initialization table to B_SLICE initialization
			sliceType = B_SLICE;
			break;
		default:
			printf("decode error, should not occur");
			break;
		}
	}
	InitCABACModelBuffur(&pSlice->pCABACModel.CUSplitFlagSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_SPLIT_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUSkipFlagSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_SKIP_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUMergeFlagExtSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_MERGE_FLAG_EXT );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUMergeIdxExtSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_MERGE_IDX_EXT );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUPartSizeSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_PART_SIZE );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUPredModeSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_PRED_MODE );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUIntraPredSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_INTRA_PRED_MODE );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUChromaPredSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_CHROMA_PRED_MODE );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUDeltaQpSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_DQP );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUInterDirSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_INTER_DIR );
	InitCABACModelBuffur(&pSlice->pCABACModel.CURefPicSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_REF_PIC );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUMvdSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_MVD );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUQtCbfSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_QT_CBF );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUTransSubdivFlagSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_TRANS_SUBDIV_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUQtRootCbfSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_QT_ROOT_CBF );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUSigCoeffGroupSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_SIG_CG_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUSigSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_SIG_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.CuCtxLastXModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_LAST );
	InitCABACModelBuffur(&pSlice->pCABACModel.CuCtxLastYModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_LAST );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUOneSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_ONE_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUAbsSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_ABS_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.MVPIdxSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_MVP_IDX );
	InitCABACModelBuffur(&pSlice->pCABACModel.SaoMergeSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_SAO_MERGE_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.SaoTypeIdxSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_SAO_TYPE_IDX );
	InitCABACModelBuffur(&pSlice->pCABACModel.TransformSkipSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_TRANSFORMSKIP_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUTransquantBypassFlagSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_CU_TRANSQUANT_BYPASS_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.explicitRdpcmFlagSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_EXPLICIT_RDPCM_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.explicitRdpcmDirSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_EXPLICIT_RDPCM_DIR );
	InitCABACModelBuffur(&pSlice->pCABACModel.IntraBCPredFlagSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_INTRABC_PRED_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.CrossComponentPredictionSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_CROSS_COMPONENT_PREDICTION );
	InitCABACModelBuffur(&pSlice->pCABACModel.ChromaQpAdjFlagSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_CHROMA_QP_ADJ_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.ChromaQpAdjIdcSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_CHROMA_QP_ADJ_IDC );
	InitCABACModelBuffur(&pSlice->pCABACModel.CUColourTransformFlagSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_COLOUR_TRANS );
	InitCABACModelBuffur(&pSlice->pCABACModel.IntraBCBVDSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_INTRABC_BVD );
	InitCABACModelBuffur(&pSlice->pCABACModel.PLTModeFlagSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_PLTMODE_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.SPointSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_SPOINT );
	InitCABACModelBuffur(&pSlice->pCABACModel.CopyTopRunSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_TOP_RUN );
	InitCABACModelBuffur(&pSlice->pCABACModel.RunSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_RUN );
	InitCABACModelBuffur(&pSlice->pCABACModel.PLTSharingModeFlagSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_PLT_REUSE_FLAG );
	InitCABACModelBuffur(&pSlice->pCABACModel.PLTScanRotationModeFlagSCModel,sliceType,sliceQP,(HEVC_UINT8*)INIT_SCAN_ROTATION_FLAG );
	for (i = 0; i < RExt__GOLOMB_RICE_ADAPTATION_STATISTICS_SETS; i++)
	{
		pSlice->GolombRiceAdaptationStatistics[i] = 0;
	}
	StartSliceCABAC(&pSlice->decCABACEnviro,pImg);
}
void InitCABACModelBuffur(ContextModel3D *pContextModel3D,SliceType sliceType, HEVC_UINT8 sliceQP, HEVC_UINT8* ctxModel)
{                          //<ContextModel3DBuffer::initBuffer
	HEVC_INT32 i = 0;
	HEVC_INT32 value = 0;
	HEVC_INT32 slope;
	HEVC_INT32 offset;
	HEVC_INT32 initState;
	HEVC_UINT8 mpState;
	ContextModel * pContextModel = pContextModel3D->pContextModel;
	if (sliceQP > 51)   //XT   CLIP3操作
	{
		sliceQP = 51;
	}
	ctxModel += sliceType*pContextModel3D->SizeXYZ;
	for (i = 0; i < pContextModel3D->SizeXYZ; i++)
	{
		value = ctxModel[i];
		slope = (value >> 4)*5-45;
		offset = ((value & 15)<<3)-16;
		initState = min(max(1,(((slope * sliceQP) >> 4) + offset)),126);
		mpState = (initState >= 64);
		mpState = ( (mpState? (initState - 64):(63 - initState)) <<1) + mpState;
		pContextModel[i].State = mpState;
		pContextModel[i].BinsCoded = 0;
	}
}
void StartSliceCABAC(DecCABACEnviro *decCABACEnviro,IMGINFO *pImg)
{
	const HEVC_INT8*	pUnitBuf 	= pImg->pUnitBuf;
	HEVC_UINT32	bitOffset = pImg->bitOffset;
	decCABACEnviro->Range = 510;
	decCABACEnviro->BitsNeeded = -8;
	decCABACEnviro->Value = (READ_BITS(pUnitBuf,&bitOffset,8,"XT_StartSliceCABAC") << 8);
	decCABACEnviro->Value |= READ_BITS(pUnitBuf,&bitOffset,8,"XT_StartSliceCABAC");
	pImg->bitOffset = bitOffset;
}

然后初始化就完成了,是不是清楚一些了

然后就是真正解码的过程了

在解码中主要从码流中读取算数编码的过程,重写的时候尽量简化,在码流中用两个变量就够了

HEVC_INT8 *pUnitBuf; //码流缓存

HEVC_UINT32 bitOffset; //读取的bit的偏移量

这里写出来一个decodeBin的函数

void DecodeBin(IMGINFO *pImg,HEVC_UINT8 *Bin, ContextModel *pCtxModel,DecCABACEnviro *pDecCABACEnviro)
{
	HEVC_UINT32 Range = pDecCABACEnviro->Range; //< Remebeer to exchange the value at last
	HEVC_UINT32 Value = pDecCABACEnviro->Value;
	HEVC_INT32 BitNeed = pDecCABACEnviro->BitsNeeded;

	HEVC_UINT32 scaledRange = 0;
	HEVC_INT32 numBits;
	HEVC_UINT32 LPS = LPSTable[(pCtxModel->State)>>1][(Range >> 6) - 4];
	Range -= LPS;
	scaledRange = Range << 7;
	if (Value < scaledRange)  //<MPS Path
	{
		*Bin = (pCtxModel->State) & 1;
		pCtxModel->State = NextStateMPS[pCtxModel->State]; //<update the state
		if (scaledRange < (256 << 7))
		{
			Range = scaledRange >> 6;
			Value += Value;
			if (++BitNeed == 0)
			{
				BitNeed = -8;
				Value += READ_BITS(pImg->pUnitBuf, &pImg->bitOffset,8,"XT");
			}
		}
	}
	else  //<LPS PATH
	{
		*Bin = 1-((pCtxModel->State) & 1);
		numBits = RenormTable[LPS >> 3];
		Value = (Value - scaledRange) << numBits;
		Range = LPS << numBits;
		pCtxModel->State = NextStateLPS[pCtxModel->State];  //<update the state
		BitNeed += numBits;
		if (BitNeed >= 0)
		{
			Value += (READ_BITS(pImg->pUnitBuf, &pImg->bitOffset,8,"XT")) << BitNeed;
			BitNeed -= 8;
		}
	}
	pDecCABACEnviro->Range = Range;
	pDecCABACEnviro->Value = Value;
	pDecCABACEnviro->BitsNeeded = BitNeed;
}
时间: 2024-11-07 06:36:38

HEVC熵解码代码分析—重写熵解码(3)的相关文章

HEVC熵解码代码分析—类结构(1)

最近开始做HEVC了,其中熵解码作为最底层的部分,因为和h264差不多,难度系数不是很大,主要是一些查表的操作 具体的实现原理就不细说了,主要从代码来进行解释 首先分析HM工程当中的熵解码的部分作为引导,因为最终要在DSP上进行运行,之后会重写为C代码,流程性更强 代码分析 首先介绍熵解码中比较重要的几个结构体和设计到的函数 一进入main函数,最主要的就是对应的解码类TAppDecTop int main(int argc, char* argv[]) { TAppDecTop cTAppDe

FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-TU

本文分析FFmpeg的libavcodec中的HEVC解码器的CTU解码(CTU Decode)部分的源代码.FFmpeg的HEVC解码器调用hls_decode_entry()函数完成了Slice解码工作.hls_decode_entry()则调用了hls_coding_quadtree()完成了CTU解码工作.由于CTU解码部分的内容比较多,因此将这一部分内容拆分成两篇文章:一篇文章记录PU的解码,另一篇文章记录TU解码.本文记录TU的解码过程. 函数调用关系图 FFmpeg HEVC解码器

FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-PU

本文分析FFmpeg的libavcodec中的HEVC解码器的CTU解码(CTU Decode)部分的源代码.FFmpeg的HEVC解码器调用hls_decode_entry()函数完成了Slice解码工作.hls_decode_entry()则调用了hls_coding_quadtree()完成了CTU解码工作.由于CTU解码部分的内容比较多,因此将这一部分内容拆分成两篇文章:一篇文章记录PU的解码,另一篇文章记录TU解码.本文记录PU的解码过程. 函数调用关系图 FFmpeg HEVC解码器

HEVC熵解码代码分析—代码解码流程(2)

虽然熵解码的过程并不是很复杂,但是因为涉及太多的文档和函数比较让人心烦,所以稍微进行一下整理 熵解码一般一开始就是需要对上下文模式进行一定得初始化 在HEVC中 因为是类结构,所以在声明对象的时候,基本就完成了一般的初始化工作,下面详细介绍一下: 在类TDecSbac当中包含所有的上下文模式,但是在HM中有两个对应的结构 ContextModel m_contextModels[MAX_NUM_CTX_MOD]; //<一共512个 元素 Int m_numContextModels; Cont

FFmpeg的HEVC解码器源代码简单分析:环路滤波(Loop Filter)

===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpeg的HEVC解码器源代码简单分析:概述 FFmpeg的HEVC解码器源代码简单分析:解析器(Parser)部分 FFmpeg的HEVC解码器源代码简单分析:解码器主干部分 FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-PU FFmpeg的HEVC解码器源代码简单

FFmpeg的H.264解码器源代码简单分析:熵解码(Entropy Decoding)部分

本文分析FFmpeg的H.264解码器的熵解码(Entropy Decoding)部分的源代码.FFmpeg的H.264解码器调用decode_slice()函数完成了解码工作.这些解码工作可以大体上分为3个步骤:熵解码,宏块解码以及环路滤波.本文分析这3个步骤中的第1个步骤. 函数调用关系图 熵解码(Entropy Decoding)部分的源代码在整个H.264解码器中的位置如下图所示. 单击查看更清晰的图片 熵解码(Entropy Decoding)部分的源代码的调用关系如下图所示. 单击查

FFmpeg的H.264解码器源代码简单分析:宏块解码(Decode)部分-帧内宏块(Intra)

本文分析FFmpeg的H.264解码器的宏块解码(Decode)部分的源代码.FFmpeg的H.264解码器调用decode_slice()函数完成了解码工作.这些解码工作可以大体上分为3个步骤:熵解码,宏块解码以及环路滤波.本文分析这3个步骤中的第2个步骤.由于宏块解码部分的内容比较多,因此将本部分内容拆分成两篇文章:一篇文章记录帧内预测宏块(Intra)的宏块解码,另一篇文章记录帧间预测宏块(Inter)的宏块解码. 函数调用关系图 宏块解码(Decode)部分的源代码在整个H.264解码器

Netty编解码框架分析

1. 背景 1.1. 编解码技术 通常我们也习惯将编码(Encode)称为序列化(serialization),它将对象序列化为字节数组,用于网络传输.数据持久化或者其它用途. 反之,解码(Decode)/反序列化(deserialization)把从网络.磁盘等读取的字节数组还原成原始对象(通常是原始对象的拷贝),以方便后续的业务逻辑操作. 进行远程跨进程服务调用时(例如RPC调用),需要使用特定的编解码技术,对需要进行网络传输的对象做编码或者解码,以便完成远程调用. 1.2. 常用的编解码框

【转】Netty系列之Netty编解码框架分析

http://www.infoq.com/cn/articles/netty-codec-framework-analyse/ 1. 背景 1.1. 编解码技术 通常我们也习惯将编码(Encode)称为序列化(serialization),它将对象序列化为字节数组,用于网络传输.数据持久化或者其它用途. 反之,解码(Decode)/反序列化(deserialization)把从网络.磁盘等读取的字节数组还原成原始对象(通常是原始对象的拷贝),以方便后续的业务逻辑操作. 进行远程跨进程服务调用时(