之前的xCompressCU函数学习中,我们知道帧间每一个模式的选择都会调用xCheckRDCostInter函数,下面就来具体学习一下。
xCheckRDCostInter主要的功能是,进行帧间搜索,计算当前CU划分模式的RDcost
这样就找到了帧间搜索的入口函数:predInterSearch,下面将对他进行学习。其中调用的重要函数encodeResAndCalcRdInterCU可见:http://blog.csdn.net/lin453701006/article/details/77249344。
#if AMP_MRG
Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize DEBUG_STRING_FN_DECLARE(sDebug), Bool bUseMRG)
#else
Void TEncCu::xCheckRDCostInter( TComDataCU*& rpcBestCU, TComDataCU*& rpcTempCU, PartSize ePartSize )
#endif
{
DEBUG_STRING_NEW(sTest)
if(getFastDeltaQp()) //快速deltaQP模式,只有在2Nx2N的帧间模式中使用。
{
const TComSPS &sps=*(rpcTempCU->getSlice()->getSPS());
const UInt fastDeltaQPCuMaxSize = Clip3(sps.getMaxCUHeight()>>(sps.getLog2DiffMaxMinCodingBlockSize()), sps.getMaxCUHeight(), 32u);
if(ePartSize != SIZE_2Nx2N || rpcTempCU->getWidth( 0 ) > fastDeltaQPCuMaxSize)
{
return; // only check necessary 2Nx2N Inter in fast deltaqp mode
}
}
// prior to this, rpcTempCU will have just been reset using rpcTempCU->initEstData( uiDepth, iQP, bIsLosslessMode );
//对rpcTempCU进行初始化
UChar uhDepth = rpcTempCU->getDepth( 0 );
rpcTempCU->setPartSizeSubParts ( ePartSize, 0, uhDepth );
rpcTempCU->setPredModeSubParts ( MODE_INTER, 0, uhDepth );
rpcTempCU->setChromaQpAdjSubParts( rpcTempCU->getCUTransquantBypass(0) ? 0 : m_cuChromaQpOffsetIdxPlus1, 0, uhDepth );
#if AMP_MRG //进行Inter整像素搜索
rpcTempCU->setMergeAMP (true);
m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] DEBUG_STRING_PASS_INTO(sTest), false, bUseMRG );
#else
m_pcPredSearch->predInterSearch ( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcRecoYuvTemp[uhDepth] );
#endif
#if AMP_MRG
if ( !rpcTempCU->getMergeAMP() )
{
return;
}
#endif
//计算普通Inter模式残差及RDcost
m_pcPredSearch->encodeResAndCalcRdInterCU( rpcTempCU, m_ppcOrigYuv[uhDepth], m_ppcPredYuvTemp[uhDepth], m_ppcResiYuvTemp[uhDepth], m_ppcResiYuvBest[uhDepth], m_ppcRecoYuvTemp[uhDepth], false DEBUG_STRING_PASS_INTO(sTest) );
//存储总代价
rpcTempCU->getTotalCost() = m_pcRdCost->calcRdCost( rpcTempCU->getTotalBits(), rpcTempCU->getTotalDistortion() );
#if DEBUG_STRING
DebugInterPredResiReco(sTest, *(m_ppcPredYuvTemp[uhDepth]), *(m_ppcResiYuvBest[uhDepth]), *(m_ppcRecoYuvTemp[uhDepth]), DebugStringGetPredModeMask(rpcTempCU->getPredictionMode(0)));
#endif
//deltaQP检测
xCheckDQP( rpcTempCU );
//检测并设置最优模式
xCheckBestMode(rpcBestCU, rpcTempCU, uhDepth DEBUG_STRING_PASS_INTO(sDebug) DEBUG_STRING_PASS_INTO(sTest));
}