diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 833299192ec15bb1df1fdcc32b1ce75f7b954051..eb745ce96a9bb8e899f5d8a656410284026e1f2f 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -131,7 +131,7 @@ - +#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 diff --git a/source/Lib/CommonLib/Unit.cpp b/source/Lib/CommonLib/Unit.cpp index b6f6ce9443fb7c000ef76925be6b19bbb1b99391..77756a16be6a6bb1222c5f7d24f0b56b97eaf91e 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 idxFor64x64Node = slice->getSPS()->getCTUSize() == 128 ? 1 : 0; + const PartSplit cuSplitTypeDepth1 = PartSplit( (splitSeries >> (idxFor64x64Node * SPLIT_DMULT)) & SPLIT_MASK ); + const PartSplit cuSplitTypeDepth2 = PartSplit( (splitSeries >> ((idxFor64x64Node + 1) * SPLIT_DMULT)) & SPLIT_MASK ); + + //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) ) + { + assert( blocks[COMPONENT_Cb].width <= 16 && blocks[COMPONENT_Cb].height <= 16 ); + 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 == 0 ) + { + assert( blocks[COMPONENT_Cb].width == 32 && blocks[COMPONENT_Cb].height == 32 ); + 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 == 0 ) + { + assert( blocks[COMPONENT_Cb].width == 32 && blocks[COMPONENT_Cb].height == 16 ); + 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 = PartSplit( (colLumaCu->splitSeries >> (idxFor64x64Node * SPLIT_DMULT)) & SPLIT_MASK ); + assert( cuSplitTypeDepth1Luma >= CU_QUAD_SPLIT && cuSplitTypeDepth1Luma <= CU_TRIV_SPLIT ); + 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 ee1a993fca511cfdb8bedefd2721eb2aa5112734..6b61d96e61f0ebce6d37f50d9a5928dc1293f4bd 100644 --- a/source/Lib/DecoderLib/CABACReader.cpp +++ b/source/Lib/DecoderLib/CABACReader.cpp @@ -1298,7 +1298,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 604d36461be3e626b3791babf447633eed3d5c85..96a7eebbb7ffa1d0d47617af68a8961999ff0a6d 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 ) )