CABAC对算术编码的特性做了许多优化,这其中也包括从统计角度对输入流做的一套预编码方法,当前处理的字符为MPS时,区间递进只是子区间长度发生变化,而作为影响实际输出值的L却并未变化,这个现象意味着如果输入流中连续出现大量的MPS,或者MPS对LPS的概率比非常高时,可以达到极高的压缩效果。 这个预编码的过程叫做输入流的二进制化,经它输出的是MPS概率极高的比特流
二进制化包括四种方法:U , TU, UEGK, FL
H.264 将一个条带内的数据划分为399个上下文模型,每个模型以ctxIdx标示,在每个模型内部进行概率的查找和更新。
解码器对输入的每一个比特首先要做的工作时查找它属于哪个上下文模型,然后查找该上下文模型对应的概率表以递进区间。查找某个比特对应的上下文模型一般有以下两个步骤:
(1)确定该比特所属的句法元素,由句法元素查找上下文模型(区间)索引ctxIdx(表9-11)
(2)按照法则为当前比特在(1)中得到的区间找到对应的ctxIdx.该法则对于每个句法元素都不同。一般情况下是用表定义的(表9-30)
初始化:CABAC的生命周期是slice,每个slice开始时,要对460种上下文模型全部进行初始化工作:
(1)递进区间复位到 [0,1)
(2)为每个上下文模型制定一个初始的ω(MPS),σ(Plps索引)
(1) 通过查表获得上下文模型对应的m,n获得初值
(2)按照算法计算得到ω,σ
CABAC编码流程(引自《新一代视频压缩编码标准H.264》毕厚杰):在建立了概率模型和乘法模型之后,在递进计算过程中CABAC必须保存以下变量的记录状态:
(1)当前区间的下限L
(2)当前区间的大小R
(3)当前MPS字符ω
(4)LPS打概率编号(索引)
注意,MPS对应的区间始终在左边
图 1 算术编码流程
CABAC解码流程(引自H.264规范):
算术解码过程,输入:bypassFlag,ctxIdx,算术解码引擎中的状态变量codIRange和codIOffset
输出:二进制码值
核心解码步骤包括:
(1) 二进制判决的算术解码过程
获得LPS对应的区间间隔:codIRangeLPS = rangeTabLPS[pStateIdx][qCodeIRangeIdx]
更新codIRange = codIRange - codIRangeLPS
if(codIOffset >= codIRange){
binVal = 1 - valMPS;
codIOffset -= codIRange;
}else{
binVal = valMPS;
}
执行规定的状态转移,注意MPS和LPS置换,之所以执行状态转移,是因为自适应需要对概率模型进行刷新
(2)算术解码引擎的重归一化过程
(3)二进制判决的解码旁路过程
(4)结束前的二进制判决解码过程
图 2