H.264/AVC标准采用了很多新技术和新方法,大大提高了视频编码效率,其中CABAC便是H.264/AVC采用的新型熵编码方法之一。CABAC采用了高效的算术编码思想,同时充分考虑了视频流相关统计特性,大大提高了编码效率。概括起来,CABAC有三个丰要特点:
(1)上下文建模提供编码符号条件概率分布的估计。利用适当的上下文模型,在编码当前符号时,根据已编码的临近符号的概率统计,在不同的概率模型间转换,借此去掉符号间的冗余。
(2)算术编码可以给每一个符号字母分配非整数比特,因此符号能以接近它的熵率被编码。这对概率大于O.5的符号很有效。如果选择了高效的概率模型,符号概率常常大于O.5,这时分数比特就比UVLC的整数比特(至少1比特)高效得多。
(3)自适应的算术编码可以使熵编码器自适应动态符号的概率统计。一般情况下,运动矢量的概率统计随空间、时间的不同,或序列、码牢的不同可以发生较大的变化。因此,自适应模型由于充分利用已编码符号的概率统计,可使算术编码更好地适应当前符号的概率,从而提高了编码效率。
CABAC包括三个部分:二进制化、上下文建模和二进制算术编码
下面对每个部分进行详述:
(1)二进制化
CABAC是二进制算术编码,对非二进制符号如运动矢量、宏块类型、参考帧号以及变换量化后的残差数据,需要预先进行二进制化。在H.264/AVC标准中,CABAC二进制化方案由基本方案和串接方案组成。基本方案有一元码(Unary binarization,U),截断一元码(Truncatedunary binarization,TU),K阶指数哥伦布码(Kthorder Exp_golomb binarization,UEGK)和定长码(Fixed.1ength binarization,FL)四种。串接方案由基本方案串接而成。不同的二进制化方案适用于不同类型的语法元素。对于数值变化范围较大的残差数据(如运动矢量与运动矢量预测值间的残差数据MVD)用UEGK码表示,对于简单的符号标志元素用FL码表示。下面是四种基本方案的编码方法:
U二进制化编码:此方法将一个无符号整数X,编码为X个“1”并加上一个后缀位“0”。例如,整数3转换为“lllO”。
TU二进制化编码 :此方法根据参数cMax采用不同的转换方法。如果无符号整数x<cMax,用Unary binarization方法转换;如果x=cMax,X被转换成X个“1”。UEGK二进制化编码:用此方法转换后的码字由两部分构成:前缀和后缀。前缀部分由Unary binarization转换得到。
FL二进制化编码:此方法为语法元素工设定固定的长度。假如0≤X<cMax,其长度L=
CABAC把待编码的语法元素按照一定的规则转换为只用“0”和“l”表示的二进制比特流,称为比特流(bin string),然后采用不同的概率模型对bin string进行编码,充分考虑了视频流的相关性,能适应信号统计特性的变化,容易达到渐进性能。在编码过程中,bin string的信源符号被分为大概率符号(Most Probability Symbol,MPS)和小概率符号(Least Probability Symbol,LPS)。若MPS为“0”,则LPS为“l"。反之,若NIPS为“l",则LPS为“0”。但当MPS与LPS的出现概率相差比较大时,根据信息熵的原理,bin string的熵值比较小,压缩效果比较好。如果MPS与LPS出现概率相当或者相等,bin string的熵值就比较大,则压缩效果不明显。
(2)上下文建模
编码符号具有上下文相关性,利用已编码符号提供的上下文信息,为编码符号选择合适的概率模型,这就是上下文建模。它是为了对与运动、模式和结构信息相关的句法元素进行编码而设计的。通过对上下文模型的构建,摹本概率模型能够适应随视频图像而改变的统计特性,降低符号间的冗余度,并大大减少运算开支。
CABAC将片作为算术编码的牛命周期,H.264/AVC标准将一个片内可能出现的数据划分为399个上下文模型,每个模型均有自己的上下文序号(Ctxldx),每个不同的字符依据对应的上下文模型,来索引自身的概率查找表。即收到字符后,先索引该字符的Ctxldx,才能找到它的概率查找表(TransldxLPS)。这些模型的划分精确到比特,几乎大多数的比特和它们邻近的比特处于不同的上下文模型中。查找每个比特所对应的上下文模型有两个步骤:
第一步:确定该比特所属的句法元素。CABAC为每个句法元素分配了一个上下文模型区间,详见Table9.1l。
第二步:按照某一个法则为当前比特在上一步中得到的区间中找到对应的Ctxldx。该法则对不同的句法元素各不相同,它通常用表来表示。那些399个上下文模型模型分为4种类型:第一种类型根据左边和上边的语法元素对当前的语法元素进行预测。第二种类型仅用于宏块类型和予宏块类型。其中第n比特的类型要参考前面已编码的n-1比特所采用的类型。第三、四种类型只用于残差。第三种类型不依赖前面的编码数据,而是依赖扫描路径的位置。第四种类型还包括对编码积聚数量的计算。在CABAC中用“个有代表性的概率值来表示LPS的概率。这64个概率值通过公式(3.1)和(3.2)来计算产生:
值可以用7个比特来表示。
前文提到CABAC的生命期是片,每个片开始,要对399种上下文模型全部过行初始化工作,初始化的步骤是:
(3)二进制算术编码
概率估计和编码器构成了一个自适应二进制算术编码器。概率估计是在前一次上下文建模阶段更新后的概率估计。在对每个二进制数值编码过后,这个概率估计的值又要根据刚刚编码的二进制符号进行调整。二进制算术编码是算术编码的特殊情况,其原理与一般算术编码一样。所不同的是,在二进制算术编码中编码序列只有“0"和“l一两种符号,所涉及的概率也只有P(0)和P(1)。概率区间分成两份,一份是MPS的编码区间,一份是LPS的编码区间。区间长度由每个信源符号的概率决定,LPS的编码区间总应该小于MPS的编码区间。若把LPS的概率记为Q,则MPS的概率记为P=I-Q。在编码进程中,如果有连续的LPS输入,有可能出现Q>P的情况,此时MPS和LPS所代表的信源符号要互换,以确保MPS所代表的信源符号的概率始终大于LPS所代表的信源符号的概率。在每个片开始时,CABAC进行初始化,建立了一个概率状态表。在进行二进制算术编码时,每一位的概率状态值通过查概率状态表得到。而且每编码完一位,就要对概率状态表中的状态值进行更新。概率状态值的更新是这样实现的:如果编码的比特位(binval)是NIPS,概率状态值a加l,这意味着R值减小,(1.R)值增大,这实际就是表示下一次出现MPS的概率增大,出现LPS的概率减小。如果a=62,表示(1.n)已经达到最大,这时a不再改变,直到出现LPS。如果编码的比特位biIlvm是LPS,且a=0,表示MPS和LPS的概率相等,MPS和LPS的值进行互换。具体的概率值更新参考公式(3.3)
为了方便观察,我们给出CABAC概牢估计与更新模型图(如图3.2)。在处理binval时,概率的刷新有两个方向:如果binval是LPS,则LPS的概率变大,顺着下图中的虚线向左寻找;如果binval是MPS,则LPS的概率变小,顺着下图中的实线向右寻找。我们可以看到,当出现MPS时的更新值都只是简单地指向当前值的下一位,即a+l。也即,当前处理的字符为MPS时,区间递进只是了区间的长度发生了改变,而作为影响实际输出值的L却没有发生改变,这个现象意味着如果输入流中连续出现大量的MPS,或者MPS相对LPS出现的概率比较高时,可以达到极高的压缩效果,编码输出的码率也更接近熵率。