18-回顾:h264中的CABAC

来源:互联网 发布:核武 知乎 编辑:程序博客网 时间:2024/05/13 13:34
【开始学习HEVC的算数编码之前,先修补一下知识漏洞,回去学一下H.264的CABAC为好。参考文献为: D. Marpe, H. Schwarz, and T. Wiegand, “Context-based adaptive binary arithmetic coding in the H.264/AVC video compression standard,” IEEETrans. Circuits Syst. Video Technol., vol. 13, no. 7, pp. 620–636, Jul. 2003.
Context-based adaptive binaryarithmetic coding in the H.264/AVC video compression standard

1、引言
CABAC将二进制算数编码同上下文模型结合,极大提高了算法的适应性和消除冗余的能力。除此之外,CABAC还包括一种低复杂度算法,可以较好地适应低功耗的软硬件实现方案。在针对测试序列的实验结果中显示,相对于传统的熵编码方法,CABAC可以节省9-14%的码流。CABAC是H.264/AVC中规定的两种熵编码方法的一种,首先在【7】中提出初步版本并在【8-17】中逐步优化。本文主要描述了【1】中CABAC的最终版本。相比之下,MPEG-2,H.263和MPEG-4等标准主要采用基于定长表的VLC编码,存在诸多问题。
第一个可以实用的基于块结构的混合视频编码方法的自适应算数编码在H.263的附录中提出【4】.然而该方法也存在问题。首先,这种方法所针对的目标同H.263的VLC相同,包括对变换系数的编码的组合符号。这样算数编码对非整数码长的带编码元素的处理能力没有被充分发掘。其次,这种方法所有的概率模型是固定的,因为不能在实际的符号概率分布统计中自适应变化,因此效率不高;最后,由于其过高的运算复杂度和有限的压缩效率增益,在多数场合的应用价值不大。
 在一些非块结构的编码算法中,经常涉及到算数编码。这些算法常常基于离散小波变换DWT,并结合了一些如重叠块运动补偿、基于网格的变形和基于运动补偿的时域滤波等于时域预测无关的技术。而其中采用的熵编码通常源自于基于DWT的静态图像压缩标准如SPIHT和JPEG2000的前身等。
 关于“分割、聚合和条件编码”(PACC),该方法的特点在于分割策略:给定一个特定大小的表作为源数据(如量化过的系数),通过二元分割的方法削减表的尺寸,例如对于量化系数,依据该系数是否被量化为0。实际上,这样的方法便是一种二值化的过程。通过这种“表缩减”操作,后续的建模阶段在最大程度缩减的表上的操作的效率可以更有效率。如此,高阶条件模型的设计和应用可以极大简化并且降低了模型过度拟合的风险。鉴于此,最终的算数编码方法选择了一种快速的表驱动算数编码。
 为了改进H.263附录E的方法,CABAC将自适应二进制算数编码同精心设计的上下文模型结合。由表缩减所提示,对于非二元符号引入了额外的二值化过程。由于相对VLC,CABAC的运算复杂度被视为主要不足,因此大量精力被投入在软硬件优化的算法设计方面。在硬件资源有限,难以满足CABAC条件的场合中,H.264/AVC的基准档次上编码器提供了另一种方法,除了对残差数据之外,其他语法元素采用一种基于零阶指数哥伦布编码无限扩展集合的方法;对残差数据,采用了一种上下文自适应的边长编码方法CAVLC,通过对不同的语法元素选择不同的码表压缩符号间冗余。同样,CAVLC也面临着与之前的算法类似的问题,对概率大于0.5的符号没有足够的效果。

2、CABAC的框架结构
【HEVC学习与研究】20、回顾:H.264的CABAC原理
上图显示的是CABAC的流程架构。整个CABAC编码架构主要分为三个部分:1、二值化;2、上下文建模;

3、二进制算数编码;
  在第一步二值化中,一个非0/1的语法结构被映射成一个唯一的二进制01序列;而对二进制元素,该过程被跳过。对于生成的二进制码流,随后根据常规编码或者旁路编码的选择,可能经过一步或者两步处理步骤。
在常规编码模式中,完成二进制话的bin进行上下文建模,通过选择一个概率模型,在做相应的选择的时候参考之前处理的bin或者语法元素。之后,bin和上下文模型在算数编码器中进行编码,并且更新上下文模型。另一种方式旁路编码模式,因为没有显式地选择上下文模型,简化了编码引擎,因此编解码速度更快,复杂度更低。
A. 二值化过程
  可用于视频编码的上下文建模和自适应二进制编码所必须满足的要求主要有:(1)在一个较短的时间内获取尽可能精确的条件概率模型;(2)为确保串行架构处理过程的数据吞吐量,概率估计和算数编码的基本操作的运算复杂度需尽可能低。为满足这样的条件,采用了二值化作为预处理过程,将每一个值非0/1的语法元素转化为0/1,成为一串二进制的码字流。这样,算数编码的码表长度被削减为2个,在建模和编码方面都更加容易。同时由于出现长码字流的概率并不大,因此快速的二进制编码引擎可以弥补这一步骤造成的运算量负担。最后,二值化使上下文建模可以在亚符号层进行,对于大概率的常见符号可采用条件概率,对于其他小概率符号可采用(零阶)联合概率模型。相比之下,这样的设计在不造成上下文稀释效果的前提下,可以选择更高阶的条件概率模型。
  CABAC二值化的方法。在实际的应用中,H.264的CABAC采用了一元码、截断一元码、k阶指数哥伦布编码和定长码的方法,可以在不保存和传输任何码表的情况下恢复原值。另外还可能采用多种方法的结合方法。
B.   上下文建模
  在上下文建模中,给定的符号将被分配一个概率分布模型,编码引擎根据该模型生成比特序列以表示该符号。由于上下文模型决定了编码及其效率,因此设计合理的,可以充分挖掘统计依赖性,并且可以动态更新的上下文模型具有重大意义。
  由之前处理的符号组成的集合T={z}称作上下文模板集,另一个相关集合C={0,...,C-1}为上下文集。通过选取T中不同的元素z切换不同概率模型,估计出条件概率p(x|F(z)),使用此条件概率编码元素x后,根据x的值更新概率模型。H.264的CABAC对上下文模型施加了两个限制减少估计条件概率时的计算复杂度。其一,上下文模板集T仅包含与当前编码符号相邻的元素,因此实际上C集合实际使用的元素较少;其二,上下文建模仅针对二值化过后的二进制码字流。
  在CABAC中指定了4种类型的上下文模型。第一种类型的上下文模板与两个最近处理过的相邻语法元素相关。相邻的定义根据语法元素的不同而不同,通常指语法元素左侧和上方相邻元素。第二种类型专门用于mb_type和sub_mb_type两个元素,依据之前编码的bin来做模型选择。第三种和第四种模型都只用于残差数据,且根据不同的块类型分属不同的模型类别。第三种模型不依赖于先前处理的数据,而是依据扫描路径上的位置。第四种模型设计了一种建模函数,涉及到累计编码层级数的估计。
  除了这些基于条件概率的上下文模型之外,部分bin使用固定分配的上下文模型,这些bin必须是由常规编码模式,并且不适用前述各个类别的上下文模型。下表中包含了H.264/AVC中的语法元素以及其对应的上下文模型索引。
【HEVC学习与研究】20、回顾:H.264的CABAC原理
【HEVC学习与研究】20、回顾:H.264的CABAC原理
  每一个索引值对应的上下文模型都分为两个部分,包括一个6为的概率状态索引和一个二进制的最大概率符号MPS。这样一个上下文模型可用一个7位的无符号整数表示。序号0-72的上下文模型用于表示宏块类型、子块类型、空间域/时域预测模式以及基于条带和宏块的控制信息。每一个相应的上下文模型索引都可以用context index offset和context index increment求和表示。序号73-398的上下文模型用于处理残差数据。对significant_coeff_flag和last_significant_coeff_flag各设置两个集合的上下文模型,因为这两个语法元素同像素扫描模式相关,因此分别为帧编码和长编码定义不同的上下文模型集合。在完全的帧或场编码的情况下,该集合中实际上只有277个元素。对于coded_block_pattern,上下文索引值的计算方法同0-72的一致,对于其他的模型则引入了context category的值。另需注明的是上下文建模中,只使用了当前条带中的先前处理的语法元素,即跨slice边界的数据不作为建模的依据。
C.   二进制算数编码
  算数编码是一种基于递归区间划分的方法。假设某最小概率符号(LPS)对应的概率区间为pLPS∈(0,0.5],其区间下限和范围分别由L和R表示。在编码过程中,该区间被分割为两个部分:其一与LPS关联,宽度为RLPS=R*pLPS。而RMPS=R-RLPS为最大概率符号对应区间,其概率估计为1-pLPS。根据二进制码元判定选择为LPS或者MPS这两个区间中的一个,并用“指向”该区间的二进制值表示目前处理过的二元序列,而这个区间的长度代表各个二进制码出现概率的乘积。如此可以更加逼近信息熵的下限值。

3、CABAC的细节详述
A.   宏块类型、预测模式和控制信息的编码
      1). 宏块和子宏块类型编码:mb_skip_flag表示在P/SP帧中当前宏块是否被跳过,若非跳过宏块,则mb_type表示该宏块的的类型。对于P8×8和B8×8宏块,对于每一个子宏块都有一个语法元素sub_mb_type表示其类型。
    编码mb_skip_flag:对于任意一个宏块C,对应的上下文模型包含了该宏块左侧(宏块A)和上方(宏块B)的mb_skip_flag的值。根据这两个参数的取值,当前宏块的取值可能为0、1或2。
  编码mb_type:下图表示了宏块和子宏块类型的二值化方法。
【HEVC学习与研究】20、回顾:H.264的CABAC原理
【HEVC学习与研究】20、回顾:H.264的CABAC原理
  在P条带中,mb_type不使用4这个模式,而5-30的值表示P条带中帧内宏块的类型,此类情况下,二值化的第一位为1。对上图中的各个二值化结果,对mb_type取值分别为C0-C3,对sub_mb_type分别为C0, C1, C2。
2).  预测模式的编码
  对于帧内宏块,需编码的语法元素有亮度和色度分量的预测模式;对于帧间宏块,则包含参考帧的索引和相关的运动矢量残差信息。
      (1).帧内4×4模式的亮度分量:用到两个语法元素prev_intra4x4_pred_mode_flag和rem_intra4x4_pred_mode(只有在前者=0的时候有效,二值化用3位定长码);采用两个不同概率模型;
      (2).帧内模式的色度分量:ChPredInDcMode表明了相应的宏块是否采用DC预测模式,而当前宏块则依据左、上方的相邻宏块的ChPredInDcMode是否为1决定上下文模型索引值为0、1或2。这些上下文模型用于编码intra_chroma_pred_mode(二值化用截断1元码)的第一个二进制码字。剩余的码字采用其他固定的概率模型。
  (3).参考帧索引:同上类似,语法元素ref_idx的上下文模型索引号有当前宏块左侧和上方的宏块信息(RefIdxZeroFlag,表示该区域的ref_idx是否为0)决定,有0-3共4种可能取值。采用该模型编码第一个码字,其他码字用另外两个模型完成。
  (4).MVD分量:其选择的上下文模型,根据左和上方宏块或子宏块的MVD模的和值的范围分为0.1.2三个值。MVD的二值化采用3阶指数哥伦布编码,只有前缀部分的第一个码字采用上述模型,第2-9个码字使用另外的4个模型编码。后缀部分都采用旁路编码模式。
  3).   控制信息的编码:
  主要包三个元素的处理:mb_qp_delta, end_of_slice_flag和mb_field_decoding_flag。
  (1)mb_qp_delta:用于可变宏块量化参数,包含在coded_block_pattern=0的非跳过模式的宏块中。第一步Δ(C)映射为一个对应的非负值并采用二院码二值化。根据之前编码宏块的Δ(P)是否为0决定为第一个码字选取哪一个概率模型,其余码字采用另外的模型。
  (2)end_of_slice_flag:标识当前宏块是条带内的最后一个宏块。采用某个特别设计的非自适应概率模型。
  (3)mb_field_decoding_flag:标识在帧场自适应模式中,该宏块使用帧编码还是场编码。其上下文模型索引通过对比左、上方相邻块的mb_field_decoding_flag值取0、1或2;

B.   残差数据的编码
  1)特点:
  针对残差数据,H.264/AVC的CABAC定义了多种特定的语法元素进行处理,其中有:
  (1)1位标识位coded_block_flag和二元重要性图结构,表示某个块结构中非0变换系数的位置;
  (2)非零值level按反向扫描顺序进行编码;
  (3)依据之前传输的非零level值,反向扫描确定非零变换系数的上下文;
  2)编码残差数据的过程
  下图表示对残差进行CABAC的流程框图:
【HEVC学习与研究】20、回顾:H.264的CABAC原理
【HEVC学习与研究】20、回顾:H.264的CABAC原理
  首先,除非coded_block_pattern或宏块模式表明,该块内不存在非零变化系数,则首先传递的是coded_block_flag这个值。如果这个值为0,则该block不会再传输任何信息;如果不为0,则编码该块的重要性图,指示非0系数的位置。最后对每一个非零系数,编码其符号和绝对值。所有数值按照反向扫描顺序传输。具体细节如下:
  (1)编码块模式coded_block_pattern:针对非intra16x16模式的非跳过宏块,这个值表示六个8×8子块(亮度×4+色度×2)中的哪一个包含非零系数。采用4位定长码和截断值=2的截断一元码进行二值化;
  (2)编码块标志coded_block_flag:1位符号,表示当前块内存在非零变换系数。若不存在,则跳过该块后期的处理;
  (3)变换系数的扫描:第一步是以某种扫描模式,将2D的变换系数矩阵映射为一个一维序列;
  (4)重要性表significant map:在coded_block_flag表明该块内存在非零系数的情况下,编码该块的重要性表;对于每一个系数,对应存在一个1位标志significant_coeff_flag,该标志=1,则存在另一个标志last_significant_coeff_flag,该符号表示当前系数是否是该块中的最后一个非零系数还是后面还有其他的。对于块的最后一个而言,这两个标识位不需要也不会发送。
  (5)级别信息Level Information:块的重要性表决定了块内非零系数的位置,非零系数的值以级别level表示,在编码中编成两个符号coeff_abs_level_minus1和coeff_sign_flag,分别代表系数的绝对值和符号。系数的绝对值信息用0阶指数哥伦布编码二值化。级别信息以反向扫描顺序传输,即从最后一个重要系数开始想第一个传递。
  3).残差信号的上下文建模
  在H.264/AVC中,共把变换系数矩阵分为12中不同类型,分别代表了不同的统计特性,并针对实际情况将这12中类型分成5大类。对每一个大类,都制定一个上下文模型的集合用于编码残差数据相关的语法元素(coded_block_pattern除外)。下面说明对coded_block_pattern所采用的方法。
  coded_block_pattern:该语法元素中的每一位都表示相应变换系数块的编码判定,因此语法元素的概率模型取决于码元的索引值。对表示4个8×8亮度块的前四个码元,上下文模型索引根据左方和上方8×8块的coded_block_pattern是否为0的值取0-3;第四个和第五个码元与色度分量相关,上下文的分配模型同亮度码元类似,共额外定义了8种概率模型。
  coded_block_flag:对于5中类别任意之一,采用了4种不同的概率模型,根据左、上方块的coded_block_flag的取值可能取0-3。只有相同类型的块才用作判决。
  significant map:【为什么文献中前面讲了一个15而后面却又提到61中呢?不明白。】
  级别信息level information:CABAC中采用了反向扫描,因为这样更有利于获取稳定的统计信息。在编码coeff_abs_level_minus1时,选用两个上下文模型集合,其中之一用于第一个二元码,另一个用于其他的二值化码字。

C.   概率估计
  CABAC定义了64中概率值,有以下公式推出:
【HEVC学习与研究】20、回顾:H.264的CABAC原理
【HEVC学习与研究】20、回顾:H.264的CABAC原理
  在上式中,α≈0.95,N=64,这两个取值确保算法在稳定、精确估计以及快速自适应之间取得一个平衡。这些概率值通过对应的索引值隐式地包含在了算数编码引擎中。这样,CABAC的每一个上下文模型可以用两个参数完全表示:一个LPS的当前估计值(0-63的索引)和MPS的值(0/1),实际在CABAC中仅有126个模型状态是有效的。
  1).   更新概率状态:
CABAC中的概率模型基本上都是自适应模型,在没编码完成一个符号之后会更新状态。对于给定状态,更新的结果取决于当前状态以及当前的符号是按照LPS/MPS编码。更新完成之后将产生一个新的概率模型。在一个MPS事件发生时,给定状态索引加1,除非状态索引已经为62,此时LPS概率估计已经为最小值,或者MPS概率估计已经达到上限(此情况下,状态索引保持为62直到遇到LPS,此时状态索引将减小)。
  2).   概率状态的初始化与重置
  所有的概率状态在条带的边界处都应初始化为某种预定义的初始状态(如全部初始化为等概率状态)。CABAC提供的“上下文模型初始化机制”利用了先验知识,在两个层次上对上下文模型进行初始化:
  (1)依赖于量化参数的初始化:
  此方法预设了一个初始化值的集合,通过初始设定的SliceQP导出。
  (2)依赖于条带的初始化:
  通过定义两个附加的上下文初始化集合实现,特定用于P和B条带的上下文建模。编码器通过在三个初始化表中选择以适应不同的条带类型。

D:   基于表的二进制算数编码
  关于CABAC的算术编码引擎,共存在两种引擎:其一为常规编码引擎,此类方法利用了自适应概率模型进行算术编码;另一种为旁路编码引擎用于快速编码,利用一种近似等概率模型。
  1).常规编码模式的区间分割:
  下图表示了某一个二进制值binVal进行常规模式算术编码的流程。
【HEVC学习与研究】20、回顾:H.264的CABAC原理
      【HEVC学习与研究】20、回顾:H.264的CABAC原理
在CABAC的过程中,区间的状态可以用当前区间范围R和区间下限L表示,在寄存器中这两个值的精度可达9和10位。编码binVal这个值需要上下文模型,其中包含概率状态索引σ和MPS的值ω,具体步骤分为以下四步:
  第一步也是最主要的一部,是根据给定的概率估计,将当前区间进行分割成两个子区间。首先采用将2^8<=R<=2^9区间等分为4份获得某个量化的Q(R)值,近似表示当前区间长度R。Q(R)由其量化索引表示,ρ=(R>>6)&3。
  第二步,这个索引值ρ和概率状态索引值σ用于在二维表TabRangeLPS中查找与LPS相关的子区间范围RLPS。同时可以获得的是对应MPS的子区间R-RLPS。选定给定的二进制值binVal对应的子区间,若binVal等于MPS对应的值ω,则选定低子区间,否则选定高子区间;
  第三步,采用2.C中的方法更新概率模型;
  第四步,将寄存器复位,即图中的RenormE;
  2).旁路编码模式
  为了加快编解码的速度,对于近似等概率的情况,CABAC提供了简化版本——旁路编码模式。该模式绕过了概率模型的估计和更新,并对区间进行平均分割。下图表示旁路模式的流程框图。
【HEVC学习与研究】20、回顾:H.264的CABAC原理
      【HEVC学习与研究】20、回顾:H.264的CABAC原理
3).归一化:
  在区间范围R离开合法范围之后,分割过程终止,并进行归一化操作。每次归一化时,会输入1个或多个码流字符,编码器中存在进位传送现象。
  4).编码终止:
  索引值为63的概率模型是特别设计的、非自适应的模型。这样,相关的表的入口TabRangeLPS[63,ρ]和Rlps由固定值2确定。这样确保在编码条带的终止语法元素end_of_slice_flag的时候输出7bit码字。

4、实验结果和总结
  采用了CABAC后,H.264的编码效率远远超过了基准档次、采用CAVLC的算法。在视频广播应用中,30-38db可接受的视频质量范围下,CABAC比CAVLC节省了9%-14%的码率,并且在更低码率的情况下,编码增益也更高。
【由于平时上班没多少时间,只能抽业余时间学,所以进度太慢,而且难以深入,单单是这一篇论文竟然看了将近一个月,而且也没能完全理解透彻。之前还剩下了一些问题没有解决,比如GOP、hierarchy B和IntraPeriod等等的概念,这些会在未来几天理解清楚。然后会找H.264的代码在实际场景中走一遍CABAC的过程。】
原创粉丝点击