VTM10.0反量化之RDOQ一般量化
Posted 神遁克里苏
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VTM10.0反量化之RDOQ一般量化相关的知识,希望对你有一定的参考价值。
RDOQ与一般量化的过程虽然不同,但是解码的步骤时在相同的,如下:
解码都调用的dequant函数:
该函数主要完成写下面的公式,进行反量化。
void Quant::dequant(const TransformUnit &tu,
CoeffBuf &dstCoeff,
const ComponentID &compID,
const QpParam &cQP)
{
const SPS *sps = tu.cs->sps;
const CompArea &area = tu.blocks[compID];
const uint32_t uiWidth = area.width;
const uint32_t uiHeight = area.height;
TCoeff *const piCoef = dstCoeff.buf;
const uint32_t numSamplesInBlock = uiWidth * uiHeight;
const int maxLog2TrDynamicRange = sps->getMaxLog2TrDynamicRange(toChannelType(compID));
const TCoeff transformMinimum = -(1 << maxLog2TrDynamicRange);
const TCoeff transformMaximum = (1 << maxLog2TrDynamicRange) - 1;
const bool isTransformSkip = (tu.mtsIdx[compID] == MTS_SKIP);
const bool disableSMForLFNST = tu.cs->slice->getExplicitScalingListUsed() ? tu.cs->slice->getSPS()->getDisableScalingMatrixForLfnstBlks() : false;
const bool isLfnstApplied = tu.cu->lfnstIdx > 0 && (tu.cu->isSepTree() ? true : isLuma(compID));
const bool disableSMForACT = tu.cs->slice->getSPS()->getScalingMatrixForAlternativeColourSpaceDisabledFlag() && (tu.cs->slice->getSPS()->getScalingMatrixDesignatedColourSpaceFlag() == tu.cu->colorTransform);
const bool enableScalingLists = getUseScalingList(uiWidth, uiHeight, isTransformSkip, isLfnstApplied, disableSMForLFNST, disableSMForACT);
const int scalingListType = getScalingListType(tu.cu->predMode, compID);
const int channelBitDepth = sps->getBitDepth(toChannelType(compID));
const TCoeff *coef;
if ((tu.cu->bdpcmMode && isLuma(compID)) || ( tu.cu->bdpcmModeChroma && isChroma(compID) ))
{
invResDPCM( tu, compID, dstCoeff );
coef = piCoef;
}
else
{
coef = tu.getCoeffs(compID).buf;
}
const TCoeff *const piQCoef = coef;
CHECK(scalingListType >= SCALING_LIST_NUM, "Invalid scaling list");
CHECK(uiWidth > m_uiMaxTrSize, "Unsupported transformation size");
// Represents scaling through forward transform
const bool bClipTransformShiftTo0 = tu.mtsIdx[compID] != MTS_SKIP && sps->getSpsRangeExtension().getExtendedPrecisionProcessingFlag();
const int originalTransformShift = getTransformShift(channelBitDepth, area.size(), maxLog2TrDynamicRange);
const bool needSqrtAdjustment = TU::needsBlockSizeTrafoScale( tu, compID );
const int iTransformShift = (bClipTransformShiftTo0 ? std::max<int>(0, originalTransformShift) : originalTransformShift) + (needSqrtAdjustment?-1:0);
const int QP_per = cQP.per(isTransformSkip);// QP/6
const int QP_rem = cQP.rem(isTransformSkip);// QP%6
const int rightShift = (IQUANT_SHIFT - ((isTransformSkip ? 0 : iTransformShift) + QP_per)) + (enableScalingLists ? LOG2_SCALING_LIST_NEUTRAL_VALUE : 0);
if(enableScalingLists)//是否使用量化矩阵
{
//from the dequantization equation:
//iCoeffQ = ((Intermediate_Int(clipQCoef) * piDequantCoef[deQuantIdx]) + iAdd ) >> rightShift
//(sizeof(Intermediate_Int) * 8) = inputBitDepth + dequantCoefBits - rightShift
const uint32_t dequantCoefBits = 1 + IQUANT_SHIFT + SCALING_LIST_BITS;
const uint32_t targetInputBitDepth = std::min<uint32_t>((maxLog2TrDynamicRange + 1), (((sizeof(Intermediate_Int) * 8) + rightShift) - dequantCoefBits));
const Intermediate_Int inputMinimum = -(1 << (targetInputBitDepth - 1));
const Intermediate_Int inputMaximum = (1 << (targetInputBitDepth - 1)) - 1;
const uint32_t uiLog2TrWidth = floorLog2(uiWidth);
const uint32_t uiLog2TrHeight = floorLog2(uiHeight);
int *piDequantCoef = getDequantCoeff(scalingListType, QP_rem, uiLog2TrWidth, uiLog2TrHeight);
if(rightShift > 0)
{
const Intermediate_Int iAdd = (Intermediate_Int) 1 << (rightShift - 1);
for( int n = 0; n < numSamplesInBlock; n++ )
{
const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, piQCoef[n]));
const Intermediate_Int iCoeffQ = ((Intermediate_Int(clipQCoef) * piDequantCoef[n]) + iAdd ) >> rightShift;
piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
}
}
else
{
const int leftShift = -rightShift;
for( int n = 0; n < numSamplesInBlock; n++ )
{
const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, piQCoef[n]));
const Intermediate_Int iCoeffQ = (Intermediate_Int(clipQCoef) * piDequantCoef[n]) << leftShift;
piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
}
}
}
else//不使用量化矩阵
{
const int scale = g_invQuantScales[needSqrtAdjustment?1:0][QP_rem];
const int scaleBits = ( IQUANT_SHIFT + 1 );
//from the dequantisation equation:
//iCoeffQ = Intermediate_Int((int64_t(clipQCoef) * scale + iAdd) >> rightShift);
//(sizeof(Intermediate_Int) * 8) = inputBitDepth + scaleBits - rightShift
const uint32_t targetInputBitDepth = std::min<uint32_t>((maxLog2TrDynamicRange + 1), (((sizeof(Intermediate_Int) * 8) + rightShift) - scaleBits));
const Intermediate_Int inputMinimum = -(1 << (targetInputBitDepth - 1));
const Intermediate_Int inputMaximum = (1 << (targetInputBitDepth - 1)) - 1;
if (rightShift > 0)//如果右移位数大于0
{
const Intermediate_Int iAdd = (Intermediate_Int) 1 << (rightShift - 1);
for( int n = 0; n < numSamplesInBlock; n++ )
{
const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, piQCoef[n]));
const Intermediate_Int iCoeffQ = (Intermediate_Int(clipQCoef) * scale + iAdd) >> rightShift;
piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
}
}
else//如果是不移或者左移(其实与右移相似,只是左移不用再进行四舍五入了)
{
const int leftShift = -rightShift;
for( int n = 0; n < numSamplesInBlock; n++ )
{
const TCoeff clipQCoef = TCoeff(Clip3<Intermediate_Int>(inputMinimum, inputMaximum, piQCoef[n]));
const Intermediate_Int iCoeffQ = (Intermediate_Int(clipQCoef) * scale) << leftShift;
piCoef[n] = TCoeff(Clip3<Intermediate_Int>(transformMinimum,transformMaximum,iCoeffQ));
}
}
}
}
以上是关于VTM10.0反量化之RDOQ一般量化的主要内容,如果未能解决你的问题,请参考以下文章