1、这个函数是CU的模式决定:CB,PU,TU的划分及PU的帧间或是帧内的模式
1)给定CB,求PU过程
流程为:
帧间模式的遍历SIZE_2NX2N的merge mode、SIZE_2NX2N、SIZE_NXN、SIZE_NX2N、SIZE_2NXN、AMP模式
帧间模式的遍历:进行SIZE_2NX2N、最小的CB还要进行SIZE_NXN的分割。
PCM模式:直接传输像素值。
2)CB的划分
递归的树划分形式
基本的流程为:1)深度为0,64x64的CB大小,求其最佳的PU分割,并判断是否进行划分
2)深度为1,64x64划分为4个32x32的CB,求每个的最佳PU的分割。第一个分割CB要直到分割
到最深层或是不能分割返回了,才进行第二个CB的PU的决定,依次类推。
3)深度为2,四个16x16块同深度为1相同,前一个CB分割划分到最深层或是不能再继续分割返回
了(CB划分完毕),才进行第二个CB的划分
这里需要注意的是,每个深度的CB的PU的划分的计算了什么?计算的结果存到个结构中?结构如何组织?在哪里完成比较?最终的CB的分割,PU的分割,TU的分割是如何存储的?
2、该函数中涉及到很多的编码工具
1)skip的快速判断 记录所有深度的skip模式的比特数和块数
// accumulate statistics for early skip
if ( m_pcEncCfg->getUseFastEnc() )
{
if ( rpcBestCU->isSkipped(0) )
{
Int iIdx = g_aucConvertToBit[ rpcBestCU->getWidth(0) ];
afCost[ iIdx ] += rpcBestCU->getTotalCost();
aiNum [ iIdx ] ++;
}
}
计算完成SIZE_2Nx2N的merge mode的RDcost后,根据先前所得到的统计信息来判断是否为skip模式,
这只适用于帧间模式
xCheckRDCostMerge2Nx2N( rpcBestCU, rpcTempCU, &earlyDetectionSkipMode );
//by Merge for inter_2Nx2N
rpcTempCU->initEstData( uiDepth, iQP );
// fast encoder decision for early skip
if ( m_pcEncCfg->getUseFastEnc() )
{
Int iIdx = g_aucConvertToBit[ rpcBestCU->getWidth(0) ];
if ( aiNum [ iIdx ] > 5 && fRD_Skip < EARLY_SKIP_THRES*afCost[ iIdx ]/aiNum[ iIdx ] )
{
bEarlySkip = true;
bTrySplit = false;
}
}
2)PU的快速决定
CB划分为PU的过程中,根据当前计算的PU模式的cbf来决定当前计算的PU是否是最优的,结束遍历所有的
分割模式。
doNotBlockPu = rpcBestCU->getQtRootCbf( 0 ) != 0;
3)AMP的快速算法:只考虑merge mode的AMP只进行运动补偿,不进行运动估计。
根据先前编码的模式,为SIZE_NX2N和SIZE_2NXN等来缩小范围。
Bool bTestAMP_Hor = false, bTestAMP_Ver = false;
//64x64不进行skip mode
#if AMP_MRG
//这里只能使用merge mode的模式,即只进行运动补偿,不进行运动估计。来减少编码的复杂度
Bool bTestMergeAMP_Hor = false, bTestMergeAMP_Ver = false;
deriveTestModeAMP (rpcBestCU, eParentPartSize, bTestAMP_Hor, bTestAMP_Ver,
bTestMergeAMP_Hor, bTestMergeAMP_Ver);