motioncompensation.cpp
来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,966 行 · 第 1/5 页
CPP
1,966 行
if( NULL != pcRefBuffer )
{
const Mv cMv = rcMc8x8D.m_aacMv[n][eSParIdx];
m_pcQuarterPelFilter->predBlk( apcTarBuffer[n], pcRefBuffer, cIdx, cMv, iSizeY, iSizeX );
if( cMbIcp.getIcAct() )
xIcForPredLuma( cMbIcp, apcTarBuffer[n], cIdx, iSizeY, iSizeX );
}
}
}
Void MotionCompensation::xPredLuma( MbIcp cMbIcp, IntYuvMbBuffer* pcRecBuffer, Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D )
{
IntYuvMbBuffer* apcTarBuffer[2];
m_pcSampleWeighting->getTargetBuffers( apcTarBuffer, pcRecBuffer, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );
for( Int n = 0; n < 2; n++ )
{
IntYuvPicBuffer* pcRefBuffer = rcMc8x8D.m_apcRefBuffer[n];
if( NULL != pcRefBuffer )
{
const Mv cMv = rcMc8x8D.m_aacMv[n][0];
m_pcQuarterPelFilter->predBlk( apcTarBuffer[n], pcRefBuffer, rcMc8x8D.m_cIdx, cMv, iSizeY, iSizeX );
}
}
m_pcSampleWeighting->weightLumaSamples( pcRecBuffer, iSizeX, iSizeY, rcMc8x8D.m_cIdx, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );
if( cMbIcp.getIcAct() )
xIcForPredLuma( cMbIcp, pcRecBuffer, rcMc8x8D.m_cIdx, iSizeY, iSizeX );
}
Void MotionCompensation::xPredLuma( MbIcp cMbIcp, YuvMbBuffer* pcRecBuffer, Int iSizeX, Int iSizeY, MC8x8D& rcMc8x8D )
{
YuvMbBuffer* apcTarBuffer[2];
m_pcSampleWeighting->getTargetBuffers( apcTarBuffer, pcRecBuffer, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );
for( Int n = 0; n < 2; n++ )
{
YuvPicBuffer* pcRefBuffer = rcMc8x8D.m_apcRefBuffer[n];
if( NULL != pcRefBuffer )
{
const Mv cMv = rcMc8x8D.m_aacMv[n][0];
m_pcQuarterPelFilter->predBlk( apcTarBuffer[n], pcRefBuffer, rcMc8x8D.m_cIdx, cMv, iSizeY, iSizeX );
}
}
m_pcSampleWeighting->weightLumaSamples( pcRecBuffer, iSizeX, iSizeY, rcMc8x8D.m_cIdx, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );
if( cMbIcp.getIcAct() )
xIcForPredLuma( cMbIcp, pcRecBuffer, rcMc8x8D.m_cIdx, iSizeY, iSizeX );
}
Void MotionCompensation::xIcForPredLuma( MbIcp cMbIcp, IntYuvMbBuffer* pcDesBuffer, LumaIdx cIdx, Int iSizeY, Int iSizeX )
{
XPel* pucDes = pcDesBuffer->getYBlk( cIdx );
Int iDesStride = pcDesBuffer->getLStride();
bool bClip = m_pcQuarterPelFilter->getClipMode();
if (iSizeY<=8 && iSizeX<=8)
{
if ( cMbIcp.getIcAct(cIdx.y(), cIdx.x()) )
{
short sOffset = (XPel)cMbIcp.getIcp(cIdx.y(), cIdx.x()).getOffset();
for (Int y=0; y < iSizeY; y++)
{
for (Int x=0; x < iSizeX; x++)
{
pucDes[x] = xClip( bClip, pucDes[x] + sOffset );
}
pucDes += iDesStride;
}
}
}
else
{
Int iblkY4x4;
short sIcAct0, sIcAct1;
short sOffset0, sOffset1;
for (Int y=0; y < iSizeY; y++)
{
iblkY4x4 = (y>>2) + cIdx.y();
sIcAct0 = cMbIcp.getIcAct(iblkY4x4, cIdx.x());
if (sIcAct0)
{
sOffset0 = cMbIcp.getIcp(iblkY4x4, cIdx.x()).getOffset();
pucDes[0 ] = xClip( bClip, pucDes[0 ] + sOffset0 );
pucDes[1 ] = xClip( bClip, pucDes[1 ] + sOffset0 );
pucDes[2 ] = xClip( bClip, pucDes[2 ] + sOffset0 );
pucDes[3 ] = xClip( bClip, pucDes[3 ] + sOffset0 );
pucDes[4 ] = xClip( bClip, pucDes[4 ] + sOffset0 );
pucDes[5 ] = xClip( bClip, pucDes[5 ] + sOffset0 );
pucDes[6 ] = xClip( bClip, pucDes[6 ] + sOffset0 );
pucDes[7 ] = xClip( bClip, pucDes[7 ] + sOffset0 );
}
if (iSizeX==16)
{
sIcAct1 = cMbIcp.getIcAct(iblkY4x4, cIdx.x()+2);
if (sIcAct1)
{
sOffset1 = cMbIcp.getIcp(iblkY4x4, cIdx.x()+2).getOffset();
pucDes[8 ] = xClip( bClip, pucDes[8 ] + sOffset1 );
pucDes[9 ] = xClip( bClip, pucDes[9 ] + sOffset1 );
pucDes[10] = xClip( bClip, pucDes[10] + sOffset1 );
pucDes[11] = xClip( bClip, pucDes[11] + sOffset1 );
pucDes[12] = xClip( bClip, pucDes[12] + sOffset1 );
pucDes[13] = xClip( bClip, pucDes[13] + sOffset1 );
pucDes[14] = xClip( bClip, pucDes[14] + sOffset1 );
pucDes[15] = xClip( bClip, pucDes[15] + sOffset1 );
}
}
pucDes += iDesStride;
}
}
return;
}
Void MotionCompensation::xIcForPredLuma( MbIcp cMbIcp, YuvMbBuffer* pcDesBuffer, LumaIdx cIdx, Int iSizeY, Int iSizeX )
{
Pel* pucDes = pcDesBuffer->getYBlk( cIdx );
Int iDesStride = pcDesBuffer->getLStride();
bool bClip = m_pcQuarterPelFilter->getClipMode();
if( iSizeY<=8 && iSizeX<=8 )
{ // KJH: block size at most 8x8 : no change in ICP
if( cMbIcp.getIcAct(cIdx.y(), cIdx.x()) )
{
short sOffset = (XPel)cMbIcp.getIcp(cIdx.y(), cIdx.x()).getOffset();
for( Int y=0; y < iSizeY; y++ )
{
for( Int x=0; x < iSizeX; x++ )
{
pucDes[x] = xClip( bClip, pucDes[x] + sOffset );
}
pucDes += iDesStride;
}
}
}
else
{
Int iblkY4x4;
short sIcAct0, sIcAct1;
short sOffset0, sOffset1;
for (Int y=0; y < iSizeY; y++)
{
iblkY4x4 = (y>>2) + cIdx.y();
sIcAct0 = cMbIcp.getIcAct(iblkY4x4, cIdx.x());
if (sIcAct0)
{
sOffset0 = cMbIcp.getIcp(iblkY4x4, cIdx.x()).getOffset();
pucDes[0 ] = xClip( bClip, pucDes[0 ] + sOffset0 );
pucDes[1 ] = xClip( bClip, pucDes[1 ] + sOffset0 );
pucDes[2 ] = xClip( bClip, pucDes[2 ] + sOffset0 );
pucDes[3 ] = xClip( bClip, pucDes[3 ] + sOffset0 );
pucDes[4 ] = xClip( bClip, pucDes[4 ] + sOffset0 );
pucDes[5 ] = xClip( bClip, pucDes[5 ] + sOffset0 );
pucDes[6 ] = xClip( bClip, pucDes[6 ] + sOffset0 );
pucDes[7 ] = xClip( bClip, pucDes[7 ] + sOffset0 );
}
if (iSizeX==16)
{
sIcAct1 = cMbIcp.getIcAct(iblkY4x4, cIdx.x()+2);
if (sIcAct1)
{
sOffset1 = cMbIcp.getIcp(iblkY4x4, cIdx.x()+2).getOffset();
pucDes[8 ] = xClip( bClip, pucDes[8 ] + sOffset1 );
pucDes[9 ] = xClip( bClip, pucDes[9 ] + sOffset1 );
pucDes[10] = xClip( bClip, pucDes[10] + sOffset1 );
pucDes[11] = xClip( bClip, pucDes[11] + sOffset1 );
pucDes[12] = xClip( bClip, pucDes[12] + sOffset1 );
pucDes[13] = xClip( bClip, pucDes[13] + sOffset1 );
pucDes[14] = xClip( bClip, pucDes[14] + sOffset1 );
pucDes[15] = xClip( bClip, pucDes[15] + sOffset1 );
}
}
pucDes += iDesStride;
}
}
return;
}
Void MotionCompensation::xInverseDPCMIcp( MbDataAccess& rcMbDataAccess )
{
Icp cIcp = rcMbDataAccess.getMbData().getMbIcp().getIcp();
SChar scRefIdx0, scRefIdx1;
if( rcMbDataAccess.getSH().isInterB() )
{
UInt uiBlockFwdBwd = rcMbDataAccess.getMbData().getBlockFwdBwd(B_8x8_0);
if (uiBlockFwdBwd==1)
{
scRefIdx0 = rcMbDataAccess.getMbMotionData(LIST_0).getRefIdx(B_8x8_0);
rcMbDataAccess.getIcpPredictor(cIcp, LIST_0, scRefIdx0);
}
else if (uiBlockFwdBwd==2)
{
scRefIdx1 = rcMbDataAccess.getMbMotionData(LIST_1).getRefIdx(B_8x8_0);
rcMbDataAccess.getIcpPredictor(cIcp, LIST_1, scRefIdx1);
}
else if (uiBlockFwdBwd==3)
{
scRefIdx0 = rcMbDataAccess.getMbMotionData(LIST_0).getRefIdx(B_8x8_0);
scRefIdx1 = rcMbDataAccess.getMbMotionData(LIST_1).getRefIdx(B_8x8_0);
rcMbDataAccess.getIcpPredictor(cIcp, scRefIdx0, scRefIdx1);
}
}
else
{
scRefIdx0 = rcMbDataAccess.getMbMotionData(LIST_0).getRefIdx(B_8x8_0);
rcMbDataAccess.getIcpPredictor(cIcp, LIST_0, scRefIdx0);
}
short symOffset = cIcp.getSymbolOffset();
short predOffset = cIcp.getPredOffset();
short recOffset = symOffset + predOffset;
cIcp.setSymbolOffset( symOffset );
cIcp.setOffset( recOffset );
rcMbDataAccess.getMbData().getMbIcp().setAllIcp(cIcp);
}
#endif
__inline Void MotionCompensation::xPredChromaPel( XPel* pucDest, Int iDestStride, XPel* pucSrc, Int iSrcStride, Mv cMv, Int iSizeY, Int iSizeX )
{
Int xF1 = cMv.getHor();
Int yF1 = cMv.getVer();
xF1 &= 0x7;
yF1 &= 0x7;
Int x, y;
if( 0 == xF1 )
{
if( 0 == yF1 )
{
for( y = 0; y < iSizeY; y++ )
{
for( x = 0; x < iSizeX; x++ )
{
pucDest[x ] = pucSrc[x ];
}
pucDest += iDestStride;
pucSrc += iSrcStride;
}
return;
}
Int yF0 = 8 - yF1;
for( y = 0; y < iSizeY; y++ )
{
for( x = 0; x < iSizeX; x++ )
{
#if AR_FGS_COMPENSATE_SIGNED_FRAME
pucDest[x ] = SIGNED_ROUNDING( yF0 * pucSrc[x ] + yF1 * pucSrc[x+iSrcStride ], 4, 3 );
#else
pucDest[x ] = (yF0 * pucSrc[x ] + yF1 * pucSrc[x+iSrcStride ] + 4) >> 3;
#endif
}
pucDest += iDestStride;
pucSrc += iSrcStride;
}
return;
}
if( 0 == yF1 )
{
Int xF0 = 8 - xF1;
for( y = 0; y < iSizeY; y++ )
{
for( x = 0; x < iSizeX; x++ )
{
#if AR_FGS_COMPENSATE_SIGNED_FRAME
pucDest[x] = SIGNED_ROUNDING( xF0 * pucSrc[x] + xF1 * pucSrc[x+1], 4, 3 );
#else
pucDest[x] = (xF0 * pucSrc[x] + xF1 * pucSrc[x+1] + 4) >> 3;
#endif
}
pucDest += iDestStride;
pucSrc += iSrcStride;
}
return;
}
Int xF0 = 8 - xF1;
Int yF0 = 8 - yF1;
for( y = 0; y < iSizeY; y++ )
{
Int a = xF0* ( yF0 * pucSrc[0] + yF1 * pucSrc[iSrcStride]);
for( x = 0; x < iSizeX; x++ )
{
Int b = yF0 * pucSrc[x+1] + yF1 * pucSrc[iSrcStride+x+1];
Int c = xF1 * b;
#if AR_FGS_COMPENSATE_SIGNED_FRAME
pucDest[x] = SIGNED_ROUNDING( a + c, 0x20, 6 );
#else
pucDest[x] = (a + c + 0x20) >> 6;
#endif
a = (b<<3) - c;
}
pucDest += iDestStride;
pucSrc += iSrcStride;
}
}
__inline Void MotionCompensation::xPredChroma( IntYuvMbBuffer* pcDesBuffer, IntYuvPicBuffer* pcSrcBuffer, LumaIdx cIdx, Mv cMv, Int iSizeY, Int iSizeX)
{
const Int iDesStride = pcDesBuffer->getCStride();
const Int iSrcStride = pcSrcBuffer->getCStride();
cMv.limitComponents( m_cMin, m_cMax );
const Int iOffset = (cMv.getHor() >> 3) + (cMv.getVer() >> 3) * iSrcStride;
xPredChromaPel( pcDesBuffer->getUBlk( cIdx ), iDesStride,
pcSrcBuffer->getUBlk( cIdx )+ iOffset, iSrcStride,
cMv, iSizeY, iSizeX );
xPredChromaPel( pcDesBuffer->getVBlk( cIdx ), iDesStride,
pcSrcBuffer->getVBlk( cIdx )+ iOffset, iSrcStride,
cMv, iSizeY, iSizeX );
}
Void MotionCompensation::xPredChroma( IntYuvMbBuffer* pcRecBuffer, Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D )
{
IntYuvMbBuffer* apcTarBuffer[2];
m_pcSampleWeighting->getTargetBuffers( apcTarBuffer, pcRecBuffer, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );
for( Int n = 0; n < 2; n++ )
{
IntYuvPicBuffer* pcRefBuffer = rcMc8x8D.m_apcRefBuffer[n];
if( NULL != pcRefBuffer )
{
Mv cMv = rcMc8x8D.m_aacMv[n][0];
xPredChroma( apcTarBuffer[n], pcRefBuffer, rcMc8x8D.m_cIdx, cMv, iSizeY, iSizeX );
}
}
m_pcSampleWeighting->weightChromaSamples( pcRecBuffer, iSizeX, iSizeY, rcMc8x8D.m_cIdx, rcMc8x8D.m_apcPW[LIST_0], rcMc8x8D.m_apcPW[LIST_1] );
}
Void MotionCompensation::xPredChroma( IntYuvMbBuffer* apcTarBuffer[2], Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D, SParIdx4x4 eSParIdx )
{
B4x4Idx cIdx( rcMc8x8D.m_cIdx + eSParIdx );
for( Int n = 0; n < 2; n++ )
{
IntYuvPicBuffer* pcRefBuffer = rcMc8x8D.m_apcRefBuffer[n];
if( NULL != pcRefBuffer )
{
Mv cMv = rcMc8x8D.m_aacMv[n][eSParIdx];
xPredChroma( apcTarBuffer[n], pcRefBuffer, cIdx, cMv, iSizeY, iSizeX );
}
}
}
ErrVal MotionCompensation::updateSubMb( B8x8Idx c8x8Idx,
MbDataAccess& rcMbDataAccess,
IntFrame* pcMCFrame,
IntFrame* pcPrdFrame,
ListIdx eListPrd )
{
m_curMbX = rcMbDataAccess.getMbX();
m_curMbY = rcMbDataAccess.getMbY();
xUpdateMb8x8Mode( c8x8Idx, rcMbDataAccess, pcMCFrame, pcPrdFrame, eListPrd );
return Err::m_nOK;
}
Void MotionCompensation::xUpdateMb8x8Mode( B8x8Idx c8x8Idx,
MbDataAccess& rcMbDataAccess,
IntFrame* pcMCFrame,
IntFrame* pcPrdFrame,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?