diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h index 59ade8e0b6c87c087a4458a9ff4d4e1eee36e577..2041fcf01365cd3dda1cad752aef45a89e6b96e5 100644 --- a/source/Lib/CommonLib/CommonDef.h +++ b/source/Lib/CommonLib/CommonDef.h @@ -1001,15 +1001,27 @@ static const int CCCM_DECIM_BITS = 22; static const int CCCM_DECIM_ROUND = ( 1 << (CCCM_DECIM_BITS - 1 ) ); #if JVET_AB0143_CCCM_TS #if MMLM +#if JVET_AC0054_GLCCCM +static const int CCCM_NUM_MODES = 12; +#else +static const int CCCM_NUM_MODES = 6; +#endif +#else +#if JVET_AC0054_GLCCCM static const int CCCM_NUM_MODES = 6; #else static const int CCCM_NUM_MODES = 3; #endif #endif +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING static const int CCCM_NO_SUB_NUM_PARAMS = 11; static const double CCCM_NO_SUB_WEIGHT = 1.1; #endif +#if JVET_AC0054_GLCCCM +static const int CCCM_LOC_SHIFT = 3; +static const int CCCM_LOC_OFFSET = (1 << CCCM_LOC_SHIFT); +#endif #endif #if JVET_AA0126_GLM diff --git a/source/Lib/CommonLib/Contexts.cpp b/source/Lib/CommonLib/Contexts.cpp index 25ed082fe83f3269f02fd86a7c65768abc024ff0..b7c83642d15442f387151e22ccb478c8b9304fe8 100644 --- a/source/Lib/CommonLib/Contexts.cpp +++ b/source/Lib/CommonLib/Contexts.cpp @@ -3181,7 +3181,19 @@ const CtxSet ContextSetCfg::GlmFlags = ContextSetCfg::addCtxSet #if JVET_AA0057_CCCM const CtxSet ContextSetCfg::CccmFlag = ContextSetCfg::addCtxSet ({ -#if JVET_AC0147_CCCM_NO_SUBSAMPLING +#if JVET_AC0147_CCCM_NO_SUBSAMPLING && JVET_AC0054_GLCCCM + { CNU, CNU, CNU, }, + { CNU, CNU, CNU, }, + { CNU, CNU, CNU, }, + { DWS, DWS, DWS, }, + { DWS, DWS, DWS, }, + { DWS, DWS, DWS, }, + { DWE, DWE, DWE, }, + { DWE, DWE, DWE, }, + { DWE, DWE, DWE, }, + { DWO, DWO, DWO, }, + { DWO, DWO, DWO, }, +#elif JVET_AC0147_CCCM_NO_SUBSAMPLING || JVET_AC0054_GLCCCM { CNU, CNU, }, { CNU, CNU, }, { CNU, CNU, }, @@ -4867,7 +4879,14 @@ const CtxSet ContextSetCfg::GlmFlags = ContextSetCfg::addCtxSet #if JVET_AA0057_CCCM const CtxSet ContextSetCfg::CccmFlag = ContextSetCfg::addCtxSet ({ -#if JVET_AC0147_CCCM_NO_SUBSAMPLING +#if JVET_AC0147_CCCM_NO_SUBSAMPLING && JVET_AC0054_GLCCCM + { CNU, CNU, CNU, }, + { CNU, CNU, CNU, }, + { CNU, CNU, CNU, }, + { DWS, DWS, DWS, }, + { DWS, DWS, DWS, }, + { DWS, DWS, DWS, }, +#elif JVET_AC0147_CCCM_NO_SUBSAMPLING || JVET_AC0054_GLCCCM { CNU, CNU, }, { CNU, CNU, }, { CNU, CNU, }, @@ -6056,7 +6075,12 @@ const CtxSet ContextSetCfg::GlmFlags = ContextSetCfg::addCtxSet #if JVET_AA0057_CCCM const CtxSet ContextSetCfg::CccmFlag = ContextSetCfg::addCtxSet ({ -#if JVET_AC0147_CCCM_NO_SUBSAMPLING +#if JVET_AC0147_CCCM_NO_SUBSAMPLING && JVET_AC0054_GLCCCM + { CNU, CNU, CNU, }, + { CNU, CNU, CNU, }, + { CNU, CNU, CNU, }, + { DWS, DWS, DWS, }, +#elif JVET_AC0147_CCCM_NO_SUBSAMPLING || JVET_AC0054_GLCCCM { CNU, CNU, }, { CNU, CNU, }, { CNU, CNU, }, diff --git a/source/Lib/CommonLib/IntraPrediction.cpp b/source/Lib/CommonLib/IntraPrediction.cpp index 382181d2df2b11f07a71536b8d8c7dd478b19f76..e454a0c3360d91afcbdc304143925d2f2b2ab555 100644 --- a/source/Lib/CommonLib/IntraPrediction.cpp +++ b/source/Lib/CommonLib/IntraPrediction.cpp @@ -10830,7 +10830,10 @@ void IntraPrediction::xCccmApplyModel(const PredictionUnit& pu, const ComponentI #if JVET_AC0147_CCCM_NO_SUBSAMPLING CHECK( pu.cccmNoSubFlag, "cccmNoSubFlag shall be disabled" ); #endif - +#if JVET_AC0054_GLCCCM + int refSizeX = m_cccmBlkArea.x - m_cccmRefArea.x; // Reference lines available left and above + int refSizeY = m_cccmBlkArea.y - m_cccmRefArea.y; +#endif CPelBuf refLumaBlk = xCccmGetLumaPuBuf(pu); for (int y = 0; y < refLumaBlk.height; y++) @@ -10847,6 +10850,30 @@ void IntraPrediction::xCccmApplyModel(const PredictionUnit& pu, const ComponentI } // 7-tap cross +#if JVET_AC0054_GLCCCM + if (!pu.glCccmFlag) + { + samples[0] = refLumaBlk.at( x , y ); // C + samples[1] = refLumaBlk.at( x , y-1 ); // N + samples[2] = refLumaBlk.at( x , y+1 ); // S + samples[3] = refLumaBlk.at( x-1, y ); // W + samples[4] = refLumaBlk.at( x+1, y ); // E + samples[5] = cccmModel.nonlinear( refLumaBlk.at( x, y) ); + samples[6] = cccmModel.bias(); + } + else + { + samples[0] = refLumaBlk.at( x , y ); // C + samples[1] = (2 * refLumaBlk.at( x , y-1 ) + refLumaBlk.at( x-1 , y-1 ) + refLumaBlk.at( x+1 , y-1 )) + -(2 * refLumaBlk.at( x , y+1 ) + refLumaBlk.at( x-1 , y+1 ) + refLumaBlk.at( x+1 , y+1 )); // Vertical gradient + samples[2] = (2 * refLumaBlk.at( x-1, y ) + refLumaBlk.at( x-1 , y-1 ) + refLumaBlk.at( x-1 , y+1 )) + -(2 * refLumaBlk.at( x+1, y ) + refLumaBlk.at( x+1 , y-1 ) + refLumaBlk.at( x+1 , y+1 )); // Horizontal gradient + samples[3] = ((y + refSizeY + CCCM_LOC_OFFSET) << CCCM_LOC_SHIFT); // Y coordinate + samples[4] = ((x + refSizeX + CCCM_LOC_OFFSET) << CCCM_LOC_SHIFT); // X coordinate + samples[5] = cccmModel.nonlinear( refLumaBlk.at( x, y) ); + samples[6] = cccmModel.bias(); + } +#else samples[0] = refLumaBlk.at( x , y ); // C samples[1] = refLumaBlk.at( x , y-1 ); // N samples[2] = refLumaBlk.at( x , y+1 ); // S @@ -10854,7 +10881,8 @@ void IntraPrediction::xCccmApplyModel(const PredictionUnit& pu, const ComponentI samples[4] = refLumaBlk.at( x+1, y ); // E samples[5] = cccmModel.nonlinear( refLumaBlk.at( x, y) ); samples[6] = cccmModel.bias(); - +#endif + piPred.at(x, y) = ClipPel<Pel>( cccmModel.convolve(samples), clpRng ); } } @@ -10924,6 +10952,30 @@ void IntraPrediction::xCccmCalcModels(const PredictionUnit& pu, CccmModel<CCCM_N } // 7-tap cross +#if JVET_AC0054_GLCCCM + if (!pu.glCccmFlag) + { + A[0][sampleNum] = refLuma.at( x , y ); // C + A[1][sampleNum] = refLuma.at( x , y-1 ); // N + A[2][sampleNum] = refLuma.at( x , y+1 ); // S + A[3][sampleNum] = refLuma.at( x-1, y ); // W + A[4][sampleNum] = refLuma.at( x+1, y ); // E + A[5][sampleNum] = cccmModelCb.nonlinear( refLuma.at( x, y) ); + A[6][sampleNum] = cccmModelCb.bias(); + } + else + { + A[0][sampleNum] = refLuma.at( x , y ); // C + A[1][sampleNum] = (2 * refLuma.at( x , y-1 ) + refLuma.at( x-1 , y-1 ) + refLuma.at( x+1 , y-1 )) + -(2 * refLuma.at( x , y+1 ) + refLuma.at( x-1 , y+1 ) + refLuma.at( x+1 , y+1 )); // Vertical gradient + A[2][sampleNum] = (2 * refLuma.at( x-1, y ) + refLuma.at( x-1 , y-1 ) + refLuma.at( x-1 , y+1 )) + -(2 * refLuma.at( x+1, y ) + refLuma.at( x+1 , y-1 ) + refLuma.at( x+1 , y+1 )); // Horizontal gradient + A[3][sampleNum] = ((y + CCCM_LOC_OFFSET) << CCCM_LOC_SHIFT); // Y coordinate + A[4][sampleNum] = ((x + CCCM_LOC_OFFSET) << CCCM_LOC_SHIFT); // X coordinate + A[5][sampleNum] = cccmModelCb.nonlinear( refLuma.at( x, y) ); + A[6][sampleNum] = cccmModelCb.bias(); + } +#else A[0][sampleNum] = refLuma.at( x , y ); // C A[1][sampleNum] = refLuma.at( x , y-1 ); // N A[2][sampleNum] = refLuma.at( x , y+1 ); // S @@ -10931,7 +10983,8 @@ void IntraPrediction::xCccmCalcModels(const PredictionUnit& pu, CccmModel<CCCM_N A[4][sampleNum] = refLuma.at( x+1, y ); // E A[5][sampleNum] = cccmModelCb.nonlinear( refLuma.at( x, y) ); A[6][sampleNum] = cccmModelCb.bias(); - +#endif + YCb[sampleNum] = recoCb.at(refPosPicX + x, refPosPicY + y); YCr[sampleNum++] = recoCr.at(refPosPicX + x, refPosPicY + y); } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 6c0b9a3af5922fb0bb4e23068c83126e2d5ebc7c..9579e589afb1574c233fe0571d2ea4540d6aaa8d 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -157,6 +157,7 @@ #if JVET_AA0057_CCCM #define JVET_AB0143_CCCM_TS 1 // JVET-AB0143: CCCM template selection #define JVET_AC0147_CCCM_NO_SUBSAMPLING 1 // JVET-AC0147: Subsampling is not applied to CCCM +#define JVET_AC0054_GLCCCM 1 // JVET_AC0054: Gradient and location based CCCM #endif #define JVET_AA0126_GLM 1 // JVET-AA0126: Gradient linear model #if JVET_AA0126_GLM diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp index 0063dfab62529765392859bc5010d12b9fa1925f..55fdbe0ec8bea66b3429ecbe1d006ea4eac4feff 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -799,6 +799,9 @@ void PredictionUnit::initData() #if JVET_AC0147_CCCM_NO_SUBSAMPLING cccmNoSubFlag = 0; #endif +#if JVET_AC0054_GLCCCM + glCccmFlag = 0; +#endif #endif // inter data #if ENABLE_INTER_TEMPLATE_MATCHING && JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION @@ -950,6 +953,9 @@ PredictionUnit& PredictionUnit::operator=(const IntraPredictionData& predData) #if JVET_AC0147_CCCM_NO_SUBSAMPLING cccmNoSubFlag = predData.cccmNoSubFlag; #endif +#if JVET_AC0054_GLCCCM + glCccmFlag = predData.glCccmFlag; +#endif #endif return *this; } @@ -1098,6 +1104,9 @@ PredictionUnit& PredictionUnit::operator=( const PredictionUnit& other ) #if JVET_AC0147_CCCM_NO_SUBSAMPLING cccmNoSubFlag = other.cccmNoSubFlag; #endif +#if JVET_AC0054_GLCCCM + glCccmFlag = other.glCccmFlag; +#endif #endif mergeFlag = other.mergeFlag; diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h index 271adcf25e5591770d73dd05cbe3321cea1e9f0e..7f813e65215a0be295460a689d8e5335fe0b543c 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -509,6 +509,9 @@ struct IntraPredictionData #if JVET_AC0147_CCCM_NO_SUBSAMPLING int cccmNoSubFlag; #endif +#if JVET_AC0054_GLCCCM + int glCccmFlag; +#endif #endif }; diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 9ddfc8dcf4f42acfeca1702adca032c2fec0ccf7..ffa57642590c4bafbb5aff55b2c4067f0127f937 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -2528,12 +2528,25 @@ void CABACReader::cccmFlag(PredictionUnit& pu) #else pu.cccmFlag = (intraDir == MDLM_T_IDX) ? 3 : (intraDir == MDLM_L_IDX) ? 2 : 1; #endif + #if JVET_AC0147_CCCM_NO_SUBSAMPLING pu.cccmNoSubFlag = 0; if ( pu.cs->sps->getUseCccm() == 2 ) { pu.cccmNoSubFlag += m_BinDecoder.decodeBin( Ctx::CccmFlag( 1 ) ); - } + } +#endif +#if JVET_AC0054_GLCCCM + pu.glCccmFlag = 0; +#if !JVET_AC0147_CCCM_NO_SUBSAMPLING + unsigned ctxId = 1; +#else + unsigned ctxId = 2; + if (!pu.cccmNoSubFlag) +#endif + { + pu.glCccmFlag = m_BinDecoder.decodeBin( Ctx::CccmFlag( ctxId ) ); + } #endif } #endif diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index 0ab51eebddc0dc09b7569d91d7c4f803fe350f2b..417998113cdcfc67e67364cca2c3418c59168e84 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -2258,10 +2258,22 @@ void CABACWriter::cccmFlag(const PredictionUnit& pu) { m_BinEncoder.encodeBin( pu.cccmFlag ? 1 : 0, Ctx::CccmFlag( 0 ) ); #if JVET_AC0147_CCCM_NO_SUBSAMPLING - if ( pu.cccmFlag && ( pu.cs->sps->getUseCccm() == 2 ) ) + if ( pu.cccmFlag && ( pu.cs->sps->getUseCccm() == 2 ) ) { m_BinEncoder.encodeBin( pu.cccmNoSubFlag ? 1 : 0, Ctx::CccmFlag( 1 ) ); } +#endif +#if JVET_AC0054_GLCCCM +#if !JVET_AC0147_CCCM_NO_SUBSAMPLING + unsigned ctxId = 1; + if (pu.cccmFlag) +#else + unsigned ctxId = 2; + if (pu.cccmFlag && !pu.cccmNoSubFlag) +#endif + { + m_BinEncoder.encodeBin( pu.glCccmFlag ? 1 : 0, Ctx::CccmFlag( ctxId ) ); + } #endif } } diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp index feedffd6e1f78f7ab04314f78c478dd1b5d0f54d..6ad13a4ef028e23b70349364e401726042b0b7cc 100644 --- a/source/Lib/EncoderLib/IntraSearch.cpp +++ b/source/Lib/EncoderLib/IntraSearch.cpp @@ -2575,6 +2575,9 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner #if JVET_AC0147_CCCM_NO_SUBSAMPLING int cccmNoSubBest = 0; #endif +#if JVET_AC0054_GLCCCM + int glCccmBest = 0; +#endif #endif #if JVET_Z0050_CCLM_SLOPE CclmOffsets bestCclmOffsets = {}; @@ -2933,11 +2936,25 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner #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 }; #else uint32_t chromaCandCccmModes[CCCM_NUM_MODES] = { LM_CHROMA_IDX, MDLM_L_IDX, MDLM_T_IDX }; #endif +#endif +#if JVET_AC0054_GLCCCM + int satdCccmFlagList[CCCM_NUM_MODES]; +#endif + #if JVET_AC0147_CCCM_NO_SUBSAMPLING int64_t satdCccmSortedCost[2][CCCM_NUM_MODES]; int satdCccmModeList[2][CCCM_NUM_MODES]; @@ -2948,6 +2965,9 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner 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}; @@ -2975,6 +2995,12 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner for (int idx = 0; idx < CCCM_NUM_MODES; idx++) { +#if JVET_AC0054_GLCCCM + if (sub && idx >= CCCM_NUM_MODES / 2) + { + continue; + } +#endif int mode = chromaCandCccmModes[idx]; if (idx == 0) { @@ -3008,6 +3034,34 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner pu.cccmFlag = 3; } #endif + +#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 + } +#endif if (isCCCMEnabled) { @@ -3068,12 +3122,19 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner } } } +#if JVET_AC0054_GLCCCM + int tempGlCccmFlag = 0; +#endif int tempCccmIdx = 0; int64_t tempCccmCost = 0; +#if JVET_AC0054_GLCCCM + for (int i = 1; i < CCCM_NUM_MODES; i++) +#else #if MMLM for (int i = 1; i < 4; i++) #else for (int i = 1; i < 3; i++) +#endif #endif { for (int j = i + 1; j < CCCM_NUM_MODES; j++) @@ -3087,6 +3148,11 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner 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 } } } @@ -3094,10 +3160,26 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner #if MMLM bool isCccmModeEnabledInRdo[2][MMLM_T_IDX + 1] = { false }; isCccmModeEnabledInRdo[0][satdCccmModeList[0][0]] = true; +#if JVET_AC0054_GLCCCM + bool isGlCccmModeEnabledInRdo[MMLM_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 < 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 { @@ -3105,7 +3187,18 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner { break; } +#if JVET_AC0054_GLCCCM + if (satdCccmFlagList[i] == 2) + { + isGlCccmModeEnabledInRdo[satdCccmModeList[0][i]] = true; + } + else + { + isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]] = true; + } +#else isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]] = true; +#endif } if (pu.cu->slice->getSPS()->getUseCccm() == 2) @@ -3157,7 +3250,11 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner { if (satdCccmSortedCost[1][i] >= CCCM_NO_SUB_WEIGHT * bestCccmCost[1]) { +#if JVET_AC0054_GLCCCM + if (satdCccmSortedCost[1][i - 1] > bestCccmCost[0] && satdCccmFlagList[0] != 2) +#else if (satdCccmSortedCost[1][i - 1] > bestCccmCost[0]) +#endif { bestCccmCost[0] = satdCccmSortedCost[1][i - 1]; } @@ -3177,6 +3274,9 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner } pu.cccmFlag = 0; pu.cccmNoSubFlag = 0; +#if JVET_AC0054_GLCCCM + pu.glCccmFlag = 0; +#endif #else int64_t satdCccmSortedCost[CCCM_NUM_MODES]; int satdCccmModeList[CCCM_NUM_MODES]; @@ -3370,7 +3470,11 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner #if JVET_AC0147_CCCM_NO_SUBSAMPLING if (pu.cu->slice->getSPS()->getUseCccm() == 2) { +#if JVET_AC0054_GLCCCM + if (satdSortedCost[uiMaxMode - 1 - reducedModeNumber] > bestCccmCost[0] && satdCccmFlagList[uiMaxMode - 1 - reducedModeNumber] != 2) +#else if (satdSortedCost[uiMaxMode - 1 - reducedModeNumber] > bestCccmCost[0]) +#endif { modeIsEnable[satdModeList[uiMaxMode - 1 - reducedModeNumber]] = 0; // disable the last reducedModeNumber modes } @@ -3378,7 +3482,11 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner { for (int i = 3; i > 0; i--) { +#if JVET_AC0054_GLCCCM + if ((satdCccmSortedCost[0][i] > satdSortedCost[uiMaxMode - 1 - reducedModeNumber]) && (isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]]) && satdCccmFlagList[uiMaxMode - 1 - reducedModeNumber] != 2) +#else if ((satdCccmSortedCost[0][i] > satdSortedCost[uiMaxMode - 1 - reducedModeNumber]) && (isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]])) +#endif { isCccmModeEnabledInRdo[0][satdCccmModeList[0][i]] = false; break; @@ -3960,15 +4068,57 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner pu.cccmFlag = 3; } #endif -#if JVET_AC0147_CCCM_NO_SUBSAMPLING - if (!isCccmModeEnabledInRdo[0][chromaIntraModeInCCCM] && !isCccmModeEnabledInRdo[1][chromaIntraModeInCCCM]) + +#if JVET_AC0054_GLCCCM + pu.glCccmFlag = 0; + if (uiMode >= CCCM_NUM_MODES / 2) + { + pu.glCccmFlag = 1; +#if MMLM + chromaIntraModeInCCCM = uiMode == 6 ? LM_CHROMA_IDX + : uiMode == 7 ? MDLM_L_IDX + : uiMode == 8 ? MDLM_T_IDX + : uiMode == 9 ? MMLM_CHROMA_IDX + : uiMode == 10 ? MMLM_L_IDX : MMLM_T_IDX; + isCCCMEnabled = uiMode == 6 ? isCccmFullEnabled + : uiMode == 7 ? isCccmLeftEnabled + : uiMode == 8 ? isCccmTopEnabled + : uiMode == 9 ? isMultiCccmFullEnabled + : uiMode == 10 ? isMultiCccmLeftEnabled : isMultiCccmTopEnabled; + pu.cccmFlag = uiMode == 6 ? 1 + : uiMode == 7 ? 2 + : uiMode == 8 ? 3 + : uiMode == 9 ? 1 + : uiMode == 10 ? 2 : 3; #else - if (!isCccmModeEnabledInRdo[chromaIntraModeInCCCM]) + chromaIntraModeInCCCM = uiMode == 3 ? LM_CHROMA_IDX + : uiMode == 4 ? MDLM_L_IDX : MDLM_T_IDX; + isCCCMEnabled = uiMode == 3 ? isCccmFullEnabled + : uiMode == 4 ? isCccmLeftEnabled : isCccmTopEnabled; + pu.cccmFlag = uiMode == 3 ? 1 + : uiMode == 4 ? 2 : 3; #endif + if (!isGlCccmModeEnabledInRdo[chromaIntraModeInCCCM]) + { + continue; + } + } + else { - continue; +#endif // JVET_AC0054_GLCCCM + +#if JVET_AC0147_CCCM_NO_SUBSAMPLING + if (!isCccmModeEnabledInRdo[0][chromaIntraModeInCCCM] && !isCccmModeEnabledInRdo[1][chromaIntraModeInCCCM]) +#else + if (!isCccmModeEnabledInRdo[chromaIntraModeInCCCM]) +#endif + { + continue; + } +#if JVET_AC0054_GLCCCM } - +#endif + if (isCCCMEnabled) { #else @@ -3990,11 +4140,25 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner #if JVET_AC0147_CCCM_NO_SUBSAMPLING for (int sub = 0; sub < pu.cu->slice->getSPS()->getUseCccm(); sub++) { - pu.cccmNoSubFlag = sub; - if (!isCccmModeEnabledInRdo[sub][chromaIntraModeInCCCM]) - { - continue; - } + pu.cccmNoSubFlag = sub; +#if JVET_AC0054_GLCCCM + if (sub && ((uiMode >= CCCM_NUM_MODES / 2) || pu.glCccmFlag)) + { + continue; + } + else + { + if (!isCccmModeEnabledInRdo[sub][chromaIntraModeInCCCM]) + { + continue; + } + } +#else // else of JVET_AC0054_GLCCCM + if (!isCccmModeEnabledInRdo[sub][chromaIntraModeInCCCM]) + { + continue; + } +#endif // end of JVET_AC0054_GLCCCM #endif // Original RD check code replicated from above @@ -4076,7 +4240,10 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner cccmModeBest = pu.cccmFlag; #if JVET_AA0126_GLM bestGlmIdc = pu.glmIdc; -#endif +#endif +#if JVET_AC0054_GLCCCM + glCccmBest = pu.glCccmFlag; +#endif #if JVET_AC0147_CCCM_NO_SUBSAMPLING cccmNoSubBest = pu.cccmNoSubFlag; } @@ -4123,6 +4290,9 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner #if JVET_AC0147_CCCM_NO_SUBSAMPLING pu.cccmNoSubFlag = cccmNoSubBest; #endif +#if JVET_AC0054_GLCCCM + pu.glCccmFlag = glCccmBest; +#endif #endif #if JVET_Z0050_DIMD_CHROMA_FUSION pu.isChromaFusion = isChromaFusion;