(2)残差叠加
对 DCT 残差数据进行反变换,获得残差像素数据,综合之前得到的熵解 码得出的数据,最终推导出 YUV 图像。 首先讨论对于帧内预测的宏块解码
帧内预测的原理就是通过对宏块左边和上边的边界像素值进行演算,用演算的 结果对宏块内部的像素赋值,图像经过变换的结果如下图 2。3 所示。很明显经 过叠加残差的画面跟原图相比很不清晰,需要进一步处理。
图 2。3 原图像 帧内预测后的图像
解码基本流程:
(1)先判断需要解码的宏块类型,如果是 4x4 帧内预测类型,则: 循环遍历 16 个块,并读取帧内预测方法,之后根据帧内预测方法调用 汇编函数进行帧内预测,最后调用汇编函数对 DCT 残差数据进行反变换; 在 DCT 系数中不包含 AC 系数的情况下,则调用另一个会变速度更快的 汇编函数对残差数据进行 4x4DCT 反变换,得到图像数据。
(2)判断需要解码的宏块类型的时候,如果是 16x16 帧内预测类型,那么: 首先获得帧内预测方法,然后根据帧内预测方法调用汇编函数进行帧内 预测,最后调用汇编函数对 16 个小块的 DC 系数进行 Hadamard 反变换, 得到更为真实的图像数据。
执行到这一步的时候,4x4 的宏块实际上已经完成了“帧内预测+DCT 反变 换”的流程;而 16x16 的宏块仅仅完成了“帧内预测+Hadamard 反变换”的流 程,而并未进行“DCT 反变换”的步骤,解码并没有完成,这一步骤需要在后 续步骤中完成。论文网
2。3。5 环路滤波
经过解码器解码的数据常常会因为 DCT 变换后的量化造成误差和运动补偿而出现 方块效应。
使用环路滤波器,通过对相邻的“块”边缘上的像素值进行运算,来对图像上的 像素重新赋值,就可以有效地减少这种块效应对图片造成的视觉上的模糊感。下面图 2。4 显示了环路滤波的效果。可以明显地观察到,经过环路滤波后,图像相当于进行 了锐化,清晰了很多。
图 2。4 未实现环路滤波 实现环路滤波
从滤波的强度为出发点考虑,环路滤波器有为两种:
(1)普通滤波器。针对边界的 Bs(边界强度)为 1、2、3 的滤波器。在这种情 况下,环路滤波需要处理方块边界两边各 3 个点:p2,p1,p0,q0,q1,q2。边界两 边各 2 个点应该被重新赋值,只以 p 点为例:
p0’ = p0 + (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3 p1’ = ( p2 + ( ( p0 + q0 + 1 ) >> 1) – 2p1 ) >> 1
(2)强滤波器。针对边界的 Bs(边界强度)为 4 的滤波器。在这种情况下,环 路滤波需要处理方块边界两边各 4 个点:p3,p2,p1,p0,q0,q1,q2,q3。边界两 边各 3 个点应该被重新赋值,只以 p 点为例:
p0’ = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3 p1’ = ( p2 + p1 + p0 + q0 + 2 ) >> 2
p2’ = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3
边界强度 Bs 的判定方式如下表 2。1
表 2。1 边界强度 Bs 的判定
从上表可以看出,与空域预测相关的宏块的边界强度 Bs 相对比较大;与之相对的, 与时间域预测相关的宏块的边界强度 Bs 比较小。
为了对一个宏块进行环路滤波,第一步我们读取 QP 等几个参数,用于推导门限值。 如果是帧内宏块(Intra),那么就要按照首先对水平的边界,然后垂直的边界的顺 序进行滤波。