H.266中的各类滤波器总结

      一直搞不清楚各种滤波器之间的区别,今天好好看看记录下来(持续更新)。

一.参考采样中的平滑滤波

在函数initIntraPatternChType里面,完成对相邻参考采样的填充后,要对参考采样进行平滑滤波;

平滑滤波又分为强平滑滤波和常规平滑滤波。

强平滑滤波的条件:只用于亮度分量且块的宽大于32且相邻采样间的差大于某个阈值

 Bool useStrongIntraSmoothing = isLuma(chType) && sps.getUseStrongIntraSmoothing();
      const Pel bottomLeft = piIntraTemp[stride * uiTuHeight2];//左下
      const Pel topLeft    = piIntraTemp[0];//左上
      const Pel topRight   = piIntraTemp[uiTuWidth2];//右上

      if (useStrongIntraSmoothing)
      {
#if O0043_BEST_EFFORT_DECODING
        const Int  threshold     = 1 << (bitDepthForChannelInStream - 5);//32;
#else
        const Int  threshold     = 1 << (bitDepthForChannel - 5);
#endif  //对左列的参考像素和上方的参考像素进行双线性插值
        const Bool bilinearLeft  = abs((bottomLeft + topLeft ) - (2 * piIntraTemp[stride * uiTuHeight])) < threshold; //difference between the
        const Bool bilinearAbove = abs((topLeft    + topRight) - (2 * piIntraTemp[         uiTuWidth ])) < threshold; //ends and the middle
        if ((uiTuWidth < 32) || (!bilinearLeft) || (!bilinearAbove))//如果满足三个条件的其中之一,就不执行强平滑滤波
        {
          useStrongIntraSmoothing = false;
        }
      }

过程(以左列参考像素为例):

强平滑滤波:

  if (useStrongIntraSmoothing)
      {
#if JVET_C0024_QTBT
        const Int shift = g_aucConvertToBit[uiTuHeight] + MIN_CU_LOG2 + 1; //log2(uiTuHeight2)    //it is a bug for non-square PU for strong filter, JCA
#endif
       //滤波系数与距离有关
        for(UInt i=1; i<uiTuHeight2; i++, piDestPtr-=stride)
        {
          *piDestPtr = (((uiTuHeight2 - i) * bottomLeft) + (i * topLeft) + uiTuHeight) >> shift;
        }

        piSrcPtr -= stride * (uiTuHeight2 - 1);
      }

常规滤波:

  for(UInt i=1; i<uiTuHeight2; i++, piDestPtr-=stride, piSrcPtr-=stride)
        {
          *piDestPtr = ( piSrcPtr[stride] + 2*piSrcPtr[0] + piSrcPtr[-stride] + 2 ) >> 2;//即是[1 2 1]/4的3抽头滤波
        }


二.EdgeFilter

该滤波器在xPredIntraAng函数里面使用。

        enableEdgeFilters = !(pcCU->isRDPCMEnabled(uiAbsPartIdx) && pcCU->getCUTransquantBypass(uiAbsPartIdx));

条件:只对亮度分量且块的宽和高都小于16的块应用。

过程:当模式是纯水平或者是纯垂直模式,则对预测块(即已经得到预测值的当前块)的第一行/第一列进行滤波;

          pDst[y*dstStride] = ClipA (pDst[y*dstStride] + (( refSide[y+1] - refSide[0] ) >> 1) ,compID);

         当模式是纯水平模式左右的模式(即17,19)和纯垂直模式左右的模式(即49,51),则对预测块的第一行/第一列进行滤波;

         pDst[y*dstStride] = ClipA(pDst[y*dstStride] + (( refSide[y+1] - refSide[0] ) >> 2) ,compID);

总结:EdgeFilter模式只用于纯水平垂直和类水平垂直(各两个)模式,对预测值进行滤波。

三.BoundaryFilter

该滤波器在xPredIntraAng函数后面使用。

         enableBoundaryFilter = pcCU->getSlice()->getSPS()->getUseIntraBoundaryFilter();

条件:只对亮度分量且块的宽和高都大于2的块应用,且只应用于角度模式;

过程:当模式是2时,对预测块的上面四行(JEM中扩展到了4行)进行2抽头滤波;

for ( Int x = 0; x < iWidth; x++ )
  {
    pDst[x             ] = (  8 * pDst[x             ] + 8 * pSrc[x - iSrcStride + 1] + 8 ) >> 4;
#if VCEG_AZ07_INTRA_BOUNDARY_FILTER_MULTI_LINE
    pDst[x+iDstStride  ] = ( 12 * pDst[x+iDstStride  ] + 4 * pSrc[x - iSrcStride + 2] + 8 ) >> 4;
#if JVET_C0024_QTBT
    if (iHeight>2)
    {
#endif
    pDst[x+iDstStride*2] = ( 14 * pDst[x+iDstStride*2] + 2 * pSrc[x - iSrcStride + 3] + 8 ) >> 4;
    pDst[x+iDstStride*3] = ( 15 * pDst[x+iDstStride*3] +     pSrc[x - iSrcStride + 4] + 8 ) >> 4; 
#if JVET_C0024_QTBT
    }
#endif
#endif
  }

         当模式是66时,对预测块的最左边四列(JEM中扩展到了4列)进行2抽头滤波;

 for ( Int y = 0, iDstStride2 = 0, iSrcStride2 = -1; y < iHeight; y++, iDstStride2+=iDstStride, iSrcStride2+=iSrcStride )
  {
    pDst[iDstStride2  ] = (  8 * pDst[iDstStride2  ] + 8 * pSrc[iSrcStride2+iSrcStride  ] + 8 ) >> 4;
#if VCEG_AZ07_INTRA_BOUNDARY_FILTER_MULTI_LINE
    pDst[iDstStride2+1] = ( 12 * pDst[iDstStride2+1] + 4 * pSrc[iSrcStride2+iSrcStride*2] + 8 ) >> 4;     
#if JVET_C0024_QTBT
    if (iWidth>2)
    {
#endif
    pDst[iDstStride2+2] = ( 14 * pDst[iDstStride2+2] + 2 * pSrc[iSrcStride2+iSrcStride*3] + 8 ) >> 4;    
    pDst[iDstStride2+3] = ( 15 * pDst[iDstStride2+3] +     pSrc[iSrcStride2+iSrcStride*4] + 8 ) >> 4;
#if JVET_C0024_QTBT
    }
#endif
#endif
  }

        当模式是3--10或者是58--66模式,则

        如果是水平模式,则对当前块的第一行边界进行3抽头滤波;

 for ( Int x = 0; x < iWidth; x++ )
    {
      pDst[x] = ( filter[0] * pDst[x] 
      + filter[1] * pSrc[x - iSrcStride + offset[0]] 
      + filter[2] * pSrc[x - iSrcStride + offset[1]] + 8) >> 4;//对第一行边界进行3抽头滤波
    }

       如果是垂直模式,则对当前块的第一列边界进行3抽头滤波;

 for ( Int y = 0; y < iHeight; y++ )
    {         
      pDst[y * iDstStrid
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值