initCULevel函数在xCompressCU函数中被调用,xCompressCU函数中在最开始就调用m_modeCtrl->initCULevel( partitioner, *tempCS ),初始化m_modeCtrl,确定当期cu的test模式。
initCULevel函数用来确定当前compress的cu可以进行以及需要进行test的模式,保存在m_modeCtrl,然后在do_while循环中逐个进行test,选取当前cu的最优模式。
其实,对于一个cu需要test的模式,都是由EncModeCtrl类来进行控制的,initCULevel其实就是该类的初始化和test模式的填充。
对于EncModeCtrl类的分析,前面已经总结,其控制cu在compress过程中需要test的模式。
传入的partitioner记录划分树各层的信息,cs为xCompressCU函数中的tempCS。
void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStructure& cs )
{
// Min/max depth
unsigned minDepth = 0;
unsigned maxDepth = g_aucLog2[cs.sps->getSpsNext().getCTUSize()] - g_aucLog2[cs.sps->getSpsNext().getMinQTSize( m_slice->getSliceType(), partitioner.chType )];
if( m_pcEncCfg->getUseFastLCTU() )
{
if( auto adPartitioner = dynamic_cast<AdaptiveDepthPartitioner*>( &partitioner ) )
{
// LARGE CTU
adPartitioner->setMaxMinDepth( minDepth, maxDepth, cs );
}
}
m_ComprCUCtxList.push_back( ComprCUCtx( cs, minDepth, maxDepth, NUM_EXTRA_FEATURES ) );
// set features
ComprCUCtx &cuECtx = m_ComprCUCtxList.back();
cuECtx.set( BEST_NON_SPLIT_COST, MAX_DOUBLE );
cuECtx.set( BEST_VERT_SPLIT_COST, MAX_DOUBLE );
cuECtx.set( BEST_HORZ_SPLIT_COST, MAX_DOUBLE );
cuECtx.set( BEST_TRIH_SPLIT_COST, MAX_DOUBLE );
cuECtx.set( BEST_TRIV_SPLIT_COST, MAX_DOUBLE );
cuECtx.set( DO_TRIH_SPLIT, cs.sps->getSpsNext().getMTTMode() & 1 );
cuECtx.set( DO_TRIV_SPLIT, cs.sps->getSpsNext().getMTTMode() & 1 );
SaveLoadStruct &sls = getSaveLoadStruct( partitioner.currArea() );
cuECtx.set( HISTORY_D