VTM1.0代码阅读:estIntraPredChromaQT函数

estIntraPredChromaQT函数在xCheckRDCostIntra中被调用,以获取最优的色度帧内模式。
getIntraChromaCandModes调用getIntraChromaCandModes函数得到色度的5个候选模式,5个候选通过RDO选取最优色度帧内模式。

Void IntraSearch::estIntraPredChromaQT(CodingUnit &cu, Partitioner &partitioner)
{
  const ChromaFormat format   = cu.chromaFormat;

  const UInt    numberValidComponents = getNumberValidComponents(format);
  CodingStructure &cs = *cu.cs;
  const TempCtx ctxStart  ( m_CtxCache, m_CABACEstimator->getCtx() );

  cs.setDecomp( cs.area.Cb(), false );


  auto &pu = *cu.firstPU;

  {

    UInt       uiBestMode = 0;
    Distortion uiBestDist = 0;
    Double     dBestCost = MAX_DOUBLE;

    //----- init mode list ----
    {
      UInt  uiMinMode = 0;
      UInt  uiMaxMode = NUM_CHROMA_MODE;	//5

      //----- check chroma modes -----
      UInt chromaCandModes[ NUM_CHROMA_MODE ];
      PU::getIntraChromaCandModes( pu, chromaCandModes );	//得到5个色度候选模式

      // create a temporary CS
      CodingStructure &saveCS = *m_pSaveCS[0];		//saveCS用于存储RDO过程中最优模式的数据
      saveCS.pcv      = cs.pcv;
      saveCS.picture  = cs.picture;
      saveCS.area.repositionTo( cs.area );
      saveCS.clearTUs();

      if( CS::isDualITree( cs ) )
      {
#if ENABLE_BMS
        if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )	//当前cu是否可以划分为多个tu来处理
        {
          partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );

          do
          {
            cs.addTU( CS::getArea( cs, partitioner.currArea(), partitioner.chType ), partitioner.chType ).depth = partitioner.currTrDepth;
          } while( partitioner.nextPart( cs ) );

          partitioner.exitCurrSplit();
        }
        else
#endif
        cs.addTU( CS::getArea( cs, partitioner.currArea(), partitioner.chType ), partitioner.chType );	//cu和tu大小一样,没划分
      }

      std::vector<TransformUnit*> orgTUs;	


      // create a store for the TUs
      for( const auto &ptu : cs.tus )
      {
        // for split TUs in HEVC, add the TUs without Chroma parts for correct setting of Cbfs
        if( pu.contains( *ptu, CHANNEL_TYPE_CHROMA ) || ( !cs.pcv->noRQT && !ptu->Cb().valid() && !ptu->Cr().valid() ) )
        {
          saveCS.addTU( *ptu, partitioner.chType );
          orgTUs.push_back( ptu );								//orgTUs中就是cs的tu
        }
      }

      // save the dist
      Distortion baseDist = cs.dist;

      for (UInt uiMode = uiMinMode; uiMode < uiMaxMode; uiMode++)	//对5个色度候选模式RDO选最优
      {
        const int chromaIntraMode = chromaCandModes[uiMode];

        cs.setDecomp( pu.Cb(), false );
        cs.dist = baseDist;
        //----- restore context models -----
        m_CABACEstimator->getCtx() = ctxStart;

        //----- chroma coding -----
        pu.intraDir[1] = chromaIntraMode;

        xRecurIntraChromaCodingQT( cs, partitioner );		//预测得到各色度模式的pred像素,从而得到残差,经过变换反变换得到reco像素	
															//由orig和reco,得到失真,从而得到cost
        if (cs.pps->getUseTransformSkip())
        {
          m_CABACEstimator->getCtx() = ctxStart;
        }

        UInt64 fracBits   = xGetIntraFracBitsQT( cs, partitioner, false, true );		//编码比特数
        Distortion uiDist = cs.dist;
        Double    dCost   = m_pcRdCost->calcRdCost( fracBits, uiDist - baseDist );		//cost

        //----- compare -----
        if( dCost < dBestCost )		//将最优模式数据存入saveCS,包括reco、pred、resi像素和tu信息
        {
          for( UInt i = getFirstComponentOfChannel( CHANNEL_TYPE_CHROMA ); i < numberValidComponents; i++ )
          {
            const CompArea &area = pu.blocks[i];

            saveCS.getRecoBuf     ( area ).copyFrom( cs.getRecoBuf   ( area ) );
#if KEEP_PRED_AND_RESI_SIGNALS
            saveCS.getPredBuf     ( area ).copyFrom( cs.getPredBuf   ( area ) );
            saveCS.getResiBuf     ( area ).copyFrom( cs.getResiBuf   ( area ) );
#endif
            cs.picture->getRecoBuf( area ).copyFrom( cs.getRecoBuf( area ) );

            for( UInt j = 0; j < saveCS.tus.size(); j++ )
            {
              saveCS.tus[j]->copyComponentFrom( *orgTUs[j], area.compID );		//将最优的tu信息存入saveCS
#if ENABLE_CHROMA_422
              if( cs.pcv->multiBlock422 )
              {
                saveCS.tus[ j ]->copyComponentFrom( *orgTUs[ j ], ComponentID( area.compID + SCND_TBLOCK_OFFSET ) );
              }
#endif
            }
          }

          dBestCost  = dCost;				//更新记录最优的失真cost和色度模式
          uiBestDist = uiDist;
          uiBestMode = chromaIntraMode;
        }
      }
					//将saveCS中存储的最优色度模式相关信息,copy到cs中去,即xCheckRDCostIntra函数中的tempCS
      for( UInt i = getFirstComponentOfChannel( CHANNEL_TYPE_CHROMA ); i < numberValidComponents; i++ )
      {
        const CompArea &area = pu.blocks[i];

        cs.getRecoBuf         ( area ).copyFrom( saveCS.getRecoBuf( area ) );	//将saveCS最优信息copy给cs

        cs.picture->getRecoBuf( area ).copyFrom( cs.    getRecoBuf( area ) );

        for( UInt j = 0; j < saveCS.tus.size(); j++ )
        {
          orgTUs[ j ]->copyComponentFrom( *saveCS.tus[ j ], area.compID );

        }
      }
    }

    pu.intraDir[1] = uiBestMode;
    cs.dist        = uiBestDist;

  }
  
  //----- restore context models -----
  m_CABACEstimator->getCtx() = ctxStart;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值