在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; <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;
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;
}原文地址:http://blog.csdn.net/xietingcandice/article/details/42106407