⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loopfilter.cpp

📁 JVT-Z203_jsvm.rar
💻 CPP
📖 第 1 页 / 共 4 页
字号:

  //===== 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 + -