• HM16.0 TAppEncoder


     参考:  https://www.cnblogs.com/tiansha/p/6458573.html

        https://blog.csdn.net/liangjiubujiu/article/details/81128013

    一、编码流程

    1、encmain.cpp:

      // 创建cTAppEncTop类,解析输入的配置函数,设定时间相关的参数
      int main(int argc, char* argv[])  
      {
        ...

        cTAppEncTop.encode();  // call encoding function

        ...

      }

    2、TAppEncTop.cpp:

      /**
       - create internal class
       - initialize internal variable
       - until the end of input YUV file, call encoding function in TEncTop class
       - delete allocated buffers
       - destroy internal class
       .
       */

      // 对编码器所使用的几个对象进行初始化,分配YUV数据缓存,循环读取YUV文件

      Void TAppEncTop::encode()  

      {

        ...

        // call encoding function for one frame
           if ( m_isField )

          m_cTEncTop.encode( bEos, flush ? 0 : pcPicYuvOrg, flush ? 0 : &cPicYuvTrueOrg, snrCSC, m_cListPicYuvRec,

                    outputAccessUnits, iNumEncoded, m_isTopFieldFirst );

           else            

          m_cTEncTop.encode( bEos, flush ? 0 : pcPicYuvOrg, flush ? 0 : &cPicYuvTrueOrg, snrCSC, m_cListPicYuvRec,

                    outputAccessUnits, iNumEncoded );

        ...

      }

    3、TEncTop.cpp:

      // 调用m_cGOPEncoder.compressGOP()实现对GOP的实际编码

      Void TEncTop::encode(Bool flush, TComPicYuv* pcPicYuvOrg, TComPicYuv* pcPicYuvTrueOrg, const InputColourSpaceConversion snrCSC,

               TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsOut, Int& iNumEncoded, Bool isTff)
      {

        ...

        // compress GOP

        m_cGOPEncoder.compressGOP(m_iPOCLast, m_iNumPicRcvd, m_cListPic, rcListPicYuvRecOut, accessUnitsOut, true,

                       isTff, snrCSC, m_printFrameMSE);

        ...

      }

    4、TEncGOP.cpp:

      // 设置GOP的参数;利用SPS和PPS中的信息创建编码的slice对象,对每一个slice进行编码

      Void TEncGOP::compressGOP( Int iPOCLast, Int iNumPicRcvd, TComList<TComPic*>& rcListPic,

                               TComList<TComPicYuv*>& rcListPicYuvRecOut, std::list<AccessUnit>& accessUnitsInGOP,
                               Bool isField, Bool isTff, const InputColourSpaceConversion snr_conversion, const Bool printFrameMSE )  
      {

        ...

        m_pcSliceEncoder->compressSlice   ( pcPic );  //对每一个slice,找出编码的最优参数

        ...

        m_pcSliceEncoder->encodeSlice(pcPic, pcSubstreamsOut);  //对每一个slice,对其进行实际的熵编码工作

        ...

      }

    5、TEncSlice.cpp:

      /** param rpcPic   picture class
       */

      // 设置编码slice的参数,对slice中的每一个CU进行处理
      Void TEncSlice::compressSlice( TComPic*& rpcPic )

      {

        ...

        // run CU encoder
           m_pcCuEncoder->compressCU( pcCU );  //对每一个CU,找出编码的最优参数

        ...

        m_pcCuEncoder->encodeCU( pcCU );  //对每一个CU,对其进行实际的熵编码工作

        ...

      }

    6、TEncCu.cpp:

      /** param  rpcCU pointer of CU data class  //指向CU的参数
       */
      Void TEncCu::compressCU( TComDataCU*& rpcCU )  //找到编码一个CU的最优参数
      {   

        // initialize CU data
        m_ppcBestCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );  //用来存储最好的QP和在每一个深度的预测模式决策。
        m_ppcTempCU[0]->initCU( rpcCU->getPic(), rpcCU->getAddr() );  //用来存储当前的QP和在每一个深度的预测模式决策。
        // analysis of CU
        DEBUG_STRING_NEW(sDebug)
        // 从深度0开始一直往上加,选择最好的预测模式和QP
        xCompressCU( m_ppcBestCU[0], m_ppcTempCU[0], 0 DEBUG_STRING_PASS_INTO(sDebug) );
        DEBUG_STRING_OUTPUT(std::cout, sDebug)
        #if ADAPTIVE_QP_SELECTION
        if( m_pcEncCfg->getUseAdaptQpSelect() )
        {
          if(rpcCU->getSlice()->getSliceType()!=I_SLICE)
          {
            xLcuCollectARLStats( rpcCU);
          }
        }
        #endif

      }

      /** Compress a CU block recursively with enabling sub-LCU-level delta QP
       *param   rpcBestCU
       *param   rpcTempCU
       *param   uiDepth
       * eturns Void
       *
       *- for loop of QP value to compress the current CU with all possible QP
      */
      Void TEncCu::xCompressCU( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, UInt uiDepth DEBUG_STRING_FN_DECLARE(sDebug_), PartSize eParentPartSize )

      {    

        ...
        // get Original YUV data from picture
        m_ppcOrigYuv[uiDepth]->copyFromPicYuv( pcPic->getPicYuvOrg(), rpcBestCU->getAddr(), rpcBestCU->getZorderIdxInCU() );
        ...
        // compute BaseQP
        // 通过iBaseQP计算iMinQP和iMaxQP
        Int iBaseQP = xComputeQP( rpcBestCU, uiDepth );

        ...

        {

          // 尝试每一个可能的QP对应的每一种预测模式,得到QP和预测模式;实现对本层LCU的模式选择RDCost计算;

          // 执行顺序:帧间模式(Inter、SKIP、AMP)----- 帧内模式(Intra)----- PCM模式;

          // PCM以一种无损的方式进行编码,没有预测和残差,失真为0;如果最优模式产生的比特数大于PCM模式,则选择PCM模式;

          // xCheckRDCostInter():帧间模式;xCheckRDCostMerge2Nx2N():帧间Merge模式;

          // xCheckRDCostIntra():帧内模式;xCheckIntraPCM():PCM模式.

          // 代码框架:

          for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)
             {

            // try all kinds of prediction modes for every possible QP

            ...

          }

          ...

        }

        ...

        // 实现下层分割的计算,最后通过xCheckBestMode来比较是否选用分割

        for (Int iQP=iMinQP; iQP<=iMaxQP; iQP++)

        {

          const Bool bIsLosslessMode = false; // False at this level. Next level down may set it to true.

          rpcTempCU->initEstData( uiDepth, iQP, bIsLosslessMode );

          // further split

          if( bSubBranch && uiDepth < g_uiMaxCUDepth - g_uiAddCUDepth )

          {

            ...

            xCheckBestMode( rpcBestCU, rpcTempCU, uiDepth DEBUG_STRING_PASS_INTO(sDebug) DEBUG_STRING_PASS_INTO(sTempDebug) DEBUG_STRING_PASS_INTO(false) ); // RD compare current larger prediction

          }  

        }

        ...

      }

    二、预测模式选择

    1、帧间模式:

    TypeDef.h:

    /// supported partition shape
    /// AMP (SIZE_2NxnU, SIZE_2NxnD, SIZE_nLx2N, SIZE_nRx2N)
    enum PartSize { SIZE_2Nx2N = 0, ///< symmetric motion partition, 2Nx2N SIZE_2NxN = 1, ///< symmetric motion partition, 2Nx N SIZE_Nx2N = 2, ///< symmetric motion partition, Nx2N SIZE_NxN = 3, ///< symmetric motion partition, Nx N SIZE_2NxnU = 4, ///< asymmetric motion partition, 2Nx( N/2) + 2Nx(3N/2) SIZE_2NxnD = 5, ///< asymmetric motion partition, 2Nx(3N/2) + 2Nx( N/2) SIZE_nLx2N = 6, ///< asymmetric motion partition, ( N/2)x2N + (3N/2)x2N SIZE_nRx2N = 7, ///< asymmetric motion partition, (3N/2)x2N + ( N/2)x2N NUMBER_OF_PART_SIZES = 8 };
    #if AMP_MRG
    Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize DEBUG_STRING_FN_DECLARE(sDebug), Bool bUseMRG)
    #else
    Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize )
    #endif
    {
      DEBUG_STRING_NEW(sTest)
    
      UChar uhDepth = rpcTempCU->getDepth( 0 );
    
      rpcTempCU->setDepthSubParts( uhDepth, 0 );
    
      rpcTempCU->setSkipFlagSubParts( false, 0, uhDepth );
    
      rpcTempCU->setPartSizeSubParts  ( ePartSize,  0, uhDepth );
      rpcTempCU->setPredModeSubParts  ( MODE_INTER, 0, uhDepth );
      rpcTempCU->setChromaQpAdjSubParts( rpcTempCU->getCUTransquantBypass(0) ? 0 : m_ChromaQpAdjIdc, 0, uhDepth );
    
    #if AMP_MRG
      rpcTempCU->setMergeAMP (true);
      m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] DEBUG_STRING_PASS_INTO(sTest), false, bUseMRG );
    #else
      m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] );
    #endif
    
    #if AMP_MRG
      if ( !rpcTempCU->getMergeAMP() )
      {
        return;
      }
    #endif
    
      m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], false DEBUG_STRING_PASS_INTO(sTest) );
      rpcTempCU->getTotalCost()  = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
    
    #ifdef DEBUG_STRING
      DebugInterPredResiReco(sTest, *(m_ppcPredYuvTemp[uhDepth]), *(m_ppcResiYuvBest[uhDepth]), *(m_ppcRecoYuvTemp[uhDepth]), DebugStringGetPredModeMask(rpcTempCU->getPredictionMode(0)));
    #endif
    
      xCheckDQP( rpcTempCU );
      xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth DEBUG_STRING_PASS_INTO(sDebug) DEBUG_STRING_PASS_INTO(sTest));
    }

    2、帧间Merge模式:

    /** check RD costs for a CU block encoded with merge
     * param rpcBestCU
     * param rpcTempCU
     * 
    eturns Void
     */
    Void TEncCu::xCheckRDCostMerge2Nx2N( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU DEBUG_STRING_FN_DECLARE(sDebug), Bool *earlyDetectionSkipMode )
    {
      assert( rpcTempCU->getSlice()->getSliceType() != I_SLICE );
      TComMvField  cMvFieldNeighbours[2 * MRG_MAX_NUM_CANDS]; // double length for mv of both lists
      UChar uhInterDirNeighbours[MRG_MAX_NUM_CANDS];
      Int numValidMergeCand = 0;
      const Bool bTransquantBypassFlag = rpcTempCU->getCUTransquantBypass(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->getInterMergeCandidates( 0, 0, cMvFieldNeighbours,uhInterDirNeighbours, numValidMergeCand );
    
      Int mergeCandBuffer[MRG_MAX_NUM_CANDS];
      for( UInt ui = 0; ui < numValidMergeCand; ++ui )
      {
        mergeCandBuffer[ui] = 0;
      }
    
      Bool bestIsSkip = false;
    
      UInt iteration;
      if ( rpcTempCU->isLosslessCoded(0))
      {
        iteration = 1;
      }
      else
      {
        iteration = 2;
      }
      DEBUG_STRING_NEW(bestStr)
    
      for( UInt uiNoResidual = 0; uiNoResidual < iteration; ++uiNoResidual )
      {
        for( UInt uiMergeCand = 0; uiMergeCand < numValidMergeCand; ++uiMergeCand )
        {
          if(!(uiNoResidual==1 && mergeCandBuffer[uiMergeCand]==1))
          {
            if( !(bestIsSkip && uiNoResidual == 0) )
            {
              DEBUG_STRING_NEW(tmpStr)
              // set MC parameters
              rpcTempCU->setPredModeSubParts( MODE_INTER, 0, uhDepth ); // interprets depth relative to LCU level
              rpcTempCU->setCUTransquantBypassSubParts( bTransquantBypassFlag, 0, uhDepth );
              rpcTempCU->setChromaQpAdjSubParts( bTransquantBypassFlag ? 0 : m_ChromaQpAdjIdc, 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 != 0) DEBUG_STRING_PASS_INTO(tmpStr) );
    
    #ifdef DEBUG_STRING
              DebugInterPredResiReco(tmpStr, *(m_ppcPredYuvTemp[uhDepth]), *(m_ppcResiYuvBest[uhDepth]), *(m_ppcRecoYuvTemp[uhDepth]), DebugStringGetPredModeMask(rpcTempCU->getPredictionMode(0)));
    #endif
    
              if ((uiNoResidual == 0) && (rpcTempCU->getQtRootCbf(0) == 0))
              {
                // If no residual when allowing for one, then set mark to not try case where residual is forced to 0
                mergeCandBuffer[uiMergeCand] = 1;
              }
    
              rpcTempCU->setSkipFlagSubParts( rpcTempCU->getQtRootCbf(0) == 0, 0, uhDepth );
              Int orgQP = rpcTempCU->getQP( 0 );
              xCheckDQP( rpcTempCU );
              xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth DEBUG_STRING_PASS_INTO(bestStr) DEBUG_STRING_PASS_INTO(tmpStr));
    
              rpcTempCU->initEstData( uhDepth, orgQP, bTransquantBypassFlag );
    
              if( m_pcEncCfg->getUseFastDecisionForMerge() && !bestIsSkip )
              {
                bestIsSkip = rpcBestCU->getQtRootCbf(0) == 0;
              }
            }
          }
        }
    
        if(uiNoResidual == 0 && m_pcEncCfg->getUseEarlySkipDetection())
        {
          if(rpcBestCU->getQtRootCbf( 0 ) == 0)
          {
            if( rpcBestCU->getMergeFlag( 0 ))
            {
              *earlyDetectionSkipMode = true;
            }
            else if(m_pcEncCfg->getFastSearch() != SELECTIVE)
            {
              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;
              }
            }
          }
        }
      }
      DEBUG_STRING_APPEND(sDebug, bestStr)
    }

    3、帧内模式:

    Void TEncCu::xCheckRDCostIntra( TComDataCU *&rpcBestCU,
                                    TComDataCU *&rpcTempCU,
                                    Double      &cost,
                                    PartSize     eSize
                                    DEBUG_STRING_FN_DECLARE(sDebug) )
    {
      DEBUG_STRING_NEW(sTest)
    
      UInt uiDepth = rpcTempCU->getDepth( 0 );
    
      rpcTempCU->setSkipFlagSubParts( false, 0, uiDepth );
    
      rpcTempCU->setPartSizeSubParts( eSize, 0, uiDepth );
      rpcTempCU->setPredModeSubParts( MODE_INTRA, 0, uiDepth );
      rpcTempCU->setChromaQpAdjSubParts( rpcTempCU->getCUTransquantBypass(0) ? 0 : m_ChromaQpAdjIdc, 0, uiDepth );
    
      Bool bSeparateLumaChroma = true; // choose estimation mode
    
      Distortion uiPreCalcDistC = 0;
      if (rpcBestCU->getPic()->getChromaFormat()==CHROMA_400)
      {
        bSeparateLumaChroma=true;
      }
    
      Pel resiLuma[NUMBER_OF_STORED_RESIDUAL_TYPES][MAX_CU_SIZE * MAX_CU_SIZE];
    
      if( !bSeparateLumaChroma )
      {
        // after this function, the direction will be PLANAR, DC, HOR or VER
        // however, if Luma ends up being one of those, the chroma dir must be later changed to DM_CHROMA.
        m_pcPredSearch->preestChromaPredMode( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth] );
      }
      m_pcPredSearch->estIntraPredQT( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth], resiLuma, uiPreCalcDistC, bSeparateLumaChroma DEBUG_STRING_PASS_INTO(sTest) );
    
      m_ppcRecoYuvTemp[uiDepth]->copyToPicComponent(COMPONENT_Y, rpcTempCU->getPic()->getPicYuvRec(), rpcTempCU->getAddr(), rpcTempCU->getZorderIdxInCU() );
    
      if (rpcBestCU->getPic()->getChromaFormat()!=CHROMA_400)
      {
        m_pcPredSearch->estIntraPredChromaQT( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth], resiLuma, uiPreCalcDistC DEBUG_STRING_PASS_INTO(sTest) );
      }
    
      m_pcEntropyCoder->resetBits();
    
      if ( rpcTempCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
      {
        m_pcEntropyCoder->encodeCUTransquantBypassFlag( rpcTempCU, 0,          true );
      }
    
      m_pcEntropyCoder->encodeSkipFlag ( rpcTempCU, 0,          true );
      m_pcEntropyCoder->encodePredMode( rpcTempCU, 0,          true );
      m_pcEntropyCoder->encodePartSize( rpcTempCU, 0, uiDepth, true );
      m_pcEntropyCoder->encodePredInfo( rpcTempCU, 0 );
      m_pcEntropyCoder->encodeIPCMInfo(rpcTempCU, 0, true );
    
      // Encode Coefficients
      Bool bCodeDQP = getdQPFlag();
      Bool codeChromaQpAdjFlag = getCodeChromaQpAdjFlag();
      m_pcEntropyCoder->encodeCoeff( rpcTempCU, 0, uiDepth, bCodeDQP, codeChromaQpAdjFlag );
      setCodeChromaQpAdjFlag( codeChromaQpAdjFlag );
      setdQPFlag( bCodeDQP );
    
      m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
    
      rpcTempCU->getTotalBits() = m_pcEntropyCoder->getNumberOfWrittenBits();
      rpcTempCU->getTotalBins() = ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
      rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
    
      xCheckDQP( rpcTempCU );
    
      cost = rpcTempCU->getTotalCost();
    
      xCheckBestMode(rpcBestCU, rpcTempCU, uiDepth DEBUG_STRING_PASS_INTO(sDebug) DEBUG_STRING_PASS_INTO(sTest));
    }

    4、PCM模式:

    /** Check R-D costs for a CU with PCM mode.
     * param rpcBestCU pointer to best mode CU data structure
     * param rpcTempCU pointer to testing mode CU data structure
     * 
    eturns Void
     *
     * 
    ote Current PCM implementation encodes sample values in a lossless way. The distortion of PCM mode CUs are zero. PCM mode is selected if the best mode yields bits greater than that of PCM mode.
     */
    Void TEncCu::xCheckIntraPCM( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU )
    {
      UInt uiDepth = rpcTempCU->getDepth( 0 );
    
      rpcTempCU->setSkipFlagSubParts( false, 0, uiDepth );
    
      rpcTempCU->setIPCMFlag(0, true);
      rpcTempCU->setIPCMFlagSubParts (true, 0, rpcTempCU->getDepth(0));
      rpcTempCU->setPartSizeSubParts( SIZE_2Nx2N, 0, uiDepth );
      rpcTempCU->setPredModeSubParts( MODE_INTRA, 0, uiDepth );
      rpcTempCU->setTrIdxSubParts ( 0, 0, uiDepth );
      rpcTempCU->setChromaQpAdjSubParts( rpcTempCU->getCUTransquantBypass(0) ? 0 : m_ChromaQpAdjIdc, 0, uiDepth );
    
      m_pcPredSearch->IPCMSearch( rpcTempCU, m_ppcOrigYuv[uiDepth], m_ppcPredYuvTemp[uiDepth], m_ppcResiYuvTemp[uiDepth], m_ppcRecoYuvTemp[uiDepth]);
    
      m_pcRDGoOnSbacCoder->load(m_pppcRDSbacCoder[uiDepth][CI_CURR_BEST]);
    
      m_pcEntropyCoder->resetBits();
    
      if ( rpcTempCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())
      {
        m_pcEntropyCoder->encodeCUTransquantBypassFlag( rpcTempCU, 0,          true );
      }
    
      m_pcEntropyCoder->encodeSkipFlag ( rpcTempCU, 0,          true );
      m_pcEntropyCoder->encodePredMode ( rpcTempCU, 0,          true );
      m_pcEntropyCoder->encodePartSize ( rpcTempCU, 0, uiDepth, true );
      m_pcEntropyCoder->encodeIPCMInfo ( rpcTempCU, 0, true );
    
      m_pcRDGoOnSbacCoder->store(m_pppcRDSbacCoder[uiDepth][CI_TEMP_BEST]);
    
      rpcTempCU->getTotalBits() = m_pcEntropyCoder->getNumberOfWrittenBits();
      rpcTempCU->getTotalBins() = ((TEncBinCABAC *)((TEncSbac*)m_pcEntropyCoder->m_pcEntropyCoderIf)->getEncBinIf())->getBinsCoded();
      rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
    
      xCheckDQP( rpcTempCU );
      DEBUG_STRING_NEW(a)
      DEBUG_STRING_NEW(b)
      xCheckBestMode(rpcBestCU, rpcTempCU, uiDepth DEBUG_STRING_PASS_INTO(a) DEBUG_STRING_PASS_INTO(b));
    }
  • 相关阅读:
    设计模式之桥接模式
    设计模式之适配器模式
    设计模式之建造者模式
    设计模式之原型设计
    Exception in thread "main" java.lang.UnsupportedOperationException
    设计模式7大原则
    设计模式之单例模式
    初识python
    消息传递:发布订阅模式详解
    哨兵机制(Redis Sentinel)
  • 原文地址:https://www.cnblogs.com/lucifer1997/p/10974275.html
Copyright © 2020-2023  润新知