HM是H.265/HEVC的官方参考软件,H.265是基于块的混合编码标准,以CTU为单位进行四叉树划分,H.265中规定最大的CTU为64x64。在HM中CTU的信息保存在TComDataCU类中,TComDataCU类的定义(定义太长下面列出部分成员)如下:

class TComDataCU
{
private:
​
  // -------------------------------------------------------------------------------------------------------------------
  // class pointers
  // -------------------------------------------------------------------------------------------------------------------
​
  TComPic*      m_pcPic;                                ///< picture class pointer
  TComSlice*    m_pcSlice;                              ///< slice header pointer
​
  // -------------------------------------------------------------------------------------------------------------------
  // CU description
  // -------------------------------------------------------------------------------------------------------------------
  //hm中怎么保存划分信息的。参考pCtu->getDepth(i),其中i代表当前CTU划分为最小CU的编号。
  //如64*64划分为256个4*4。成员变量m_puhDepth[uiIdx]是用来记录当前CU的深度信息。
  //因此可以判断出m_puhDepth[uiIdx]是在rpcTempCU中进行处理的。
​
  UInt          m_ctuRsAddr;                            ///< CTU (also known as LCU) address in a slice (Raster-scan address, as opposed to tile-scan/encoding order).
  UInt          m_absZIdxInCtu;                         ///< absolute address in a CTU. It's Z scan order
  UInt          m_uiCUPelX;                             ///< CU position in a pixel (X)
  UInt          m_uiCUPelY;                             ///< CU position in a pixel (Y)
  UInt          m_uiNumPartition;                       ///< total number of minimum partitions in a CU
  UChar*        m_puhWidth;                             ///< array of widths
  UChar*        m_puhHeight;                            ///< array of heights
  UChar*        m_puhDepth;                             ///< array of depths
  Int           m_unitSize;                             ///< size of a "minimum partition"
      SChar*        m_pePartSize;                           ///< array of partition sizes
  SChar*        m_pePredMode;                           ///< array of prediction modes
    ..........
        //省略
}

CTU可以按四叉树方式递归划分为子CU,子CU按zig-zag顺序递归处理,如下图所示:

HM内CU的数据结构_HM

 

图中数字是CU的处理顺序。

实际上整个CTU的信息都在TComDataCU类中,且数据仅在CTU中存储一份,子CU只需指定其在CTU中的位置即可。类中成员变量m_absZIdxInCtu表示子CU在CTU中的位置(zig-zag顺序)。

CTU并不是按照二维数组形式表示的,因为CTU的划分方式不同,每个部分的深度也不同,所以CTU的“形状”不同无法用统一的形式表示出来。

为了使用统一的数据结构简洁的表示CTU,TComDataCU类将CTU划分成4x4的小块,存储每个小块的深度。64x64的CTU可以划分为256个4x4块,32x32的CTU可以划分为64个4x4块。

HM内CU的数据结构_TComDataCU_02

 

上图是一个32x32的CTU划分成64个4x4块的结果,按zig-zag顺序扫描。

TComDataCU类中成员m_puhWidth、m_puhHeight、m_puhDepth三个数组存储了每个4x4小块的宽、高和深度。

下面是一个真实的64x64CTU划分示例:

HM内CU的数据结构_视频编码_03

 

上面64x64的CTU包含256个4x4的块,每个块对应的宽、高、深如下:

HM内CU的数据结构_视频编码_04

 

HM内CU的数据结构_HM_05

HM内CU的数据结构_HM_06

因为四叉树划分都是正方形块,所以宽高一样。对比m_puhDepth数组和上面的划分结构可以看出两者结果一致。(注意:数组是按zig-zag顺序输出的)

HM中提供了两个数组g_auiZscanToRaster和g_auiRasterToZscan可以进行zig-zag顺序和光栅扫描顺序间的转换。

g_auiZscanToRaster[ z-scan index ] = raster scan index
g_auiRasterToZscan[ raster index ] = z-scan index

HM内CU的数据结构_h.265/hevc_07

感兴趣的请关注微信公众号Video Coding

HM内CU的数据结构_TComDataCU_08