您的位置:首页 > 其它

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

2018-03-20 16:20 477 查看
目录:

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

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

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

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

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

上节我们介绍了CABAC的先导知识,这节我们将介绍H.264协议中的CABAC熵编码。

CABAC编码流程

在协议中CABAC编码流程主要分为三个部分:

语法元素二值化

上下文模型选择

基于查表法的二进制算术编码

CABAC全称为上下文自适应二进制算术编码(Context-based Adaptive Binary Arithmetic Coding),即动态调整0和1的概率,来压缩比特串。而在协议中,为了更加便捷的在计算机上实现二进制算术编码,使用了查表法,替代繁杂得乘法计算,大大加速了CABAC的编码过程。

语法元素二值化

具体二值化过程可以参考H.264协议CABAC熵编码学习(一)。

协议中规定了宏块级语法元素的二值化方案,具体可参考协议中Table 9-34。











基于查表法的二进制算术编码

在协议中,为了简化算术编码的计算复杂度,首先是将[0,1][0,1]区间扩展成[0,1024][0,1024],同时将乘法转化成查表得方法,大大得缩减了计算复杂。接下来,我们将介绍协议中是如何进行二进制算术编码。

首先介绍几个变量得定义:

MPS:表示出现概率较大得数值,该数值为0或1

LPS:表示出现概率较小得数值,该数值为0或1

L(ow):概率区间得起始位置

R(ange):概率区间得长度

在协议中,一个概率区间的布局如下:



CABAC将[0.01875,0.5][0.01875,0.5]区间划分成0~63个状态,其中63号状态表示退出,0号状态表示数值翻转,即LPS和MPS所代表的值进行翻转。每个状态的概率计算如下:

p(t+1)LPS={α⋅ptLPSα⋅ptLPS+(1−α)if an MPS occursif an LPS occurspLPS(t+1)={α⋅pLPStif an MPS occursα⋅pLPSt+(1−α)if an LPS occurs

α=(0.018750.5)(1/63)≈0.95α=(0.018750.5)(1/63)≈0.95

同时L和R的更新如下:

L(t+1)={LtLt+Rt⋅PtLPSif an MPS occursif an LPS occursL(t+1)={Ltif an MPS occursLt+Rt⋅PLPStif an LPS occurs

R(t+1)={Rt⋅(1−PtLPS)Rt⋅PtLPSif an MPS occursif an LPS occursR(t+1)={Rt⋅(1−PLPSt)if an MPS occursRt⋅PLPStif an LPS occurs

根据上述公式,每次编码完0或1后,CABAC的概率跳转如下:



很明显,每个状态的概率都可以先算好,存到一张表中。而实际使用时,只需要用该状态号的下标,快速查表获取即可。协议中,状态号的跳转如下表:



其中pStateIdx表示当前状态好,transIdxLPS表示当编码LPS时,要跳转的状态号,transIdxMPS表示当编码MPS时,要跳转的状态号。

上下文模型选择

H.264协议中总共有1024个上下文模型ctxIdx,每个ctxIdx对应不同的m和n。获取到m和n后,通过如下的计算,获得对应的状态号:

preCtxState = Clip3( 1, 126, ( ( m * Clip3( 0, 51,                  SliceQPY ) ) >> 4 ) + n )
if( preCtxState <= 63 ) {
pStateIdx = 63 − preCtxState
valMPS = 0
} else {
pStateIdx = preCtxState − 64
valMPS = 1
}


每个ctxIdx对应的m和n可以通过查阅协议9.3.1.1节获取

计算ctxIdx

协议中ctxIdx的推导过程比较复杂,后续章节会详细介绍每个宏块级语法元素的ctxIdx计算。当总的来说,协议中ctxIdx皆由以下两种计算方式之一获得:

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

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

无论式1还是式2,ctxIdxOffset、maxBinIdxCtx都通过协议的Table 9-34查询。宏块中的语法元素,若无以下特殊说明,皆使用式1进行计算。对于式1,可以参考协议9.3.3.1节的Table 9-39,了解通过ctxIdxOffset和binIdx获取ctxIdxInc的过程。而对于式2,可以参考协议9.3.3.1节的Table 9-40,了解通过ctxBlockCat获取ctxIdxBlockCatOffset的过程,同时参考协议的Table 9-42,了解通过宏块类型获取ctxBlockCat和maxNumCoeff的过程。

接下来的章节,笔者将会搭配x264代码详细介绍每个宏块级语法元素的ctxIdx计算过程。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息