突然发现自己这个系列起的名字函数入门怪怪的,不是很对,但是现在更改也不方便啦,其实很少涉及HEVC真正的函数,应该是HM中的函数,懒癌犯了,下面接着参考http://blog.youkuaiyun.com/NB_vol_1/article/details/51162846来看一下MV的获取吧。
xEstimateMvPredAMVP的工作流程
首先注意:AMVP模式的入口函数是xCheckRDCostInter
主要流程如下:
(1)得到当前的深度。
(2)调用predInterSearch,进行ME(运动估计)和MC(运动补偿)。
(3)调用encodeResAndCalcRdInterCU,根据预测值,求出残差,然后进行TU的划分,然后进行变换、量化等操作以及RD代价的计算。
(4)调用xCheckBestMode选择最好的模式。
其次注意:ME,MC的入口函数为predInterSearch
再次,predInterSearch调用xEstimateMvPredAMVP,其流程如下:
AMVP中MVP的获取就是通过xEstimateMvPredAMVP这个函数得到的
1、判断bFilled标识,该标识表示MVP候选列表是否已经建立好
2、如果bFilled是false,通过fillMvpCand获取MVP候选列表;否则,不需要重新建立MVP候选列表
3、先把MVP候选列表中的第一个MVP作为最优的MVP
4、如果候选列表中MVP的数量小于等于1,那么直接把步骤3选出的MVP返回
5、如果bFilled是true,表示MVP候选列表是原来已经建立好的,那么直接根据PU的相关信息得到最优的MVP,然后返回
6、遍历MVP候选列表,选出代价最小的MVP作为当前PU的MVP,并设置相关信息,然后返回
Void TEncSearch::xEstimateMvPredAMVP( TComDataCU* pcCU, TComYuv* pcOrgYuv, UInt uiPartIdx, RefPicList eRefPicList, Int iRefIdx, TComMv& rcMvPred, Bool bFilled, Distortion* puiDistBiP )
{
AMVPInfo* pcAMVPInfo = pcCU->getCUMvField(eRefPicList)->getAMVPInfo();
TComMv cBestMv;
Int iBestIdx = 0;
TComMv cZeroMv;
TComMv cMvPred;
Distortion uiBestCost = std::numeric_limits<Distortion>::max();
UInt uiPartAddr = 0;
Int iRoiWidth, iRoiHeight;
Int i;
// 得到此次分割的索引和大小
pcCU->getPartIndexAndSize( uiPartIdx, uiPartAddr, iRoiWidth, iRoiHeight );
// Fill the MV Candidates
// 获取MVP(即预测的MV),MVP存放在pcAMVPInfo中
if (!bFilled)
{
pcCU->fillMvpCand( uiPartIdx, uiPartAddr, eRefPicList, iRefIdx, pcAMVPInfo );
}
// initialize Mvp index & Mvp
// 最优MVP的默认索引是0
iBestIdx = 0;
// 最优MVP默认是列表的第一个
cBestMv = pcAMVPInfo->m_acMvCand[0];
// 如果MVP候选列表中