🎬 第六章 音视频压缩编码基础
📄 一句话概括

运动补偿就是用矢量加残差把当前块重建出来——预测得越准,残差越小,要编码的东西越少。

📝 本节和前面几节的关系

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. 再想一下极端情况——完全静止时,理论上需要传什么。

常见误区

  1. 以为运动补偿是【把画面移回来】。它移的是预测块,画面本身不变。
  2. 忽略亚像素精度。它直接影响残差大小。
自测三问(点开对答案) 1. 运动补偿的四个步骤是什么? —— 搜位置、记矢量、算残差、编码。 2. 运动补偿的收益取决于什么? —— 参考块找得准不准——越准残差越小。 3. 什么是亚像素精度? —— 运动矢量可以带小数,参考块落在像素之间,需要先插值。

相关笔记