4. 预测编码(上):帧内预测原理,H264的9种Intra 4x4模式与DC模式

各位同学,今天我们进入视频编码里最核心的一个环节——预测编码。说白了,预测编码就是「猜」。编码器不直接存像素值,而是先猜这个像素大概是多少,然后只存「猜错了多少」。这个差值通常很小,压缩起来就特别省空间。

我刚开始接触编码时,觉得这玩意儿挺玄乎。后来自己动手写了一个简易的帧内预测模块,才真正理解——帧内预测的本质,就是用已经编好的像素,去推算还没编的像素。

4.1 为什么需要帧内预测?

先想一个问题:一张纯蓝色的天空图片,每个像素都是 (0, 0, 255)。如果直接存每个像素的值,数据量很大。但如果我只存第一个像素,然后告诉解码器「后面每个像素都和前面一样」,那后面的像素只需要存一个「和前面相同」的标记,是不是省了很多?

帧内预测就是这个思路的升级版。它不只在水平方向复制,而是支持多个方向——斜着、竖着、甚至取平均值。

核心思想: 利用空间冗余。相邻像素之间,颜色和亮度通常变化不大。预测越准,残差越小,压缩率越高。

4.2 H.264 的 Intra 4x4 预测:9 种方向模式

H.264 针对 4x4 大小的块,定义了 9 种预测模式。为什么是 4x4?因为小块能更好地适应图像细节——纹理变化剧烈的地方,用小块预测更准。

这 9 种模式里,有 8 种是方向预测,1 种是 DC 模式(平均值模式)。我习惯把它们分成三类来记:

  • 水平类: 模式 1(水平预测)
  • 垂直类: 模式 0(垂直预测)
  • 对角线类: 模式 3~8(各种斜向预测)
  • 平面类: 模式 2(DC 模式)

下面这张图,是我当年学习时自己画的,能帮你直观理解这 9 种模式的预测方向:

H.264 Intra 4x4 预测模式方向示意图 当前 4x4 块 上方参考像素 左侧参考像素 模式 0(垂直) 模式 1(水平) 模式 2(DC):取上方和左侧参考像素的平均值 模式 3(左下) 模式 4(右下) 模式 5(垂直偏右) 模式 6(水平偏下) 模式 7(垂直偏左) 模式 8(水平偏上)

4.3 方向预测的直觉理解

方向预测到底怎么工作的?我举个例子你就明白了。

假设当前要预测 4x4 块里第 0 行第 0 列的像素(左上角第一个)。

  • 模式 0(垂直预测): 直接用正上方那个像素的值。如果上方像素是 128,那这个像素就预测为 128。
  • 模式 1(水平预测): 直接用左边那个像素的值。
  • 模式 4(右下对角线预测): 沿着 45 度方向,用左上角的像素来预测。

你想想看,如果图像里有一条斜着的边缘,用模式 4 去预测,残差就会非常小。但如果用垂直预测,边缘处就会产生很大的误差。

我的经验: 在实际编码中,编码器会遍历所有 9 种模式,选残差最小的那个。但如果你知道图像纹理方向(比如通过边缘检测),可以优先尝试对应方向的模式,能省不少计算量。

4.4 DC 模式:最稳妥的「平均主义」

DC 模式是 9 种模式里最特殊的一个。它不沿任何方向预测,而是取上方和左侧参考像素的平均值。

公式很简单:

// 假设上方有 4 个参考像素 A0, A1, A2, A3
// 左侧有 4 个参考像素 B0, B1, B2, B3
// DC 值 = (A0 + A1 + A2 + A3 + B0 + B1 + B2 + B3 + 4) / 8
// 加 4 是为了四舍五入

uint8_t dc_value = (sum_above + sum_left + 4) >> 3;

DC 模式的好处是——它永远不会太差。即使方向预测全部猜歪,DC 模式至少能给出一个「平均水准」的预测。我在做移动端编码器时,经常把 DC 模式作为默认模式,因为它的计算量最小,硬件实现也最简单。

注意: DC 模式在平坦区域表现很好,但在纹理丰富的区域,残差会比较大。我曾经在一个项目里遇到过——整张图都是 DC 模式,结果码率飙升了 30%。后来加了方向预测,才降下来。

4.5 9 种模式的完整列表

为了方便你查阅,我把 9 种模式整理成了一张表:

模式编号 模式名称 预测方向 适用场景
0 垂直 从上到下 水平纹理
1 水平 从左到右 垂直纹理
2 DC 平均值 平坦区域
3 左下对角线 45° 左下 右上到左下边缘
4 右下对角线 45° 右下 左上到右下边缘
5 垂直偏右 偏右 22.5° 接近垂直的斜边
6 水平偏下 偏下 22.5° 接近水平的斜边
7 垂直偏左 偏左 22.5° 接近垂直的斜边(反向)
8 水平偏上 偏上 22.5° 接近水平的斜边(反向)

4.6 帧内预测的完整流程

最后,我把帧内预测在编码器里的完整流程梳理一下。嗯,这里要注意,预测只是第一步,后面还有变换、量化、熵编码。但今天我们只聚焦预测部分:

  1. 获取参考像素: 从当前块的上方和左侧,取出已经重建好的像素。
  2. 遍历预测模式: 对 9 种模式(4x4 块)或 4 种模式(16x16 块),分别计算预测块。
  3. 计算残差: 原始像素减去预测像素,得到残差块。
  4. 选择最优模式: 用率失真优化(RDO)选残差最小、码率最低的模式。
  5. 编码模式信息: 把选中的模式编号写入码流,解码器用同样的方式重建。
关键点: 解码器必须能用「已经解码的像素」做预测。所以编码器和解码器用的参考像素必须完全一致——这就是为什么帧内预测要用「重建后的像素」,而不是原始像素。

好了,帧内预测的原理和 H.264 的 9 种 Intra 4x4 模式就讲到这里。方向预测的直觉其实很简单——沿着图像纹理的方向去猜,猜中的概率最大。DC 模式则是「实在不行就取平均」,虽然不惊艳,但永远不会翻车。