编码与解码是两条反向的流水线:看起来几乎对称,代价却差一个量级——因为搜索只在编码端发生。
9.2.1 列了六项技术,这一节看它们按什么顺序跑起来。
一、两条流水线
把编码与解码的步骤并排写出来,镜像关系一眼可见: 编码:划分宏块 → 帧内/帧间预测 → 变换量化 → 熵编码 → 组 NAL 输出; 解码:解析 NAL → 熵解码 → 反量化反变换 → 预测重建 → 去块滤波输出; 中间的转换点是熵编码——它之前是【编码域】,之后是【像素域】。 所以两条流水线在这个点上镜像对称。
二、两处不对称
但对称只是表面,有两处根本性的不对称: 一是编码端有【预测的搜索】,解码端没有——运动矢量与预测模式都写在码流里,解码端直接读; 二是编码端也要做反量化与重建——因为下一帧的预测必须用重建帧(第 8.2 节的反馈支路); 所以编码器内部同时跑着正向与反向两条计算,工作量大得多。 这直接解释了为什么播放总比导出轻松。
三、去块滤波放在哪一端
去块滤波在两条流水线里都出现,位置值得注意: 解码端——放在最后,输出前抹平块边界; 编码端——放在重建之后,而且滤波结果要存回参考帧缓冲; 所以它不是一个显示阶段的美化,而是编码环路的一部分; 这也意味着滤波强度等参数必须写进码流,让两端做出同样的处理。 凡是会影响后续帧的处理,都必须两端严格一致。
四、为什么流程要按【宏块】走
H.264 最小的完整处理单位是宏块,而不是整帧: 帧内预测要用左邻与上邻已重建的像素——所以必须从左到右、从上到下; 帧间预测要对每个宏块单独选分块方式与矢量; 量化是在宏块级分配 QP 的(可以有 QP 偏移); 所以【宏块】既是数据单位,也是决策单位与依赖单位(第 8.3.6 节)。 这种串行依赖是编码并行化的主要障碍,也是各种【切片并行】方案要绕开的难点。
五、从流程看性能优化
理解了流程,就能理解工程上那些优化手段为什么有效: 切片(Slice)并行——片与片之间可以独立解码,把串行依赖切开; Lookahead 前瞻——提前分析后面几帧的内容,让码率分配更聪明,代价是延迟; 只跑必要步骤——解码端省掉搜索,硬件解码器因此可以做得又小又省电; 所有优化的共同点:在依赖图里找能并行的部分,或者干脆去掉某些步骤。
六、动手 Demo:编码与解码,两条反向的流水线
H.264 的编码流程与解码流程几乎是镜像关系。
enc = ["划分宏块", "帧内或帧间预测", "变换量化", "熵编码", "组 NAL 输出"]
dec = ["解析 NAL", "熵解码", "反量化反变换", "预测重建", "去块滤波输出"]
for i, (a, b) in enumerate(zip(enc, dec), 1):
print("第 %d 步 编码 %-14s 解码 %s" % (i, a, b))
实跑输出:
--------------------------------------------------------------------
编码与解码,两条反向的流水线
--------------------------------------------------------------------
H.264 的编码流程与解码流程几乎是镜像关系。
步骤 编码端 解码端
--------------------------------------------------------
1 划分宏块 解析 NAL
2 帧内或帧间预测 熵解码
3 变换量化 反量化反变换
4 熵编码 预测重建
5 组 NAL 输出 去块滤波输出
两个不对称之处,正是前面反复讲过的:
**一是编码端有【预测的搜索】,解码端没有**——矢量直接读;
**二是编码端也要做反量化与重建**,因为下一帧的预测必须用重建帧。
所以两条流水线**看起来对称,代价却差一个量级**(第 8.2 节)。
两个不对称之处:编码端有搜索,解码端没有;编码端还要做反量化与重建,因为预测必须用重建帧。 所以两条流水线看起来对称,代价却差一个量级。
30 秒实验
- 拿同一个视频,对比【播放】与【用 FFmpeg 重新编码】时的 CPU 占用。
- 差距的来源就是本节说的那两处不对称——搜索与重建。
常见误区
- 以为编码解码是严格的逆运算。编码端多了搜索与重建,不是简单逆过程。
- 以为去块滤波只是显示美化。它结果会回到参考帧缓冲,影响后续帧。
- 以为整帧一起处理。H.264 以宏块为决策与依赖单位,串行顺序不能乱。
自测三问(点开对答案)
1. 编码与解码流程的镜像转换点在哪? —— 熵编码/熵解码——之前是编码域,之后是像素域。 2. 两处不对称分别是什么? —— 编码端有预测搜索,且必须做反量化与重建以生成参考帧。 3. 为什么去块滤波参数要写进码流? —— 它影响后续帧的重建,两端必须做出一致的处理。- ☐ 下一节(9.2.3 H.264的帧内预测编码)
相关笔记
- H.264的帧内预测编码 — 流程里的预测细节
- H.264码流结构 — 输出端到底写了什么
- 视频编码流程 — 通用流程的讲法
- 视频编解码流程 — 第五章的流程视角
- 🎬 FFmpeg入门详解 · 索引