diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 93bf0194c23c886cb794efd1a729e6265099ec41..fbd74161547b4fa89effe8c87387b30cd506622c 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -213,6 +213,9 @@ void EncApp::xInitLibCfg() m_cEncLib.setRDpenalty ( m_rdPenalty ); m_cEncLib.setQTBT ( m_QTBT ); m_cEncLib.setCTUSize ( m_uiCTUSize ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + m_cEncLib.setUseSplitConsOverride ( m_SplitConsOverrideEnabledFlag ); +#endif m_cEncLib.setMinQTSizes ( m_uiMinQT ); m_cEncLib.setMaxBTDepth ( m_uiMaxBTDepth, m_uiMaxBTDepthI, m_uiMaxBTDepthIChroma ); m_cEncLib.setDualITree ( m_dualTree ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 52be0b4aebf2d94a4cc514722f788aaa756f302f..b2dddf536669dd9502599de189752275e7e37fb4 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -796,6 +796,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) ("QTBT", m_QTBT, false, "Enable QTBT (0:off, 1:on) [default: off]") ("MTT", m_MTT, 0u, "Multi type tree type (0: off, 1:QTBT + triple split) [default: 0]") ("CTUSize", m_uiCTUSize, 128u, "CTUSize (specifies the CTU size if QTBT is on) [default: 128]") +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + ("EnablePartitionConstraintsOverride", m_SplitConsOverrideEnabledFlag, true, "Enable partition constraints override") +#endif ("MinQTISlice", m_uiMinQT[0], 8u, "MinQTISlice") ("MinQTLumaISlice", m_uiMinQT[0], 8u, "MinQTLumaISlice") ("MinQTChromaISlice", m_uiMinQT[2], 4u, "MinQTChromaISlice") @@ -1828,7 +1831,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) m_uiLog2DiffMaxMinCodingBlockSize = m_uiMaxCodingDepth; m_uiMaxCUWidth = m_uiMaxCUHeight = m_uiCTUSize; m_uiMaxCUDepth = m_uiMaxCodingDepth; +#if !JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT m_uiLog2DiffMaxMinCodingBlockSize = m_uiMaxCUDepth - 1; +#endif } // check validity of input parameters @@ -1979,6 +1984,9 @@ bool EncAppCfg::xCheckParameter() #endif +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + xConfirmPara( m_useAMaxBT && !m_SplitConsOverrideEnabledFlag, "AMaxBt can only be used with PartitionConstriantsOverride enabled" ); +#endif xConfirmPara( m_useAMaxBT && !m_QTBT, "AMaxBT can only be used with QTBT!" ); diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index c30670b9872dad3e6d8897be13b525a73cc39825..601fcd5a56494ecbec4468ce781405934ce56348 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -198,6 +198,9 @@ protected: // coding unit (CU) definition bool m_QTBT; unsigned m_uiCTUSize; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + bool m_SplitConsOverrideEnabledFlag; +#endif unsigned m_uiMinQT[3]; // 0: I slice luma; 1: P/B slice; 2: I slice chroma unsigned m_uiMaxBTDepth; unsigned m_uiMaxBTDepthI; diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 6023e01bc877a3e7a47d9a804bb897eb9b9e5323..a11b0c1b5f0d28a03be401d9f12a87980c1fd241 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -124,6 +124,16 @@ Slice::Slice() , m_encCABACTableIdx (I_SLICE) , m_iProcessingStartTime ( 0 ) , m_dProcessingTime ( 0 ) +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT +, m_splitConsOverrideFlag ( false ) +, m_uiMinQTSize ( 0 ) +, m_uiMaxBTDepth ( 0 ) +, m_uiMaxTTSize ( 0 ) +, m_uiMinQTSizeIChroma ( 0 ) +, m_uiMaxBTDepthIChroma ( 0 ) +, m_uiMaxBTSizeIChroma ( 0 ) +, m_uiMaxTTSizeIChroma ( 0 ) +#endif , m_uiMaxBTSize ( 0 ) { for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++) @@ -815,6 +825,16 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll) m_subPuMvpSubBlkLog2Size = pSrc->m_subPuMvpSubBlkLog2Size; m_maxNumMergeCand = pSrc->m_maxNumMergeCand; if( cpyAlmostAll ) m_encCABACTableIdx = pSrc->m_encCABACTableIdx; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + m_splitConsOverrideFlag = pSrc->m_splitConsOverrideFlag; + m_uiMinQTSize = pSrc->m_uiMinQTSize; + m_uiMaxBTDepth = pSrc->m_uiMaxBTDepth; + m_uiMaxTTSize = pSrc->m_uiMaxTTSize; + m_uiMinQTSizeIChroma = pSrc->m_uiMinQTSizeIChroma; + m_uiMaxBTDepthIChroma = pSrc->m_uiMaxBTDepthIChroma; + m_uiMaxBTSizeIChroma = pSrc->m_uiMaxBTSizeIChroma; + m_uiMaxTTSizeIChroma = pSrc->m_uiMaxTTSizeIChroma; +#endif m_uiMaxBTSize = pSrc->m_uiMaxBTSize; } @@ -1646,9 +1666,16 @@ SPSNext::SPSNext( SPS& sps ) // default values for additional parameters , m_CTUSize ( 0 ) +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + , m_minQT { 0, 0, 0 } +#else , m_minQT { 0, 0 } +#endif , m_maxBTDepth { MAX_BT_DEPTH, MAX_BT_DEPTH_INTER, MAX_BT_DEPTH_C } , m_maxBTSize { MAX_BT_SIZE, MAX_BT_SIZE_INTER, MAX_BT_SIZE_C } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + , m_maxTTSize { MAX_TT_SIZE, MAX_TT_SIZE_INTER, MAX_TT_SIZE_C } +#endif , m_subPuLog2Size ( 0 ) , m_subPuMrgMode ( 0 ) , m_ImvMode ( IMV_OFF ) @@ -2445,6 +2472,11 @@ uint32_t PreCalcValues::getValIdx( const Slice &slice, const ChannelType chType uint32_t PreCalcValues::getMaxBtDepth( const Slice &slice, const ChannelType chType ) const { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if ( slice.getSplitConsOverrideFlag() ) + return (!slice.isIRAP() || isLuma(chType) || ISingleTree) ? slice.getMaxBTDepth() : slice.getMaxBTDepthIChroma(); + else +#endif return maxBtDepth[getValIdx( slice, chType )]; } @@ -2455,7 +2487,14 @@ uint32_t PreCalcValues::getMinBtSize( const Slice &slice, const ChannelType chTy uint32_t PreCalcValues::getMaxBtSize( const Slice &slice, const ChannelType chType ) const { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if (slice.getSplitConsOverrideFlag()) + return (!slice.isIRAP() || isLuma(chType) || ISingleTree) ? slice.getMaxBTSize() : slice.getMaxBTSizeIChroma(); + else + return maxBtSize[getValIdx(slice, chType)]; +#else return ( !slice.isIRAP() || isLuma( chType ) || ISingleTree ) ? slice.getMaxBTSize() : MAX_BT_SIZE_C; +#endif } uint32_t PreCalcValues::getMinTtSize( const Slice &slice, const ChannelType chType ) const @@ -2465,10 +2504,20 @@ uint32_t PreCalcValues::getMinTtSize( const Slice &slice, const ChannelType chTy uint32_t PreCalcValues::getMaxTtSize( const Slice &slice, const ChannelType chType ) const { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if ( slice.getSplitConsOverrideFlag() ) + return (!slice.isIRAP() || isLuma(chType) || ISingleTree) ? slice.getMaxTTSize() : slice.getMaxTTSizeIChroma(); + else +#endif return maxTtSize[getValIdx( slice, chType )]; } uint32_t PreCalcValues::getMinQtSize( const Slice &slice, const ChannelType chType ) const { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if ( slice.getSplitConsOverrideFlag() ) + return (!slice.isIRAP() || isLuma(chType) || ISingleTree) ? slice.getMinQTSize() : slice.getMinQTSizeIChroma(); + else +#endif return minQtSize[getValIdx( slice, chType )]; } diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 57acda967f0835978a34a19b2612f9a557d29927..a1f4a9b0f4a929fc1b8aca238edfa7405ddb8ae8 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -822,9 +822,15 @@ private: //===== additional parameters ===== // qtbt unsigned m_CTUSize; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + unsigned m_partitionOverrideEnalbed; // enable partition constraints override function +#endif unsigned m_minQT[3]; // 0: I slice luma; 1: P/B slice; 2: I slice chroma unsigned m_maxBTDepth[3]; unsigned m_maxBTSize[3]; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + unsigned m_maxTTSize[3]; +#endif unsigned m_dualITree; // sub-pu merging unsigned m_subPuLog2Size; @@ -880,6 +886,10 @@ public: // qtbt void setCTUSize ( unsigned ctuSize ) { m_CTUSize = ctuSize; } unsigned getCTUSize () const { return m_CTUSize; } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + void setSplitConsOverrideEnabledFlag(bool b) { m_partitionOverrideEnalbed = b; } + bool getSplitConsOverrideEnabledFlag() const { return m_partitionOverrideEnalbed; } +#endif void setMinQTSizes ( unsigned* minQT ) { m_minQT[0] = minQT[0]; m_minQT[1] = minQT[1]; m_minQT[2] = minQT[2]; } unsigned getMinQTSize ( SliceType slicetype, ChannelType chType = CHANNEL_TYPE_LUMA ) @@ -896,6 +906,14 @@ public: unsigned getMaxBTSize () const { return m_maxBTSize[1]; } unsigned getMaxBTSizeI () const { return m_maxBTSize[0]; } unsigned getMaxBTSizeIChroma () const { return m_maxBTSize[2]; } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + void setMaxTTSize (unsigned maxTTSize, + unsigned maxTTSizeI, + unsigned maxTTSizeC) { m_maxTTSize[1] = maxTTSize; m_maxTTSize[0] = maxTTSizeI; m_maxTTSize[2] = maxTTSizeC; } + unsigned getMaxTTSize() const { return m_maxTTSize[1]; } + unsigned getMaxTTSizeI() const { return m_maxTTSize[0]; } + unsigned getMaxTTSizeIChroma() const { return m_maxTTSize[2]; } +#endif void setUseDualITree ( bool b ) { m_dualITree = b; } bool getUseDualITree () const { return m_dualITree; } @@ -1543,6 +1561,17 @@ private: clock_t m_iProcessingStartTime; double m_dProcessingTime; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + bool m_splitConsOverrideFlag; + uint32_t m_uiMinQTSize; + uint32_t m_uiMaxBTDepth; + uint32_t m_uiMaxTTSize; + + uint32_t m_uiMinQTSizeIChroma; + uint32_t m_uiMaxBTDepthIChroma; + uint32_t m_uiMaxBTSizeIChroma; + uint32_t m_uiMaxTTSizeIChroma; +#endif uint32_t m_uiMaxBTSize; AlfSliceParam m_alfSliceParam; @@ -1653,6 +1682,25 @@ public: void setLambdas( const double lambdas[MAX_NUM_COMPONENT] ) { for (int component = 0; component < MAX_NUM_COMPONENT; component++) m_lambdas[component] = lambdas[component]; } const double* getLambdas() const { return m_lambdas; } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + void setSplitConsOverrideFlag(bool b) { m_splitConsOverrideFlag = b; } + bool getSplitConsOverrideFlag() const { return m_splitConsOverrideFlag; } + void setMinQTSize(int i) { m_uiMinQTSize = i; } + uint32_t getMinQTSize() const { return m_uiMinQTSize; } + void setMaxBTDepth(int i) { m_uiMaxBTDepth = i; } + uint32_t getMaxBTDepth() const { return m_uiMaxBTDepth; } + void setMaxTTSize(int i) { m_uiMaxTTSize = i; } + uint32_t getMaxTTSize() const { return m_uiMaxTTSize; } + + void setMinQTSizeIChroma(int i) { m_uiMinQTSizeIChroma = i; } + uint32_t getMinQTSizeIChroma() const { return m_uiMinQTSizeIChroma; } + void setMaxBTDepthIChroma(int i) { m_uiMaxBTDepthIChroma = i; } + uint32_t getMaxBTDepthIChroma() const { return m_uiMaxBTDepthIChroma; } + void setMaxBTSizeIChroma(int i) { m_uiMaxBTSizeIChroma = i; } + uint32_t getMaxBTSizeIChroma() const { return m_uiMaxBTSizeIChroma; } + void setMaxTTSizeIChroma(int i) { m_uiMaxTTSizeIChroma = i; } + uint32_t getMaxTTSizeIChroma() const { return m_uiMaxTTSizeIChroma; } +#endif void setMaxBTSize(int i) { m_uiMaxBTSize = i; } uint32_t getMaxBTSize() const { return m_uiMaxBTSize; } @@ -2050,7 +2098,11 @@ public: , minBtSize { MIN_BT_SIZE, MIN_BT_SIZE_INTER, MIN_BT_SIZE_C } , maxBtSize { sps.getSpsNext().getMaxBTSizeI(), sps.getSpsNext().getMaxBTSize(), sps.getSpsNext().getMaxBTSizeIChroma() } , minTtSize { MIN_TT_SIZE, MIN_TT_SIZE_INTER, MIN_TT_SIZE_C } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + , maxTtSize { sps.getSpsNext().getMaxTTSizeI(), sps.getSpsNext().getMaxTTSize(), sps.getSpsNext().getMaxTTSizeIChroma() } +#else , maxTtSize { MAX_TT_SIZE, MAX_TT_SIZE_INTER, MAX_TT_SIZE_C } +#endif , minQtSize { sps.getSpsNext().getMinQTSize( I_SLICE, CHANNEL_TYPE_LUMA ), sps.getSpsNext().getMinQTSize( B_SLICE, CHANNEL_TYPE_LUMA ), sps.getSpsNext().getMinQTSize( I_SLICE, CHANNEL_TYPE_CHROMA ) } {} diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 40c4cacf91de61c19291d33559878411f0eef72b..ca7bd7f4c6435a6d626a8a3469f13798ebe920e3 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -100,6 +100,7 @@ #define NUM_SPLIT_THREADS_IF_MSVC 4 #endif +#define JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT 1 // ==================================================================================================================== diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index de6b9dc231d656fb738fb9e33940f6c0379beb6f..d27d6c821526e92c9c7177f1b4d2067d860db236 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -821,23 +821,64 @@ void HLSyntaxReader::parseSPSNext( SPSNext& spsNext, const bool usePCM ) unsigned minQT [3] = { 0, 0, 0 }; unsigned maxBTD[3] = { 0, 0, 0 }; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + unsigned maxBTSize[3] = { 0, 0, 0 }; + unsigned maxTTSize[3] = { 0, 0, 0 }; +#endif READ_FLAG( symbol, "qtbt_dual_intra_tree" ); spsNext.setUseDualITree( symbol ); READ_UVLC( symbol, "log2_CTU_size_minus2" ); spsNext.setCTUSize( 1 << ( symbol + MIN_CU_LOG2 ) ); spsNext.getSPS().setMaxCodingDepth( symbol ); // overwrite original value spsNext.getSPS().setMaxCUWidth ( spsNext.getCTUSize() ); // overwrite original value spsNext.getSPS().setMaxCUHeight ( spsNext.getCTUSize() ); // overwrite original value +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + READ_FLAG( symbol, "override_partition_constraints_enable_flag"); spsNext.setSplitConsOverrideEnabledFlag( symbol ); + READ_UVLC( symbol, "log2_diff_min_qt_min_cb_intra_slice"); minQT[0] = 1 << (symbol + spsNext.getSPS().getLog2MinCodingBlockSize()); + READ_UVLC( symbol, "log2_diff_min_qt_min_cb_inter_slice"); minQT[1] = 1 << (symbol + spsNext.getSPS().getLog2MinCodingBlockSize()); +#else READ_UVLC( symbol, "log2_minQT_ISlice_minus2" ); minQT [0] = 1 << ( symbol + MIN_CU_LOG2 ); READ_UVLC( symbol, "log2_minQT_PBSlice_minus2" ); minQT [1] = 1 << ( symbol + MIN_CU_LOG2 ); - READ_UVLC( symbol, "max_bt_depth" ); maxBTD[0] = symbol; - READ_UVLC( symbol, "max_bt_depth_i_slice" ); maxBTD[1] = symbol; +#endif + READ_UVLC( symbol, "max_bt_depth" ); maxBTD[1] = symbol; + READ_UVLC( symbol, "max_bt_depth_i_slice" ); maxBTD[0] = symbol; + +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + maxTTSize[0] = maxBTSize[0] = minQT[0]; + if (maxBTD[0] != 0) + { + READ_UVLC(symbol, "log2_diff_max_bt_min_qt_intra_slice"); maxBTSize[0] <<= symbol; + READ_UVLC(symbol, "log2_diff_max_tt_min_qt_intra_slice"); maxTTSize[0] <<= symbol; + } + maxTTSize[1] = maxBTSize[1] = minQT[1]; + if (maxBTD[1] != 0) + { + READ_UVLC(symbol, "log2_diff_max_bt_min_qt_inter_slice"); maxBTSize[1] <<= symbol; + READ_UVLC(symbol, "log2_diff_max_tt_min_qt_inter_slice"); maxTTSize[1] <<= symbol; + } +#endif if( spsNext.getUseDualITree() ) { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + READ_UVLC( symbol, "log2_diff_min_qt_min_cb_intra_slice_chroma" ); minQT [2] = 1 << ( symbol + spsNext.getSPS().getLog2MinCodingBlockSize()); +#else READ_UVLC( symbol, "log2_minQT_ISliceChroma_minus2" ); minQT [2] = 1 << ( symbol + MIN_CU_LOG2 ); +#endif READ_UVLC( symbol, "max_bt_depth_i_slice_chroma" ); maxBTD[2] = symbol; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + maxTTSize[2] = maxBTSize[2] = minQT[2]; + if (maxBTD[2] != 0) + { + READ_UVLC(symbol, "log2_diff_max_bt_min_qt_intra_slice_chroma"); maxBTSize[2] <<= symbol; + READ_UVLC(symbol, "log2_diff_max_tt_min_qt_intra_slice_chroma"); maxTTSize[2] <<= symbol; + } +#endif } spsNext.setMinQTSizes( minQT ); - spsNext.setMaxBTDepth( maxBTD[0], maxBTD[1], maxBTD[2] ); + spsNext.setMaxBTDepth( maxBTD[1], maxBTD[0], maxBTD[2] ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + spsNext.setMaxBTSize( maxBTSize[1], maxBTSize[0], maxBTSize[2]); + spsNext.setMaxTTSize( maxTTSize[1], maxTTSize[0], maxTTSize[2]); +#endif } if( spsNext.getUseSubPuMvp() ) @@ -954,8 +995,13 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + READ_UVLC( uiCode, "log2_min_luma_coding_block_size_minus2"); + int log2MinCUSize = uiCode + 2; +#else READ_UVLC( uiCode, "log2_min_luma_coding_block_size_minus3" ); int log2MinCUSize = uiCode + 3; +#endif pcSPS->setLog2MinCodingBlockSize(log2MinCUSize); READ_UVLC( uiCode, "log2_diff_max_min_luma_coding_block_size" ); pcSPS->setLog2DiffMaxMinCodingBlockSize(uiCode); @@ -1658,6 +1704,42 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para #endif if( sps->getSpsNext().getUseQTBT() ) { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if (sps->getSpsNext().getSplitConsOverrideEnabledFlag()) + { + READ_FLAG(uiCode, "partition_constrainst_override_flag"); pcSlice->setSplitConsOverrideFlag(uiCode ? true : false); + if (pcSlice->getSplitConsOverrideFlag()) + { + READ_UVLC(uiCode, "log2_diff_min_qt_min_cb"); pcSlice->setMinQTSize(1 << (uiCode + sps->getLog2MinCodingBlockSize())); + READ_UVLC(uiCode, "max_bt_depth"); pcSlice->setMaxBTDepth(uiCode); + if (pcSlice->getMaxBTDepth() != 0) + { + READ_UVLC(uiCode, "log2_diff_max_bt_min_qt"); pcSlice->setMaxBTSize(pcSlice->getMinQTSize() << uiCode); + READ_UVLC(uiCode, "log2_diff_max_tt_min_qt"); pcSlice->setMaxTTSize(pcSlice->getMinQTSize() << uiCode); + } + else + { + pcSlice->setMaxBTSize(pcSlice->getMinQTSize()); + pcSlice->setMaxTTSize(pcSlice->getMinQTSize()); + } + if (pcSlice->isIntra() && sps->getSpsNext().getUseDualITree()) + { + READ_UVLC(uiCode, "log2_diff_min_qt_min_cb_I_chroma"); pcSlice->setMinQTSizeIChroma(1 << (uiCode + sps->getLog2MinCodingBlockSize())); + READ_UVLC(uiCode, "max_bt_depth_I_chroma"); pcSlice->setMaxBTDepthIChroma(uiCode); + if (pcSlice->getMaxBTDepthIChroma() != 0) + { + READ_UVLC(uiCode, "log2_diff_max_bt_min_qt_I_chroma"); pcSlice->setMaxBTSizeIChroma(pcSlice->getMinQTSizeIChroma() << uiCode); + READ_UVLC(uiCode, "log2_diff_max_tt_min_qt_I_chroma"); pcSlice->setMaxTTSizeIChroma(pcSlice->getMinQTSizeIChroma() << uiCode); + } + else + { + pcSlice->setMaxBTSizeIChroma(pcSlice->getMinQTSizeIChroma()); + pcSlice->setMaxTTSizeIChroma(pcSlice->getMinQTSizeIChroma()); + } + } + } + } +#else if (!pcSlice->isIntra()) { READ_UVLC(uiCode, "max_binary_tree_unit_size"); @@ -1668,6 +1750,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para { pcSlice->setMaxBTSize(MAX_BT_SIZE); } +#endif } if (!pcSlice->isIntra()) { diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index 871fca519e72a4a6a1eb1d704544cb7a097f89bf..df57f962be73b55b29a29899e11cc2c6ea488d1a 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -174,6 +174,9 @@ protected: bool m_useAMP; bool m_QTBT; unsigned m_CTUSize; +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + bool m_useSplitConsOverride; +#endif unsigned m_uiMinQT[3]; //0: I slice; 1: P/B slice, 2: I slice chroma unsigned m_uiMaxBTDepth; unsigned m_uiMaxBTDepthI; @@ -594,6 +597,10 @@ public: unsigned getMaxBTDepthIChroma () const { return m_uiMaxBTDepthIChroma; } bool getQTBT () const { return m_QTBT; } int getCTUSize () const { return m_CTUSize; } +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + void setUseSplitConsOverride (bool n) { m_useSplitConsOverride = n; } + bool getUseSplitConsOverride () const { return m_useSplitConsOverride; } +#endif void setDualITree ( bool b ) { m_dualITree = b; } bool getDualITree () const { return m_dualITree; } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 4768bd7914759c699945005c7e3e5d188004b108..c531e9d1cfe0a58e0a3cc8bddeaab9f0e2343898 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -1644,6 +1644,9 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, if( refLayer >= 0 && m_uiNumBlk[refLayer] != 0 ) { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + pcSlice->setSplitConsOverrideFlag(true); +#endif double dBlkSize = sqrt( ( double ) m_uiBlkSize[refLayer] / m_uiNumBlk[refLayer] ); if( dBlkSize < AMAXBT_TH32 ) { diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 3460e0c9f90b54afe65158eaddff8021b9bd8ced..970fc0a5b451bdb71a83d56fd42c7b7c1025b97a 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -830,6 +830,9 @@ void EncLib::xInitSPS(SPS &sps) sps.getSpsNext().setNextToolsEnabled ( m_profile == Profile::NEXT ); sps.getSpsNext().setUseQTBT ( m_QTBT ); sps.getSpsNext().setCTUSize ( m_CTUSize ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + sps.getSpsNext().setSplitConsOverrideEnabledFlag( m_useSplitConsOverride ); +#endif sps.getSpsNext().setMinQTSizes ( m_uiMinQT ); sps.getSpsNext().setUseLargeCTU ( m_LargeCTU ); sps.getSpsNext().setMaxBTDepth ( m_uiMaxBTDepth, m_uiMaxBTDepthI, m_uiMaxBTDepthIChroma ); diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index dd02a24b0caba44506d5d2c488319e37f9e9e3ff..1336219ab0c623e9c9005e5cd92aa8113db79a5c 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -672,7 +672,22 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr rpcSlice->setSliceSegmentArgument ( m_pcCfg->getSliceSegmentArgument() ); #endif rpcSlice->setMaxNumMergeCand ( m_pcCfg->getMaxNumMergeCand() ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + rpcSlice->setSplitConsOverrideFlag(false); + rpcSlice->setMinQTSize( rpcSlice->getSPS()->getSpsNext().getMinQTSize(eSliceType)); + rpcSlice->setMaxBTDepth( rpcSlice->isIntra() ? rpcSlice->getSPS()->getSpsNext().getMaxBTDepthI() : rpcSlice->getSPS()->getSpsNext().getMaxBTDepth() ); + rpcSlice->setMaxBTSize( rpcSlice->isIntra() ? rpcSlice->getSPS()->getSpsNext().getMaxBTSizeI() : rpcSlice->getSPS()->getSpsNext().getMaxBTSize() ); + rpcSlice->setMaxTTSize( rpcSlice->isIntra() ? rpcSlice->getSPS()->getSpsNext().getMaxTTSizeI() : rpcSlice->getSPS()->getSpsNext().getMaxTTSize() ); + if ( eSliceType == I_SLICE && rpcSlice->getSPS()->getSpsNext().getUseDualITree() ) + { + rpcSlice->setMinQTSizeIChroma( rpcSlice->getSPS()->getSpsNext().getMinQTSize(eSliceType, CHANNEL_TYPE_CHROMA) ); + rpcSlice->setMaxBTDepthIChroma( rpcSlice->getSPS()->getSpsNext().getMaxBTDepthIChroma() ); + rpcSlice->setMaxBTSizeIChroma( rpcSlice->getSPS()->getSpsNext().getMaxBTSizeIChroma() ); + rpcSlice->setMaxTTSizeIChroma( rpcSlice->getSPS()->getSpsNext().getMaxTTSizeIChroma() ); + } +#else rpcSlice->setMaxBTSize ( rpcSlice->isIntra() ? MAX_BT_SIZE : MAX_BT_SIZE_INTER ); +#endif } diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index f29ec0b3f6771e6874f832657be6f58ceab3991f..e28647afc264d9b12c045777ee0621be04f1b646 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -562,14 +562,45 @@ void HLSWriter::codeSPSNext( const SPSNext& spsNext, const bool usePCM ) { WRITE_FLAG( spsNext.getUseDualITree(), "qtbt_dual_intra_tree" ); WRITE_UVLC( g_aucLog2[spsNext.getCTUSize()] - MIN_CU_LOG2, "log2_CTU_size_minus2" ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + WRITE_FLAG (spsNext.getSplitConsOverrideEnabledFlag(), "override_partition_constraints_enable_flag"); +#endif +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize(I_SLICE)] - spsNext.getSPS().getLog2MinCodingBlockSize(), "log2_diff_min_qt_min_cb_intra_slice"); + WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize(B_SLICE)] - spsNext.getSPS().getLog2MinCodingBlockSize(), "log2_diff_min_qt_min_cb_inter_slice"); +#else WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize( I_SLICE ) ] - MIN_CU_LOG2, "log2_minQT_ISlice_minus2" ); WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize( B_SLICE ) ] - MIN_CU_LOG2, "log2_minQT_PBSlice_minus2" ); +#endif WRITE_UVLC( spsNext.getMaxBTDepth(), "max_bt_depth" ); WRITE_UVLC( spsNext.getMaxBTDepthI(), "max_bt_depth_i_slice" ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if (spsNext.getMaxBTDepthI() != 0) + { + WRITE_UVLC(g_aucLog2[spsNext.getMaxBTSizeI()] - g_aucLog2[spsNext.getMinQTSize(I_SLICE)], "log2_diff_max_bt_min_qt_intra_slice"); + WRITE_UVLC(g_aucLog2[spsNext.getMaxTTSizeI()] - g_aucLog2[spsNext.getMinQTSize(I_SLICE)], "log2_diff_max_tt_min_qt_intra_slice"); + } + if (spsNext.getMaxBTDepth() != 0) + { + WRITE_UVLC(g_aucLog2[spsNext.getMaxBTSize()] - g_aucLog2[spsNext.getMinQTSize(B_SLICE)], "log2_diff_max_bt_min_qt_inter_slice"); + WRITE_UVLC(g_aucLog2[spsNext.getMaxTTSize()] - g_aucLog2[spsNext.getMinQTSize(B_SLICE)], "log2_diff_max_tt_min_qt_inter_slice"); + } +#endif if( spsNext.getUseDualITree() ) { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize( I_SLICE, CHANNEL_TYPE_CHROMA )] - spsNext.getSPS().getLog2MinCodingBlockSize(), "log2_diff_min_qt_min_cb_intra_slice_chroma"); +#else WRITE_UVLC( g_aucLog2[spsNext.getMinQTSize( I_SLICE, CHANNEL_TYPE_CHROMA )] - MIN_CU_LOG2, "log2_minQT_ISliceChroma_minus2" ); +#endif WRITE_UVLC( spsNext.getMaxBTDepthIChroma(), "max_bt_depth_i_slice_chroma" ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if (spsNext.getMaxBTDepthIChroma() != 0) + { + WRITE_UVLC(g_aucLog2[spsNext.getMaxBTSizeIChroma()] - g_aucLog2[spsNext.getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA)], "log2_diff_max_bt_min_qt_intra_slice_chroma"); + WRITE_UVLC(g_aucLog2[spsNext.getMaxTTSizeIChroma()] - g_aucLog2[spsNext.getMinQTSize(I_SLICE, CHANNEL_TYPE_CHROMA)], "log2_diff_max_tt_min_qt_intra_slice_chroma"); + } +#endif } } @@ -646,7 +677,11 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) } } CHECK( pcSPS->getMaxCUWidth() != pcSPS->getMaxCUHeight(), "Rectangular CTUs not supported" ); +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + WRITE_UVLC( pcSPS->getLog2MinCodingBlockSize() - 2, "log2_min_luma_coding_block_size_minus2"); +#else WRITE_UVLC( pcSPS->getLog2MinCodingBlockSize() - 3, "log2_min_luma_coding_block_size_minus3" ); +#endif WRITE_UVLC( pcSPS->getLog2DiffMaxMinCodingBlockSize(), "log2_diff_max_min_luma_coding_block_size" ); WRITE_UVLC( pcSPS->getQuadtreeTULog2MinSize() - 2, "log2_min_luma_transform_block_size_minus2" ); WRITE_UVLC( pcSPS->getQuadtreeTULog2MaxSize() - pcSPS->getQuadtreeTULog2MinSize(), "log2_diff_max_min_luma_transform_block_size" ); @@ -1178,6 +1213,36 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) #endif if( pcSlice->getSPS()->getSpsNext().getUseQTBT() ) { +#if JVET_L0217_L0678_PARTITION_HIGHLEVEL_CONSTRAINT + if (pcSlice->getSPS()->getSpsNext().getSplitConsOverrideEnabledFlag()) + { + WRITE_FLAG(pcSlice->getSplitConsOverrideFlag() ? 1 : 0, "partition_constrainst_override_flag"); + if (pcSlice->getSplitConsOverrideFlag()) + { + WRITE_UVLC(g_aucLog2[pcSlice->getMinQTSize()] - pcSlice->getSPS()->getLog2MinCodingBlockSize(), "log2_diff_min_qt_min_cb"); + WRITE_UVLC(pcSlice->getMaxBTDepth(), "max_bt_depth"); + if (pcSlice->getMaxBTDepth() != 0) + { + CHECK(pcSlice->getMaxBTSize() < pcSlice->getMinQTSize(), "maxBtSize is smaller than minQtSize"); + WRITE_UVLC(g_aucLog2[pcSlice->getMaxBTSize()] - g_aucLog2[pcSlice->getMinQTSize()], "log2_diff_max_bt_min_qt"); + CHECK(pcSlice->getMaxTTSize() < pcSlice->getMinQTSize(), "maxTtSize is smaller than minQtSize"); + WRITE_UVLC(g_aucLog2[pcSlice->getMaxTTSize()] - g_aucLog2[pcSlice->getMinQTSize()], "log2_diff_max_tt_min_qt"); + } + if (pcSlice->isIntra() && pcSlice->getSPS()->getSpsNext().getUseDualITree()) + { + WRITE_UVLC(g_aucLog2[pcSlice->getMinQTSizeIChroma()] - pcSlice->getSPS()->getLog2MinCodingBlockSize(), "log2_diff_min_qt_min_cb_I_chroma"); + WRITE_UVLC(pcSlice->getMaxBTDepthIChroma(), "max_bt_depth_I_chroma"); + if (pcSlice->getMaxBTDepthIChroma() != 0) + { + CHECK(pcSlice->getMaxBTSizeIChroma() < pcSlice->getMinQTSizeIChroma(), "maxBtSizeC is smaller than minQtSizeC"); + WRITE_UVLC(g_aucLog2[pcSlice->getMaxBTSizeIChroma()] - g_aucLog2[pcSlice->getMinQTSizeIChroma()], "log2_diff_max_bt_min_qt_I_chroma"); + CHECK(pcSlice->getMaxTTSizeIChroma() < pcSlice->getMinQTSizeIChroma(), "maxTtSizeC is smaller than minQtSizeC"); + WRITE_UVLC(g_aucLog2[pcSlice->getMaxTTSizeIChroma()] - g_aucLog2[pcSlice->getMinQTSizeIChroma()], "log2_diff_max_tt_min_qt_I_Chroma"); + } + } + } + } +#else if( !pcSlice->isIntra() ) { if( pcSlice->getSPS()->getSpsNext().getCTUSize() > pcSlice->getMaxBTSize() ) @@ -1189,6 +1254,7 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) WRITE_UVLC( 0, "max_binary_tree_unit_size" ); } } +#endif } if( !pcSlice->isIntra() ) {