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

编码流程串起来很长,但耗时几乎全压在运动估计上——所以调【快/慢】其实就是在调搜索,压得越细就越慢。

📝 本节和前面几节的关系

8.1 认清了六块模块,这一节把它们按真实顺序串成一条流水线。

一、整体流水线

一帧进编码器,走的是这条线: 读取原始帧 → 划分宏块 → 逐块预测(帧内/帧间)→ 变换 → 量化 → 熵编码 → 写码流。 同时还有一条反馈支路:量化后的系数要反量化、反变换,与预测值相加,重建出解码端会看到的帧,再放进参考帧缓冲。 这条反馈支路是编码器与解码器保持一致的关键——编码器必须用【解码端会得到的画面】去做后续预测,否则误差会一路累积。

二、为什么要有反馈支路

这是初学者最容易漏掉的一处设计: 编码器手里其实有两份画面——原始帧与重建帧; 做预测时只能用重建帧,因为解码端拿不到原始帧; 用原始帧做预测看起来更准,但解码端复现不出来,会导致画面持续漂移。 所以编码器宁愿【自己骗自己】,也必须照着解码端的条件走。

三、时间都花在哪

这条流水线各步的耗时极不均衡: 运动估计占大头(六成以上)——它在参考帧里逐点搜索,穷举量最大; 熵编码次之——逐符号查表,并行度低; 变换与量化反而很轻——规则、整齐、容易并行,硬件里通常是专门电路; 其余是分块、码率控制与写码流。 所以调 preset 主要调的就是运动估计,其余各步的调优空间小得多。

四、码率控制插在流程里

码率控制不是某一步,而是贯穿整个流程的调度层: 它在每一帧开始前决定这一帧分到多少位; 在每个宏块决定用多大 QP; 在缓冲区快满时,把 QP 调高、多丢一点,避免码流溢出。 这就是为什么同样的编码器,换个码率控制策略,画面质量分布完全不同——复杂场景被压狠一点,简单场景省下来留给它。

五、解码流程:把这条线倒着走

解码器做的事几乎就是编码流程的逆序,但省掉了最贵的搜索: 读码流 → 熵解码 → 反量化 → 反变换 → 加预测(帧内/帧间)→ 重建帧 → 输出。 运动矢量直接读出来用,不用搜索;预测模式也直接读。 所以解码比编码快得多——这也是为什么【播放】总比【导出】轻松。

六、动手 Demo:编码器的时间去哪了

同样是压一帧,编码器内部各步骤的耗时差得很远。

steps = [("运动估计", 65), ("熵编码", 15),
        ("变换与量化", 12), ("其他", 8)]
for name, pct in steps:
    print("%-12s 约 %d%%" % (name, pct))

实跑输出:

--------------------------------------------------------------------
编码器的时间去哪了
--------------------------------------------------------------------

同样是压一帧,编码器内部各步骤的耗时差得很远。

  步骤           耗时占比(示意)     为什么
  -------------------------------------------------------------------
  运动估计       约 65%               要在参考帧里逐点搜索,穷举量大
  熵编码         约 15%               逐符号查表,不能并行太多
  变换与量化     约 12%               块级计算,规则且易并行
  其他           约 8%                分块、码率控制、写码流

  这张表解释了一件事:**调 preset(快速/慢速)主要在调运动估计**。
  搜索范围缩小、算法换粗糙,**速度立刻上去、码率也立刻上去**。
  所以【压得好不好】与【压得快不快】是同一个旋钮的两端。

这张表解释了一件事:调 preset(快速/慢速)主要在调运动估计。 搜索范围缩小、算法换粗糙,速度立刻上去、码率也立刻上去。

30 秒实验

  1. 在 FFmpeg 里给同一个命令分别加 -preset ultrafast 与 -preset veryslow,记录编码速度(fps)。
  2. 再对比输出的文件大小,算出慢速多花的代价换回了几个百分点。

常见误区

  1. 以为编码器只用原始帧做预测。必须用重建帧,否则解码端无法复现、画面会漂移。
  2. 以为流程里每一步都很耗时。运动估计占六成以上,其余各步加起来才是它的零头。
  3. 以为码率控制是一个独立步骤。它贯穿全流程,在帧级与宏块级都在做决策。
自测三问(点开对答案) 1. 编码器里为什么要有一条重建的反馈支路? —— 因为解码端只有重建帧,编码器必须用同一份画面做预测。 2. 编码流程里最耗时的是哪一步? —— 运动估计,通常占六成以上的时间。 3. 解码流程相对编码省掉了什么? —— 省掉了搜索——运动矢量与预测模式直接读码流即可。

相关笔记