总结一下VVC普通量化部分
主体函数
void Quant::quant(TransformUnit &tu, const ComponentID &compID, const CCoeffBuf &pSrc, TCoeff &uiAbsSum, const QpParam &cQP, const Ctx& ctx)
主要用到的变量:
const CCoeffBuf &piCoef = pSrc; //变换系数
CoeffBuf piQCoef = tu.getCoeffs(compID); //量化后系数
//根据缩放类型获取量化系数矩阵
int *piQuantCoeff = getQuantCoeff(scalingListType, cQP.rem(useTransformSkip), uiLog2TrWidth, uiLog2TrHeight);
//获取默认量化系数 MF值
// cQP.per表示floor(QP/6)的值
// cQP.rem表示QP%6的值
const int defaultQuantisationCoefficient = g_quantScales[needSqrtAdjustment?1:0][cQP.rem(useTransformSkip)];
// iTranformShift表示整数DCT变换的缩放因子,该因子和变换尺寸有关
int iTransformShift = getTransformShift(channelBitDepth, rect.size(), maxLog2TrDynamicRange) + ( needSqrtAdjustment?-1:0);
//计算qbit,QUANT_SHIFT =14,cQP.per=floor(QP/6),qbit=14+floor(QP/6)
//如果使用的不是变换跳过模式,则再加上DCT系数的缩放因子
const int iQBits = QUANT_SHIFT + cQP.per(useTransformSkip) + (useTransformSkip ? 0 : iTransformShift);
// 计算f'=f<<(qbit+T)
const int64_t iAdd = int64_t(tu.cs->slice->isIRAP() ? 171 : 85) << int64_t(iQBits - 9);
const int qBits8 = iQBits - 8;
//最大系数数目
const int maxNumberOfCoeffs = lfnstIdx > 0 ? ((( uiWidth == 4 && uiHeight == 4 ) || ( uiWidth == 8 && uiHeight == 8) ) ? 8 : 16) : piQCoef.area();
然后,用for循环遍历块内所有系数,分别对其量化:
for (int uiScanPos = 0; uiScanPos < maxNumberOfCoeffs; uiScanPos++)
{
const int uiBlockPos = scan[uiScanPos].idx;//变换系数d
const TCoeff iLevel = piCoef.buf[uiBlockPos];//变换系数符号
const TCoeff iSign = (iLevel < 0 ? -1: 1);
// enableScalingLists 表示是否同时完成DCT变换中的伸缩因子的乘法运算
//表示缩放前的变换系数d * MF
const int64_t tmpLevel = (int64_t)abs(iLevel) * (enableScalingLists ? piQuantCoeff[uiBlockPos] : defaultQuantisationCoefficient);
//根据量化公式得到量化后系数的幅度值(即绝对值)
const TCoeff quantisedMagnitude = TCoeff((tmpLevel + iAdd ) >> iQBits); //|l(i,j)|
deltaU[uiBlockPos] = (TCoeff)((tmpLevel - ((int64_t)quantisedMagnitude<<iQBits) )>> qBits8);
uiAbsSum += quantisedMagnitude;
const TCoeff quantisedCoefficient = quantisedMagnitude * iSign;//最终的量化系数
piQCoef.buf[uiBlockPos] = Clip3<TCoeff>( entropyCodingMinimum, entropyCodingMaximum, quantisedCoefficient );
} // for n
if ((tu.cu->bdpcmMode && isLuma(compID)) || (tu.cu->bdpcmModeChroma && isChroma(compID)) )
{
fwdResDPCM( tu, compID );
}
if( cctx.signHiding() )
{
//这就防止了只有一个系数值为1的TUs被测试
if(uiAbsSum >= 2) //this prevents TUs with only one coefficient of value 1 from being tested
{
//只为了最小化失真,不考虑比特率
xSignBitHidingHDQ(piQCoef.buf, piCoef.buf, deltaU, cctx, maxLog2TrDynamicRange);
}
}
} //if RDOQ
//return;
}