H.264协议CABAC熵编码学习(五)

目录:
H.264协议CABAC熵编码学习(一)
H.264协议CABAC熵编码学习(二)
H.264协议CABAC熵编码学习(三)
H.264协议CABAC熵编码学习(四)
H.264协议CABAC熵编码学习(五)

  • (1)ctxIdx=ctxIdxOffset+ctxIdxInc(ctxIdxOffset,binIdx)

  • (2)ctxIdx=ctxIdxOffset+ctxIdxInc(ctxBlockCat)+ctxIdxBlockCatOffset(ctxBlockCat)

不做特殊说明,本节提到的残差系数都是经过DCT变换和量化后的值。

这节主要介绍宏块残差相关的语法元素的ctxIdxInc推导,该部分语法元素使用的是式2,参考协议Table 9-40,可以获取不同ctxBlockCat对应的ctxBlockCatOffset,而ctxBlockCat可以通过协议Table 9-42获取。

H.264协议CABAC熵编码学习(五)

宏块残差类型

在协议Table 9-42中,根据宏块的划分方法,以及YUV的类型(即为YUV420或者YUV422),将残差类型划分如下,每个类型对应的maxNumCoeff和ctxBlockCat不同:

H.264协议CABAC熵编码学习(五)

coded_block_flag

首先通过Table 9-42,根据残差类型,获取ctxBlockCat和maxNumCoeff。而后通过Table 9-40,通过ctxBlockCat获取ctxIdxBlockCatOffset。对于ctxIdxInc,可以参考协议9.3.3.1.1.9节,会推导出一些中间变量,之后通过中间变量获取condTermFlagN的值,而后通过以下公式计算ctxIdxInc:

ctxIdxInc=condTermFlagA+2condTermFlagB

残差语法元素的推导方式

该小节包含了以下语法元素:

  • significant_coeff_flag[i]:Z扫描后的位置i上,残差系数是否为0,是为1,否为1

  • last_significant_coeff_flag[i]:Z扫描后的位置i上是否为最后一个不为0的系数,是为1,不是为0

  • coeff_abs_level_minus1[i]:Z扫描后的位置i上残差系数的绝对值减1

  • coeff_sign_flag[i]:Z扫描后位置i上残差系数的正负号,1为正,0为负

同时介绍下推导ctxIdxInc时会使用到的一些变量:

  • levelListIdx:Z扫描的残差系数的下标

  • numDecodAbsLevelEq1:假设现在编码第i个残差系数,该值为之前i-1个残差系数中,数值为1的个数

  • numDecodAbsLevelGt1:假设现在编码第i个残差系数,该值为之前i-1个残差系数中,数值大于1的个数

  • numC8x8:chroma 8x8的个数,YUV420时该值为1,YUV422时该值为2

对于significant_coeff_flag和last_significant_coeff_flag:

  • 若ctxBlockCat不为3,则ctxIdxInc=levelListIdx,其中levelListIdx的取值范围为0到maxNumCoeff - 2

  • 若ctxBlockCat等于3,则ctxIdxInc=Min(levelListIdx/numC8x8,2),其中levelListIdx的取值范围为0到4 * numC8x8 - 2

  • 若ctxBlockCat为5、9、13,则ctxIdxInc通过下表查询:

H.264协议CABAC熵编码学习(五)
H.264协议CABAC熵编码学习(五)

对于coeff_abs_level_minus1:

  • 若binIdx为0,则ctxIdxInc=((numDecodAbsLevelGt1!=0)?0:Min(4,1+numDecodAbsLevelEq1)

  • 若binIdx大于0,则- 若binIdx为0,则ctxIdxInc=5+Min(4((ctxBlockCat==3)?1:0),numDecodAbsLevelGt1)

对于coeff_sign_flag,使用的是旁路编码,即0和1概率相等,不需要进行上下文模型建模。