diff --git a/cfg/encoder_intra_ecm.cfg b/cfg/encoder_intra_ecm.cfg
index 6bdc61a035b576575b6359537d964183a232782b..d22aba251746decf56eee6d9dba1f349de45a132 100644
--- a/cfg/encoder_intra_ecm.cfg
+++ b/cfg/encoder_intra_ecm.cfg
@@ -114,6 +114,7 @@ FastMrg                      : 1
 AMaxBT                       : 1
 FastMIP                      : 1
 FastLFNST                    : 1
+MTTSkipping                  : 1      # MTTSkipping: 0: disable, 1:enable
 
 # Encoder optimization tools
 AffineAmvrEncOpt             : 0
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index b149ac464cb2e05f3ac342cd13db708cde4e417c..1ba5adb972080804319dee2719f214ab644c5ac5 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -1189,7 +1189,7 @@ void EncApp::xInitLibCfg()
 #if JVET_Z0135_TEMP_CABAC_WIN_WEIGHT
   m_cEncLib.setTempCabacInitMode                                 ( m_tempCabacInitMode );
 #endif
-  #if JVET_AE0057_MTT_ET 
+  #if JVET_AJ0226_MTT_SKIP 
   m_cEncLib.setUseMttSkip                                        (m_useMttSkip);
 #endif
   // set internal bit-depth and constants
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index e9efe75120028a9f72c7ecbd3bf430cf88e4c953..05e6f31461c235b5409f8b74cad48336f8db3347 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1390,7 +1390,7 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("PBIntraFast",                                     m_usePbIntraFast,                                 false, "Fast assertion if the intra mode is probable")
   ("AMaxBT",                                          m_useAMaxBT,                                      false, "Adaptive maximal BT-size")
   ("E0023FastEnc",                                    m_e0023FastEnc,                                    true, "Fast encoding setting for QTBT (proposal E0023)")
-#if JVET_AE0057_MTT_ET
+#if JVET_AJ0226_MTT_SKIP
   ("MTTSkipping",                                     m_useMttSkip,                                     false, "MTT split modes early termination")
 #endif 
   ("ContentBasedFastQtbt",                            m_contentBasedFastQtbt,                           false, "Signal based QTBT speed-up")
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index e999b0988c8ed2dac680a9253c967c39b3d77195..a9b97a805b4aae4f5ca8d9d756c6c4a7a4d7e207 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -707,7 +707,7 @@ protected:
   unsigned  m_uiMaxCUWidth;                                   ///< max. CU width in pixel
   unsigned  m_uiMaxCUHeight;                                  ///< max. CU height in pixel
   unsigned m_log2MinCuSize;                                   ///< min. CU size log2
-#if JVET_AE0057_MTT_ET
+#if JVET_AJ0226_MTT_SKIP
   bool m_useMttSkip;
 #endif
 
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index cecac60bf30e775ec762867667720aa7206f2a7f..db50f722cc9257a577de395ae1b9886f08ea4266 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -63,7 +63,6 @@
 #define ALF_SAO_TRUE_ORG                                  1 // using true original samples for SAO and ALF optimization
 #define REMOVE_PCM                                        1 // Remove PCM related code for memory reduction and speedup
 #define JVET_Y0152_TT_ENC_SPEEDUP                         1 // TT encoding speedup
-#define JVET_AE0057_MTT_ET                                1 // JVET-AE0057: MTT early termination of 64x64 luma CU based on no-split RD cost 
 #define JVET_AF0177_ALF_COV_FLOAT                         1 // JVET-AF0177: Use float for ALF and CCALF covariance matrix
 
 
@@ -93,6 +92,7 @@
 #define LMCS_CHROMA_CALC_CU                               1 // Derive chroma LMCS parameter based on neighbor CUs. Needed by VPDU removal and 128x128 transform.
 #endif
 #define JVET_AI0087_BTCUS_RESTRICTION                     1 // JVET-AI0087: Restriction on BT CUs from applying QT like partitioning structure
+#define JVET_AJ0226_MTT_SKIP                              1 // JVET-AJ0226: MTT early termination applied to 64x64 & 32x32 luma CUs  
 
 //-- intra
 #define INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS             1 // Enable 2xN and Nx2 block by removing SCIPU constraints
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 9a2cd70cc0510aaa95464412e48905c13fd6d219..5572978251f9aa29cfa26385f89f613785e49fa1 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -682,7 +682,7 @@ protected:
   int       m_fastLocalDualTreeMode;
 #endif
   uint32_t  m_log2MaxTbSize;
-#if JVET_AE0057_MTT_ET
+#if JVET_AJ0226_MTT_SKIP
   bool      m_useMttSkip;
 #endif
 
@@ -2088,7 +2088,7 @@ public:
   int      getFastLocalDualTreeMode         () const         { return m_fastLocalDualTreeMode; }
 #endif
   void      setLog2MaxTbSize                ( uint32_t  u )   { m_log2MaxTbSize = u; }
-#if JVET_AE0057_MTT_ET
+#if JVET_AJ0226_MTT_SKIP
   void      setUseMttSkip                   (bool i)         { m_useMttSkip = i; }
   bool      getUseMttSkip                   () const         { return m_useMttSkip; }
 #endif
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index 9382e7c45e731ecd5bae8b3ba605fe2b43ef11b6..a4bdb314820cf9ea329ae8762275bef650ca1399 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -1005,6 +1005,143 @@ bool EncCu::xStoreRDcostandPredMode(CodingStructure *&tempCS, CodingStructure *&
   return true;
 }
 #endif
+#if JVET_AJ0226_MTT_SKIP
+void EncCu::xStoreMttSplitFlagCabacBits(CodingStructure*& tempCS, Partitioner& partitioner, int mttSplitFlagCabacBits)
+{
+  m_CABACEstimator->getCtx() = SubCtx(Ctx::Split, m_CurrCtx->start);
+  // TTH Split flag CABAC bits
+  m_CABACEstimator->resetBits();
+  m_CABACEstimator->split_cu_mode(PartSplit::CU_TRIH_SPLIT, *tempCS, partitioner
+#if JVET_AI0136_ADAPTIVE_DUAL_TREE
+    , nullptr
+#endif
+    , 0);
+
+  if (partitioner.currArea().lheight() == 256)
+  {
+    m_modeCtrl->setTthCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 0);
+  }
+  else if (partitioner.currArea().lheight() == 128)
+  {
+    m_modeCtrl->setTthCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 1);
+  }
+  else if (partitioner.currArea().lheight() == 64)
+  {
+    m_modeCtrl->setTthCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 2);
+  }
+  else if (partitioner.currArea().lheight() == 32)
+  {
+    m_modeCtrl->setTthCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 3);
+  }
+
+  m_CABACEstimator->getCtx() = SubCtx(Ctx::Split, m_CurrCtx->start);
+
+  // TTV Split flag CABAC bits
+  m_CABACEstimator->resetBits();
+  m_CABACEstimator->split_cu_mode(PartSplit::CU_TRIV_SPLIT, *tempCS, partitioner
+#if JVET_AI0136_ADAPTIVE_DUAL_TREE
+    , nullptr
+#endif
+    , 0);
+  if (partitioner.currArea().lheight() == 256)
+  {
+    m_modeCtrl->setTtvCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 0);
+  }
+  else if (partitioner.currArea().lheight() == 128)
+  {
+    m_modeCtrl->setTtvCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 1);
+  }
+  else if (partitioner.currArea().lheight() == 64)
+  {
+    m_modeCtrl->setTtvCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 2);
+  }
+  else if (partitioner.currArea().lheight() == 32)
+  {
+    m_modeCtrl->setTtvCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 3);
+  }
+
+  m_CABACEstimator->getCtx() = SubCtx(Ctx::Split, m_CurrCtx->start);
+
+  // BTH Split flag CABAC bits
+  m_CABACEstimator->resetBits();
+  m_CABACEstimator->split_cu_mode(PartSplit::CU_HORZ_SPLIT, *tempCS, partitioner
+#if JVET_AI0136_ADAPTIVE_DUAL_TREE
+    , nullptr
+#endif
+    , 0);
+  if (partitioner.currArea().lheight() == 256)
+  {
+    m_modeCtrl->setBthCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 0);
+  }
+  else if (partitioner.currArea().lheight() == 128)
+  {
+    m_modeCtrl->setBthCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 1);
+  }
+  else if (partitioner.currArea().lheight() == 64)
+  {
+    m_modeCtrl->setBthCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 2);
+  }
+  else if (partitioner.currArea().lheight() == 32)
+  {
+    m_modeCtrl->setBthCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 3);
+  }
+
+  m_CABACEstimator->getCtx() = SubCtx(Ctx::Split, m_CurrCtx->start);
+
+  // BTV Split flag CABAC bits
+  m_CABACEstimator->resetBits();
+  m_CABACEstimator->split_cu_mode(PartSplit::CU_VERT_SPLIT, *tempCS, partitioner
+#if JVET_AI0136_ADAPTIVE_DUAL_TREE
+    , nullptr
+#endif
+    , 0);
+  if (partitioner.currArea().lheight() == 256)
+  {
+    m_modeCtrl->setBtvCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 0);
+  }
+  else if (partitioner.currArea().lheight() == 128)
+  {
+    m_modeCtrl->setBtvCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 1);
+  }
+  else if (partitioner.currArea().lheight() == 64)
+  {
+    m_modeCtrl->setBtvCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 2);
+  }
+  else if (partitioner.currArea().lheight() == 32)
+  {
+    m_modeCtrl->setBtvCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 3);
+  }
+
+  m_CABACEstimator->getCtx() = SubCtx(Ctx::Split, m_CurrCtx->start);
+
+  // QT Split flag CABAC bits
+  m_CABACEstimator->resetBits();
+  m_CABACEstimator->split_cu_mode(PartSplit::CU_QUAD_SPLIT, *tempCS, partitioner
+#if JVET_AI0136_ADAPTIVE_DUAL_TREE
+    , nullptr
+#endif
+    , 0);
+
+  if (partitioner.currArea().lheight() == 256)
+  {
+    m_modeCtrl->setQtCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 0);
+  }
+  else if (partitioner.currArea().lheight() == 128)
+  {
+    m_modeCtrl->setQtCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 1);
+  }
+  else if (partitioner.currArea().lheight() == 64)
+  {
+    m_modeCtrl->setQtCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 2);
+  }
+  else if (partitioner.currArea().lheight() == 32)
+  {
+    m_modeCtrl->setQtCabacBits(mttSplitFlagCabacBits + (int)m_CABACEstimator->getEstFracBits(), 3);
+  }
+
+  m_CABACEstimator->getCtx() = SubCtx(Ctx::Split, m_CurrCtx->start);
+}
+#endif
 
 bool EncCu::xCheckBestMode( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode )
 {
@@ -1050,7 +1187,11 @@ bool EncCu::xCheckBestMode( CodingStructure *&tempCS, CodingStructure *&bestCS,
 
 }
 
-void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Partitioner& partitioner, double maxCostAllowed )
+void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Partitioner& partitioner, double maxCostAllowed 
+#if JVET_AJ0226_MTT_SKIP  
+  , int mttSplitFlagCabacBits
+#endif
+)
 {
   CHECK(maxCostAllowed < 0, "Wrong value of maxCostAllowed!");
 #if JVET_AA0133_INTER_MTS_OPT
@@ -1321,6 +1462,16 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 #endif
   m_CurrCtx->start = m_CABACEstimator->getCtx();
 
+#if JVET_AJ0226_MTT_SKIP  
+  if (partitioner.currBtDepth == 0  && (partitioner.currArea().lwidth() == partitioner.currArea().lheight())  && ( partitioner.currArea().lwidth() == 32 || partitioner.currArea().lwidth() == 64 || partitioner.currArea().lwidth() == 128  || partitioner.currArea().lwidth() == 256)
+#if JVET_AI0136_ADAPTIVE_DUAL_TREE
+    && (!(bestCS->slice->getProcessingIntraRegion() && bestCS->slice->getProcessingSeparateTrees()) || bestCS->slice->isIntra())
+#endif
+    )
+  {   
+    EncCu::xStoreMttSplitFlagCabacBits(tempCS, partitioner,mttSplitFlagCabacBits);
+  }
+#endif
   m_cuChromaQpOffsetIdxPlus1 = 0;
 
   if( slice.getUseChromaQpAdj() )
@@ -1712,16 +1863,25 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
       {
         xCheckRDCostIntra(tempCS, bestCS, partitioner, currTestMode, false);
       }
-#if JVET_AE0057_MTT_ET
-      if (partitioner.currQtDepth == (tempCS->sps->getCTUSize() == 256 ? 2 : 1) && partitioner.currBtDepth == 0
-          && partitioner.currArea().lwidth() == 64 && partitioner.currArea().lheight() == 64)
-      {
-        if ((partitioner.chType == CHANNEL_TYPE_LUMA)
-            && ((partitioner.currArea().Y().x + 63 < bestCS->picture->lwidth())
-                && (partitioner.currArea().Y().y + 63 < bestCS->picture->lheight())))
-
+#if JVET_AJ0226_MTT_SKIP
+      if ((partitioner.chType == CHANNEL_TYPE_LUMA) && partitioner.currBtDepth == 0
+        && (partitioner.currArea().lwidth() == partitioner.currArea().lheight())
+#if JVET_AI0136_ADAPTIVE_DUAL_TREE
+        && (!(bestCS->slice->getProcessingIntraRegion() && bestCS->slice->getProcessingSeparateTrees()) || bestCS->slice->isIntra())
+#endif
+        )
+      {       
+        if (( partitioner.currArea().Y().x + partitioner.currArea().lheight() - 1 < bestCS->picture->lwidth())
+          && (partitioner.currArea().Y().y + partitioner.currArea().lheight() - 1 < bestCS->picture->lheight()))
         {
-          m_modeCtrl->setNoSplitIntraCost(bestCS->cost);
+          if (partitioner.currArea().lheight() == 64)
+          {
+            m_modeCtrl->setNoSplitIntraCost64CU(bestCS->cost);
+          }
+          if (partitioner.currArea().lheight() == 32)
+          {
+            m_modeCtrl->setNoSplitIntraCost32CU(bestCS->cost);
+          }
         }
       }
 #endif
@@ -1885,11 +2045,30 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
         xCheckModeSplit( tempCS, bestCS, partitioner, currTestMode, modeTypeParent, skipInterPass );
 #endif
 #else
+#if JVET_AJ0226_MTT_SKIP      
+      if (partitioner.currBtDepth == 0 && (currTestMode.type == ETM_SPLIT_QT) && (partitioner.currArea().lwidth() == partitioner.currArea().lheight()) && partitioner.chType == CHANNEL_TYPE_LUMA
+#if JVET_AI0136_ADAPTIVE_DUAL_TREE
+        && (!(bestCS->slice->getProcessingIntraRegion() && bestCS->slice->getProcessingSeparateTrees()) || bestCS->slice->isIntra())
+#endif
+        )
+      {
+        mttSplitFlagCabacBits = (partitioner.currArea().lwidth() == 128 ? m_modeCtrl->getQtCabacBits(0) : partitioner.currArea().lwidth() == 64 ? m_modeCtrl->getQtCabacBits(1) : partitioner.currArea().lwidth() == 32 ? m_modeCtrl->getQtCabacBits(2) : 0);
+      }
+#endif
 #if JVET_Y0152_TT_ENC_SPEEDUP
-      xCheckModeSplit(tempCS, bestCS, partitioner, currTestMode, splitRdCostBest);
+     
+      xCheckModeSplit(tempCS, bestCS, partitioner, currTestMode, splitRdCostBest
+#if JVET_AJ0226_MTT_SKIP 
+        , mttSplitFlagCabacBits
+#endif
+      );
       tempCS->splitRdCostBest = splitRdCostBest;
 #else
-      xCheckModeSplit(tempCS, bestCS, partitioner, currTestMode);
+      xCheckModeSplit(tempCS, bestCS, partitioner, currTestMode
+#if JVET_AJ0226_MTT_SKIP 
+        , mttSplitFlagCabacBits
+#endif
+      );      
 #endif
 #endif
 #if JVET_AI0087_BTCUS_RESTRICTION 
@@ -2478,9 +2657,17 @@ void EncCu::copyState( EncCu* other, Partitioner& partitioner, const UnitArea& c
 #endif
 #if INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
 #if JVET_Y0152_TT_ENC_SPEEDUP
-void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode, double *splitRdCostBest)
+void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode, double *splitRdCostBest
+#if JVET_AJ0226_MTT_SKIP  
+  , int mttSplitFlagCabacBits
+#endif
+)
 #else
-void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode )
+void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode 
+#if JVET_AJ0226_MTT_SKIP  
+  , int mttSplitFlagCabacBits
+#endif
+)
 #endif
 #else
 #if JVET_Y0152_TT_ENC_SPEEDUP
@@ -2610,15 +2797,25 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
       CodingStructure *tempSubCS = m_pTempCS[wIdx][hIdx];
       CodingStructure *bestSubCS = m_pBestCS[wIdx][hIdx];
 
-#if JVET_AE0057_MTT_ET
-      if (partitioner.currQtDepth == (tempCS->sps->getCTUSize() == 256 ? 2 : 1) && partitioner.currBtDepth == 0
-          && partitioner.currArea().lwidth() == 64 && partitioner.currArea().lheight() == 64)
+#if JVET_AJ0226_MTT_SKIP
+      if ((partitioner.chType == CHANNEL_TYPE_LUMA) && partitioner.currBtDepth == 0
+        && (partitioner.currArea().lwidth() == partitioner.currArea().lheight())
+#if JVET_AI0136_ADAPTIVE_DUAL_TREE
+        && (!(bestCS->slice->getProcessingIntraRegion() && bestCS->slice->getProcessingSeparateTrees()) || bestCS->slice->isIntra())
+#endif
+      )
       {
-        if ((partitioner.chType == CHANNEL_TYPE_LUMA)
-            && ((partitioner.currArea().Y().x + 63 < bestCS->picture->lwidth())
-                && (partitioner.currArea().Y().y + 63 < bestCS->picture->lheight())))
+        if ((( partitioner.currArea().Y().x + partitioner.currArea().lheight() - 1) < bestCS->picture->lwidth())
+          && ((partitioner.currArea().Y().y + partitioner.currArea().lheight() - 1) < bestCS->picture->lheight()))
         {
-          m_modeCtrl->setNoSplitIntraCost(0.0);
+          if (partitioner.currArea().lheight() == 64)
+          {
+            m_modeCtrl->setNoSplitIntraCost64CU(0.0);
+          }
+          if (partitioner.currArea().lheight() == 32)
+          {
+            m_modeCtrl->setNoSplitIntraCost32CU(0.0);
+          }
         }
       }
 #endif 
@@ -2690,7 +2887,11 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
       tempSubCS->bestParent = bestSubCS->bestParent = bestCS;
       double newMaxCostAllowed = isLuma(partitioner.chType) ? std::min(encTestMode.maxCostAllowed, bestCS->cost - m_pcRdCost->calcRdCost(tempCS->fracBits, tempCS->dist)) : MAX_DOUBLE;
       newMaxCostAllowed = std::max(0.0, newMaxCostAllowed);
-      xCompressCU(tempSubCS, bestSubCS, partitioner, newMaxCostAllowed);
+      xCompressCU(tempSubCS, bestSubCS, partitioner, newMaxCostAllowed
+#if JVET_AJ0226_MTT_SKIP  
+        , mttSplitFlagCabacBits
+#endif
+      );
       tempSubCS->bestParent = bestSubCS->bestParent = nullptr;
 
       if( bestSubCS->cost == MAX_DOUBLE )
diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h
index ae0e5cff63e62f7adcde06d4cf039a105afea21c..982211a7dfce095678da7c51b107b81fc2cd830e 100644
--- a/source/Lib/EncoderLib/EncCu.h
+++ b/source/Lib/EncoderLib/EncCu.h
@@ -528,8 +528,14 @@ protected:
 
   void xCalDebCost            ( CodingStructure &cs, Partitioner &partitioner, bool calDist = false );
   Distortion getDistortionDb  ( CodingStructure &cs, CPelBuf org, CPelBuf reco, ComponentID compID, const CompArea& compArea, bool afterDb );
-
-  void xCompressCU            ( CodingStructure*& tempCS, CodingStructure*& bestCS, Partitioner& pm, double maxCostAllowed = MAX_DOUBLE );
+#if JVET_AJ0226_MTT_SKIP
+  void xStoreMttSplitFlagCabacBits(CodingStructure*& tempCS, Partitioner& partitioner, int mttSplitFlagCabacBits);
+#endif
+  void xCompressCU            ( CodingStructure*& tempCS, CodingStructure*& bestCS, Partitioner& pm, double maxCostAllowed = MAX_DOUBLE 
+#if JVET_AJ0226_MTT_SKIP 
+    , int mttSplitFlagCabacBits = 0
+#endif
+  );
 #if ENABLE_SPLIT_PARALLELISM
   void xCompressCUParallel    ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm );
   void copyState              ( EncCu* other, Partitioner& pm, const UnitArea& currArea, const bool isDist );
@@ -538,15 +544,31 @@ protected:
     xCheckBestMode         ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestmode );
 #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
 #if JVET_Y0152_TT_ENC_SPEEDUP
-  void xCheckModeSplit        ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode, const ModeType modeTypeParent, bool &skipInterPass, double *splitRdCostBest );
+  void xCheckModeSplit        ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode, const ModeType modeTypeParent, bool &skipInterPass, double *splitRdCostBest 
+#if JVET_AJ0226_MTT_SKIP
+    , int mttSplitFlagCabacBits
+#endif
+  );
 #else
-  void xCheckModeSplit        ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode, const ModeType modeTypeParent, bool &skipInterPass );
+  void xCheckModeSplit        ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode, const ModeType modeTypeParent, bool &skipInterPass 
+#if JVET_AJ0226_MTT_SKIP
+    , int mttSplitFlagCabacBits
+#endif
+  );
 #endif
 #else
 #if JVET_Y0152_TT_ENC_SPEEDUP
-  void xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode, double *splitRdCostBest);
+  void xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode, double *splitRdCostBest
+#if JVET_AJ0226_MTT_SKIP
+    , int mttSplitFlagCabacBits
+#endif
+  );
 #else
-  void xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode );
+  void xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode 
+#if JVET_AJ0226_MTT_SKIP
+    , int mttSplitFlagCabacBits
+#endif
+  );
 #endif
 #endif
   bool xCheckRDCostIntra(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode, bool adaptiveColorTrans);
diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp
index 0328a69b8e0fc213129b5ead2fc425216e19a169..b2472bf5e2f7fab82157c65b71893823a78898df 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.cpp
+++ b/source/Lib/EncoderLib/EncModeCtrl.cpp
@@ -1727,12 +1727,11 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
 #if JVET_AI0087_BTCUS_RESTRICTION
   bool disableBTV = false;
   bool disableBTH = false;
-  
+  if (EncModeCtrl::isLumaNonBoundaryCu(partitioner, cs.picture->lwidth(), cs.picture->lheight()) 
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
-  if (EncModeCtrl::isLumaNonBoundaryCu(partitioner, cs.picture->lwidth(), cs.picture->lheight()) && (!(cs.slice->getProcessingIntraRegion() && cs.slice->getProcessingSeparateTrees()) || cs.slice->isIntra()) )
-#else
-  if (EncModeCtrl::isLumaNonBoundaryCu(partitioner, cs.picture->lwidth(), cs.picture->lheight()) )
+    && (!(cs.slice->getProcessingIntraRegion() && cs.slice->getProcessingSeparateTrees()) || cs.slice->isIntra()) 
 #endif
+    )
   {
     if ((partitioner.currBtDepth == 1) && (partitioner.currPartIdx() == 1))
     {
@@ -2541,28 +2540,48 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
   ComprCUCtx& cuECtx = m_ComprCUCtxList[EncModeCtrl::m_treeIdx].back();
 #else
   ComprCUCtx& cuECtx = m_ComprCUCtxList.back();
-#endif
-  // MTT modes early termination for 64x64 luma CU based on nosplit intra cost
-#if JVET_AE0057_MTT_ET
-  if (m_pcEncCfg->getUseMttSkip() && partitioner.currQtDepth == (cs.sps->getCTUSize() == 256 ? 2 : 1)
-      && partitioner.currBtDepth == 0
-      && partitioner.currArea().lwidth() == 64 && partitioner.currArea().lheight() == 64
+#endif     
+
+#if JVET_AJ0226_MTT_SKIP   
+  if (m_pcEncCfg->getUseMttSkip() && partitioner.currBtDepth == 0 && (partitioner.currArea().lwidth() == partitioner.currArea().lheight()) &&
+      (partitioner.currArea().lwidth() == 64 || partitioner.currArea().lwidth() == 32 ))
+  {
+    if (((partitioner.currArea().Y().x + partitioner.currArea().lwidth()-1  < cs.picture->lwidth())
+      && (partitioner.currArea().Y().y + partitioner.currArea().lwidth()-1  < cs.picture->lheight()))
+      && (encTestmode.type == ETM_SPLIT_BT_H || encTestmode.type == ETM_SPLIT_BT_V
+        || encTestmode.type == ETM_SPLIT_TT_H || encTestmode.type == ETM_SPLIT_TT_V)
+      && partitioner.chType == CHANNEL_TYPE_LUMA 
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
-      && !(cs.slice->getSeparateTreeEnabled() && cs.sps->getInterSliceSeparateTreeEnabled())
+      && (!(cs.slice->getProcessingIntraRegion() && cs.slice->getProcessingSeparateTrees()) || cs.slice->isIntra())
 #endif
-    )
-  {
-    if (((partitioner.currArea().Y().x + 63 < cs.picture->lwidth())
-         && (partitioner.currArea().Y().y + 63 < cs.picture->lheight()))
-        && (encTestmode.type == ETM_SPLIT_BT_H || encTestmode.type == ETM_SPLIT_BT_V
-            || encTestmode.type == ETM_SPLIT_TT_H || encTestmode.type == ETM_SPLIT_TT_V)
-        && partitioner.chType == CHANNEL_TYPE_LUMA)
+      )
     {
-      int thresholdMTT = Clip3(0, MAX_INT, (120 - ((m_pcEncCfg->getBaseQP() - 22) * 3)) * 1000000);
-      if (m_noSplitIntraRdCost > thresholdMTT)
+      double splitSignalCostScaling = Clip3(0.0, 4.0, (4.0 * pow(0.5, (m_pcEncCfg->getBaseQP() - 22.0) / 5)));
+      int modeCabacCost = 0;
+
+      if (encTestmode.type == ETM_SPLIT_TT_H)
       {
-        const PartSplit split = getPartSplit(encTestmode);
+        modeCabacCost = partitioner.currArea().lwidth() == 64 ? m_cabacBitsforTTH[2] : partitioner.currArea().lwidth() == 32 ? m_cabacBitsforTTH[3] : 0;
+      }
+      else if (encTestmode.type == ETM_SPLIT_TT_V)
+      {
+        modeCabacCost = partitioner.currArea().lwidth() == 64 ? m_cabacBitsforTTV[2] : partitioner.currArea().lwidth() == 32 ? m_cabacBitsforTTV[3] : 0;
+      }
+      else if (encTestmode.type == ETM_SPLIT_BT_H)
+      {
+        modeCabacCost = partitioner.currArea().lwidth() == 64 ? m_cabacBitsforBTH[2] : partitioner.currArea().lwidth() == 32 ? m_cabacBitsforBTH[3] : 0;
+      }
+      else if (encTestmode.type == ETM_SPLIT_BT_V)
+      {
+        modeCabacCost = partitioner.currArea().lwidth() == 64 ? m_cabacBitsforBTV[2] : partitioner.currArea().lwidth() == 32 ? m_cabacBitsforBTV[3] : 0;
+      }
+
+      int thresholdMTT = Clip3(0, MAX_INT, (140 - ((cs.slice->getSliceQp() - 22) * 3)) * (1000000 - (int)(modeCabacCost * splitSignalCostScaling) ));
+      double noSplitCost = partitioner.currArea().lwidth() == 64 ? m_noSplitIntraRdCost64CU : partitioner.currArea().lwidth() == 32 ? m_noSplitIntraRdCost32CU :  0;
 
+      if (noSplitCost > thresholdMTT)
+      {
+        const PartSplit split = getPartSplit(encTestmode);
         if (split == CU_HORZ_SPLIT)
         {
           cuECtx.set(DID_HORZ_SPLIT, false);
@@ -2571,6 +2590,14 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
         {
           cuECtx.set(DID_VERT_SPLIT, false);
         }
+        if (split == CU_TRIH_SPLIT)
+        {
+          cuECtx.set(DO_TRIH_SPLIT, false);
+        }
+        if (split == CU_TRIV_SPLIT)
+        {
+          cuECtx.set(DO_TRIV_SPLIT, false);
+        }
         return false;
       }
     }
diff --git a/source/Lib/EncoderLib/EncModeCtrl.h b/source/Lib/EncoderLib/EncModeCtrl.h
index f86fbb8b29ab9edeacbb5a8de36ee63fc43d2101..b58a6ee74372a53f33f9424c42a8106ecea597b8 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.h
+++ b/source/Lib/EncoderLib/EncModeCtrl.h
@@ -356,8 +356,14 @@ protected:
   InterSearch*          m_pcInterSearch;
 
   bool                  m_doPlt;
-#if JVET_AE0057_MTT_ET
-  double                m_noSplitIntraRdCost;   
+#if JVET_AJ0226_MTT_SKIP
+  double                m_noSplitIntraRdCost64CU;
+  double                m_noSplitIntraRdCost32CU;
+  int                   m_cabacBitsforBTH[4];
+  int                   m_cabacBitsforBTV[4];
+  int                   m_cabacBitsforTTH[4];
+  int                   m_cabacBitsforTTV[4];
+  int                   m_cabacBitsforQT[4];
 #endif
 
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
@@ -410,8 +416,23 @@ public:
 #if JVET_AI0087_BTCUS_RESTRICTION
   bool         isLumaNonBoundaryCu(const Partitioner& partitioner, SizeType picWidth, SizeType picHeight);
 #endif
-#if JVET_AE0057_MTT_ET
-  void         setNoSplitIntraCost  (double cost) { m_noSplitIntraRdCost = cost; }
+#if JVET_AJ0226_MTT_SKIP
+  void         setNoSplitIntraCost64CU(double cost) { m_noSplitIntraRdCost64CU = cost; }
+  void         setNoSplitIntraCost32CU  (double cost) { m_noSplitIntraRdCost32CU = cost;}
+
+  void         setBthCabacBits(int bitsCabac, int pos) { m_cabacBitsforBTH[pos]  = bitsCabac; }
+  void         setBtvCabacBits(int bitsCabac, int pos) { m_cabacBitsforBTV[pos]  = bitsCabac; }
+  void         setTthCabacBits(int bitsCabac, int pos) { m_cabacBitsforTTH[pos] = bitsCabac; }
+  void         setTtvCabacBits(int bitsCabac, int pos) { m_cabacBitsforTTV[pos] = bitsCabac; }
+  void         setQtCabacBits (int bitsCabac, int pos) { m_cabacBitsforQT[pos] = bitsCabac; }
+
+
+  int         getBthCabacBits(int pos) { return m_cabacBitsforBTH[pos] ; }
+  int         getBtvCabacBits(int pos) { return m_cabacBitsforBTV[pos] ; }
+  int         getTthCabacBits(int pos) { return m_cabacBitsforTTH[pos] ; }
+  int         getTtvCabacBits(int pos) { return m_cabacBitsforTTV[pos] ; }
+  int         getQtCabacBits (int pos)  { return m_cabacBitsforQT[pos]  ; }
+
 #endif
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
   ComprCUCtx&       getComprCUCtx    ()                      { CHECK( m_ComprCUCtxList[m_treeIdx].empty(), "Accessing empty list!"); return m_ComprCUCtxList[m_treeIdx].back(); }
@@ -517,6 +538,18 @@ public:
   void   setStopNonDCT2Transforms     ( bool val )              { m_ComprCUCtxList.back().stopNonDCT2Transforms = val; }
 #endif 
 
+
+#if JVET_AJ0226_MTT_SKIP 
+  void resetSplitSignalCostParams()
+  {
+    std::memset(m_cabacBitsforTTH, 0, sizeof(m_cabacBitsforTTH));
+    std::memset(m_cabacBitsforTTV, 0, sizeof(m_cabacBitsforTTV));
+    std::memset(m_cabacBitsforBTH, 0, sizeof(m_cabacBitsforBTH));
+    std::memset(m_cabacBitsforBTV, 0, sizeof(m_cabacBitsforBTV));
+    std::memset(m_cabacBitsforQT, 0, sizeof(m_cabacBitsforQT));
+  }
+#endif
+
   void setInterSearch                 (InterSearch* pcInterSearch)   { m_pcInterSearch = pcInterSearch; }
   void   setPltEnc                    ( bool b )                { m_doPlt = b; }
   bool   getPltEnc()                                      const { return m_doPlt; }
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index b61088704df6c3edfa2c90cd38390d6d0b9791fc..af77dcfd4c4481b513fa72cbd28dd0186c1f4b74 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -2080,6 +2080,9 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
   {
     const int32_t ctuRsAddr = pcSlice->getCtuAddrInSlice( ctuIdx );
 
+#if JVET_AJ0226_MTT_SKIP 
+    m_pcCuEncoder->getModeCtrl()->resetSplitSignalCostParams();
+#endif
     // update CABAC state
     const uint32_t ctuXPosInCtus        = ctuRsAddr % widthInCtus;
     const uint32_t ctuYPosInCtus        = ctuRsAddr / widthInCtus;