xRecurIntraChromaCodingQT在estIntraPredChromaQT函数中被调用,用来计算每个帧内色度预测模式时的cost。
流程:
首先判断tu是否需要划分,若tu划分时,对每个划分出的小tu递归调用本函数,计算每个小tu的在chromaIntra模式下的最优的cost,最后求和;
如果tu不划分,分别对Cb和Cr通道进行处理。对于每个通道,是/否TS模式+是/否跨组件预测可以构成4种模式,分别对4种模式调用xIntraCodingTUBlock函数进行预测变换量化反量化反变换,得到reco像素和cost,按照cost选取TU的最优模式。选择的最优cost即当前test的chromaIntra模式的最优的cost。
本函数和VTM1中没有太大区别:
VTM1.0代码阅读:xRecurIntraChromaCodingQT函数
函数中调用的xIntraCodingTUBlock函数在帧内亮度预测时已经看过:
VTM3.0代码阅读:xIntraCodingTUBlock函数
ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT(CodingStructure &cs, Partitioner& partitioner)
{
UnitArea currArea = partitioner.currArea();
const bool keepResi = cs.sps->getSpsNext().getUseLMChroma() || KEEP_PRED_AND_RESI_SIGNALS;
if( !currArea.Cb().valid() ) return ChromaCbfs( false );
//色度tu、色度pu、lumaTU
TransformUnit &currTU = *cs.getTU( currArea.chromaPos(), CHANNEL_TYPE_CHROMA );
const PredictionUnit &pu = *cs.getPU( currArea.chromaPos(), CHANNEL_TYPE_CHROMA );
const TransformUnit &currTULuma = CS::isDualITree( cs ) ? *cs.picture->cs->getTU( currArea.lumaPos(), CHANNEL_TYPE_LUMA ) : currTU;
//CS::isDualITree()为true时,亮度和色度域有不同的划分树,就必须特别的getLumaTU;如果不是DualITree,直接用currTU
uint32_t currDepth = partitioner.currTrDepth; //tu的划分深度
const PPS &pps = *cs.pps;
ChromaCbfs cbfs ( false );
if (currDepth == currTU.depth) //tu划分深度已达到partitioner.currTrDepth,不再划分
{
if (!currArea.Cb().valid() || !currArea.Cr().valid()) //Cb/Cr分量可用
{
return cbfs;
}
bool checkTransformSkip = pps.getUseTransformSkip(); //Cb是否TS模式
checkTransformSkip &= TU::hasTransformSkipFlag( *currTU.cs, partitioner.currArea().Cb() );
if( m_pcEncCfg->getUseTransformSkipFast() ) //Y的TS模式
{
checkTransformSkip &= TU::hasTransformSkipFlag( *currTU.cs, partitioner.currArea().Y() );
if( checkTransformSkip && cs.pcv->noChroma2x2