3、帧内预测模式优化:35种帧内预测模式详解、模式决策快速算法、RMD与MPM技术
帧内预测,说白了就是利用当前帧里已经编好的像素,去猜还没编的块长什么样。HEVC 把这事做得特别细——它一口气定义了 35 种预测模式。你想想看,一个 4×4 的块就要从 35 个方向里挑一个最好的,这计算量可不是闹着玩的。
我早年刚接触 HEVC 时,觉得这 35 种模式不就是 H.264 那 9 种的简单扩展吗?后来踩了坑才发现,事情远没那么简单。模式多了,决策路径就复杂了,稍不注意编码器就跑不动。今天咱们就把这 35 种模式、快速决策算法、RMD 和 MPM 技术彻底捋清楚。
核心要点:帧内预测优化的本质,是在 35 种候选模式中快速找到率失真代价最小的那个。直接遍历 35 种模式做 RDO 是不现实的,必须用 RMD 粗筛 + MPM 补充 + 细选三步走策略。
3.1 35种帧内预测模式详解
HEVC 的帧内预测分为两大类:角度模式(33 种)和非角度模式(2 种)。非角度模式就是 Planar(模式 0)和 DC(模式 1),剩下的 2~34 全是角度模式。
我个人习惯把角度模式想象成一个圆盘上的刻度。模式 2 对应右下方向,模式 18 是正水平,模式 34 是右上方向。每两个相邻模式之间只差约 5.6 度,精度比 H.264 高了一倍不止。
| 模式编号 | 类型 | 方向描述 | 适用场景 |
|---|---|---|---|
| 0 | Planar | 双线性插值,平滑渐变 | 平坦区域、渐变纹理 |
| 1 | DC | 参考像素均值填充 | 大面积均匀区域 |
| 2~17 | 角度(水平偏斜) | 从右下到水平偏上 | 水平纹理、斜向边缘 |
| 18~34 | 角度(垂直偏斜) | 从水平到右上偏下 | 垂直纹理、斜向边缘 |
这里有个细节容易忽略:角度模式的参考像素不是直接复制,而是通过 1/32 像素精度的插值滤波器生成的。我在项目中遇到过一个问题——同样的纹理,用模式 18 和模式 19 预测出来的残差差别很大,就是因为插值精度导致的细微偏移。
实战技巧:对于 32×32 以上的大块,Planar 模式往往比任何角度模式都稳定。我一般在大块上优先测 Planar 和 DC,如果残差已经很小了,就直接跳过角度模式的遍历。
3.2 模式决策快速算法
直接对 35 种模式做全 RDO 计算,复杂度高得吓人。实际工程中,我们用的是三步走策略:
- 粗选阶段(RMD):用 Hadamard 变换快速估算 SATD 代价,从 35 种模式中挑出 N 个候选。
- 补充阶段(MPM):把相邻块的预测模式加进来,防止 RMD 漏掉最优解。
- 细选阶段(RDO):对候选列表里的模式做完整的率失真优化,选出最终模式。
你可能会问:为什么 RMD 选出来的还不够,还要加 MPM?
嗯,这里有个坑。RMD 用的是 SATD,它只衡量残差的变换域能量,不考虑码率。有时候 SATD 很小的模式,编码比特数却很大。而 MPM 来自相邻块的真实决策,往往能补上 RMD 漏掉的好模式。
避坑指南:我曾经在优化一个低码率场景时,发现 RMD 选出的前 3 个模式全是角度模式,但实际最优解是 Planar。后来查代码才发现,RMD 的 SATD 阈值设得太低了,导致 Planar 被过早淘汰。解决方案是:在 RMD 阶段强制保留 Planar 和 DC,不管它们的 SATD 排名如何。
3.3 RMD技术详解
RMD(Rough Mode Decision)的核心思想很简单:用轻量级的 SATD 代替完整的 RDO 计算。具体流程如下:
// RMD 伪代码示例
for (mode = 0; mode < 35; mode++) {
// 1. 生成预测块
pred = intraPredict(pu, mode);
// 2. 计算残差
residual = original - pred;
// 3. 对残差做 Hadamard 变换
hadamard = hadamardTransform(residual);
// 4. 计算 SATD 代价
satdCost = sum(abs(hadamard));
// 5. 加上模式比特数估计
cost[mode] = satdCost + lambda * bits[mode];
}
// 选出代价最小的 N 个模式
candidateList = selectTopN(cost, N);
这里的 N 取值很关键。我一般这样设:
- 4×4 块:N = 8(纹理复杂,多留几个候选)
- 8×8 块:N = 5
- 16×16 块:N = 3
- 32×32 块:N = 3
为什么大块反而候选少?因为大块纹理通常更平滑,最优模式往往集中在 Planar、DC 和少数几个角度模式上。
3.4 MPM技术详解
MPM(Most Probable Mode)是利用空间相关性来补充候选模式。HEVC 标准规定最多可以有 3 个 MPM,它们来自:
- 左侧块(Left PU)的帧内模式
- 上方块(Above PU)的帧内模式
- 如果前两个相同,则补充 Planar 或 DC
我见过不少实现直接把 MPM 加到 RMD 候选列表后面,然后去重。但这样做有个问题:如果 MPM 和 RMD 候选完全重合,那 MPM 就没起到补充作用。
我的改进方案:在构建候选列表时,先放 RMD 选出的前 N 个模式,再放 MPM。如果 MPM 已经在列表里了,就把它提到前面,而不是简单去重。这样在后续 RDO 阶段,MPM 会优先被评估,节省了不必要的计算。
3.5 整体决策流程
把上面这些串起来,就是完整的帧内模式决策流程。我画了一张图,方便你理解:
3.6 工程优化经验
在实际编码器里,帧内模式决策的优化空间很大。我分享几个实战中验证过的技巧:
- 提前终止:如果 RMD 阶段 SATD 最小的模式代价已经低于某个阈值,直接用它,跳过 RDO。这个阈值我一般设为
lambda * 256。 - 模式分组:把 33 个角度模式按方向分成 6 组,先测每组中心模式,再根据结果决定是否测组内其他模式。这招在 64×64 块上能省 40% 的计算量。
- 参考像素缓存:帧内预测需要频繁读取参考像素,我习惯把当前 CTU 的参考像素全部预取到 L1 cache 里,避免反复访存。
注意:不要为了追求速度而过度简化 RMD。我见过有人把 RMD 的候选数从 8 减到 3,结果 BD-Rate 涨了 2.3%。速度是快了,但压缩效率掉得太多,得不偿失。
好了,帧内预测模式优化这块就聊到这儿。35 种模式、RMD 粗筛、MPM 补充、RDO 细选,这套流程你吃透了,HEVC 帧内编码的核心就算拿下了。实际调优时,记得根据你的应用场景(实时通信、离线编码、硬件实现)来调整候选数量和提前终止阈值——没有银弹,只有不断试出来的最佳实践。