Jiaolong's Blog Jiaolong's Blog
首页
分类
归档
Wiki
摘录
导航
留言
关于

Jiaolong

Solo Developer
首页
分类
归档
Wiki
摘录
导航
留言
关于
  • 理论

    • CABAC
      • 算术编码
        • 传统编码算法
        • 算术编码
        • 二进制算术编码
  • 源码

    • x264
    • 结构体
    • 源码分析
    • 运动估计
  • __x264
  • 理论
Jiaolong
2022-10-07
Catelog

CABAC

CABAC(Context-based Adaptive Binary Arithmetic Coding),基于上下文的自适应二进制算术编码。CABAC是H.264/AVC标准中两种熵编码中的一种,它的编码核心算法就是算术编码(Arithmetic Coding)。

# 算术编码

# 传统编码算法

算术编码与传统的编码方法有很大的区别,传统编码是通过符号映射实现的。映射包含符号(symbol)与码字(codeword)两个要素,如下面的例子

symbol e h l o
codeword 00 01 10 11

通过上述的映射表,我们可以把“hello”编码成码流 01 00 10 10 11。而诸如Haffuman,Shannon这些编码方法也没脱离这种编码模式,他们只是通过符号出现的概率对码字进行调优。

# 算术编码

算术编码采用的并非上述这种传统的单符号映射模式进行编码,它不是将单个符号映射成一个码字,而是从全序列出发,将输入的符号依据它的概率映射到[0,1)内的一个小区间上,如此递归地进行区间映射,最后得到一个小区间,从该区间内选取一个代表性的小数作为实际的编码输出。

如下面为算术编码的例子

symbol e h l o
probability 0.1 0.2 0.3 0.4

假设需要编码的符号只有“e”,“h”,“l”,“o”四个,他们出现的总概率为1,各个符号出现的概率如上述表格所示。现要求“hello”经过算术编码后的码字。

算术编码有如下编码步骤:

  1. 首先我们需要根据概率设定各符号在[0,1)上的初始区间,其中区间的起点为表中前面的符号的累计概率

    symbol e h l o
    sum of probability 0 0.1 0.1+0.2 0.1+0.2+0.3
    interval [0,0.1) [0.1,0.3) [0.3,0.6) [0.6,1)

    “hello”的第一个符号为“h”,那么映射的区间为[0.1,0.3)。

  2. 接下来我们需要根据符号的概率分割[0.1,0.3)上的区间,得到的结果如下

    symbol e h l o
    interval [0.1,0.12) [0.12,0.16) [0.16,0.22) [0.22,0.3)

    “hello”的第二个符号为“e”,那么映射的区间为[0.1,0.12)。

  3. 按照这种方式继续进行区间映射,最终“hello”映射到的区间是[0.10888,0.1096)

    映射区间 区间大小
    初始值 [0,1) 1
    编码完h后 [0.1,0.3) 0.2
    编码完e后 [0.1,0.12) 0.02
    编码完l后 [0.106,0.112) 0.006
    编码完l后 [0.1078,0.1096) 0.0018
    编码完o后 [0.10888,0.1096) 0.00072
  4. 从区间[0.10888,0.1096)中任取一个代表性的小数,如“0.109”就是编码“hello”后的输出值

    算术编码的总体的编码流程可以参考下图

    img

    img

    算术解码就只是需要判断代表性的小数在哪个区间,相应地就知道输入的符号了。

# 二进制算术编码

二进制算术编码的编码方法跟算术编码是一样的,但是输入只有两个符号:“0”,“1”,也就是说输入的是二进制串。除了是对二进制串进行编码这个特征外,二进制算术编码跟普通的算术编码还有一些区别,总体上可以按照如下进行描述: s

Last updated: 2022/12/04, 13:58:10

x264→

Copyright © 2022-2023 | Jiaolong Wang
  • 跟随系统
  • 浅色模式
  • 深色模式