欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

HM中CU的ZOrder表示——uiAbsPartIdx变量

程序员文章站 2022-07-07 14:06:47
...

HM中经常看到uiAbsPartIdx这个变量,之前对这个变量一直不是太理解,前段时间看HM代码又深入理解了一下。

Z-Order

Z字形扫描顺序在编码中经常用到,如下图是CTU划分成CU后的Z字形编码顺序,CU按此顺序逐个进行编码。
HM中CU的ZOrder表示——uiAbsPartIdx变量
但是CU在CTU中的index却不是简单等于这个编码顺序,因为不确定一个CTU会划分成多少个CU,只是知道编码顺序并不能确定CU的位置。

因为编码过程中最小的单元是4×4大小,所以可以将CTU划分成若干个4×4大小的块,进而确定CU的位置,这也是uiAbsPartIdx变量的作用。

CU的Z-index

我们默认CTU大小是64×64,那么就可以划分成256个4×4大小的块。将这256个块按Z字形顺序编号,得到其各自的Z-Order。如下图中每个小方块大小为4×4,红线代表Z字形扫描的顺序。
HM中CU的ZOrder表示——uiAbsPartIdx变量
对应的每个4×4单元的Z-index为:
HM中CU的ZOrder表示——uiAbsPartIdx变量
而一个CU的Zorder则是以当前CU左上方的4×4单元的Z-index表示,也就是我们经常看到的变量uiAbsPartIdx存储的值。

相关接口

CU可以通过getZorderIdxInCtu()函数来得到其在CTU中的Zorder。该函数定义在TComDataCU类中,一般在代码中都是通过CU的指针pcCU来调用,即

UInt uiAbsPartIdx = pcCU->getZorderIdxInCtu()

除了Zorder外,我们还经常需要用到CU的光栅扫描顺序或者CU的像素坐标,这都可以通过将Zorder转换得到。

在HM中有几个与坐标转换相关的数组如下:

UInt g_auiZscanToRaster[MAX_NUM_PART_IDXS_IN_CTU_WIDTH * MAX_NUM_PART_IDXS_IN_CTU_WIDTH] = {0,};
UInt g_auiRasterToZscan[MAX_NUM_PART_IDXS_IN_CTU_WIDTH * MAX_NUM_PART_IDXS_IN_CTU_WIDTH] = {0,};
UInt g_auiRasterToPelX[MAX_NUM_PART_IDXS_IN_CTU_WIDTH * MAX_NUM_PART_IDXS_IN_CTU_WIDTH] = {0,};
UInt g_auiRasterToPelY[MAX_NUM_PART_IDXS_IN_CTU_WIDTH * MAX_NUM_PART_IDXS_IN_CTU_WIDTH] = {0,};

由名字可以很容易理解它们的作用,其实这些数组就是一个映射关系,如g_auiZscanToRaster,ZOrder的4对应RasterOrder的2,所以g_auiZscanToRaster[4]的值就为2。

拓展

我们看到CU的Zorder一般是用uiAbsPartIdx变量来表示,这个变量为什么叫这个名字呢,首先ui是unsinged int 这个大家应该都知道,那Part是什么意思呢?其实是每个4×4单元被称为一个Part。那Abs是表示CU在CTU中的绝对下标,同样也有Rel表示相对的下标,如一个CU有可能会被划分成不同深度的TU,TU就可以通过GetTransformDepthRel()函数来获得TU相对CU的深度。