4. 帧间预测:运动估计与运动补偿
帧间预测,说白了就是利用视频里相邻帧的相似性来压缩数据。你想想看,一段视频里,背景通常是不动的,动的只是前景物体。如果我们能把「哪里动了、怎么动的」这个信息编码进去,而不是每帧都重新画一遍,压缩效率自然就上来了。
H.265 的帧间预测比 H.264 复杂得多,但也灵活得多。我个人习惯把帧间预测拆成四个核心模块来理解:运动估计、运动补偿、Merge/AMVP 模式选择,以及亚像素插值。下面我们一个一个说。
4.1 运动估计与运动补偿
运动估计是在参考帧里找当前块的最佳匹配位置。编码器会遍历一个搜索范围,用某种匹配准则(比如 SAD、SATD)来评估每个候选位置的好坏。
运动补偿则是根据找到的运动矢量,从参考帧里「抠」出预测块,然后和当前块做差,得到残差。残差越小,说明预测越准,编码需要的比特就越少。
核心公式:
当前块 = 预测块 + 残差块
残差块 = 当前块 - 预测块
预测块 = 参考帧(当前坐标 + 运动矢量)
我在项目中遇到过一个问题:运动估计的搜索范围设得太大,编码时间直接翻倍。后来我学乖了,根据视频分辨率和帧率动态调整搜索范围——1080p 的视频,搜索范围 ±64 就够用了,4K 才需要 ±128。
4.2 Merge 模式与 AMVP
H.265 引入了两种运动矢量编码模式:Merge 和 AMVP(Advanced Motion Vector Prediction)。它们的目的都是减少运动矢量本身的编码开销。
4.2.1 Merge 模式
Merge 模式的核心思想是:当前块的运动矢量直接从相邻块「继承」过来,编码器只需要传一个索引,告诉解码器用哪个候选块的运动信息就行。
Merge 候选列表最多包含 5 个候选,来源包括:
- 空间候选:当前块左侧、上方、右上、左下的相邻块
- 时间候选:同位置或邻近位置的已编码帧中的块
- 组合候选:对 B 帧,还可以把两个单向预测组合成双向预测
- 零矢量候选:兜底用的,保证列表长度固定
我的经验:Merge 模式在平坦区域和静止背景上效果特别好。我曾经在一个监控视频编码项目里,把 Merge 模式的使用率从 40% 提到了 70%,码率直接降了 15%。
4.2.2 AMVP 模式
AMVP 和 Merge 不同,它只预测运动矢量的「起点」,然后编码器还需要传一个运动矢量差值(MVD)。AMVP 候选列表只有 2 个候选,来源也是空间和时间相邻块。
| 特性 | Merge 模式 | AMVP 模式 |
|---|---|---|
| 传输内容 | 仅候选索引 | 候选索引 + MVD |
| 候选数量 | 最多 5 个 | 2 个 |
| 适用场景 | 运动简单、残差小 | 运动复杂、需要精细调整 |
| 编码开销 | 低 | 中 |
嗯,这里要注意:AMVP 的候选列表构建和 Merge 不完全一样。AMVP 的空间候选只取左侧和上方两个位置,而且会做缩放处理——因为参考帧可能不同。
4.3 亚像素插值
真实世界的运动很少是整像素对齐的。物体可能移动了 0.3 个像素,或者 1.7 个像素。为了捕捉这些非整数运动,H.265 支持 1/4 像素精度的运动矢量。
亚像素位置的像素值怎么来?靠插值。H.265 使用 8 抽头 DCT 插值滤波器(亮度分量)和 4 抽头滤波器(色度分量)。
我曾经踩过的坑:亚像素插值的计算量非常大。有一次我在嵌入式平台上跑编码器,发现运动估计占了 60% 的 CPU 时间,其中一半都花在亚像素插值上。后来我做了两件事:一是提前把参考帧的亚像素位置全部插好存起来(预插值),二是对平坦区域直接跳过亚像素搜索。编码速度提升了 2 倍。
插值过程分两步:
- 水平插值:用 8 抽头滤波器对整像素行做水平方向的 1/2 和 1/4 插值
- 垂直插值:用同样的滤波器对水平插值结果做垂直方向的插值
说白了,就是先算水平方向,再算垂直方向,两个方向组合起来就能得到任意 1/4 像素位置的值。
4.4 参考帧管理
H.265 的参考帧管理比 H.264 灵活得多。它引入了 参考帧列表 的概念,每个 P 帧或 B 帧都可以从多个参考帧中选择最佳参考。
参考帧列表分为三种:
- List0:前向参考帧列表,用于 P 帧和 B 帧
- List1:后向参考帧列表,仅用于 B 帧
- 组合列表:B 帧双向预测时,从 List0 和 List1 中选取组合
参考帧的管理通过 DPB(Decoded Picture Buffer) 来实现。DPB 的大小有限,编码器需要决定哪些帧保留、哪些帧丢弃。
参考帧选择策略(我的推荐):
- 对低延迟场景:只保留最近 2-4 帧,减少 DPB 压力
- 对随机访问场景:定期插入 IDR 帧,重置参考帧列表
- 对高压缩比场景:保留更多参考帧(最多 16 帧),但注意内存开销
我记得有一次做视频会议编码,发现参考帧管理没做好,导致解码器端出现了参考帧缺失的问题。原因是编码器用了 B 帧做长期参考,但解码器的 DPB 太小,存不下那么多帧。从那以后,我养成了一个习惯:编码器和解码器的 DPB 配置必须对齐,否则就会出现花屏或卡顿。
4.5 本章知识体系
下面这张图把帧间预测的核心模块和它们之间的关系画出来了,方便你整体把握。
从这张图你可以看到,帧间预测的四个模块是环环相扣的。运动估计找到最佳匹配,运动补偿生成预测块,Merge/AMVP 决定如何高效编码运动矢量,亚像素插值则保证了运动估计的精度。而参考帧管理,则是这一切的基础——没有好的参考帧,再好的预测算法也是白搭。
一句话总结:帧间预测的核心就是「用已有的帧,猜当前帧」。猜得越准,压缩率越高。而猜得准不准,取决于运动估计的精度、Merge/AMVP 的候选质量、亚像素插值的准确性,以及参考帧管理的合理性。