HEVC中CTU递归代码分析

CU递归的算法,那么就是xDecodeCU这个函数里面

首先对其中一些比较难以理解的部分进行相应的整理


UInt uiCurNumParts    = pcPic->getNumPartitionsInCtu() >> (uiDepth<<1);  

pcPic->getNumPartitionsInCtu() 获得的数据就是LCU中也就是根节点中CTU对应的按照最小TU进行划分得到的数量,后面进行>> (uiDepth<<1) 

这样一个移位操作表示递归操作过后,当前CU当中按照最小TU进行划分的数量

因为才开始整理,为什么要以最小TU来进行数据存储,想可能是因为最后都要落实到变换操作,所以按照这个划分,数据结构都是可以的


UInt uiQNumParts      = uiCurNumParts>>2;  这个变量主要是用于递归操作的时候一个递增数据的操作,假设当前CU需要划分,那么索引值需要增加多少进行返回


if( ( ( uiDepth < pcCU->getDepth( uiAbsPartIdx ) ) && ( uiDepth < g_uiMaxCUDepth - g_uiAddCUDepth ) ) || bBoundary )  这一个判断表示读取划分split的时候是否需要进行划分

g_uiMaxCUDepth  这个变量表示,LCU 到 最小TU 之间的级别,比如 LCU 为64*64, 最小TU 为4*4, 那么这个变量表示的级别就是 log2(64/4) = 4;

g_uiAddCUDepth  这个变量表示,SCU到最小TU之间的级别,SCU为8*8, 那么级别就是3

两者相减获得的就是LCU 到 SCU 之间的级别

那么这个判断就很好理解了,如果当前uiDepth < 两者差值,同时满足条件了,就应该进行劈分


递归过程还是比较简单,同时在存储相应的数据的时候:比如存储CU的深度信息

UInt uiCurrPartNumb = m_pcPic->getNumPartitionsInCtu() >> (uiDepth << 1);
  memset( m_puhDepth + uiAbsPartIdx, uiDepth, sizeof(UChar)*uiCurrPartNumb );

uiCurrPartNumb 表示当前CU中有多少以最小TU为单位的NUM

m_puhDepth 对于每一个LCU(根节点CTU) 都有一个存储变量,最后就是进行memset进行赋值操作


下面是部分有注释的代码,帮助大家分析代码

Void TDecCu::xDecodeCU( TComDataCU* pcCU, UInt uiAbsPartIdx, UInt uiDepth, Bool &isLastCtuOfSliceSegment) //uiAbsPartIdx 表示当前CU在CTU中X扫描位置对应的索引位置
{
  TComPic* pcPic = pcCU->getPic();
   UInt uiCurNumParts    = pcPic->getNumPartitionsInCtu() >> (uiDepth<<1); //<当前CU中按照最小TU为单元划分,有多少个宏块
  UInt uiQNumParts      = uiCurNumParts>>2; //<用于递归过程中,偏移量递增,如果当前CU需要劈分,那么劈分后每一个CU中包含的STU数量

  Bool bBoundary = false;//<是否为边界位置
  UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsPartIdx] ];//getCUPelX()获取当前CTU在图片中的绝对位置,后者为当前CU在CTU中位置的偏移量
  UInt uiRPelX   = uiLPelX + (g_uiMaxCUWidth>>uiDepth)  - 1;//>uiDepth)表示当前CU的宽度
  UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsPartIdx] ];
  UInt uiBPelY   = uiTPelY + (g_uiMaxCUHeight>>uiDepth) - 1;

  TComSlice * pcSlice = pcCU->getPic()->getSlice(pcCU->getPic()->getCurrSliceIdx());
  if( ( uiRPelX < pcSlice->getSPS()->getPicWidthInLumaSamples() ) && ( uiBPelY < pcSlice->getSPS()->getPicHeightInLumaSamples() ) )//<根据图片的像素位置进行判断
  {
    m_pcEntropyDecoder->decodeSplitFlag( pcCU, uiAbsPartIdx, uiDepth );//<将当前的深度存储在m_puhDepth
  }
  else
  {
    bBoundary = true;
  }
  //getDepth( uiAbsPartIdx ) ) && ( uiDepth < g_uiMaxCUDepth - g_uiAddCUDepth ) ) || bBoundary )//<需要劈分或者是达到边界?
  {
    UInt uiIdx = uiAbsPartIdx; //>uiDepth) == pcCU->getSlice()->getPPS()->getMinCuDQPSize() && pcCU->getSlice()->getPPS()->getUseDQP())//XT?getMinCuDQPSize: LCU宽度>>diff_cu_qp_delta_depth获得一个最小的什么的宽度
    {
      setdQPFlag(true);
      pcCU->setQPSubParts( pcCU->getRefQP(uiAbsPartIdx), uiAbsPartIdx, uiDepth ); // set QP to default QP
    }

    if( (g_uiMaxCUWidth>>uiDepth) == pcCU->getSlice()->getPPS()->getMinCuChromaQpAdjSize() && pcCU->getSlice()->getUseChromaQpAdj() )
    {
      setIsChromaQpAdjCoded(true);
    }

    for ( UInt uiPartUnitIdx = 0; uiPartUnitIdx < 4; uiPartUnitIdx++ ) //<如果劈分,对应分成4份
    {
      uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiIdx] ];
      uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiIdx] ];//<仍然是获得当前CU在图片中位置

      if ( !isLastCtuOfSliceSegment && ( uiLPelX < pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) )
      {
        xDecodeCU( pcCU, uiIdx, uiDepth+1, isLastCtuOfSliceSegment ); //<递归操作,uiIdx表示当前CU在CTU中的Z扫描索引,深度+1
      }
      else
      {
        pcCU->setOutsideCUPart( uiIdx, uiDepth+1 ); //<将深度,高度,宽度信息进行存储m_puhDepth,m_puhWidth,m_puhHeight
      }

      uiIdx += uiQNumParts; //<位置索引进行递增的操作
    }
    if( (g_uiMaxCUWidth>>uiDepth) == pcCU->getSlice()->getPPS()->getMinCuDQPSize() && pcCU->getSlice()->getPPS()->getUseDQP()) //<这一部分应该是当前CU和DQP直接有关系的部分
    {
      if ( getdQPFlag() )
      {
        UInt uiQPSrcPartIdx = uiAbsPartIdx;
        pcCU->setQPSubParts( pcCU->getRefQP( uiQPSrcPartIdx ), uiAbsPartIdx, uiDepth ); // set QP to default QP
      }
    }
    return;
  }





你可能感兴趣的:(HEVC技术,HEVC,递归,CU)