VTM xCheckRDCostIntra---estIntraPredLumaQT

xCompressCU

  // 以下 do 循环开始遍历 m_ComprCUCtxList 中的测试模式(划分、模式、QP)
  do
  {
    // 遍历分量,将 PLT 的相关变量填充
    for (int i = compBegin; i < (compBegin + numComp); i++)
    {
    }
    // 当前测试模式
    EncTestMode currTestMode = m_modeCtrl->currTestMode();
    // 当前测试模式的允许最大 cost
    currTestMode.maxCostAllowed = maxCostAllowed;

    // 若使用 DQP 且是 SepTree 且当前为色度分量
    if (pps.getUseDQP() && partitioner.isSepTree(*tempCS) && isChroma( partitioner.chType ))
    {
      // 若对应亮度位置存在,则当前测试模式 QP 值设定为对应 bestCS 亮度位置的 QP 值
      if (colLumaCu)
      {
        currTestMode.qp = colLumaCu->qp;
      }
    }
    // 若当前 QG 可用,且使用亮度 delta QP 映射或(使用 perceptQPA,且不使用 rate control,且使用DQP) 
    if (partitioner.currQgEnable() && (.....
      // 若当前测试模式的 QP 值有效,则更新 lambda
    {
      if (currTestMode.qp >= 0)
      {
        updateLambda (&slice, currTestMode.qp,
                      m_pcEncCfg->getWCGChromaQPControl().isEnabled(),
                      CS::isDualITree (*tempCS) || (partitioner.currDepth == 0));
      }
    }
    // 若当前测试模式是 INTER
    if( currTestMode.type == ETM_INTER_ME )
    {
      tempCS->bestCS = bestCS;
      xCheckRDCostInterIMV(tempCS, bestCS, partitioner, currTestMode, bestIntPelCost);
      tempCS->bestCS = nullptr;
    }
    // 若当前测试模式是 HASH INTER,则检查 HashInter 的 RD cost
    else if (currTestMode.type == ETM_HASH_INTER)
    {
      xCheckRDCostHashInter( tempCS, bestCS, partitioner, currTestMode );
    }
    // 若当前测试模式是 AFFINE,则检查 Affine 的 RD cost
    else if( currTestMode.type == ETM_AFFINE )
    {
      xCheckRDCostAffineMerge2Nx2N( tempCS, bestCS, partitioner, currTestMode );
    }
    // 若当前测试模式是 RECO_CACHED,则检查 Reuse Cached 的 RD cost
    else if( currTestMode.type == ETM_RECO_CACHED )
    {
      xReuseCachedResult( tempCS, bestCS, partitioner );
    }
    // 若当前测试模式是 MERGE_SKIP,则检查 Merge 的 RD cost
    else if( currTestMode.type == ETM_MERGE_SKIP )
    {
      xCheckRDCostMerge2Nx2N( tempCS, bestCS, partitioner, currTestMode );
      CodingUnit* cu = bestCS->getCU(partitioner.chType);
      // 若 bestCS 的 cu 不使用 skip,则不使用 mmvd(Merge mode with MVD)
      if (cu)
      cu->mmvdSkip = cu->skip == false ? false : cu->mmvdSkip;
    }
    // 若当前测试模式是 MERGE_GEO,则检查 Merge Geo 的 RD cost
    else if( currTestMode.type == ETM_MERGE_GEO )
    {
      xCheckRDCostMergeGeo2Nx2N( tempCS, bestCS, partitioner, currTestMode );
    }
    // 若当前测试模式是 INTRA
    else if( currTestMode.type == ETM_INTRA )
    {
      xCheckRDCostIntra(tempCS, bestCS, partitioner, currTestMode, false);
    }
    // 若当前测试模式是 PALETTE,则检查 PLT 的 RD cost
    else if (currTestMode.type == ETM_PALETTE)
    {
      xCheckPLT( tempCS, bestCS, partitioner, currTestMode );
    }
    // 若当前测试模式是 IBC(Intra block copy),则检查 IBC 的 RD cost
    else if (currTestMode.type == ETM_IBC)
    {
      xCheckRDCostIBCMode(tempCS, bestCS, partitioner, currTestMode);
    }
    // 若当前测试模式是 IBC_MERGE,则检查 IBC_MERGE 的 RD cost
    else if (currTestMode.type == ETM_IBC_MERGE)
    {
      xCheckRDCostIBCModeMerge2Nx2N(tempCS, bestCS, partitioner, currTestMode);
    }
    // 若当前测试模式划分模式(ETM_SPLIT_QT、ETM_SPLIT_BT_H、ETM_SPLIT_BT_V、ETM_SPLIT_TT_H、ETM_SPLIT_TT_V)
    else if( isModeSplit( currTestMode ) )

xCheckRDCostIntra

void EncCu::xCheckRDCostIntra( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode )
{
  for( uint8_t emtCuFlag = 0; emtCuFlag <= considerEmtSecondPass; emtCuFlag++ )
  {
    tempCS->initStructData( encTestMode.qp, encTestMode.lossless );		//tempCS清空初始化

    CodingUnit &cu      = tempCS->addCU( CS::getArea( *tempCS, tempCS->area, partitioner.chType ), partitioner.chType );
	//tempCS添加cu,初始化cu,用于帧内预测
    partitioner.setCUData( cu );
    cu.slice            = tempCS->slice;
    cu.tileIdx          = tempCS->picture->tileMap->getTileIdxMap( tempCS->area.lumaPos() );
    cu.skip             = false;
    cu.partSize         = encTestMode.partSize;
    cu.predMode         = MODE_INTRA;

    CU::addPUs( cu );				//cu添加pu

    tempCS->interHad    = interHad;
//1.亮度帧内预测
    if( isLuma( partitioner.chType ) )
    {
      m_pcIntraSearch->estIntraPredLumaQT( cu, partitioner );//亮度帧内预测
      // cu.firstPU

      if (m_pcEncCfg->getUsePbIntraFast() && tempCS->dist == std::numeric_limits<Distortion>::max()
          && tempCS->interHad == 0)
      {
        interHad = 0;
        // JEM assumes only perfect reconstructions can from now on beat the inter mode
        m_modeCtrl->enforceInterHad( 0 );
        continue;
      }

      if( !CS::isDualITree( *tempCS ) )		//I帧且亮度色度不同划分时isDualITree为true
      {
        cu.cs->picture->getRecoBuf( cu.Y() ).copyFrom( cu.cs->getRecoBuf( COMPONENT_Y ) );
      }
    }
	//注意:这里是!CS::isDualITree( *tempCS )
//2.色度帧内预测
    if( tempCS->area.chromaFormat != CHROMA_400 && ( partitioner.chType == CHANNEL_TYPE_CHROMA || !CS::isDualITree( *tempCS ) ) )
    {
      m_pcIntraSearch->estIntraPredChromaQT( cu, partitioner );		//色度帧内预测
    }

    cu.rootCbf = false;

    for( uint32_t t = 0; t < getNumberValidTBlocks( *cu.cs->pcv ); t++ )
    {
      cu.rootCbf |= cu.firstTU->cbf[t] != 0;
    }

// 3.接下来计算编码比特数和失真,计算cost
    m_CABACEstimator->resetBits();

    if( pps.getTransquantBypassEnabledFlag() )
    {
      m_CABACEstimator->cu_transquant_bypass_flag( cu );
    }

    if( !cu.cs->slice->isIntra() && cu.Y().valid())
    {
      m_CABACEstimator->cu_skip_flag ( cu );
    }
    m_CABACEstimator->pred_mode      ( cu );
#if JVET_L0283_MULTI_REF_LINE
    m_CABACEstimator->extend_ref_line( cu );
#endif
    m_CABACEstimator->cu_pred_data   ( cu );
    m_CABACEstimator->pcm_data       ( cu );

    // Encode Coefficients
    CUCtx cuCtx;
    cuCtx.isDQPCoded = true;
    cuCtx.isChromaQpAdjCoded = true;
    m_CABACEstimator->cu_residual( cu, partitioner, cuCtx );			//失真
    tempCS->fracBits = m_CABACEstimator->getEstFracBits();				//比特数
    tempCS->cost     = m_pcRdCost->calcRdCost(tempCS->fracBits, tempCS->dist);	//cost

    xEncodeDontSplit( *tempCS, partitioner );
    xCheckDQP( *tempCS, partitioner );
    // we save the cost of the modes for the first EMT pass
    if( !emtCuFlag ) static_cast< double& >( cu.partSize == SIZE_2Nx2N ? costSize2Nx2NemtFirstPass : costSizeNxNemtFirstPass ) = tempCS->cost;
    DTRACE_MODE_COST( *tempCS, m_pcRdCost->getLambda( true ) );
    DTRACE_MODE_COST( *tempCS, m_pcRdCost->getLambda() );
    xCheckBestMode( tempCS, bestCS, partitioner, encTestMode );		
    //将帧内最优模式的cost与bestCS的cost对比   //将最优模式存入bestCS

    //now we check whether the second pass of SIZE_2Nx2N and the whole Intra SIZE_NxN should be skipped or not
    if( !emtCuFlag && !tempCS->slice->isIntra() && bestCU && bestCU->predMode != MODE_INTRA && cu.partSize == SIZE_2Nx2N && m_pcEncCfg->getFastInterEMT() )
    {
    }
  } //for emtCuFlag
}

estIntraPredLumaQT


/******** 进入最终对RD候选列表中的模式进一步精选RDcost ********/
    //遍历RD候选列表
    for (int mode = isSecondColorSpace ? 0 : -2 * int(testBDPCM); mode < (int)uiRdModeList.size(); mode++)
    {
......
 // Mode loop RD候选模式的循环遍历结束,选出最优模式, 设置最优模式
//当前候选模式是否是ISP
cu.ispMode  = uiOrgMode.ispMod;
//定义当前PU最优的亮度帧内预测模式
ModeInfo    uiBestPUMode;
......
    cu.ispMode = uiBestPUMode.ispMod;
    cu.lfnstIdx = bestLfnstIdx;

    if( validReturn )
    {
      //如果色彩转换
      if (cu.colorTransform)
      {
        cs.useSubStructure(*csBest, partitioner.chType, pu, true, true, KEEP_PRED_AND_RESI_SIGNALS, KEEP_PRED_AND_RESI_SIGNALS, true);
      }
      else
      {
        cs.useSubStructure(*csBest, partitioner.chType, pu.singleChan(CHANNEL_TYPE_LUMA), true, true, KEEP_PRED_AND_RESI_SIGNALS,
                           KEEP_PRED_AND_RESI_SIGNALS, true);
      }
    }
    csBest->releaseIntermediateData();
    if( validReturn )
    {
      //=== update PU data ==== 
      //更新PU数据
      //auto &pu = *cu.firstPU;
      cu.mipFlag = uiBestPUMode.mipFlg;
      pu.mipTransposedFlag             = uiBestPUMode.mipTrFlg;
      pu.multiRefIdx = uiBestPUMode.mRefId;
      pu.intraDir[ CHANNEL_TYPE_LUMA ] = uiBestPUMode.modeId;
      //pu.intraDir[]=
      cu.bdpcmMode = bestBDPCMMode;
      if (cu.colorTransform)
      {
        CHECK(pu.intraDir[CHANNEL_TYPE_CHROMA] != DM_CHROMA_IDX, "chroma should use DM mode for adaptive color transform");
      }
    }
  }

  //===== reset context models =====
  //重置上下文模型
  m_CABACEstimator->getCtx() = ctxStart;
  //bool validReturn = false;
  //validReturn |= tmpValidReturn;
  return validReturn;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值