2. H.264编码原理(上):帧内预测、帧间预测、运动估计与补偿

H.264 为什么能比 MPEG-2 省一半码率?说白了,就是它把「预测」这件事做到了极致。今天咱们先聊上半部分——帧内预测、帧间预测,还有运动估计与补偿。这几个概念你搞懂了,H.264 的骨架也就搭起来了。

2.1 帧内预测:空间上的「抄邻居」

帧内预测,我习惯叫它「空间预测」。它不依赖其他帧,只靠当前帧里已经编好的像素,去猜当前块长什么样。

举个例子:你有一面纯蓝色的墙,编码器只需要存「这面墙是蓝色」和「从哪个方向开始渐变」,而不是存每个像素的 RGB 值。这就是帧内预测的核心思路——利用图像在空间上的相关性,去掉冗余。

2.1.1 4×4 亮度块的 9 种预测模式

H.264 对 4×4 亮度块定义了 9 种预测模式。我当年第一次看到这个表时,心想:有必要搞这么复杂吗?后来调优时才发现,每种模式对应一种纹理走向,选对了能省不少码流。

模式编号 预测方向 适用场景
0 垂直 竖条纹纹理
1 水平 横条纹纹理
2 DC(均值) 平坦区域
3 左下对角线 45° 斜纹理
4 右下对角线 135° 斜纹理
5 垂直偏右 接近垂直的斜纹理
6 水平偏下 接近水平的斜纹理
7 垂直偏左 另一方向斜纹理
8 水平偏上 另一方向斜纹理
我的经验:DC 模式(模式 2)是最安全的兜底方案。如果你不确定选哪个,选 DC 至少不会出大错。但想压码率,就得老老实实做 RDO(率失真优化),遍历所有模式选最优。

2.1.2 16×16 亮度块的 4 种模式

对于大块的平坦区域,4×4 的 9 种模式有点杀鸡用牛刀了。H.264 又给了 16×16 的 4 种模式:垂直、水平、DC、平面(Plane)。平面模式能模拟渐变背景,比如天空从蓝到白的过渡。

我记得有一次做视频会议系统,背景是一面白墙,用 16×16 的 DC 模式就能搞定,码率直接砍掉 30%。

2.2 帧间预测:时间上的「抄前帧」

帧间预测就更直接了——找参考帧里最像当前块的那一块,然后只存两者的差异。这就是运动估计和运动补偿干的事。

2.2.1 运动估计:找「最像」的那一块

运动估计的核心是搜索。编码器在参考帧里划一个搜索窗口,然后一块一块地比对,找到匹配度最高的位置。

常用的搜索算法有几种:

  • 全搜索:穷举所有位置,精度最高,但计算量爆炸。我在嵌入式平台上试过,跑 1080p 全搜索,帧率直接掉到个位数。
  • 菱形搜索:从中心开始,按菱形模式向外扩散。速度快,精度也还行,是工程中最常用的。
  • 六边形搜索:比菱形更快,适合大运动场景。
避坑指南:我曾经在移动端项目里用了全搜索,结果发热严重,被测试同学追着骂。后来换成菱形搜索 + 提前终止阈值,效果好了很多。记住:实时系统里,速度比精度更重要。

2.2.2 运动补偿:算出差值

找到匹配块之后,编码器计算当前块和参考块的差值(残差),然后只编码这个残差。解码时,解码器用参考块加上残差,就能还原出当前块。

运动补偿的精度可以到 1/4 像素。为什么?因为真实世界的运动很少刚好落在整数像素上。H.264 支持 1/4 像素插值,用六抽头滤波器算出亚像素位置的像素值。

关键点:1/4 像素精度比整数像素精度能省 10%~20% 的码率,但计算量也翻倍。这是典型的「用算力换带宽」的 trade-off。

2.3 帧内 vs 帧间:什么时候用哪个?

这个问题我经常被问到。简单说:

  • I 帧(关键帧):只用帧内预测。场景切换、视频开头、随机接入点,必须用 I 帧。
  • P 帧(前向预测帧):用帧间预测,参考前面的帧。
  • B 帧(双向预测帧):参考前后两帧,压缩率最高,但延迟也最大。

我个人的习惯是:直播场景少用 B 帧,因为 B 帧会引入延迟;点播场景可以多用 B 帧,省码率。

2.4 知识体系总览

下面这张图把 H.264 编码的核心流程串起来了。你可以看到帧内预测和帧间预测是两条并行的路径,最终汇合到变换量化环节。

H.264 编码核心流程 当前帧(输入) 帧内预测(空间) 4×4 九模式 / 16×16 四模式 帧间预测(时间) 运动估计 + 运动补偿 参考帧缓存 预测块 残差 = 当前块 - 预测块 变换 → 量化 → 熵编码 帧内预测和帧间预测是两条并行路径,最终通过残差计算汇合到变换量化环节

2.5 运动估计的工程细节

运动估计不是简单比一比就完事了。有几个参数直接影响编码质量和速度:

  • 搜索范围:比如 [-16, +16] 像素。范围越大,越能找到全局最优,但计算量也越大。
  • 块大小:H.264 支持从 4×4 到 16×16 的多种块大小。大块适合平坦区域,小块适合细节丰富的区域。
  • 参考帧数量:最多可以引用 16 个参考帧。参考帧越多,压缩率越高,但解码器压力也越大。
我的建议:做嵌入式开发时,搜索范围设到 [-8, +8] 就够了。别贪心,否则你的 CPU 会哭的。

2.6 小结

帧内预测和帧间预测是 H.264 的两大支柱。帧内预测靠空间冗余,帧间预测靠时间冗余。运动估计和补偿则是帧间预测的具体实现手段。

嗯,这里要注意:帧内预测虽然叫「帧内」,但它并不是完全不依赖外部信息——它依赖的是当前帧里已经编好的像素。所以编码顺序和解码顺序必须一致,否则预测就乱了。