为了更好地与draft进行对应,看HM中的反量化部分代码:
Void TComTrQuant::xDeQuant(Int bitDepth, const TCoeff* pSrc, Int* pDes, Int iWidth, Int iHeight, Int scalingListType )
{
const TCoeff* piQCoef = pSrc;
Int* piCoef = pDes;
if ( iWidth > (Int)m_uiMaxTrSize )
{
iWidth = m_uiMaxTrSize;
iHeight = m_uiMaxTrSize;
}
Int iShift,iAdd,iCoeffQ;
UInt uiLog2TrSize = g_aucConvertToBit[ iWidth ] + 2;
Int iTransformShift = MAX_TR_DYNAMIC_RANGE - bitDepth - uiLog2TrSize;
iShift = QUANT_IQUANT_SHIFT - QUANT_SHIFT - iTransformShift; //!< draft (8-240)、(8-241)
//! iShift = bitDepth + uiLog2 - 5 - 4
//! 注意,这个结果比draft中多减了个4,这是因为此时scaling_list_enable_flag默认情况下为0,则m[x][y]为16,比较
//! 式(8-250)可知代码中并未乘以m[x][y],而iShift比式子小了4(相当于总结果少除以16),故代码与draft两者是一致的
TCoeff clipQCoef;
const Int bitRange = min( 15, ( Int )( 12 + uiLog2TrSize + bitDepth - m_cQP.m_iPer) );
const Int levelLimit = 1 << bitRange;
if(getUseScalingList()) //!< 默认情况下为false
{
iShift += 4;
if(iShift > m_cQP.m_iPer)
{
iAdd = 1 << (iShift - m_cQP.m_iPer - 1);
}
else
{
iAdd = 0;
}
Int *piDequantCoef = getDequantCoeff(scalingListType,m_cQP.m_iRem,uiLog2TrSize-2);
if(iShift > m_cQP.m_iPer)
{
for( Int n = 0; n < iWidth*iHeight; n++ )
{
clipQCoef = Clip3( -32768, 32767, piQCoef[n] );
iCoeffQ = ((clipQCoef * piDequantCoef[n]) + iAdd ) >> (iShift - m_cQP.m_iPer);
piCoef[n] = Clip3(-32768,32767,iCoeffQ);
}
}
else
{
for( Int n = 0; n < iWidth*iHeight; n++ )
{
clipQCoef = Clip3( -levelLimit, levelLimit - 1, piQCoef[n] );
iCoeffQ = (clipQCoef * piDequantCoef[n]) << (m_cQP.m_iPer - iShift);
piCoef[n] = Clip3(-32768,32767,iCoeffQ);
}
}
}
else //!< draft 8.6.3 (8-250)
{
iAdd = 1 << (iShift-1);
Int scale = g_invQuantScales[m_cQP.m_iRem] << m_cQP.m_iPer; //!< levelScale[qP % 6] << (qP / 6)
for( Int n = 0; n < iWidth*iHeight; n++ )
{
clipQCoef = Clip3( -32768, 32767, piQCoef[n] ); //!< TransCoeffLevel[xT][yT][cIdx]
iCoeffQ = ( clipQCoef * scale + iAdd ) >> iShift; //!< d[x][y]
piCoef[n] = Clip3(-32768,32767,iCoeffQ);
}
}
}