VVC/VTM:代码学习——alfFilter()函数

25个ALF滤波器的系数存储在Slice级别,所以,先解析Slice级别的滤波器参数(filter coefficient),解析滤波器参数的主体函数为void HLSyntaxReader::alfFilter()
关键点包括

  1. alfLumaCoeffDeltaPredictionFlag :亮度分量的滤波器之间的Filter Coeff可使用DPCM编码方式;
  2. alfLumaCoeffDeltaFlag :用总标识位标识是否每个FIlter都传输了参数;
  3. alfLumaCoeffFlag:每个滤波器单独一个Flag标识是否传输了参数;
  4. 滤波器参数用k阶指数哥伦布码进行熵编码;
void HLSyntaxReader::alfFilter( AlfSliceParam& alfSliceParam, const bool isChroma )
{
  uint32_t code;
  if( !isChroma )
  {
  //alfLumaCoeffDeltaFlag :numLumaFilters 个是否都传输了Filter Coeff(意思是有些滤波器没有传输参数)
    READ_FLAG( code, "alf_luma_coeff_delta_flag" );
    alfSliceParam.alfLumaCoeffDeltaFlag = code;

    if( !alfSliceParam.alfLumaCoeffDeltaFlag )
    {
      std::memset( alfSliceParam.alfLumaCoeffFlag, true, sizeof( alfSliceParam.alfLumaCoeffFlag ) );

      if( alfSliceParam.numLumaFilters > 1 )
      {
      //alfLumaCoeffDeltaPredictionFlag :Filter Coeff之间是否采用DPCM的方式编码(差分编码)
        READ_FLAG( code, "alf_luma_coeff_delta_prediction_flag" );
        alfSliceParam.alfLumaCoeffDeltaPredictionFlag = code;
      }
      else
      {
      //若滤波器种类数只有1个,那么也不存在DPCM编码方式这一做法
        alfSliceParam.alfLumaCoeffDeltaPredictionFlag = 0;
      }
    }
    else
    {
      alfSliceParam.alfLumaCoeffDeltaPredictionFlag = 0;
    }
  }

  // derive maxGolombIdx,根据颜色分量获取滤波器形状,色度5x5或亮度7x7
  AlfFilterShape alfShape( isChroma ? 5 : 7 );
  const int maxGolombIdx = AdaptiveLoopFilter::getMaxGolombIdx( alfShape.filterType );
  READ_UVLC( code, isChroma ? "alf_chroma_min_eg_order_minus1" : "alf_luma_min_eg_order_minus1" );

  int kMin = code + 1;
  static int kMinTab[MAX_NUM_ALF_COEFF];
  //滤波器种类数numFilters ,色度统一使用一个滤波器,亮度分量根据解析的参数赋值
  const int numFilters = isChroma ? 1 : alfSliceParam.numLumaFilters;
  short* coeff = isChroma ? alfSliceParam.chromaCoeff : alfSliceParam.lumaCoeff;

  for( int idx = 0; idx < maxGolombIdx; idx++ )
  {
    READ_FLAG( code, isChroma ? "alf_chroma_eg_order_increase_flag"  : "alf_luma_eg_order_increase_flag" );
    CHECK( code > 1, "Wrong golomb_order_increase_flag" );
    kMinTab[idx] = kMin + code;
    kMin = kMinTab[idx];
  }

  if( !isChroma )
  {
    if( alfSliceParam.alfLumaCoeffDeltaFlag )
    //如果numLumaFilters个滤波器均传输了Filter Coeff,获取某个滤波器是否传输Filter Coeff
    {
      for( int ind = 0; ind < alfSliceParam.numLumaFilters; ++ind )
      {
        READ_FLAG( code, "alf_luma_coeff_flag[i]" );
        alfSliceParam.alfLumaCoeffFlag[ind] = code;//第ind个滤波器是否传输了Filter Coeff
      }
    }
  }

  // Filter coefficients
  for( int ind = 0; ind < numFilters; ++ind )//逐个解析滤波器参数
  {
    if( !isChroma && !alfSliceParam.alfLumaCoeffFlag[ind] && alfSliceParam.alfLumaCoeffDeltaFlag )
    //若亮度分量情况下,不是numLumaFilters个都传输了Filter Coeff,且第ind个滤波器未传输Filter Coeff,则直接将当前Filter Coeff置0
    {
      memset( coeff + ind * MAX_NUM_ALF_LUMA_COEFF, 0, sizeof( *coeff ) * alfShape.numCoeff );
      continue;
    }

    for( int i = 0; i < alfShape.numCoeff - 1; i++ )
    //否则,解析Filter Coeff
    {
    //熵解码滤波器参数
      coeff[ind * MAX_NUM_ALF_LUMA_COEFF + i] = alfGolombDecode( kMinTab[alfShape.golombIdx[i]] );
    }
  }
}



原文:https://blog.csdn.net/baidu_28446365/article/details/89927944

你可能感兴趣的:(VVC,(H266))