Newer
Older
{
continue;
}
pu.intraDir[1] = mode; // temporary assigned, for SATD checking.
int64_t sad = 0;
int64_t sadCb = 0;
int64_t satdCb = 0;
int64_t sadCr = 0;
int64_t satdCr = 0;
CodingStructure& cs = *(pu.cs);
CompArea areaCb = pu.Cb();
PelBuf orgCb = cs.getOrgBuf(areaCb);
PelBuf predCb = cs.getPredBuf(areaCb);
m_pcRdCost->setDistParam(distParamSad, orgCb, predCb, pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cb, false);
m_pcRdCost->setDistParam(distParamSatd, orgCb, predCb, pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cb, true);
distParamSad.applyWeight = false;
distParamSatd.applyWeight = false;
if (PU::isLMCMode(mode))
{
predIntraChromaLM(COMPONENT_Cb, predCb, pu, areaCb, mode);
}
else
{
Alexey Filippov
committed
initPredIntraParams(pu, pu.Cb(), *pu.cs->sps);
predIntraAng(COMPONENT_Cb, predCb, pu);
sadCb = distParamSad.distFunc(distParamSad) * 2;
satdCb = distParamSatd.distFunc(distParamSatd);
sad += std::min(sadCb, satdCb);
CompArea areaCr = pu.Cr();
PelBuf orgCr = cs.getOrgBuf(areaCr);
PelBuf predCr = cs.getPredBuf(areaCr);
m_pcRdCost->setDistParam(distParamSad, orgCr, predCr, pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cr, false);
m_pcRdCost->setDistParam(distParamSatd, orgCr, predCr, pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cr, true);
distParamSad.applyWeight = false;
distParamSatd.applyWeight = false;
if (PU::isLMCMode(mode))
{
predIntraChromaLM(COMPONENT_Cr, predCr, pu, areaCr, mode);
}
else
{
Alexey Filippov
committed
initPredIntraParams(pu, pu.Cr(), *pu.cs->sps);
predIntraAng(COMPONENT_Cr, predCr, pu);
sadCr = distParamSad.distFunc(distParamSad) * 2;
satdCr = distParamSatd.distFunc(distParamSatd);
sad += std::min(sadCr, satdCr);
#if JVET_AB0143_CCCM_TS
#if MMLM
#if JVET_AC0054_GLCCCM
uint32_t chromaCandCccmModes[CCCM_NUM_MODES] = { LM_CHROMA_IDX, MDLM_L_IDX, MDLM_T_IDX, MMLM_CHROMA_IDX, MMLM_L_IDX, MMLM_T_IDX
, LM_CHROMA_IDX, MDLM_L_IDX, MDLM_T_IDX, MMLM_CHROMA_IDX, MMLM_L_IDX, MMLM_T_IDX };
#else
uint32_t chromaCandCccmModes[CCCM_NUM_MODES] = { LM_CHROMA_IDX, MDLM_L_IDX, MDLM_T_IDX, MMLM_CHROMA_IDX, MMLM_L_IDX, MMLM_T_IDX };
#endif
#else
#if JVET_AC0054_GLCCCM
uint32_t chromaCandCccmModes[CCCM_NUM_MODES] = { LM_CHROMA_IDX, MDLM_L_IDX, MDLM_T_IDX
, LM_CHROMA_IDX, MDLM_L_IDX, MDLM_T_IDX };
uint32_t chromaCandCccmModes[CCCM_NUM_MODES] = { LM_CHROMA_IDX, MDLM_L_IDX, MDLM_T_IDX };
#if JVET_AD0202_CCCM_MDF
int satdCccmFilterIndex[TOTAL_NUM_CCCM_MODES];
#if JVET_AC0054_GLCCCM
int satdCccmFlagList[TOTAL_NUM_CCCM_MODES];
#endif
#else
#if JVET_AC0054_GLCCCM
int satdCccmFlagList[CCCM_NUM_MODES];
#endif
#if JVET_AC0147_CCCM_NO_SUBSAMPLING
#if JVET_AD0202_CCCM_MDF
int64_t satdCccmSortedCost[2][TOTAL_NUM_CCCM_MODES];
int satdCccmModeList[2][TOTAL_NUM_CCCM_MODES];
for (int i = 0; i < CCCM_NUM_PRED_FILTER; i++)
{
int startIdx = i * CCCM_NUM_MODES;
for (int j = 0; j < CCCM_NUM_MODES; j++)
{
int currCccmModeIdx = startIdx + j;
satdCccmSortedCost[0][currCccmModeIdx] = LLONG_MAX; // for the mode not pre-select by SATD, do RDO by default, so set the initial value 0.
satdCccmSortedCost[1][currCccmModeIdx] = LLONG_MAX; // for the mode not pre-select by SATD, do RDO by default, so set the initial value 0.
satdCccmModeList[0][currCccmModeIdx] = chromaCandCccmModes[j];
satdCccmModeList[1][currCccmModeIdx] = chromaCandCccmModes[j];
#if JVET_AC0054_GLCCCM
satdCccmFlagList[currCccmModeIdx] = j < (CCCM_NUM_MODES / 2) ? 1 : 2; // 1: cccm, 2: glCccm
#endif
satdCccmFilterIndex[currCccmModeIdx] = i;
}
}
#else
int64_t satdCccmSortedCost[2][CCCM_NUM_MODES];
int satdCccmModeList[2][CCCM_NUM_MODES];
for (int i = 0; i < CCCM_NUM_MODES; i++)
{
satdCccmSortedCost[0][i] = LLONG_MAX; // for the mode not pre-select by SATD, do RDO by default, so set the initial value 0.
satdCccmSortedCost[1][i] = LLONG_MAX; // for the mode not pre-select by SATD, do RDO by default, so set the initial value 0.
satdCccmModeList[0][i] = chromaCandCccmModes[i];
satdCccmModeList[1][i] = chromaCandCccmModes[i];
#if JVET_AC0054_GLCCCM
satdCccmFlagList[i] = i < (CCCM_NUM_MODES / 2) ? 1 : 2; // 1: cccm, 2: glCccm
#endif
int64_t bestCccmCost[2] = { LLONG_MAX, LLONG_MAX};
bool isCccmFullEnabled = PU::cccmSingleModeAvail(pu, LM_CHROMA_IDX);
bool isCccmLeftEnabled = PU::isLeftCccmMode(pu, MDLM_L_IDX);
bool isCccmTopEnabled = PU::isTopCccmMode(pu, MDLM_T_IDX);
#if MMLM
bool isMultiCccmFullEnabled = PU::cccmMultiModeAvail(pu, MMLM_CHROMA_IDX);
bool isMultiCccmLeftEnabled = PU::cccmMultiModeAvail(pu, MMLM_L_IDX);
bool isMultiCccmTopEnabled = PU::cccmMultiModeAvail(pu, MMLM_T_IDX);
#endif
#if JVET_AD0202_CCCM_MDF
bool isMultiCccmFullEnabled2 = PU::isMultiCccmWithMdf(pu, MMLM_CHROMA_IDX);
bool isMultiCccmLeftEnabled2 = PU::isMultiCccmWithMdf(pu, MMLM_L_IDX);
bool isMultiCccmTopEnabled2 = PU::isMultiCccmWithMdf(pu, MMLM_T_IDX);
#endif
const UnitArea localUnitArea(cs.area.chromaFormat, Area(0, 0, (pu.Cb().width) << 1, (pu.Cb().height) << 1));
#if JVET_AD0202_CCCM_MDF
PelUnitBuf cccmStorage[2][TOTAL_NUM_CCCM_MODES];
#else
PelUnitBuf cccmStorage[2][CCCM_NUM_MODES];
pu.cccmFlag = 1;
#if JVET_AD0202_CCCM_MDF
pu.cccmNoSubFlag = 1;
xGetLumaRecPixels(pu, pu.Cb());
pu.cccmNoSubFlag = 0;
xGetLumaRecPixels(pu, pu.Cb());
xGetLumaRecPixels(pu, pu.Cb(), 1);
xGetLumaRecPixels(pu, pu.Cb(), 2);
xGetLumaRecPixels(pu, pu.Cb(), 3);
#endif
for (int sub = 0; sub < pu.cu->slice->getSPS()->getUseCccm(); sub++)
{
pu.cccmNoSubFlag = sub;
#if !JVET_AD0202_CCCM_MDF
xGetLumaRecPixels(pu, pu.Cb());
bool isCCCMEnabled = false;
for (int idx = 0; idx < CCCM_NUM_MODES; idx++)
{
#if JVET_AC0054_GLCCCM
if (sub && idx >= CCCM_NUM_MODES / 2)
{
continue;
}
#endif
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
int mode = chromaCandCccmModes[idx];
if (idx == 0)
{
isCCCMEnabled = isCccmFullEnabled;
pu.cccmFlag = 1;
}
else if (idx == 1)
{
isCCCMEnabled = isCccmLeftEnabled;
pu.cccmFlag = 2;
}
else if (idx == 2)
{
isCCCMEnabled = isCccmTopEnabled;
pu.cccmFlag = 3;
}
#if MMLM
else if (idx == 3)
{
isCCCMEnabled = isMultiCccmFullEnabled;
pu.cccmFlag = 1;
}
else if (idx == 4)
{
isCCCMEnabled = isMultiCccmLeftEnabled;
pu.cccmFlag = 2;
}
else if (idx == 5)
{
isCCCMEnabled = isMultiCccmTopEnabled;
pu.cccmFlag = 3;
}
#endif
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
#if JVET_AC0054_GLCCCM
if (idx < CCCM_NUM_MODES / 2)
{
pu.glCccmFlag = 0;
}
else
{
pu.glCccmFlag = 1;
#if MMLM
isCCCMEnabled = idx == 6 ? isCccmFullEnabled
: idx == 7 ? isCccmLeftEnabled
: idx == 8 ? isCccmTopEnabled
: idx == 9 ? isMultiCccmFullEnabled
: idx == 10 ? isMultiCccmLeftEnabled : isMultiCccmTopEnabled;
pu.cccmFlag = idx == 6 ? 1
: idx == 7 ? 2
: idx == 8 ? 3
: idx == 9 ? 1
: idx == 10 ? 2 : 3;
#else
isCCCMEnabled = idx == 3 ? isCccmFullEnabled
: idx == 4 ? isCccmLeftEnabled : isCccmTopEnabled;
pu.cccmFlag = idx == 3 ? 1
: idx == 4 ? 2 : 3;
#endif
#if JVET_AD0202_CCCM_MDF
if (isCCCMEnabled)
{
if (m_skipCCCMwithMdfSATD)
{
if (m_isCccmWithMdfEnabledInRdo[4][mode] == 0)
{
continue;
}
}
}
#endif
if (isCCCMEnabled)
{
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
#if JVET_AD0202_CCCM_MDF
for (int32_t filterIdx = 0; filterIdx < CCCM_NUM_PRED_FILTER; filterIdx++)
{
if (filterIdx > 0)
{
if (sub == 1 || idx > 5)
{
continue;
}
if (m_skipCCCMwithMdfSATD)
{
if (m_isCccmWithMdfEnabledInRdo[filterIdx][mode] == 0)
{
continue;
}
}
if (mode == MMLM_CHROMA_IDX && !isMultiCccmFullEnabled2)
{
continue;
}
else if (mode == MMLM_L_IDX && !isMultiCccmLeftEnabled2)
{
continue;
}
else if (mode == MMLM_T_IDX && !isMultiCccmTopEnabled2)
{
continue;
}
}
else if (sub == 0 && idx <= 5)
{
if (m_skipCCCMwithMdfSATD)
{
if (m_isCccmWithMdfEnabledInRdo[filterIdx][mode] == 0)
{
continue;
}
}
}
pu.cccmMultiFilterIdx = filterIdx;
#endif
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
pu.intraDir[1] = mode; // temporary assigned, for SATD checking.
if ( ( sub == 1 ) && m_skipCCCMSATD )
{
if (m_isCccmNoSubModeEnabledInRdo[mode] == 0)
{
continue;
}
}
int64_t sad = 0;
int64_t sadCb = 0;
int64_t satdCb = 0;
int64_t sadCr = 0;
int64_t satdCr = 0;
CodingStructure& cs = *(pu.cs);
DistParam distParamSadCb;
DistParam distParamSatdCb;
DistParam distParamSadCr;
DistParam distParamSatdCr;
#if JVET_AD0202_CCCM_MDF
const int cccmBufferIdx = filterIdx * CCCM_NUM_MODES + idx;
cccmStorage[sub][cccmBufferIdx] = m_cccmStorage[sub][cccmBufferIdx].getBuf(localUnitArea);
#else
cccmStorage[sub][idx] = m_cccmStorage[sub][idx].getBuf(localUnitArea);
CompArea areaCb = pu.Cb();
PelBuf orgCb = cs.getOrgBuf(areaCb);
CompArea areaCr = pu.Cr();
PelBuf orgCr = cs.getOrgBuf(areaCr);
#if JVET_AD0202_CCCM_MDF
m_pcRdCost->setDistParam(distParamSadCb, orgCb, cccmStorage[sub][cccmBufferIdx].Cb(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cb, false);
m_pcRdCost->setDistParam(distParamSatdCb, orgCb, cccmStorage[sub][cccmBufferIdx].Cb(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cb, true);
#else
m_pcRdCost->setDistParam(distParamSadCb, orgCb, cccmStorage[sub][idx].Cb(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cb, false);
m_pcRdCost->setDistParam(distParamSatdCb, orgCb, cccmStorage[sub][idx].Cb(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cb, true);
distParamSadCb.applyWeight = false;
distParamSatdCb.applyWeight = false;
#if JVET_AD0202_CCCM_MDF
m_pcRdCost->setDistParam(distParamSadCr, orgCr, cccmStorage[sub][cccmBufferIdx].Cr(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cr, false);
m_pcRdCost->setDistParam(distParamSatdCr, orgCr, cccmStorage[sub][cccmBufferIdx].Cr(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cr, true);
#else
m_pcRdCost->setDistParam(distParamSadCr, orgCr, cccmStorage[sub][idx].Cr(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cr, false);
m_pcRdCost->setDistParam(distParamSatdCr, orgCr, cccmStorage[sub][idx].Cr(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cr, true);
distParamSadCr.applyWeight = false;
distParamSatdCr.applyWeight = false;
#if JVET_AD0202_CCCM_MDF
predIntraCCCM(pu, cccmStorage[sub][cccmBufferIdx].Cb(), cccmStorage[sub][cccmBufferIdx].Cr(), mode);
#else
predIntraCCCM(pu, cccmStorage[sub][idx].Cb(), cccmStorage[sub][idx].Cr(), mode);
sadCb = distParamSadCb.distFunc(distParamSadCb) * 2;
satdCb = distParamSatdCb.distFunc(distParamSatdCb);
sad += std::min(sadCb, satdCb);
sadCr = distParamSadCr.distFunc(distParamSadCr) * 2;
satdCr = distParamSatdCr.distFunc(distParamSatdCr);
sad += std::min(sadCr, satdCr);
#if JVET_AD0202_CCCM_MDF
satdCccmSortedCost[sub][cccmBufferIdx] = sad;
#else
satdCccmSortedCost[sub][idx] = sad;
if (sad < bestCccmCost[sub])
{
bestCccmCost[sub] = sad;
}
#if JVET_AD0202_CCCM_MDF
}
#endif
#if JVET_AC0054_GLCCCM
int tempGlCccmFlag = 0;
#endif
int tempCccmIdx = 0;
int64_t tempCccmCost = 0;
#if JVET_AC0054_GLCCCM
#if JVET_AD0202_CCCM_MDF
for (int i = 1; i < 7; i++)
#else
for (int i = 1; i < CCCM_NUM_MODES; i++)
#if MMLM
for (int i = 1; i < 4; i++)
#else
for (int i = 1; i < 3; i++)
#if JVET_AD0202_CCCM_MDF
for (int j = i + 1; j < VALID_NUM_CCCM_MODES; j++)
#else
for (int j = i + 1; j < CCCM_NUM_MODES; j++)
{
if (satdCccmSortedCost[0][j] < satdCccmSortedCost[0][i])
{
tempCccmIdx = satdCccmModeList[0][i];
satdCccmModeList[0][i] = satdCccmModeList[0][j];
satdCccmModeList[0][j] = tempCccmIdx;
tempCccmCost = satdCccmSortedCost[0][i];
satdCccmSortedCost[0][i] = satdCccmSortedCost[0][j];
satdCccmSortedCost[0][j] = tempCccmCost;
#if JVET_AC0054_GLCCCM
tempGlCccmFlag = satdCccmFlagList[i];
satdCccmFlagList[i] = satdCccmFlagList[j];
satdCccmFlagList[j] = tempGlCccmFlag;
#endif
#if JVET_AD0202_CCCM_MDF
tempCccmIdx = satdCccmFilterIndex[i];
satdCccmFilterIndex[i] = satdCccmFilterIndex[j];
satdCccmFilterIndex[j] = tempCccmIdx;
}
}
}
#if MMLM
bool isCccmModeEnabledInRdo[2][MMLM_T_IDX + 1] = { false };
#if !JVET_AD0202_CCCM_MDF
isCccmModeEnabledInRdo[0][satdCccmModeList[0][0]] = true;
#if JVET_AC0054_GLCCCM
bool isGlCccmModeEnabledInRdo[MMLM_T_IDX + 1] = { false };
#if !JVET_AD0202_CCCM_MDF
if (satdCccmFlagList[0] == 2)
{
isCccmModeEnabledInRdo[0][satdCccmModeList[0][0]] = false;
isGlCccmModeEnabledInRdo[satdCccmModeList[0][0]] = true;
}
#endif
#endif
#if JVET_AD0202_CCCM_MDF
bool isCccmWithMulDownSamplingEnabledInRdo[MMLM_T_IDX + 1][CCCM_NUM_PRED_FILTER] = { false };
isCccmWithMulDownSamplingEnabledInRdo[satdCccmModeList[0][0]][satdCccmFilterIndex[0]] = true;
for (int i = 1; i < 7; i++)
#else
for (int i = 1; i < 4; i++)
#else
bool isCccmModeEnabledInRdo[MDLM_T_IDX + 1] = { false };
isCccmModeEnabledInRdo[satdCccmModeList[0]] = true;
#if JVET_AC0054_GLCCCM
bool isGlCccmModeEnabledInRdo[MDLM_T_IDX + 1] = { false };
if (satdCccmFlagList[0] == 2)
{
isCccmModeEnabledInRdo[0][satdCccmModeList[0][0]] = false;
isGlCccmModeEnabledInRdo[satdCccmModeList[0][0]] = true;
}
#endif
for (int i = 1; i < 3; i++)
#endif
{
if (satdCccmSortedCost[0][i] >= 1.15 * bestCccmCost[0])
{
break;
}
#if JVET_AC0054_GLCCCM
if (satdCccmFlagList[i] == 2)
{
isGlCccmModeEnabledInRdo[satdCccmModeList[0][i]] = true;
}
else
{
#if JVET_AD0202_CCCM_MDF
isCccmWithMulDownSamplingEnabledInRdo[satdCccmModeList[0][i]][satdCccmFilterIndex[i]] = true;
#else
isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]] = true;
isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]] = true;
#if JVET_AD0202_CCCM_MDF
if (m_skipCCCMwithMdfSATD == false)
{
m_skipCCCMwithMdfSATD = true;
for (int i = LM_CHROMA_IDX; i <= MMLM_T_IDX; i++)
{
m_isCccmWithMdfEnabledInRdo[4][i] = isGlCccmModeEnabledInRdo[i] ? 1 : 0;
for (int j = 0; j < 4; j++)
{
m_isCccmWithMdfEnabledInRdo[j][i] = isCccmWithMulDownSamplingEnabledInRdo[i][j] ? 1 : 0;
}
}
}
#endif
if (pu.cu->slice->getSPS()->getUseCccm() == 2)
{
if (bestCccmCost[1] < bestCccmCost[0])
{
#if MMLM
#if JVET_AD0202_CCCM_MDF
for (int i = 1; i < 7; i++)
#else
for (int i = 0; i < 4; i++)
#else
for (int i = 0; i < 3; i++)
#endif
{
#if JVET_AD0202_CCCM_MDF
if (isCccmWithMulDownSamplingEnabledInRdo[satdCccmModeList[0][i]][satdCccmFilterIndex[i]] && (satdCccmSortedCost[0][i] >= 1.2 * bestCccmCost[1]))
{
isCccmWithMulDownSamplingEnabledInRdo[satdCccmModeList[0][i]][satdCccmFilterIndex[i]] = false;
}
#else
if (isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]] && (satdCccmSortedCost[0][i] >= 1.2 * bestCccmCost[1]))
{
isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]] = false;
}
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
else
{
bestCccmCost[0] = satdCccmSortedCost[0][i];
}
}
}
else
{
bestCccmCost[1] = bestCccmCost[0];
}
tempCccmIdx = 0;
tempCccmCost = 0;
for (int i = 1; i < 2; i++)
{
for (int j = i + 1; j < 6; j++)
{
if (satdCccmSortedCost[1][j] < satdCccmSortedCost[1][i])
{
tempCccmIdx = satdCccmModeList[1][i];
satdCccmModeList[1][i] = satdCccmModeList[1][j];
satdCccmModeList[1][j] = tempCccmIdx;
tempCccmCost = satdCccmSortedCost[1][i];
satdCccmSortedCost[1][i] = satdCccmSortedCost[1][j];
satdCccmSortedCost[1][j] = tempCccmCost;
}
}
}
isCccmModeEnabledInRdo[1][satdCccmModeList[1][0]] = true;
for (int i = 1; i < 2; i++)
{
if (satdCccmSortedCost[1][i] >= CCCM_NO_SUB_WEIGHT * bestCccmCost[1])
{
#if !JVET_AD0202_CCCM_MDF
#if JVET_AC0054_GLCCCM
if (satdCccmSortedCost[1][i - 1] > bestCccmCost[0] && satdCccmFlagList[0] != 2)
#else
if (satdCccmSortedCost[1][i - 1] > bestCccmCost[0])
{
bestCccmCost[0] = satdCccmSortedCost[1][i - 1];
}
bestCccmCost[1] = satdCccmSortedCost[1][i - 1];
break;
}
isCccmModeEnabledInRdo[1][satdCccmModeList[1][i]] = true;
}
#if JVET_AD0202_CCCM_MDF
bestCccmCost[1] = (isCccmModeEnabledInRdo[1][satdCccmModeList[1][1]] && satdCccmSortedCost[1][0] < satdCccmSortedCost[1][1]) ? satdCccmSortedCost[1][1] : satdCccmSortedCost[1][0];
bestCccmCost[0] = (bestCccmCost[1] > bestCccmCost[0]) ? bestCccmCost[1] : bestCccmCost[0];
bestCccmCost[0] = (satdCccmSortedCost[0][0] > bestCccmCost[0]) ? satdCccmSortedCost[0][0] : bestCccmCost[0];
#endif
if (m_skipCCCMSATD == false)
{
m_skipCCCMSATD = true;
for (int i = 0; i < (MMLM_T_IDX + 1); i++)
{
m_isCccmNoSubModeEnabledInRdo[i] = isCccmModeEnabledInRdo[1][i];
}
}
}
pu.cccmFlag = 0;
pu.cccmNoSubFlag = 0;
#if JVET_AC0054_GLCCCM
pu.glCccmFlag = 0;
#endif
#if JVET_AD0202_CCCM_MDF
pu.cccmMultiFilterIdx = 0;
#endif
int64_t satdCccmSortedCost[CCCM_NUM_MODES];
int satdCccmModeList[CCCM_NUM_MODES];
for (int i = 0; i < CCCM_NUM_MODES; i++)
{
satdCccmSortedCost[i] = LLONG_MAX; // for the mode not pre-select by SATD, do RDO by default, so set the initial value 0.
satdCccmModeList[i] = chromaCandCccmModes[i];
}
int64_t bestCccmCost = LLONG_MAX;
bool isCccmFullEnabled = PU::cccmSingleModeAvail(pu, LM_CHROMA_IDX);
bool isCccmLeftEnabled = PU::isLeftCccmMode(pu, MDLM_L_IDX);
bool isCccmTopEnabled = PU::isTopCccmMode(pu, MDLM_T_IDX);
#if MMLM
bool isMultiCccmFullEnabled = PU::cccmMultiModeAvail(pu, MMLM_CHROMA_IDX);
bool isMultiCccmLeftEnabled = PU::cccmMultiModeAvail(pu, MMLM_L_IDX);
bool isMultiCccmTopEnabled = PU::cccmMultiModeAvail(pu, MMLM_T_IDX);
#endif
const UnitArea localUnitArea(cs.area.chromaFormat, Area(0, 0, (pu.Cb().width) << 1, (pu.Cb().height) << 1));
pu.cccmFlag = 1;
xGetLumaRecPixels(pu, pu.Cb());
bool isCCCMEnabled = false;
for (int idx = 0; idx < CCCM_NUM_MODES; idx++)
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
{
int mode = chromaCandCccmModes[idx];
if (idx == 0)
{
isCCCMEnabled = isCccmFullEnabled;
pu.cccmFlag = 1;
}
else if (idx == 1)
{
isCCCMEnabled = isCccmLeftEnabled;
pu.cccmFlag = 2;
}
else if (idx == 2)
{
isCCCMEnabled = isCccmTopEnabled;
pu.cccmFlag = 3;
}
#if MMLM
else if (idx == 3)
{
isCCCMEnabled = isMultiCccmFullEnabled;
pu.cccmFlag = 1;
}
else if (idx == 4)
{
isCCCMEnabled = isMultiCccmLeftEnabled;
pu.cccmFlag = 2;
}
else if (idx == 5)
{
isCCCMEnabled = isMultiCccmTopEnabled;
pu.cccmFlag = 3;
}
#endif
if (isCCCMEnabled)
{
pu.intraDir[1] = mode; // temporary assigned, for SATD checking.
int64_t sad = 0;
int64_t sadCb = 0;
int64_t satdCb = 0;
int64_t sadCr = 0;
int64_t satdCr = 0;
CodingStructure& cs = *(pu.cs);
DistParam distParamSadCb;
DistParam distParamSatdCb;
DistParam distParamSadCr;
DistParam distParamSatdCr;
cccmStorage[idx] = m_cccmStorage[idx].getBuf(localUnitArea);
CompArea areaCb = pu.Cb();
PelBuf orgCb = cs.getOrgBuf(areaCb);
CompArea areaCr = pu.Cr();
PelBuf orgCr = cs.getOrgBuf(areaCr);
m_pcRdCost->setDistParam(distParamSadCb, orgCb, cccmStorage[idx].Cb(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cb, false);
m_pcRdCost->setDistParam(distParamSatdCb, orgCb, cccmStorage[idx].Cb(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cb, true);
distParamSadCb.applyWeight = false;
distParamSatdCb.applyWeight = false;
m_pcRdCost->setDistParam(distParamSadCr, orgCr, cccmStorage[idx].Cr(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cr, false);
m_pcRdCost->setDistParam(distParamSatdCr, orgCr, cccmStorage[idx].Cr(), pu.cs->sps->getBitDepth(CHANNEL_TYPE_CHROMA), COMPONENT_Cr, true);
distParamSadCr.applyWeight = false;
distParamSatdCr.applyWeight = false;
predIntraCCCM(pu, cccmStorage[idx].Cb(), cccmStorage[idx].Cr(), mode);
sadCb = distParamSadCb.distFunc(distParamSadCb) * 2;
satdCb = distParamSatdCb.distFunc(distParamSatdCb);
sad += std::min(sadCb, satdCb);
sadCr = distParamSadCr.distFunc(distParamSadCr) * 2;
satdCr = distParamSatdCr.distFunc(distParamSatdCr);
sad += std::min(sadCr, satdCr);
satdCccmSortedCost[idx] = sad;
if (sad < bestCccmCost)
{
bestCccmCost = sad;
}
}
}
int tempCccmIdx = 0;
int64_t tempCccmCost = 0;
#if MMLM
for (int i = 1; i < 4; i++)
#else
for (int i = 1; i < 3; i++)
#endif
{
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
{
if (satdCccmSortedCost[j] < satdCccmSortedCost[i])
{
tempCccmIdx = satdCccmModeList[i];
satdCccmModeList[i] = satdCccmModeList[j];
satdCccmModeList[j] = tempCccmIdx;
tempCccmCost = satdCccmSortedCost[i];
satdCccmSortedCost[i] = satdCccmSortedCost[j];
satdCccmSortedCost[j] = tempCccmCost;
}
}
}
#if MMLM
bool isCccmModeEnabledInRdo[MMLM_T_IDX + 1] = { false };
isCccmModeEnabledInRdo[satdCccmModeList[0]] = true;
for (int i = 1; i < 4; i++)
#else
bool isCccmModeEnabledInRdo[MDLM_T_IDX + 1] = { false };
isCccmModeEnabledInRdo[satdCccmModeList[0]] = true;
for (int i = 1; i < 3; i++)
#endif
{
if (satdCccmSortedCost[i] >= 1.15 * bestCccmCost)
{
break;
}
isCccmModeEnabledInRdo[satdCccmModeList[i]] = true;
}
pu.cccmFlag = 0;
#endif
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
// sort the mode based on the cost from small to large.
int tempIdx = 0;
int64_t tempCost = 0;
for (int i = uiMinMode; i <= uiMaxMode - 1; i++)
{
for (int j = i + 1; j <= uiMaxMode - 1; j++)
{
if (satdSortedCost[j] < satdSortedCost[i])
{
tempIdx = satdModeList[i];
satdModeList[i] = satdModeList[j];
satdModeList[j] = tempIdx;
tempCost = satdSortedCost[i];
satdSortedCost[i] = satdSortedCost[j];
satdSortedCost[j] = tempCost;
}
}
}
int reducedModeNumber = 2; // reduce the number of chroma modes
#if MMLM
reducedModeNumber += 3; // Match number of RDs with the anchor
#endif
for (int i = 0; i < reducedModeNumber; i++)
{
modeIsEnable[satdModeList[uiMaxMode - 1 - i]] = 0; // disable the last reducedModeNumber modes
}
#if JVET_AC0147_CCCM_NO_SUBSAMPLING
if (pu.cu->slice->getSPS()->getUseCccm() == 2)
{
#if JVET_AC0054_GLCCCM
#if JVET_AD0202_CCCM_MDF
int32_t lastModeIdx = uiMaxMode - 1 - reducedModeNumber; ;
if (satdSortedCost[lastModeIdx] > bestCccmCost[0])
#else
if (satdSortedCost[uiMaxMode - 1 - reducedModeNumber] > bestCccmCost[0] && satdCccmFlagList[uiMaxMode - 1 - reducedModeNumber] != 2)
if (satdSortedCost[uiMaxMode - 1 - reducedModeNumber] > bestCccmCost[0])
#if JVET_AD0202_CCCM_MDF
{
modeIsEnable[satdModeList[lastModeIdx]] = 0; // disable the last reducedModeNumber modes
}
else if (satdSortedCost[lastModeIdx] < bestCccmCost[0])
{
for (int i = 6; i > 0; i--)
#else
{
modeIsEnable[satdModeList[uiMaxMode - 1 - reducedModeNumber]] = 0; // disable the last reducedModeNumber modes
}
else if (satdSortedCost[uiMaxMode - 1 - reducedModeNumber] < bestCccmCost[0])
{
for (int i = 3; i > 0; i--)
#if JVET_AC0054_GLCCCM
#if JVET_AD0202_CCCM_MDF
if ((satdCccmSortedCost[0][i] > satdSortedCost[lastModeIdx]) && isCccmWithMulDownSamplingEnabledInRdo[satdCccmModeList[0][i]][satdCccmFilterIndex[i]])
#else
if ((satdCccmSortedCost[0][i] > satdSortedCost[uiMaxMode - 1 - reducedModeNumber]) && (isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]]) && satdCccmFlagList[uiMaxMode - 1 - reducedModeNumber] != 2)
if ((satdCccmSortedCost[0][i] > satdSortedCost[uiMaxMode - 1 - reducedModeNumber]) && (isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]]))
#if JVET_AD0202_CCCM_MDF
isCccmWithMulDownSamplingEnabledInRdo[satdCccmModeList[0][i]][satdCccmFilterIndex[i]] = false;
#else
isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]] = false;
break;
}
}
}
#if JVET_AD0202_CCCM_MDF
if (satdSortedCost[lastModeIdx] < bestCccmCost[1])
{
if ((satdCccmSortedCost[1][1] > satdSortedCost[lastModeIdx]) && (isCccmModeEnabledInRdo[1][satdCccmModeList[1][1]]))
#else
if (satdSortedCost[uiMaxMode - 1 - reducedModeNumber] < bestCccmCost[1])
{
if ((satdCccmSortedCost[1][1] > satdSortedCost[uiMaxMode - 1 - reducedModeNumber]) && (isCccmModeEnabledInRdo[1][satdCccmModeList[1][1]]))
{
isCccmModeEnabledInRdo[1][satdCccmModeList[1][1]] = false;
}
}
}
#endif

Karsten Suehring
committed
// save the dist
Distortion baseDist = cs.dist;
bool testBDPCM = true;
testBDPCM = testBDPCM && CU::bdpcmAllowed(cu, COMPONENT_Cb) && cu.ispMode == 0 && cu.mtsFlag == 0 && cu.lfnstIdx == 0;
#if JVET_Z0050_DIMD_CHROMA_FUSION
double dBestNonLmCost = MAX_DOUBLE;
#if JVET_AC0119_LM_CHROMA_FUSION
int bestNonLmMode = -1;
#else
#if ENABLE_DIMD
int bestNonLmMode = (cu.slice->getSPS()->getUseDimd()) ? DIMD_CHROMA_IDX : DM_CHROMA_IDX;
#else
int bestNonLmMode = DM_CHROMA_IDX;
#endif
#endif
#endif
#if JVET_AC0119_LM_CHROMA_FUSION
int secondNonLmMode = -1;
double dSecondNonLmCost = MAX_DOUBLE;
PelUnitBuf predStorage[2], fusionStorage[6];
const UnitArea localArea(cs.area.chromaFormat, Area(0, 0, (pu.Cb().width) << 1, (pu.Cb().height) << 1));
for (uint32_t i = 0; i < 2; i++)
{
predStorage[i] = m_predStorage[i].getBuf(localArea);
}
for (uint32_t i = 0; i < 6; i++)
{
fusionStorage[i] = m_fusionStorage[i].getBuf(localArea);
}
for (int32_t uiMode = uiMinMode - (2 * int(testBDPCM)); uiMode < uiMaxMode; uiMode++)

Karsten Suehring
committed
{
if (uiMode < 0)
{
cu.bdpcmModeChroma = -uiMode;
chromaIntraMode = cu.bdpcmModeChroma == 2 ? chromaCandModes[1] : chromaCandModes[2];
chromaIntraMode = chromaCandModes[uiMode];

Karsten Suehring
committed
cu.bdpcmModeChroma = 0;
if( PU::isLMCMode( chromaIntraMode ) && ! PU::isLMCModeEnabled( pu, chromaIntraMode ) )
{
continue;
}
if (!modeIsEnable[chromaIntraMode] && PU::isLMCModeEnabled(pu, chromaIntraMode)) // when CCLM is disable, then MDLM is disable. not use satd checking
{
continue;
}
#if JVET_Z0050_DIMD_CHROMA_FUSION && ENABLE_DIMD
if (chromaIntraMode == DIMD_CHROMA_IDX && !cu.slice->getSPS()->getUseDimd()) // when DIMD is disable, then DIMD_CHROMA is disable.
{
continue;
}
#endif
#if JVET_AC0071_DBV
if (chromaIntraMode == DBV_CHROMA_IDX && !PU::hasChromaBvFlag(pu))
{
continue;
}

Karsten Suehring
committed
cs.setDecomp( pu.Cb(), false );
cs.dist = baseDist;
//----- restore context models -----
m_CABACEstimator->getCtx() = ctxStart;
//----- chroma coding -----
pu.intraDir[1] = chromaIntraMode;
xRecurIntraChromaCodingQT( cs, partitioner, bestCostSoFar, ispType
#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS && (JVET_AB0143_CCCM_TS || JVET_AC0119_LM_CHROMA_FUSION)
, UnitBuf<Pel>()
#endif
#if JVET_AD0208_IBC_ADAPT_FOR_CAM_CAPTURED_CONTENTS
, pcInterPred
#endif
);
if( lumaUsesISP && cs.dist == MAX_UINT )
{
continue;
}

Karsten Suehring
committed
if (cs.sps->getTransformSkipEnabledFlag())

Karsten Suehring
committed
{
m_CABACEstimator->getCtx() = ctxStart;
}
uint64_t fracBits = xGetIntraFracBitsQT( cs, partitioner, false, true, -1, ispType );

Karsten Suehring
committed
Distortion uiDist = cs.dist;
double dCost = m_pcRdCost->calcRdCost( fracBits, uiDist - baseDist );
//----- compare -----
if( dCost < dBestCost )
{
if( lumaUsesISP && dCost < bestCostSoFar )
{
bestCostSoFar = dCost;
}

Karsten Suehring
committed
for( uint32_t i = getFirstComponentOfChannel( CHANNEL_TYPE_CHROMA ); i < numberValidComponents; i++ )
{
const CompArea &area = pu.blocks[i];
saveCS.getRecoBuf ( area ).copyFrom( cs.getRecoBuf ( area ) );
#if KEEP_PRED_AND_RESI_SIGNALS
saveCS.getPredBuf ( area ).copyFrom( cs.getPredBuf ( area ) );
saveCS.getResiBuf ( area ).copyFrom( cs.getResiBuf ( area ) );
#endif
saveCS.getPredBuf ( area ).copyFrom( cs.getPredBuf (area ) );
cs.picture->getPredBuf( area ).copyFrom( cs.getPredBuf (area ) );
#if JVET_Z0118_GDR
cs.updateReconMotIPM(area);
#else

Karsten Suehring
committed
cs.picture->getRecoBuf( area ).copyFrom( cs.getRecoBuf( area ) );

Karsten Suehring
committed
for( uint32_t j = 0; j < saveCS.tus.size(); j++ )
{
saveCS.tus[j]->copyComponentFrom( *orgTUs[j], area.compID );
}
}
dBestCost = dCost;
uiBestDist = uiDist;
uiBestMode = chromaIntraMode;
bestBDPCMMode = cu.bdpcmModeChroma;

Karsten Suehring
committed
}
#if JVET_AC0119_LM_CHROMA_FUSION
bool findBestNonLm = !PU::isLMCMode(chromaIntraMode) && !cu.bdpcmModeChroma && PU::hasChromaFusionFlag(pu, chromaIntraMode);
#else
bool findBestNonLm = !PU::isLMCMode(chromaIntraMode) && !cu.bdpcmModeChroma && pu.cs->slice->isIntra();
if (findBestNonLm && dCost < dBestNonLmCost)
{
#if JVET_AC0119_LM_CHROMA_FUSION
predStorage[1].Cb().copyFrom(predStorage[0].Cb());
predStorage[1].Cr().copyFrom(predStorage[0].Cr());
secondNonLmMode = bestNonLmMode;
dSecondNonLmCost = dBestNonLmCost;
predStorage[0].Cb().copyFrom(cs.getPredBuf(pu.Cb()));
predStorage[0].Cr().copyFrom(cs.getPredBuf(pu.Cr()));
#endif
bestNonLmMode = chromaIntraMode;
dBestNonLmCost = dCost;
}
#if JVET_AC0119_LM_CHROMA_FUSION
else if (findBestNonLm && dCost < dSecondNonLmCost)
{
predStorage[1].Cb().copyFrom(cs.getPredBuf(pu.Cb()));
predStorage[1].Cr().copyFrom(cs.getPredBuf(pu.Cr()));
secondNonLmMode = chromaIntraMode;