在解码框架中最后是做滤波处理
环路滤波是以微块做处理,按照解码顺序依次进行处理,在AVS中就是以16*16的大小
对亮度和色度分别做环路滤波,首先从左到右对垂直边界滤波,然后从上到下进行处理。
需要滤波的边界包括图像边界,条带边界,微块的上边界和下边界,同时对处理的过程会有相应的强度控制算法,如果强度为0,那么不进行滤波处理
下面介绍的更多的还是一些实现上的优化的例子,以一个垂直边界的一个点作为例子:
<span style="font-size:14px;">L2 = SrcPtr[-inc3] ;
L1 = SrcPtr[-inc2] ;
L0 = SrcPtr[-inc ] ;
R0 = SrcPtr[ 0] ;
R1 = SrcPtr[ inc ] ;
R2 = SrcPtr[ inc2] ;</span>
首先获取图片中该点周围的几个像素点,通过解码流中的阿尔法值和贝塔值获得强度,这里介绍一下ti6467中一些内联指令的使用:
在循环中有if指令符号会减速cpu的运行速度,无法并行处理
<span style="font-size:14px;">if ((AbsDelta < Alpha) && (AbsDelta > 1)) {
if (abs(L1 - L0) < Beta) {
FlatnessL = 2;
} else {
FlatnessL = 0;
}
if (abs(L2 - L0) < Beta) {
FlatnessL += 1;
}
if (abs(R0 - R1) < Beta) {
FlatnessR = 2;
} else {
FlatnessR = 0;
}
if (abs(R0 - R2) < Beta) {
FlatnessR += 1;
}}</span>
其实利用内联函数,几句话就可以解决
<span style="font-size:14px;">AbsDelta = abs(R0 - L0) ;
iConFlag = (Alpha > AbsDelta) &(AbsDelta > 1);
if (!iConFlag)
{
continue;
}
FlatnessL = _cmpgt2(_pack2(Beta, Beta),_pack2(abs(L1-L0), abs(L2-L0)))*iConFlag;
FlatnessR = _cmpgt2(_pack2(Beta, Beta),_pack2(abs(R0-R1), abs(R0-R2)))*iConFlag;</span>
_pack2是对两个32bit数据的低16位进行组合为一个新的32bit数据
_cmpgt2是对两个32bit数据的分别16位进行比较,将比较结果放在返回值对应的低两位当中
在获得了强度值之后会根据对应的强度对点进行不同的环路滤波处理方式,那么就难免需要用到switch操作,这也是我们不想要的,那么我们可以进行下面的处理
原方法:
<span style="font-size:14px;">switch (fs) {
case 4:
SrcPtr[-inc] = //L0
SrcPtr[-inc2] = //L1
SrcPtr[-inc3] = //L2
SrcPtr[0] = //R0
SrcPtr[inc] = //R1
SrcPtr[inc2] = //R2
break;
case 3:
SrcPtr[-inc] = //L0
SrcPtr[0] = //R0
SrcPtr[-inc2] =
SrcPtr[inc] =
break;
case 2: ....................................................
default:
break;
}</span>
这里进行处理,将一个点的每个强度的点都进行处理,针对fs的值进行静态数组查询,根据值挑选出需要赋值的点
<span style="font-size:14px;">{ 0,0,0x01000000,0x01000000,0,0,0x01000000,0x01000000,0,0,0x01000000,0x01000000,0,0,0x01000000,0x01000000 },
{ 0x01000000,0x01000000,0x01000000,0x01000000,0x01000000,0x01000000,0x01000000,0x01000000,0x01000000,0x01000000,0x01000000,0x01000000}
</span>
将所有需要的8bit点pack进入32bit的数据当中,然后将这个数据和上面数组中挑选的值进行点乘处理得出需要的值