📄 loopfilter.cpp
字号:
//===== filtering =====
m_bHorMixedMode = m_bHorMixedMode && bCurrFrame;
RNOK ( xLumaVerFiltering ( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
RNOK ( xLumaHorFiltering ( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
ROTRS ( iFilterIdc > 3, Err::m_nOK );
RNOK ( xChromaVerFiltering ( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
RNOK ( xChromaHorFiltering ( rcMbDataAccess, rcDFP, pcYuvBuffer ) );
return Err::m_nOK;
}
ErrVal
LoopFilter::xRecalcCBP( MbDataAccess &rcMbDataAccess )
{
UInt uiCbp = 0;
UInt uiStart = 0;
UInt uiStop = 16;
if( rcMbDataAccess.getMbData().isTransformSize8x8() )
{
const UChar *pucScan = rcMbDataAccess.getMbData().getFieldFlag() ? g_aucFieldScan64 : g_aucFrameScan64;
uiStart <<= 2;
uiStop <<= 2;
for( B8x8Idx cIdx; cIdx.isLegal(); cIdx++ )
{
TCoeff *piCoeff = rcMbDataAccess.getMbTCoeffs().get8x8( cIdx );
for( UInt ui = uiStart; ui < uiStop; ui++ )
{
if( m_bEncoder ? piCoeff[pucScan[ui]].getLevel() : piCoeff[pucScan[ui]].getCoeff() )
{
uiCbp |= 0x33 << cIdx.b8x8();
break;
}
}
}
}
else
{
const UChar *pucScan = rcMbDataAccess.getMbData().getFieldFlag() ? g_aucFieldScan : g_aucFrameScan;
for( B4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
TCoeff *piCoeff = rcMbDataAccess.getMbTCoeffs().get( cIdx );
for( UInt ui = uiStart; ui < uiStop; ui++ )
{
if( m_bEncoder ? piCoeff[pucScan[ui]].getLevel() : piCoeff[pucScan[ui]].getCoeff() )
{
uiCbp |= 1<<cIdx.b4x4();
break;
}
}
}
if( rcMbDataAccess.getMbData().isIntra16x16() )
{
uiCbp = uiCbp ? 0xFFFF : 0;
}
}
rcMbDataAccess.getMbData().setAndConvertMbExtCbp( uiCbp );
return Err::m_nOK;
}
UInt
LoopFilter::xGetHorFilterStrength ( const MbDataAccess& rcMbDataAccess,
LumaIdx cIdx,
Int iFilterIdc,
Bool bInterLayerFlag,
Bool bSpatialScalableFlag,
LFPass eLFPass )
{
Short sHorMvThr = 4;
Short sVerMvThr = ( rcMbDataAccess.getMbPicType() == FRAME ? 4 : 2 );
Bool bFilterInside = xFilterInsideEdges( rcMbDataAccess, iFilterIdc, bInterLayerFlag, eLFPass );
Bool bFilterTop = xFilterTopEdge ( rcMbDataAccess, iFilterIdc, bInterLayerFlag, eLFPass );
ROFRS( ( ! cIdx.y() && bFilterTop ) || ( cIdx.y() && bFilterInside ), 0 );
//--------------------------
//--- INTERNAL EDGES ---
//--------------------------
if( cIdx.y() )
{
const MbData& rcMbDataCurr = rcMbDataAccess.getMbData();
//===== check special condition for I_BL in spatial scalable coding =====
if( bSpatialScalableFlag && rcMbDataCurr.isIntraBL() )
{
ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx ), 1 ); // only coefficients of the current layer are counted
ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx + CURR_MB_ABOVE_NEIGHBOUR ), 1 ); // only coefficients of the current layer are counted
return 0;
}
//===== check for intra =====
ROTRS( rcMbDataCurr.isIntra(), 3 );
//===== check for transform coefficients and residual samples =====
ROTRS( rcMbDataCurr.is4x4BlkResidual( cIdx ), 2 );
ROTRS( rcMbDataCurr.is4x4BlkResidual( cIdx + CURR_MB_ABOVE_NEIGHBOUR ), 2 );
ROTRS( rcMbDataCurr.is4x4BlkCoded ( cIdx ), 2 );
ROTRS( rcMbDataCurr.is4x4BlkCoded ( cIdx + CURR_MB_ABOVE_NEIGHBOUR ), 2 );
//===== check for motion vectors ====
if( rcMbDataCurr.isInterPMb() )
{
return xCheckMvDataP( rcMbDataCurr, cIdx, rcMbDataCurr, cIdx + CURR_MB_ABOVE_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
return xCheckMvDataB( rcMbDataCurr, cIdx, rcMbDataCurr, cIdx + CURR_MB_ABOVE_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
//-------------------------
//--- EXTERNAL EDGE ---
//-------------------------
const MbData& rcMbDataCurr = rcMbDataAccess.getMbData();
const MbData& rcMbDataAbove = xGetMbDataAbove( rcMbDataAccess );
//===== check special condition for inter-layer deblocking =====
if( bInterLayerFlag )
{
ROFRS( rcMbDataCurr .isIntra(), 0 ); // redundant - just for clarity
ROFRS( rcMbDataAbove.isIntra(), 0 );
}
//===== check special condition for I_BL in spatial scalable coding =====
if( bSpatialScalableFlag && ( rcMbDataCurr.isIntraBL() || rcMbDataAbove.isIntraBL() ) )
{
ROTRS( rcMbDataCurr .isIntraButnotIBL(), 4 );
ROTRS( rcMbDataAbove.isIntraButnotIBL(), 4 );
if( rcMbDataCurr.isIntraBL() && rcMbDataAbove.isIntraBL() )
{
ROTRS( rcMbDataCurr .is4x4BlkCoded( cIdx ), 1 ); // only coefficients of the current layer are counted
ROTRS( rcMbDataAbove.is4x4BlkCoded( cIdx + ABOVE_MB_ABOVE_NEIGHBOUR ), 1 ); // only coefficients of the current layer are counted
return 0;
}
ROTRS( ! rcMbDataCurr .isIntra() && rcMbDataCurr .is4x4BlkResidual( cIdx ), 2 );
ROTRS( ! rcMbDataAbove.isIntra() && rcMbDataAbove.is4x4BlkResidual( cIdx + ABOVE_MB_ABOVE_NEIGHBOUR ), 2 );
return 1;
}
//===== check for intra =====
UInt bIntraBs = ( ! m_bHorMixedMode && rcMbDataAccess.getMbPicType() == FRAME ? 4 : 3 );
ROTRS( rcMbDataCurr .isIntra(), bIntraBs );
ROTRS( rcMbDataAbove.isIntra(), bIntraBs );
//===== check for transform coefficients and residual samples =====
ROTRS( rcMbDataCurr. is4x4BlkResidual ( cIdx ), 2 );
ROTRS( rcMbDataAbove.is4x4BlkResidual ( cIdx + ABOVE_MB_ABOVE_NEIGHBOUR ), 2 );
ROTRS( rcMbDataCurr. is4x4BlkCoded ( cIdx ), 2 );
ROTRS( rcMbDataAbove.is4x4BlkCoded ( cIdx + ABOVE_MB_ABOVE_NEIGHBOUR ), 2 );
//===== check for mixed mode =====
ROTRS( m_bHorMixedMode, 1 );
//===== check for motion vectors ====
if( rcMbDataCurr.isInterPMb() && rcMbDataAbove.isInterPMb() )
{
return xCheckMvDataP( rcMbDataCurr, cIdx, rcMbDataAbove, cIdx + ABOVE_MB_ABOVE_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
return xCheckMvDataB( rcMbDataCurr, cIdx, rcMbDataAbove, cIdx + ABOVE_MB_ABOVE_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
UInt
LoopFilter::xGetVerFilterStrength( const MbDataAccess& rcMbDataAccess,
LumaIdx cIdx,
Int iFilterIdc,
Bool bInterLayerFlag,
Bool bSpatialScalableFlag,
LFPass eLFPass )
{
Short sHorMvThr = 4;
Short sVerMvThr = ( rcMbDataAccess.getMbPicType() == FRAME ? 4 : 2 );
Bool bFilterInside = xFilterInsideEdges( rcMbDataAccess, iFilterIdc, bInterLayerFlag, eLFPass );
Bool bFilterLeft = xFilterLeftEdge ( rcMbDataAccess, iFilterIdc, bInterLayerFlag, eLFPass );
ROFRS( ( ! cIdx.x() && bFilterLeft ) || ( cIdx.x() && bFilterInside ), 0 );
//--------------------------
//--- INTERNAL EDGES ---
//--------------------------
if( cIdx.x() )
{
const MbData& rcMbDataCurr = rcMbDataAccess.getMbData();
//===== check special condition for I_BL in spatial scalable coding =====
if( bSpatialScalableFlag && rcMbDataCurr.isIntraBL() )
{
ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx ), 1 ); // only coefficients of the current layer are counted
ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx + CURR_MB_LEFT_NEIGHBOUR ), 1 ); // only coefficients of the current layer are counted
return 0;
}
//===== check for intra =====
ROTRS( rcMbDataCurr.isIntra(), 3 );
//===== check for transform coefficients and residual samples =====
ROTRS( rcMbDataCurr.is4x4BlkResidual( cIdx ), 2 );
ROTRS( rcMbDataCurr.is4x4BlkResidual( cIdx + CURR_MB_LEFT_NEIGHBOUR ), 2 );
ROTRS( rcMbDataCurr.is4x4BlkCoded ( cIdx ), 2 );
ROTRS( rcMbDataCurr.is4x4BlkCoded ( cIdx + CURR_MB_LEFT_NEIGHBOUR ), 2 );
//===== check for motion vectors ====
if( rcMbDataCurr.isInterPMb() )
{
return xCheckMvDataP( rcMbDataCurr, cIdx, rcMbDataCurr, cIdx + CURR_MB_LEFT_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
return xCheckMvDataB( rcMbDataCurr, cIdx, rcMbDataCurr, cIdx + CURR_MB_LEFT_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
//-------------------------
//--- EXTERNAL EDGE ---
//-------------------------
B4x4Idx cIdxLeft = B4x4Idx( cIdx );
const MbData& rcMbDataCurr = rcMbDataAccess.getMbData();
const MbData& rcMbDataLeft = xGetMbDataLeft( rcMbDataAccess, cIdxLeft );
//===== check special condition for inter-layer deblocking =====
if( bInterLayerFlag )
{
ROFRS( rcMbDataCurr.isIntra(), 0 ); // redundant - just for clarity
ROFRS( rcMbDataLeft.isIntra(), 0 );
}
//===== check special condition for I_BL in spatial scalable coding =====
if( bSpatialScalableFlag && ( rcMbDataCurr.isIntraBL() || rcMbDataLeft.isIntraBL() ) )
{
ROTRS( rcMbDataCurr.isIntraButnotIBL(), 4 );
ROTRS( rcMbDataLeft.isIntraButnotIBL(), 4 );
if( rcMbDataCurr.isIntraBL() && rcMbDataLeft.isIntraBL() )
{
ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx ), 1 ); // only coefficients of the current layer are counted
ROTRS( rcMbDataLeft.is4x4BlkCoded( cIdxLeft ), 1 ); // only coefficients of the current layer are counted
return 0;
}
ROTRS( ! rcMbDataCurr.isIntra() && rcMbDataCurr.is4x4BlkResidual( cIdx ), 2 );
ROTRS( ! rcMbDataLeft.isIntra() && rcMbDataLeft.is4x4BlkResidual( cIdxLeft ), 2 );
return 1;
}
//===== check for intra =====
ROTRS( rcMbDataCurr.isIntra(), 4 );
ROTRS( rcMbDataLeft.isIntra(), 4 );
//===== check for transform coefficients and residual samples =====
ROTRS( rcMbDataCurr.is4x4BlkResidual ( cIdx ), 2 );
ROTRS( rcMbDataLeft.is4x4BlkResidual ( cIdxLeft ), 2 );
ROTRS( rcMbDataCurr.is4x4BlkCoded ( cIdx ), 2 );
ROTRS( rcMbDataLeft.is4x4BlkCoded ( cIdxLeft ), 2 );
//===== check for mixed mode =====
ROTRS( m_bVerMixedMode, 1 );
//===== check for motion vectors ====
if( rcMbDataCurr.isInterPMb() && rcMbDataLeft.isInterPMb() )
{
return xCheckMvDataP( rcMbDataCurr, cIdx, rcMbDataLeft, cIdxLeft, sHorMvThr, sVerMvThr );
}
return xCheckMvDataB( rcMbDataCurr, cIdx, rcMbDataLeft, cIdxLeft, sHorMvThr, sVerMvThr );
}
const MbData&
LoopFilter::xGetMbDataLeft( const MbDataAccess& rcMbDataAccess, LumaIdx& rcIdx )
{
if( ! m_bVerMixedMode)
{
rcIdx = ( rcIdx + LEFT_MB_LEFT_NEIGHBOUR );
return rcMbDataAccess.getMbDataLeft();
}
if( rcMbDataAccess.getMbPicType() == FRAME )
{
rcIdx = (LumaIdx)B4x4Idx( rcMbDataAccess.isTopMb() ? ( rcIdx < 8 ? 3 : 7 ) : ( rcIdx < 8 ? 11 : 15 ) );
ROTRS( rcMbDataAccess.isTopMb() && m_bAddEdge, rcMbDataAccess.getMbDataBelowLeft() );
ROTRS( !rcMbDataAccess.isTopMb() && !m_bAddEdge, rcMbDataAccess.getMbDataAboveLeft() );
return rcMbDataAccess.getMbDataLeft();
}
Bool bBotHalf = ( rcIdx > 7 );
rcIdx = (LumaIdx)B4x4Idx( ( ( rcIdx % 8) << 1 ) + ( m_bAddEdge ? 7 : 3 ) );
ROTRS( rcMbDataAccess.isTopMb() && bBotHalf, rcMbDataAccess.getMbDataBelowLeft() );
ROTRS( !rcMbDataAccess.isTopMb() && !bBotHalf, rcMbDataAccess.getMbDataAboveLeft() );
return rcMbDataAccess.getMbDataLeft();
}
const MbData&
LoopFilter::xGetMbDataAbove( const MbDataAccess& rcMbDataAccess )
{
ROTRS( ! m_bHorMixedMode && rcMbDataAccess.getMbData().getFieldFlag(), rcMbDataAccess.getMbDataAboveAbove() );
ROTRS( ! m_bHorMixedMode, rcMbDataAccess.getMbDataAbove() );
ROTRS( rcMbDataAccess.getMbPicType() == FRAME && m_bAddEdge, rcMbDataAccess.getMbDataAboveAbove() );
ROTRS( rcMbDataAccess.getMbPicType() == FRAME, rcMbDataAccess.getMbDataAbove() );
ROTRS( rcMbDataAccess.isTopMb(), rcMbDataAccess.getMbDataAbove() );
return rcMbDataAccess.getMbDataAboveAbove();
}
Bool
LoopFilter::xFilterInsideEdges( const MbDataAccess& rcMbDataAccess, Int iFilterIdc, Bool bInterLayerFlag, LFPass eLFPass )
{
ROTRS( iFilterIdc == 1, false );
ROTRS( iFilterIdc == 3 && eLFPass == SECOND_PASS, false );
ROTRS( iFilterIdc == 6 && eLFPass == SECOND_PASS, false );
ROTRS( bInterLayerFlag && ! rcMbDataAccess.getMbData().isIntra(), false );
return true;
}
Bool
LoopFilter::xFilterLeftEdge( const MbDataAccess& rcMbDataAccess, Int iFilterIdc, Bool bInterLayerFlag, LFPass eLFPass )
{
ROTRS( iFilterIdc == 1, false );
ROFRS( rcMbDataAccess.isLeftMbExisting(), false );
if( ! rcMbDataAccess.isAvailableLeft () )
{
ROTRS( iFilterIdc == 2, false );
ROTRS( iFilterIdc == 5, false );
ROTRS( iFilterIdc == 3 && eLFPass == FIRST_PASS, false );
ROTRS( iFilterIdc == 6 && eLFPass == FIRST_PASS, false );
}
else
{
ROTRS( iFilterIdc == 3 && eLFPass == SECOND_PASS, false );
ROTRS( iFilterIdc == 6 && eLFPass == SECOND_PASS, false );
}
ROTRS( bInterLayerFlag && ! rcMbDataAccess.getMbData().isIntra(), false );
// NOTE: intra status of neighboring MB must be checked in dependence of the block index (and field mode)
return true;
}
Bool
LoopFilter::xFilterTopEdge( const MbDataAccess& rcMbDataAccess, Int iFilterIdc, Bool bInterLayerFlag, LFPass eLFPass )
{
ROTRS( iFilterIdc == 1, false );
ROFRS( rcMbDataAccess.isAboveMbExisting(), false );
if( ! rcMbDataAccess.isAvailableAbove () )
{
ROTRS( iFilterIdc == 2, false );
ROTRS( iFilterIdc == 5, false );
ROTRS( iFilterIdc == 3 && eLFPass == FIRST_PASS, false );
ROTRS( iFilterIdc == 6 && eLFPass == FIRST_PASS, false );
}
else
{
ROTRS( iFilterIdc == 3 && eLFPass == SECOND_PASS, false );
ROTRS( iFilterIdc == 6 && eLFPass == SECOND_PASS, false );
}
ROTRS( bInterLayerFlag && ! rcMbDataAccess.getMbData().isIntra(), false );
// NOTE: intra status of neighboring MB must be checked in dependence of the block index (and field mode)
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -