loopfilter.cpp

来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,794 行 · 第 1/5 页

CPP
1,794
字号

  // both ref pic are used for both blocks
  if( rcRefPicL1P.getFrame() != rcRefPicL0P.getFrame() )
  {
    // at least two diff ref pic are in use
    if( rcRefPicL1P.getFrame() != rcRefPicL1Q.getFrame() )
    {
      ROTRS( rcRefPicL1P.getFrame() != rcRefPicL0Q.getFrame(), 1 );
      ROTRS( rcRefPicL0P.getFrame() != rcRefPicL1Q.getFrame(), 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 );

      //{{SAMSUNG&KHU (JVT-W024)
#if JMVM_ONLY 
      if ((rcQMbData.getMbIcp().getIcAct() && rcPMbData.getMbIcp().getIcAct() && 
          (rcQMbData.getMbIcp().getIcp().getOffset() != rcPMbData.getMbIcp().getIcp().getOffset())) ||
          (rcQMbData.getMbIcp().getIcAct() ^ rcPMbData.getMbIcp().getIcAct()))
      {
        if ( abs(rcQMbData.getMbIcp().getIcp().getOffset() - rcPMbData.getMbIcp().getIcp().getOffset()) >= T)
          return K2;
        else
          return K1;
      }
#endif
      //}}

      return 0;
    }

    // rcRefPicL1P == rcRefPicL1Q
    ROTRS( rcRefPicL0P.getFrame() != rcRefPicL0Q.getFrame(), 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 );

    //{{SAMSUNG&KHU (JVT-W024)
#if JMVM_ONLY 
    if ((rcQMbData.getMbIcp().getIcAct() && rcPMbData.getMbIcp().getIcAct() && 
        (rcQMbData.getMbIcp().getIcp().getOffset() != rcPMbData.getMbIcp().getIcp().getOffset())) ||
        (rcQMbData.getMbIcp().getIcAct() ^ rcPMbData.getMbIcp().getIcAct()))
    {
      if ( abs(rcQMbData.getMbIcp().getIcp().getOffset() - rcPMbData.getMbIcp().getIcp().getOffset()) >= T)
        return K2;
      else
        return K1;
    }
#endif
    //}}

    return 0;
  }

  //  rcRefPicL1P == rcRefPicL0P
  ROTRS( rcRefPicL1Q.getFrame() != rcRefPicL0Q.getFrame(), 1 ) ;
  ROTRS( rcRefPicL0P.getFrame() != rcRefPicL0Q.getFrame(), 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 );

  //{{SAMSUNG&KHU (JVT-W024)
#if JMVM_ONLY 
  if ((rcQMbData.getMbIcp().getIcAct() && rcPMbData.getMbIcp().getIcAct() && 
      (rcQMbData.getMbIcp().getIcp().getOffset() != rcPMbData.getMbIcp().getIcp().getOffset())) ||
      (rcQMbData.getMbIcp().getIcAct() ^ rcPMbData.getMbIcp().getIcAct()))
  {
    if ( abs(rcQMbData.getMbIcp().getIcp().getOffset() - rcPMbData.getMbIcp().getIcp().getOffset()) >= T)
      return K2;
    else
      return K1;
  }
#endif
  //}}

  return 0;
}




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 );

  const RefPic& rcRefPicL0Q = rcMbMotionDataL0Q.getRefPic( cQIdx );
  const RefPic& rcRefPicL0P = rcMbMotionDataL0P.getRefPic( cPIdx );

  // different reference pictures
  ROTRS( rcRefPicL0Q.getFrame() != rcRefPicL0P.getFrame(), 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 );

  //{{SAMSUNG&KHU (JVT-W024)
#if JMVM_ONLY 
  if ((rcQMbData.getMbIcp().getIcAct() && rcPMbData.getMbIcp().getIcAct() && 
      (rcQMbData.getMbIcp().getIcp().getOffset() != rcPMbData.getMbIcp().getIcp().getOffset())) ||
      (rcQMbData.getMbIcp().getIcAct() ^ rcPMbData.getMbIcp().getIcAct()))
  {
    if ( abs(rcQMbData.getMbIcp().getIcp().getOffset() - rcPMbData.getMbIcp().getIcp().getOffset()) >= T)
      return K2;
    else
      return K1;
  }
#endif
  //}}

  return 0;
}


__inline UInt LoopFilter::xGetVerFilterStrength( const MbDataAccess&  rcMbDataAccess,
                                                 LumaIdx              cIdx,
                                                 Int                  iFilterIdc )
{
  const MbData& rcMbDataCurr  = rcMbDataAccess.getMbDataCurr();
  Short         sHorMvThr     = 4;
  Short         sVerMvThr     = 4;

  if( cIdx.x() )
  {
    // this is a edge inside of a macroblock
    ROTRS( rcMbDataCurr.isIntra(), 3 );

    if( m_pcHighpassYuvBuffer )
    {
      ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero ( cIdx                          ), 2 );
      ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero ( cIdx + CURR_MB_LEFT_NEIGHBOUR ), 2 );
    }
    else
    { 
      ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx                          ), 2 );
      ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx + CURR_MB_LEFT_NEIGHBOUR ), 2 );
    }

    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 );
  }


  // if we get here we are on a macroblock edge
  ROTRS( iFilterIdc == 2 && ! rcMbDataAccess.isAvailableLeft(), 0 );
  ROTRS( ! rcMbDataAccess.isLeftMbExisting(),                   0 );


  const MbData& rcMbDataLeft = rcMbDataAccess.getMbDataLeft();

  ROTRS( LFM_DEFAULT_FILTER != m_eLFMode && rcMbDataCurr.isIntra() ^ rcMbDataLeft.isIntra(), 0 );

  ROTRS( rcMbDataCurr.isIntra(), 4 );
  ROTRS( rcMbDataLeft.isIntra(), 4 );

  if( m_pcHighpassYuvBuffer )
  {
    ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero ( cIdx                          ), 2 );
    ROTRS( m_pcHighpassYuvBuffer->isLeft4x4BlkNotZero ( cIdx + LEFT_MB_LEFT_NEIGHBOUR ), 2 );
  }
  else
  {
    ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx                          ), 2 );
    ROTRS( rcMbDataLeft.is4x4BlkCoded( cIdx + LEFT_MB_LEFT_NEIGHBOUR ), 2 );
  }

  if( rcMbDataCurr.isInterPMb() && rcMbDataLeft.isInterPMb())
  {
    return xCheckMvDataP( rcMbDataCurr, cIdx, rcMbDataLeft, cIdx + LEFT_MB_LEFT_NEIGHBOUR, sHorMvThr, sVerMvThr );
  }
  return xCheckMvDataB  ( rcMbDataCurr, cIdx, rcMbDataLeft, cIdx + LEFT_MB_LEFT_NEIGHBOUR, sHorMvThr, sVerMvThr );
}



__inline UInt LoopFilter::xGetHorFilterStrength( const MbDataAccess&  rcMbDataAccess,
                                                 LumaIdx              cIdx,
                                                 Int                  iFilterIdc )
{
  const MbData& rcMbDataCurr  = rcMbDataAccess.getMbDataCurr();
  Short         sHorMvThr     = 4;
  Short         sVerMvThr     = 4;

  if( cIdx.y() )
  {
    // internal edge
    ROTRS( rcMbDataCurr.isIntra(), 3 );

    if( m_pcHighpassYuvBuffer )
    {
      ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero ( cIdx                           ), 2 );
      ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero ( cIdx + CURR_MB_ABOVE_NEIGHBOUR ), 2 );
    }
    else
    {
      ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx                           ), 2 );
      ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx + CURR_MB_ABOVE_NEIGHBOUR ), 2 );
    }

    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 );
  }

  // if we get here we are on a macroblock edge
  ROTRS( iFilterIdc == 2 && ! rcMbDataAccess.isAvailableAbove(),  0 );
  ROTRS( ! rcMbDataAccess.isAboveMbExisting(),                    0 );


  const MbData& rcMbDataAbove = rcMbDataAccess.getMbDataAbove();

  ROTRS( LFM_DEFAULT_FILTER != m_eLFMode && rcMbDataCurr.isIntra() ^ rcMbDataAbove.isIntra(), 0 );
  ROTRS( rcMbDataCurr. isIntra(), 4 );
  ROTRS( rcMbDataAbove.isIntra(), 4 );

  if( m_pcHighpassYuvBuffer )
  {
    ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero  ( cIdx                            ), 2 );
    ROTRS( m_pcHighpassYuvBuffer->isAbove4x4BlkNotZero ( cIdx + ABOVE_MB_ABOVE_NEIGHBOUR ), 2 );
  }
  else
  {
    ROTRS( rcMbDataCurr. is4x4BlkCoded( cIdx                            ), 2 );
    ROTRS( rcMbDataAbove.is4x4BlkCoded( cIdx + ABOVE_MB_ABOVE_NEIGHBOUR ), 2 );
  }

  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 );
}





ErrVal LoopFilter::process( SliceHeader&  rcSH,
                            IntFrame*     pcFrame,
                            MbDataCtrl*   pcMbDataCtrlMot, // if NULL -> all intra
                            MbDataCtrl*   pcMbDataCtrlRes,
                            UInt          uiMbInRow,
                            RefFrameList* pcRefFrameList0,
                            RefFrameList* pcRefFrameList1,			
							bool		  bAllSliceDone, 
                            bool          spatial_scalable_flg)  // SSUN@SHARP
{
  ROT( NULL == m_pcControlMngIf );

  RNOK(   m_pcControlMngIf->initSliceForFiltering ( rcSH               ) );
  RNOK(   pcMbDataCtrlRes ->initSlice             ( rcSH, POST_PROCESS, false, NULL ) );
  if( pcMbDataCtrlMot )
  {
    RNOK( pcMbDataCtrlMot ->initSlice             ( rcSH, POST_PROCESS, false, NULL ) );
  }    

  //-> ICU/ETRI DS FMO Process
  UInt uiFirstMbInSlice;
  UInt uiLastMbInSlice;

  FMO* pcFMO = rcSH.getFMO();  

  for(Int iSliceGroupID=0;!pcFMO->SliceGroupCompletelyCoded(iSliceGroupID);iSliceGroupID++)   
  {
	 if (false == pcFMO->isCodedSG(iSliceGroupID) && false == bAllSliceDone)	 
	 {
		 continue;
	 }

	 uiFirstMbInSlice = pcFMO->getFirstMacroblockInSlice(iSliceGroupID);
	 uiLastMbInSlice = pcFMO->getLastMBInSliceGroup(iSliceGroupID);

    for(UInt uiMbAddress= uiFirstMbInSlice ;uiMbAddress<=uiLastMbInSlice ;)  
    //===== loop over macroblocks use raster scan =====  
	{
      UInt          uiMbY             = uiMbAddress / uiMbInRow;
      UInt          uiMbX             = uiMbAddress % uiMbInRow;
      MbDataAccess* pcMbDataAccessMot = 0;
      MbDataAccess* pcMbDataAccessRes = 0;

      if( pcMbDataCtrlMot )
	  {
        RNOK( pcMbDataCtrlMot ->initMb            (  pcMbDataAccessMot, uiMbY, uiMbX ) );
	  }
      RNOK(   pcMbDataCtrlRes ->initMb            (  pcMbDataAccessRes, uiMbY, uiMbX ) );
      RNOK(   m_pcControlMngIf->initMbForFiltering(  uiMbAddress ) );

      // Hanke@RWTH
      if( m_pcHighpassFrame ) {
        m_pcHighpassYuvBuffer = m_pcHighpassFrame->getFullPelYuvBuffer();
	  }else{
        m_pcHighpassYuvBuffer = NULL;
	  }

	
      if( 0 == (m_eLFMode & LFM_NO_FILTER))
	  {				
		RNOK( xFilterMb( pcMbDataAccessMot,
                       pcMbDataAccessRes,
                       pcFrame->getFullPelYuvBuffer(),
                       pcRefFrameList0,
                       pcRefFrameList1,
                       spatial_scalable_flg ) );  // SSUN@SHARP	  
		//*/
	  }

      if( m_eLFMode & LFM_EXTEND_INTRA_SUR )
	  {
        UInt uiMask = 0;

        RNOK( pcMbDataCtrlRes->getBoundaryMask( uiMbY, uiMbX, uiMask ) );

        if( uiMask )
		{
          IntYuvMbBufferExtension cBuffer;
          cBuffer.setAllSamplesToZero();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?