您的位置:首页 > 编程语言

FVC/JEM代码学习3:getIntraDirPredictor

2018-01-15 22:26 881 查看
(个人理解)
    该函数的作用就是在亮度分量预测时在67种模式中选取6个MPMs。首先是查看当前CU邻近5个CU的亮度预测模式和DC和planar模式,加入顺序为左,上,planar,DC,左下,右上,最后是左上(如果该模式MPM中以存在,不重复添加)。如果这几个模式形成的MPM的数目不足6,则将列表里的角度模式的相邻模式也加入。如果还不足6,则加入默认模式。默认模式列表为{PLANAR_IDX, DC_IDX, VER_IDX, HOR_IDX, 2, DIA_IDX(34)}。Void TComDataCU::getIntraDirPredictor( UInt uiAbsPartIdx, Int uiIntraDirPred[NUM_MOST_PROBABLE_MODES], const ComponentID compID

#if VCEG_AZ07_INTRA_65ANG_MODES && !JVET_C0055_INTRA_MPM
, Int &iLeftAboveCase
#endif
, Int* piMode )
{
#if JVET_C0055_INTRA_MPM
// This function is not used for chroma texture type.
// If it is used for chroma, DM mode should be converted to real mode during MPM list derivation.
#if !JVET_E0062_MULTI_DMS
assert( isLuma(compID) );
#endif

const ChannelType chType = toChannelType(compID);//表示三个分量中的哪一个;
Bool includedMode[NUM_INTRA_MODE];//NUM_INTRA_MODE=73;
memset( includedMode, false, sizeof(includedMode) );

UInt modeIdx = 0, partIdx;

#if VCEG_AZ07_INTRA_65ANG_MODES
const Int offset = 62;
#else
const Int offset = 29;
#endif
const Int mod = offset + 3;

UInt width = getWidth(uiAbsPartIdx);//64;
UInt height = getHeight(uiAbsPartIdx);//64;

#if !JVET_C0024_QTBT
if( getPartitionSize(uiAbsPartIdx) == SIZE_NxN )
{
width >>= 1;
height >>= 1;
}
#endif

UInt partIdxLT = m_absZIdxInCtu + uiAbsPartIdx;
UInt partIdxRT = g_auiRasterToZscan [g_auiZscanToRaster[ partIdxLT ] + width / m_pcPic->getMinCUWidth() - 1 ];
UInt partIdxLB = g_auiRasterToZscan [g_auiZscanToRaster[ partIdxLT ] + ( (height / m_pcPic->getMinCUHeight()) - 1 ) * m_pcPic->getNumPartInCtuWidth()];
#if JVET_E0062_MULTI_DMS//Cb分量最大模式数量为5,其他为6;
Int iMaxModeNum = (compID == COMPONENT_Cb ? NUM_DM_MODES : NUM_MOST_PROBABLE_MODES);
if(compID == COMPONENT_Cb)
{
Int i = 0;
for(; i< NUM_DM_MODES; i++)
{
if (uiIntraDirPred[i] == INVALID_CHROMAMODE)
{
break;
}
else
{
includedMode[uiIntraDirPred[i]] = true;
}
}
#if COM16_C806_LMCHROMA
includedMode[LM_CHROMA_IDX] = true;
#endif

#if JVET_E0077_MMLM
includedMode[MMLM_CHROMA_IDX] = true;
#endif
#if JVET_E0077_LM_MF
for (Int iF = 0; iF < LM_FILTER_NUM; iF++)//LM_FILTER_NUM=4;
{
includedMode[LM_CHROMA_F1_IDX + iF] = true;
}
#endif

modeIdx = i;
}
#endif
// left
TComDataCU *cu = getPULeft( partIdx, partIdxLB );//得到左边的相邻PU;
if( cu && cu->isIntra(partIdx) )//若左边相邻块存在且使帧内预测模式;
{
uiIntraDirPred[modeIdx] = cu->getIntraDir( chType, partIdx );//得到左边相邻块的帧内预测方向;
if( !includedMode[uiIntraDirPred[modeIdx]] )
{
includedMode[uiIntraDirPred[modeIdx]] = true;
modeIdx++;
}
}
#if JVET_E0062_MULTI_DMS
if(compID == COMPONENT_Cb && modeIdx == NUM_DM_MODES )
{
return;
}
#endif

// above
cu = getPUAbove( partIdx, partIdxRT );
if( cu && cu->isIntra(partIdx) )
{
uiIntraDirPred[modeIdx] = cu->getIntraDir( chType, partIdx );//若上边相邻块存在且使帧内预测模式;
if( !includedMode[uiIntraDirPred[modeIdx]] )
{
includedMode[uiIntraDirPred[modeIdx]] = true;
modeIdx++;
}
}
#if JVET_E0062_MULTI_DMS
if( compID == COMPONENT_Cb && modeIdx == NUM_DM_MODES )
{
return;
}
#endif

if( piMode )
{
*piMode = Int(modeIdx > 1) + 1;
}
#if JVET_E0062_MULTI_DMS
if(compID != COMPONENT_Cb)
{
#endif
// PLANAR mode
uiIntraDirPred[modeIdx] = PLANAR_IDX;
if( !includedMode[uiIntraDirPred[modeIdx]] )//如果没有包括Planar模式,则将该模式包括进去,并将模式索引加1;
{
includedMode[uiIntraDirPred[modeIdx]] = true;
modeIdx++;
}

// DC mode
#if !VCEG_AZ07_INTRA_65ANG_MODES
if( modeIdx < NUM_MOST_PROBABLE_MODES )
#endif
{
uiIntraDirPred[modeIdx] = DC_IDX;
if( !includedMode[uiIntraDirPred[modeIdx]] )
{
includedMode[uiIntraDirPred[modeIdx]] = true;//如果没有包括DC模式,则将该模式包括进去,并将模式索引加1;
modeIdx++;
}
}
#if JVET_E0062_MULTI_DMS
}
#endif
// below left
#if !VCEG_AZ07_INTRA_65ANG_MODES
if( modeIdx < NUM_MOST_PROBABLE_MODES )
#endif
{
cu = getPUBelowLeft( partIdx, partIdxLB );
if( cu && cu->isIntra(partIdx) )//若左下相邻块存在且使帧内预测模式;
{
uiIntraDirPred[modeIdx] = cu->getIntraDir( chType, partIdx );
if( !includedMode[uiIntraDirPred[modeIdx]] )
{
includedMode[uiIntraDirPred[modeIdx]] = true;
modeIdx++;
}
}
}
#if JVET_E0062_MULTI_DMS
if( compID == COMPONENT_Cb && modeIdx == NUM_DM_MODES )
{
return;
}
#endif

// above right
#if !VCEG_AZ07_INTRA_65ANG_MODES
if( modeIdx < NUM_MOST_PROBABLE_MODES )
#endif
{
cu = getPUAboveRight( partIdx, partIdxRT );
if( cu && cu->isIntra(partIdx) )//若右上相邻块存在且使帧内预测模式;
{
uiIntraDirPred[modeIdx] = cu->getIntraDir( chType, partIdx );
if( !includedMode[uiIntraDirPred[modeIdx]] )
{
includedMode[uiIntraDirPred[modeIdx]] = true;
modeIdx++;
}
}
}
#if JVET_E0062_MULTI_DMS
if( compID == COMPONENT_Cb && modeIdx == NUM_DM_MODES )
{
return;
}
#endif

//above left
#if JVET_E0062_MULTI_DMS
if( modeIdx < iMaxModeNum )//iMaxModeNum=6;
#else
if( modeIdx < NUM_MOST_PROBABLE_MODES )
#endif
{
cu = getPUAboveLeft( partIdx, partIdxLT );
if( cu && cu->isIntra(partIdx) )//若左上相邻块存在且使帧内预测模式;
{
uiIntraDirPred[modeIdx] = cu->getIntraDir( chType, partIdx );
if( !includedMode[uiIntraDirPred[modeIdx]] )
{
includedMode[uiIntraDirPred[modeIdx]] = true;
modeIdx++;
}
}
}
#if JVET_E0062_MULTI_DMS
if( compID == COMPONENT_Cb && modeIdx == NUM_DM_MODES )
{
return;
}

if(compID == COMPONENT_Cb)
{
// PLANAR mode
uiIntraDirPred[modeIdx] = PLANAR_IDX;
if( !includedMode[uiIntraDirPred[modeIdx]] )
{
includedMode[uiIntraDirPred[modeIdx]] = true;
modeIdx++;
}

if( compID == COMPONENT_Cb && modeIdx == NUM_DM_MODES )
{
return;
}

// DC mode
#if !VCEG_AZ07_INTRA_65ANG_MODES
if( modeIdx < NUM_MOST_PROBABLE_MODES )
#endif
{
uiIntraDirPred[modeIdx] = DC_IDX;
if( !includedMode[uiIntraDirPred[modeIdx]] )
{
includedMode[uiIntraDirPred[modeIdx]] = true;
modeIdx++;
}
}

if( compID == COMPONENT_Cb && modeIdx == NUM_DM_MODES )
{
return;
}
}
#endif
UInt numAddedModes = modeIdx;

// -+1 derived modes
#if JVET_E0062_MULTI_DMS //如果MPM里的候选模式个数少于6,则将列表中角度模式相邻的模式加入;
for( UInt idx = 0; idx < numAddedModes && modeIdx < iMaxModeNum; idx++ )
#else
for( UInt idx = 0; idx < numAddedModes && modeIdx < NUM_MOST_PROBABLE_MODES; idx++ )
#endif
{
UInt mode = uiIntraDirPred[idx];

// directional mode
if( mode <= DC_IDX )
{
continue;
}

// -1
uiIntraDirPred[modeIdx] = ((mode + offset) % mod) + 2;

if( !includedMode[uiIntraDirPred[modeIdx]] )
{
includedMode[uiIntraDirPred[modeIdx]] = true;
modeIdx++;
}

#if JVET_E0062_MULTI_DMS
if( modeIdx == iMaxModeNum )
#else
if( modeIdx == NUM_MOST_PROBABLE_MODES )
#endif
{
break;
}

// +1
uiIntraDirPred[modeIdx] = ((mode - 1) % mod) + 2;

if( !includedMode[uiIntraDirPred[modeIdx]] )
{
includedMode[uiIntraDirPred[modeIdx]] = true;
modeIdx++;
}
}

// default modes
UInt defaultIntraModes[] = {PLANAR_IDX, DC_IDX, VER_IDX, HOR_IDX, 2, DIA_IDX};
assert( modeIdx > 1 );
#if JVET_E0062_MULTI_DMS
for( UInt idx = 2; idx < iMaxModeNum && modeIdx < iMaxModeNum; idx++)//如果MPM里的模式个数还小于6,则加入默认模式;
#else
for( UInt idx = 2; idx < NUM_MOST_PROBABLE_MODES && modeIdx < NUM_MOST_PROBABLE_MODES; idx++ )
#endif
{
uiIntraDirPred[modeIdx] = defaultIntraModes[idx];
if( !includedMode[uiIntraDirPred[modeIdx]] )
{
includedMode[uiIntraDirPred[modeIdx]] = true;
modeIdx++;
}
}
#if JVET_E0062_MULTI_DMS
assert( modeIdx == iMaxModeNum );

#if JVET_E0062_MULTI_DMS
for (UInt i=0; i<iMaxModeNum; i++)
#else
for (UInt i=0; i<NUM_MOST_PROBABLE_MODES; i++)
#endif
{
#if VCEG_AZ07_INTRA_65ANG_MODES
assert(uiIntraDirPred[i] < (NUM_INTRA_MODE-1));
#else
assert(uiIntraDirPred[i] < 35);
#endif
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: