📄 loopfilter.cpp
字号:
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
if( !b8x8 || ( ( cIdx.x() & 1 ) == 0 ) )
{
m_aaaucBs[VER][cIdx.x()][cIdx.y()] = xGetVerFilterStrength( rcMbDataAccess, cIdx, iFilterIdc );
}
else
{
m_aaaucBs[VER][cIdx.x()][cIdx.y()] = 0;
}
if( !b8x8 || ( ( cIdx.y() & 1 ) == 0 ) )
{
m_aaaucBs[HOR][cIdx.x()][cIdx.y()] = xGetHorFilterStrength( rcMbDataAccess, cIdx, iFilterIdc );
}
else
{
m_aaaucBs[HOR][cIdx.x()][cIdx.y()] = 0;
}
}
m_bHorMixedMode = m_bHorMixedMode && bCurrFrame;
if( m_apcIntYuvBuffer[ FRAME ] )
{
const PicType ePicType = rcMbDataAccess.getMbPicType();
RNOK( xLumaVerFiltering( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
RNOK( xLumaHorFiltering( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
//V032 of FSL for disabling chroma deblocking in enh. layer
if (!enhancedLayerFlag || (enhancedLayerFlag && (iFilterIdc !=3 && iFilterIdc != 4)) )
{
RNOK( xChromaVerFiltering( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
RNOK( xChromaHorFiltering( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
}
return Err::m_nOK;
}
const SliceHeader& rcSH = rcMbDataAccess.getSH();
const PicType ePicType = ( rcSH.getFieldPicFlag() ) ? rcSH.getPicType() : rcMbDataAccess.getMbPicType();
YuvPicBuffer* pcYuvBuffer = m_pcRecFrameUnit->getPic( ePicType )->getFullPelYuvBuffer();
RNOK( xLumaVerFiltering( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
RNOK( xLumaHorFiltering( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
//V032 of FSL for disabling chroma deblocking in enh. layer
if (!enhancedLayerFlag || (enhancedLayerFlag && (iFilterIdc !=3 && iFilterIdc != 4)) )
{
RNOK( xChromaVerFiltering( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
RNOK( xChromaHorFiltering( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
}
return Err::m_nOK;
}
__inline ErrVal LoopFilter::xFilterMb_RCDO( const MbDataAccess& rcMbDataAccess )
{
const DFP& rcDFP = rcMbDataAccess.getDeblockingFilterParameter( m_eLFMode & LFM_NO_INTER_FILTER );
Int iFilterIdc = rcDFP.getDisableDeblockingFilterIdc();
ROTRS( (m_eLFMode & LFM_NO_INTER_FILTER) && ! rcMbDataAccess.getMbData().isIntra(), Err::m_nOK );
ROTRS( iFilterIdc == 1, Err::m_nOK );
Bool bFieldFlag = rcMbDataAccess.getMbData().getFieldFlag();
m_bVerMixedMode = ( bFieldFlag != rcMbDataAccess.getMbDataLeft().getFieldFlag() );
m_bHorMixedMode = ( bFieldFlag ? ( bFieldFlag != rcMbDataAccess.getMbDataAboveAbove().getFieldFlag() )
: ( bFieldFlag != rcMbDataAccess.getMbDataAbove ().getFieldFlag() ) );
if( m_apcIntYuvBuffer[ FRAME ] )
{
const PicType ePicType = rcMbDataAccess.getMbPicType();
RNOK( xLumaVerFiltering_H241RCDO( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ], &rcMbDataAccess, NULL, NULL ) );
RNOK( xLumaHorFiltering_H241RCDO( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ], &rcMbDataAccess, NULL, NULL ) );
RNOK( xChromaVerFiltering_H241RCDO( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
RNOK( xChromaHorFiltering_H241RCDO( rcMbDataAccess, rcDFP, m_apcIntYuvBuffer[ ePicType ] ) );
return Err::m_nOK;
}
const SliceHeader& rcSliceHeader = rcMbDataAccess.getSH();
const PicType ePicType = ( rcSliceHeader.getFieldPicFlag() ? rcSliceHeader.getPicType() : rcMbDataAccess.getMbPicType() );
YuvPicBuffer* pcYuvBuffer = m_pcRecFrameUnit->getPic( ePicType )->getFullPelYuvBuffer();
RNOK( xLumaVerFiltering_H241RCDO( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
RNOK( xLumaHorFiltering_H241RCDO( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
RNOK( xChromaVerFiltering_H241RCDO( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
RNOK( xChromaHorFiltering_H241RCDO( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
return Err::m_nOK;
}
__inline Void LoopFilter::xFilter( Pel* pFlt, const Int& iOffset, const Int& iIndexA, const Int& iIndexB, const UChar& ucBs, const Bool& bLum )
{
const Int iAlpha = g_acAlphaClip[ iIndexA ].ucAlpha;
Int P0 = pFlt[-iOffset];
Int Q0 = pFlt[ 0];
Int iDelta = Q0 - P0;
Int iAbsDelta = abs( iDelta );
AOF_DBG( ucBs );
ROFVS( iAbsDelta < iAlpha );
const Int iBeta = g_aucBetaTab [ iIndexB ];
Int P1 = pFlt[-2*iOffset];
Int Q1 = pFlt[ iOffset];
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;
}
}
}
#define Clip1Y(a) ((a)>255 ? 255 :((a)<0?0:(a)))
#define Clip1C(a) ((a)>255 ? 255 :((a)<0?0:(a)))
#define Clip3(mn,mx,val) (((val)<(mn))?(mn):(((val)>(mx))?(mx):(val)))
__inline Void LoopFilter::xFilter_H241RCDO( Pel* pFlt, const Int& iOffset, const Int& iIndexA, const Int& iIndexB, const Int& blk_pos, const Bool& bLum )
{
const Int iTc = g_aucTcTab_H241RCDO [ iIndexA ];
Int P2 = pFlt[-3*iOffset];
Int P1 = pFlt[-2*iOffset];
Int P0 = pFlt[-1*iOffset];
Int Q0 = pFlt[ 0];
Int Q1 = pFlt[ 1*iOffset];
Int Q2 = pFlt[ 2*iOffset];
Int iDelta;
if( bLum )
{
if( blk_pos ) // not on macroblock edge
{
iDelta = Clip3( -iTc, iTc, ( ( Q0 + ( ( P2 + Q1 ) >> 1 ) ) >> 1 ) - ( ( P0 + ( ( Q2 + P1 ) >> 1 ) ) >> 1 ) );
}
else
{
iDelta = Clip3( -iTc, iTc, ( ( Q0 + ( Q1 >> 1 ) ) >> 1 ) - ( ( P0 + ( Q2 >> 1 ) ) >> 1 ) );
}
pFlt[-2*iOffset] = Clip1Y(P1 +(iDelta/2));
pFlt[-1*iOffset] = Clip1Y(P0 + iDelta );
pFlt[ 0] = Clip1Y(Q0 - iDelta );
pFlt[ 1*iOffset] = Clip1Y(Q1 -(iDelta/2));
}
else
{
iDelta = Clip3 ( -iTc, iTc, ( ( ( ( Q0 - P0 ) << 2 ) + P1 - Q1 + 4 ) >> 3 ) );
pFlt[-iOffset] = Clip1C( P0 + iDelta );
pFlt[ 0] = Clip1C( Q0 - iDelta );
}
}
__inline Void LoopFilter::xFilter_H241RCDO( XPel* pFlt, const Int& iOffset, const Int& iIndexA, const Int& iIndexB, const Int& blk_pos, const Bool& bLum )
{
const Int iTc = g_aucTcTab_H241RCDO [ iIndexA ];
Int P2 = pFlt[-3*iOffset];
Int P1 = pFlt[-2*iOffset];
Int P0 = pFlt[-1*iOffset];
Int Q0 = pFlt[ 0];
Int Q1 = pFlt[ 1*iOffset];
Int Q2 = pFlt[ 2*iOffset];
Int iDelta;
if( bLum )
{
if( blk_pos ) // not on macroblock edge
{
iDelta = Clip3( -iTc, iTc, ( ( Q0 + ( ( P2 + Q1 ) >> 1 ) ) >> 1 ) - ( ( P0 + ( ( Q2 + P1 ) >> 1 ) ) >> 1 ) );
}
else
{
iDelta = Clip3( -iTc, iTc, ( ( Q0 + ( Q1 >> 1 ) ) >> 1 ) - ( ( P0 + ( Q2 >> 1 ) ) >> 1 ) );
}
pFlt[-2*iOffset] = Clip1Y(P1 +(iDelta/2));
pFlt[-1*iOffset] = Clip1Y(P0 + iDelta );
pFlt[ 0] = Clip1Y(Q0 - iDelta );
pFlt[ 1*iOffset] = Clip1Y(Q1 -(iDelta/2));
}
else
{
iDelta = Clip3 ( -iTc, iTc, ( ( ( ( Q0 - P0 ) << 2 ) + P1 - Q1 + 4 ) >> 3 ) );
pFlt[-iOffset] = Clip1C( P0 + iDelta );
pFlt[ 0] = Clip1C( Q0 - iDelta );
}
}
__inline ErrVal LoopFilter::xLumaVerFiltering_H241RCDO( const MbDataAccess& rcMbDataAccess, const DFP& rcDFP, YuvPicBuffer* pcYuvBuffer )
{
Int iCurrQp = rcMbDataAccess.getMbDataCurr().getQpLF();
Int iStride = pcYuvBuffer->getLStride();
Pel* pPelLum = pcYuvBuffer->getMbLumAddr();
Bool b8x8 = rcMbDataAccess.getMbData().isTransformSize8x8();
Bool filterBlockEdge = false;
Bool bFilterTopOnly = false;
Bool bFilterBotOnly = false;
Short sHorMvThr = 4;
Short sVerMvThr = ( FRAME == rcMbDataAccess.getMbPicType() ? 4 : 2 );
Int CheckMVandRefVal;
Int xBlk, yBlk, iLeftQp = 0, iLeftQpTop = 0, iLeftQpBot = 0;
//===== LEFT MACROBLOCK EDGE =====
B4x4Idx cIdx=0;
for( yBlk = 0; yBlk <= 8; yBlk+=8 )
{
filterBlockEdge = rcMbDataAccess.isLeftMbExisting();
bFilterTopOnly = false;
bFilterBotOnly = false;
if( filterBlockEdge )
{
Bool bLeftIntra = rcMbDataAccess.getMbDataLeft().isIntra();
iLeftQp = rcMbDataAccess.getMbDataLeft().getQpLF();
if( m_bVerMixedMode )
{
if ( rcMbDataAccess.getMbData().getFieldFlag() && yBlk == 0 )
{
bLeftIntra = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataLeft().isIntra() : rcMbDataAccess.getMbDataAboveLeft().isIntra() );
iLeftQp = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataLeft().getQpLF() : rcMbDataAccess.getMbDataAboveLeft().getQpLF() );
}
else if ( rcMbDataAccess.getMbData().getFieldFlag() )
{
bLeftIntra = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataBelowLeft().isIntra() : rcMbDataAccess.getMbDataLeft().isIntra() );
iLeftQp = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataBelowLeft().getQpLF() : rcMbDataAccess.getMbDataLeft().getQpLF() );
}
else // current pair is frame, left pair is field
{
Bool bLI_Top = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataLeft().isIntra() : rcMbDataAccess.getMbDataAboveLeft().isIntra() );
Bool bLI_Bot = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataBelowLeft().isIntra() : rcMbDataAccess.getMbDataLeft().isIntra() );
iLeftQpTop = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataLeft().getQpLF() : rcMbDataAccess.getMbDataAboveLeft().getQpLF() );
iLeftQpBot = ( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataBelowLeft().getQpLF() : rcMbDataAccess.getMbDataLeft().getQpLF() );
if( ( bLI_Top ^ bLI_Bot ) && LFM_DEFAULT_FILTER != m_eLFMode )
{
bLeftIntra = true;
bFilterTopOnly= bLI_Top;
bFilterBotOnly= bLI_Bot;
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -