VVC环路滤波(一):ALF

在VTM5中提供了三种环路滤波技术:去方块滤波(Deblocking filter,DF),样点自适应补偿(Sample adaptive offset,SAO)和自适应环路滤波(adaptive loop fitler,ALF)。在VTM5中这些滤波工具的使用顺序为DF,SAO,ALF。

VTM5中的DF和SAO与HEVC中的类似,ALF是VTM5中新增的技术。本文主要介绍ALF。

ALF

自适应环路滤波(adaptive loop fitler,ALF)是VTM5中新增的技术。是基于块的滤波技术,它作用于4x4的子块,对于每个4x4的子块需要将其归为25个类别之一,然后根据类别为其选择滤波器。

1、滤波器形状

VTM5提供了两种菱形滤波器,如上图所示。左边5x5的菱形滤波器用于色度分量,右边7x7的菱形滤波器用于亮度分量。

enum AlfFilterType
{
  ALF_FILTER_5,
  ALF_FILTER_7,
  ALF_NUM_OF_FILTER_TYPES
};

2、块分类

对于亮度分量需要为每个4x4的子块分类,共25个类别。类别C由块的方向D和活动性A决定:

C = 5D + A

为了计算D和A,需要计算子块的水平、垂直、两个对角线方向的梯度,梯度计算使用1维拉普拉斯方法实现:

为了减少计算复杂度在计算梯度前进行下采样,如下图:

得到梯度后D和A的计算方法如下:

对于色度分量不需要对其子块进行分类操作,它只有一个滤波器。

3、滤波器系数和门限值几何变换

由上一步可以得到滤波器,但是在滤波操作前需要对滤波器系数和相应门限值进行几何变换,包括旋转、对角和垂直翻转。变换类型由上面计算的块的梯度决定。对滤波器进行几何变换效果等价于对滤波区域进行相应几何变换,这么做的目的是使不同块方向对齐。

  if( filtType == ALF_FILTER_7 )
      {
        if( transposeIdx == 1 )
        {//!<对角线变换
          filterCoeff = { coef[9], coef[4], coef[10], coef[8], coef[1], coef[5], coef[11], coef[7], coef[3], coef[0], coef[2], coef[6], coef[12] };
#if JVET_N0242_NON_LINEAR_ALF
          filterClipp = { clip[9], clip[4], clip[10], clip[8], clip[1], clip[5], clip[11], clip[7], clip[3], clip[0], clip[2], clip[6], clip[12] };
#endif
        }
        else if( transposeIdx == 2 )
        {//!<垂直翻转
          filterCoeff = { coef[0], coef[3], coef[2], coef[1], coef[8], coef[7], coef[6], coef[5], coef[4], coef[9], coef[10], coef[11], coef[12] };
#if JVET_N0242_NON_LINEAR_ALF
          filterClipp = { clip[0], clip[3], clip[2], clip[1], clip[8], clip[7], clip[6], clip[5], clip[4], clip[9], clip[10], clip[11], clip[12] };
#endif
        }
        else if( transposeIdx == 3 )
        {//!<旋转变换
          filterCoeff = { coef[9], coef[8], coef[10], coef[4], coef[3], coef[7], coef[11], coef[5], coef[1], coef[0], coef[2], coef[6], coef[12] };
#if JVET_N0242_NON_LINEAR_ALF
          filterClipp = { clip[9], clip[8], clip[10], clip[4], clip[3], clip[7], clip[11], clip[5], clip[1], clip[0], clip[2], clip[6], clip[12] };
#endif
        }
        else
        {//!<不变换
          filterCoeff = { coef[0], coef[1], coef[2], coef[3], coef[4], coef[5], coef[6], coef[7], coef[8], coef[9], coef[10], coef[11], coef[12] };
#if JVET_N0242_NON_LINEAR_ALF
          filterClipp = { clip[0], clip[1], clip[2], clip[3], clip[4], clip[5], clip[6], clip[7], clip[8], clip[9], clip[10], clip[11], clip[12] };
#endif
        }
      }
      else
      {
        if( transposeIdx == 1 )
        {//!<对角线变换
          filterCoeff = { coef[4], coef[1], coef[5], coef[3], coef[0], coef[2], coef[6] };
#if JVET_N0242_NON_LINEAR_ALF
          filterClipp = { clip[4], clip[1], clip[5], clip[3], clip[0], clip[2], clip[6] };
#endif
        }
        else if( transposeIdx == 2 )
        {//!<垂直翻转
          filterCoeff = { coef[0], coef[3], coef[2], coef[1], coef[4], coef[5], coef[6] };
#if JVET_N0242_NON_LINEAR_ALF
          filterClipp = { clip[0], clip[3], clip[2], clip[1], clip[4], clip[5], clip[6] };
#endif
        }
        else if( transposeIdx == 3 )
        {//!<旋转变换
          filterCoeff = { coef[4], coef[3], coef[5], coef[1], coef[0], coef[2], coef[6] };
#if JVET_N0242_NON_LINEAR_ALF
          filterClipp = { clip[4], clip[3], clip[5], clip[1], clip[0], clip[2], clip[6] };
#endif
        }
        else
        {//!<不变换
          filterCoeff = { coef[0], coef[1], coef[2], coef[3], coef[4], coef[5], coef[6] };
#if JVET_N0242_NON_LINEAR_ALF
          filterClipp = { clip[0], clip[1], clip[2], clip[3], clip[4], clip[5], clip[6] };
#endif
        }

采用的几何变换方式由上面计算的四个方向的梯度决定:

   int hv1, hv0, d1, d0, hvd1, hvd0;
​
      if( sumV > sumH )
      {
        hv1 = sumV;
        hv0 = sumH;
        dirTempHV = 1;
      }
      else
      {
        hv1 = sumH;
        hv0 = sumV;
        dirTempHV = 3;
      }
      if( sumD0 > sumD1 )
      {
        d1 = sumD0;
        d0 = sumD1;
        dirTempD = 0;
      }
      else
      {
        d1 = sumD1;
        d0 = sumD0;
        dirTempD = 2;
      }
      if( d1*hv0 > hv1*d0 )
      {
        hvd1 = d1;
        hvd0 = d0;
        mainDirection = dirTempD;
        secondaryDirection = dirTempHV;
      }
      else
      {
        hvd1 = hv1;
        hvd0 = hv0;
        mainDirection = dirTempHV;
        secondaryDirection = dirTempD;
      }
​
      int directionStrength = 0;
      if( hvd1 > 2 * hvd0 )
      {
        directionStrength = 1;
      }
      if( hvd1 * 2 > 9 * hvd0 )
      {
        directionStrength = 2;
      }
​
      if( directionStrength )
      {
        classIdx += ( ( ( mainDirection & 0x1 ) << 1 ) + directionStrength ) * 5;
      }
      //!<几何变换索引计算
      static const int transposeTable[8] = { 0, 1, 0, 2, 2, 3, 1, 3 };
      int transposeIdx = transposeTable[mainDirection * 2 + ( secondaryDirection >> 1 )];

4、滤波器参数传输

在VTM5中,ALF滤波器参数在Adaptation Parameter Set (APS)中。在一个APS中,有至多25组亮度滤波器参数和门限值,及至多1组色度滤波器参数和门限值。为了减少比特开销,不同类别的滤波器参数可以merge。当前slice使用的APS索引在slice header中。

APS中可以解码出门限值索引,通过门限值索引可以从亮度门限值列表和色度门限值列表中指定所需的门限值。门限值列表由位深决定:

滤波过程可以在CTB级进行控制,可以传输一个标志位表示是否需要对一个亮度CTB进行ALF滤波。一个亮度CTB使用的滤波器可以从16个固定滤波器和APS提供的滤波器中选择。有一个滤波器索引表示最终使用的滤波器。16个固定滤波器是预定义好的,硬编码进编码器和解码器了。

滤波器参数被量化成均值为128。为了减少乘法的复杂性,需要对码流进行一致性处理以使非中心位置的参数在[-128,127]间。中心位置的参数不需要传输,默认等于128。

5、滤波操作

感兴趣的请关注微信公众号Video Coding

发布了108 篇原创文章 · 获赞 189 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/Dillon2015/article/details/104288658