HEVC帧间预测之一――TComDataCU::getInterMergeCandidates函数分析(二)

2014-11-24 07:27:15 · 作者: · 浏览: 1
urPS == SIZE_2NxN || cCurPS == SIZE_2NxnU || cCurPS == SIZE_2NxnD) ) &&
!pcCUAbove->isIntra( uiAbovePartIdx );
if ( isAvailableB1 && (!isAvailableA1 || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAbove, uiAbovePartIdx ) ) )
#else//!< 如果A1可用,则检查A1和B1的MV是否相同,否则不需要检查
if (pcCUAbove)
{
if (!pcCUAbove->isDiffMER(xP+nPSW-1, yP-1, xP, yP))
{
pcCUAbove = NULL;
}
}
if ( pcCUAbove && !pcCUAbove->isIntra( uiAbovePartIdx )
&& !(uiPUIdx == 1 && (cCurPS == SIZE_2NxN || cCurPS == SIZE_2NxnU || cCurPS == SIZE_2NxnD))
&& ( !pcCULeft || pcCULeft->isIntra( uiLeftPartIdx ) || !pcCULeft->hasEqualMotion( uiLeftPartIdx, pcCUAbove, uiAbovePartIdx ) ) )
#endif
{
abCandIsInter[iCount] = true;
// get Inter Dir
puhInterDirNeighbours[iCount] = pcCUAbove->getInterDir( uiAbovePartIdx );
// get Mv from Above
pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
if ( getSlice()->isInterB() )
{
pcCUAbove->getMvField( pcCUAbove, uiAbovePartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
}
if ( mrgCandIdx == iCount )
{
return;
}
iCount ++;
}
// early termination
if (iCount == getSlice()->getMaxNumMergeCand())
{
return;
}
// above right
UInt uiAboveRightPartIdx = 0;
TComDataCU* pcCUAboveRight = 0;
#if LINEBUF_CLEANUP
pcCUAboveRight = getPUAboveRight( uiAboveRightPartIdx, uiPartIdxRT, true, false );
#else
pcCUAboveRight = getPUAboveRight( uiAboveRightPartIdx, uiPartIdxRT, true, false, true );
#endif
#if MERGE_CLEANUP_AND_K0197
Bool isAvailableB0 = pcCUAboveRight &&
pcCUAboveRight->isDiffMER(xP+nPSW, yP-1, xP, yP) &&
!pcCUAboveRight->isIntra( uiAboveRightPartIdx );
if ( isAvailableB0 && ( !isAvailableB1 || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveRight, uiAboveRightPartIdx ) ) )
#else//!< 如果B1可用,则检查B1和B0的MV是否相同,否则不需要检查
if (pcCUAboveRight)
{
if (!pcCUAboveRight->isDiffMER(xP+nPSW, yP-1, xP, yP))
{
pcCUAboveRight = NULL;
}
}
if ( pcCUAboveRight && !pcCUAboveRight->isIntra( uiAboveRightPartIdx ) && ( !pcCUAbove || pcCUAbove->isIntra( uiAbovePartIdx ) || !pcCUAbove->hasEqualMotion( uiAbovePartIdx, pcCUAboveRight, uiAboveRightPartIdx ) ) )
#endif
{
abCandIsInter[iCount] = true;
// get Inter Dir
puhInterDirNeighbours[iCount] = pcCUAboveRight->getInterDir( uiAboveRightPartIdx );
// get Mv from AboveRight
pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_0, pcMvFieldNeighbours[iCount<<1] );
if ( getSlice()->isInterB() )
{
pcCUAboveRight->getMvField( pcCUAboveRight, uiAboveRightPartIdx, REF_PIC_LIST_1, pcMvFieldNeighbours[(iCount<<1)+1] );
}
if ( mrgCandIdx == iCount )
{
return;
}
iCount ++;
}
// early termination
if (iCount == getSlice()->getMaxNumMergeCand())
{
return;
}
//left bottom
UInt uiLeftBottomPartIdx = 0;
TComDataCU* pcCULeftBottom = 0;
pcCULeftBottom = this->getPUBelowLeft( uiLeftBottomPartIdx, uiPartIdxLB, true, false );
#if MERGE_CLEANUP_AND_K0197
Bool isAvailableA0 = pcCULeftBottom &&
pcCULeftBottom->isDiffMER(xP-1, yP+nPSH, xP, yP) &&