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顺序递归处理,如下图所示:
图中数字是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块。
上图是一个32x32的CTU划分成64个4x4块的结果,按zig-zag顺序扫描。
TComDataCU类中成员m_puhWidth、m_puhHeight、m_puhDepth三个数组存储了每个4x4小块的宽、高和深度。
下面是一个真实的64x64CTU划分示例:
上面64x64的CTU包含256个4x4的块,每个块对应的宽、高、深如下:
因为四叉树划分都是正方形块,所以宽高一样。对比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
感兴趣的请关注微信公众号Video Coding