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

B 帧同时参考前后两个方向,残差最小所以最省码率——代价是它必须先解码后面的帧,这就是 DTS 与 PTS 要分开的原因。

📝 本节和前面几节的关系

6.4.4 讲了单方向的运动补偿,这一节讲参考两个方向的版本。

一、三种预测方式

前向预测:只参考前一帧——延迟最低。 后向预测:只参考后一帧——需要先缓存后面的帧。 双向预测:前后都参考,取加权平均——残差最小。 所以 B 帧在码率上最划算,但在时序上最麻烦。

二、为什么双向更省

因为两个参考方向提供的信息是互补的: 前一帧告诉你【它从哪儿来】,后一帧告诉你【它要到哪儿去】。 两者的加权平均往往比任何单个参考都更接近目标——残差自然更小。 这就是 B 帧能压到 I 帧 15% 左右的原因。

三、代价:必须重排序

因为 B 帧要等后面的帧,所以解码顺序与显示顺序不再一致。 编码器必须把【该显示的顺序】与【该解码的顺序】都写进码流—— 前者是 PTS,后者是 DTS。 6.5.3 会给出一个具体的顺序例子,这里先把原因记住。

四、什么时候不用 B 帧

低延迟场景(视频会议、直播)常常禁用 B 帧: 因为 B 帧要缓存后续帧,会引入额外的延迟; 而且一旦丢包,重排序会变得更复杂。 所以在【省码率】与【低延迟】之间,B 帧是一个明确的取舍开关。

五、动手 Demo:双向预测为什么能再省一半

B 帧同时参考前后两个方向,取两者的加权平均。

rows = [("前向预测", "前一帧", "中等", "低延迟"),
        ("后向预测", "后一帧", "中等", "要缓存"),
        ("双向预测", "前后两帧", "最小", "要重排序")]
for a, b, c, d in rows:
    print("%-8s %-10s %-8s %s" % (a, b, c, d))

实跑输出:

--------------------------------------------------------------------
双向预测为什么能再省一半
--------------------------------------------------------------------

B 帧同时参考前后两个方向,取两者的加权平均。

  预测方式     参考         残差大小     代价
  ------------------------------------------------
  前向预测     前一帧       中等         低延迟
  后向预测     后一帧       中等         要缓存
  双向预测     前后两帧     最小         要重排序

  双向预测的残差最小,**所以 B 帧最省码率。**
  代价是:**它必须先解码后面的帧**——这就是 DTS 与 PTS 要分开的原因。

双向预测的残差最小,所以 B 帧最省码率。 代价是:它必须先解码后面的帧——这就是 DTS 与 PTS 要分开的原因。

30 秒实验

  1. 用 ffprobe 看一段视频的帧序列,找出 B 帧的位置。
  2. 观察它前后是不是都有 P 帧或 I 帧。

常见误区

  1. 以为 B 帧总是更好。它引入延迟,实时场景常常禁用。
  2. 把【后向预测】理解成【预测未来】。它只是参考已经编码好的后一帧。
自测三问(点开对答案) 1. 三种预测方式分别参考什么? —— 前向参考前一帧、后向参考后一帧、双向参考前后两帧。 2. 为什么双向预测残差最小? —— 前后两个方向提供的信息互补,加权平均更接近目标。 3. 什么时候应该禁用 B 帧? —— 低延迟场景,如视频会议与直播。

相关笔记