getIntraMPMs在estIntraPredLumaQT函数中被调用,用来获取MPM候选模式,MPM模式存储在mpm中。
流程大致为:获取左侧和上侧的pu帧内预测模式,然后按照left和above模式的情况,给mpm列表赋值。
MPM列表长度为6。由于宏JVET_L0165_6MPM开启,所以删掉了一些无用的代码。
int PU::getIntraMPMs( const PredictionUnit &pu, unsigned* mpm, const ChannelType &channelType /*= CHANNEL_TYPE_LUMA*/ )
{
const int numMPMs = NUM_MOST_PROBABLE_MODES; //6
#if JVET_L0283_MULTI_REF_LINE //MRL
const int extendRefLine = (channelType == CHANNEL_TYPE_LUMA) ? pu.multiRefIdx : 0;
#endif
{
int numCand = -1;
int leftIntraDir = PLANAR_IDX, aboveIntraDir = PLANAR_IDX;
const CompArea &area = pu.block(getFirstComponentOfChannel(channelType));
const Position posRT = area.topRight();
const Position posLB = area.bottomLeft(); //右上、左下坐标
// Get intra direction of left PU 左侧pu
const PredictionUnit *puLeft = pu.cs->getPURestricted(posLB.offset(-1, 0), pu, channelType);
if (puLeft && CU::isIntra(*puLeft->cu))
{
leftIntraDir = puLeft->intraDir[channelType]; //左侧pu的帧内模式
}
// Get intra direction of above PU 上侧pu
const PredictionUnit *puAbove = pu.cs->getPURestricted(posRT.offset(0, -1), pu, channelType);
if (puAbove && CU::isIntra(*puAbove->cu) && CU::isSameCtu(*pu.cu, *puAbove->cu))
{
aboveIntraDir = puAbove->intraDir[channelType]; //上侧pu的帧内模式
}
CHECK(2 >= numMPMs, "Invalid number of most probable modes");
const int offset = (int)NUM_LUMA_MODE - 6; //67-6
const int mod = offset + 3; //61+3
/然后根据左侧和上侧pu的亮度帧内模式,构建mpm列表
#if JVET_L0283_MULTI_REF_LINE
if (extendRefLine) //MRL
{
int modeIdx = 0;
int angularMode[2