首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 操作系统 >

HEVC帧间预测之三——TEncCu:xCheckRDCostMerge2Nx2N函数分析

2014-06-08 
HEVC帧间预测之三——TEncCu::xCheckRDCostMerge2Nx2N函数分析本文将对实现merge模式的主函数xCheckRDCostMe

HEVC帧间预测之三——TEncCu::xCheckRDCostMerge2Nx2N函数分析

本文将对实现merge模式的主函数xCheckRDCostMerge2Nx2N进行分析,方便理清merge模式的整个过程。之前的一篇分析了getInterMergeCandidates的具体实现,还有两个比较重要的函数motionCompensation和encodeResAndCalcRdInterCU,将留在后面陆续进行分析,但是根据它们的命名就不难猜出它们的作用,而且事实也是这样,因此对理解merge模式的整个过程没有影响,可以暂时不用去细究具体实现。下面仍然以贴代码及注释的方式来进行分析:

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++ )        {          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 ) } 

热点排行