4. 编码流程总览

H.264 编码器并不是“一步压缩”,而是一条由多个阶段串联而成的流水线。输入是一帧帧原始 YUV 像素,输出是符合 H.264 语法规范的 NAL 单元组成的码流。理解这条流水线,是后续学习帧内预测、运动估计、变换量化、熵编码等模块的前提。本节从整体视角梳理从 YUV 到 H.264 码流的完整路径,并说明各阶段之间的数据依赖关系。

一、核心原理:编码器是一条“预测—残差—变换—量化—熵编码”的闭环流水线

H.264 编码的核心思想是去除冗余:空间冗余靠帧内预测消除,时间冗余靠帧间预测消除,剩余残差再通过变换、量化去除频域与视觉冗余,最后用熵编码去除统计冗余。整个流程可以概括为“预测产生残差,残差变换量化,量化系数熵编码”,同时重建帧会回写参考帧缓冲区,形成闭环。

需要特别注意的是,编码器内部存在一条重建回路:量化后的系数经过反量化、反变换得到重建残差,再与预测值相加得到重建块,经去块滤波后写入参考帧。这条回路保证编码端与解码端使用相同的参考图像,否则后续帧的预测会持续漂移。

一句话记忆:输入 YUV → 分块与预测 → 残差 → 变换 → 量化 → 熵编码 → 输出码流;同时量化系数 → 反量化 → 反变换 → 重建 → 滤波 → 参考帧。

二、方法流程:从 YUV 到 H.264 码流的八个阶段

  1. 输入与预处理:读取 YUV 4:2:0 帧,按宏块(16×16)或编码树单元划分。YUV 三个分量分别处理,亮度与色度使用不同量化参数。
  2. 帧类型决策:确定 I 帧、P 帧或 B 帧。I 帧只做帧内预测,P/B 帧可做帧间预测。GOP 结构决定参考关系。
  3. 预测:帧内预测利用当前帧已重建的相邻像素生成预测块;帧间预测通过运动估计在参考帧中寻找匹配块,得到运动矢量与预测块。
  4. 残差计算:原始块减去预测块,得到残差块。残差通常比原始像素更“平坦”,更利于压缩。
  5. 变换:对残差做整数 DCT 变换(4×4 或 8×8),将能量集中到低频系数,便于后续压缩。
  6. 量化:用量化参数 QP 对变换系数进行除法取整,这是有损压缩的关键步骤,QP 越大压缩率越高但画质越差。
  7. 熵编码:对量化系数、运动矢量、预测模式等语法元素进行 CABAC 或 CAVLC 编码,输出二进制码流。
  8. 封装输出:将编码数据打包为 NAL 单元,加上 SPS、PPS 等参数集,形成可传输或存储的 H.264 码流。

下面这张图展示了从输入 YUV 到输出 H.264 码流的完整数据流,以及重建回路与参考帧的关系:

H.264 编码主流程与重建回路 输入 YUV 4:2:0 帧序列 分块与帧类型 I / P / B 决策 预测 帧内 / 帧间预测 残差计算 原始 − 预测 变换 整数 DCT 量化 QP 控制 熵编码 CABAC / CAVLC NAL 封装 SPS / PPS / 切片 输出 H.264 码流文件 反量化 恢复系数 反变换 重建残差 重建 + 去块滤波 写入参考帧 参考帧缓冲 DPB 参考帧用于帧间预测 主流程 重建回路 参考帧反馈 量化是有损关键点;重建回路保证编解码参考一致

三、案例/场景:一帧 P 帧的编码过程

假设输入一帧 1920×1080 的 YUV420 P 帧,编码器按以下顺序处理:

  • 将帧划分为 16×16 宏块,对每个宏块在参考帧中做运动估计,找到最佳匹配块,得到运动矢量 MV 和预测块。
  • 原始宏块减去预测块得到残差,残差做 4×4 整数 DCT,得到 16 个变换系数。
  • 用当前 QP 对系数量化,高频系数大量变为 0,实现压缩。
  • 量化系数一路送熵编码,另一路送反量化、反变换,重建残差加上预测块得到重建宏块。
  • 重建宏块经去块滤波后写入 DPB,供后续帧参考。
  • 熵编码将量化系数、MV、预测模式等写入切片数据,最终封装为 NAL 单元输出。

如果 QP 设置过小,码率会急剧上升;如果 QP 过大,高频细节丢失,出现块效应和模糊。实际编码中常通过码率控制算法动态调整 QP。

四、关键参数与阶段对照

阶段 输入 输出 关键参数 是否可逆
预测 原始块 + 参考帧 预测块 + MV/模式 预测模式、搜索范围 可逆
变换 残差块 变换系数 变换尺寸 4×4/8×8 近似可逆
量化 变换系数 量化系数 QP 不可逆
熵编码 量化系数 + 语法元素 二进制码流 CABAC/CAVLC 可逆
重建回路 量化系数 重建帧 QP、滤波强度 与解码端一致

五、常见误区与复盘

误区一:认为编码器只做一次前向处理。实际上编码器内部有重建回路,否则参考帧会与解码端不一致,导致画面持续漂移。
误区二:把量化当成普通除法。量化是有损压缩的核心,QP 直接决定码率与画质平衡,且色度与亮度可使用不同 QP。
误区三:忽略熵编码前的语法组织。运动矢量、预测模式、块类型等都要按 H.264 语法写入码流,并非只编码像素残差。
复盘建议:学习后续章节时,始终把每个模块放回这条流水线中定位:它处理的是原始像素、残差、变换系数还是语法元素?它的输出流向熵编码还是重建回路?这样能避免“只见树木不见森林”。

掌握这条完整流程后,再深入帧内预测、运动估计、变换量化、CABAC 等模块时,就能清楚每个模块在整体中的位置与作用。编码器的性能优化,本质上也是在这条流水线上寻找计算瓶颈与率失真平衡点。