VTM3.0代码阅读:estIntraPredLumaQT函数

本文详细探讨了HEVC编码中estIntraPredLumaQT函数的作用,该函数用于帧内亮度模式的预测,通过计算不同角度模式的SATD并结合MRL和MPM策略,最终使用RDO选择最佳模式。
摘要由CSDN通过智能技术生成

estIntraPredLumaQT进行帧内亮度模式的预测,在67种帧内亮度模式中,获取帧内亮度模式的最优模式。
首先进行SATD粗选择,对HEVC中的35种角度模式进行SATD选择;
再分别对SATD所选择的角度模式的左右两种角度模式(即模式号±1),进行再一次的SATD;
然后进行MRL模式的检测;
再添加亮度的MPM模式;
最后对列表中的帧内亮度模式进行RDO,分别调用xRecurIntraCodingLumaQT函数,选择最优帧内亮度模式。

void IntraSearch::estIntraPredLumaQT( CodingUnit &cu, Partitioner &partitioner )
{
   
  CodingStructure       &cs            = *cu.cs;
  const SPS             &sps           = *cs.sps;
  const uint32_t             uiWidthBit    = cs.pcv->rectCUs ? g_aucLog2[partitioner.currArea().lwidth() ] : CU::getIntraSizeIdx(cu);
  const uint32_t             uiHeightBit   =                   g_aucLog2[partitioner.currArea().lheight()];

  // Lambda calculation at equivalent Qp of 4 is recommended because at that Qp, the quantization divisor is 1.
  const double sqrtLambdaForFirstPass = m_pcRdCost->getMotionLambda(cu.transQuantBypass) / double(1 << SCALE_BITS);


  //===== loop over partitions =====

  const TempCtx ctxStart          ( m_CtxCache, m_CABACEstimator->getCtx() );
  const TempCtx ctxStartIntraMode ( m_CtxCache, SubCtx( Ctx::IPredMode[CHANNEL_TYPE_LUMA],        m_CABACEstimator->getCtx() ) );
#if JVET_L0100_MULTI_HYPOTHESIS_INTRA
  const TempCtx ctxStartMHIntraMode ( m_CtxCache, SubCtx( Ctx::MHIntraPredMode,        m_CABACEstimator->getCtx() ) );
#endif
#if JVET_L0283_MULTI_REF_LINE
  const TempCtx ctxStartMrlIdx      ( m_CtxCache, SubCtx( Ctx::MultiRefLineIdx,        m_CABACEstimator->getCtx() ) );
#endif

  CHECK( !cu.firstPU, "CU has no PUs" );
  const bool keepResi   = cs.pps->getPpsRangeExtension().getCrossComponentPredictionEnabledFlag() || KEEP_PRED_AND_RESI_SIGNALS;


  uint32_t extraModes = 0; // add two extra modes, which would be used after uiMode <= DC_IDX is removed for cu.nsstIdx == 3


  const int width   = partitioner.currArea().lwidth();
  const int height  = partitioner.currArea().lheight();

  // Marking EMT usage for faster EMT
  // 0: EMT is either not applicable for current CU (cuWidth > EMT_INTRA_MAX_CU or cuHeight > EMT_INTRA_MAX_CU), not active in the config file or the fast decision algorithm is not used in this case
  // 1: EMT fast algorithm can be applied for the current CU, and the DCT2 is being checked
  // 2: EMT is being checked for current CU. Stored results of DCT2 can be utilized for speedup
  uint8_t emtUsageFlag = 0;
  const int maxSizeEMT = cs.pcv->noRQT ? EMT_INTRA_MAX_CU_WITH_QTBT : EMT_INTRA_MAX_CU;
  if( width <= maxSizeEMT && height <= maxSizeEMT && sps.getSpsNext().getUseIntraEMT() )
  {
   
    emtUsageFlag = cu.emtFlag == 1 ? 2 : 1;
  }

  bool isAllIntra = m_pcEncCfg->getIntraPeriod() == 1;

  if( cs.pcv->rectCUs )
  {
   
    if( width * height < 64 && !isAllIntra )
    {
   
      emtUsageFlag = 0; //this forces the recalculation of the candidates list. Why is this necessary? (to be checked)
    }
  }

  static_vector<uint32_t,   FAST_UDI_MAX_RDMODE_NUM> uiHadModeList;
  static_vector<double, FAST_UDI_MAX_RDMODE_NUM> CandCostList;
  static_vector<double, FAST_UDI_MAX_RDMODE_NUM> CandHadList;

#if JVET_L0283_MULTI_REF_LINE
  static_vector<int, FAST_UDI_MAX_RDMODE_NUM> extendRefList;	//MRL
  static_vector<int, FAST_UDI_MAX_RDMODE_NUM>* nullList = NULL;
#endif

  auto &pu = *cu.firstPU;
  int puIndex = 0;
  {
   
    CandHadList.clear();
    CandCostList.clear();
    uiHadModeList.clear();
#if JVET_L0283_MULTI_REF_LINE
    extendRefList.clear();
#endif

    CHECK(pu.cu != &cu, "PU is not contained in the CU");	/以上为各种数据的初始化

    //===== determine set of modes to be tested (using prediction signal only) =====
    int numModesAvailable = NUM_LUMA_MODE; // total number of Intra modes	 67种帧内模式
    static_vector< uint32_t, FAST_UDI_MAX_RDMODE_NUM > uiRdModeList;

    int numModesForFullRD = 3;		//numModesForFullRD为最后进行帧内模式RDO的模式数
    if( cs.pcv->rectCUs )
    {
   
      numModesForFullRD = g_aucIntraModeNumFast_UseMPM_2D[uiWidthBit - MIN_CU_LOG2][uiHeightBit - MIN_CU_LOG2];
    }
    else
    {
   
      numModesForFullRD = m_pcEncCfg->getFastUDIUseMPMEnabled() ? g_aucIntraModeNumFast_UseMPM[uiWidthBit] : g_aucIntraModeNumFast_NotUseMPM[uiWidthBit];
      numModesForFullRD -= 1;
    }

#if INTRA_FULL_SEARCH
    numModesForFullRD = numModesAvailable;
#endif


    if( emtUsageFlag != 2 )	
    {
   
      // this should always be true			一般均为true
      CHECK( !pu.Y().valid(), "PU is not valid" );
#if JVET_L0283_MULTI_REF_LINE
      bool isFirstLineOfCtu = (
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值