📄 一句话概括
运动补偿就是用矢量加残差把当前块重建出来——预测得越准,残差越小,要编码的东西越少。
📝 本节和前面几节的关系
6.4.3 讲了运动矢量,这一节讲怎么用它把画面重建出来。
一、四步走
① 搜位置:在参考帧里找出与当前块最相似的块。 ② 记矢量:记下位移量——通常只要几个比特。 ③ 算残差:当前块减去参考块。 ④ 编码:矢量与残差一起送进后续的变换与量化。 前三步在编码端做,解码端做的正好是倒过来的事:按矢量取块、加上残差。
二、【准】是唯一的追求
整个运动补偿的收益,完全取决于第 ① 步找得准不准。 找得准 → 残差接近 0 → 后面几乎没什么要编的; 找不准 → 残差很大 → 等于白预测,甚至比帧内编码还亏。 所以现代编码器一大半的复杂度,都花在【怎么把位置找得更准】上。
三、亚像素精度
一个容易被忽略的细节:运动矢量可以带小数。 也就是说,参考块可以落在【参考帧两个像素之间】——这叫亚像素精度。 做法是在参考帧上先做插值,造出半像素、四分之一像素的位置。 精度越高,残差越小,代价是插值计算量上升——又是一次取舍。
四、它在整条链里的位置
顺序是:运动补偿 → 变换 → 量化 → 熵编码。 所以运动补偿的作用是把【帧与帧的差别】提取出来,变成一个小得多的残差块。 后面三步处理的,全是这个小残差——这就是时间冗余被真正兑现的地方。
五、动手 Demo:运动补偿的四步走
运动补偿就是用【矢量加残差】把当前块重建出来。
rows = [("1 搜位置", "在参考帧里找出最相似的块"),
("2 记矢量", "存下位移量,通常只几比特"),
("3 算残差", "当前块减去参考块"),
("4 编码", "矢量与残差一起送进变换与量化")]
for a, b in rows:
print("%-8s %s" % (a, b))
实跑输出:
--------------------------------------------------------------------
运动补偿的四步走
--------------------------------------------------------------------
运动补偿就是用【矢量加残差】把当前块重建出来。
步骤 做什么
------------------------------------------
1 搜位置 在参考帧里找出最相似的块
2 记矢量 存下位移量,通常只几比特
3 算残差 当前块减去参考块
4 编码 矢量与残差一起送进变换与量化
第 3 步是关键:**预测得越准,残差越小,后面要编码的东西就越少。**
所以现代编码器一大半的复杂度,**都花在【怎么把位置找得更准】上。**
第 3 步是关键:预测得越准,残差越小,后面要编码的东西就越少。 所以现代编码器一大半的复杂度,都花在【怎么把位置找得更准】上。
30 秒实验
- 想一下:如果拍一段【静止不动的场景】,码率会高还是低?
- 再想一下极端情况——完全静止时,理论上需要传什么。
常见误区
- 以为运动补偿是【把画面移回来】。它移的是预测块,画面本身不变。
- 忽略亚像素精度。它直接影响残差大小。
自测三问(点开对答案)
1. 运动补偿的四个步骤是什么? —— 搜位置、记矢量、算残差、编码。 2. 运动补偿的收益取决于什么? —— 参考块找得准不准——越准残差越小。 3. 什么是亚像素精度? —— 运动矢量可以带小数,参考块落在像素之间,需要先插值。- ☐ 下一节(6.4.5 双向预测)
相关笔记
- 运动矢量 — 它用的那个数据结构
- 双向预测 — 参考两个方向的版本
- 视频编码的关键技术 — 它在六项技术里的位置
- 🎬 FFmpeg入门详解 · 索引