3. 预测编码:帧内预测原理、帧间预测原理、运动估计与运动补偿
预测编码,说白了就是「猜」。
视频里相邻的像素、相邻的画面,其实长得都差不多。我不需要把每个像素都原样存下来,只需要存「我猜的值」和「实际值之间的差」。这个差通常很小,甚至为零,压缩效率自然就上去了。
我个人习惯把预测编码分成两类:帧内预测和帧间预测。一个在单张图里猜,一个在前后帧之间猜。下面我们一个一个拆开讲。
3.1 帧内预测原理
帧内预测,就是利用同一帧里已经编好的像素,去推测当前块的像素值。
你想想看,一张天空的图片,左边一块蓝色和右边一块蓝色,大概率是差不多的。那我只需要存一个「预测模式」和「残差」就行了。
3.1.1 预测方向与模式
在 H.264/H.265 里,帧内预测支持多种方向模式。以 4x4 块为例,有 9 种模式:
- 模式 0(垂直):用上边像素往下复制。
- 模式 1(水平):用左边像素往右复制。
- 模式 2(DC):取上边和左边像素的平均值。
- 模式 3~8(对角线方向):沿特定角度插值。
核心思路:预测越准,残差越小,码率越低。帧内预测的本质就是「用空间相关性换码率」。
我在项目中遇到过一个问题:画面纹理特别复杂时,帧内预测的残差反而会变大。这时候强行用小块预测(比如 4x4)反而比 16x16 更高效。嗯,这里要注意——块大小不是越小越好,得看纹理复杂度。
3.1.2 帧内预测的流程
- 从已重建的相邻块获取参考像素。
- 根据选定的预测模式,生成预测块。
- 原始块减去预测块,得到残差块。
- 对残差进行变换、量化、熵编码。
避坑指南:我曾经在调优时忽略了参考像素的滤波处理,导致预测块出现明显的块效应。后来发现 H.264 的帧内预测在边界处需要做平滑滤波,尤其是 DC 模式。这个细节很容易被新手忽略。
3.2 帧间预测原理
帧间预测,说白了就是「抄作业」。前后两帧画面变化不大,我直接拿前一帧的某个块过来用,再微调一下位置和残差就行了。
这比帧内预测效率高得多——因为时间上的冗余通常比空间上的冗余更大。
3.2.1 参考帧与块匹配
帧间预测的核心是块匹配。编码器会在参考帧(通常是前一帧或后一帧)里找一个最相似的块,然后记录下这个块的位置偏移量——也就是运动矢量(MV)。
| 概念 | 说明 |
|---|---|
| 参考帧 | 用于搜索匹配块的已编码帧 |
| 当前块 | 当前正在编码的块 |
| 运动矢量 (MV) | 当前块与匹配块之间的位移 |
| 残差 | 当前块与匹配块的像素差值 |
举个例子:一个球从左边滚到右边。我只需要存球的纹理(残差)和它移动的方向距离(MV),不需要每帧都重新画一遍球。
3.2.2 帧间预测的类型
- P 帧(前向预测):只参考前面的帧。
- B 帧(双向预测):参考前后两帧,取平均或加权。
注意:B 帧压缩率最高,但需要缓存未来帧,会增加延迟。实时通信场景(如视频会议)通常只用 P 帧,不用 B 帧。
3.3 运动估计与运动补偿
运动估计和运动补偿,是帧间预测的两个核心步骤。我习惯把它们看作「找块」和「补块」的关系。
3.3.1 运动估计(ME)
运动估计就是在参考帧里搜索最匹配的块。搜索范围越大,匹配越准,但计算量也越大。
常用的搜索算法有:
- 全搜索:穷举所有位置,精度最高,速度最慢。
- 三步搜索:从粗到细,逐步缩小范围,速度快但可能陷入局部最优。
- 菱形搜索:以菱形模板迭代搜索,平衡精度和速度。
- 六边形搜索:H.264 中常用,比菱形更快。
我的经验:在实际编码器调优中,我通常先用全搜索跑一遍离线测试,确定最优 MV 的分布范围,然后再用快速搜索算法去逼近。这样既能保证质量,又能控制复杂度。
3.3.2 运动补偿(MC)
运动补偿就是根据运动矢量,从参考帧里取出对应的块,生成预测块。然后和当前块做差,得到残差。
运动补偿的精度取决于亚像素插值。因为物体的运动不一定是整像素的,可能是半像素、1/4 像素甚至 1/8 像素。
| 精度 | 插值方法 | 常见标准 |
|---|---|---|
| 整像素 | 直接取整 | MPEG-2 |
| 1/2 像素 | 6 抽头 FIR 滤波 | H.264 |
| 1/4 像素 | 7 抽头 FIR + 线性插值 | H.264 / H.265 |
| 1/8 像素 | 8 抽头 DCT 插值 | H.265 / AV1 |
避坑指南:我曾经在低码率场景下强行使用 1/8 像素精度,结果码率没降多少,编码时间翻了三倍。后来发现,对于低码率视频,1/4 像素精度已经足够,再高就是浪费计算资源。
3.4 预测编码的整体流程
下面这张图展示了预测编码在视频编码器中的位置和流程:
3.5 预测编码的调优要点
在实际编码器调优中,预测编码这块有几个关键参数需要关注:
- 块大小选择:大块适合平坦区域,小块适合纹理复杂区域。H.265 引入了 CU 四叉树划分,可以自适应选择。
- 参考帧数量:参考帧越多,预测越准,但内存和计算开销也越大。我一般建议在 2~4 帧之间权衡。
- 搜索范围:对于 1080p 视频,搜索范围 ±64 像素通常够用;4K 视频可能需要 ±128 像素。
- 亚像素精度:低码率用 1/4 像素,高码率或无损场景可以用 1/8 像素。
重要提醒:预测编码的调优没有银弹。同一个参数在不同分辨率、不同码率、不同内容类型下的表现可能完全相反。我建议每次只改一个参数,用 PSNR 和 SSIM 双重验证,不要盲目相信单一指标。
好了,预测编码的核心内容就这些。帧内预测解决空间冗余,帧间预测解决时间冗余,运动估计和运动补偿是帧间预测的左右手。理解这些,你就掌握了视频编码压缩的根基。