🎬 第八章 音视频编解码技术与流程
📄 一句话概括

帧内与帧间是一对镜像:帧内压得少但断得干净,帧间压得多但牵着别人——所以健康的码流里两者必须都有。

📝 本节和前面几节的关系

8.3.1 到 8.3.3 讲的是【帧之间】的事,从这一节开始钻进帧内部。

一、一对镜像

两种编码方式的差别,几乎处处对称: 参考来源——帧内用本帧已解码的相邻像素,帧间用前后帧的对应块; 压缩比——帧内约 5~10 倍,帧间可达 50 倍以上; 计算量——帧内小(只在几个方向里选),帧间大(要在参考帧里搜索); 错误传播——帧内只影响本块,帧间会沿参考链一路传下去。 这四个维度是同一件事的不同侧面:参考范围越大,压得越多、也越不干净。

二、为什么两者都不能少

既然帧间编码压得多,为什么不全用帧间? 因为帧间需要一个【起点】——总得有一块不依赖别人的数据,否则解码器无从开始; 而且场景切换、剧烈运动时,前后帧几乎没关系,帧间预测找不到好参考,反而比帧内还差; 再考虑抗丢包——全帧间的链条一断,后面全废。 所以 I 帧的存在不是【保守】,而是结构上必需。

三、编码器怎么在两者之间选

面对一个块,编码器的选择逻辑很朴素——试,然后比: 先用帧内预测算一遍,得到残差与代价; 再用帧间预测算一遍,得到残差与代价; 加上各自要写入码流的【附加信息】(模式、运动矢量),取总代价小的那个; 代价通常用 率失真代价衡量:位数加权的失真。 这就是 8.2 里说的【搜索与决策】——标准不管,各家自由发挥。

四、帧内编码的压缩上限从哪来

帧内编码只能靠空间冗余,天花板不高,原因很直接: 它处理的残差本来就小(相邻像素差别不大),能榨的油水有限; 它没有运动补偿这种【整块搬运】的利器,只能靠预测方向猜; 所以 I 帧的码率通常是 P 帧的几倍、B 帧的十倍上下。 这也解释了为什么 GOP 不能太短——I 帧一多,平均码率立刻被抬上去。

五、两条线的分工

把这一节和前面几节接起来,就得到了完整的分工图: 帧内编码——负责【起点】,产出 I 帧; 帧间编码——负责【主体】,产出 P 帧与 B 帧; 两者按 GOP 的节奏交替出现,共同决定了这段视频的压缩比与拖动手感。 下一节把镜头再推近一层——帧内编码内部的流程。

六、动手 Demo:帧内与帧间,一对镜像

同一帧里两种编码方式的分工,几乎是完全对称的。

rows = [("参考来源", "本帧相邻像素", "前后帧对应块"),
        ("压缩比", "约 5~10 倍", "可达 50 倍以上"),
        ("计算量", "小", "大(要搜索)")]
for a, b, c in rows:
    print("%-8s 帧内 %-14s 帧间 %s" % (a, b, c))

实跑输出:

--------------------------------------------------------------------
帧内与帧间,一对镜像
--------------------------------------------------------------------

同一帧里两种编码方式的分工,几乎是完全对称的。

  维度         帧内编码                 帧间编码
  -----------------------------------------------------------
  参考来源     本帧已解码的相邻像素     前后帧的对应块
  压缩比       低(约 5~10 倍)         高(可达 50 倍以上)
  计算量       小                       大(要搜索)
  典型用途     I 帧、场景切换处         P 帧、B 帧
  错误传播     只影响本块               会沿参考链往后传

  一句话总结这对镜像:
  **帧内编码压得少但断得干净,帧间编码压得多但牵着别人。**
  所以一个健康的码流里**两者都要有**——全靠帧内码率太高,全靠帧间一错全错。

帧内编码压得少但断得干净,帧间编码压得多但牵着别人。 所以一个健康的码流里两者都要有——全靠帧内码率太高,全靠帧间一错全错。

30 秒实验

  1. 用码流分析工具看一段视频里 I 帧与 P 帧的平均大小之比,算算差几倍。
  2. 找一段有场景切换的视频,看看切换处是不是插了一个 I 帧。

常见误区

  1. 以为帧内编码【技术落后】。它是结构的起点,没有它帧间编码无法开始。
  2. 以为帧间编码永远更好。场景切换或剧烈运动时帧内反而更划算。
  3. 以为编码器会固定用某一种。它逐块比较代价,是动态选择的。
自测三问(点开对答案) 1. 帧内与帧间编码的参考来源分别是什么? —— 前者用本帧已解码的相邻像素,后者用前后帧的对应块。 2. 为什么不能全用帧间编码? —— 帧间需要起点,且场景切换与丢包场景下必须靠帧内兜底。 3. 编码器怎么在两者之间选择? —— 分别算出率失真代价,取总代价小的那种。

相关笔记