HEVC函数入门(15)——重要变量以及CU索引

本文详细介绍了HEVC编码中的关键数据结构TComDataCU及其重要变量,如CUAddr、CUAbsIdxInLCU、CU尺寸等,并探讨了RDO过程中的临时变量使用,如量化系数、预测值存储。此外,还讲解了CU的Zscan扫描顺序、地址计算以及CU的递归划分。CU索引的处理在HEVC编码中至关重要,涉及到Raster到Zscan的映射以及CU在图像中的地址计算。
摘要由CSDN通过智能技术生成

本文整理自:1:http://blog.csdn.net/nb_vol_1/article/details/51145006
2:http://blog.csdn.net/NB_vol_1/article/details/71187426
首先感谢大神授权可以整理转载,后面会接着读大神的博客,所以后面一段时间里文章基本也是整理自这位大神。
1、TComDataCU。TComDataCU:LCU 及其子 CU 的数据结构,存储了一个 LCU 所有的相关信息,里面重要的数据结构包括:
m_uiCUAddr:一个 LCU 在 slice 中的位置
m_uiAbsIdxInLCU:当前 CU 在 LCU 中的位置,位置用 Z 扫描顺序
m_puhWidth: CU 的宽度
m_puhHeight:CU 的高度
m_puhDepth: CU 所处的深度
m_pePartSize : PU 的类型
m_pePredMode:编码模式
m_pcTrCoeffY,m_pcTrCoeffCb,m_pcTrCoeffCr:量化后的系数
m_puhLumaIntraDir:亮度的模式信息
m_puhChromaIntraDir:色度的模式信息
m_puhInterDir:帧间的预测方向
m_apiMVPIdx:MVP 索引
m_apiMVPNum:MVP 的候选数
以上的数据结构都是以动态存储来分配空间,一般只有一维,这一维具体取值的含义就是 CU 里面的每个对应的 4x4 的小块的信息,而开辟的数目就是 CU 所包含的 4x4 的数目,而在实际编码时也是编码了这些信息。
2、RDO 时所用到的主要临时变量:
2.1、m_ppcQTTempCoeffY, m_ppcQTTempCoeffCb, m_ppcQTTempCoeffCr: RQT时每层的量化系数,都保存在此,是为了确定最终分割后可以很容易的获取最优值
2.2、m_pcQTTempCoeffY,m_pcQTTempCoeffCb,m_pcQTTempCoeffCr:CU 层的量化系数暂存地,只有帧间编码时才会用到,是中间变量
2.3、m_pcQTTempTComYuv : 重建视频的暂存缓冲区
2.4、m_puhQTTempCbf: cbf 的暂存
2.4、m_puhQTTempTrIdx:变换层数的暂存
2.5、m_ppcBestCU:存储每层最优(RD代价最小)的CU的信息
2.6、m_ppcTempCU: 存储每层CU的信息的临时变量
2.7、m_ppcPredYuvBest: 存储每层最优的预测值
2.8、m_ppcResiYuvBest:存储每层最优的残差值
2.9、m_ppcRecoYuvBest:存储每层最优的重建值
2.10、m_ppcPredYuvTemp:存储每层预测值的临时变量
2.11、m_ppcResiYuvTemp:存储每层残差值的临时变量
2.12、m_ppcRecoYuvTemp:存储每层重建值的临时变量
2.13、m_ppcOrigYuv: :存储每层对应的原始值
3、yuv 的存储的关系
3.1、TComYuv 数据结构。由 m_apiBufY,m_apiBufU 以及 m_apiBufV 三个 buffer 组成,通用的 yuv数据结构,存储是 yuv 的亮度和色度信息
3.2、TComPicYuv 数据结构。图像层级的 yuv 数据结构,存储的是一帧的 yuv 信息,主要用于 ALF 和去方块滤波等处理的过程中
3.3、TComYuv 的类型的变量存储的是 RDO 时的值,最优的信息要存在 TComPicYuv中,便于输出和进行全局处理

下面的部分是和CU索引相关的,部分是和上面内容相关的。
1. 扫描顺序
HEVC中对像素块的扫描方式有两种:Raster和Zscan
Raster扫描方式:从上到下,从左到右进行扫描,是最直观也是最容易理解的方式
Zscan扫描方式:因为CU是递归划分的,因此为了方便处理,HM中使用了Z扫描,也就是从左上角按照Z字形扫描到右下角。下面是Zscan扫描的一个例子:
这里写图片描述
2.CU的划分
CU按照四叉树的方式自上而下,进行递归划分,由于使用了这种递归的方式,因此HEVC中必须要使用Zscan的扫描方式。每划分一次CU深度加一:
1、深度等于0时,CU的尺寸是64x64,该CU下面4x4小块的数量是256
2、深度等于1时,CU的尺寸是32x32,该CU下面4x4小块的数量是64
3、深度等于2时,CU的尺寸是16x16,该CU下面4x4小块的数量是16
4、深度等于3时,CU的尺寸是8x8,该CU下面4x4小块的数量是4
3.HEVC中对扫描顺序以及地址的处理
3.1 初始化扫描顺序
1、把每一个LCU都划分为4x4的小块,分别以Raster和Zscan的方式对4x4的小块进行编号(也就是索引)
2、把Raster到Zscan的编号映射存储在g_auiRasterToZscan数组中
3、把Zscan到Raster的编号映射存储在g_auiZscanToRaster数组中
4、把Raster索引到像素地址的映射放在g_auiRasterToPelX和g_auiRasterToPelY中
后面的代码为HM16.3版本,最新版本为16.9仅供参考:
在TEncCU.cpp找关于关于这几个函数的代码如下:

Void initZscanToRaster ( Int iMaxDepth, Int iDepth, UInt uiStartVal, UInt*& rpuiCurrIdx )
{
  Int iStride = 1 << ( iMaxDepth - 1 );

  if ( iDepth == iMaxDepth )
  {
    rpuiCurrIdx[0] = uiStartVal;
    rpuiCurrIdx++;
  }
  else
  {
    Int iStep = iStride >> iDepth;
    initZscanToRaster( iMaxDepth, iDepth+1, uiStartVal,                     rpuiCurrIdx );
    initZscanToRaster( iMaxDepth, iDepth+1, uiStartVal+iStep,               rpuiCurrIdx );
    initZscanToRaster( iMaxDepth, iDepth+1, uiStartVal+iStep*iStride,       rpuiCurrIdx );
    initZscanToRaster( iMaxDepth, iDepth+1, uiStartVal+iStep*iStride+iStep, rpuiCurrIdx );
  }
}

Void initRasterToZscan ( UInt uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiMaxDepth )
{
  UInt  uiMinCUWidth  = uiMaxCUWidth  >> ( uiMaxDepth - 1 );
  UInt  uiMinCUHeight = uiMaxCUHeight >> ( uiMaxDepth - 1 );

  UInt  uiNumPartInWidth  = (UInt)uiMaxCUWidth  / uiMinCUWidth;
  UInt  uiNumPartInHeight = (UInt)uiMaxCUHeight / uiMinCUHeight;

  for ( UInt i = 0; i < uiNumPartInWidth*uiNumPartInHeight; i++ )
  {
    g_auiRasterToZscan[ g_auiZscanToRaster[i] ] = i;
  }
}

Void initRasterToPelXY ( UInt uiMaxCUWidth, UInt uiMaxCUHeight, UInt uiMaxDepth )
{
  UInt    i;

  UInt* uiTempX = &g_auiRasterToPelX[0];
  UInt* uiTempY = &g_auiRasterToPelY[0];

  UInt  uiMinCUWidth  = uiMaxCUWidth  >> ( uiMaxDepth - 1 );
  UInt  uiMinCUHeight = uiMaxCUHeight >> ( uiMaxDepth - 1 );

  UInt  uiNumPartInWidth  = uiMaxCUWidth  / uiMinCUWidth;
  UInt  uiNumPartInHeight = uiMaxCUHeight / uiMinCUHeight;

  uiTempX[0] = 0; uiTempX++;
  for ( i = 1; i < uiNumPartInWidth; i++ )
  {
    uiTempX[0] = uiTempX[-1] + uiMinCUWidth; uiTempX++;
  }
  for ( i = 1; i < uiNumPartInHeight; i++ )
  
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值