H266:xCheckRdCostInter()到xPredInterUni()流程

版权声明:本文为博主原创文章,未经博主允许不得转载。 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。

猜你喜欢

转载自blog.csdn.net/baidu_28446365/article/details/79957046