📄 loopfilter.cpp
字号:
UChar
LoopFilter::xCheckMvDataP( const MbData& rcQMbData,
const LumaIdx cQIdx,
const MbData& rcPMbData,
const LumaIdx cPIdx,
const Short sHorMvThr,
const Short sVerMvThr )
{
const MbMotionData& rcMbMotionDataL0Q = rcQMbData.getMbMotionData( LIST_0 );
const MbMotionData& rcMbMotionDataL0P = rcPMbData.getMbMotionData( LIST_0 );
//===== check reference pictures =====
const RefPicIdc& rcRefPicIdcQ = rcMbMotionDataL0Q.getRefPicIdc( cQIdx );
const RefPicIdc& rcRefPicIdcP = rcMbMotionDataL0P.getRefPicIdc( cPIdx );
ROF ( rcRefPicIdcQ.isValid() );
ROF ( rcRefPicIdcP.isValid() );
ROTRS ( rcRefPicIdcQ != rcRefPicIdcP, 1 );
//===== check the motion vector distance =====
const Mv& cMvQ = rcMbMotionDataL0Q.getMv( cQIdx );
const Mv& cMvP = rcMbMotionDataL0P.getMv( cPIdx );
ROTRS( cMvP.getAbsHorDiff( cMvQ ) >= sHorMvThr, 1 );
ROTRS( cMvP.getAbsVerDiff( cMvQ ) >= sVerMvThr, 1 );
return 0;
}
UChar
LoopFilter::xCheckMvDataB( const MbData& rcQMbData,
const LumaIdx cQIdx,
const MbData& rcPMbData,
const LumaIdx cPIdx,
const Short sHorMvThr,
const Short sVerMvThr )
{
const MbMotionData& rcMbMotionDataL0Q = rcQMbData.getMbMotionData( LIST_0 );
const MbMotionData& rcMbMotionDataL1Q = rcQMbData.getMbMotionData( LIST_1 );
const MbMotionData& rcMbMotionDataL0P = rcPMbData.getMbMotionData( LIST_0 );
const MbMotionData& rcMbMotionDataL1P = rcPMbData.getMbMotionData( LIST_1 );
const RefPicIdc& rcRefPicIdcL0Q = rcMbMotionDataL0Q.getRefPicIdc( cQIdx );
const RefPicIdc& rcRefPicIdcL1Q = rcMbMotionDataL1Q.getRefPicIdc( cQIdx );
const RefPicIdc& rcRefPicIdcL0P = rcMbMotionDataL0P.getRefPicIdc( cPIdx );
const RefPicIdc& rcRefPicIdcL1P = rcMbMotionDataL1P.getRefPicIdc( cPIdx );
UInt uiNumRefPicQ = ( rcRefPicIdcL0Q.isValid() ? 1 : 0 ) + ( rcRefPicIdcL1Q.isValid() ? 1 : 0 );
UInt uiNumRefPicP = ( rcRefPicIdcL0P.isValid() ? 1 : 0 ) + ( rcRefPicIdcL1P.isValid() ? 1 : 0 );
ROF( uiNumRefPicQ );
ROF( uiNumRefPicP );
//===== check number of reference pictures =====
ROTRS( uiNumRefPicQ != uiNumRefPicP, 1 );
if( uiNumRefPicP == 1 ) // one reference picture
{
//====_ check reference pictures =====
const RefPicIdc& rcRefPicIdcQ = ( rcRefPicIdcL0Q.isValid() ? rcRefPicIdcL0Q : rcRefPicIdcL1Q );
const RefPicIdc& rcRefPicIdcP = ( rcRefPicIdcL0P.isValid() ? rcRefPicIdcL0P : rcRefPicIdcL1P );
ROTRS( rcRefPicIdcQ != rcRefPicIdcP, 1 );
//===== check the motion vector distance =====
const Mv& cMvQ = ( rcRefPicIdcL0Q.isValid() ? rcMbMotionDataL0Q.getMv( cQIdx ) : rcMbMotionDataL1Q.getMv( cQIdx ) );
const Mv& cMvP = ( rcRefPicIdcL0P.isValid() ? rcMbMotionDataL0P.getMv( cPIdx ) : rcMbMotionDataL1P.getMv( cPIdx ) );
ROTRS( cMvP.getAbsHorDiff( cMvQ ) >= sHorMvThr, 1 );
ROTRS( cMvP.getAbsVerDiff( cMvQ ) >= sVerMvThr, 1 );
return 0;
}
// both ref pic are used for both blocks
if( rcRefPicIdcL1P != rcRefPicIdcL0P )
{
// at least two diff ref pic are in use
if( rcRefPicIdcL1P != rcRefPicIdcL1Q )
{
ROTRS( rcRefPicIdcL1P != rcRefPicIdcL0Q, 1 );
ROTRS( rcRefPicIdcL0P != rcRefPicIdcL1Q, 1 );
// rcRefPicL0P == rcRefPicL1Q && rcRefPicL1P == rcRefPicL0Q
// check the motion vector distance
const Mv& cMvQ0 = rcMbMotionDataL0Q.getMv( cQIdx );
const Mv& cMvP0 = rcMbMotionDataL0P.getMv( cPIdx );
const Mv& cMvQ1 = rcMbMotionDataL1Q.getMv( cQIdx );
const Mv& cMvP1 = rcMbMotionDataL1P.getMv( cPIdx );
ROTRS( cMvP0.getAbsHorDiff( cMvQ1 ) >= sHorMvThr, 1 );
ROTRS( cMvP0.getAbsVerDiff( cMvQ1 ) >= sVerMvThr, 1 );
ROTRS( cMvP1.getAbsHorDiff( cMvQ0 ) >= sHorMvThr, 1 );
ROTRS( cMvP1.getAbsVerDiff( cMvQ0 ) >= sVerMvThr, 1 );
return 0;
}
// rcRefPicL1P == rcRefPicL1Q
ROTRS( rcRefPicIdcL0P != rcRefPicIdcL0Q, 1 );
// rcRefPicL0P == rcRefPicL0Q && rcRefPicL1P == rcRefPicL1Q
// check the motion vector distance
const Mv& cMvQ0 = rcMbMotionDataL0Q.getMv( cQIdx );
const Mv& cMvP0 = rcMbMotionDataL0P.getMv( cPIdx );
const Mv& cMvQ1 = rcMbMotionDataL1Q.getMv( cQIdx );
const Mv& cMvP1 = rcMbMotionDataL1P.getMv( cPIdx );
ROTRS( cMvP0.getAbsHorDiff( cMvQ0 ) >= sHorMvThr, 1 );
ROTRS( cMvP0.getAbsVerDiff( cMvQ0 ) >= sVerMvThr, 1 );
ROTRS( cMvP1.getAbsHorDiff( cMvQ1 ) >= sHorMvThr, 1 );
ROTRS( cMvP1.getAbsVerDiff( cMvQ1 ) >= sVerMvThr, 1 );
return 0;
}
// rcRefPicL1P == rcRefPicL0P
ROTRS( rcRefPicIdcL1Q != rcRefPicIdcL0Q, 1 ) ;
ROTRS( rcRefPicIdcL0P != rcRefPicIdcL0Q, 1 ) ;
// rcRefPicL0P == rcRefPicL0Q == rcRefPicL1P == rcRefPicL1Q
// check the motion vector distance
const Mv& cMvQ0 = rcMbMotionDataL0Q.getMv( cQIdx );
const Mv& cMvP0 = rcMbMotionDataL0P.getMv( cPIdx );
const Mv& cMvQ1 = rcMbMotionDataL1Q.getMv( cQIdx );
const Mv& cMvP1 = rcMbMotionDataL1P.getMv( cPIdx );
Bool bSameListCond = ( (cMvP0.getAbsHorDiff( cMvQ0 ) >= sHorMvThr) );
bSameListCond = ( bSameListCond || ( (cMvP0.getAbsVerDiff( cMvQ0 ) >= sVerMvThr) ) );
bSameListCond = ( bSameListCond || ( (cMvP1.getAbsHorDiff( cMvQ1 ) >= sHorMvThr) ) );
bSameListCond = ( bSameListCond || ( (cMvP1.getAbsVerDiff( cMvQ1 ) >= sVerMvThr) ) );
Bool bDiffListCond = ( (cMvP0.getAbsHorDiff( cMvQ1 ) >= sHorMvThr) );
bDiffListCond = ( bDiffListCond || ( (cMvP0.getAbsVerDiff( cMvQ1 ) >= sVerMvThr) ) );
bDiffListCond = ( bDiffListCond || ( (cMvP1.getAbsHorDiff( cMvQ0 ) >= sHorMvThr) ) );
bDiffListCond = ( bDiffListCond || ( (cMvP1.getAbsVerDiff( cMvQ0 ) >= sVerMvThr) ) );
ROTRS( bSameListCond && bDiffListCond, 1 );
return 0;
}
Void
LoopFilter::xFilter( XPel* pFlt, const Int& iOffset, const Int& iIndexA, const Int& iIndexB, const UChar& ucBs, const Bool& bLum )
{
Int iAlpha = g_acAlphaClip[ iIndexA ].ucAlpha;
Int P0 = pFlt[ -iOffset];
Int Q0 = pFlt[ 0];
Int P1 = pFlt[-2*iOffset];
Int Q1 = pFlt[ iOffset];
Int iDelta = Q0 - P0;
Int iAbsDelta = abs( iDelta );
Int iBeta = g_aucBetaTab [ iIndexB ];
ROFVS( ucBs );
ROFVS( iAbsDelta < iAlpha );
ROFVS( (abs(P0 - P1) < iBeta) && (abs(Q0 - Q1) < iBeta) );
if( ucBs < 4 )
{
Int C0 = g_acAlphaClip[ iIndexA ].aucClip[ucBs];
if( bLum )
{
Int P2 = pFlt[-3*iOffset] ;
Int Q2 = pFlt[ 2*iOffset] ;
Int aq = (( abs( Q2 - Q0 ) < iBeta ) ? 1 : 0 );
Int ap = (( abs( P2 - P0 ) < iBeta ) ? 1 : 0 );
if( ap )
{
pFlt[-2*iOffset] = P1 + gClipMinMax((P2 + ((P0 + Q0 + 1)>>1) - (P1<<1)) >> 1, -C0, C0 );
}
if( aq )
{
pFlt[ iOffset] = Q1 + gClipMinMax((Q2 + ((P0 + Q0 + 1)>>1) - (Q1<<1)) >> 1, -C0, C0 );
}
C0 += ap + aq -1;
}
C0++;
Int iDiff = gClipMinMax(((iDelta << 2) + (P1 - Q1) + 4) >> 3, -C0, C0 ) ;
pFlt[-iOffset] = gClip( P0 + iDiff );
pFlt[ 0] = gClip( Q0 - iDiff );
return;
}
if( ! bLum )
{
pFlt[ 0] = ((Q1 << 1) + Q0 + P1 + 2) >> 2;
pFlt[ -iOffset] = ((P1 << 1) + P0 + Q1 + 2) >> 2;
}
else
{
Int P2 = pFlt[-3*iOffset] ;
Int Q2 = pFlt[ 2*iOffset] ;
Bool bEnable = (iAbsDelta < ((iAlpha >> 2) + 2));
Bool aq = bEnable & ( abs( Q2 - Q0 ) < iBeta );
Bool ap = bEnable & ( abs( P2 - P0 ) < iBeta );
Int PQ0 = P0 + Q0;
if( aq )
{
pFlt[ 0] = (P1 + ((Q1 + PQ0) << 1) + Q2 + 4) >> 3;
pFlt[ iOffset] = (PQ0 +Q1 + Q2 + 2) >> 2;
pFlt[ 2*iOffset] = (((pFlt[ 3*iOffset] + Q2) <<1) + Q2 + Q1 + PQ0 + 4) >> 3;
}
else
{
pFlt[ 0] = ((Q1 << 1) + Q0 + P1 + 2) >> 2;
}
if( ap )
{
pFlt[ -iOffset] = (Q1 + ((P1 + PQ0) << 1) + P2 + 4) >> 3;
pFlt[-2*iOffset] = (PQ0 +P1 + P2 + 2) >> 2;
pFlt[-3*iOffset] = (((pFlt[-4*iOffset] + P2) <<1) + pFlt[-3*iOffset] + P1 + PQ0 + 4) >> 3;
}
else
{
pFlt[ -iOffset] = ((P1 << 1) + P0 + Q1 + 2) >> 2;
}
}
}
ErrVal
LoopFilter::xLumaVerFiltering( const MbDataAccess& rcMbDataAccess, const DBFilterParameter& rcDFP, YuvPicBuffer* pcYuvBuffer )
{
Int iCurrQp = rcMbDataAccess.getMbData().getQpLF();
Int iStride = pcYuvBuffer->getLStride();
XPel* pPelLum = pcYuvBuffer->getMbLumAddr();
//===== filtering of left macroblock edge =====
if( ! m_bVerMixedMode )
{
//----- curr == FRM && left == FRM or curr == FLD && left == FLD -----
Int iLeftQp = rcMbDataAccess.getMbDataLeft().getQpLF();
Int iQp = ( iLeftQp + iCurrQp + 1) >> 1;
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iQp, 0, 51);
for( Int yBlk = 0; yBlk < 4; yBlk++)
{
const UChar ucBs = m_aaaucBs[VER][0][yBlk];
if( 0 != ucBs )
{
xFilter( pPelLum, 1, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+ iStride, 1, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+2*iStride, 1, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+3*iStride, 1, iIndexA, iIndexB, ucBs, true );
}
pPelLum += 4*iStride;
}
}
else
{
Int iLeftQpTop = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataLeft ().getQpLF() : rcMbDataAccess.getMbDataAboveLeft().getQpLF() );
Int iLeftQpBot = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataBelowLeft().getQpLF() : rcMbDataAccess.getMbDataLeft ().getQpLF() );
Int iQpTop = ( iLeftQpTop + iCurrQp + 1) >> 1;
Int iQpBot = ( iLeftQpBot + iCurrQp + 1) >> 1;
Int iIndexATop = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQpTop, 0, 51);
Int iIndexABot = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQpBot, 0, 51);
Int iIndexBTop = gClipMinMax( rcDFP.getSliceBetaOffset() + iQpTop, 0, 51);
Int iIndexBBot = gClipMinMax( rcDFP.getSliceBetaOffset() + iQpBot, 0, 51);
if( ! rcMbDataAccess.getMbData().getFieldFlag() )
{
//----- curr == FRM && left == FLD -----
for( Int yBlk = 0; yBlk < 4; yBlk++)
{
const UChar ucBsTop = m_aaaucBs[VER][0][yBlk];
const UChar ucBsBot = m_aucBsVerBot[yBlk];
if( 0 != ucBsTop )
{
xFilter( pPelLum, 1, iIndexATop, iIndexBTop, ucBsTop, true );
xFilter( pPelLum+2*iStride, 1, iIndexATop, iIndexBTop, ucBsTop, true );
}
if( 0 != ucBsBot )
{
xFilter( pPelLum+ iStride, 1, iIndexABot, iIndexBBot, ucBsBot, true );
xFilter( pPelLum+3*iStride, 1, iIndexABot, iIndexBBot, ucBsBot, true );
}
pPelLum += 4*iStride;
}
}
else
{
//----- curr == FLD && left == FRM -----
Int yBlk;
for( yBlk = 0; yBlk < 2; yBlk++)
{
const UChar ucBsTop = m_aaaucBs[VER][0][yBlk];
const UChar ucBsBot = m_aucBsVerBot[yBlk];
if( 0 != ucBsTop )
{
xFilter( pPelLum, 1, iIndexATop, iIndexBTop, ucBsTop, true );
xFilter( pPelLum+ iStride, 1, iIndexATop, iIndexBTop, ucBsTop, true );
}
if( 0 != ucBsBot )
{
xFilter( pPelLum+2*iStride, 1, iIndexATop, iIndexBTop, ucBsBot, true );
xFilter( pPelLum+3*iStride, 1, iIndexATop, iIndexBTop, ucBsBot, true );
}
pPelLum += 4*iStride;
}
for( yBlk = 2; yBlk < 4; yBlk++)
{
const UChar ucBsTop = m_aaaucBs[VER][0][yBlk];
const UChar ucBsBot = m_aucBsVerBot[yBlk];
if( 0 != ucBsTop )
{
xFilter( pPelLum, 1, iIndexABot, iIndexBBot, ucBsTop, true );
xFilter( pPelLum+ iStride, 1, iIndexABot, iIndexBBot, ucBsTop, true );
}
if( 0 != ucBsBot )
{
xFilter( pPelLum+2*iStride, 1, iIndexABot, iIndexBBot, ucBsBot, true );
xFilter( pPelLum+3*iStride, 1, iIndexABot, iIndexBBot, ucBsBot, true );
}
pPelLum += 4*iStride;
}
}
}
pPelLum -= 16*iStride-4;
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iCurrQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iCurrQp, 0, 51);
for( Int xBlk = 1; xBlk < 4; xBlk++)
{
for( Int yBlk = 0; yBlk < 4; yBlk++)
{
const UChar ucBs = m_aaaucBs[VER][xBlk][yBlk];
if( 0 != ucBs )
{
xFilter( pPelLum, 1, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+ iStride, 1, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+2*iStride, 1, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+3*iStride, 1, iIndexA, iIndexB, ucBs, true );
}
pPelLum += 4*iStride;
}
pPelLum -= 16*iStride-4;
}
return Err::m_nOK;
}
ErrVal
LoopFilter::xLumaHorFiltering( const MbDataAccess& rcMbDataAccess, const DBFilterParameter& rcDFP, YuvPicBuffer* pcYuvBuffer )
{
Int iCurrQp = rcMbDataAccess.getMbData().getQpLF();
Int iStride = pcYuvBuffer->getLStride();
XPel* pPelLum = pcYuvBuffer->getMbLumAddr();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -