标题:Context-adaptive binary arithmetic coding. Part 3 链接:https://www.elecard.com/page/article_context_adaptive_binary_arithmetic_coding_3 整理人:何冰 内容摘要:本文是对 ELECARD Video Compression Book 第八章的翻译。
CABAC(上下文自适应二进制算术编码)这一名称本身就意味着 HEVC 使用二进制版本的算术编码,其中输入信息字母表仅由 0 和 1 两个字符组成。 为了区分表示编码结果的输出流比特和表示编码信息的二进制字符,我们使用 "bins "一词来指代这些字符。让我们看看在第 7 章图 2 至图 4 所示的流程图中,如果考虑到被编码信息的二进制性质,会有什么变化。
首先要注意的是,过去表示报文结束的 EOF 字符不再是字母表的一部分。在解码时需要知道信息的结束点,否则即使正确解码了整个信息,解码过程仍将继续。我们稍后将探讨如何在 HEVC 中传输信息结束点信息,现在只想指出需要实施一个传输该信息的程序。
如果要编码的信息中只有两个不同的字符,还会有什么变化?存储累积字符概率的数组
将只包含三个值:
=
。其中
是更有可能出现在信息中的字符的概率(如果我们从 20 个字符的信息 {b, a, b, b, b, b, b, b, b, b, b, a, b, b, b, b, b, b, b, EOF} 中剔除 EOF 字符,信息长度将变为 19 个字符,更有可能出现的字符 "b "的概率将等于 17/19 ). 这意味着当前区间
将在编码过程中的每次迭代中被分成两部分。较大部分的长度由概率
决定,而较小部分的长度则由
决定. 数组
因此基本上退化为一个数字。这个数字可以是
,也可以是
。
在此之前,编码时要分割的区间在数轴上的位置是由区间端点
和
的位置决定的。显然,我们也可以用数字
来描述算术编码过程的当前状态(区间在数轴上的位置)其中
为区间长度。这就是 HEVC 所使用的描述方法。
现在,让我们把表征迭代分割时区间各部分之间比率的数字表示为
。 HEVC 标准符号中,
是待编码序列中最有可能的编码单元的值(0 或 1)、
是当前正在编码的编码单元的值、
是左间隔端点的位置(如前所述),以及
是当前区间长度。如果当前编码的编码单元的值等于
,则
和
的新值可以根据其当前值和
计算得:
如图 1 所示:
图 1 :当
时,计算
和
。
如果当前编码的编码单元的值不等于
,则
和
的新值可以被表示为:
如图 2 所示:
图2
结果是一个略有更新的流程图(图 3),现在描述的是二进制算术编码。
图 3 :二进制编码程序流程图
虽然二进制编码可以不修改重正化程序,但对它做一些小修改可以在一定程度上简化算法,节省计算量。使用新的符号
和
,重正化过程在一个 while
循环中执行,而如果同时
, 则编码位的值为 0。如果
, 则编码位的值为 1(为简单起见,我们仅在此说明;第 2 部分的图 2 和相关说明文字中详细描述了这一过程)。显然,当
,编码位的值也将完全确定。如果同时有
, 当前区间将被全包含在区间
, 因此编码比特值为 0 。如果
但是
,当前区间被全包含在区间
, 因此编码的比特值为1。修改后的重正化编码程序流程图如图 4 所示。
图 4 :修改后的重正化编码程序流程图
现在让我们看看编码信息的二进制性质将如何改变解码过程。在这种情况下,算术解码程序包括将当前区间反复分割成两个部分,其长度分别与
和
成比例。每次迭代时,都要进行检查,以确定所产生的两个区间中哪一个包含了代表编码信息的二进制数。这就是当前区间。
让
成为一个变量,其中包含编码信息的几个比特(我们在此使用 HEVC 符号表示该变量)。如前所述,我们用当前区间的左端点
和长度
来描述它。解码过程如图 5 所示,图中显示了两次连续的迭代。在第一次迭代中,数字
(其在当前区间内的位置用圆圈表示)位于区间
内。因此,解码后的字节等于
。在第二次迭代中,数字
位于更小的区间内,解码后的字节等于 valMPS。
图 5 :解码过程中的间隔分割
从上图可以看出,每次迭代的区间选择是通过比较
的值和区间
的右侧端点来确定的。当
位于与概率
相对应的较大区间内时,
会得到一个新值
,而
则保持不变。当
位于与概率
相对应的较小区间内时,左区间端点被重新定义为
,
得到一个新值
。请注意,在第二种情况下,我们可以通过给
赋值
来修改
,而不是修改
。现在,
的值所表征的不是代表编码信息的二进制数本身,而是该二进制数相对于当前区间左端点的位置。在这种情况下,解码过程中不再使用 L。在每次迭代时,我们只需比较
和
,就能决定哪个区间成为当前区间。解码算法的流程图如图 6 所示。
图6 :解码算法流程图
为二进制编码重新定义
的含义也会导致重正化过程发生重大变化(简化)。当当前区间长度小于
时,将调用重正化程序。由于
现在是代表编码信息的数字与当前区间左端点之间的差值,重正化程序只需无条件地将
的值加倍,然后将编码信息中的一个比特添加到空闲的比特位置,从而提高
值的精度。 . 二进制解码过程中改进的重归一化算法流程图如图 7 所示。
图7 :解码过程中的重正化算法流程图
这个流程图调用了一个名为 read_bit() 的函数,从它的名字就可以看出其目的:该函数从代表编码信息的比特流中读取下一位。它还使用了 C 语言中的符号"|",表示位操作 OR。