inter_ME模式的时候,调用xEstimateMvPredAMVP进行AMVP,获得当前pu的相邻运动信息,构建AMVP列表,最终选择出最优的MVP。
AMVP最终获得的MVP作为ME的起点。
xEstimateMvPredAMVP函数流程很简单:
fillMvpCand函数构建AMVP列表;
然后遍历列表中所有AMVP候选,通过xGetTemplateCost函数得到失真;
最终选择失真最小的AMVP候选,将其mvpIdx返回即可。
入口参数rcMvPred用来存储并返回AMVP最优的mvp,用于AMVP之后的ME。
Void InterSearch::xEstimateMvPredAMVP( PredictionUnit& pu, PelUnitBuf& origBuf, RefPicList eRefPicList, Int iRefIdx, Mv& rcMvPred, AMVPInfo& rAMVPInfo, Bool bFilled, Distortion* puiDistBiP )
{
Mv cBestMv;
Int iBestIdx = 0;
Distortion uiBestCost = std::numeric_limits<Distortion>::max();
Int i;
AMVPInfo* pcAMVPInfo = &rAMVPInfo; //AMVPInfo为AMVP列表的类,存储AMVP候选
// Fill the MV Candidates
if (!bFilled)
{
PU::fillMvpCand( pu, eRefPicList, iRefIdx, *pcAMVPInfo ); //构建AMVP候选列表
}
// initialize Mvp index & Mvp
iBestIdx = 0;
cBestMv = pcAMVPInfo->mvCand[0];
PelUnitBuf predBuf = m_tmpStorageLCU.getBuf( UnitAreaRelative(*pu.cu, pu) );
//-- Check Minimum Cost.
for( i = 0 ; i < pcAMVPInfo->numCand; i++)
{ //xGetTemplateCost计算失真 选最优
Distortion uiTmpCost = xGetTemplateCost( pu, origBuf, predBuf, pcAMVPInfo->mvCand[i], i, AMVP_MAX_NUM_CANDS, eRefPicList, iRefIdx );
if( uiBestCost > uiTmpCost )
{
uiBestCost = uiTmpCost;
cBestMv = pcAMVPInfo->mvCand[i];
iBestIdx = i;
(*puiDistBiP) = uiTmpCost;
}
}
// Setting Best MVP
rcMvPred = cBestMv;
pu.mvpIdx[eRefPicList] = iBestIdx; //最优AMVP候选的AMVPIdx
pu.mvpNum[eRefPicList] = pcAMVPInfo->numCand;
return;
}