2. H265编码结构:CTU、CU、PU、TU
H265/HEVC 的编码结构,说白了就是一套「分而治之」的策略。我刚开始接触 H264 转 H265 的项目时,最直观的感受就是——这货把「块」的概念玩出了花。H264 里的宏块(Macroblock)是 16x16 固定大小,到了 H265 这里,变成了四叉树划分的灵活结构。
嗯,咱们一个一个来看。
2.1 编码树单元(CTU)—— 最大的块
CTU 是 H265 编码的起点。你可以把它理解成一张图片被切成的「瓦片」,每个 CTU 的大小由编码器决定。
CTU 尺寸范围: 64x64、32x32、16x16(H264 的宏块最大才 16x16)
我个人习惯在编码器中把 CTU 设成 64x64,尤其是处理 4K 视频时。为什么?因为平坦区域(比如天空、白墙)用一个 64x64 的块就能搞定,码率省得不是一星半点。
每个 CTU 会递归地向下划分,形成一棵四叉树。这棵树长什么样?我画了个图,你一看就明白。
2.2 编码单元(CU)—— 真正的决策者
CTU 划分出来的每个节点,就是一个 CU。CU 是编码决策的基本单位——编码器在这里决定:用帧内预测还是帧间预测?用哪个模式?
CU 的大小可以从 64x64 一直降到 8x8。你想想看,这意味着什么?
- 平坦区域:用大 CU(64x64 或 32x32),一个块搞定,码率极低。
- 纹理复杂区域:用小 CU(16x16 或 8x8),精细刻画细节。
- 运动剧烈区域:同样用小 CU,运动估计更精准。
我的经验: 在编码监控视频时,背景基本不动,我习惯把最大 CU 设成 64x64,深度设到 3 层。这样背景用大块,前景运动物体用小块,码率能省 20% 以上。
2.3 预测单元(PU)—— 预测的最小单位
CU 决定「怎么编」,PU 决定「怎么预测」。一个 CU 可以包含 1 个或多个 PU。
PU 的划分方式取决于 CU 的预测模式:
| 预测模式 | PU 划分方式 | 说明 |
|---|---|---|
| 帧内预测 | 2N×2N 或 N×N | 只有正方形,大小与 CU 相同或 1/4 |
| 帧间预测 | 2N×2N、2N×N、N×2N、N×N、2N×nU、2N×nD、nL×2N、nR×2N | 支持矩形和非对称划分 |
帧间预测的 PU 划分花样很多。我记得有一次调试运动估计的 bug,发现某个运动剧烈的区域用 2N×nU(上宽下窄)的划分效果特别好——因为物体上半部分在动,下半部分静止。这种非对称划分在 H264 里是没有的。
注意: PU 的划分深度不能超过 CU 的深度。也就是说,PU 最小是 4x4(当 CU 为 8x8 且采用 N×N 划分时)。
2.4 变换单元(TU)—— 残差变换的载体
TU 负责对预测残差做 DCT 变换(或 DST 变换)。TU 的大小也是可变的,从 32x32 到 4x4。
TU 的划分独立于 PU,但受 CU 约束。说白了:
- TU 不能超出 CU 的边界。
- TU 的最大尺寸由编码器指定(通常 32x32)。
- TU 的最小尺寸是 4x4。
为什么 TU 要独立划分?我举个例子你就懂了:
假设一个 CU 是 32x32,里面包含一个 32x32 的 PU(帧内预测)。预测做完后,残差信号可能在某些区域很平坦,某些区域有细节。这时候:
- 平坦区域用 32x32 的 TU,变换后高频系数几乎为零,直接跳过。
- 细节区域用 8x8 或 4x4 的 TU,精细保留纹理。
这种灵活性,是 H265 压缩效率比 H264 高 30%-50% 的重要原因之一。
2.5 四者关系总结
CTU、CU、PU、TU 的关系,可以用一句话概括:
CTU 是根,CU 是枝,PU 和 TU 是叶。
CTU 划分出 CU,CU 决定预测模式后划分出 PU,CU 决定变换方式后划分出 TU。
我习惯用一张表来对比它们的核心属性:
| 单元 | 全称 | 大小范围 | 核心作用 |
|---|---|---|---|
| CTU | Coding Tree Unit | 16x16 ~ 64x64 | 编码树的根节点,图像分块 |
| CU | Coding Unit | 8x8 ~ 64x64 | 编码决策(帧内/帧间、模式选择) |
| PU | Prediction Unit | 4x4 ~ 64x64 | 预测操作(运动估计、帧内预测) |
| TU | Transform Unit | 4x4 ~ 32x32 | 残差变换(DCT/DST) |
2.6 实际编码中的坑
讲几个我在项目中踩过的坑,希望能帮你少走弯路。
坑一:CU 深度与编码速度的权衡
我曾经在一个实时编码项目中,把 CU 最大深度设成了 4(允许 8x8 的 CU)。结果编码速度直接掉了一半。后来发现,对于 1080p 的视频,深度 3(最小 16x16)就足够了,再深收益很小,代价却很大。
坑二:TU 大小与码率控制
有次做低码率编码,我把 TU 最大尺寸设成 32x32,结果画面出现块效应。后来分析发现:低码率下大 TU 的量化步长太大,细节全丢了。改成最大 16x16 后,块效应明显改善。
建议: 如果你用 FFmpeg 的 libx265 编码,可以通过参数控制这些结构:
# 设置 CTU 大小 64x64,CU 最大深度 3
-crf 23 -x265-params "ctu=64:max-cu-depth=3"
# 限制 TU 最大为 16x16
-x265-params "tu-intra-depth=2:tu-inter-depth=2"
嗯,CTU、CU、PU、TU 这套四叉树结构,是 H265 的核心骨架。理解了它们,你就掌握了 H265 编码的一半。剩下的,就是预测、变换、量化这些具体操作了。