📄 motionestimationquarterpel.cpp
字号:
#if JMVM_ONLY // JVT-U052
Void MotionEstimationQuarterPel::xSubPelSearch( Icp& rcIcp,
IntYuvPicBuffer* pcPelData,
Mv& rcMv,
UInt& ruiSAD,
UInt uiBlk,
UInt uiMode,
Bool bQPelOnly )
{
// TMM_ESS {
Mv cIniMv = rcMv;
if( bQPelOnly && (rcMv.getHor() % 2 || rcMv.getVer() % 2) )
{
rcMv >>= 1;
rcMv <<= 1;
}
// TMM_ESS }
Icp cIcpBestMatch = rcIcp;
Mv cMvBestMatch = rcMv;
UInt uiBestSad = MSYS_UINT_MAX;
UInt uiNumHPelPos = 9;
UInt uiNumQPelPos = 9;
UInt uiBestHPelPos = MSYS_UINT_MAX;
Int n;
UInt uiYSize;
UInt uiXSize;
// KJH: set m_cXDSS scale/offset as found Icp : NO NEED
xResetIcpInMs( m_cXDSS.sIcpInMs );
m_cXDSS.sIcpInMs.sIcAct = rcIcp.getIcAct();
if( bQPelOnly )
{
AOT( (rcMv.getHor() % 2) || (rcMv.getVer() % 2) );
cMvBestMatch >>= 2;
cMvBestMatch <<= 2;
//--- get best h-pel search position ---
Mv cMvDiff = rcMv - cMvBestMatch;
for( Int iHIndex = 0; iHIndex < 9; iHIndex++ )
{
if( cMvDiff == g_acHPSearchMv[iHIndex] )
{
uiBestHPelPos = iHIndex;
break;
}
}
AOT( uiBestHPelPos == 5 || uiBestHPelPos == 1 || uiBestHPelPos == 6 ||
uiBestHPelPos == 3 || uiBestHPelPos == 7 || uiBestHPelPos == MSYS_UINT_MAX );
rcMv = cMvBestMatch;
}
xGetSizeFromMode ( uiXSize, uiYSize, uiMode);
xCompensateBlocksHalf ( m_aXHPelSearch, pcPelData, cMvBestMatch, uiMode, uiYSize, uiXSize ) ;
m_cXDSS.iYStride = X1;
if( ! bQPelOnly || 0 == uiBestHPelPos )
{
n = 0;
Mv cMvTest = g_acHPSearchMv[n];
m_cXDSS.pYSearch = m_apXHPelSearch[n];
UInt uiSad = m_cXDSS.Func( &m_cXDSS );
cMvTest += rcMv;
uiSad += xGetCost( cMvTest );
if( uiSad < uiBestSad )
{
m_uiBestMode = n;
uiBestSad = uiSad;
cMvBestMatch = cMvTest;
if (cIcpBestMatch.getIcAct())
{
cIcpBestMatch.setOffset( m_cXDSS.sIcpInMs.sOffset );
}
}
}
//compute SAD for initial 1/2 pel MV
for( n = 1; n < (Int)uiNumHPelPos; n++ )
{
if( bQPelOnly && n != uiBestHPelPos )
{
continue;
}
Mv cMvTest = g_acHPSearchMv[n];
m_cXDSS.pYSearch = m_apXHPelSearch[n];
UInt uiSad = m_cXDSS.Func( &m_cXDSS );
cMvTest += rcMv;
UInt uiCost = xGetCost( cMvTest );
uiSad += uiCost;
if( uiSad < uiBestSad )
{
m_uiBestMode = n;
uiBestSad = uiSad;
cMvBestMatch = cMvTest;
if (cIcpBestMatch.getIcAct())
{
cIcpBestMatch.setOffset( m_cXDSS.sIcpInMs.sOffset );
}
}
}
rcMv = cMvBestMatch;
rcIcp = cIcpBestMatch;
XPel* pPel = pcPelData->getLumBlk();
Int iStride = pcPelData->getLStride();
pPel += (cMvBestMatch.getHor()>>1) + (cMvBestMatch.getVer()>>1) * iStride;
m_pcQuarterPelFilter->filterBlock( m_aXQPelSearch, pPel, iStride, uiXSize, uiYSize, g_aucFilter[m_uiBestMode]);
m_cXDSS.iYStride = 16;
//1/4 pel refinement around initial 1/2 pel MV
for( n = 1; n < (Int)uiNumQPelPos; n++ )
{
Mv cMvTest = g_acQPSearchMv[n];
m_cXDSS.pYSearch = m_apXQPelSearch[n];
UInt uiSad = m_cXDSS.Func( &m_cXDSS );
cMvTest += rcMv;
uiSad += xGetCost( cMvTest );
// TMM_ESS {
if( bQPelOnly && (abs(cIniMv.getHor()-cMvTest.getHor()) > 1 || abs(cIniMv.getVer()-cMvTest.getVer()) > 1) )
uiSad = MSYS_UINT_MAX;
// TMM_ESS }
if( uiSad < uiBestSad )
{
m_uiBestMode = n<<4;
uiBestSad = uiSad;
cMvBestMatch = cMvTest;
if (cIcpBestMatch.getIcAct())
{
cIcpBestMatch.setOffset( m_cXDSS.sIcpInMs.sOffset);
}
}
}
rcMv = cMvBestMatch;
ruiSAD = uiBestSad;
rcIcp = cIcpBestMatch;
// TMM_ESS {
//---
if( bQPelOnly && (cIniMv.getHor() % 2 || cIniMv.getVer() % 2) )
{
int dx0 = ((cIniMv.getHor()>>1)<<1);
int dy0 = ((cIniMv.getVer()>>1)<<1);
int dx1 = (cIniMv.getHor() % 2) ? (dx0+2) : dx0;
int dy1 = (cIniMv.getVer() % 2) ? (dy0+2) : dy0;
for (int dx=dx0; dx<=dx1; dx+=2)
{
for (int dy=dy0; dy<=dy1; dy+=2)
{
if (dx!=dx0 || dy!=dy0)
{
rcMv.setHor(dx);
rcMv.setVer(dy);
UInt uiBestSad1 = MSYS_UINT_MAX;
Mv cMvBestMatch1 = rcMv;
cMvBestMatch1 >>= 2;
cMvBestMatch1 <<= 2;
//--- get best h-pel search position ---
Mv cMvDiff = rcMv - cMvBestMatch1;
for( Int iHIndex = 0; iHIndex < 9; iHIndex++ )
{
if( cMvDiff == g_acHPSearchMv[iHIndex] )
{
uiBestHPelPos = iHIndex;
break;
}
}
AOT( uiBestHPelPos == 5 || uiBestHPelPos == 1 || uiBestHPelPos == 6 ||
uiBestHPelPos == 3 || uiBestHPelPos == 7 || uiBestHPelPos == MSYS_UINT_MAX );
rcMv = cMvBestMatch1;
xGetSizeFromMode ( uiXSize, uiYSize, uiMode);
xCompensateBlocksHalf ( m_aXHPelSearch, pcPelData, cMvBestMatch1, uiMode, uiYSize, uiXSize ) ;
m_cXDSS.iYStride = X1;
if( 0 == uiBestHPelPos )
{
n = 0;
Mv cMvTest = g_acHPSearchMv[n];
m_cXDSS.pYSearch = m_apXHPelSearch[n];
UInt uiSad = m_cXDSS.Func( &m_cXDSS );
cMvTest += rcMv;
uiSad += xGetCost( cMvTest );
if( uiSad < uiBestSad1 )
{
m_uiBestMode = n;
uiBestSad1 = uiSad;
cMvBestMatch1 = cMvTest;
}
}
//compute SAD for initial 1/2 pel MV
for( n = 1; n < (Int)uiNumHPelPos; n++ )
{
if( n != uiBestHPelPos )
{
continue;
}
Mv cMvTest = g_acHPSearchMv[n];
m_cXDSS.pYSearch = m_apXHPelSearch[n];
UInt uiSad = m_cXDSS.Func( &m_cXDSS );
cMvTest += rcMv;
UInt uiCost = xGetCost( cMvTest );
uiSad += uiCost;
if( uiSad < uiBestSad1 )
{
m_uiBestMode = n;
uiBestSad1 = uiSad;
cMvBestMatch1 = cMvTest;
}
}
rcMv = cMvBestMatch1;
XPel* pPel = pcPelData->getLumBlk();
Int iStride = pcPelData->getLStride();
pPel += (cMvBestMatch1.getHor()>>1) + (cMvBestMatch1.getVer()>>1) * iStride;
m_pcQuarterPelFilter->filterBlock( m_aXQPelSearch, pPel, iStride, uiXSize, uiYSize, g_aucFilter[m_uiBestMode]); //1/4 pel interp
m_cXDSS.iYStride = 16;
//1/4 pel refinement around initial 1/2 pel MV
for( n = 1; n < (Int)uiNumQPelPos; n++ )
{
Mv cMvTest = g_acQPSearchMv[n];
m_cXDSS.pYSearch = m_apXQPelSearch[n];
UInt uiSad = m_cXDSS.Func( &m_cXDSS );
cMvTest += rcMv;
uiSad += xGetCost( cMvTest );
if( bQPelOnly && (abs(cIniMv.getHor()-cMvTest.getHor()) > 1 || abs(cIniMv.getVer()-cMvTest.getVer()) > 1) )
uiSad = MSYS_UINT_MAX;
if( uiSad < uiBestSad1 )
{
m_uiBestMode = n<<4;
uiBestSad1 = uiSad;
cMvBestMatch1 = cMvTest;
}
}
if (uiBestSad1 < uiBestSad)
{
uiBestSad = uiBestSad1;
rcMv = cMvBestMatch1;
ruiSAD = uiBestSad;
}
} // if (dx!=dx0 || dy!=dy0)
} // for (int dy=dy0; dy<=dy1; dy+=2)
} // for (int dx=dx0; dx<=dx1; dx+=2)
}
//---
// TMM_ESS }
return;
}
#endif
Void MotionEstimationQuarterPel::xGetSizeFromMode( UInt& ruiXSize, UInt& ruiYSize, UInt uiMode )
{
switch( uiMode )
{
case MODE_16x16:
{
ruiYSize = 16;
ruiXSize = 16;
break;
}
case MODE_8x16:
{
ruiYSize = 16;
ruiXSize = 8;
break;
}
case MODE_16x8:
{
ruiYSize = 8;
ruiXSize = 16;
break;
}
case BLK_8x8:
{
ruiYSize = 8;
ruiXSize = 8;
break;
}
case BLK_4x8:
{
ruiYSize = 8;
ruiXSize = 4;
break;
}
case BLK_8x4:
{
ruiYSize = 4;
ruiXSize = 8;
break;
}
case BLK_4x4:
{
ruiYSize = 4;
ruiXSize = 4;
break;
}
default:
assert( 0 );
return;
}
}
Void MotionEstimationQuarterPel::xCompensateBlocksHalf( XPel *pPelDes, IntYuvPicBuffer *pcRefPelData, Mv cMv, UInt uiMode, UInt uiYSize, UInt uiXSize )
{
XPel* pPelSrc = pcRefPelData->getLumBlk();
Int iSrcStride = pcRefPelData->getLStride();
pPelSrc += (cMv.getHor()>>1) + (cMv.getVer()>>1) * iSrcStride;
uiXSize++;
UInt x, y;
for( y = 0; y < uiYSize; y++)
{
for( x = 0; x < uiXSize; x++)
{
Int x4 = x<<1;
pPelDes[3*X1*17] = pPelSrc[x4-iSrcStride-1],
pPelDes[1*X1*17] = pPelSrc[x4-iSrcStride],
pPelDes++;
}
pPelDes -= uiXSize;
for( x = 0; x < uiXSize; x++)
{
Int x4 = x<<1;
pPelDes[2*X1*17] = pPelSrc[x4-1];
pPelDes[0*X1*17] = pPelSrc[x4],
pPelDes++;
}
pPelDes += X1-uiXSize;
pPelSrc += 2*iSrcStride;
}
for( x = 0; x < uiXSize; x++)
{
Int x4 = x<<1;
pPelDes[3*X1*17] = pPelSrc[x4-iSrcStride-1],
pPelDes[1*X1*17] = pPelSrc[x4-iSrcStride],
pPelDes++;
}
return;
}
ErrVal MotionEstimationQuarterPel::compensateBlock( IntYuvMbBuffer* pcRecPelData,
UInt uiBlk,
UInt uiMode,
IntYuvMbBuffer* pcRefPelData2 )
{
pcRecPelData->set4x4Block( B4x4Idx(uiBlk) );
XPel iStride = pcRecPelData->getLStride();
XPel* pDes = pcRecPelData->getLumBlk();
XPel* pSrc;
Int iAdd;
if( 0x10 > m_uiBestMode )
{
pSrc = m_apXHPelSearch[m_uiBestMode];
iAdd = X1;
}
else
{
pSrc = m_apXQPelSearch[m_uiBestMode>>4];
iAdd = 16;
}
UInt uiXSize = 0;
UInt uiYSize = 0;
xGetSizeFromMode( uiXSize, uiYSize, uiMode);
if( pcRefPelData2 == NULL )
{
for( UInt y = 0; y < uiYSize; y++)
{
for( UInt x = 0; x < uiXSize; x+=4 )
{
pDes[x+0] = pSrc[x+0];
pDes[x+1] = pSrc[x+1];
pDes[x+2] = pSrc[x+2];
pDes[x+3] = pSrc[x+3];
}
pDes += iStride;
pSrc += iAdd;
}
}
else
{
pcRefPelData2->set4x4Block( B4x4Idx(uiBlk) );
XPel iStride2 = pcRefPelData2->getLStride();
XPel* pSrc2 = pcRefPelData2->getLumBlk();
for( UInt y = 0; y < uiYSize; y++)
{
for( UInt x = 0; x < uiXSize; x+=4 )
{
pDes[x+0] = (pSrc[x+0] + pSrc2[x+0] + 1)>>1;
pDes[x+1] = (pSrc[x+1] + pSrc2[x+1] + 1)>>1;
pDes[x+2] = (pSrc[x+2] + pSrc2[x+2] + 1)>>1;
pDes[x+3] = (pSrc[x+3] + pSrc2[x+3] + 1)>>1;
}
pDes += iStride;
pSrc += iAdd;
pSrc2 += iStride2;
}
}
return Err::m_nOK;
}
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -