diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp
index 4f2296d89d8ddfc86a40b055842c345f539a6bce..9f41baa2f13ebd3fb2c9912b3ec24a1ba834bde7 100644
--- a/source/Lib/CommonLib/ContextModelling.cpp
+++ b/source/Lib/CommonLib/ContextModelling.cpp
@@ -198,7 +198,9 @@ unsigned DeriveCtx::CtxCUsplit( const CodingStructure& cs, Partitioner& partitio
 #endif
 
   ctxId += ( cuAbove && cuAbove->qtDepth > partitioner.currQtDepth ) ? 1 : 0;
-
+#if JVET_L0361_SPLIT_CTX
+  ctxId += partitioner.currQtDepth < 2 ? 0 : 3;
+#else
   if( cs.sps->getSpsNext().getUseLargeCTU() )
   {
     unsigned minDepth = 0;
@@ -213,6 +215,7 @@ unsigned DeriveCtx::CtxCUsplit( const CodingStructure& cs, Partitioner& partitio
       ctxId = 4;
     }
   }
+#endif
 
   return ctxId;
 }
@@ -319,10 +322,39 @@ unsigned DeriveCtx::CtxBTsplit(const CodingStructure& cs, Partitioner& partition
 #endif
 
   {
+#if JVET_L0361_SPLIT_CTX
+    unsigned widthCurr = partitioner.currArea().lwidth();
+    unsigned heightCurr = partitioner.currArea().lheight();
+
+    if( cuLeft )
+    {
+      unsigned heightLeft = cuLeft->Y().height;
+      ctx += ( heightLeft < heightCurr ? 1 : 0 );
+    }
+    if( cuAbove )
+    {
+      unsigned widthAbove = cuAbove->Y().width;
+      ctx += ( widthAbove < widthCurr ? 1 : 0 );
+    }
+
+    if( partitioner.chType == CHANNEL_TYPE_CHROMA )
+    {
+      ctx += 9;
+    }
+    else
+    {
+      int maxBTSize = cs.pcv->getMaxBtSize( *cs.slice, partitioner.chType );
+      int th1 = ( maxBTSize == 128 ) ? 128  : ( ( maxBTSize == 64 ) ? 64  : 64  );
+      int th2 = ( maxBTSize == 128 ) ? 1024 : ( ( maxBTSize == 64 ) ? 512 : 256 );
+      unsigned int sizeCurr = widthCurr * heightCurr;
+      ctx += sizeCurr > th2 ? 0 : ( sizeCurr > th1 ? 3 : 6 );
+    }
+#else
     const unsigned currDepth = partitioner.currQtDepth * 2 + partitioner.currBtDepth;
 
     if( cuLeft )  ctx += ( ( 2 * cuLeft->qtDepth  + cuLeft->btDepth  ) > currDepth ? 1 : 0 );
     if( cuAbove ) ctx += ( ( 2 * cuAbove->qtDepth + cuAbove->btDepth ) > currDepth ? 1 : 0 );
+#endif
   }
   return ctx;
 }
diff --git a/source/Lib/CommonLib/Contexts.cpp b/source/Lib/CommonLib/Contexts.cpp
index 63576e159053b7ae8bf35f55b6658c5a6141409f..434e66e89c9de59b81126a4def2fbfdc28370c46 100644
--- a/source/Lib/CommonLib/Contexts.cpp
+++ b/source/Lib/CommonLib/Contexts.cpp
@@ -262,16 +262,29 @@ std::vector<std::vector<uint8_t>> ContextSetCfg::sm_InitTables( NUMBER_OF_SLICE_
 
 const CtxSet ContextSetCfg::SplitFlag = ContextSetCfg::addCtxSet
 ({
+#if JVET_L0361_SPLIT_CTX
+  {  107, 139, 126, 107, 139, 126, },
+  {  107, 139, 126, 107, 139, 126, },
+  {  139, 141, 157, 139, 141, 157, },
+#else
   {  107, 139, 126, 255,   0,},
   {  107, 139, 126, 255,   0,},
   {  139, 141, 157, 255,   0,},
+#endif
 });
 
 const CtxSet ContextSetCfg::BTSplitFlag = ContextSetCfg::addCtxSet
 ({
+#if JVET_L0361_SPLIT_CTX
+  // |-------- 1st bin, 9 ctx for luma + 3 ctx for chroma------| |--2nd bin--| |3rd bin|
+  {  107, 139, 126, 107, 139, 126, 107, 139, 126, 107, 139, 126, 154, 154, 154, 154,},
+  {  107, 139, 126, 107, 139, 126, 107, 139, 126, 107, 139, 126, 154, 154, 154, 154,},
+  {  139, 141, 157, 139, 141, 157, 139, 141, 157, 139, 141, 157, 154, 154, 154, 154,},
+#else
   {  107, 139, 126, 154, 154, 154, 154, 154, 154, 154, 154, 154,},
   {  107, 139, 126, 154, 154, 154, 154, 154, 154, 154, 154, 154,},
   {  139, 141, 157, 154, 154, 154, 154, 154, 154, 154, 154, 154,},
+#endif
 });
 
 const CtxSet ContextSetCfg::SkipFlag = ContextSetCfg::addCtxSet
diff --git a/source/Lib/CommonLib/LoopFilter.cpp b/source/Lib/CommonLib/LoopFilter.cpp
index e0135d1c1dee0841329c7d4bc0d40b6b9baa7792..f4b7522fcca5fa803b7c52569a6fd313297f1966 100644
--- a/source/Lib/CommonLib/LoopFilter.cpp
+++ b/source/Lib/CommonLib/LoopFilter.cpp
@@ -250,6 +250,10 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir )
     xSetEdgefilterMultiple( cu, EDGE_HOR, areaTu, m_stLFCUParam.internalEdge );
   }
 
+#if L0074_SUBBLOCK_DEBLOCKING
+  bool mvSubBlocks = false;
+  int subBlockSize = 8;
+#endif
   for( auto &currPU : CU::traversePUs( cu ) )
   {
     const Area& areaPu = cu.Y().valid() ? currPU.block( COMPONENT_Y ) : area;
@@ -259,8 +263,31 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir )
     xSetEdgefilterMultiple( cu, EDGE_VER, areaPu, (xOff ? m_stLFCUParam.internalEdge : m_stLFCUParam.leftEdge), xOff );
     xSetEdgefilterMultiple( cu, EDGE_HOR, areaPu, (yOff ? m_stLFCUParam.internalEdge : m_stLFCUParam.topEdge),  yOff );
 
+#if L0074_SUBBLOCK_DEBLOCKING
+    if ((currPU.mergeFlag && (currPU.mergeType == MRG_TYPE_SUBPU_ATMVP)) || cu.affine)
+    {
+      mvSubBlocks = true;
+      if (edgeDir == EDGE_HOR)
+      {
+        for (uint32_t off = subBlockSize; off < areaPu.height; off += subBlockSize)
+        {
+          const Area mvBlockH(cu.Y().x, cu.Y().y + off, cu.Y().width, pcv.minCUHeight);
+          xSetEdgefilterMultiple(cu, EDGE_HOR, mvBlockH, m_stLFCUParam.internalEdge, 1);
+        }
+      }
+      else
+      {
+        for (uint32_t off = subBlockSize; off < areaPu.width; off += subBlockSize)
+        {
+          const Area mvBlockV(cu.Y().x + off, cu.Y().y, pcv.minCUWidth, cu.Y().height);
+          xSetEdgefilterMultiple(cu, EDGE_VER, mvBlockV, m_stLFCUParam.internalEdge, 1);
+        }
+      }
+    }
+#endif
   }
 
+#if !L0074_SUBBLOCK_DEBLOCKING
   if ( cu.affine )
   {
     const int widthInBaseUnits = cu.Y().width >> pcv.minCUWidthLog2;
@@ -276,6 +303,7 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir )
       xSetEdgefilterMultiple( cu, EDGE_HOR, affiBlockH, m_stLFCUParam.internalEdge, 1 );
     }
   }
+#endif
   const unsigned uiPelsInPart = pcv.minCUWidth;
 
   for( int y = 0; y < area.height; y += uiPelsInPart )
@@ -316,12 +344,27 @@ void LoopFilter::xDeblockCU( CodingUnit& cu, const DeblockEdgeDir edgeDir )
 
   if (cu.blocks[COMPONENT_Y].valid())
   {
+#if L0074_SUBBLOCK_DEBLOCKING
+    if (mvSubBlocks)
+    {
+      orthogonalIncrement = subBlockSize / 4;
+      orthogonalLength = (edgeDir == EDGE_HOR) ? cu.blocks[COMPONENT_Y].height / 4 : cu.blocks[COMPONENT_Y].width / 4;
+    }
+#endif
+#if L0074_SUBBLOCK_DEBLOCKING
+    if ((cu.blocks[COMPONENT_Y].height > 64) && (edgeDir == EDGE_HOR) && !mvSubBlocks)
+#else
     if ((cu.blocks[COMPONENT_Y].height > 64) && (edgeDir == EDGE_HOR))
+#endif
     {
       orthogonalIncrement = 64 / 4;
       orthogonalLength = cu.blocks[COMPONENT_Y].height / 4;
     }
+#if L0074_SUBBLOCK_DEBLOCKING
+    if ((cu.blocks[COMPONENT_Y].width > 64) && (edgeDir == EDGE_VER) && !mvSubBlocks)
+#else
     if ((cu.blocks[COMPONENT_Y].width > 64) && (edgeDir == EDGE_VER))
+#endif
     {
       orthogonalIncrement = 64 / 4;
       orthogonalLength = cu.blocks[COMPONENT_Y].width / 4;
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index afc72b3b03d815888b1ae9afc455379aacbdaf99..af2cf490b7a86a5545535951e2bb5a30a7ca446b 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -50,6 +50,8 @@
 #include <assert.h>
 #include <cassert>
 
+#define JVET_L0553_FIX_INITQP                             1
+
 #define JVET_L0147_ALF_SUBSAMPLED_LAPLACIAN               1 // Subsampled Laplacian calculation
 
 #define JVET_L0191_LM_WO_LMS                              1 // NO LMS regression. min/max are used instead
@@ -66,9 +68,13 @@
 
 #define JVET_L0194_ONE_CTX_FOR_MRG_IDX                    1 // one context for full-block Merge index
 
+#define JVET_L0361_SPLIT_CTX                              1 // context for cu-split-related flags
+
 #define JVET_L0274                                        1
 #define JVET_L0274_ENCODER_SPEED_UP                     ( 1 && JVET_L0274 ) // encoder speed-up by pre-calculating position dependent parameters
 
+#define L0074_SUBBLOCK_DEBLOCKING                         1
+
 #define JVET_L0256_BIO                                    1
 #if JVET_L0256_BIO
 #define JVET_L0256_BIO_EXTEND_SIZE                        1
@@ -84,6 +90,8 @@
 
 #define JVET_L0093_SIMP_PRUNE                             1
 
+#define JVET_L0257_ATMVP_COLBLK_CLIP                      1
+
 #ifndef JVET_B0051_NON_MPM_MODE
 #define JVET_B0051_NON_MPM_MODE                         ( 1 && JEM_TOOLS )
 #endif
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 50a027e071af64297cd7c24ed9ea49e4c8c4366e..065e4fe39742efeb66e7cff63714dc3909d5d84f 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -2239,6 +2239,23 @@ static bool deriveScaledMotionTemporal( const Slice&      slice,
   return false;
 }
 
+#if JVET_L0257_ATMVP_COLBLK_CLIP
+void clipColPos(int& posX, int& posY, const PredictionUnit& pu)
+{
+  Position puPos = pu.lumaPos();
+  int log2CtuSize = g_aucLog2[pu.cs->sps->getSpsNext().getCTUSize()];
+  int ctuX = ((puPos.x >> log2CtuSize) << log2CtuSize);
+  int ctuY = ((puPos.y >> log2CtuSize) << log2CtuSize);
+
+  int horMax = std::min((int)pu.cs->sps->getPicWidthInLumaSamples() - 1, ctuX + (int)pu.cs->sps->getSpsNext().getCTUSize() + 3);
+  int horMin = std::max((int)0, ctuX);
+  int verMax = std::min((int)pu.cs->sps->getPicHeightInLumaSamples() - 1, ctuY + (int)pu.cs->sps->getSpsNext().getCTUSize() - 1);
+  int verMin = std::max((int)0, ctuY);
+
+  posX = std::min(horMax, std::max(horMin, posX));
+  posY = std::min(verMax, std::max(verMin, posY));
+}
+#else
 void clipColBlkMv(int& mvX, int& mvY, const PredictionUnit& pu)
 {
   Position puPos = pu.lumaPos();
@@ -2261,6 +2278,7 @@ void clipColBlkMv(int& mvX, int& mvY, const PredictionUnit& pu)
   mvX = std::min(horMax, std::max(horMin, mvX));
   mvY = std::min(verMax, std::max(verMin, mvY));
 }
+#endif
 
 bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, bool& LICFlag, const int count
 )
@@ -2303,7 +2321,9 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b
 #if !REMOVE_MV_ADAPT_PREC
   }
 #endif
+#if !JVET_L0257_ATMVP_COLBLK_CLIP
   int mvRndOffs = (1 << mvPrec) >> 1;
+#endif
 
   Mv cTempVector = cTMv;
   bool  tempLICFlag = false;
@@ -2324,6 +2344,15 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b
 
   bool found = false;
   cTempVector = cTMv;
+#if JVET_L0257_ATMVP_COLBLK_CLIP
+  int tempX = cTempVector.getHor() >> mvPrec;
+  int tempY = cTempVector.getVer() >> mvPrec;
+
+  centerPos.x = puPos.x + (puSize.width >> 1) + tempX;
+  centerPos.y = puPos.y + (puSize.height >> 1) + tempY;
+
+  clipColPos(centerPos.x, centerPos.y, pu);
+#else
   int tempX = ((cTempVector.getHor() + mvRndOffs) >> mvPrec);
   int tempY = ((cTempVector.getVer() + mvRndOffs) >> mvPrec);
   clipColBlkMv(tempX, tempY, pu);
@@ -2341,6 +2370,7 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b
 
   centerPos.x = Clip3(0, (int)pColPic->lwidth() - 1, centerPos.x);
   centerPos.y = Clip3(0, (int)pColPic->lheight() - 1, centerPos.y);
+#endif
 
   centerPos = Position{ PosType(centerPos.x & mask), PosType(centerPos.y & mask) };
 
@@ -2377,6 +2407,10 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b
     return false;
   }
   
+#if JVET_L0257_ATMVP_COLBLK_CLIP
+  int xOff = (puWidth >> 1) + tempX;
+  int yOff = (puHeight >> 1) + tempY;
+#else
   int xOff = puWidth / 2;
   int yOff = puHeight / 2;
 
@@ -2386,6 +2420,7 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b
 
   int iPicWidth = pColPic->lwidth() - 1;
   int iPicHeight = pColPic->lheight() - 1;
+#endif
 
   MotionBuf& mb = mrgCtx.subPuMvpMiBuf;
 
@@ -2397,8 +2432,12 @@ bool PU::getInterMergeSubPuMvpCand(const PredictionUnit &pu, MergeCtx& mrgCtx, b
     {
       Position colPos{ x + xOff, y + yOff };
 
+#if JVET_L0257_ATMVP_COLBLK_CLIP
+      clipColPos(colPos.x, colPos.y, pu);
+#else
       colPos.x = Clip3(0, iPicWidth, colPos.x);
       colPos.y = Clip3(0, iPicHeight, colPos.y);
+#endif
 
       colPos = Position{ PosType(colPos.x & mask), PosType(colPos.y & mask) };
 
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index 1c7fcab067343d766f7ecab778b6910f90945fd2..70aae0890cdc0a0bd6a842586cf89ef874d7ad75 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -622,10 +622,17 @@ PartSplit CABACReader::split_cu_mode_mt( CodingStructure& cs, Partitioner &parti
 
   unsigned btSCtxId = width == height ? 0 : ( width > height ? 1 : 2 );
   dt.setCtxId( DTT_SPLIT_DO_SPLIT_DECISION,   Ctx::BTSplitFlag( ctxIdBT ) );      // 0- 2
+#if JVET_L0361_SPLIT_CTX
+  dt.setCtxId( DTT_SPLIT_HV_DECISION,         Ctx::BTSplitFlag( 12 + btSCtxId ) );//12-14
+
+  dt.setCtxId( DTT_SPLIT_H_IS_BT_12_DECISION, Ctx::BTSplitFlag( 15 ) );
+  dt.setCtxId( DTT_SPLIT_V_IS_BT_12_DECISION, Ctx::BTSplitFlag( 15 ) );
+#else
   dt.setCtxId( DTT_SPLIT_HV_DECISION,         Ctx::BTSplitFlag( 3 + btSCtxId ) ); // 3- 5
 
   dt.setCtxId( DTT_SPLIT_H_IS_BT_12_DECISION, Ctx::BTSplitFlag( 6 + btSCtxId ) ); // 6- 8
   dt.setCtxId( DTT_SPLIT_V_IS_BT_12_DECISION, Ctx::BTSplitFlag( 9 + btSCtxId ) ); // 9-11
+#endif
 
   unsigned id = decode_sparse_dt( dt );
 
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index 6052f00ae25639b7b5793cc66e052bf9edf14f13..6eb95048a8d34be9fdb4d2bd1d56368420e34b0e 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -565,10 +565,17 @@ void CABACWriter::split_cu_mode_mt(const PartSplit split, const CodingStructure&
 
   unsigned btSCtxId = width == height ? 0 : ( width > height ? 1 : 2 );
   dt.setCtxId( DTT_SPLIT_DO_SPLIT_DECISION,   Ctx::BTSplitFlag( ctxIdBT ) );
+#if JVET_L0361_SPLIT_CTX
+  dt.setCtxId( DTT_SPLIT_HV_DECISION,         Ctx::BTSplitFlag( 12 + btSCtxId ) );
+
+  dt.setCtxId( DTT_SPLIT_H_IS_BT_12_DECISION, Ctx::BTSplitFlag( 15 ) );
+  dt.setCtxId( DTT_SPLIT_V_IS_BT_12_DECISION, Ctx::BTSplitFlag( 15 ) );
+#else
   dt.setCtxId( DTT_SPLIT_HV_DECISION,         Ctx::BTSplitFlag( 3 + btSCtxId ) );
 
   dt.setCtxId( DTT_SPLIT_H_IS_BT_12_DECISION, Ctx::BTSplitFlag( 6 + btSCtxId ) );
   dt.setCtxId( DTT_SPLIT_V_IS_BT_12_DECISION, Ctx::BTSplitFlag( 9 + btSCtxId ) );
+#endif
 
 
   encode_sparse_dt( dt, split == CU_DONT_SPLIT ? ( unsigned ) DTT_SPLIT_NO_SPLIT : ( unsigned ) split );
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index a261753a769640fa52d07a9cf8aa8268896c78ec..ea5b9913b8c0ef17763ed002151df0548c1aa581 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -1237,7 +1237,11 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps)
     {
       baseQp = getBaseQP()-26;
     }
+#if JVET_L0553_FIX_INITQP
+    const int maxDQP = 37;
+#else
     const int maxDQP = 25;
+#endif
     const int minDQP = -26 + sps.getQpBDOffset(CHANNEL_TYPE_LUMA);
 
     pps.setPicInitQPMinus26( std::min( maxDQP, std::max( minDQP, baseQp ) ));