版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_28446365/article/details/79957046
rpcTempCU->setICFlagSubParts(bICFlag, 0, uiDepth);
xCheckRDCostInter()
Bool bICFlag = rpcTempCU->getICFlag( 0 );
if( bIMV && pcCUInfo2Reuse != NULL )//若信息可以重复使用,则无需进行帧间预测
{
rpcTempCU->copyPartFrom();//reuse the motion info from pcCUInfo2Reuse
bICFlag = rpcTempCU->getICFlag( 0 );//信息复用之后可能改变,所以需重新赋值
if( !rpcTempCU->hasSubCUNonZeroMVd() )//若MV均为0,则返回,否则可直接进行运动补偿
{
return;
}
else
{
//直接进行运动补偿
m_pcPredSearch->motionCompensation( rpcTempCU , m_pppcPredYuvTemp[uiWIdx][uiHIdx] );
}
}
else
{
m_pcPredSearch->predInterSearch ();
}
rpcTempCU->setICFlagSubParts(bICFlag, 0, uhDepth);
xCheckBestMode();
predInterSearch()
for ( Int iPartIdx = 0; iPartIdx < iNumPart; iPartIdx++ )//CU中PU的个数,H266为1
{
//Cost等初始化,都赋值为最大值
if (bTestNormalMC)
{
// Uni-directional prediction
for ( Int iRefList = 0; iRefList < iNumPredDir; iRefList++ )//前后向预测循环
{
for ( Int iRefIdxTemp = 0; iRefIdxTemp < pcCU->getSlice()->getNumRefIdx(eRefPicList); iRefIdxTemp++ )//单向预测循环
{
//如果是list1(即B帧)
//else(如果对于使用list0的帧(P帧和B帧),调用xMotionEstimation进行运动估计。)
if ( m_pcEncCfg->getFastMEForGenBLowDelayEnabled() && iRefList == 1 ) // list 1
{
/*如果list0和list1之间有映射(即这个帧同时出现在list0和list1中),
那么直接把在list0中的计算信息复制过来就行了。*/
//else(如果没有映射,那么调用xMotionEstimation进行运动估计。)
if ( pcCU->getSlice()->getList1IdxToList0Idx( iRefIdxTemp ) >= 0 )//把在list0中的计算信息复制过来
{
//复制信息
}
else
{
xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
}
}
else
{
xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPred[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp );
}
}
}
// Bi-directional prediction
if ( (pcCU->getSlice()->isInterB()) && (pcCU->isBipredRestriction(iPartIdx) == false)
{
//并且list1是空的(getMvdL1ZeroFlag标志为真),那么调用motionCompensation进行运动补偿运算
if(pcCU->getSlice()->getMvdL1ZeroFlag())
{
motionCompensation( pcCU, pcYuvPred, REF_PIC_LIST_1, iPartIdx );
}
for ( Int iIter = 0; iIter < iNumIter; iIter++ )//双向预测中list 0和list 1相互查找最优解,迭代四次
{
//如果是第一个子CU,并且getMvdL1ZeroFlag为false(list 1非空),那么调用motionCompensation进行运动补偿计算
if ( iIter == 0 && !pcCU->getSlice()->getMvdL1ZeroFlag()
{
motionCompensation ( pcCU, pcYuvPred, RefPicList(1-iRefList), iPartIdx );
}
for ( Int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++ )
{
xMotionEstimation ( pcCU, pcOrgYuv, iPartIdx, eRefPicList, &cMvPredBi[iRefList][iRefIdxTemp], iRefIdxTemp, cMvTemp[iRefList][iRefIdxTemp], uiBitsTemp, uiCostTemp, true );
if ( uiCostTemp < uiCostBi )
{
//如果不是第一个子CU的话,还需要调用motionCompensation进行运动补偿
if(iNumIter!=1)
{
motionCompensation( pcCU, pcYuvPred, eRefPicList, iPartIdx );
}
}
}
}
}
}
motionCompensation ( pcCU, pcPredYuv, REF_PIC_LIST_X, iPartIdx );
}
motionCompensation()
if ( iPartIdx >= 0 )
{
if ( eRefPicList != REF_PIC_LIST_X )
{
if(!pcCU->getICFlag( uiPartAddr ))
xPredInterUni();
else//LIC为真
{
xPredInterUni();
}
if(!pcCU->getICFlag( uiPartAddr ))
xWeightedPredictionUni();
}
else//做完运动估计选出最优,此处进行最后的运动补偿
{
}
return;
}
xPredInterUni()
for( Int y = 0 , yRasterOffset = 0 ; y < nBlkHeight ; y += nBlkStepY , yRasterOffset += yRasterOffsetStep )
{
for( Int x = 0 , xRasterOffset = 0 ; x < nBlkWidth ; x += nBlkStepX , xRasterOffset += xRasterOffsetStep )
{
uiPartAddr = g_auiRasterToZscan[uiIdxRasterStart+yRasterOffset+xRasterOffset] - pcCU->getZorderIdxInCtu();//4*4小块索引
for (UInt comp=COMPONENT_Y; comp<pcYuvPred->getNumberValidComponents(); comp++)
{
xPredInterBlk( , pcCU->getICFlag( uiPartAddr ) );
}
}
}
运动估计的时候进行了LIC,使用的是AMVP中的预测MV,最后运动补偿的时候进行了LIC使用的是自身的MV。