4. 帧内预测:35种模式与编码流程

帧内预测,说白了就是利用当前帧里已经编好的像素,去猜还没编的像素。我刚开始接触HEVC时,觉得这玩意儿不就是H.264的升级版嘛?后来踩了坑才发现——完全不是一回事。

HEVC的帧内预测把模式从H.264的9种扩展到了35种。为什么多了这么多?因为高清视频里纹理更复杂,角度更精细。你想想看,一个45度的斜边和43度的斜边,用同一种模式去预测,残差能差出一大截。

4.1 35种预测模式总览

这35种模式分为三类:

  • Planar模式(模式0):平滑渐变预测,适合纹理平缓的区域
  • DC模式(模式1):均值填充,适合大面积平坦区域
  • 角度模式(模式2-34):33种不同方向的预测

我个人的习惯是,先把这33种角度模式按方向分组记:

方向组 模式范围 角度偏移 典型场景
水平偏上 2-9 接近水平,略向上 水平纹理
水平偏下 10-17 水平到45度 斜向纹理
垂直偏左 18-25 垂直到45度 垂直纹理
垂直偏右 26-34 接近垂直,略向右 精细斜纹

嗯,这里要注意:模式18是纯垂直,模式26是纯水平。这两个是基准方向,其他模式都是在这两个方向上的微调。

4.2 角度预测:精细到1/32像素

HEVC的角度预测比H.264精细得多。H.264只支持1/4像素精度,HEVC直接干到了1/32像素。为什么?

举个例子:一个4K视频里,建筑物边缘可能是87度倾斜。如果用H.264的粗粒度角度去预测,残差会很大。HEVC的1/32精度可以更精确地匹配这种纹理方向。

角度预测的核心公式其实不复杂:

// 伪代码:角度预测核心逻辑
predSample[x][y] = ( (32 - iFact) * refArray[idx + iIdx + 1] 
                   + iFact * refArray[idx + iIdx + 2] + 16 ) >> 5

这里的 iFact 就是1/32像素的偏移量。我当年在优化移动端解码器时,发现这个插值计算占了帧内预测30%的耗时。后来改成查表法,速度提升了将近一倍。

我的经验:角度预测的参考像素选择很关键。如果参考像素离当前块太远,相关性会下降。我建议在编码器里加一个距离加权因子,对远距离参考像素降权。这个trick在纹理复杂的场景下能省5%-8%的码率。

4.3 DC预测:简单但有效

DC预测的逻辑极其简单——取左边和上边参考像素的平均值,填满整个块。

dcVal = (sumLeft + sumAbove + (nS >> 1)) / nS

但越简单的东西越容易出问题。我曾经在一个监控视频编码项目里,发现大量平坦区域(比如天空、墙壁)用DC模式编码后出现块效应。排查了半天,原因是DC值计算时没有考虑边界像素的连续性。

避坑指南:DC预测虽然简单,但边界处理不能马虎。HEVC标准里对DC模式的边界滤波有明确要求——第一行和第一列像素要和相邻参考像素做一次平滑。我见过不少实现直接跳过这步,结果PSNR掉了0.3dB。

4.4 Planar预测:渐变之美

Planar模式是我个人最喜欢的一种。它通过水平和垂直两个方向的线性插值,生成一个平滑的渐变面。

公式长这样:

predSample[x][y] = ( (nS - 1 - x) * refLeft[y] 
                   + (x + 1) * refAboveRight
                   + (nS - 1 - y) * refAbove[x]
                   + (y + 1) * refBelowLeft
                   + nS ) >> (log2(nS) + 1)

说白了,就是四个角的参考像素共同决定整个面的走势。这种预测方式特别适合自然图像中的渐变区域,比如天空从蓝到白的过渡。

我记得有一次做医疗图像编码,CT影像里有很多软组织渐变区域。用Planar模式比DC模式节省了12%的码率,而且视觉上完全看不出块边界。

4.5 帧内预测编码流程

整个流程我画了一张图,方便你理解:

HEVC帧内预测编码流程 输入当前块像素 构建参考像素(左+上) 参考像素滤波(3-tap) RDO模式决策(35选1) 生成预测块 计算残差(原始-预测) 关键点 参考像素必须已重建 滤波只对部分模式生效 RDO遍历所有35种模式 输出 最佳模式索引(5bit) 残差数据(DCT变换) 预测块(用于重建)

整个流程看起来简单,但每个环节都有坑。我重点说几个:

4.5.1 参考像素构建

参考像素必须来自已重建的块,不能直接用原始像素。为什么?因为解码端只有重建后的像素可用。如果编码器用原始像素做参考,解码器算出来的预测值对不上,画面就崩了。

4.5.2 参考像素滤波

HEVC对部分模式(主要是DC和Planar)的参考像素做了3-tap平滑滤波。这个滤波不是可选的,是标准强制要求。我见过有实现为了省计算量跳过这步,结果码流不符合标准,解码器直接报错。

4.5.3 RDO模式决策

35种模式全遍历?太慢了。实际工程中会用快速算法:

  • 粗选阶段:用SATD(Hadamard变换后的绝对差和)快速筛选出Top N个候选模式
  • 精选阶段:对候选模式做完整的RDO(率失真优化)计算

我一般把N设为8,这样能在编码质量和速度之间取得比较好的平衡。如果对质量要求极高,可以放宽到12。

核心要点:帧内预测的35种模式不是摆设。实际编码时,Planar和DC模式占了约40%的选择率,剩下的60%分布在33种角度模式中。纹理越复杂,角度模式的使用率越高。

4.6 实际编码中的优化技巧

最后分享几个我在项目中积累的经验:

  1. 参考像素缓存:帧内预测需要频繁读取参考像素。我建议用环形缓冲区管理,避免重复计算像素位置。
  2. 模式快速跳过:如果当前块的方差很小(平坦区域),直接跳过角度模式,只试DC和Planar。能省60%的预测时间。
  3. 角度模式分组:33种角度模式可以分成4组。先确定最优组,再在组内精细搜索。这个策略在编码器里很常用。

嗯,帧内预测的内容就这些。记住一点:预测越准,残差越小,码率越低。35种模式给了你足够多的选择,关键是怎么用对它们。