之前主要集中在亚像素部分,整像素搜索没仔细看,只看过理论部分,现在来看下整像素部分的代码。
之前已经说过,运动估计中首先进行整像素搜索,找到了一个局部最优点,作为亚像素搜索的起点继续搜索,得到最优MV。
整像素搜索的入口函数是xPatternSearch(Full search)和xPatternSearchFast(TZ search),两者的选择由m_iFastSearch决定。m_iFastSearch为真时,使用TZ search。m_iFastSearch通过cfg文件中的FastSearch赋值,默认为1,使用TZ search。其实m_iFastSearch为真时,是有两种取值的:当为1时,使用Diamond算法;当为2时使用PMVFAST算法。在实际应用中,都使用的是Diamond算法。
这里就来学习一下xPatternSearchFast函数,代码很简单,就是一个入口函数,其中调用重要函数xTZSearch来实现Diamond搜索,另一个xTZSearchSelective实现的是PMVFAST,一般不使用。
Void TEncSearch::xPatternSearchFast( TComDataCU* pcCU,
TComPattern* pcPatternKey,
Pel* piRefY,
Int iRefStride,
TComMv* pcMvSrchRngLT,
TComMv* pcMvSrchRngRB,
TComMv &rcMv,
Distortion &ruiSAD,
const TComMv* pIntegerMv2Nx2NPred )
{
assert (MD_LEFT < NUM_MV_PREDICTORS);
pcCU->getMvPredLeft ( m_acMvPredictors[MD_LEFT] ); //获取左侧MVP
assert (MD_ABOVE < NUM_MV_PREDICTORS);
pcCU->getMvPredAbove ( m_acMvPredictors[MD_ABOVE] ); //获取上方MVP
assert (MD_ABOVE_RIGHT < NUM_MV_PREDICTORS);
pcCU->getMvPredAboveRight ( m_acMvPredictors[MD_ABOVE_RIGHT] ); //获取右上MVP
switch ( m_iFastSearch )
{
case 1:
xTZSearch( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD, pIntegerMv2Nx2NPred ); //Diamond
break;
case 2:
xTZSearchSelective( pcCU, pcPatternKey, piRefY, iRefStride, pcMvSrchRngLT, pcMvSrchRngRB, rcMv, ruiSAD, pIntegerMv2Nx2NPred ); //PMVFAST
break;
default:
break;
}
}