音视频修炼之编码器(一):AVC、HEVC编码器内部

H.264 / H.265 编码器内部架构

基础理论篇讲过 H.264 的"标准是什么", 这篇讲"编码器内部怎么实现"------以 x264 / x265 为代表, 拆开看每一块.


本文速览

章节 阅读重点
0. 编码器五大块 把握本节核心概念和使用场景
1. 帧间 / 帧内 决策 把握本节核心概念和使用场景
2. 帧内预测 (Intra) 把握本节核心概念和使用场景
3. 帧间预测 (Inter) 把握本节核心概念和使用场景
4. 变换 + 量化 把握本节核心概念和使用场景
5. 熵编码 把握本节核心概念和使用场景
6. 码率控制 (Rate Control) 把握本节核心概念和使用场景
7. 后处理: 去块滤波 把握本节核心概念和使用场景
8. x264 编码流程 重点看数据/调用如何流转
9. 编码器复杂度对比 按场景做技术取舍
后续章节 余下 2 节继续按"概念 → 示例 → 坑点 → 总结"展开

0. 编码器五大块

任何编码器都是这五块, 只是各家算法不同.


1. 帧间 / 帧内 决策

1.1 GOP 结构

最常见 : IBBPBBPBBP...

I (关键帧) 每 N 帧一个

P (前向预测) 参考前面的 I 或 P

B (双向预测) 参考前后 (压缩率最高)

x264 默认 :

--keyint 250 (250 帧 = 10 秒@25fps)

--bframes 3 (最多 3 个连续 B)

1.2 帧类型决策

"这一帧是 I 还是 P 还是 B?"

简单策略 :

每 250 帧强制 I

其他都是 P

高级 (x264) :

场景切换检测 → 强制 I

动态调整 B 帧数

开放 GOP / 闭合 GOP


2. 帧内预测 (Intra)

2.1 H.264

H.264 的帧内预测按块大小分两类:小块更精细,大块更省计算。

块类型 预测模式 适合场景
4×4 块 9 种预测方向:0 垂直、1 水平、2 DC 平均、3~8 斜向 纹理复杂、边缘变化多的小区域
16×16 块 4 种预测方向:垂直 / 水平 / DC / Plane 大面积平坦区域,模式少、开销低

编码器真正做的是 Mode Decision:把可选方向都试一遍,选择"预测后残差最小、码率代价最低"的模式。

2.2 H.265

H.265 的核心变化是:预测方向更多、块更大,所以平坦区域能用更少码率表达。

对比项 H.264 H.265 影响
帧内预测方向 9 种 35 种 方向更细,边缘 / 纹理预测更准
最大块大小 16×16 64×64 大块平坦区域更省码率
压缩收益 基准 更高 同等主观画质下码率更低

一句话记忆:H.265 用"更多方向 + 更大块"换来更好的预测,从而减少残差、节省码率。


3. 帧间预测 (Inter)

3.1 运动估计 (ME)

当前块 vs 参考帧 :

在参考帧中找"最像"的块

→ 运动矢量 (MV)

→ 残差 (差值)

搜索算法 :

全搜索 (FS): 最准, 最慢

钻石搜索 (DIA)

六边形 (HEX)

EPZS (x264 推荐)

UMH (x265)

3.2 子像素精度

H.264 : 1/4 pixel (插值 6-tap 滤波器)

H.265: 1/4 pixel (8-tap 滤波器)

精度越高, 压缩越好但越慢

3.3 多参考帧

项 内容
H.264 最多 16 个参考帧
H.265 最多 16 个
x264 默认 ref=3

4. 变换 + 量化

4.1 整数 DCT

H.264 :

4×4, 8×8 整数 DCT

H.265 :

4×4, 8×8, 16×16, 32×32

→ 大块更高效

DST (Discrete Sine Transform) :

H.265 帧内 4×4 块用 DST (亮度)

比 DCT 更适合帧内

4.2 量化

量化决定"保留多少细节":数值越大,码率越小,但画质损失越明显。

参数 范围 / 推荐 含义 画质影响
QP(Quantization Parameter) 0~51 编码标准里的量化参数 QP 越大,压缩越狠,画质越差
QP = 0 无损 基本不丢信息 码率极高
QP ≈ 22 高质量 常见高画质档 细节保留较多
QP ≈ 28 一般质量 常见折中档 码率明显下降
QP ≈ 35 低质量 强压缩 容易出现块效应 / 细节糊掉
CRF(Constant Rate Factor) 22~28 x264 推荐的恒定质量控制方式 适合大多数离线转码场景

调参直觉:想要体积小就提高 QP / CRF,想要画质好就降低 QP / CRF。


5. 熵编码

5.1 CABAC (Context-Adaptive Binary Arithmetic Coding)

H.264 main 以上, H.265 全用

原理 :

根据前文上下文, 调整概率

→ 出现频繁的符号用更短的码

特点 :

压缩率: 比 CAVLC 高 10-15%

速度: 比 CAVLC 慢

5.2 CAVLC

CAVLC 是 H.264 Baseline 常见的熵编码方式,特点是兼容性好、速度快,但压缩率不如 CABAC。

项 CAVLC CABAC
典型使用 H.264 Baseline / 老设备兼容 H.264 Main 及以上、H.265 默认
压缩率 较低 更高,通常比 CAVLC 省 10~15% 码率
速度 更快 更慢,计算复杂度更高
x264 参数 --no-cabac --cabac,默认开启
适合场景 老设备、低复杂度、兼容优先 画质 / 码率优先的主流场景

一句话记忆:CAVLC 是"快但压缩差一点",CABAC 是"慢一点但更省码率"。


6. 码率控制 (Rate Control)

6.1 三种模式

CBR (Constant Bit Rate) :

恒定码率, 直播用

画质波动大

VBR (Variable Bit Rate) :

可变码率, 点播用

动态场景给高码率, 静止低

画质均衡

CRF (Constant Rate Factor) :

恒定质量, x264 推荐

画质恒定, 文件大小不固定

6.2 x264 参数

用途 命令
CRF 模式 (推荐) ffmpeg -i input.mp4 -c:v libx264 -crf 23 output.mp4
CBR ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -minrate 2M -maxrate 2M -bufsize 2M output.mp4
VBR (2-pass) ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 1 -f null /dev/null
VBR (2-pass) ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -pass 2 output.mp4

7. 后处理: 去块滤波

量化导致块边界不连续

→ Deblocking Filter (DBF)

H.264 : 帧间循环

H.265 :

DBF + SAO (Sample Adaptive Offset)

SAO 进一步去除振铃


8. x264 编码流程

x264_encoder_encode() 可以理解成"读帧 → 预分析 → 编码 → 输出 NAL"的流水线:

阶段 模块 / 动作 主要工作 产物
1 读入 frame 接收输入图像帧,准备进入编码队列 原始输入帧
2 lookahead 做 B 帧决策、场景切换检测、mb-tree 分析 帧类型和复杂度预估
3.1 analyse 选择帧内 / 帧间模式 最优预测模式
3.2 me 运动估计 在参考帧里找最像的块 运动矢量 MV + 残差
3.3 transform + quant 变换到频域并量化 量化系数
3.4 entropy CABAC / CAVLC 熵编码 压缩后的 bitstream
3.5 deblock 去块滤波,减少块边界伪影 环路滤波后的参考帧
4 输出 NAL 单元 封装成 H.264 NAL 可写入码流 / 容器的数据

x264 源码主入口:encoder/encoder.c。

一句话记忆:x264 的主流程就是先决定"怎么预测",再计算"残差怎么压",最后输出 NAL。


9. 编码器复杂度对比

单 frame 1080p 30fps 编码耗时 (现代 CPU 单线程):

项 内容
H.264 x264 ultrafast ~5ms
H.264 x264 medium ~15ms
H.264 x264 veryslow ~80ms
H.265 x265 medium ~50ms
H.265 x265 slow ~150ms
AV1 SVT-AV1 medium ~200ms
AV1 libaom-av1 ~1000ms ⛔

10. 实战: 不同 preset 对比

原始: 1080p 30fps 60 秒 H.264 → H.265

项 说明
preset 速度 码率 画质 (VMAF)

项 说明
ultrafast 5x 2.5M 88
fast 2x 2.0M 90
medium 1x 1.8M 92 ← 推荐
slow 0.5x 1.7M 93
veryslow 0.2x 1.6M 94

结论: medium 是性价比最高的 preset.


11. 总结

五大块:

帧间/内决策 + 运动估计 + 变换量化 + 熵编码 + 码率控制

调参顺序 (x264):

  1. preset (medium 起步)
  2. crf (23-28)
  3. tune (film/animation/grain/...)
  4. profile (high 通常)
  5. level (4.1 1080p, 5.1 4K)

金句: 编码器内部是"压榨每一个比特"的艺术------同样的 1080p 视频, x264 能省到 2 Mbps, x265 能省到 1 Mbps, AV1 能到 0.7 Mbps. 这背后是无数算法上的精雕细琢.

相关推荐
2601_9498477520 小时前
io-ts 跨端三方库仓颉适配全流程
linux·运维·ubuntu
誰能久伴不乏1 天前
桌面客户端的运行日志系统:SQLite 分块 + 独立写线程 + 文本降级
数据库·c++·qt·架构·sqlite
readhere1 天前
从ZYNQ7000开发板,学会启动嵌入式Linux系统——入门学习:EBAZ4205篇目录
linux·启动·嵌入式linux·zynq7000·ebaz4205
独隅1 天前
Claude API 实战教程:从入门到完整项目
android·java·数据库·claude·claude code
打工仔折腾 AI1 天前
在 Ubuntu ARM64 部署 Q1 V3.0 MuJoCo 模型:加载、单步推理与执行器响应解析
linux·运维·人工智能·python·深度学习·ubuntu·性能优化
choumin1 天前
C++中万能引用与std::forward的作用和用法
c++·万能引用·std forward
‎ദ്ദിᵔ.˛.ᵔ₎1 天前
关于Linux 线程局部存储的认识
linux·运维
下一站春风里1 天前
位运算完整学习笔记:按位与(&)+ 异或(^)
开发语言·c++·算法
小小de风呀1 天前
de风——【从零开始学习Linux】(九):进程基础 —— 从冯诺依曼体系到 fork 创建进程
linux·学习