程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> HEVC幀間預測之三——TEncCu::xCheckRDCostMerge2Nx2N函數分析

HEVC幀間預測之三——TEncCu::xCheckRDCostMerge2Nx2N函數分析

編輯:C++入門知識

本文將對實現merge模式的主函數xCheckRDCostMerge2Nx2N進行分析,方便理清merge模式的整個過程。之前的一篇分析了getInterMergeCandidates的具體實現,還有兩個比較重要的函數motionCompensation和encodeResAndCalcRdInterCU,將留在後面陸續進行分析,但是根據它們的命名就不難猜出它們的作用,而且事實也是這樣,因此對理解merge模式的整個過程沒有影響,可以暫時不用去細究具體實現。下面仍然以貼代碼及注釋的方式來進行分析: [cpp]  

Void TEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, Bool *earlyDetectionSkipMode )  

{     assert( rpcTempCU->getSlice()->getSliceType() != I_SLICE );     TComMvField  cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1]; // double length for mv of both lists     UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];     Int numValidMergeCand = 0;

 

 for( UInt ui = 0; ui < rpcTempCU->getSlice()->getMaxNumMergeCand(); ++ui )  

  {       uhInterDirNeighbours[ui] = 0;     }     UChar uhDepth = rpcTempCU->getDepth( 0 );     rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level     rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uhDepth );     rpcTempCU->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );     //! 創建一個merging candidates的列表     Int mergeCandBuffer[MRG_MAX_NUM_CANDS];     for( UInt ui = 0; ui < rpcTempCU->getSlice()->getMaxNumMergeCand(); ++ui )     {       mergeCandBuffer[ui] = 0;     }

 

 Bool bestIsSkip = false;

 UInt iteration;  

  if ( rpcTempCU->isLosslessCoded(0)) //!< 默認為false     {       iteration = 1;     }     else      {       iteration = 2;     }

 

 for( UInt uiNoResidual = 0; uiNoResidual < iteration; ++uiNoResidual )  

  {       for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand ) //!< 遍歷所有merging candidates       {         {           if(!(uiNoResidual==1 && mergeCandBuffer[uiMergeCand]==1)) //!< uiNoResidual等於0或者mergeCandBuffer[uiMergeCand]等於0時條件成立           {

 

       if( !(bestIsSkip && uiNoResidual == 0) ) //!< bestIsSkip等於false或者uiNoResidual等於1時條件成立  

        {             // set MC parameters             rpcTempCU->setPredModeSubParts( MODE_INTER, 0, uhDepth ); // interprets depth relative to LCU level             rpcTempCU->setCUTransquantBypassSubParts( m_pcEncCfg->getCUTransquantBypassFlagValue(),     0, uhDepth );             rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative to LCU level             rpcTempCU->setMergeFlagSubParts( true, 0, 0, uhDepth ); // interprets depth relative to LCU level             rpcTempCU->setMergeIndexSubParts( uiMergeCand, 0, 0, uhDepth ); // interprets depth relative to LCU level             rpcTempCU->setInterDirSubParts( uhInterDirNeighbours[uiMergeCand], 0, 0, uhDepth ); // interprets depth relative to LCU level             rpcTempCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField( cMvFieldNeighbours[0 + 2*uiMergeCand], SIZE_2Nx2N, 0, 0 ); // interprets depth relative to rpcTempCU level             rpcTempCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField( cMvFieldNeighbours[1 + 2*uiMergeCand], SIZE_2Nx2N, 0, 0 ); // interprets depth relative to rpcTempCU level

 

      // do MC  

       m_pcPredSearch->motionCompensation ( rpcTempCU, m_ppcPredYuvTemp[uhDepth] ); //!< 運動補償          // estimate residual and encode everything          m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU,            m_ppcOrigYuv    [uhDepth],            m_ppcPredYuvTemp[uhDepth],            m_ppcResiYuvTemp[uhDepth],            m_ppcResiYuvBest[uhDepth],            m_ppcRecoYuvTemp[uhDepth],            (uiNoResidual? true:false)); //!< 對殘差進行編碼並計算RDCost

 

 

       if(uiNoResidual==0)          {            if(rpcTempCU->getQtRootCbf(0) == 0) //!< CBF為0,說明變換系數全為0            {              mergeCandBuffer[uiMergeCand] = 1;            }          }

 

      rpcTempCU->setSkipFlagSubParts( rpcTempCU->getQtRootCbf(0) == 0, 0, uhDepth );  

          Int orgQP = rpcTempCU->getQP( 0 );             xCheckDQP( rpcTempCU );             xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth); //!< 更新最佳模式             rpcTempCU->initEstData( uhDepth, orgQP ); //!< 重新初始化預測參數,為下一次預測做准備

 

 

      if( m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip ) //!< m_useFastDecisionForMerge默認為true         {           bestIsSkip = rpcBestCU->getQtRootCbf(0) == 0;         }

 

   }//!< if( !(bestIsSkip && uiNoResidual == 0) )   

    }//!< if(!(uiNoResidual==1 && mergeCandBuffer[uiMergeCand]==1))      }//!<      }//!< for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )

 

 if(uiNoResidual == 0 && m_pcEncCfg->getUseEarlySkipDetection()) //!< 第一次對merging candidates迭代後  

  {       if(rpcBestCU->getQtRootCbf( 0 ) == 0) //!< earlyDetectionSkip 算法       {         if( rpcBestCU->getMergeFlag( 0 ))         {           *earlyDetectionSkipMode = true;         }         else         {           Int absoulte_MV=0;           for ( UInt uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )           {       www.2cto.com           if ( rpcBestCU->getSlice()->getNumRefIdx( RefPicList( uiRefListIdx ) ) > 0 )             {               TComCUMvField* pcCUMvField = rpcBestCU->getCUMvField(RefPicList( uiRefListIdx ));               Int iHor = pcCUMvField->getMvd( 0 ).getAbsHor();               Int iVer = pcCUMvField->getMvd( 0 ).getAbsVer();               absoulte_MV+=iHor+iVer;             }           }

 

       if(absoulte_MV == 0)  

        {             *earlyDetectionSkipMode = true;           }         }//!< else       }//!< if(rpcBestCU->getQtRootCbf( 0 ) == 0)     }//!< if(uiNoResidual == 0 && m_pcEncCfg->getUseEarlySkipDetection())    }//!< for( UInt uiNoResidual = 0; uiNoResidual < iteration; ++uiNoResidual )    }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved