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 | 水平偏上 | 另一方向斜纹理 |
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 编码的核心流程串起来了。你可以看到帧内预测和帧间预测是两条并行的路径,最终汇合到变换量化环节。
2.5 运动估计的工程细节
运动估计不是简单比一比就完事了。有几个参数直接影响编码质量和速度:
- 搜索范围:比如 [-16, +16] 像素。范围越大,越能找到全局最优,但计算量也越大。
- 块大小:H.264 支持从 4×4 到 16×16 的多种块大小。大块适合平坦区域,小块适合细节丰富的区域。
- 参考帧数量:最多可以引用 16 个参考帧。参考帧越多,压缩率越高,但解码器压力也越大。
2.6 小结
帧内预测和帧间预测是 H.264 的两大支柱。帧内预测靠空间冗余,帧间预测靠时间冗余。运动估计和补偿则是帧间预测的具体实现手段。
嗯,这里要注意:帧内预测虽然叫「帧内」,但它并不是完全不依赖外部信息——它依赖的是当前帧里已经编好的像素。所以编码顺序和解码顺序必须一致,否则预测就乱了。