VVC 代码阅读 compressCtu()函数

void EncCu::compressCtu( CodingStructure& cs, const UnitArea& area, const unsigned ctuRsAddr, const int prevQP[], const int currQP[] )

VTM3.0代码阅读:compressCtu函数_矛盾统一的博客-CSDN博客

H.266/VVC代码学习13:VTM4.0中的CU层操作(compressCtu 、 xCompressCU)_海洋之心。的博客-CSDN博客

cs:包含之前picture,slice全部的信息,如位置,色度亮度,preQP的设置等。不包括当前CTU的信息。这个之后再确认一下

area,ctuRsAddr,prevQP, currQP:传输过来CTU的位置,ctuRsAddr的值,过去与现在QP的设置,这些都是当前CPU的值。

ctuRsAddr为当前ctu的rs扫描地址。这个之后再确认一下

m_modeCtrl->initCTUEncoding( *cs.slice );
  cs.treeType = TREE_D;

  cs.slice->m_mapPltCost[0].clear();
  cs.slice->m_mapPltCost[1].clear();
  // init the partitioning manager
  QTBTPartitioner partitioner;
  partitioner.initCtu(area, CH_L, *cs.slice);// 用当前area初始化partitioner

initCTUEncoding():进行模式控制类实例的CTU级初始化

enum TreeType
{
  TREE_D = 0, //树的状态设置 (for single-tree slice, TREE_D means joint tree; for dual-tree I slice, TREE_D means TREE_L for luma and TREE_C for chroma)

//single tree应该是对应于dual tree,表明亮度色度都有相同的编码树结构。joint tree应该表示亮色度共用同一种树结构。对于I 帧的dual_tree,不同的变量来表示
  TREE_L = 1, //separate tree only contains luma (may split) 可再分,对single tree和dual tree来说TREE_L 都代表亮度树
  TREE_C = 2, //separate tree only contains chroma (not split), to avoid small chroma block//不可再分,以免出现过小的色度块
};

QTBTPartitioner partitioner:是管理划分的变量,包含划分的栈、CU/PU/TU划分信息(划分深度、UnitArea等信息)、设置划分限制的方法以及划分合理性检查(canSplit)

initCtu():进行划分类实例的初始化,接收传输过来的数据

 if (m_pcEncCfg->getIBCMode())
  {
    if (area.lx() == 0 && area.ly() == 0)
    {
      m_pcInterSearch->resetIbcSearch();
    }
    m_pcInterSearch->resetCtuRecord();
    m_ctuIbcSearchRangeX = m_pcEncCfg->getIBCLocalSearchRangeX();
    m_ctuIbcSearchRangeY = m_pcEncCfg->getIBCLocalSearchRangeY();
  }
  if (m_pcEncCfg->getIBCMode() && m_pcEncCfg->getIBCHashSearch() && (m_pcEncCfg->getIBCFastMethod() & IBC_FAST_METHOD_ADAPTIVE_SEARCHRANGE))
  {
    const int hashHitRatio = m_ibcHashMap.getHashHitRatio(area.Y()); // in percent
    if (hashHitRatio < 5) // 5%
    {
      m_ctuIbcSearchRangeX >>= 1;
      m_ctuIbcSearchRangeY >>= 1;
    }
    if (cs.slice->getNumRefIdx(REF_PIC_LIST_0) > 0)
    {
      m_ctuIbcSearchRangeX >>= 1;
      m_ctuIbcSearchRangeY >>= 1;
    }
  }

IBC:IntraBlockCopy(帧内块复制)模式,默认false,jvetw2002   3.91节有介绍先跳过

// init current context pointer  初始化当前上下文指针
  m_CurrCtx = m_CtxBuffer.data();

  CodingStructure *tempCS = m_pTempCS[gp_sizeIdxInfo->idxFrom( area.lumaSize().width )][gp_sizeIdxInfo->idxFrom( area.lumaSize().height )];
  CodingStructure *bestCS = m_pBestCS[gp_sizeIdxInfo->idxFrom( area.lumaSize().width )][gp_sizeIdxInfo->idxFrom( area.lumaSize().height )];

  cs.initSubStructure(*tempCS, partitioner.chType, partitioner.currArea(), false);
  cs.initSubStructure(*bestCS, partitioner.chType, partitioner.currArea(), false);
  tempCS->currQP[CH_L] = bestCS->currQP[CH_L] =
  tempCS->baseQP       = bestCS->baseQP       = currQP[CH_L];//把当前亮度QP统一赋给temp和best
  tempCS->prevQP[CH_L] = bestCS->prevQP[CH_L] = prevQP[CH_L];

  xCompressCU(tempCS, bestCS, partitioner);

tempCS和bestCS:当前临时的Coding Struct结构和最佳模式的Coding Structure结构,对于每一个尺寸的CU和CTU,都可以根据尺寸在m_pTempCS和m_pBestCS得到对应的CS结构,通过父cs调用initSubStructure将相应信息复制到子cs中(sps、pps等)

gp_sizeIdxInfo->idxFrom():得到当前块的亮度分量的宽度或高度。因为当前area是传输过来的CTUarea,所以此时得到的是当前CTU的宽高
tempCS:得到当前块的宽高后,从m_pTempCS中得到当前块尺寸对应的临时Coding Struct结构(当前待划分CTU的临时Coding Struct结构)

bestCS:得到当前块的宽高后,从m_pBestCS中得到当前块尺寸对应的最佳Coding Struct结构(当前待划分CTU的最佳Coding Struct结构)

VTM3.0代码阅读:xCompressCU函数_矛盾统一的博客-CSDN博客

复制的:tempCS用来存储当前compress区域的各种模式下处理得到的数据,如果tempCS的cost小于bestCS,那么赋给给bestCS;如果差于bestCS,那么丢弃tempCS中数据。bestCS在xCompressCU函数中的任何位置,都用来存储到目前为止所得到的最优划分和最优模式数据。   这个之后看代码再具体理解‘

重要重要:initSubStructure():picture级别的CS通过调用这个函数把SPS,PPS还有preQP等基础参数传给了tempCS和bestCS(CTU级别),注意CS所代表的区域

第一个xCompressCU():因为CTU也可以被看作最大的CU,所以没有encode cu,进入CompressCU()

cs.slice->m_mapPltCost[0].clear();
  cs.slice->m_mapPltCost[1].clear();
  // all signals were already copied during compression if the CTU was split - at this point only the structures are copied to the top level CS
  const bool copyUnsplitCTUSignals = bestCS->cus.size() == 1;
  cs.useSubStructure(*bestCS, partitioner.chType, CS::getArea(*bestCS, area, partitioner.chType), copyUnsplitCTUSignals,
                     false, false, copyUnsplitCTUSignals, true);

copyUnsplitCTUSignals:默认为false

 if (CS::isDualITree (cs) && isChromaEnabled (cs.pcv->chrFormat))
  {
    m_CABACEstimator->getCtx() = m_CurrCtx->start;

    partitioner.initCtu(area, CH_C, *cs.slice);

    cs.initSubStructure(*tempCS, partitioner.chType, partitioner.currArea(), false);
    cs.initSubStructure(*bestCS, partitioner.chType, partitioner.currArea(), false);
    tempCS->currQP[CH_C] = bestCS->currQP[CH_C] =
    tempCS->baseQP       = bestCS->baseQP       = currQP[CH_C];
    tempCS->prevQP[CH_C] = bestCS->prevQP[CH_C] = prevQP[CH_C];

    xCompressCU(tempCS, bestCS, partitioner);

    const bool copyUnsplitCTUSignals = bestCS->cus.size() == 1;
    cs.useSubStructure(*bestCS, partitioner.chType, CS::getArea(*bestCS, area, partitioner.chType),
                       copyUnsplitCTUSignals, false, false, copyUnsplitCTUSignals, true);
  }

  if (m_pcEncCfg->getUseRateCtrl())
  {
    (m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr)).m_actualMSE = (double)bestCS->dist / (double)m_pcRateCtrl->getRCPic()->getLCU(ctuRsAddr).m_numberOfPixel;
  }
  // reset context states and uninit context pointer
  m_CABACEstimator->getCtx() = m_CurrCtx->start;
  m_CurrCtx                  = 0;


  // Ensure that a coding was found
  // Selected mode's RD-cost must be not MAX_DOUBLE.
  CHECK( bestCS->cus.empty()                                   , "No possible encoding found" );
  CHECK( bestCS->cus[0]->predMode == NUMBER_OF_PREDICTION_MODES, "No possible encoding found" );
  CHECK( bestCS->cost             == MAX_DOUBLE                , "No possible encoding found" );
}

if语句:如果当前为dualtree且色度采样格式不为4:0:0,则再对色度进行一次划分。与上面基本相同,只是变为了色度分量

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值