- 参考软件选择branch HM13.0+QTBT:https://hevc.hhi.fraunhofer.de/trac/jem/browser/branches/HM-13.0-QTBT
- TypeDef.h宏定义,包括前面提到的重要参数,以及一些快速算法
#define CTU_LOG2 7 //1<<CTU_LOG2
: 64x64 or 128x128
#define MIN_CU_LOG2 2 //1<<MIN_CU_LOG2
: 2x2 or 4x4
#if MIN_CU_LOG2==1
#define DF_MODIFY 1 //deblocking modifications
#else
#define DF_MODIFY 0
#endif
//QTBT high level parameters
//for I slice luma CTB configuration para.
#define MAX_BT_DEPTH 4 // <=7
#define MAX_BT_SIZE 32 / /[1<<MIN_QT_SIZE,
1<<CTU_LOG2
]
#define MIN_QT_SIZE 16
#define MIN_BT_SIZE 4 // can be set down to 1<<MIN_CU_LOG2
//for I slice chroma CTB configuration para. (in luma samples)
#define MAX_BT_DEPTH_C 0 //<=7
#define MAX_BT_SIZE_C 32 //[1<<MIN_QT_SIZE_C
, 1<<CTU_LOG2
]
#define MIN_QT_SIZE_C 4
#define MIN_BT_SIZE_C 4 //can be set down to 4
//for P/B slice CTU config. para.
#define MAX_BT_DEPTH_INTER 4 //<=7
#define MAX_BT_SIZE_INTER 128 //for initialization, [1<<MIN_BT_SIZE_INTER
, 1<<CTU_LOG2
]
#define MIN_QT_SIZE_INTER 16 //for initialization
#define MIN_BT_SIZE_INTER 4 //
//end of QTBT high level parameters
//fast algorithms
#define AMAX_BT 1 //slice level adaptive maxBT for P/B slice
#define AMAXBT_TH32 15.0
#define AMAXBT_TH64 30.0
#define AMIN_QT 1 //slice level adaptive minQT for P/B slice
#define AMINQT_TH32 40.0
#define SKIP_DEPTH 3
#define SKIPHORNOVERQT_DEPTH_TH 2
#define BT_RMV_REDUNDANT 1 ///< Remove redundant BT structure for B/P slice
#define MRG_FAST 1 //merge mode RDO, first SATD select <=3 candidates, then full RDO.
#define NUM_MRG_SATD_CAND 4
#define MRG_FAST_RATIO 1.25
#define NEIGHBOR_FAST 1
#define PBINTRA_FAST 1 //Intra CU fast for B/P slice
#define PBINTRA_RATIO 1.1
#define ITSKIP 1 //inverse transform not used for zero-line, for transform size > 32
- 关键参数设置
printf("CTU size : %d \n", 1<<CTU_LOG2);//128
printf("I slice (LS=luma samples, CS=chroma samples) \n");
printf("maxBTSize(L,C) : %d LS, %d CS\n", MAX_BT_SIZE, MAX_BT_SIZE_C>>1);//32, 16
printf("minQTSize(L,C) : %dx%d LS, %dx%d CS\n", MIN_QT_SIZE, MIN_QT_SIZE, MIN_QT_SIZE_C>>1, MIN_QT_SIZE_C>>1);//16x16, 2x2
printf("minBTSize(L,C) : %d LS, %d CS\n", MIN_BT_SIZE, MIN_BT_SIZE_C>>1);//4, 2
printf("maxBTDepth(L,C) : %d, %d\n", MAX_BT_DEPTH, MAX_BT_DEPTH_C);//4,0
printf("P, B slice \n");
printf("maxBTSize(init) : %d \n", MAX_BT_SIZE_INTER);//128
printf("minQTSize(init) : %dx%d\n", MIN_QT_SIZE_INTER, MIN_QT_SIZE_INTER);//16, 16
printf("minBTSize : %d\n", MIN_BT_SIZE_INTER);//4
printf("maxBTDepth : %d\n", MAX_BT_DEPTH_INTER);//4
- compressCU伪代码
initCU();
xCompressCU(Luma)
if(isISlice)
xCompressCU(Chroma)
- xCompressCU伪代码(符合上文中的图片描述)
//no part
xCheckRDCostInter(2Nx2N)
xCheckRDCostMerge2Nx2N()
xCheckRDCostIntra(2Nx2N)
xCheckIntraPCM()
//figure the possibility of BT
//test horizontal split
2 * xCompressCU(uiWidth, uiHeight>>1)
//test vertical split
2 * xCompressCU(uiWidth>>1, uiHeight)
//QT
4 * xCompressCU(uiWidth>>1, uiHeight>>1)
- xQuantTU2(),对2 * X / X*2的变换系数块量化,不使用RDOQ,也不使用signBitHiding
- 宏AMAX_BT,对于非Islice,利用同一layer上CU的平均边长,对当前BT的最大划分尺寸约束
Double dBlkSize = sqrt((Double)g_uiBlkSize[refLayer]/g_uiNumBlk[refLayer]);
if (dBlkSize < AMAXBT_TH32)
{
pcSlice->setMaxBTSize(32>MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER: 32);
}
else if (dBlkSize < AMAXBT_TH64)
{
pcSlice->setMaxBTSize(64>MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER: 64);
}
else
{
pcSlice->setMaxBTSize(128>MAX_BT_SIZE_INTER? MAX_BT_SIZE_INTER: 128);
...
- 宏AMIN_QT,对于非I Slice,利用同一layer上CU的平均边长,对当前QT的最小划分尺寸进行约束。
if (dBlkSize > AMINQT_TH32 && MAX_BT_DEPTH_INTER>=4)
{
pcSlice->setMinQTSize(32);
}
- 宏SKIP_DEPTH,当当前最佳预测模式为skip模式时,且BT深度大于等于SKIP_DEPTH时,则跳过BT和QT划分。
if (rpcBestCU->getSkipFlag(0) && (bTestHorSplit || bTestVerSplit) && uiBTDepth>=SKIP_DEPTH)
{
bTestHorSplit = bTestVerSplit = bQTSplit = false;
}
- 宏SKIPHORNOVERQT_DEPTH_TH,当当前CU允许Horizontal划分,且当前最佳预测模式为skip模式,且最佳BT划分深度是当前深度,且当前BT深度大于等于SKIPHORNOVERQT_DEPTH_TH时,则
跳过Vertical划分和QT。
if (bTestHorSplit && rpcBestCU->isSkipped(0) && rpcBestCU->getBTDepth(0)==uiBTDepth && uiBTDepth>=SKIPHORNOVERQT_DEPTH_TH)
{
bTestVerSplit = bQTSplit = false;
}
- 宏BT_RMV_REDUNDANT,减少BT和QT重复计算,如下图所示,若CU划分为horizontal BT,则当第一个BT块做完xCompressCU后,得到最佳划分模式是vertical BT,那么,当第二个BT块做xCompressCU时,则直接跳过vertical BT的划分。原因在于,当前CU支持QT划分,那么QT划分时的块预测和第一个BT再进行vertical BT划分+第二个BT再进行verticalBT划分是一样的。因此,对于第二个BT而言,存在冗余的BT划分,即可跳过。同理,对于先Vertical划分BT而言,第二个块也可能存在类似的冗余。

- 宏MRG_FAST,根据SATD的代价先对merge candidate排序,并选择SATD较小的几个进行RDO。个数由即使SATD的大小与阈值MRG_FAST_RATIO决定。
- 宏NEIGHBOR_FAST,先计算相邻块left, bottom, top, top right的depth(需满足所有相邻块都存在)的最小和最大depth,只有当当前CUdepth大于等于最小depth,则不做不划分;当当前CUdepth小于等于最大depth,则不做QT & BT。
- 宏PBITNTRA_FAST,是PB Slice内的intra2Nx2N模式的一种加速算法。利用HAD计算RMD,并保存最小的三个HADcost,从小到大依次记为HAD1,HAD2,HAD3。与帧间预测得到的HAD0比较,当HAD1 > HAD0*阈值时,则跳过所有mode的full RDO,并结束帧内预测。当HAD2 > HAD0*阈值时,则仅对最小HAD的模式做full RDO。当HAD3 > HAD0 * 阈值时,则仅对最小的两个HAD对应的模式做full RDO。
- 宏ITSKIP,当变换块大于32x32时,跳过所有全零行的反变换