motioncompensation.cpp
来自「JVT-S203 contains the JSVM 6 reference s」· C++ 代码 · 共 1,927 行 · 第 1/5 页
CPP
1,927 行
if(eListPrd == LIST_0)
xGetMbPredData( rcMbDataAccess, pcMCFrame, NULL, cMC8x8D1 );
else
xGetMbPredData( rcMbDataAccess, NULL, pcMCFrame, cMC8x8D1 );
xUpdateBlk( pcPrdFrame, 8, 16, cMC8x8D1 );
}
}
break;
case MODE_SKIP:
{
if( rcMbDataAccess.getSH().isInterB() )
{
B8x8Idx c8x8Idx;
RNOK( updateDirectBlock( rcMbDataAccess, pcMCFrame, pcPrdFrame, eListPrd, iRefIdx, c8x8Idx ) ); c8x8Idx++;
RNOK( updateDirectBlock( rcMbDataAccess, pcMCFrame, pcPrdFrame, eListPrd, iRefIdx, c8x8Idx ) ); c8x8Idx++;
RNOK( updateDirectBlock( rcMbDataAccess, pcMCFrame, pcPrdFrame, eListPrd, iRefIdx, c8x8Idx ) ); c8x8Idx++;
RNOK( updateDirectBlock( rcMbDataAccess, pcMCFrame, pcPrdFrame, eListPrd, iRefIdx, c8x8Idx ) ); ;
}
else
{
IntMC8x8D cMC8x8D( B_8x8_0 );
if(rcMbDataAccess.getMbMotionData(eListPrd).getRefIdx(PART_8x16_0) != iRefIdx)
return Err::m_nOK;
if(eListPrd == LIST_0)
xGetMbPredData( rcMbDataAccess, pcMCFrame, NULL, cMC8x8D );
else
xGetMbPredData( rcMbDataAccess, NULL, pcMCFrame, cMC8x8D );
xUpdateBlk( pcPrdFrame, 16, 16, cMC8x8D );
return Err::m_nOK;
}
}
break;
case MODE_8x8:
case MODE_8x8ref0:
printf("function not defined for the case\n");
RERR();
break;
default:
break;
}
return Err::m_nOK;
}
ErrVal MotionCompensation::updateDirectBlock( MbDataAccess& rcMbDataAccess,
IntFrame* pcMCFrame,
IntFrame* pcPrdFrame,
ListIdx eListPrd,
Int iRefIdx,
B8x8Idx c8x8Idx )
{
Par8x8 ePar8x8 = c8x8Idx.b8x8Index();
IntMC8x8D cMC8x8D( ePar8x8 );
if(rcMbDataAccess.getMbData().getMbMotionData(eListPrd).getRefIdx(ePar8x8) != iRefIdx)
return Err::m_nOK;
if( rcMbDataAccess.getSH().getSPS().getDirect8x8InferenceFlag() )
{
if(eListPrd == LIST_0)
xGetBlkPredData( rcMbDataAccess, pcMCFrame, NULL, cMC8x8D, BLK_8x8 );
else
xGetBlkPredData( rcMbDataAccess, NULL, pcMCFrame, cMC8x8D, BLK_8x8 );
xUpdateBlk( pcPrdFrame, 8, 8, cMC8x8D, SPART_4x4_0 );
}
else
{
if(eListPrd == LIST_0)
xGetBlkPredData( rcMbDataAccess, pcMCFrame, NULL, cMC8x8D, BLK_4x4 );
else
xGetBlkPredData( rcMbDataAccess, NULL, pcMCFrame, cMC8x8D, BLK_4x4 );
xUpdateBlk( pcPrdFrame, 4, 4, cMC8x8D, SPART_4x4_0 );
xUpdateBlk( pcPrdFrame, 4, 4, cMC8x8D, SPART_4x4_1 );
xUpdateBlk( pcPrdFrame, 4, 4, cMC8x8D, SPART_4x4_2 );
xUpdateBlk( pcPrdFrame, 4, 4, cMC8x8D, SPART_4x4_3 );
}
return Err::m_nOK;
}
Void MotionCompensation::xUpdateBlk( IntFrame* pcPrdFrame, Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D)
{
UShort weight;
xUpdateLuma( pcPrdFrame, iSizeX, iSizeY, rcMc8x8D, &weight);
xUpdateChroma(pcPrdFrame, iSizeX/2, iSizeY/2, rcMc8x8D, &weight);
}
Void MotionCompensation::xUpdateBlk( IntFrame* pcPrdFrame, Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D, SParIdx4x4 eSParIdx )
{
UShort weight;
xUpdateLuma( pcPrdFrame, iSizeX, iSizeY, rcMc8x8D, eSParIdx, &weight);
xUpdateChroma(pcPrdFrame, iSizeX/2, iSizeY/2, rcMc8x8D, eSParIdx, &weight);
}
Void MotionCompensation::xUpdateLuma( IntFrame* pcPrdFrame, Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D, UShort *usWeight)
{
for( Int n = 0; n < 2; n++ )
{
IntYuvPicBuffer* pcRefBuffer = rcMc8x8D.m_apcRefBuffer[n];
if( NULL != pcRefBuffer )
{
const Mv cMv = rcMc8x8D.m_aacMv[n][0];
const Mv dMv = rcMc8x8D.m_aacMvd[n][0];
if( dMv.getAbsHor() + dMv.getAbsVer() >= DMV_THRES)
continue;
updateBlkAdapt( pcPrdFrame->getFullPelYuvBuffer(), pcRefBuffer, rcMc8x8D.m_cIdx, cMv, iSizeY, iSizeX, usWeight);
}
}
}
Void MotionCompensation::xUpdateLuma( IntFrame* pcPrdFrame, Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D, SParIdx4x4 eSParIdx, UShort *usWeight )
{
B4x4Idx cIdx( rcMc8x8D.m_cIdx + eSParIdx );
for( Int n = 0; n < 2; n++ )
{
IntYuvPicBuffer* pcRefBuffer = rcMc8x8D.m_apcRefBuffer[n];
if( NULL != pcRefBuffer )
{
const Mv cMv = rcMc8x8D.m_aacMv[n][eSParIdx];
const Mv dMv = rcMc8x8D.m_aacMvd[n][eSParIdx];
if( dMv.getAbsHor() + dMv.getAbsVer() >= DMV_THRES)
continue;
updateBlkAdapt( pcPrdFrame->getFullPelYuvBuffer(), pcRefBuffer, cIdx, cMv, iSizeY, iSizeX, usWeight );
}
}
}
Void MotionCompensation::updateBlkAdapt( IntYuvPicBuffer* pcSrcBuffer, IntYuvPicBuffer* pcDesBuffer, LumaIdx cIdx, Mv cMv, Int iSizeY, Int iSizeX,
UShort *usWeight)
{
XPel* pucDes = pcDesBuffer->getYBlk( cIdx );
XPel* pucSrc = pcSrcBuffer->getYBlk( cIdx );
Int iDesStride = pcDesBuffer->getLStride();
Int iSrcStride = pcSrcBuffer->getLStride();
Short mvHor = cMv.getHor(), mvVer = cMv.getVer();
Int iOffsetDes = (mvHor >>2 ) + (mvVer >>2 ) * iDesStride;
pucDes += iOffsetDes;
m_pcQuarterPelFilter->weightOnEnergy(usWeight, pucSrc, iSrcStride, iSizeY, iSizeX);
Int iDx = (mvHor & 3) ;
Int iDy = (mvVer & 3) ;
xUpdAdapt( pucDes, pucSrc, iDesStride, iSrcStride, iDx, iDy, iSizeY, iSizeX, *usWeight, 16);
}
#define BUF_W 19
#define BUF_H 19
Void MotionCompensation::xUpdAdapt( XPel* pucDest, XPel* pucSrc, Int iDestStride, Int iSrcStride, Int iDx, Int iDy,
UInt uiSizeY, UInt uiSizeX, UShort weight, UShort wMax )
{
Int methodId;
Int interpBuf[BUF_W*BUF_H]; // interpolation buffer
Int* pBuf = interpBuf;
XPel* pDest = 0;
Int updSizeX = 0, updSizeY = 0;
Int bitShift = 0;
if(weight > wMax/2)
{
methodId = 2;
}
else if(weight > 0)
{
methodId = 1;
}
else
return;
// initialize buffer
memset(pBuf, 0, sizeof(Int)*BUF_W*BUF_H);
// INTERPOLATION
if(methodId==1)
{
// method 1: bi-linear for sub-pel samples
m_pcQuarterPelFilter->xUpdInterpBlnr(pBuf, pucSrc, BUF_W, iSrcStride, iDx, iDy, uiSizeY, uiSizeX);
updSizeX = uiSizeX + 1;
updSizeY = uiSizeY + 1;
pDest = pucDest;
bitShift = 4;
}
else if(methodId == 2)
{
// method 2: 4 tap filter for sub-pel samples
m_pcQuarterPelFilter->xUpdInterp4Tap(pBuf, pucSrc, BUF_W, iSrcStride, iDx, iDy, uiSizeY, uiSizeX);
updSizeX = uiSizeX + 3;
updSizeY = uiSizeY + 3;
pDest = pucDest - iDestStride - 1;
bitShift = 8;
}
pBuf = interpBuf;
int Th = max(0, (int)weight/2 - 1 ) ;
for( Int y = 0; y < updSizeY; y++)
{
for( Int x = 0; x < updSizeX; x++)
{
pBuf [x] = (pBuf[x] + (1 << (bitShift-1))) >> bitShift;
pBuf [x] = max(-Th, min(Th, pBuf[x]));
pDest[x] = (XPel)gClip( pDest[x] + ((pBuf[x] + (pBuf[x]>0? 1:-1))/4) );
}
pBuf += BUF_W;
pDest += iDestStride;
}
}
__inline Void MotionCompensation::xUpdateChroma( IntYuvPicBuffer* pcSrcBuffer, IntYuvPicBuffer* pcDesBuffer, LumaIdx cIdx, Mv cMv,
Int iSizeY, Int iSizeX, UShort *usWeight)
{
const Int iDesStride = pcDesBuffer->getCStride();
const Int iSrcStride = pcSrcBuffer->getCStride();
cMv.limitComponents( m_cMin, m_cMax );
Short mvHor = cMv.getHor(), mvVer = cMv.getVer();
const Int iOffsetDes = (mvHor>>3) + (mvVer>>3) * iDesStride;
const Int iOffsetSrc = 0;
xUpdateChromaPel( pcDesBuffer->getUBlk( cIdx )+ iOffsetDes, iDesStride,
pcSrcBuffer->getUBlk( cIdx )+ iOffsetSrc, iSrcStride,
cMv, iSizeY, iSizeX, *usWeight );
xUpdateChromaPel( pcDesBuffer->getVBlk( cIdx )+ iOffsetDes, iDesStride,
pcSrcBuffer->getVBlk( cIdx )+ iOffsetSrc, iSrcStride,
cMv, iSizeY, iSizeX, *usWeight );
}
Void MotionCompensation::xUpdateChroma( IntFrame* pcSrcFrame, Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D, UShort *usWeight )
{
for( Int n = 0; n < 2; n++ )
{
IntYuvPicBuffer* pcRefBuffer = rcMc8x8D.m_apcRefBuffer[n];
if( NULL != pcRefBuffer )
{
Mv cMv = rcMc8x8D.m_aacMv[n][0];
Mv dMv = rcMc8x8D.m_aacMvd[n][0];
if( dMv.getAbsHor() + dMv.getAbsVer() >= DMV_THRES)
return;
xUpdateChroma( pcSrcFrame->getFullPelYuvBuffer(), pcRefBuffer, rcMc8x8D.m_cIdx, cMv, iSizeY, iSizeX, usWeight );
}
}
}
Void MotionCompensation::xUpdateChroma( IntFrame* pcSrcFrame, Int iSizeX, Int iSizeY, IntMC8x8D& rcMc8x8D, SParIdx4x4 eSParIdx, UShort *usWeight )
{
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];
Mv dMv = rcMc8x8D.m_aacMvd[n][eSParIdx];
if( dMv.getAbsHor() + dMv.getAbsVer() >= DMV_THRES)
return;
xUpdateChroma( pcSrcFrame->getFullPelYuvBuffer(), pcRefBuffer, cIdx, cMv, iSizeY, iSizeX, usWeight );
}
}
}
__inline Void MotionCompensation::xUpdateChromaPel( XPel* pucDest, Int iDestStride, XPel* pucSrc, Int iSrcStride, Mv cMv, Int iSizeY, Int iSizeX, UShort weight )
{
Int interpBuf[BUF_W*BUF_H]; // interpolation buffer
Int* pBuf = interpBuf;
// initialize buffer
memset(pBuf, 0, sizeof(Int)*BUF_W*BUF_H);
m_pcQuarterPelFilter->xUpdInterpChroma(pBuf, BUF_W, pucSrc, iSrcStride, cMv, iSizeY, iSizeX);
pBuf = interpBuf;
int Th = max(0, (int)weight/2 - 1 ) ;
for( Int y = 0; y < iSizeY + 1; y++)
{
for( Int x = 0; x < iSizeX + 1; x++)
{
pBuf [x] = (pBuf[x] + 32) >> 6;
pBuf [x] = max(-Th, min(Th, pBuf[x]));
pucDest[x] = (XPel)gClip( pucDest[x] + ((pBuf[x] + (pBuf[x]>0? 2:-2))/4) );
}
pBuf += BUF_W;
pucDest += iDestStride;
}
}
ErrVal MotionCompensation::calcMvMb( MbDataAccess& rcMbDataAccess, MbDataAccess* pcMbDataAccessBase )
{
MbMode eMbMode = rcMbDataAccess.getMbData().getMbMode();
switch( eMbMode )
{
case MODE_16x16:
xCalc16x16( rcMbDataAccess, pcMbDataAccessBase );
break;
case MODE_16x8:
xCalc16x8( rcMbDataAccess, pcMbDataAccessBase );
break;
case MODE_8x16:
xCalc8x16( rcMbDataAccess, pcMbDataAccessBase );
break;
case MODE_SKIP:
if( rcMbDataAccess.getSH().isInterB() )
{
xCalcSDirect( rcMbDataAccess, pcMbDataAccessBase );
}
else
{
Mv cMvSkip;
rcMbDataAccess.getMvPredictorSkipMode( cMvSkip );
rcMbDataAccess.getMbMotionData( LIST_0 ).setAllMv( cMvSkip );
}
break;
case MODE_8x8:
case MODE_8x8ref0:
xCalc8x8( rcMbDataAccess, pcMbDataAccessBase, false );
break;
default:
break;
}
return Err::m_nOK;
}
ErrVal MotionCompensation::calcMvSubMb( B8x8Idx c8x8Idx, MbDataAccess& rcMbDataAccess, MbDataAccess* pcMbDataAccessBase )
{
xCalc8x8( c8x8Idx, rcMbDataAccess, pcMbDataAccessBase, false );
return Err::m_nOK;
}
ErrVal MotionCompensation::compensateSubMb( B8x8Idx c8x8Idx,
MbDataAccess& rcMbDataAccess,
RefFrameList& rcRefFrameList0,
RefFrameList& rcRefFrameList1,
IntYuvMbBuffer* pcRecBuffer,
Bool bCalcMv,
Bool bFaultTolerant )
{
if( bCalcMv )
{
xCalc8x8( c8x8Idx, rcMbDataAccess, NULL, bFaultTolerant );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?