📄 motionestimation.cpp
字号:
xTZSearchHelp( rcStrukt, iLeft, iStartY, 0, iDist );
}
if ( iRight <= rcSearchRect.iPosHorLimit ) // check right
{
xTZSearchHelp( rcStrukt, iRight, iStartY, 0, iDist );
}
if ( iBottom <= rcSearchRect.iPosVerLimit ) // check bottom
{
xTZSearchHelp( rcStrukt, iStartX, iBottom, 0, iDist );
}
for ( Int index = 1; index < 4; index++ )
{
Int iPosYT = iTop + ((iDist>>2) * index);
Int iPosYB = iBottom - ((iDist>>2) * index);
Int iPosXL = iStartX - ((iDist>>2) * index);
Int iPosXR = iStartX + ((iDist>>2) * index);
if ( iPosYT >= -rcSearchRect.iNegVerLimit ) // check top
{
if ( iPosXL >= -rcSearchRect.iNegHorLimit ) // check left
{
xTZSearchHelp( rcStrukt, iPosXL, iPosYT, 0, iDist );
}
if ( iPosXR <= rcSearchRect.iPosHorLimit ) // check right
{
xTZSearchHelp( rcStrukt, iPosXR, iPosYT, 0, iDist );
}
} // check top
if ( iPosYB <= rcSearchRect.iPosVerLimit ) // check bottom
{
if ( iPosXL >= -rcSearchRect.iNegHorLimit ) // check left
{
xTZSearchHelp( rcStrukt, iPosXL, iPosYB, 0, iDist );
}
if ( iPosXR <= rcSearchRect.iPosHorLimit ) // check right
{
xTZSearchHelp( rcStrukt, iPosXR, iPosYB, 0, iDist );
}
} // check bottom
} // for ...
} // check border
} // iDist <= 8
} // iDist == 1
}
Void MotionEstimation::xTZSearch( IntYuvPicBuffer *pcPelData, Mv& rcMv, UInt& ruiSAD, UInt uiSearchRange )
{
TZ_SEARCH_CONFIGURATION
// limit search range
if( ! uiSearchRange ) { uiSearchRange = m_cParams.getSearchRange(); }
rcMv.limitComponents(MotionCompensation::m_cMin, MotionCompensation::m_cMax );
SearchRect cSearchRect;
rcMv >>= 2;
cSearchRect.init( uiSearchRange, rcMv, MotionCompensation::m_cMin, MotionCompensation::m_cMax );
// init TZSearchStrukt
IntTZSearchStrukt cStrukt;
cStrukt.iYStride = pcPelData->getLStride();
cStrukt.iCStride = pcPelData->getCStride();
m_cXDSS.iYStride = cStrukt.iYStride;
m_cXDSS.iCStride = cStrukt.iCStride;
cStrukt.pucYRef = pcPelData->getLumBlk();
cStrukt.pucURef = pcPelData->getCbBlk ();
cStrukt.pucVRef = pcPelData->getCrBlk ();
cStrukt.uiBestSad = MSYS_UINT_MAX;
#if JMVM_ONLY // JVT-U052
// KJH: set IcAct 0
m_cXDSS.sIcpInMs.sIcAct = cStrukt.sBestIcpInMs.sIcAct = 0;
#endif
// set rcMv as start point and as best point
xTZSearchHelp( cStrukt, rcMv.getHor(), rcMv.getVer(), 0, 0 );
if( bTestOtherPredictedMV )
{
for( UInt index = 0; index < 3; index++ )
{
Mv cMv = m_acMvPredictors[index];
cMv.limitComponents( MotionCompensation::m_cMin, MotionCompensation::m_cMax );
cMv >>= 2;
xTZSearchHelp( cStrukt, cMv.getHor(), cMv.getVer(), 0, 0 );
}
}
// test whether zerovektor is a better start point than the current rcMv
if( bTestZeroVector )
{
xTZSearchHelp( cStrukt, 0, 0, 0, 0 );
}
// start search // ucPointNr
Int iDist = 0; // 1 2 3
Int iStartX = cStrukt.iBestX; // 4 0 5
Int iStartY = cStrukt.iBestY; // 6 7 8
// fist search
for( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
{
if( bFirstSearchDiamond == 1 )
{
xTZ8PointDiamondSearch( cStrukt, cSearchRect, iStartX, iStartY, iDist );
}
else
{
xTZ8PointSquareSearch( cStrukt, cSearchRect, iStartX, iStartY, iDist );
}
if( bFirstSearchStop && (cStrukt.uiBestRound >= uiFirstSearchRounds) ) // stop criterion
{
break;
}
}
// test whether zerovektor is a better start point than current rcMv
if( bTestZeroVectorStar && ((cStrukt.iBestX != 0) || (cStrukt.iBestY != 0)) )
{
xTZSearchHelp( cStrukt, 0, 0, 0, 0 );
if( (cStrukt.iBestX == 0) && (cStrukt.iBestY == 0) )
{
// test his neighborhood
for( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
{
xTZ8PointDiamondSearch( cStrukt, cSearchRect, 0, 0, iDist );
if( bTestZeroVectorStop && (cStrukt.uiBestRound > 0) ) // stop criterion
{
break;
}
}
}
}
// calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
if( cStrukt.uiBestDistance == 1 )
{
cStrukt.uiBestDistance = 0;
xTZ2PointSearch( cStrukt, cSearchRect );
}
// raster search if distance is to big
if( bEnableRasterSearch && ( (cStrukt.uiBestDistance > iRaster) || bAlwaysRasterSearch ) )
{
cStrukt.uiBestDistance = iRaster;
for( iStartY = -cSearchRect.iNegVerLimit; iStartY <= cSearchRect.iPosVerLimit; iStartY += iRaster )
{
for( iStartX = -cSearchRect.iNegHorLimit; iStartX <= cSearchRect.iPosHorLimit; iStartX += iRaster )
{
xTZSearchHelp( cStrukt, iStartX, iStartY, 0, iRaster );
}
}
}
// raster refinement
if( bRasterRefinementEnable && cStrukt.uiBestDistance > 0 )
{
while( cStrukt.uiBestDistance > 0 )
{
iStartX = cStrukt.iBestX;
iStartY = cStrukt.iBestY;
if( cStrukt.uiBestDistance > 1 )
{
iDist = cStrukt.uiBestDistance >>= 1;
if( bRasterRefinementDiamond == 1 )
{
xTZ8PointDiamondSearch( cStrukt, cSearchRect, iStartX, iStartY, iDist );
}
else
{
xTZ8PointSquareSearch( cStrukt, cSearchRect, iStartX, iStartY, iDist );
}
}
// calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
if( cStrukt.uiBestDistance == 1 )
{
cStrukt.uiBestDistance = 0;
if( cStrukt.ucPointNr != 0 )
{
xTZ2PointSearch( cStrukt, cSearchRect );
}
}
}
}
// star refinement
if( bStarRefinementEnable && cStrukt.uiBestDistance > 0 )
{
while( cStrukt.uiBestDistance > 0 )
{
iStartX = cStrukt.iBestX;
iStartY = cStrukt.iBestY;
cStrukt.uiBestDistance = 0;
cStrukt.ucPointNr = 0;
for( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
{
if( bStarRefinementDiamond == 1 )
{
xTZ8PointDiamondSearch( cStrukt, cSearchRect, iStartX, iStartY, iDist );
}
else
{
xTZ8PointSquareSearch( cStrukt, cSearchRect, iStartX, iStartY, iDist );
}
if( bStarRefinementStop && (cStrukt.uiBestRound >= uiStarRefinementRounds) ) // stop criterion
{
break;
}
}
// calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
if( cStrukt.uiBestDistance == 1 )
{
cStrukt.uiBestDistance = 0;
if( cStrukt.ucPointNr != 0 )
{
xTZ2PointSearch( cStrukt, cSearchRect );
}
}
}
}
// write out best match
ruiSAD = cStrukt.uiBestSad - MotionEstimationCost::xGetCost( cStrukt.iBestX, cStrukt.iBestY);
rcMv.setHor( cStrukt.iBestX );
rcMv.setVer( cStrukt.iBestY );
// test for errors in debug mode
DO_DBG( m_cXDSS.pYSearch = cStrukt.pucYRef + cStrukt.iBestY * cStrukt.iYStride + cStrukt.iBestX );
DO_DBG( m_cXDSS.pUSearch = cStrukt.pucURef + (cStrukt.iBestY>>1) * cStrukt.iCStride + (cStrukt.iBestX>>1) );
DO_DBG( m_cXDSS.pVSearch = cStrukt.pucVRef + (cStrukt.iBestY>>1) * cStrukt.iCStride + (cStrukt.iBestX>>1) );
AOF_DBG( ruiSAD == ( m_cXDSS.Func( &m_cXDSS ) ) );
}
#if JMVM_ONLY // JVT-U052
Void MotionEstimation::xTZSearch( Icp& rcIcp, IntYuvPicBuffer *pcPelData, Mv& rcMv, UInt& ruiSAD, UInt uiSearchRange )
{
TZ_SEARCH_CONFIGURATION
// limit search range
if( ! uiSearchRange ) { uiSearchRange = m_cParams.getSearchRange(); }
rcMv.limitComponents(MotionCompensation::m_cMin, MotionCompensation::m_cMax );
SearchRect cSearchRect;
rcMv >>= 2;
cSearchRect.init( uiSearchRange, rcMv, MotionCompensation::m_cMin, MotionCompensation::m_cMax );
// init TZSearchStrukt
IntTZSearchStrukt cStrukt;
cStrukt.iYStride = pcPelData->getLStride();
cStrukt.iCStride = pcPelData->getCStride();
m_cXDSS.iYStride = cStrukt.iYStride;
m_cXDSS.iCStride = cStrukt.iCStride;
cStrukt.pucYRef = pcPelData->getLumBlk();
cStrukt.pucURef = pcPelData->getCbBlk ();
cStrukt.pucVRef = pcPelData->getCrBlk ();
cStrukt.uiBestSad = MSYS_UINT_MAX;
// KJH: set IcAct
xResetIcpInMs( m_cXDSS.sIcpInMs );
xResetIcpInMs( cStrukt.sBestIcpInMs );
m_cXDSS.sIcpInMs.sIcAct = cStrukt.sBestIcpInMs.sIcAct = rcIcp.getIcAct();
// set rcMv as start point and as best point
xTZSearchHelp( cStrukt, rcMv.getHor(), rcMv.getVer(), 0, 0 );
if( bTestOtherPredictedMV )
{
for( UInt index = 0; index < 3; index++ )
{
Mv cMv = m_acMvPredictors[index];
cMv.limitComponents( MotionCompensation::m_cMin, MotionCompensation::m_cMax );
cMv >>= 2;
xTZSearchHelp( cStrukt, cMv.getHor(), cMv.getVer(), 0, 0 );
}
}
// test whether zerovektor is a better start point than the current rcMv
if( bTestZeroVector )
{
xTZSearchHelp( cStrukt, 0, 0, 0, 0 );
}
// start search // ucPointNr
Int iDist = 0; // 1 2 3
Int iStartX = cStrukt.iBestX; // 4 0 5
Int iStartY = cStrukt.iBestY; // 6 7 8
// fist search
for( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
{
if( bFirstSearchDiamond == 1 )
{
xTZ8PointDiamondSearch( cStrukt, cSearchRect, iStartX, iStartY, iDist );
}
else
{
xTZ8PointSquareSearch( cStrukt, cSearchRect, iStartX, iStartY, iDist );
}
if( bFirstSearchStop && (cStrukt.uiBestRound >= uiFirstSearchRounds) ) // stop criterion
{
break;
}
}
// test whether zerovektor is a better start point than current rcMv
if( bTestZeroVectorStar && ((cStrukt.iBestX != 0) || (cStrukt.iBestY != 0)) )
{
xTZSearchHelp( cStrukt, 0, 0, 0, 0 );
if( (cStrukt.iBestX == 0) && (cStrukt.iBestY == 0) )
{
// test his neighborhood
for( iDist = 1; iDist <= (Int)uiSearchRange; iDist*=2 )
{
xTZ8PointDiamondSearch( cStrukt, cSearchRect, 0, 0, iDist );
if( bTestZeroVectorStop && (cStrukt.uiBestRound > 0) ) // stop criterion
{
break;
}
}
}
}
// calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
if( cStrukt.uiBestDistance == 1 )
{
cStrukt.uiBestDistance = 0;
xTZ2PointSearch( cStrukt, cSearchRect );
}
// raster search if distance is to big
if( bEnableRasterSearch && ( (cStrukt.uiBestDistance > iRaster) || bAlwaysRasterSearch ) )
{
cStrukt.uiBestDistance = iRaster;
for( iStartY = -cSearchRect.iNegVerLimit; iStartY <= cSearchRect.iPosVerLimit; iStartY += iRaster )
{
for( iStartX = -cSearchRect.iNegHorLimit; iStartX <= cSearchRect.iPosHorLimit; iStartX += iRaster )
{
xTZSearchHelp( cStrukt, iStartX, iStartY, 0, iRaster );
}
}
}
// raster refinement
if( bRasterRefinementEnable && cStrukt.uiBestDistance > 0 )
{
while( cStrukt.uiBestDistance > 0 )
{
iStartX = cStrukt.iBestX;
iStartY = cStrukt.iBestY;
if( cStrukt.uiBestDistance > 1 )
{
iDist = cStrukt.uiBestDistance >>= 1;
if( bRasterRefinementDiamond == 1 )
{
xTZ8PointDiamondSearch( cStrukt, cSearchRect, iStartX, iStartY, iDist );
}
else
{
xTZ8PointSquareSearch( cStrukt, cSearchRect, iStartX, iStartY, iDist );
}
}
// calculate only 2 missing points instead 8 points if cStrukt.uiBestDistance == 1
if( cStrukt.uiBestDistance == 1 )
{
cStrukt.uiBestDistance = 0;
if( cStrukt.ucPointNr != 0 )
{
xTZ2PointSearch( cStrukt, cSearchRect );
}
}
}
}
// star refinement
if( bStarRefinementEnable && cStrukt.uiBestDistance > 0 )
{
while( cStrukt.uiBestDistance > 0 )
{
iStartX = cStrukt.iBestX;
iStartY = cStrukt.iBestY;
cStrukt.uiBestDistance = 0;
cStrukt.ucPointNr = 0;
for( iDist = 1; iDist < (Int)uiSearchRange + 1; iDist*=2 )
{
if( bStarRefinementDiamond == 1 )
{
xTZ8PointDiamondSearch( cStrukt, cSearchRect, iStartX, iStartY, iDist );
}
else
{
xTZ8PointSquareSearch(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -