diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 9c54b0e6f0d5aadcd8072dc32fd1d709406a6016..21e7104bba8376467db4ef2fc527ada9ad399912 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -85,6 +85,8 @@ #define JVET_O0364_PDPC_DC 1 // JVET-O0364 Part 4: align PDPC process for DC with the one for Planar #define JVET_O0364_PDPC_ANGULAR 1 // JVET-O0364 Part 5: simplify PDPC process for angular modes +#define JVET_O1124_ALLOW_CCLM_COND 1 // JVET-O1124/JVET-O0196: CCLM restriction to reduce luma-chroma latency for chroma separate tree + #define FIX_DB_MAX_TRANSFORM_SIZE 1 #define MRG_SHARELIST_SHARSIZE 32 diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp index b6f6ce9443fb7c000ef76925be6b19bbb1b99391..eff7d0bc5b1415266fac38047fe0d69d94aeabbe 100644 --- a/source/Lib/CommonLib/Unit.cpp +++ b/source/Lib/CommonLib/Unit.cpp @@ -327,6 +327,71 @@ void CodingUnit::initData() mipFlag = false; } +#if JVET_O1124_ALLOW_CCLM_COND +const bool CodingUnit::checkCCLMAllowed() const +{ + bool allowCCLM = false; + + if( chType != CHANNEL_TYPE_CHROMA ) //single tree + { + allowCCLM = true; + } + else if( slice->getSPS()->getCTUSize() <= 32 ) //dual tree, CTUsize < 64 + { + allowCCLM = true; + } + else //dual tree, CTU size 64 or 128 + { + int depthFor64x64Node = slice->getSPS()->getCTUSize() == 128 ? 1 : 0; + const PartSplit cuSplitTypeDepth1 = CU::getSplitAtDepth( *this, depthFor64x64Node ); + const PartSplit cuSplitTypeDepth2 = CU::getSplitAtDepth( *this, depthFor64x64Node + 1 ); + + //allow CCLM if 64x64 chroma tree node uses QT split or HBT+VBT split combination + if( cuSplitTypeDepth1 == CU_QUAD_SPLIT || (cuSplitTypeDepth1 == CU_HORZ_SPLIT && cuSplitTypeDepth2 == CU_VERT_SPLIT) ) + { + CHECK( !(blocks[COMPONENT_Cb].width <= 16 && blocks[COMPONENT_Cb].height <= 16), "chroma cu size shall be <= 16x16" ); + allowCCLM = true; + } + //allow CCLM if 64x64 chroma tree node uses NS (No Split) and becomes a chroma CU containing 32x32 chroma blocks + else if( cuSplitTypeDepth1 == CU_DONT_SPLIT ) + { + CHECK( !(blocks[COMPONENT_Cb].width == 32 && blocks[COMPONENT_Cb].height == 32), "chroma cu size shall be 32x32" ); + allowCCLM = true; + } + //allow CCLM if 64x32 chroma tree node uses NS and becomes a chroma CU containing 32x16 chroma blocks + else if( cuSplitTypeDepth1 == CU_HORZ_SPLIT && cuSplitTypeDepth2 == CU_DONT_SPLIT ) + { + CHECK( !(blocks[COMPONENT_Cb].width == 32 && blocks[COMPONENT_Cb].height == 16), "chroma cu size shall be 32x16" ); + allowCCLM = true; + } + + //further check luma conditions + if( allowCCLM ) + { + //disallow CCLM if luma 64x64 block uses BT or TT or NS with ISP + const Position lumaRefPos( chromaPos().x << getComponentScaleX( COMPONENT_Cb, chromaFormat ), chromaPos().y << getComponentScaleY( COMPONENT_Cb, chromaFormat ) ); + const CodingUnit* colLumaCu = cs->picture->cs->getCU( lumaRefPos, CHANNEL_TYPE_LUMA ); + + if( colLumaCu->lwidth() < 64 || colLumaCu->lheight() < 64 ) //further split at 64x64 luma node + { + const PartSplit cuSplitTypeDepth1Luma = CU::getSplitAtDepth( *colLumaCu, depthFor64x64Node ); + CHECK( !(cuSplitTypeDepth1Luma >= CU_QUAD_SPLIT && cuSplitTypeDepth1Luma <= CU_TRIV_SPLIT), "split mode shall be BT, TT or QT" ); + if( cuSplitTypeDepth1Luma != CU_QUAD_SPLIT ) + { + allowCCLM = false; + } + } + else if( colLumaCu->lwidth() == 64 && colLumaCu->lheight() == 64 && colLumaCu->ispMode ) //not split at 64x64 luma node and use ISP mode + { + allowCCLM = false; + } + } + } + + return allowCCLM; +} +#endif + const uint8_t CodingUnit::checkAllowedSbt() const { if( !slice->getSPS()->getUseSBT() ) diff --git a/source/Lib/CommonLib/Unit.h b/source/Lib/CommonLib/Unit.h index 5c2f9eb56775973b179559910cc1a3ac9e569175..99286a0a7c55a2fa5f81aa9d669394083e959f3e 100644 --- a/source/Lib/CommonLib/Unit.h +++ b/source/Lib/CommonLib/Unit.h @@ -350,6 +350,9 @@ struct CodingUnit : public UnitArea void setSbtPos( uint8_t pos ) { CHECK( pos >= 4, "sbt_pos wrong" ); sbtInfo = ( pos << 4 ) + ( sbtInfo & 0xcf ); } uint8_t getSbtTuSplit() const; const uint8_t checkAllowedSbt() const; +#if JVET_O1124_ALLOW_CCLM_COND + const bool checkCCLMAllowed() const; +#endif }; // --------------------------------------------------------------------------- diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp index ee6c152191caf340cfdbb35b1013f8aade1e5ee3..3fbe034110dd68e7230730dddbe82662bd3ada1d 100644 --- a/source/Lib/CommonLib/UnitTools.cpp +++ b/source/Lib/CommonLib/UnitTools.cpp @@ -787,7 +787,11 @@ bool PU::isLMCMode(unsigned mode) } bool PU::isLMCModeEnabled(const PredictionUnit &pu, unsigned mode) { +#if JVET_O1124_ALLOW_CCLM_COND + if ( pu.cs->sps->getUseLMChroma() && pu.cu->checkCCLMAllowed() ) +#else if ( pu.cs->sps->getUseLMChroma() ) +#endif { return true; } diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp index 3f017485f4890c2b520e9da1552b0be37de97127..8337c6b7035d2889344026ccea158b0cfb369056 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -1305,7 +1305,11 @@ void CABACReader::intra_chroma_pred_mode( PredictionUnit& pu ) } // LM chroma mode +#if JVET_O1124_ALLOW_CCLM_COND + if( pu.cs->sps->getUseLMChroma() && pu.cu->checkCCLMAllowed() ) +#else if( pu.cs->sps->getUseLMChroma() ) +#endif { if( intra_chroma_lmc_mode( pu ) ) { diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp index 16bf915584a1b5a2b3e21fad7cf39a6b8af83639..126a0d64767f4bf4f130f9afc5bf6e2e5f1227a8 100644 --- a/source/Lib/EncoderLib/CABACWriter.cpp +++ b/source/Lib/EncoderLib/CABACWriter.cpp @@ -1199,7 +1199,11 @@ void CABACWriter::intra_chroma_pred_mode( const PredictionUnit& pu ) } // LM chroma mode +#if JVET_O1124_ALLOW_CCLM_COND + if( pu.cs->sps->getUseLMChroma() && pu.cu->checkCCLMAllowed() ) +#else if( pu.cs->sps->getUseLMChroma() ) +#endif { intra_chroma_lmc_mode( pu ); if ( PU::isLMCMode( intraDir ) )