VVC/JEM代码学习17:xCheckRDCostMerge2Nx2NFRUC

26 篇文章 2 订阅

在执行完xCheckRDCostMerge2N*2N函数完后,会执行此函数。FRUC包含两种技术,一种是模板匹配,一种是双边匹配。该计算的关键在于怎么推导MV,下次再看吧。

#if VCEG_AZ07_FRUC_MERGE
Void TEncCu::xCheckRDCostMerge2Nx2NFRUC( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU , Bool *earlyDetectionSkipMode )
{
#if JVET_C0024_QTBT
  UInt uiWIdx = g_aucConvertToBit[rpcBestCU->getWidth(0)];
  UInt uiHIdx = g_aucConvertToBit[rpcBestCU->getHeight(0)];
#endif
  UChar uhDepth = rpcTempCU->getDepth( 0 );
  const UChar uhFRUCME[2] = { FRUC_MERGE_BILATERALMV , FRUC_MERGE_TEMPLATE };//双边匹配和模板匹配
#if VCEG_AZ06_IC
  Bool bICFlag = rpcTempCU->getICFlag( 0 );
#endif
  ///循环两次,一次是双边匹配(时域),一次是模板匹配(空域)/
  for( Int nME = 0 ; nME < 2 ; nME++ )
  {
#if JVET_D0077_SAVE_LOAD_ENC_INFO
    if( m_pcPredSearch->getSaveLoadTag(rpcBestCU->getZorderIdxInCtu(), uiWIdx, uiHIdx) == LOAD_ENC_INFO && 
      uhFRUCME[nME] != m_pcPredSearch->getSaveLoadFrucMode( uiWIdx, uiHIdx ) )
    {
      continue;
    }
#endif
#if !JVET_C0024_QTBT
    rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); 
#endif//设置运动补偿参数
    rpcTempCU->setPredModeSubParts( MODE_INTER, 0, uhDepth ); // interprets depth relative to LCU level
    rpcTempCU->setCUTransquantBypassSubParts( false,     0, uhDepth );
    rpcTempCU->setMergeFlagSubParts( true, 0, 0, uhDepth ); // interprets depth relative to LCU level
    rpcTempCU->setMergeIndexSubParts( 0, 0, 0, uhDepth ); // interprets depth relative to LCU level
    rpcTempCU->setFRUCMgrModeSubParts( uhFRUCME[nME] , 0 , 0 , uhDepth );
#if VCEG_AZ06_IC
    rpcTempCU->setICFlagSubParts( bICFlag, 0, uhDepth );
#endif
    Bool bAvailable = m_pcPredSearch->deriveFRUCMV( rpcTempCU , uhDepth , 0 , 0 ); //基于FRUC推导块的MV;
#if JVET_C0024_QTBT
    m_pppcFRUCBufferCU[uiWIdx][uiHIdx]->copyPartFrom( rpcTempCU , 0 , uhDepth, rpcTempCU->getWidth(0), rpcTempCU->getHeight(0) );
#else
    m_ppcFRUCBufferCU[uhDepth]->copyPartFrom( rpcTempCU , 0 , uhDepth );
#endif
    if( bAvailable )//如果上面推导出来的MV可用
    {
      UInt iteration = 1 + !rpcTempCU->isLosslessCoded(0) ;//无损,则等于1,有损,则等于2;
	  //iteration开始,残差系数全为0迭代1次,否则2次//
      for( UInt uiNoResidual = 0; uiNoResidual < iteration; uiNoResidual++ )
      {
        if( uiNoResidual > 0 )//第二次迭代;
        {
#if JVET_C0024_QTBT
            rpcTempCU->copyPartFrom( m_pppcFRUCBufferCU[uiWIdx][uiHIdx] , 0 , uhDepth, rpcTempCU->getWidth(0), rpcTempCU->getHeight(0) );
#else
          rpcTempCU->copyPartFrom( m_ppcFRUCBufferCU[uhDepth] , 0 , uhDepth );
#endif
        }
        // do MC
#if JVET_C0024_QTBT
        m_pcPredSearch->motionCompensation ( rpcTempCU, m_pppcPredYuvTemp[uiWIdx][uiHIdx] );//做运动补偿
#if COM16_C806_OBMC//进行重叠块运动补偿
        m_pcPredSearch->subBlockOBMC( rpcTempCU, 0, m_pppcPredYuvTemp[uiWIdx][uiHIdx], m_pppcTmpYuv1[uiWIdx][uiHIdx], m_pppcTmpYuv2[uiWIdx][uiHIdx] );
#endif
        // estimate residual and encode everything,估计残差并且编码所有数据,计算失真
        m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU,
          m_pppcOrigYuv    [uiWIdx][uiHIdx],
          m_pppcPredYuvTemp[uiWIdx][uiHIdx],
          m_pppcResiYuvTemp[uiWIdx][uiHIdx],
          m_pppcResiYuvBest[uiWIdx][uiHIdx],
          m_pppcRecoYuvTemp[uiWIdx][uiHIdx],
          (uiNoResidual? true:false)
#if COM16_C806_EMT
          , rpcBestCU->getTotalCost()
#endif
          );
#else
        m_pcPredSearch->motionCompensation ( rpcTempCU, m_ppcPredYuvTemp[uhDepth] );
#if COM16_C806_OBMC
        m_pcPredSearch->subBlockOBMC( rpcTempCU, 0, m_ppcPredYuvTemp[uhDepth], m_ppcTmpYuv1[uhDepth], m_ppcTmpYuv2[uhDepth] );
#endif
        // 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)
#if COM16_C806_EMT
          , rpcBestCU->getTotalCost()
#endif
          );
#endif
        if ( uiNoResidual == 0 && rpcTempCU->getQtRootCbf(0) == 0 )
        {//在第一次迭代中,如果残差系数全为0,则不进行第二次迭代过程;
          uiNoResidual++;
        }
        rpcTempCU->setSkipFlagSubParts( rpcTempCU->getQtRootCbf(0) == 0, 0, uhDepth );//设置SkipFlag;
        Int orgQP = rpcTempCU->getQP( 0 );
        xCheckDQP( rpcTempCU );
        xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth);
        rpcTempCU->initEstData( uhDepth, orgQP, false );
      }
	  //iteration结束///
    }
  }
  循环结束,一次双边匹配,一次模板匹配/
}
#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值