版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
xTransformSkip函数主要适用于TransformSkip模式下跳过变换直接对残差系数进行伸缩和移位;TransformSkip模式主要用于Luma变换块,且最大尺寸限制为32x32
基本流程如下:
- 初始化移位系数iTransformShift和伸缩系数iWHScale
- 判断移位系数iTransformShift,若iTransformShift大于等于0则直接将残差系数进行伸缩和移位并赋值给psCoeff,否则执行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;
}
}
}
}