xGetTemplateCost在xEstimateMvPredAMVP函数中被调用。
在获取到AMVP列表之后,调用xGetTemplateCost函数,来逐个计算每个AMVP候选的失真大小。参数cMvCand,即为需要计算失真的AMVP候选。iMVPIdx为AMVP候选在列表中的idx,iMVPNum为AMVP候选列表的大小。
失真的计算,就是AMVP候选mv所指向的pred像素predBuf,与pu原始像素origBuf之间的失真。
xGetTemplateCost函数中,调用xPredInterBlk函数来计算AMVP候选mv所指向的预测像素predBuf,其在运动补偿MC过程中也会被调用,运动补偿MC时再分析该函数。
Distortion InterSearch::xGetTemplateCost( const PredictionUnit& pu,
PelUnitBuf& origBuf,
PelUnitBuf& predBuf,
Mv cMvCand,
Int iMVPIdx,
Int iMVPNum,
RefPicList eRefPicList,
Int iRefIdx
)
{
Distortion uiCost = std::numeric_limits<Distortion>::max();
const Picture* picRef = pu.cu->slice->getRefPic( eRefPicList, iRefIdx ); //参考帧
clipMv( cMvCand, pu.cu->lumaPos(), *pu.cs->sps );
// prediction pattern //是否进行单向加权预测
const Bool bi = pu.cu->slice->testWeightPred() && pu.cu->slice->getSliceType()==P_SLICE;
//xPredInterBlk函数在运动补偿MC时会调用
//获取参考帧picRef中cMvCand所指向位置处的参考像素,即为预测像素predBuf
xPredInterBlk( COMPONENT_Y, pu, picRef, cMvCand, predBuf, bi, pu.cu->slice->clpRng( COMPONENT_Y )
);
if ( bi ) //单向预测的加权预测
{
xWeightedPredictionUni( pu, predBuf, eRefPicList, predBuf, iRefIdx, m_maxCompIDToPred );
}
// calc distortion
//由原始像素origBuf和预测像素predBuf,计算AMVP候选的失真和cost
uiCost = m_pcRdCost->getDistPart( origBuf.Y(), predBuf.Y(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, DF_SAD );
uiCost += m_pcRdCost->getCost( m_auiMVPIdxCost[iMVPIdx][iMVPNum] );
return uiCost;
}