这几天的任务是了解HM代码中变换量化的部分,能够熟练提取残差系数、变换系数以及量化系数等。定位到变换量化的函数是TComTrQuant::TransformN×N,假期的时候稍微了解了一下HEVC,但是直接看这个函数有点萌比的。`
Void TComTrQuant::transformNxN( TComTU & rTu,
const ComponentID compID,
Pel * pcResidual,//残差
const UInt uiStride,
TCoeff * rpcCoeff,//残差经过变换量化后的系数
#if ADAPTIVE_QP_SELECTION
TCoeff * pcArlCoeff,
#endif
TCoeff & uiAbsSum,
const QpParam & cQP
)
经过帧内、帧间预测,得到预测块的残差。预测残差 = 当前块信息 - 预测块信息
为了压缩残差信息的统计冗余,需要对残差数据进行变换和量化操作。
TComTrQuant::transformNxN这个函数核心调用了三个函数:xT,xTransformskip,xQuant。
if(pcCU->getTransformSkip(uiAbsPartIdx, compID) != 0)//skip模式
{
xTransformSkip( pcResidual, uiStride, m_plTempCoeff, rTu, compID );
}
对于4x4的 TU,HEVC 提供了 transformskip 模式,即跳过变换模式,在这种模式中,预测残差只进行移位。
xT函数实现变换功能,对帧内预测模式的4x4块进行DST变换,其余的根据块大小分别做蝶形快速变换(4x4,8x8,16x16,32x32)
若想要输出某一帧的残差数据,就需要设置getPOC()这个函数,这里要弄清楚与POC相关的量所在的类TComSlice和TComQuant之间的关系,才好做类继承:
TComSlice * pcSlice=pcCU->getPic()->getSlice(pcCU->getPic()->getCurrSliceIdx());
int sliceIdx=pcSlice ->getPOC();//slice即为帧数
下一步,这一帧的残差系数被提取出来了,还需要根据不同的TU尺寸(4×4/8×8/16×16/32×32)将这些数据进行划分,标识着TU尺寸的变量为uiWidth/uiHeight,设置一个switch case语句就可以将其分别打印输出了。