xEstimateMvPredAMVP函数在获取到AMVP列表之后,调用xGetTemplateCost函数,来逐个计算每个AMVP候选的失真大小。
参数cMvCand,即为需要计算失真的AMVP候选。iMVPIdx为AMVP候选在列表中的idx,iMVPNum为AMVP候选列表的大小。失真的计算,就是AMVP候选mv所指向的pred像素predBuf,与pu原始像素origBuf之间的失真。
xGetTemplateCost函数中,调用xPredInterBlk函数来计算AMVP候选mv所指向的预测像素predBuf。其在运动补偿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 ); //参考帧
#if REMOVE_MV_ADAPT_PREC
cMvCand.hor = cMvCand.hor << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
cMvCand.ver = cMvCand.ver << VCEG_AZ07_MV_ADD_PRECISION_BIT_FOR_STORE;
#endif
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 JVET_L0256_BIO
, false
#endif
#if JVET_L0293_CPR
, false
#endif
);
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;
}