H.265 熵编码
HEVC在熵编码环节的设计目标非常明确:在H.264高效的CABAC基础上,进一步提升压缩效率、降低上下文冗余,并从根本上解决并行处理的瓶颈。
1. 熵编码是什么?
熵编码是一种无损压缩技术。它的核心任务是将编码器产生的所有语法元素(Syntax Elements),如预测模式、运动矢量差、量化后的变换系数等,用尽可能少的比特来表示。
其基本原理是信息熵理论:为出现概率高的符号(Symbol)分配更短的码字,为出现概率低的符号分配更长的码字。
2. HEVC熵编码的核心:唯一的CABAC
HEVC做出了一个关键决策:在主档(Main Profile)中,只使用一种熵编码方法——上下文自适应二进制算术编码(Context-Adaptive Binary Arithmetic Coding, CABAC)。
这与H.264不同,H.264提供了两种选择:CAVLC(上下文自适应可变长编码,复杂度低)和CABAC(效率高,但复杂度也高)。HEVC通过对CABAC进行深度优化,使其在保持极高效率的同时,也变得更易于硬件实现和并行处理,从而不再需要一个低效的备用方案。
CABAC的工作流程可以分为三个核心步骤:
ASCII图表:CABAC流程
+----------------+   二值化   +------+   上下文建模   +--------------+   算术编码   +----------+
| Syntax Element | ---------> | Bins | ------------> | Probability  | ---------> | Bitstream|
| (e.g., MVD=3)  |            | (110)|               | (Context Model)|            | (0.0101..)|
+----------------+            +------+               +--------------+            +----------+
- 二值化 (Binarization)
    - 任务:将一个非二进制的语法元素值(例如,MVD=3,merge_idx=2)转换成一个二进制字符串,称为Bin String。
- 方法:HEVC引入了多种高效的二值化方案,如截断莱斯(Truncated Rice, TR)编码、截断一元码、固定长度编码等,比H.264中主要使用的一元码和指数哥伦布码更加灵活和高效,特别是对MVD和残差系数的幅值编码。
 
- 任务:将一个非二进制的语法元素值(例如,MVD=3,
- 上下文建模 (Context Modeling)
    - 任务:为每一个Bin选择一个合适的概率模型。这是“上下文自适应”的关键。
- 原理:一个Bin是0还是1的概率,往往与其“上下文(Context)”高度相关。例如,一个低频区域的残差系数,其第一个Bin(表示“是否非零”)为1的概率,远大于一个高频区域的系数。
- 实现:HEVC维护着一个概率状态机集合(称为上下文模型)。编码器会根据当前Bin所属的语法元素类型、其在块中的位置、以及其邻近已编码符号的值等信息,来选择一个最合适的上下文模型。这个模型会提供一个对当前Bin值为“1”的概率的估计。
 
- 二进制算术编码 (Binary Arithmetic Coding)
    - 任务:这是真正的编码引擎。它接收一个Bin(0或1)和它对应的概率模型。
- 原理:算术编码将整个比特流视为在[0, 1)区间内的一个小数。每编码一个Bin,它都会根据该Bin的值和概率,将当前区间“缩放”到一个更小的子区间。最终,输出一个落在该终极子区间内的、最短的二进制小数,作为压缩后的比特流。
- 优势:它可以为一个符号分配小数个比特,无限逼近其信息熵,因此压缩效率极高。
 
3. 关键流程:残差系数的编码
残差系数通常是码率的主要贡献者,HEVC对其编码流程进行了精心设计。
- 分组与扫描: 变换系数块(如16x16)被划分为多个4x4的子块。在子块内部和子块之间,系数按反对角线扫描顺序被一维化。
- 关键信息分离: HEVC不直接编码系数的值,而是将其分解为多个语法元素进行编码,每个元素都有高度优化的上下文模型。
    - last_sig_coeff_x / _y: 首先编码最后一个非零系数在块中的坐标。这极大地提高了效率,因为解码器知道了数据在哪里结束,后面的就全是0了。
- coded_sub_block_flag: 对每个4x4子块,先用一个标志位指示该子块是否全为0。如果是,则直接跳过,节省大量信令。
- sig_coeff_flag: 在非全零的子块内,为每个位置编码一个标志,指示该位置的系数是否非零。
- 幅值和符号信息: 对于非零系数,再继续编码三个信息:
        - coeff_abs_greater1_flag: 绝对值是否大于1。
- coeff_abs_greater2_flag: 绝对值是否大于2。
- coeff_abs_level_remaining: 剩余的幅值(使用TR编码)。
- coeff_sign_flag: 系数的符号(正/负)。
 
 
这种精细的、分步骤的信息编码方式,使得CABAC可以为每个决策(Bin)都找到一个极具针对性的上下文模型,从而达到极致的压缩。
4. HEVC的并行处理特性
这是HEVC熵编码相对H.264最大的架构性优势,旨在充分利用现代多核CPU/GPU。
4.1. Tiles (瓦块)
- 概念:可以将一帧图像分割成多个矩形的Tiles。每个Tile都可以被视为一个独立的子图像。
- 优势:Tiles之间没有任何数据依赖。它们的熵编码和解码过程可以完全独立、并行地进行。这是一种非常简单粗暴但极其有效的并行方案。
ASCII图表:Tiles划分
+------------------+------------------+
|                  |                  |
|      Tile 0      |      Tile 1      |
|                  |                  |
+------------------+------------------+
|                  |                  |
|      Tile 2      |      Tile 3      |
|                  |                  |
+------------------+------------------+
4.2. WPP (Wavefront Parallel Processing, 波前并行处理)
- 概念:一种更细粒度的并行技术。它将CTU行(Row of CTUs)作为处理单元。
- 工作原理:
    - 每一行的熵编码上下文,只依赖其上一行的熵编码状态。
- 在同一行内,CTU之间没有串行依赖。
- 编码开始时,第一行正常编码。当第二行的第一个CTU开始编码时,它需要等待第一行的第二个CTU编码结束,以获取其“右上方”的上下文状态。
- 一旦这个依赖满足,第二行的所有CTU就可以并行开始编码,形成一个“波浪”状向前推进的处理阵线。
 
ASCII图表:WPP处理流程 ([C_ij] 表示第i行第j列的CTU)
Time ->
T1    T2    T3    T4
|     |     |     |
V     V     V     V
[C_00] [C_01] [C_02] [C_03] ...  (Row 0: Serial)
      \     \     \
       [C_10] [C_11] [C_12] ...  (Row 1: Parallel processing starts)
             \     \
              [C_20] [C_21] ...  (Row 2: Parallel processing starts)
WPP在提供高并行度的同时,几乎不损失编码效率(通常小于1%),因为它保留了帧内的上下文依赖,是一种非常优雅的并行设计。
总结
HEVC的熵编码系统是一个集大成者:
- 统一高效: 全面采用并优化了CABAC,摒弃了低效的备用方案。
- 精细建模: 通过更优的二值化方案和高度定制的上下文模型,尤其是在残差编码上,进一步逼近信息熵极限。
- 为并行而生: 内置了Tiles和WPP两种强大的并行工具,从根本上解决了H.264中熵编码难以并行的问题,为4K/8K等超高清视频的实时处理铺平了道路。