diff --git a/source/Lib/CommonLib/Contexts_ecm14.0.inl b/source/Lib/CommonLib/Contexts_ecm14.0.inl
index 0c9a685720de8ef4af16c0f829785856103b95ba..2498b51efd573e8a3c68a035e757c5074fa78082 100644
--- a/source/Lib/CommonLib/Contexts_ecm14.0.inl
+++ b/source/Lib/CommonLib/Contexts_ecm14.0.inl
@@ -376,6 +376,32 @@ const CtxSet ContextSetCfg::GeoBlendFlag = ContextSetCfg::addCtxSet
 #endif
 
 #if JVET_AG0135_AFFINE_CIIP
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+const CtxSet ContextSetCfg::CiipAffineFlag = ContextSetCfg::addCtxSet
+({
+// ctx 57 59
+  {  12,   6,  15,  15,  15,  15 },
+  {  19,   5,   6,   6,   6,   6 },
+  {  35,  35,  35,  35,  35,  35 },
+  {  12,  14,  15,  15,  15,  15 },
+  {   5,   1,   1,   1,   1,   1 },
+  {   6,   3,   5,   5,   5,   5 },
+  {   8,   8,   8,   8,   8,   8 },
+  {   5,   1,   1,   1,   1,   1 },
+  {   4,   4,  11,  11,  11,  11 },
+  {   4,   4,  11,  11,  11,  11 },
+  {  18,  18,  18,  18,  18,  18 },
+  {   4,   4,   4,   4,   4,   4 },
+  { 105, 118, 116, 116, 116, 116 },
+  { 211, 118, 116, 116, 116, 116 },
+  { 107, 119, 103, 103, 103, 103 },
+  { 107, 122, 148, 148, 148, 148 },
+  { 119, 119, 119, 119, 119, 119 },
+  { 119, 119, 119, 119, 119, 119 },
+  { 107, 118, 116, 116, 116, 116 },
+  { 116, 119, 118, 118, 118, 118 },
+});
+#else
 const CtxSet ContextSetCfg::CiipAffineFlag = ContextSetCfg::addCtxSet
 ({
 // ctx 57 59
@@ -401,6 +427,7 @@ const CtxSet ContextSetCfg::CiipAffineFlag = ContextSetCfg::addCtxSet
   { 116, 119, 118 },
 });
 #endif
+#endif
 
 const CtxSet ContextSetCfg::MergeIdx = ContextSetCfg::addCtxSet({
 // ctx 60 69
@@ -1556,7 +1583,31 @@ const CtxSet ContextSetCfg::RefPicLC = ContextSetCfg::addCtxSet({
  { 117, 117, 234 },
  { 148, 117, 251 },
 });
-
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+const CtxSet ContextSetCfg::SubblockMergeFlag = ContextSetCfg::addCtxSet({
+// ctx 202 204
+ {  25,  34,  21,  21,  21,  21 },
+ {  40,  34,  36,  36,  36,  36 },
+ {  35,  35,  35,  35,  35,  35 },
+ {  25,  20,  37,  37,  37,  37 },
+ {   6,   5,   4,   4,   4,   4 },
+ {   6,   5,   5,   5,   5,   5 },
+ {   8,   8,   8,   8,   8,   8 },
+ {   6,   5,   5,   5,   5,   5 },
+ {   4,   4,  18,  18,  18,  18 },
+ {  11,   4,  18,  18,  18,  18 },
+ {  18,  18,  18,  18,  18,  18 },
+ {   4,   4,  18,  18,  18,  18 },
+ { 131, 116, 117, 117, 117, 117 },
+ { 131, 132, 118, 118, 118, 118 },
+ { 117, 117, 119, 119, 119, 119 },
+ { 117, 132, 117, 117, 117, 117 },
+ { 119, 119, 119, 119, 119, 119 },
+ { 119, 119, 119, 119, 119, 119 },
+ { 131, 117, 118, 118, 118, 118 },
+ { 131, 117, 118, 118, 118, 118 },
+});
+#else
 const CtxSet ContextSetCfg::SubblockMergeFlag = ContextSetCfg::addCtxSet({
 // ctx 202 204
  {  25,  34,  21 },
@@ -1580,6 +1631,7 @@ const CtxSet ContextSetCfg::SubblockMergeFlag = ContextSetCfg::addCtxSet({
  { 131, 117, 118 },
  { 131, 117, 118 },
 });
+#endif
 
 const CtxSet ContextSetCfg::BMMergeFlag = ContextSetCfg::addCtxSet({
 // ctx 205 208
diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp
index faff01c4cc0ceafd7057e3cb3374f714f55c5311..4d91910052ed3696f5e7125dc03d84f9aa476205 100644
--- a/source/Lib/CommonLib/InterPrediction.cpp
+++ b/source/Lib/CommonLib/InterPrediction.cpp
@@ -4978,8 +4978,10 @@ void InterPrediction::xPredAffineBlk(const ComponentID &compID, const Prediction
   int blockWidth = AFFINE_MIN_BLOCK_SIZE;
   int blockHeight = AFFINE_MIN_BLOCK_SIZE;
 
+#if !JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
   CHECK(blockWidth  > (width >> iScaleX ), "Sub Block width  > Block width");
   CHECK(blockHeight > (height >> iScaleY), "Sub Block height > Block height");
+#endif
 #if !AFFINE_RM_CONSTRAINTS_AND_OPT
   const int MVBUFFER_SIZE = MAX_CU_SIZE / MIN_PU_SIZE;
 #endif
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index c80541219d4fe44b7991e67242a347761c3a36af..3d4fabef4e11ceafea4ed3a66644e1428af45ae4 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -374,6 +374,7 @@
 #define JVET_AI0094_SHARP_MC_FILTER_FOR_BIPRED            1 // JVET-AI0094: Sharp motion compensation filter for bi-prediction
 #define JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE           1 // JVET-AI0185 adaptive cost function selection in merge mode
 #define JVET_AI0183_MVP_EXTENSION                         1 // JVET-AI0183 MVP extension
+#define JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION         1 // JVET-AJ0085 subblock merge mode extension
 #define JVET_AJ0097_BDOF_LDB                              1 // JVET-AJ0097 BDOF for low-delay pictures
 #define JVET_AJ0126_INTER_AMVP_ENHANCEMENT                1 // JVET-AJ0126: Enhanced inter AMVP (inter TM part is controlled by EnableTMTools)
 #define JVET_AJ0107_GPM_SHAPE_ADAPT                       1 // JVET-AJ0107: Test 3.4d, GPM with shape adaptation only applied to regular GPM.
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index e5fa9eefa83e54ea76295529c79c4b688deedc9b..64f18539c302bcb4d5201a5cebf66123562e2113 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -35620,4 +35620,81 @@ void getTemporalBv(const PredictionUnit &pu, std::vector<MotionInfo>& temporalMi
   addOneTypeTempCandidates(pu, temporalMiCandList, temporalPos);
 }
 #endif
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+bool CU::hasAffineNb(const CodingUnit& cu)
+{
+  int affineNb = 0;
+  Position pos[7] = {
+    cu.lumaPos().offset(-1, 0),
+    cu.lumaPos().offset(0, -1),
+    cu.lumaPos().offset(-1, -1),
+    cu.lumaPos().offset(cu.lwidth() - 1, -1),
+    cu.lumaPos().offset(cu.lwidth(), -1),
+    cu.lumaPos().offset(-1, cu.lheight() - 1),
+    cu.lumaPos().offset(-1, cu.lheight())
+  };
+  for (int i = 0; i < 7; i++)
+  {
+    const CodingUnit* cuNb = cu.cs->getCURestricted(pos[i], cu, CH_L);
+    affineNb += (cuNb && (cuNb->affine || (cuNb->geoFlag && (cuNb->firstPU->affineGPM[0] || cuNb->firstPU->affineGPM[1]) && !cu.slice->getCheckLDB()))) ? 1 : 0;
+    if (affineNb)
+    {
+      return true;
+    }
+  }
 
+  int offsetX = 0;
+  int offsetY = 0;
+  int offsetX0 = 0; int offsetX1 = 0; int offsetX2 = cu.lwidth() >> 1;
+  int offsetY0 = 0; int offsetY1 = 0; int offsetY2 = cu.lheight() >> 1;
+
+  const int numNACandidate = 5;
+  const int idxMap[5] = { 0, 1, 2, 3, 4 };
+  int iDistanceIndex = 0;
+  const int iNADistanceHor = cu.lwidth() * (iDistanceIndex + 1);
+  const int iNADistanceVer = cu.lheight() * (iDistanceIndex + 1);
+
+  for (int iNASPIdx = 0; iNASPIdx < numNACandidate; iNASPIdx++)
+  {
+    switch (idxMap[iNASPIdx])
+    {
+    case 0:offsetX = offsetX0 = -iNADistanceHor - 1;               offsetY = offsetY0 = cu.lheight() + iNADistanceVer - 1; break;
+    case 1:offsetX = offsetX1 = cu.lwidth() + iNADistanceHor - 1; offsetY = offsetY1 = -iNADistanceVer - 1;                break;
+    case 2:offsetX = offsetX2;                                     offsetY = offsetY1;                                      break;
+    case 3:offsetX = offsetX0;                                     offsetY = offsetY2;                                      break;
+    case 4:offsetX = offsetX0;                                     offsetY = offsetY1;                                      break;
+    case 5:offsetX = -1;                                           offsetY = offsetY0;                                      break;
+    case 6:offsetX = offsetX1;                                     offsetY = -1;                                            break;
+    case 7:offsetX = offsetX0 >> 1;                                offsetY = offsetY0;                                      break;
+    case 8:offsetX = offsetX1;                                     offsetY = offsetY1 >> 1;                                 break;
+    default: printf("error!"); exit(0); break;
+    }
+    const CodingUnit* cuNb = cu.cs->getCURestricted(cu.lumaPos().offset(offsetX, offsetY), cu, CH_L);
+    affineNb += (cuNb && (cuNb->affine || (cuNb->geoFlag && (cuNb->firstPU->affineGPM[0] || cuNb->firstPU->affineGPM[1]) && !cu.slice->getCheckLDB()))) ? 1 : 0;
+    if (affineNb)
+    {
+      return true;
+    }
+  }
+
+  return false;
+}
+bool CU::isAffineAllowed(const CodingUnit& cu)
+{
+  if ((cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 && (cu.lumaSize().width * cu.lumaSize().height >= 128)) || 
+    (cu.lumaSize().width * cu.lumaSize().height >= 32 && CU::hasAffineNb(cu)))
+  {
+    return true;
+  }
+  return false;
+}
+
+bool CU::affineCtxInc(const CodingUnit& cu)
+{
+  if (!(cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 && (cu.lumaSize().width * cu.lumaSize().height >= 128)) && !cu.slice->getCheckLDB())
+  {
+    return true;
+  }
+  return false;
+}
+#endif
diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h
index 8fd5f59dc11e4fe92a2bc86066fb99d014eaf255..afbbdd79112e693e3e175cd138f23893dd59b8d1 100644
--- a/source/Lib/CommonLib/UnitTools.h
+++ b/source/Lib/CommonLib/UnitTools.h
@@ -64,6 +64,12 @@ namespace CS
 // CU tools
 namespace CU
 {
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+  bool hasAffineNb(const CodingUnit& cu);
+  bool isAffineAllowed(const CodingUnit& cu);
+  bool affineCtxInc(const CodingUnit& cu);
+#endif
+
 #if JVET_AG0276_NLIC
   bool isSecLicParaNeeded             (const CodingUnit &cu);
   bool isPredRefined                  (const CodingUnit &cu);
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index 077b3d7584568fa7bdb1936185adac8dcf2c1a3d..03972d32e8be1ce7f60ebc60be3597ee339528ac 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -4834,11 +4834,24 @@ void CABACReader::subblock_merge_flag( CodingUnit& cu )
 {
   cu.affine = false;
 
-  if ( !cu.cs->slice->isIntra() && (cu.slice->getPicHeader()->getMaxNumAffineMergeCand() > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
+  if ( !cu.cs->slice->isIntra() && (cu.slice->getPicHeader()->getMaxNumAffineMergeCand() > 0) && 
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+    CU::isAffineAllowed(cu)
+#else
+    cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 
+#endif
+    )
   {
     RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET_SIZE( STATS__CABAC_BITS__AFFINE_FLAG, cu.lumaSize());
 
     unsigned ctxId = DeriveCtx::CtxAffineFlag( cu );
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+    if(CU::affineCtxInc(cu))
+    {
+      ctxId += 3;
+    }
+#endif
+
     cu.affine = m_BinDecoder.decodeBin( Ctx::SubblockMergeFlag( ctxId ) );
     DTRACE( g_trace_ctx, D_SYNTAX, "subblock_merge_flag() subblock_merge_flag=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
   }
@@ -7357,9 +7370,21 @@ void CABACReader::mvp_flag( PredictionUnit& pu, RefPicList eRefList )
 #if JVET_AG0135_AFFINE_CIIP
 void CABACReader::ciipAffineFlag(PredictionUnit& pu)
 {
-  if (!pu.cu->slice->isIntra() && pu.cs->sps->getUseCiipAffine() && (pu.cu->slice->getPicHeader()->getMaxNumAffineMergeCand() > 0) && pu.cu->lumaSize().width >= 8 && pu.cu->lumaSize().height >= 8)
+  if (!pu.cu->slice->isIntra() && pu.cs->sps->getUseCiipAffine() && (pu.cu->slice->getPicHeader()->getMaxNumAffineMergeCand() > 0) && 
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+    CU::isAffineAllowed(*pu.cu)
+#else
+    pu.cu->lumaSize().width >= 8 && pu.cu->lumaSize().height >= 8
+#endif
+    )
   {
     unsigned ctxId = DeriveCtx::CtxCiipAffineFlag(*pu.cu);
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+    if (CU::affineCtxInc(*pu.cu))
+    {
+      ctxId += 3;
+    }
+#endif
     pu.ciipAffine = m_BinDecoder.decodeBin(Ctx::CiipAffineFlag(ctxId));
   }
   else
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index 33c963de683c79f63e70ca33385087b8b1772dfe..137ebf1a86657512d0d78f647119c0fd343b4672 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -4430,9 +4430,21 @@ void CABACWriter::amvpSbTmvpMvdCoding(const PredictionUnit &pu)
 void CABACWriter::subblock_merge_flag( const CodingUnit& cu )
 {
 
-  if ( !cu.cs->slice->isIntra() && (cu.slice->getPicHeader()->getMaxNumAffineMergeCand() > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
+  if ( !cu.cs->slice->isIntra() && (cu.slice->getPicHeader()->getMaxNumAffineMergeCand() > 0) && 
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+    CU::isAffineAllowed(cu)
+#else
+    cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 
+#endif
+    )
   {
     unsigned ctxId = DeriveCtx::CtxAffineFlag( cu );
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+    if (CU::affineCtxInc(cu))
+    {
+      ctxId += 3;
+    }
+#endif
     m_BinEncoder.encodeBin( cu.affine, Ctx::SubblockMergeFlag( ctxId ) );
     DTRACE( g_trace_ctx, D_SYNTAX, "subblock_merge_flag() subblock_merge_flag=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
   }
@@ -7364,9 +7376,21 @@ void CABACWriter::mvp_flag( const PredictionUnit& pu, RefPicList eRefList )
 #if JVET_AG0135_AFFINE_CIIP
 void CABACWriter::ciipAffineFlag(const PredictionUnit& pu)
 {
-  if (!pu.cu->slice->isIntra() && pu.cs->sps->getUseCiipAffine() && (pu.cu->slice->getPicHeader()->getMaxNumAffineMergeCand() > 0) && pu.cu->lumaSize().width >= 8 && pu.cu->lumaSize().height >= 8)
+  if (!pu.cu->slice->isIntra() && pu.cs->sps->getUseCiipAffine() && (pu.cu->slice->getPicHeader()->getMaxNumAffineMergeCand() > 0) && 
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+    CU::isAffineAllowed(*pu.cu)
+#else
+    pu.cu->lumaSize().width >= 8 && pu.cu->lumaSize().height >= 8
+#endif
+    )
   {
     unsigned ctxId = DeriveCtx::CtxCiipAffineFlag(*pu.cu);
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+    if (CU::affineCtxInc(*pu.cu))
+    {
+      ctxId += 3;
+    }
+#endif
     m_BinEncoder.encodeBin(pu.ciipAffine, Ctx::CiipAffineFlag(ctxId));
   }
 }
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index 10376a65b18d53492f651f3674717cf7a02c22c8..6e855806252e62bc396e503bc6ff6dc35b70725e 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -5176,10 +5176,20 @@ void EncCu::xCheckRDCostMerge2Nx2N( CodingStructure *&tempCS, CodingStructure *&
   uint32_t               affMmvdLUT[AF_MMVD_NUM];
 #endif
   const SPS &sps = *tempCS->sps;
-
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+  CodingUnit tempCu(tempCS->area);
+  tempCu.cs = tempCS;
+  tempCu.slice = tempCS->slice;
+  tempCu.tileIdx = tempCS->pps->getTileIdx(tempCS->area.lumaPos());
+  bool affineMrgAvailSize = CU::isAffineAllowed(tempCu);
+#endif
 #if MERGE_ENC_OPT
   const bool affineMrgAvail = (sps.getUseAffine() || sps.getSbTMVPEnabledFlag()) && slice.getPicHeader()->getMaxNumAffineMergeCand()
+#if JVET_AJ0085_SUBBLOCK_MERGE_MODE_EXTENSION
+    && affineMrgAvailSize;
+#else
     && !(bestCS->area.lumaSize().width < 8 || bestCS->area.lumaSize().height < 8);
+#endif
 
   AffineMergeCtx affineMergeCtx;
 #if JVET_AD0182_AFFINE_DMVR_PLUS_EXTENSIONS