VTM3.0代码阅读:xRecurIntraChromaCodingQT函数

xRecurIntraChromaCodingQT在estIntraPredChromaQT函数中被调用,用来计算每个帧内色度预测模式时的cost。
流程:
首先判断tu是否需要划分,若tu划分时,对每个划分出的小tu递归调用本函数,计算每个小tu的在chromaIntra模式下的最优的cost,最后求和;
如果tu不划分,分别对Cb和Cr通道进行处理。对于每个通道,是/否TS模式+是/否跨组件预测可以构成4种模式,分别对4种模式调用xIntraCodingTUBlock函数进行预测变换量化反量化反变换,得到reco像素和cost,按照cost选取TU的最优模式。选择的最优cost即当前test的chromaIntra模式的最优的cost。

本函数和VTM1中没有太大区别:
VTM1.0代码阅读:xRecurIntraChromaCodingQT函数
函数中调用的xIntraCodingTUBlock函数在帧内亮度预测时已经看过:
VTM3.0代码阅读:xIntraCodingTUBlock函数

ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT(CodingStructure &cs, Partitioner& partitioner)
{
  UnitArea currArea                   = partitioner.currArea();
  const bool keepResi                 = cs.sps->getSpsNext().getUseLMChroma() || KEEP_PRED_AND_RESI_SIGNALS;
  if( !currArea.Cb().valid() ) return ChromaCbfs( false );

													//色度tu、色度pu、lumaTU
  TransformUnit &currTU               = *cs.getTU( currArea.chromaPos(), CHANNEL_TYPE_CHROMA );
  const PredictionUnit &pu            = *cs.getPU( currArea.chromaPos(), CHANNEL_TYPE_CHROMA );
  const TransformUnit &currTULuma     = CS::isDualITree( cs ) ? *cs.picture->cs->getTU( currArea.lumaPos(), CHANNEL_TYPE_LUMA ) : currTU;
						//CS::isDualITree()为true时,亮度和色度域有不同的划分树,就必须特别的getLumaTU;如果不是DualITree,直接用currTU
  
  uint32_t     currDepth              = partitioner.currTrDepth;	//tu的划分深度
  const PPS &pps                      = *cs.pps;
  ChromaCbfs cbfs                     ( false );

  if (currDepth == currTU.depth)		//tu划分深度已达到partitioner.currTrDepth,不再划分
  {
    if (!currArea.Cb().valid() || !currArea.Cr().valid())	//Cb/Cr分量可用
    {
      return cbfs;
    }

    bool checkTransformSkip = pps.getUseTransformSkip();	//Cb是否TS模式
    checkTransformSkip &= TU::hasTransformSkipFlag( *currTU.cs, partitioner.currArea().Cb() );

    if( m_pcEncCfg->getUseTransformSkipFast() )			//Y的TS模式
    {
      checkTransformSkip &= TU::hasTransformSkipFlag( *currTU.cs, partitioner.currArea().Y() );

      if( checkTransformSkip && cs.pcv->noChroma2x2 )
      {
        int nbLumaSkip = currTULuma.transformSkip[0] ? 1 : 0;

        {
          // the chroma blocks are co-located with the last luma block, so backwards references are needed
          nbLumaSkip += cs.getTU( currTULuma.Y().topLeft().offset( -1,  0 ), partitioner.chType )->transformSkip[0] ? 1 : 0;
          nbLumaSkip += cs.getTU( currTULuma.Y().topLeft().offset( -1, -1 ), partitioner.chType )->transformSkip[0] ? 1 : 0;
          nbLumaSkip += cs.getTU( currTULuma.Y().topLeft().offset(  0, -1 ), partitioner.chType )->transformSkip[0] ? 1 : 0;
        }

        checkTransformSkip &= ( nbLumaSkip > 0 );
      }
    }

    CodingStructure &saveCS = *m_pSaveCS[1];		//saveCS保存临时数据
    saveCS.pcv      = cs.pcv;
    saveCS.picture  = cs.picture;
    saveCS.area.repositionTo( cs.area );
    saveCS.initStructData( -1, false, true );

    TransformUnit &tmpTU = saveCS.addTU(currArea, partitioner.chType);	//saveCS的tmpTU保存临时tu数据


    cs.setDecomp(currArea.Cb(), true); // set in advance (required for Cb2/Cr2 in 4:2:2 video)

    const unsigned      numTBlocks  = ::getNumberValidTBlocks( *cs.pcv );	//4:0:0采样为1,其它为3

    for( uint32_t c = COMPONENT_Cb; c < numTBlocks; c++)	//Cb、Cr两个通道分别计算最优模式及最优模式下的信息
    {
      const ComponentID compID  = ComponentID(c);
      const CompArea&   area    = currTU.blocks[compID];

      double     dSingleCost    = MAX_DOUBLE;	//保存最优cost等信息
      int        bestModeId     = 0;		//最优变换预测模式的模式idx
      Distortion singleDistC    = 0;
      Distortion singleDistCTmp = 0;
      double     singleCostTmp  = 0;		//临时的失真和cost
																	//跨组件预测CCLM
      const bool checkCrossComponentPrediction = PU::isChromaIntraModeCrossCheckMode( pu ) && pps.getPpsRangeExtension().getCrossComponentPredictionEnabledFlag() && TU::getCbf( currTU, COMPONENT_Y );

      const int  crossCPredictionModesToTest = checkCrossComponentPrediction ? 2 : 1;	//跨组件预测
      const int  transformSkipModesToTest    = checkTransformSkip ? 2 : 1;				//TransformSkip模式
      const int  totalModesToTest            = crossCPredictionModesToTest * transformSkipModesToTest;	//总的test模式数
      const bool isOneMode                   = (totalModesToTest == 1);

      int currModeId = 0;
      int default0Save1Load2 = 0;

      TempCtx ctxStart  ( m_CtxCache );
      TempCtx ctxBest   ( m_CtxCache );

      if (!isOneMode)
      {
        ctxStart = m_CABACEstimator->getCtx();		//保存上下文模型
      }
													//是/否TS模式 + 是/否跨组件预测,最多构成4种模式
      for (int transformSkipModeId = 0; transformSkipModeId < transformSkipModesToTest; transformSkipModeId++)	//是/否TransformSkip模式
      {
        for (int crossCPredictionModeId = 0; crossCPredictionModeId < crossCPredictionModesToTest; crossCPredictionModeId++)	//是/否跨组件预测模式CCLM
        {
          currTU.compAlpha    [compID] = 0;
          currTU.transformSkip[compID] = transformSkipModeId;

          currModeId++;

          const bool isFirstMode = (currModeId == 1);							
          const bool isLastMode  = (currModeId == totalModesToTest); // currModeId is indexed from 1 //是否为最后一个需要test的模式

          if (isOneMode)		//如果只有一个模式
          {
            default0Save1Load2 = 0;
          }
          else if (!isOneMode && (transformSkipModeId == 0) && (crossCPredictionModeId == 0))
          {						//当前为第一个test的模式,并且之后还有需要test的模式
            default0Save1Load2 = 1; //save prediction on first mode	//此时下面的xIntraCodingTUBlock函数中需要保存预测像素
          }
          else					//有多个test的模式,并且当期已经不是第一个模式
          {
            default0Save1Load2 = 2; //load it on subsequent modes	//此时下面的xIntraCodingTUBlock函数中预测像素,用上面保存的
          }

          if (!isFirstMode) // if not first mode to be tested
          {
            m_CABACEstimator->getCtx() = ctxStart;
          }

          singleDistCTmp = 0;
								//当前tu采用currModeId号变换模式,然后按照本函数要计算的chromaIntra模式,进行帧内预测变换量化反量化反变换
								//从而得到reco像素,计算得到失真singleDistCTmp,返回
          xIntraCodingTUBlock( currTU, compID, crossCPredictionModeId != 0, singleDistCTmp, default0Save1Load2 );

          if( ( ( crossCPredictionModeId == 1 ) && ( currTU.compAlpha[compID] == 0 ) ) || ( ( transformSkipModeId == 1 ) && !TU::getCbf( currTU, compID ) ) ) //In order not to code TS flag when cbf is zero, the case for TS with cbf being zero is forbidden.
          {									//为了在cbf为0时不对transformSkip标志进行编码,cbf为0时的TS模式被禁止
            singleCostTmp = MAX_DOUBLE;		//cost设为最大,不会选上TS模式,即禁止
          }
          else if( !isOneMode )
          {									//如果不只一个test模式,由上面的失真,得到cost
            uint64_t fracBitsTmp = xGetIntraFracBitsQTChroma( currTU, compID );
            singleCostTmp = m_pcRdCost->calcRdCost( fracBitsTmp, singleDistCTmp );
          }

          if( singleCostTmp < dSingleCost )		//当前test模式为最优时,保存最优信息
          {
            dSingleCost = singleCostTmp;
            singleDistC = singleDistCTmp;
            bestModeId  = currModeId;

            if( !isLastMode )				//如果不是最后一个test的模式
            {
#if KEEP_PRED_AND_RESI_SIGNALS
              saveCS.getPredBuf   (area).copyFrom(cs.getPredBuf   (area));
              saveCS.getOrgResiBuf(area).copyFrom(cs.getOrgResiBuf(area));
#endif
              if( keepResi )			//保存resi、reco像素信息
              {
                saveCS.getResiBuf (area).copyFrom(cs.getResiBuf   (area));
              }
              saveCS.getRecoBuf   (area).copyFrom(cs.getRecoBuf   (area));

              tmpTU.copyComponentFrom(currTU, compID); //saveCS中的tmpTU拷贝tu的信息

              ctxBest = m_CABACEstimator->getCtx();		//最优上下文模型
            }
          }
        }
      }		// loop结束

      if (bestModeId < totalModesToTest)	//将最优的信息由saveCS拷贝给cs
      {
#if KEEP_PRED_AND_RESI_SIGNALS
        cs.getPredBuf   (area).copyFrom(saveCS.getPredBuf   (area));	//resi、reco、tu、ctxBest等信息
        cs.getOrgResiBuf(area).copyFrom(saveCS.getOrgResiBuf(area));
#endif
        if( keepResi )
        {
          cs.getResiBuf (area).copyFrom(saveCS.getResiBuf   (area));
        }
        cs.getRecoBuf   (area).copyFrom(saveCS.getRecoBuf   (area));

        currTU.copyComponentFrom(tmpTU, compID);

        m_CABACEstimator->getCtx() = ctxBest;
      }

      cs.picture->getRecoBuf(area).copyFrom(cs.getRecoBuf(area));	//reco像素保存到picture

      cbfs.cbf(compID) = TU::getCbf(currTU, compID);

      cs.dist += singleDistC; 	//单通道的失真加到cs的失真上。在下面的TU划分递归调用的情况时会用到
	  
    } Cb/Cr两个通道loop结束
  }
  else							//tu划分深度还未达到partitioner.currTrDepth,继续划分
  {
    unsigned    numValidTBlocks   = ::getNumberValidTBlocks( *cs.pcv );
    ChromaCbfs  SplitCbfs         ( false );

    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
    {
      partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );		//当前tu划分为小tu
    }
    else
      THROW( "Implicit TU split not available" );
			//do-while循环对每个划分的小tu递归调用本函数进行处理,得到每个小tu在Cb/Cr通道的最优模式信息和reco和cost
    do
    {
      ChromaCbfs subCbfs = xRecurIntraChromaCodingQT( cs, partitioner );	//xRecurIntraChromaCodingQT

      for( uint32_t ch = COMPONENT_Cb; ch < numValidTBlocks; ch++ )
      {
        const ComponentID compID = ComponentID( ch );
        SplitCbfs.cbf( compID ) |= subCbfs.cbf( compID );
      }
    } while( partitioner.nextPart( cs ) );

    partitioner.exitCurrSplit();

    {

      cbfs.Cb |= SplitCbfs.Cb;
      cbfs.Cr |= SplitCbfs.Cr;

      for( auto &ptu : cs.tus )			//对每个划分的小tu,设置cbf
      {
        if( currArea.Cb().contains( ptu->Cb() ) || ( !ptu->Cb().valid() && currArea.Y().contains( ptu->Y() ) ) )
        {
          TU::setCbfAtDepth( *ptu, COMPONENT_Cb, currDepth, SplitCbfs.Cb );
          TU::setCbfAtDepth( *ptu, COMPONENT_Cr, currDepth, SplitCbfs.Cr );
        }
      }
    }
  }

  return cbfs;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
智慧校园整体解决方案是响应国家教育信息化政策,结合教育改革和技术创新的产物。该方案以物联网、大数据、人工智能和移动互联技术为基础,旨在打造一个安全、高效、互动且环保的教育环境。方案强调从数字化校园向智慧校园的转变,通过自动数据采集、智能分析和按需服务,实现校园业务的智能化管理。 方案的总体设计原则包括应用至上、分层设计和互联互通,确保系统能够满足不同用户角色的需求,并实现数据和资源的整合与共享。框架设计涵盖了校园安全、管理、教学、环境等多个方面,构建了一个全面的校园应用生态系统。这包括智慧安全系统、校园身份识别、智能排课及选课系统、智慧学习系统、精品录播教室方案等,以支持个性化学习和教学评估。 建设内容突出了智慧安全和智慧管理的重要性。智慧安全管理通过分布式录播系统和紧急预案一键启动功能,增强校园安全预警和事件响应能力。智慧管理系统则利用物联网技术,实现人员和设备的智能管理,提高校园运营效率。 智慧教学部分,方案提供了智慧学习系统和精品录播教室方案,支持专业级学习硬件和智能化网络管理,促进个性化学习和教学资源的高效利用。同时,教学质量评估中心和资源应用平台的建设,旨在提升教学评估的科学性和教育资源的共享性。 智慧环境建设则侧重于基于物联网的设备管理,通过智慧教室管理系统实现教室环境的智能控制和能效管理,打造绿色、节能的校园环境。电子班牌和校园信息发布系统的建设,将作为智慧校园的核心和入口,提供教务、一卡通、图书馆等系统的集成信息。 总体而言,智慧校园整体解决方案通过集成先进技术,不仅提升了校园的信息化水平,而且优化了教学和管理流程,为学生、教师和家长提供了更加便捷、个性化的教育体验。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值