运动补偿MC——motionCompensation
(1) iPartIdx >= 0,对索引为iPartIdx的PU进行操作
1)不使用VSP
a.对某一参考列表list0或list1(单向),判断是否进行加权预测。
b.对某一参考列表list0和list1(双向),判断是否SPIVMP
I)进行SPIVMP
II)只考虑时域上的预测。 调用xCheckIdenticalMotion,判断pcCU在list0和list1中的mv相同。若相同,则调用xPredInterUni,进行前向预测;若不同,调用xPredInterBi,进行双向预测。
2)使用VSP
调用xCheckIdenticalMotion,判断pcCU在list0和list1中的mv相同。若相同,调用xPredInterUniVSP;若不同,调用xPredInterBiVSP。
(2) iPartIdx ==-1,对CU中所有的PU进行操作。。操作方法与(1)的内容完全一致
Void TComPrediction::motionCompensation ( TComDataCU* pcCU, TComYuv* pcYuvPred, RefPicList eRefPicList, Int iPartIdx )
{
Int iWidth;
Int iHeight;
UInt uiPartAddr;
const TComSlice *pSlice = pcCU->getSlice();
const SliceType sliceType = pSlice->getSliceType();
const TComPPS &pps = *(pSlice->getPPS());
if ( iPartIdx >= 0 )//iPartIdx为PU在CU中的索引,对索引为iPartIdx的PU进行操作
{
pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
#if NH_3D_VSP
if ( pcCU->getVSPFlag(uiPartAddr) == 0)//不使用VSP
{
#endif
if ( eRefPicList != REF_PIC_LIST_X )//对某一参考列表,list0或者list1。。单向
{
if( (sliceType == P_SLICE && pps.getUseWP()) || (sliceType == B_SLICE && pps.getWPBiPred()))//加权预测
{
xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
}
else
{
xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
}
}
else//对list0和list1。。双向
{
#if NH_3D_SPIVMP
if ( pcCU->getSPIVMPFlag(uiPartAddr)!=0)
{
Int iNumSPInOneLine, iNumSP, iSPWidth, iSPHeight;
pcCU->getSPPara(iWidth, iHeight, iNumSP, iNumSPInOneLine, iSPWidth, iSPHeight);
UInt uiW[256], uiH[256];
UInt uiSPAddr[256];
xGetSubPUAddrAndMerge(pcCU, uiPartAddr, iSPWidth, iSPHeight, iNumSPInOneLine, iNumSP, uiW, uiH, uiSPAddr);
//MC
for (Int i = 0; i < iNumSP; i++)
{
if (uiW[i]==0 || uiH[i]==0)
{
continue;
}
if( xCheckIdenticalMotion( pcCU, uiSPAddr[i] ))
{
xPredInterUni (pcCU, uiSPAddr[i], uiW[i], uiH[i], REF_PIC_LIST_0, pcYuvPred );
}
else
{
xPredInterBi (pcCU, uiSPAddr[i], uiW[i], uiH[i], pcYuvPred);
}
}
}
else
{//只考虑时域上的预测
#endif
if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )//判断pcCU在list0和list1中的mv相同
{
xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );//前向预测
}
else
{
xPredInterBi (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );//双向预测
}
#if NH_3D_SPIVMP
}
#endif
}
#if NH_3D_VSP
}
else//使用VSP
{
if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
{
xPredInterUniVSP( pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
}
else
{
xPredInterBiVSP ( pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
}
}
#endif
return;
}
for ( iPartIdx = 0; iPartIdx < pcCU->getNumPartitions(); iPartIdx++ )//对CU中所有的PU进行操作。。操作方法与上一部分if ( iPartIdx >= 0 )的内容完全一致
{
pcCU->getPartIndexAndSize( iPartIdx, uiPartAddr, iWidth, iHeight );
#if NH_3D_VSP
if ( pcCU->getVSPFlag(uiPartAddr) == 0 )
{
#endif
if ( eRefPicList != REF_PIC_LIST_X )
{
if( (sliceType == P_SLICE && pps.getUseWP()) || (sliceType == B_SLICE && pps.getWPBiPred()))
{
xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred, true );
xWeightedPredictionUni( pcCU, pcYuvPred, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
}
else
{
xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, eRefPicList, pcYuvPred );
}
}
else
{
#if NH_3D_SPIVMP
if (pcCU->getSPIVMPFlag(uiPartAddr)!=0)
{
Int iNumSPInOneLine, iNumSP, iSPWidth, iSPHeight;
pcCU->getSPPara(iWidth, iHeight, iNumSP, iNumSPInOneLine, iSPWidth, iSPHeight);
UInt uiW[256], uiH[256];
UInt uiSPAddr[256];
xGetSubPUAddrAndMerge(pcCU, uiPartAddr, iSPWidth, iSPHeight, iNumSPInOneLine, iNumSP, uiW, uiH, uiSPAddr);
//MC
for (Int i = 0; i < iNumSP; i++)
{
if (uiW[i]==0 || uiH[i]==0)
{
continue;
}
if( xCheckIdenticalMotion( pcCU, uiSPAddr[i] ))
{
xPredInterUni (pcCU, uiSPAddr[i], uiW[i], uiH[i], REF_PIC_LIST_0, pcYuvPred );
}
else
{
xPredInterBi (pcCU, uiSPAddr[i], uiW[i], uiH[i], pcYuvPred);
}
}
}
else
{
#endif
if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
{
xPredInterUni (pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
}
else
{
xPredInterBi (pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
}
#if NH_3D_SPIVMP
}
#endif
}
#if NH_3D_VSP
}
else
{
if ( xCheckIdenticalMotion( pcCU, uiPartAddr ) )
{
xPredInterUniVSP( pcCU, uiPartAddr, iWidth, iHeight, REF_PIC_LIST_0, pcYuvPred );
}
else
{
xPredInterBiVSP ( pcCU, uiPartAddr, iWidth, iHeight, pcYuvPred );
}
}
#endif
}
return;
}