📄 motioncompensation.cpp
字号:
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( YuvPicBuffer* pcSrcBuffer, YuvPicBuffer* 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( Frame* pcSrcFrame, Int iSizeX, Int iSizeY, MC8x8& rcMc8x8D, UShort *usWeight )
{
for( Int n = 0; n < 2; n++ )
{
YuvPicBuffer* 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( Frame* pcSrcFrame, Int iSizeX, Int iSizeY, MC8x8& rcMc8x8D, SParIdx4x4 eSParIdx, UShort *usWeight )
{
B4x4Idx cIdx( rcMc8x8D.m_cIdx + eSParIdx );
for( Int n = 0; n < 2; n++ )
{
YuvPicBuffer* 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::compensateSubMb( B8x8Idx c8x8Idx,
MbDataAccess& rcMbDataAccess,
RefFrameList& rcRefFrameList0,
RefFrameList& rcRefFrameList1,
YuvMbBuffer* pcRecBuffer,
Bool bCalcMv,
Bool bFaultTolerant )
{
if( bCalcMv )
{
xCalc8x8( c8x8Idx, rcMbDataAccess, NULL, bFaultTolerant );
}
Int iRefIdx0 = rcMbDataAccess.getMbMotionData( LIST_0 ).getRefIdx( c8x8Idx.b8x8() );
Int iRefIdx1 = rcMbDataAccess.getMbMotionData( LIST_1 ).getRefIdx( c8x8Idx.b8x8() );
Frame* pcRefFrame0 = ( iRefIdx0 > 0 ? rcRefFrameList0[ iRefIdx0 ] : NULL );
Frame* pcRefFrame1 = ( iRefIdx1 > 0 ? rcRefFrameList1[ iRefIdx1 ] : NULL );
xPredMb8x8Mode( c8x8Idx, rcMbDataAccess, pcRefFrame0, pcRefFrame1, pcRecBuffer );
return Err::m_nOK;
}
Void MotionCompensation::xPredMb8x8Mode( B8x8Idx c8x8Idx,
MbDataAccess& rcMbDataAccess,
const Frame* pcRefFrame0,
const Frame* pcRefFrame1,
YuvMbBuffer* pcRecBuffer )
{
YuvMbBuffer* apcTarBuffer[2];
Par8x8 ePar8x8 = c8x8Idx.b8x8Index();
BlkMode eBlkMode = rcMbDataAccess.getMbData().getBlkMode( ePar8x8 );
MC8x8 cMC8x8D( ePar8x8 );
xGetBlkPredData( rcMbDataAccess, pcRefFrame0, pcRefFrame1, cMC8x8D, eBlkMode );
m_pcSampleWeighting->getTargetBuffers( apcTarBuffer, pcRecBuffer, cMC8x8D.m_apcPW[LIST_0], cMC8x8D.m_apcPW[LIST_1] );
switch( eBlkMode )
{
case BLK_SKIP:
{
if( rcMbDataAccess.getSH().getSPS().getDirect8x8InferenceFlag() )
{
xPredLuma( apcTarBuffer, 8, 8, cMC8x8D, SPART_4x4_0 );
xPredChroma( apcTarBuffer, 4, 4, cMC8x8D, SPART_4x4_0 );
}
else
{
xPredLuma( apcTarBuffer, 4, 4, cMC8x8D, SPART_4x4_0 );
xPredLuma( apcTarBuffer, 4, 4, cMC8x8D, SPART_4x4_1 );
xPredLuma( apcTarBuffer, 4, 4, cMC8x8D, SPART_4x4_2 );
xPredLuma( apcTarBuffer, 4, 4, cMC8x8D, SPART_4x4_3 );
xPredChroma( apcTarBuffer, 2, 2, cMC8x8D, SPART_4x4_0 );
xPredChroma( apcTarBuffer, 2, 2, cMC8x8D, SPART_4x4_1 );
xPredChroma( apcTarBuffer, 2, 2, cMC8x8D, SPART_4x4_2 );
xPredChroma( apcTarBuffer, 2, 2, cMC8x8D, SPART_4x4_3 );
}
break;
}
case BLK_8x8:
{
xPredLuma( apcTarBuffer, 8, 8, cMC8x8D, SPART_4x4_0 );
xPredChroma( apcTarBuffer, 4, 4, cMC8x8D, SPART_4x4_0 );
break;
}
case BLK_8x4:
{
xPredLuma( apcTarBuffer, 8, 4, cMC8x8D, SPART_4x4_0 );
xPredLuma( apcTarBuffer, 8, 4, cMC8x8D, SPART_4x4_2 );
xPredChroma( apcTarBuffer, 4, 2, cMC8x8D, SPART_4x4_0 );
xPredChroma( apcTarBuffer, 4, 2, cMC8x8D, SPART_4x4_2 );
break;
}
case BLK_4x8:
{
xPredLuma( apcTarBuffer, 4, 8, cMC8x8D, SPART_4x4_0 );
xPredLuma( apcTarBuffer, 4, 8, cMC8x8D, SPART_4x4_1 );
xPredChroma( apcTarBuffer, 2, 4, cMC8x8D, SPART_4x4_0 );
xPredChroma( apcTarBuffer, 2, 4, cMC8x8D, SPART_4x4_1 );
break;
}
case BLK_4x4:
{
xPredLuma( apcTarBuffer, 4, 4, cMC8x8D, SPART_4x4_0 );
xPredLuma( apcTarBuffer, 4, 4, cMC8x8D, SPART_4x4_1 );
xPredLuma( apcTarBuffer, 4, 4, cMC8x8D, SPART_4x4_2 );
xPredLuma( apcTarBuffer, 4, 4, cMC8x8D, SPART_4x4_3 );
xPredChroma( apcTarBuffer, 2, 2, cMC8x8D, SPART_4x4_0 );
xPredChroma( apcTarBuffer, 2, 2, cMC8x8D, SPART_4x4_1 );
xPredChroma( apcTarBuffer, 2, 2, cMC8x8D, SPART_4x4_2 );
xPredChroma( apcTarBuffer, 2, 2, cMC8x8D, SPART_4x4_3 );
break;
}
default:
{
AF();
break;
}
}
m_pcSampleWeighting->weightLumaSamples ( pcRecBuffer, 8, 8, c8x8Idx, cMC8x8D.m_apcPW[LIST_0], cMC8x8D.m_apcPW[LIST_1] );
m_pcSampleWeighting->weightChromaSamples( pcRecBuffer, 4, 4, c8x8Idx, cMC8x8D.m_apcPW[LIST_0], cMC8x8D.m_apcPW[LIST_1] );
}
ErrVal MotionCompensation::compensateMbBLSkipIntra( MbDataAccess& rcMbDataAccess,
YuvMbBuffer* pcRecBuffer,
Frame* pcBaseLayerRec )
{
ROFRS( rcMbDataAccess.getMbData().getBLSkipFlag(), Err::m_nOK );
ROFRS( m_pcResizeParameters, Err::m_nOK );
ROTRS( m_pcResizeParameters->m_bRefLayerIsMbAffFrame, Err::m_nOK );
ROTRS( m_pcResizeParameters->m_bIsMbAffFrame, Err::m_nOK );
ROTRS( m_pcResizeParameters->getRestrictedSpatialResolutionChangeFlag(), Err::m_nOK );
Int iMbX = rcMbDataAccess.getMbX() * 16;
Int iMbY = rcMbDataAccess.getMbY() * 16;
Int iRefW = m_pcResizeParameters->m_iRefLayerFrmWidth;
Int iRefH = m_pcResizeParameters->m_iRefLayerFrmHeight;
Int iScaledW = m_pcResizeParameters->m_iScaledRefFrmWidth;
Int iScaledH = m_pcResizeParameters->m_iScaledRefFrmHeight;
Int iLeftOff = m_pcResizeParameters->m_iLeftFrmOffset;
Int iTopOff = m_pcResizeParameters->m_iTopFrmOffset;
if( m_pcResizeParameters->m_bFieldPicFlag )
{
iScaledH /= 2;
iTopOff /= 2;
}
if( m_pcResizeParameters->m_bRefLayerFieldPicFlag )
{
iRefH /= 2;
}
Int iShiftX = ( m_pcResizeParameters->m_iLevelIdc <= 30 ? 16 : 31 - CeilLog2( iRefW ) );
Int iShiftY = ( m_pcResizeParameters->m_iLevelIdc <= 30 ? 16 : 31 - CeilLog2( iRefH ) );
Int iScaleX = ( ( (UInt)iRefW << iShiftX ) + ( iScaledW >> 1 ) ) / iScaledW;
Int iScaleY = ( ( (UInt)iRefH << iShiftY ) + ( iScaledH >> 1 ) ) / iScaledH;
Int iBaseMbX0 = ( ( ( iMbX - iLeftOff ) * iScaleX + ( 1 << ( iShiftX - 1 ) ) ) >> iShiftX ) >> 4;
Int iBaseMbY0 = ( ( ( iMbY - iTopOff ) * iScaleY + ( 1 << ( iShiftY - 1 ) ) ) >> iShiftY ) >> 4;
Int iCX = 0;
Int iCY = 0;
//----- determine first location that points to a different macroblock (not efficient implementation!) -----
for( ; iCX < 16; iCX++ )
{
Int iBaseMbX = ( ( ( iMbX + iCX - iLeftOff ) * iScaleX + ( 1 << ( iShiftX - 1 ) ) ) >> iShiftX ) >> 4;
if( iBaseMbX > iBaseMbX0 )
{
break;
}
}
for( ; iCY < 16; iCY++ )
{
Int iBaseMbY = ( ( ( iMbY + iCY - iTopOff ) * iScaleY + ( 1 << ( iShiftY - 1 ) ) ) >> iShiftY ) >> 4;
if( iBaseMbY > iBaseMbY0 )
{
break;
}
}
//----- load intra data -----
YuvMbBuffer cBaseMbRec;
cBaseMbRec.loadBuffer( pcBaseLayerRec->getFullPelYuvBuffer() );
//----- copy intra data -----
MbData& rcMbData = rcMbDataAccess.getMbDataAccessBase()->getMbData();
if( rcMbData.isBaseIntra( 0, 0 ) )
{
RNOK( copyMbBuffer( &cBaseMbRec, pcRecBuffer, 0, 0, iCX, iCY ) );
}
if( rcMbData.isBaseIntra( 1, 0 ) && iCX < 16 )
{
RNOK( copyMbBuffer( &cBaseMbRec, pcRecBuffer, iCX, 0, 16, iCY ) );
}
if( rcMbData.isBaseIntra( 0, 1 ) && iCY < 16 )
{
RNOK( copyMbBuffer( &cBaseMbRec, pcRecBuffer, 0, iCY, iCX, 16 ) );
}
if( rcMbData.isBaseIntra( 1, 1 ) && iCX < 16 && iCY < 16 )
{
RNOK( copyMbBuffer( &cBaseMbRec, pcRecBuffer, iCX, iCY, 16, 16 ) );
}
return Err::m_nOK;
}
ErrVal MotionCompensation::copyMbBuffer( YuvMbBuffer* pcMbBufSrc,
YuvMbBuffer* pcMbBufDes,
Int sX, Int sY, Int eX, Int eY)
{
Int x,y;
XPel* pSrc;
XPel* pDes;
Int iSrcStride;
Int iDesStride;
if(sX == eX || sY == eY)
return Err::m_nOK;
pSrc = pcMbBufSrc->getMbLumAddr();
pDes = pcMbBufDes->getMbLumAddr();
iDesStride = pcMbBufDes->getLStride();
iSrcStride = pcMbBufSrc->getLStride();
pSrc += sY*iSrcStride;
pDes += sY*iDesStride;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -