getMipMPMs
int PU::getMipMPMs(const PredictionUnit &pu, unsigned *mpm)
{
const CompArea &area = pu.block( getFirstComponentOfChannel( CHANNEL_TYPE_LUMA ) );
const Position &pos = area.pos();
bool realMode = false;
// Get intra mode of left PU
int leftIntraMode = -1;
const PredictionUnit *puLeft = pu.cs->getPURestricted( pos.offset( -1, 0 ), pu, CHANNEL_TYPE_LUMA );
if( puLeft && CU::isIntra( *puLeft->cu ) )
{
if( PU::isMIP( *puLeft ) )
{
if (getMipSizeId(*puLeft) == getMipSizeId(pu))
{
leftIntraMode = puLeft->intraDir[CHANNEL_TYPE_LUMA];//如果左参考为ALWIP模式,直接取用
realMode = true;
}
}
else
{
leftIntraMode = g_mapAngular33ToMip[getMipSizeId(pu)][g_intraMode65to33AngMapping[puLeft->intraDir[CHANNEL_TYPE_LUMA]]];//如果左参考传统模式,映射
}
}
// Get intra mode of above PU
int aboveIntraMode = -1;
const PredictionUnit *puAbove = pu.cs->getPURestricted( pos.offset( 0, -1 ), pu, CHANNEL_TYPE_LUMA );
if( puAbove && CU::isIntra( *puAbove->cu ) && CU::isSameCtu(*pu.cu, *puAbove->cu) )
{
if( PU::isMIP( *puAbove ) )
{
if (getMipSizeId(*puAbove) == getMipSizeId(pu))
{
aboveIntraMode = puAbove->intraDir[CHANNEL_TYPE_LUMA];//如果上参考为ALWIP模式,直接取用
realMode = true;
}
}
else
{
aboveIntraMode = g_mapAngular33ToMip[getMipSizeId(pu)][g_intraMode65to33AngMapping[puAbove->intraDir[CHANNEL_TYPE_LUMA]]];//如果上参考传统模式,映射
}
}
// derive MPMs
CHECKD(NUM_MPM_MIP != 3, "Error: wrong number of MPMs for MIP");
const int* modeList = g_sortedMipMpms[getMipSizeId(pu)];//getMipSizeId:4*4--0;8*8--1;其他--2;
//g_sortedMipMpms:0- { 17, 34, 5 },
int numCand = 0; // 1- { 0, 7, 16 },
if( leftIntraMode == aboveIntraMode )//左和上相同预测模式,numCand = 1 // 2- { 1, 4, 6 },
{
if( leftIntraMode > -1 )//ex:在leftIntraMode和17,34,5中选三个不同的,顺序依次
{
mpm[0] = leftIntraMode;
numCand = 1;
if( leftIntraMode != modeList[0] )
{
mpm[1] = modeList[0];
mpm[2] = (leftIntraMode != modeList[1]) ? modeList[1] : modeList[2];
}
else
{
mpm[1] = modeList[1];
mpm[2] = modeList[2];
}
}
else
{
mpm[0] = modeList[0];
mpm[1] = modeList[1];
mpm[2] = modeList[2];
}
}
else//左和上预测模式不同,numCand = 2
{
if( leftIntraMode > -1 && aboveIntraMode > -1 )//ex:在leftIntraMode,aboveIntraMode和17,34,5中选三个不同的,顺序依次
{
mpm[0] = leftIntraMode;
mpm[1] = aboveIntraMode;
numCand = 2;
int index = 0;
for( int i = 0; i < 3; i++ )
{
if( (leftIntraMode != modeList[i]) && (aboveIntraMode != modeList[i]) )
{
index = i;
break;
}
}
CHECK( index > 2, "Error" );
mpm[2] = modeList[index];
}
else
{
mpm[0] = leftIntraMode > -1 ? leftIntraMode : aboveIntraMode;
numCand = 1;
if( mpm[0] != modeList[0] )
{
mpm[1] = modeList[0];
mpm[2] = (mpm[0] != modeList[1]) ? modeList[1] : modeList[2];
}
else
{
mpm[1] = modeList[1];
mpm[2] = modeList[2];
}
}
}
return (realMode ? numCand : 0);
}