在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