TEncCu::xCheckRDCostMerge2Nx2N

来源:互联网 发布:matlab 矩阵范数 编辑:程序博客网 时间:2024/05/14 16:41

转自:http://blog.csdn.net/mashiying2013/article/details/10068927

VoidTEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCUTComDataCU*& rpcTempCUBool*earlyDetectionSkipMode )

{

  assertrpcTempCU->getSlice()->getSliceType() !=I_SLICE ); //确定该片是P Slice 或者 B Slice

  //#define MRG_MAX_NUM_CANDS           5

  //由于是两个列表所以这里要左移一位

  TComMvField cMvFieldNeighbours[MRG_MAX_NUM_CANDS << 1];    //double length for mv of both lists

  //

  UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];

  Int numValidMergeCand = 0;

 

  //初始化,rpcTempCU->getSlice()->getMaxNumMergeCand()== 5

  forUInt ui = 0; ui < rpcTempCU->getSlice()->getMaxNumMergeCand();++ui ){

    uhInterDirNeighbours[ui] = 0;

  }

 

  //计算该CU所在的深度

  UChar uhDepth = rpcTempCU->getDepth( 0 );

  //根据当前CU的深度,做相应的初始化,以4x4块为单位

  //memset( m_pePartSize +uiAbsPartIdx, eMode, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );

  // Char*         m_pePartSize;         ///< array of partition sizes

  //  PU 中相应的partition 写入分割模式

  rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth ); // interprets depth relative toLCU level

 

  //memset( m_CUTransquantBypass +uiAbsPartIdx, flag, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );

  //m_CUTransquantBypass : array ofcu_transquant_bypass flags

  //

  rpcTempCU->setCUTransquantBypassSubParts(m_pcEncCfg->getCUTransquantBypassFlagValue(), 0, uhDepth );

  //设置cMvFieldNeighbours,uhInterDirNeighbours,numValidMergeCand 

  rpcTempCU->getInterMergeCandidates( 0, 0,cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );

 

  //! 创建一个merging candidates的列表  并初始化

  Int mergeCandBuffer[MRG_MAX_NUM_CANDS];

  forUInt ui = 0; ui < rpcTempCU->getSlice()->getMaxNumMergeCand();++ui ){

    mergeCandBuffer[ui] = 0;

  }

 

  Bool bestIsSkip = false;

 

  UInt iteration;

 

  //!< 默认为false

  if ( rpcTempCU->isLosslessCoded(0)) {

    iteration = 1;

  else {

    iteration = 2;

  }

 

  //代码结构分析

  //第一次不理skip模式bestIsSkip  初始值为 false;

  //第二次不处理mergeCandBuffer[uiMergeCand]==1的情况

 

  //遍历两次:第一次是对残差不编码;第二次对残差编码.

  forUInt uiNoResidual = 0; uiNoResidual <iteration; ++uiNoResidual ){

    //!< 遍历所有merging candidates

    forUInt uiMergeCand = 0; uiMergeCand <numValidMergeCand; ++uiMergeCand ) {

      {

        //!((uiNoResidual==1 &&mergeCandBuffer[uiMergeCand]==1) || (bestIsSkip && uiNoResidual == 0))

        //!< uiNoResidual等于0或者mergeCandBuffer[uiMergeCand]等于0时条件成立

        if(!(uiNoResidual==1 &&mergeCandBuffer[uiMergeCand]==1)){

          //!< bestIsSkip等于false或者uiNoResidual等于1时条件成立

          if( !(bestIsSkip &&uiNoResidual == 0) ){ 

            // set MC parameters

 

            // interprets depth relative to LCUlevel 设置变量 m_pePredMode

            //memset( m_pePredMode +uiAbsPartIdx(0), eMode, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ));

            rpcTempCU->setPredModeSubParts( MODE_INTER, 0, uhDepth );

            // 设置变量 m_CUTransquantBypass

            // memset( m_CUTransquantBypass +uiAbsPartIdx, flag, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );

            rpcTempCU->setCUTransquantBypassSubParts(m_pcEncCfg->getCUTransquantBypassFlagValue(),    0, uhDepth );

            // interprets depth relative to LCUlevel 设置变量 m_pePartSize

            //memset( m_pePartSize +uiAbsPartIdx, eMode, m_pcPic->getNumPartInCU() >> ( 2 * uiDepth ) );

            rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uhDepth );

 

            // interprets depth relative to LCUlevel

            rpcTempCU->setMergeFlagSubParts( true, 0, 0, uhDepth );

            // interprets depth relative to LCUlevel

            rpcTempCU->setMergeIndexSubParts(uiMergeCand, 0, 0, uhDepth );

            // interprets depth relative to LCUlevel

            rpcTempCU->setInterDirSubParts(uhInterDirNeighbours[uiMergeCand], 0, 0, uhDepth );

 

            // interprets depth relative torpcTempCU level

            rpcTempCU->getCUMvField( REF_PIC_LIST_0 )->setAllMvField(cMvFieldNeighbours[0 + 2*uiMergeCand], SIZE_2Nx2N, 0, 0 );

            // interprets depth relative torpcTempCU level

            rpcTempCU->getCUMvField( REF_PIC_LIST_1 )->setAllMvField(cMvFieldNeighbours[1 + 2*uiMergeCand], SIZE_2Nx2N, 0, 0 );

          

            //运动补偿

           m_pcPredSearch->motionCompensation ( rpcTempCU, m_ppcPredYuvTemp[uhDepth] );

            // estimate residual and encodeeverything

           m_pcPredSearch->encodeResAndCalcRdInterCU(

              rpcTempCU,

              m_ppcOrigYuv    [uhDepth],

             m_ppcPredYuvTemp[uhDepth],

              m_ppcResiYuvTemp[uhDepth],

             m_ppcResiYuvBest[uhDepth],

             m_ppcRecoYuvTemp[uhDepth],

              //!< 对残差进行编码并计算RDCost

              (uiNoResidual? true:false));

 

            //第一次修改,

            if(uiNoResidual==0){

              //!< CBF0,说明变换系数全为0

              if(rpcTempCU->getQtRootCbf(0) == 0) {

               mergeCandBuffer[uiMergeCand] = 1;

              }

            }

 

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

            Int orgQP = rpcTempCU->getQP( 0 );

            xCheckDQP( rpcTempCU );

            //!< 更新最佳模式

            xCheckBestMode(rpcBestCUrpcTempCU, uhDepth);

            //!< 重新初始化预测参数,为下一次预测做准备

            rpcTempCU->initEstData( uhDepth, orgQP);  

            //!< m_useFastDecisionForMerge默认为true

            if(m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip )   {

              bestIsSkip = rpcBestCU->getQtRootCbf(0) == 0;

            }

          }

        }

      }

    }

    // 不处理

    if(uiNoResidual == 0 &&m_pcEncCfg->getUseEarlySkipDetection())

    {

      if(rpcBestCU->getQtRootCbf( 0 ) == 0) //!< earlyDetectionSkip 算法

      {

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

          }

        }

      }

      assert(0);

    }

  }

}


0 0
原创粉丝点击