编码流程串起来很长,但耗时几乎全压在运动估计上——所以调【快/慢】其实就是在调搜索,压得越细就越慢。
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 秒实验
- 在 FFmpeg 里给同一个命令分别加
-preset ultrafast与-preset veryslow,记录编码速度(fps)。 - 再对比输出的文件大小,算出慢速多花的代价换回了几个百分点。
常见误区
- 以为编码器只用原始帧做预测。必须用重建帧,否则解码端无法复现、画面会漂移。
- 以为流程里每一步都很耗时。运动估计占六成以上,其余各步加起来才是它的零头。
- 以为码率控制是一个独立步骤。它贯穿全流程,在帧级与宏块级都在做决策。
自测三问(点开对答案)
1. 编码器里为什么要有一条重建的反馈支路? —— 因为解码端只有重建帧,编码器必须用同一份画面做预测。 2. 编码流程里最耗时的是哪一步? —— 运动估计,通常占六成以上的时间。 3. 解码流程相对编码省掉了什么? —— 省掉了搜索——运动矢量与预测模式直接读码流即可。- ☐ 下一节(8.3.1 I/P/B帧编解码技术)
相关笔记
- 视频编码简介 — 六块模块的分工
- 运动估计和运动补偿 — 最耗时那一步的细节
- 预测编码 — 残差是从哪来的
- 视频编解码流程 — 第五章的流程讲法
- 🎬 FFmpeg入门详解 · 索引