H.266/VVC变换代码学习:xTransformSkip函数

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/BigDream123/article/details/102748887

xTransformSkip函数主要适用于TransformSkip模式下跳过变换直接对残差系数进行伸缩和移位;TransformSkip模式主要用于Luma变换块,且最大尺寸限制为32x32

基本流程如下:

  1. 初始化移位系数iTransformShift和伸缩系数iWHScale
  2. 判断移位系数iTransformShift,若iTransformShift大于等于0则直接将残差系数进行伸缩和移位并赋值给psCoeff,否则执行3
  3. iTransformShift取反,然后获取偏移值offset,对残差系数进行伸缩并加上偏移再进行移位,再将结果赋值给psCoeff

代码如下:

/*
变换跳过:将残差系数进行伸缩和移位
*/
void TrQuant::xTransformSkip(const TransformUnit &tu, const ComponentID &compID, const CPelBuf &resi, TCoeff* psCoeff)
{
  const SPS &sps            = *tu.cs->sps;
  const CompArea &rect      = tu.blocks[compID];
  const uint32_t width          = rect.width;
  const uint32_t height         = rect.height;
  const ChannelType chType  = toChannelType(compID);//LUMA = 0;CHROMA = 1
  const int channelBitDepth = sps.getBitDepth(chType);
  const int maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange(chType);
  int iTransformShift       = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange);

  if( sps.getSpsRangeExtension().getExtendedPrecisionProcessingFlag() )
  {
    iTransformShift = std::max<int>( 0, iTransformShift );//移位系数
  }

  int iWHScale = 1;//伸缩系数

  const bool rotateResidual = TU::isNonTransformedResidualRotated( tu, compID ); //是否残差旋转
  const uint32_t uiSizeMinus1 = ( width * height ) - 1;

  if( iTransformShift >= 0 )
  {
    for( uint32_t y = 0, coefficientIndex = 0; y < height; y++ )
    {
      for( uint32_t x = 0; x < width; x++, coefficientIndex++ )
      {
        //先判断残差系数是否旋转
        //若残差系数旋转则psCoeff对应索引为uiSizeMinus1 - coefficientIndex
        //若残差系数没有旋转则psCoeff对应索引为coefficientIndex
        //将残差系数进行伸缩和移位赋值给psCoeff
        psCoeff[rotateResidual ? uiSizeMinus1 - coefficientIndex : coefficientIndex] = ( TCoeff( resi.at( x, y ) ) * iWHScale ) << iTransformShift;
      }
    }
  }
  else //for very high bit depths
  {
    iTransformShift = -iTransformShift;
    const TCoeff offset = 1 << ( iTransformShift - 1 );//偏移

    for( uint32_t y = 0, coefficientIndex = 0; y < height; y++ )
    {
      for( uint32_t x = 0; x < width; x++, coefficientIndex++ )
      {
        psCoeff[rotateResidual ? uiSizeMinus1 - coefficientIndex : coefficientIndex] = ( TCoeff( resi.at( x, y ) ) * iWHScale + offset ) >> iTransformShift;
      }
    }
  }
}

猜你喜欢

转载自blog.csdn.net/BigDream123/article/details/102748887