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() )
     {