diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index a2881df31554040e244d372d2ca78c24a3912e29..434aaf98dacaefe5e82267bcd65bf04ff6dbc42b 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -833,6 +833,9 @@ void EncApp::xInitLibCfg()
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
   m_cEncLib.setUseAltCost                                        ( m_useAltCost );
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  m_cEncLib.setUseExtAmvp                                        ( m_useExtAmvp );
+#endif
 #if JVET_AF0163_TM_SUBBLOCK_REFINEMENT
   m_cEncLib.setUseAffineTM                                       ( m_useAffineTM );
 #if JVET_AG0276_NLIC
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 737460da0d59fcf4437eb1a11f688ece2af21650..8212b8ff8b9d5f1dee7205ce54f51b1147f085c9 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1054,6 +1054,9 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
   ("AltCost",                                         m_useAltCost,                                      true, "Enable alternating cost function based on parity of merge index (0:off, 1:on)  [default: on]")
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  ("ExtAmvp",                                         m_useExtAmvp,                                      true, "Enable extended amvp candidates (0:off, 1:on)  [default: on]")
+#endif
 #if JVET_AF0163_TM_SUBBLOCK_REFINEMENT
   ("AffineTM",                                        m_useAffineTM,                                     true, "Enable TM-based subblock motion refinement (0:off, 1:on)  [default: on]")
 #if JVET_AG0276_NLIC
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 9a478c16a0901ac17536b60ee3dbf14f38c0769d..52930f736f79442d757adaf70364ffd6c9d2387a 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -418,6 +418,9 @@ protected:
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
   bool      m_useAltCost;
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  bool      m_useExtAmvp;
+#endif
 #if JVET_AF0163_TM_SUBBLOCK_REFINEMENT
   bool      m_useAffineTM;
 #if JVET_AG0276_NLIC
diff --git a/source/Lib/CommonLib/CommonDef.h b/source/Lib/CommonLib/CommonDef.h
index a5a6c32fc81feba3cbfcafb07e19305a1a398b66..b15f94a5f9ceeb26a17a56e6d443dd832de11dfe 100644
--- a/source/Lib/CommonLib/CommonDef.h
+++ b/source/Lib/CommonLib/CommonDef.h
@@ -181,11 +181,20 @@ static const int MAX_NUM_REF =                                     16; ///< max.
 static const int MAX_QP =                                          63;
 static const int NOT_VALID =                                       -1;
 
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+static const int AFFINE_AMVP_MAX_CAND =                             10;
+#if TM_AMVP || (JVET_Z0084_IBC_TM && IBC_TM_AMVP) || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
+static const int REGULAR_AMVP_MAX_NUM_CANDS =                       10; ///< AMVP: advanced motion vector prediction - max number of final candidate for regular inter mode
+#endif
+static const int REGULAR_AMVP_MAX_NUM_CANDS_IBC =                   5;
+#else
 #if TM_AMVP || (JVET_Z0084_IBC_TM && IBC_TM_AMVP) || JVET_AC0060_IBC_BVP_CLUSTER_RRIBC_BVD_SIGN_DERIV
 static const int REGULAR_AMVP_MAX_NUM_CANDS =                       5; ///< AMVP: advanced motion vector prediction - max number of final candidate for regular inter mode
 #endif
+#endif
 static const int AMVP_MAX_NUM_CANDS =                               2; ///< AMVP: advanced motion vector prediction - max number of final candidates
 static const int AMVP_MAX_NUM_CANDS_MEM =                           3; ///< AMVP: advanced motion vector prediction - max number of candidates
+
 #if INTER_RM_SIZE_CONSTRAINTS
 static const int AMVP_DECIMATION_FACTOR =                           1;
 #else
diff --git a/source/Lib/CommonLib/InterPrediction.cpp b/source/Lib/CommonLib/InterPrediction.cpp
index 506d65d77a62200abfba861f33c57e2a063ef84c..fe26e1d3eb948857470b96418f52ff8e755f0965 100644
--- a/source/Lib/CommonLib/InterPrediction.cpp
+++ b/source/Lib/CommonLib/InterPrediction.cpp
@@ -20292,6 +20292,193 @@ void  InterPrediction::adjustIBCMergeCandidates(PredictionUnit &pu, MergeCtx& mr
   updateIBCCandInfo(pu, mrgCtx, rdCandList, startPos, endPos);
 }
 #endif
+
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+void InterPrediction::tmRefineAffineAMVPCandidates(PredictionUnit &pu, const RefPicList &eRefPicList, const int &refIdx, AffineAMVPInfo &affiAMVPInfo, int extCond)
+{
+  if ((extCond >> 4 & 0x0f) == 0)
+  {
+    return;
+  }
+
+  if (!(pu.cs->sps->getUseAffineTM() && pu.cs->sps->getTMToolsEnableFlag()))
+  {
+    return;
+  }
+
+  int licStored = pu.cu->licFlag;
+  int refIdxL0Stored = pu.refIdx[0];
+  int refIdxL1Stored = pu.refIdx[1];
+  int affineTypeStored = pu.cu->affineType;
+
+  PredictionUnit pu2 = pu;
+  pu2.cu->licFlag = false;
+  pu2.refIdx[eRefPicList] = refIdx;
+  pu2.refIdx[1-eRefPicList] = -1;
+  pu2.mergeFlag = true;
+
+  for (int candIdx = 0; candIdx < affiAMVPInfo.numCand; ++candIdx) 
+  {
+    pu2.cu->affineType = affineTypeStored;
+
+    if (!(pu.cu->slice->getCheckLDB() && !pu.cu->slice->getExtAmvpLevel()))
+    {
+      if(candIdx % 2)
+      {
+        continue;
+      }
+    }
+
+    pu2.mvAffi[eRefPicList][0] = affiAMVPInfo.mvCandLT[candIdx];
+    pu2.mvAffi[eRefPicList][1] = affiAMVPInfo.mvCandRT[candIdx];
+    pu2.mvAffi[eRefPicList][2] = affiAMVPInfo.mvCandLB[candIdx];
+
+    if(pu2.cu->affineType == AFFINEMODEL_6PARAM && pu2.mvAffi[eRefPicList][0] == Mv(0,0) && pu2.mvAffi[eRefPicList][1] == Mv(0,0) && pu2.mvAffi[eRefPicList][2] == Mv(0,0))
+    {
+      break;
+    }
+    else if (pu2.cu->affineType == AFFINEMODEL_4PARAM && pu2.mvAffi[eRefPicList][0] == Mv(0,0) && pu2.mvAffi[eRefPicList][1] == Mv(0,0))
+    {
+      break;
+    }
+  
+    Mv  m_mvBufBDMVRAffine[2][MAX_NUM_SUBCU_DMVR];
+    for (int i = 0; i < 3; i++)
+    {
+      m_mvBufBDMVRAffine[0][i].setZero();
+      m_mvBufBDMVRAffine[1][i].setZero();
+    }
+    setBdmvrSubPuMvBuf(m_mvBufBDMVRAffine[0], m_mvBufBDMVRAffine[1]);
+    pu2.bdmvrRefine = false;
+
+    AffineMergeCtx AffineMergeCtxTmp = AffineMergeCtx();
+
+    processTM4Affine(pu2, AffineMergeCtxTmp, -1, false
+#if JVET_AH0119_SUBBLOCK_TM      
+      , false
+#endif
+      , true
+      );//uni
+
+
+    affiAMVPInfo.mvCandLT[candIdx] += m_mvBufBDMVRAffine[eRefPicList][0];
+    affiAMVPInfo.mvCandRT[candIdx] += m_mvBufBDMVRAffine[eRefPicList][1];
+    if(affineTypeStored == AFFINEMODEL_6PARAM)
+    {
+      affiAMVPInfo.mvCandLB[candIdx] += m_mvBufBDMVRAffine[eRefPicList][2];
+    }
+    else
+    {
+      affiAMVPInfo.mvCandLB[candIdx] = Mv(0,0); 
+    }
+
+    affiAMVPInfo.mvCandLT[candIdx].roundAffinePrecInternal2Amvr(pu.cu->imv);
+    affiAMVPInfo.mvCandRT[candIdx].roundAffinePrecInternal2Amvr(pu.cu->imv);
+    affiAMVPInfo.mvCandLB[candIdx].roundAffinePrecInternal2Amvr(pu.cu->imv);
+  }
+  pu.cu->licFlag = licStored;
+  pu.refIdx[0] = refIdxL0Stored;
+  pu.refIdx[1] = refIdxL1Stored;
+  pu.cu->affineType = affineTypeStored;
+}
+
+void InterPrediction::adjustAffineAMVPCandidates(PredictionUnit &pu, const RefPicList &eRefPicList, const int &refIdx, AffineAMVPInfo &affiAMVPInfo, int extCond)
+{
+  if((extCond >> 8 & 0x0f) == 0)
+  {
+    affiAMVPInfo.numCand = (affiAMVPInfo.numCand > AMVP_MAX_NUM_CANDS) ? AMVP_MAX_NUM_CANDS : affiAMVPInfo.numCand;
+    return;
+  }
+
+  DistParam cDistParam;
+  cDistParam.applyWeight = false;
+
+  int nWidth = pu.lumaSize().width;
+  int nHeight = pu.lumaSize().height;
+
+  if (!xAMLGetCurBlkTemplate(pu, nWidth, nHeight))
+  {
+    affiAMVPInfo.numCand = (affiAMVPInfo.numCand > AMVP_MAX_NUM_CANDS) ? AMVP_MAX_NUM_CANDS : affiAMVPInfo.numCand;
+    return;
+  }
+
+  int licStored = pu.cu->licFlag;
+  int refIdxL0Stored = pu.refIdx[0];
+  int refIdxL1Stored = pu.refIdx[1];
+
+  PredictionUnit pu2 = pu;
+  pu2.cu->licFlag = false;
+  pu2.refIdx[eRefPicList] = refIdx;
+  pu2.refIdx[1-eRefPicList] = -1;
+
+  struct affineamvpSort
+  {
+    Mv       mvCandLT;
+    Mv       mvCandRT;
+    Mv       mvCandLB;
+    Distortion cost;
+  };
+  affineamvpSort temp;
+  std::vector<affineamvpSort> input;
+  const auto costIncSort = [](const affineamvpSort &x, const affineamvpSort &y) { return x.cost < y.cost; };
+  Distortion tmCost[AFFINE_AMVP_MAX_CAND];
+  for (int i = 0; i < AFFINE_AMVP_MAX_CAND; i++)
+  {
+    tmCost[i] = std::numeric_limits<Distortion>::max();
+  }
+  for (int candIdx = 0; candIdx < affiAMVPInfo.numCand; ++candIdx) 
+  {
+    pu2.mvAffi[eRefPicList][0] = affiAMVPInfo.mvCandLT[candIdx];
+    pu2.mvAffi[eRefPicList][1] = affiAMVPInfo.mvCandRT[candIdx];
+    pu2.mvAffi[eRefPicList][2] = affiAMVPInfo.mvCandLB[candIdx];
+   
+    PelUnitBuf pcBufPredRefTop = (PelUnitBuf(pu2.chromaFormat, PelBuf(m_acYuvRefAMLTemplate[0][0], nWidth, AML_MERGE_TEMPLATE_SIZE)));
+    PelUnitBuf pcBufPredCurTop = (PelUnitBuf(pu2.chromaFormat, PelBuf(m_acYuvCurAMLTemplate[0][0], nWidth, AML_MERGE_TEMPLATE_SIZE)));
+    PelUnitBuf pcBufPredRefLeft = (PelUnitBuf(pu2.chromaFormat, PelBuf(m_acYuvRefAMLTemplate[1][0], AML_MERGE_TEMPLATE_SIZE, nHeight)));
+    PelUnitBuf pcBufPredCurLeft = (PelUnitBuf(pu2.chromaFormat, PelBuf(m_acYuvCurAMLTemplate[1][0], nHeight, AML_MERGE_TEMPLATE_SIZE)));
+    getAffAMLRefTemplate(pu2, pcBufPredRefTop, pcBufPredRefLeft,true, AffineMergeCtx());
+
+    if (m_bAMLTemplateAvailabe[0])
+    {
+      m_pcRdCost->setDistParam(cDistParam, pcBufPredCurTop.Y(), pcBufPredRefTop.Y(), pu2.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, false);
+
+      tmCost[candIdx] = cDistParam.distFunc(cDistParam);
+    }
+
+    if (m_bAMLTemplateAvailabe[1])
+    {
+      m_pcRdCost->setDistParam(cDistParam, pcBufPredCurLeft.Y(), pcBufPredRefLeft.Y(), pu2.cs->sps->getBitDepth(CHANNEL_TYPE_LUMA), COMPONENT_Y, false);
+
+      if(m_bAMLTemplateAvailabe[0])
+      {
+        tmCost[candIdx] += cDistParam.distFunc(cDistParam);
+      }
+      else
+      {
+        tmCost[candIdx] = cDistParam.distFunc(cDistParam);
+      }
+    }
+    temp.mvCandLT = affiAMVPInfo.mvCandLT[candIdx];
+    temp.mvCandRT = affiAMVPInfo.mvCandRT[candIdx];
+    temp.mvCandLB = affiAMVPInfo.mvCandLB[candIdx];
+    temp.cost = tmCost[candIdx];
+    input.push_back(temp);
+  }
+  stable_sort(input.begin(), input.end(), costIncSort);
+  for (int candIdx = 0; candIdx < affiAMVPInfo.numCand; ++candIdx)
+  {
+    affiAMVPInfo.mvCandLT[candIdx] = input.at(candIdx).mvCandLT;
+    affiAMVPInfo.mvCandRT[candIdx] = input.at(candIdx).mvCandRT;
+    affiAMVPInfo.mvCandLB[candIdx] = input.at(candIdx).mvCandLB;
+    tmCost[candIdx] = input.at(candIdx).cost;
+  }
+  pu.cu->licFlag = licStored;
+  pu.refIdx[0] = refIdxL0Stored;
+  pu.refIdx[1] = refIdxL1Stored;
+  affiAMVPInfo.numCand = (affiAMVPInfo.numCand > AMVP_MAX_NUM_CANDS) ? AMVP_MAX_NUM_CANDS : affiAMVPInfo.numCand;
+}
+#endif
+
 #if JVET_AA0107_RMVF_AFFINE_MERGE_DERIVATION
 void  InterPrediction::adjustAffineMergeCandidatesOneGroup(PredictionUnit &pu, AffineMergeCtx& affMrgCtx, int listsize
 #if JVET_AD0182_AFFINE_DMVR_PLUS_EXTENSIONS
@@ -24093,6 +24280,7 @@ Distortion InterPrediction::deriveTMMv(const PredictionUnit& pu, bool fillCurTpl
     {
 #endif
     tplCtrl.deriveMvUni<TM_TPL_SIZE>();
+
 #if TM_MRG && JVET_AA0093_REFINED_MOTION_FOR_ARMC
     }
 #endif
@@ -25883,6 +26071,40 @@ bool InterPrediction::readTplAmvpBuffer(AMVPInfo& dst, const CodingUnit& cu, Ref
 }
 #endif
 
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+void InterPrediction::clearAffineAmvpBuffer()
+{
+  for (int affinetype = 0; affinetype < AFFINE_MODEL_NUM; ++affinetype)
+  {
+    for (int imv = 0; imv < NUM_IMV_MODES; ++imv)
+    {
+      for (int refIdx = 0; refIdx < MAX_NUM_REF; ++refIdx)
+      {
+        m_affineAmvpInfo   [affinetype][imv][0][refIdx] = AffineAMVPInfo();
+        m_affineAmvpInfo   [affinetype][imv][1][refIdx] = AffineAMVPInfo();
+      }
+    }
+  }
+}
+
+void InterPrediction::writeAffineAmvpBuffer(const AffineAMVPInfo& src, const CodingUnit& cu, RefPicList eRefList, int refIdx)
+{
+  AffineAMVPInfo& dst = m_affineAmvpInfo[cu.affineType][cu.imv][eRefList][refIdx];
+  dst = src;
+}
+
+bool InterPrediction::readAffineAmvpBuffer(AffineAMVPInfo& dst, const CodingUnit& cu, RefPicList eRefList, int refIdx)
+{
+  AffineAMVPInfo& src = m_affineAmvpInfo[cu.affineType][cu.imv][eRefList][refIdx];
+  if (src.numCand > 0)
+  {
+    dst = src;
+    return true;
+  }
+  return false;
+}
+#endif
+
 #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION 
 void InterPrediction::writeMergeBuffer(const MergeCtx& srcList0, const MergeCtx& srcList1, const CodingUnit& cu)
 {
@@ -27816,6 +28038,9 @@ bool InterPrediction::processTM4Affine(PredictionUnit& pu, AffineMergeCtx &affin
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
   , int mergeIdx
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    , bool isInt4PosRefine
+#endif
 )
 {
   if (!pu.cs->slice->getSPS()->getTMToolsEnableFlag())
@@ -27915,13 +28140,15 @@ bool InterPrediction::processTM4Affine(PredictionUnit& pu, AffineMergeCtx &affin
       continue;
     }
     
-
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    processTM4AffineBaseMV(pu, affineMergeCtx, uiAffMergeCand, cpBestMVF, uiCostOri, uiCostBest, targetList, mergeIdx, isInt4PosRefine);
+#else
     processTM4AffineBaseMV(pu, affineMergeCtx, uiAffMergeCand, cpBestMVF, uiCostOri, uiCostBest, targetList, mergeIdx);
+#endif
 #else
     processTM4AffineBaseMV(pu, affineMergeCtx, uiAffMergeCand, cpBestMVF, uiCostOri, uiCostBest, targetList);
 #endif
-
     if (pu.refIdx[0] < 0 || pu.refIdx[1] < 0)
     {
       if (isTmPara)
@@ -28189,6 +28416,9 @@ bool InterPrediction::processTM4AffineBaseMV(PredictionUnit& pu, AffineMergeCtx
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
 , int mergeIdx
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+, bool isInt4PosRefine
+#endif
 )
 {
   Distortion uiCost = 0;;
@@ -28201,13 +28431,30 @@ bool InterPrediction::processTM4AffineBaseMV(PredictionUnit& pu, AffineMergeCtx
   Mv cpBestMVI[2][3] = { { bestCPMV[0][0] , bestCPMV[0][1] ,bestCPMV[0][2] },{ bestCPMV[1][0] , bestCPMV[1][1] , bestCPMV[1][2] } };
   Mv cpBestMVF[2][3] = { { bestCPMV[0][0] , bestCPMV[0][1] ,bestCPMV[0][2] },{ bestCPMV[1][0] , bestCPMV[1][1] , bestCPMV[1][2] } };
 
-
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  Mv   cSearchOffset[8] = { Mv(-1 , 1) , Mv(0 , 1) , Mv(1 ,  1) , Mv(1 ,  0) , Mv(1 , -1) , Mv(0 , -1) , Mv(-1 , -1) , Mv(-1 , 0) };
+  int  nDirectStart = 0;
+  int  nDirectEnd = 7;
+  int  nDirectRounding = 8;
+  int  nDirectMask = 0x07;
+  if(isInt4PosRefine)
+  {
+    cSearchOffset[0] = Mv(0 , 1);
+    cSearchOffset[1] = Mv(1 , 0);
+    cSearchOffset[2] = Mv(0 , -1);
+    cSearchOffset[3] = Mv(-1 , 0);
+    nDirectEnd = 3;
+    nDirectRounding = 4;
+    nDirectMask = 0x03;
+  }
+#else
   static const Mv   cSearchOffset[8] = { Mv(-1 , 1) , Mv(0 , 1) , Mv(1 ,  1) , Mv(1 ,  0) , Mv(1 , -1) , Mv(0 , -1) , Mv(-1 , -1) , Mv(-1 , 0) };
 
   int  nDirectStart = 0;
   int  nDirectEnd = 7;
   const int  nDirectRounding = 8;
   const int  nDirectMask = 0x07;
+#endif
   for (int i = 0; i < 2; i++)
   {
     for (int j = 0; j < 3; j++)
@@ -28342,6 +28589,9 @@ bool InterPrediction::processTM4AffineBaseMV(PredictionUnit& pu, AffineMergeCtx
     nDirectStart = nBestDirect - nStep;
     nDirectEnd = nBestDirect + nStep;
   }
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  if(!isInt4PosRefine)
+#endif
   for (int searchIndex = 0; searchIndex < 8; searchIndex++) // fractional search
   {
     uiCost = 0;
@@ -32092,7 +32342,6 @@ void InterPrediction::amvpMergeModeMvRefinement(PredictionUnit& pu, MvField* mvF
 }
 #endif
 
-
 #if JVET_Z0054_BLK_REF_PIC_REORDER
 #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED
 #if JVET_AD0140_MVD_PREDICTION
@@ -32666,8 +32915,11 @@ void InterPrediction::reorderRefCombList(PredictionUnit &pu, std::vector<RefList
 
 
       AffineAMVPInfo affineAMVPInfo;
-      PU::fillAffineMvpCand(tmpPU, eRefList, tmpPU.refIdx[eRefList], affineAMVPInfo);
-
+      PU::fillAffineMvpCand(tmpPU, eRefList, tmpPU.refIdx[eRefList], affineAMVPInfo
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    , this
+#endif
+      );
       const unsigned mvpIdx = tmpPU.mvpIdx[eRefList];
 
 #if JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED
@@ -33462,8 +33714,11 @@ void InterPrediction::reorderRefPairList(PredictionUnit &pu, std::vector<RefPicP
 
 
         RefPicList eRefList = (RefPicList)refList;
-        PU::fillAffineMvpCand(tmpPU, eRefList, tmpPU.refIdx[eRefList], affineAMVPInfo[eRefList][refIdx]);
-
+        PU::fillAffineMvpCand(tmpPU, eRefList, tmpPU.refIdx[eRefList], affineAMVPInfo[eRefList][refIdx]
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+        , this
+#endif
+        );
         if (refIdx < 0)
         {
           continue;
@@ -33531,11 +33786,13 @@ void InterPrediction::reorderRefPairList(PredictionUnit &pu, std::vector<RefPicP
       for (int refList = 0; refList < 2; refList++)
       {
         RefPicList eRefList = (RefPicList)refList;
-        PU::fillAffineMvpCand(tmpPU, eRefList, tmpPU.refIdx[eRefList], affineAMVPInfo[eRefList]);
-
-#if !JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED
+        PU::fillAffineMvpCand(tmpPU, eRefList, tmpPU.refIdx[eRefList], affineAMVPInfo[eRefList]
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+        , this
+#endif
+        );
         const unsigned mvpIdx = tmpPU.mvpIdx[eRefList];
-
+#if !JVET_Y0067_ENHANCED_MMVD_MVD_SIGN_PRED
         Mv mvLT = affineAMVPInfo[eRefList].mvCandLT[mvpIdx] + tmpPU.mvdAffi[eRefList][0];
         Mv mvRT = affineAMVPInfo[eRefList].mvCandRT[mvpIdx] + tmpPU.mvdAffi[eRefList][1];
         mvRT += tmpPU.mvdAffi[eRefList][0];
@@ -36167,7 +36424,6 @@ void InterPrediction::defineSignHypMatchAffine(PredictionUnit& pu, const RefPicL
 #endif
     );
 
-
     DistParam cDistParam;
     cDistParam.applyWeight = false;
     Distortion uiCost;
diff --git a/source/Lib/CommonLib/InterPrediction.h b/source/Lib/CommonLib/InterPrediction.h
index fd9e5139eb8bd2e96b68b6b5e775b4ab4c2edbca..b3863edc4e026a5813f87b9185dd54495cd7c74d 100644
--- a/source/Lib/CommonLib/InterPrediction.h
+++ b/source/Lib/CommonLib/InterPrediction.h
@@ -177,6 +177,10 @@ public:
   bool              m_skipDoLic;
 #endif
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+public:
+  AffineAMVPInfo m_affineAmvpInfo[AFFINE_MODEL_NUM][NUM_IMV_MODES][NUM_REF_PIC_LIST_01][MAX_NUM_REF];
+#endif
 #if JVET_AD0140_MVD_PREDICTION
   struct MvdDerivedInfo
   {
@@ -251,6 +255,7 @@ public:
   AMVPInfo m_tplAmvpInfoLIC[NUM_IMV_MODES][NUM_REF_PIC_LIST_01][MAX_NUM_REF];
 #endif
 #endif
+
 #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
   MergeCtx m_pcMergeCtxList0;
   MergeCtx m_pcMergeCtxList1;
@@ -980,6 +985,7 @@ public:
   int deriveMVSDIdxFromMVDTransSI(const Mv& cMvd, const std::vector<Mv>& cMvdDerived, const MvdSuffixInfo &si);
   Mv  deriveMVDFromMVSDIdxTransSI(int mvsdIdx, const std::vector<Mv> &cMvdDerived, const MvdSuffixInfo &si);
 #endif
+
   int deriveMVSDIdxFromMVDTrans(Mv cMvd, std::vector<Mv>& cMvdDerived);
   Mv deriveMVDFromMVSDIdxTrans(int mvsdIdx, std::vector<Mv>& cMvdDerived);
   void deriveMvdSignSMVD(const Mv& cMvPred, const Mv& cMvPred2, const Mv& cMvdKnownAtDecoder, PredictionUnit& pu, std::vector<Mv>& cMvdDerived);
@@ -1249,6 +1255,10 @@ public:
     , int mrgCandIdx = -1);
   void    updateAffineCandInfo2(PredictionUnit &pu, AffineMergeCtx& affMrgCtx, uint32_t(*rdCandList)[RMVF_AFFINE_MRG_MAX_CAND_LIST_SIZE], int listsize, int mrgCandIdx = -1);
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  void adjustAffineAMVPCandidates(PredictionUnit &pu, const RefPicList &eRefPicList, const int &refIdx, AffineAMVPInfo &affiAMVPInfo, int extCond);
+  void tmRefineAffineAMVPCandidates(PredictionUnit &pu, const RefPicList &eRefPicList, const int &refIdx, AffineAMVPInfo &affiAMVPInfo, int extCond);
+#endif
 #if JVET_Y0058_IBC_LIST_MODIFY
   void    adjustIBCMergeCandidates(PredictionUnit &pu, MergeCtx& mrgCtx, int mrgCandIdx = -1);
   void    updateIBCCandInfo(PredictionUnit &pu, MergeCtx& mrgCtx, uint32_t(*RdCandList)[IBC_MRG_MAX_NUM_CANDS], int mrgCandIdx = -1);
@@ -1511,6 +1521,11 @@ public:
   void       clearAmvpTmvpBuffer();
 #endif
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  void       clearAffineAmvpBuffer ();
+  void       writeAffineAmvpBuffer (const AffineAMVPInfo& src, const CodingUnit& cu, RefPicList eRefList, int refIdx);
+  bool       readAffineAmvpBuffer  (      AffineAMVPInfo& dst, const CodingUnit& cu, RefPicList eRefList, int refIdx);
+#endif
 #if TM_AMVP || TM_MRG || JVET_Z0084_IBC_TM || MULTI_PASS_DMVR
   static Distortion getDecoderSideDerivedMvCost (const Mv& mvStart, const Mv& mvCur, int searchRangeInFullPel, int weight);
 #if MULTI_PASS_DMVR
@@ -1576,6 +1591,7 @@ private:
 #endif
 
   Mv*       m_bdmvrSubPuMvBuf[2];
+
 #if JVET_X0083_BM_AMVP_MERGE_MODE
 public:
 #if JVET_AD0213_LIC_IMP
@@ -1586,6 +1602,7 @@ public:
   void      amvpMergeModeMvRefinement(PredictionUnit& pu, MvField* mvFieldAmListCommon, const int mvFieldMergeIdx, const int mvFieldAmvpIdx);
 #endif
 #endif
+
 #if JVET_AC0144_AFFINE_DMVR_REGRESSION
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
   void bmAffineInit(const PredictionUnit& pu, int mergeIdx = -1);
@@ -1665,6 +1682,9 @@ public:
 #endif
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
     , int mergeIdx = -1
+#endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    , bool isInt4PosRefine = false
 #endif
   );
 #if JVET_AH0119_SUBBLOCK_TM
@@ -1676,6 +1696,9 @@ public:
   bool processTM4AffineBaseMV(PredictionUnit& pu, AffineMergeCtx &affineMergeCtx, int uiAffMergeCand, Mv(&bestCPMV)[2][3], Distortion& uiCostOri, Distortion& uiCostBest, uint32_t targetList
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
     , int mergeIdx = -1
+#endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    , bool isInt4PosRefine = false
 #endif
   );
   void xUpdateCPMV(PredictionUnit &pu, int32_t targetRefList, const Mv(&curCPMV)[2][3], const int deltaMvHorX, const int deltaMvHorY, const int deltaMvVerX, const int deltaMvVerY, const int baseCP);
diff --git a/source/Lib/CommonLib/MotionInfo.h b/source/Lib/CommonLib/MotionInfo.h
index 1e2a8c4bb7f991828eafea8810ec2f80a2df49f1..bf00c8abeb9be161aac5910e52dcc9035269b24f 100644
--- a/source/Lib/CommonLib/MotionInfo.h
+++ b/source/Lib/CommonLib/MotionInfo.h
@@ -126,9 +126,16 @@ struct AMVPInfo
 
 struct AffineAMVPInfo
 {
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  unsigned maxStorageSize;
+  Mv       mvCandLT[ AFFINE_AMVP_MAX_CAND ];  ///< array of affine motion vector predictor candidates for left-top corner
+  Mv       mvCandRT[ AFFINE_AMVP_MAX_CAND ];  ///< array of affine motion vector predictor candidates for right-top corner
+  Mv       mvCandLB[ AFFINE_AMVP_MAX_CAND ];  ///< array of affine motion vector predictor candidates for left-bottom corner
+#else
   Mv       mvCandLT[ AMVP_MAX_NUM_CANDS_MEM ];  ///< array of affine motion vector predictor candidates for left-top corner
   Mv       mvCandRT[ AMVP_MAX_NUM_CANDS_MEM ];  ///< array of affine motion vector predictor candidates for right-top corner
   Mv       mvCandLB[ AMVP_MAX_NUM_CANDS_MEM ];  ///< array of affine motion vector predictor candidates for left-bottom corner
+#endif
   unsigned numCand;                       ///< number of motion vector predictor candidates
 };
 #if JVET_AA0107_RMVF_AFFINE_MERGE_DERIVATION
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index 7bfe88ad40e95a43ea8488a6ea034ebe4fcf4fd2..26d549509a85f51715748da27ce2c92b7ffa20da 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -108,6 +108,9 @@ Slice::Slice()
 #if JVET_AG0098_AMVP_WITH_SBTMVP
 , m_amvpSbTmvpAmvrEnabledFlag     (false)
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+, m_extAmvpLevel                  (0)
+#endif
 #if JVET_AA0093_DIVERSITY_CRITERION_FOR_ARMC
 , m_costForARMC                   ( MAX_UINT )
 #endif
@@ -2122,7 +2125,6 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll)
 #endif
 
   m_cabacInitFlag                 = pSrc->m_cabacInitFlag;
-
 #if JVET_AG0196_CABAC_RETRAIN
   m_cabacInitSliceType = pSrc->m_cabacInitSliceType;
 #endif
@@ -4295,6 +4297,9 @@ SPS::SPS()
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
 , m_useAltCost                ( true )
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+, m_useExtAmvp                ( true )
+#endif
 #if JVET_AF0163_TM_SUBBLOCK_REFINEMENT
 , m_useAffineTM               ( false )
 #if JVET_AG0276_NLIC
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index 4e132f78c0cf89d346a997752c0b1f695e89ea10..c4c4626fef7e8a2bbf9513b32006ab61297564b0 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -1805,6 +1805,9 @@ private:
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
   bool              m_useAltCost;
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  bool              m_useExtAmvp;
+#endif
 #if JVET_AF0163_TM_SUBBLOCK_REFINEMENT
   bool              m_useAffineTM;
 #if JVET_AG0276_NLIC
@@ -2708,6 +2711,10 @@ void                    setCCALFEnabledFlag( bool b )
   void      setUseFastSubTmvp     ( bool b )                                        { m_fastSubTmvp = b; }
   bool      getUseFastSubTmvp     ()                                      const     { return m_fastSubTmvp; }
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  void      setUseExtAmvp         ( bool b )                                        { m_useExtAmvp = b; }
+  bool      getUseExtAmvp          ()                                      const     { return m_useExtAmvp; }
+#endif
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
   void      setUseAltCost         ( bool b )                                        { m_useAltCost = b; }
   bool      getUseAltCost         ()                                      const     { return m_useAltCost; }
@@ -3768,6 +3775,9 @@ private:
   bool                       m_amvpSbTmvpAmvrEnabledFlag;
   bool                       m_amvpSbTmvpEnabledFlag;
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  int                        m_extAmvpLevel;
+#endif
 #if JVET_AA0093_DIVERSITY_CRITERION_FOR_ARMC
   uint32_t                   m_costForARMC;
 #endif
@@ -3811,7 +3821,6 @@ private:
   uint32_t                   m_numSubstream;
 
   bool                       m_cabacInitFlag;
-
 #if JVET_AG0196_CABAC_RETRAIN
   SliceType                  m_cabacInitSliceType;
 #endif
@@ -4029,6 +4038,9 @@ public:
   uint8_t                     getAmvpSbTmvpNumColPic() const                         { return m_amvpSbTmvpNumColPic;                                     }
   bool                        getAmvpSbTmvpAmvrEnabledFlag() const                   { return m_amvpSbTmvpAmvrEnabledFlag;                               }
   bool                        getAmvpSbTmvpEnabledFlag() const                       { return m_amvpSbTmvpEnabledFlag;                                   }
+#endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  int                         getExtAmvpLevel() const                                 { return m_extAmvpLevel;                                   }
 #endif
   void                        checkColRefIdx(uint32_t curSliceSegmentIdx, const Picture* pic);
 #if JVET_AA0093_DIVERSITY_CRITERION_FOR_ARMC
@@ -4228,6 +4240,9 @@ public:
   void                        setAmvpSbTmvpNumColPic(uint8_t numPic)                 { m_amvpSbTmvpNumColPic = numPic;                                   }
   void                        setAmvpSbTmvpAmvrEnabledFlag(bool b)                   { m_amvpSbTmvpAmvrEnabledFlag = b;                                  }
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  void                        setExtAmvpLevel(int b)                            { m_extAmvpLevel = b;                                    }
+#endif
 #if JVET_AA0093_DIVERSITY_CRITERION_FOR_ARMC
   void                        setCostForARMC(uint32_t cost)                          { m_costForARMC = cost;                                         }
 #endif
@@ -4364,7 +4379,6 @@ public:
 
   void                        setCabacInitFlag( bool val )                           { m_cabacInitFlag = val;                                        } //!< set CABAC initial flag
   bool                        getCabacInitFlag()                               const { return m_cabacInitFlag;                                       } //!< get CABAC initial flag
-
 #if JVET_AG0196_CABAC_RETRAIN
   void                        setCabacInitSliceType( SliceType val )                 { m_cabacInitSliceType = val; }
   SliceType                   getCabacInitSliceType()                          const { return m_cabacInitSliceType; }
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index c2c5e192c06ced35c0536cd3819d17e6a412e109..b6d58953be033c1f68b140ebf45ef9df8b5a4b42 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -51,6 +51,7 @@
 #include <cassert>
 #include <cstdint>
 
+
 #define BASE_ENCODER                                      1
 #define BASE_NORMATIVE                                    1
 #define TOOLS                                             1
@@ -368,6 +369,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_AJ0126_INTER_AMVP_ENHANCEMENT                1 // JVET-AJ0126: Enhanced inter AMVP (inter TM part is controlled by EnableTMTools)
 // Inter template matching tools
 #define JVET_AJ0096_SATD_REORDER_INTER                    1 // JVET-AJ0096: SATD-based reordering for inter coding
 #define ENABLE_INTER_TEMPLATE_MATCHING                    1 // It controls whether template matching is enabled for inter prediction
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index c44b9b1a3f1a687bd3a79aaa222718466ee90dab..20c845f7b38d3fb8d3c784b66b56bba51d296b3d 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -9803,6 +9803,7 @@ void PU::getInterMergeCandidatesSubTMVP(const PredictionUnit &pu, MergeCtx& mrgC
 #endif
     );
   }
+
   mrgCtx.numValidMergeCand = cnt;
 
   return;
@@ -17967,6 +17968,124 @@ bool PU::checkAffineTMCondition(const PredictionUnit& pu)
   return (min > 1) || !pu.cu->slice->getCheckLDC();
 }
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+int PU::checkExtAffineAmvpCondition(const PredictionUnit& pu)
+{
+  if(pu.cu->cs->sps->getUseExtAmvp() == false)
+  {
+    return EXT_AFFINE_AMVP_TYPE_NONE;
+  }
+  
+  if(pu.cu->cs->sps->getTMToolsEnableFlag() == false)
+  {
+    return EXT_AFFINE_AMVP_TYPE_NA_TEMP;
+  }
+
+  int clevel = pu.cu->slice->getExtAmvpLevel();
+  int wxh = pu.lheight() * pu.lwidth();
+  if(pu.cu->slice->getCheckLDB())
+  {
+    if(clevel < 2 && wxh <= 4*4)
+    {
+      return EXT_AFFINE_AMVP_TYPE_NONE;
+    }
+    else if (!clevel && wxh > 64*64)
+    {
+      return EXT_AFFINE_AMVP_TYPE_NONE;
+    }
+    else if (clevel >= 2 && wxh <= 8*8)
+    {
+      return EXT_AFFINE_AMVP_TYPE_NONE;
+    }
+    else if (!clevel)
+    {
+      return EXT_AFFINE_AMVP_TYPE_LISTS4_REORDER_FIRST;
+    }
+    else
+    {
+      return EXT_AFFINE_AMVP_TYPE_LISTS10;
+    }
+  }
+  else
+  {
+    if (!clevel)
+    {
+      if(pu.cs->slice->getTLayer() > 4)
+      {
+        return EXT_AFFINE_AMVP_TYPE_NONE;
+      }
+      else if (wxh <= 4*4 || wxh > 64*64 || pu.lheight() >= 5* pu.lwidth() || pu.lwidth() >= 5* pu.lheight())
+      {
+        return EXT_AFFINE_AMVP_TYPE_NONE;
+      }
+      else
+      {
+        return EXT_AFFINE_AMVP_TYPE_LISTS5;
+      }
+    }
+    else if (clevel <= 2 )
+    {
+      if (pu.lheight() >= 4* pu.lwidth() || pu.lwidth() >= 4* pu.lheight())
+      {
+        return EXT_AFFINE_AMVP_TYPE_NONE;
+      }
+      else
+      {
+        return EXT_AFFINE_AMVP_TYPE_LISTS4;
+      }
+    }
+    else
+    {
+      if(pu.cs->slice->getTLayer() > 3 || wxh <= 4*4)
+      {
+        return EXT_AFFINE_AMVP_TYPE_NONE;
+      }
+      else
+      {
+        return EXT_AFFINE_AMVP_TYPE_LISTS10;
+      }
+    }
+  }
+}
+int PU::checkExtRegularAmvpCondition(const PredictionUnit& pu)
+{
+  if(pu.cu->cs->sps->getUseExtAmvp() == false)
+  {
+    return EXT_REGULAR_AMVP_TYPE_NONE;
+  }
+
+  int clevel = pu.cu->slice->getExtAmvpLevel();
+  int wxh = pu.lheight() * pu.lwidth();
+  if(pu.cu->slice->getCheckLDB())
+  {
+    return EXT_REGULAR_AMVP_TYPE_NONE;
+  }
+  else if (clevel <= 2 && pu.cs->slice->getTLayer() > 4)
+  {
+    return EXT_REGULAR_AMVP_TYPE_NONE;
+  }
+  else if (!clevel)
+  {
+    if (pu.lheight() * pu.lwidth() > 64*64 || pu.lheight() >= 5* pu.lwidth() || pu.lwidth() >= 5* pu.lheight())
+    {
+      return EXT_REGULAR_AMVP_TYPE_NONE;
+    }
+    else
+    {
+      return EXT_REGULAR_AMVP_TYPE_NA_SPATIAL;
+    }
+  }
+  else if (clevel > 2)
+  {
+    if(pu.cs->slice->getTLayer() > 4 || wxh <= 4*4 || wxh > 128*128)
+    {
+      return EXT_REGULAR_AMVP_TYPE_NONE;
+    }
+  }
+  return EXT_REGULAR_AMVP_TYPE_LISTS10;
+}
+#endif
+
 #if MULTI_PASS_DMVR
 #if JVET_AE0046_BI_GPM
 bool PU::checkBDMVRCondition(const PredictionUnit& pu, bool disregardGpmFlag)
@@ -19339,7 +19458,11 @@ inline void PU::getRribcBvpCand(PredictionUnit &pu, AMVPInfo *pInfo)
 inline void PU::clusterBvpCand(const int cbWidth, const int cbHeight, AMVPInfo *pInfo)
 {
   int                                                numGroups = 0;
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  std::array<bool, (REGULAR_AMVP_MAX_NUM_CANDS_IBC + 1)> validCand;
+#else
   std::array<bool, (REGULAR_AMVP_MAX_NUM_CANDS + 1)> validCand;
+#endif
   validCand.fill(true);
   Mv         bestCand;
   Distortion bestCost;
@@ -19349,7 +19472,11 @@ inline void PU::clusterBvpCand(const int cbWidth, const int cbHeight, AMVPInfo *
   // Clustering of AMVP candidates into two groups
   if (pInfo->numCand > AMVP_MAX_NUM_CANDS)
   {
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    int numCand = std::min((int) pInfo->numCand, REGULAR_AMVP_MAX_NUM_CANDS_IBC + 1);
+#else
     int numCand = std::min((int) pInfo->numCand, REGULAR_AMVP_MAX_NUM_CANDS + 1);
+#endif
     for (int i = 0; i < numCand; i++)
     {
       if (validCand[i])
@@ -19444,7 +19571,11 @@ void PU::fillIBCMvpCand(PredictionUnit &pu, AMVPInfo &amvpInfo)
                           AML_MERGE_TEMPLATE_SIZE, cbHeight);
 
       int candIdx = 0;
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+      while ((pInfo->numCand < (REGULAR_AMVP_MAX_NUM_CANDS_IBC + 1)) && (candIdx < mergeCtx.numAMVPMergeCand))
+#else
       while ((pInfo->numCand < (REGULAR_AMVP_MAX_NUM_CANDS + 1)) && (candIdx < mergeCtx.numAMVPMergeCand))
+#endif
       {
         pInfo->mvCand[pInfo->numCand] = mergeCtx.mvFieldNeighbours[candIdx << 1].mv;
         pInfo->mvCost[pInfo->numCand] =
@@ -19718,7 +19849,12 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
 
   pInfo->numCand = 0;
 #if TM_AMVP
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  int extRegularAmvpCond = PU::checkExtRegularAmvpCondition(pu);
+  pInfo->maxStorageSize         = interPred != nullptr ? ((extRegularAmvpCond & 0x0f) ? REGULAR_AMVP_MAX_NUM_CANDS : REGULAR_AMVP_MAX_NUM_CANDS_IBC) : AMVP_MAX_NUM_CANDS;
+#else
   pInfo->maxStorageSize         = interPred != nullptr ? REGULAR_AMVP_MAX_NUM_CANDS : AMVP_MAX_NUM_CANDS;
+#endif
   pInfo->maxSimilarityThreshold = interPred != nullptr ? 1 : 0;
 #endif
 
@@ -20055,8 +20191,174 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
   }
 #endif
 
+
 #if TM_AMVP
   // Non-adjacent candidates
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  if (extRegularAmvpCond & 0xff)
+  {
+    auto getNAcand = [&](Position pos) -> void
+    {
+      const unsigned        plevel        = pu.cs->sps->getLog2ParallelMergeLevelMinus2() + 2;
+      const PredictionUnit *puNonAdjacent = cs.getPURestricted(pos, pu, pu.chType);
+
+#if JVET_Y0065_GPM_INTRA
+      bool isAvailableNonAdjacent = puNonAdjacent && isDiffMER(pu.lumaPos(), pos, plevel)
+                                    && CU::isInter(*puNonAdjacent->cu) && puNonAdjacent->getMotionInfo(pos).isInter;
+#else
+      bool isAvailableNonAdjacent =
+        puNonAdjacent && isDiffMER(pu.lumaPos(), pos, plevel) && CU::isInter(*puNonAdjacent->cu);
+#endif
+
+      if (isAvailableNonAdjacent)
+      {
+        MotionInfo miNeighbor = puNonAdjacent->getMotionInfo(pos);
+
+        const int        currRefPOC     = cs.slice->getRefPic(eRefPicList, refIdx)->getPOC();
+        const RefPicList eRefPicList2nd = (eRefPicList == REF_PIC_LIST_0) ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
+        int              numDir         = pu.cu->slice->getExtAmvpLevel() ? 2 : 1;
+        for (int predictorSource = 0; predictorSource < numDir; predictorSource++)
+        {
+          const RefPicList eRefPicListIndex = (predictorSource == 0) ? eRefPicList : eRefPicList2nd;
+          const int        neibRefIdx       = miNeighbor.refIdx[eRefPicListIndex];
+
+          if (neibRefIdx >= 0 && currRefPOC == cs.slice->getRefPOC(eRefPicListIndex, neibRefIdx))
+          {
+            miNeighbor.mv[eRefPicListIndex].roundTransPrecInternal2Amvr(pu.cu->imv);
+            pInfo->mvCand[(pInfo->numCand)] = miNeighbor.mv[eRefPicListIndex];
+            if (!pInfo->xCheckSimilarMotion(pInfo->numCand))
+            {
+              pInfo->numCand++;
+            }
+          }
+          if (pInfo->numCand > pInfo->maxStorageSize)
+          {
+            pInfo->numCand = pInfo->maxStorageSize;
+          }
+        }
+      }
+    };
+
+    // Non-adjacent candidates
+    if (pInfo->numCand < pInfo->maxStorageSize && interPred != nullptr)
+    {
+      // Non-adjacent candidates round 1
+      int offsetX  = 0;
+      int offsetY  = 0;
+      int offsetX0 = 0;
+      int offsetX1 = 0;
+      int offsetX2 = pu.Y().width >> 1;
+      int offsetY0 = 0;
+      int offsetY1 = 0;
+      int offsetY2 = pu.Y().height >> 1;
+
+      const int horNAInterval       = pu.Y().width;
+      const int verNAInterval       = pu.Y().height;
+      const int numNACandidate01[7] = { 7, 9, 9, 9, 9, 9, 9 };
+      const int idxMap01[7][9]      = { { 0, 1, 2, 3, 4, 5, 6 },       { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
+                                   { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
+                                   { 0, 1, 2, 3, 4, 5, 6, 7, 8 }, { 0, 1, 2, 3, 4, 5, 6, 7, 8 },
+                                   { 0, 1, 2, 3, 4, 5, 6, 7, 8 } };
+
+      for (int iDistanceIndex = 0; iDistanceIndex < 7 && pInfo->numCand < pInfo->maxStorageSize; iDistanceIndex++)
+      {
+        const int iNADistanceHor = horNAInterval * (iDistanceIndex + 1);
+        const int iNADistanceVer = verNAInterval * (iDistanceIndex + 1);
+
+        for (int naspIdx = 0; naspIdx < numNACandidate01[iDistanceIndex] && pInfo->numCand < pInfo->maxStorageSize;
+             naspIdx++)
+        {
+          switch (idxMap01[iDistanceIndex][naspIdx])
+          {
+          case 0:
+            offsetX = offsetX0 = -iNADistanceHor - 1;
+            offsetY = offsetY0 = verNAInterval + iNADistanceVer - 1;
+            break;
+          case 1:
+            offsetX = offsetX1 = horNAInterval + 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:
+            CHECK(idxMap01[iDistanceIndex][naspIdx] > 8,"error!");
+            exit(0);
+            break;
+          }
+          getNAcand(posLT.offset(offsetX, offsetY));
+        }
+      }
+
+      // Non-adjacent candidates round 2
+      const int numNACandidate2[7] = { 4, 4, 4, 4, 4, 4, 4 };
+      const int idxMap2[7][5]      = { { 0, 1, 2, 3 }, { 0, 1, 2, 3 }, { 0, 1, 2, 3 }, { 0, 1, 2, 3 },
+                                  { 0, 1, 2, 3 }, { 0, 1, 2, 3 }, { 0, 1, 2, 3 } };
+
+      for (int iDistanceIndex = 0; iDistanceIndex < 7 && pInfo->numCand < pInfo->maxStorageSize; iDistanceIndex++)
+      {
+        const int horNADistance = horNAInterval * (iDistanceIndex + 1);
+        const int verNADistance = verNAInterval * (iDistanceIndex + 1);
+
+        for (int naspIdx = 0; naspIdx < numNACandidate2[iDistanceIndex] && pInfo->numCand < pInfo->maxStorageSize;
+             naspIdx++)
+        {
+          switch (idxMap2[iDistanceIndex][naspIdx])
+          {
+          case 0:
+            offsetX = offsetX0 = -horNADistance - 1;
+            offsetY            = offsetY2 + ((verNAInterval + verNADistance - 1 - offsetY2) >> 1);
+            break;
+          case 1:
+            offsetX = offsetX2 + ((horNAInterval + horNADistance - 1 - offsetX2) >> 1);
+            offsetY = offsetY0 = -verNADistance - 1;
+            break;
+          case 2:
+            offsetX = offsetX0;
+            offsetY = offsetY0 + ((offsetY2 - offsetY0) >> 1);
+            break;
+          case 3:
+            offsetX = offsetX0 + ((offsetX2 - offsetX0) >> 1);
+            offsetY = offsetY0;
+            break;
+          default:
+            CHECK(idxMap2[iDistanceIndex][naspIdx] > 3, "error!");
+            exit(0);
+            break;
+          }
+
+          getNAcand(posLT.offset(offsetX, offsetY));
+        }
+      }
+    }
+  }
+  else
+#endif
   if (pInfo->numCand < pInfo->maxStorageSize && interPred != nullptr)
   {
     const unsigned plevel = pu.cs->sps->getLog2ParallelMergeLevelMinus2() + 2;
@@ -20137,6 +20439,7 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
     const int currRefPOC = cs.slice->getRefPic(eRefPicList, refIdx)->getPOC();
     addAMVPHMVPCand(pu, eRefPicList, currRefPOC, *pInfo);
   }
+
 #if TM_AMVP
   if (pInfo->numCand > pInfo->maxStorageSize)
   {
@@ -20188,6 +20491,7 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
         input.push_back(temp);
       }
       stable_sort(input.begin(), input.end(), costIncSort);
+
       for (int candIdx = 1; candIdx < pInfo->numCand; ++candIdx)
       {
         if (input.at(candIdx).cost > 5 * input.at(0).cost)
@@ -20222,7 +20526,6 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
 #if JVET_AA0093_REFINED_MOTION_FOR_ARMC
     pu.reduceTplSize = false;
 #endif
-
     pInfo->numCand = 1;
 #if JVET_AA0093_REFINED_MOTION_FOR_ARMC
     if (!armcRefinedMotion)
@@ -21377,7 +21680,11 @@ bool PU::addSpatialAffineMergeHMVPCand(const PredictionUnit& pu, AffineMergeCtx&
 bool PU::addSpatialAffineAMVPHMVPCand(PredictionUnit & pu, const RefPicList & eRefPicList, const int& refIdx, AffineAMVPInfo & affiAMVPInfo, static_vector<AffineMotionInfo, MAX_NUM_AFF_HMVP_CANDS>* lutAff, int iHMVPlistIdx,
   int neiIdx[], int iNeiNum, int aiNeibeInherited[], bool bFoundOne)
 {
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  if (affiAMVPInfo.numCand >= affiAMVPInfo.maxStorageSize)
+#else
   if (affiAMVPInfo.numCand >= AMVP_MAX_NUM_CANDS)
+#endif
   {
     return false;
   }
@@ -21468,7 +21775,11 @@ bool PU::addSpatialAffineAMVPHMVPCand(PredictionUnit & pu, const RefPicList & eR
 
     affiAMVPInfo.numCand++;
 
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    if (affiAMVPInfo.numCand == affiAMVPInfo.maxStorageSize)
+#else
     if (affiAMVPInfo.numCand == AMVP_MAX_NUM_CANDS)
+#endif
     {
       return true;
     }
@@ -21518,9 +21829,18 @@ bool PU::checkLastAffineAMVPCandRedundancy(const PredictionUnit& pu, AffineAMVPI
   return true;
 }
 #endif
-void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const int &refIdx, AffineAMVPInfo &affiAMVPInfo)
+void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const int &refIdx, AffineAMVPInfo &affiAMVPInfo
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    , InterPrediction* interPred
+#endif
+)
 {
   affiAMVPInfo.numCand = 0;
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  int extAffineAmvpCond = PU::checkExtAffineAmvpCondition(pu);
+  int extAffineAmvpVal = extAffineAmvpCond >> 8 & 0x0f;
+  affiAMVPInfo.maxStorageSize = (extAffineAmvpVal == 0) ? AMVP_MAX_NUM_CANDS : ((extAffineAmvpVal == 2) ? 4 : ((extAffineAmvpVal == 3) ? 5 : AFFINE_AMVP_MAX_CAND));
+#endif
 
   if (refIdx < 0)
   {
@@ -21531,6 +21851,15 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
   bool isClean = pu.cs->isClean(pu.cu->Y().bottomRight(), CHANNEL_TYPE_LUMA);
 #endif
 
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  if (interPred != nullptr)
+  {
+    if(interPred->readAffineAmvpBuffer(affiAMVPInfo, *pu.cu, eRefPicList, refIdx))
+    {
+      return;
+    }  
+  }
+#endif
   // insert inherited affine candidates
   Mv outputAffineMv[3];
   Position posLT = pu.Y().topLeft();
@@ -21632,7 +21961,11 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
 
   for (int affHMVPIdx = 0; affHMVPIdx < 1; affHMVPIdx++)
   {
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+   if (affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize && leftAffNeiNum > 0)
+#else
     if (affiAMVPInfo.numCand < AMVP_MAX_NUM_CANDS && leftAffNeiNum > 0)
+#endif
     {
 #if JVET_Z0118_GDR
       addSpatialAffineAMVPHMVPCand(pu, eRefPicList, refIdx, affiAMVPInfo, (isClean) ? pu.cs->motionLut.lutAff1 : pu.cs->motionLut.lutAff0, 0, leftNeiIdx, leftAffNeiNum, aiNeibeInherited, true);
@@ -21640,7 +21973,11 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
       addSpatialAffineAMVPHMVPCand(pu, eRefPicList, refIdx, affiAMVPInfo, pu.cs->motionLut.lutAff, 0, leftNeiIdx, leftAffNeiNum, aiNeibeInherited, true);
 #endif
     }
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    if (affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize && aboveAffNeiNum > 0)
+#else
     if (affiAMVPInfo.numCand < AMVP_MAX_NUM_CANDS && aboveAffNeiNum > 0)
+#endif
     {
 #if JVET_Z0118_GDR
       addSpatialAffineAMVPHMVPCand(pu, eRefPicList, refIdx, affiAMVPInfo, (isClean) ? pu.cs->motionLut.lutAff1 : pu.cs->motionLut.lutAff0, 0, aboveNeiIdx, aboveAffNeiNum, aiNeibeInherited, true);
@@ -21666,7 +22003,11 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
   }
 #endif
 
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  if ( affiAMVPInfo.numCand >= affiAMVPInfo.maxStorageSize )
+#else
   if ( affiAMVPInfo.numCand >= AMVP_MAX_NUM_CANDS )
+#endif
   {
     for (int i = 0; i < affiAMVPInfo.numCand; i++)
     {
@@ -21674,6 +22015,22 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
       affiAMVPInfo.mvCandRT[i].roundAffinePrecInternal2Amvr(pu.cu->imv);
       affiAMVPInfo.mvCandLB[i].roundAffinePrecInternal2Amvr(pu.cu->imv);
     }
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  if (interPred != nullptr)
+  {
+    if ((extAffineAmvpCond >> 4 & 0x0f) == 1)
+    {
+      interPred->tmRefineAffineAMVPCandidates(pu, eRefPicList, refIdx, affiAMVPInfo, extAffineAmvpCond);
+      interPred->adjustAffineAMVPCandidates(pu, eRefPicList, refIdx, affiAMVPInfo, extAffineAmvpCond);
+    }
+    else
+    {
+      interPred->adjustAffineAMVPCandidates(pu, eRefPicList, refIdx, affiAMVPInfo, extAffineAmvpCond);
+      interPred->tmRefineAffineAMVPCandidates(pu, eRefPicList, refIdx, affiAMVPInfo, extAffineAmvpCond);
+    }
+    interPred->writeAffineAmvpBuffer(affiAMVPInfo, *pu.cu, eRefPicList, refIdx);
+  }
+#endif
     return;
   }
 
@@ -21743,7 +22100,11 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
 #if JVET_Z0139_HIST_AFF
   for (int affHMVPIdx = 1; affHMVPIdx < MAX_NUM_AFF_HMVP_CANDS; affHMVPIdx++)
   {
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    if (affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize && leftAffNeiNum > 0)
+#else
     if (affiAMVPInfo.numCand < AMVP_MAX_NUM_CANDS && leftAffNeiNum > 0)
+#endif
     {
 #if JVET_Z0118_GDR
       addSpatialAffineAMVPHMVPCand(pu, eRefPicList, refIdx, affiAMVPInfo, (isClean) ? pu.cs->motionLut.lutAff1 : pu.cs->motionLut.lutAff0, 0, leftNeiIdx, leftAffNeiNum, aiNeibeInherited, true);
@@ -21751,7 +22112,11 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
       addSpatialAffineAMVPHMVPCand(pu, eRefPicList, refIdx, affiAMVPInfo, pu.cs->motionLut.lutAff, 0, leftNeiIdx, leftAffNeiNum, aiNeibeInherited, true);
 #endif
     }
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    if (affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize && aboveAffNeiNum > 0)
+#else
     if (affiAMVPInfo.numCand < AMVP_MAX_NUM_CANDS && aboveAffNeiNum > 0)
+#endif
     {
 #if JVET_Z0118_GDR
       addSpatialAffineAMVPHMVPCand(pu, eRefPicList, refIdx, affiAMVPInfo, (isClean) ? pu.cs->motionLut.lutAff1 : pu.cs->motionLut.lutAff0, 0, aboveNeiIdx, aboveAffNeiNum, aiNeibeInherited, true);
@@ -21762,10 +22127,17 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
   }
 #endif
 
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  if ( affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize )
+  {
+    // check corner MVs
+    for ( int i = 2; i >= 0 && affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize; i-- )
+#else
   if ( affiAMVPInfo.numCand < 2 )
   {
     // check corner MVs
     for ( int i = 2; i >= 0 && affiAMVPInfo.numCand < AMVP_MAX_NUM_CANDS; i-- )
+#endif
     {
       if ( cornerMVPattern & (1 << i) ) // MV i exist
       {
@@ -21780,7 +22152,11 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
     }
 
     // Get Temporal Motion Predictor
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    if ( affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize && pu.cs->picHeader->getEnableTMVPFlag() )
+#else
     if ( affiAMVPInfo.numCand < 2 && pu.cs->picHeader->getEnableTMVPFlag() )
+#endif
     {
       const int refIdxCol = refIdx;
 
@@ -21824,14 +22200,22 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
     }
 
 #if JVET_Z0139_NA_AFF
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    if (affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize)
+#else
     if (affiAMVPInfo.numCand < AMVP_MAX_NUM_CANDS)
+#endif
     {
       addNonAdjCstAffineMVPCandUnscaled(pu, eRefPicList, refIdx, affiAMVPInfo);
     }
 #endif
 
 #if JVET_Z0139_HIST_AFF
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    if (affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize)
+#else
     if (affiAMVPInfo.numCand < AMVP_MAX_NUM_CANDS)
+#endif
     {
       for (int affHMVPIdx = 0; affHMVPIdx < MAX_NUM_AFF_HMVP_CANDS; affHMVPIdx++)
       {
@@ -21843,6 +22227,158 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
       }
     }
 #endif
+
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    // Get Temporal Motion Predictor
+    if (((extAffineAmvpCond & 0x00f) == 1) && (affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize)
+        && pu.cs->picHeader->getEnableTMVPFlag())
+    {
+      // offset the pos to be sure to "point" to the same position the uiAbsPartIdx would've pointed to
+      // const PreCalcValues &pcv = *cs.pcv;
+      bool                 isC0Avail;
+      bool                 isC1Avail;
+      bool                 boundaryCond;
+      const SubPic        &curSubPic = pu.cs->slice->getPPS()->getSubPicFromPos(pu.lumaPos());
+      Position             posRB     = pu.Y().bottomRight().offset(-3, -3);
+      const PreCalcValues &pcv       = *pu.cs->pcv;
+      Position             posCenter = pu.Y().center();
+      Position             posC0;
+      Position             posC1;
+
+      int iRefIdx = refIdx;
+
+      bool bExistMV0;
+      Mv   cColMv0[3];
+
+      int offsetX0 = 0, offsetX1 = 0, offsetX2 = 0, offsetX3 = pu.Y().width >> 1;
+      int offsetY0 = 0, offsetY1 = 0, offsetY2 = 0, offsetY3 = pu.Y().height >> 1;
+
+      const int numNACandidate[5] = { 2, 2, 2, 2, 2 };
+      const int idxMap[5][2]      = { { 0, 1 }, { 0, 2 }, { 0, 2 }, { 0, 2 }, { 0, 2 } };
+
+      for (int iDistanceIndex = 0;
+           iDistanceIndex < TMVP_DISTANCE_LEVEL && affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize; iDistanceIndex++)
+      {
+        const int iNADistanceHor = pu.Y().width * iDistanceIndex;
+        const int iNADistanceVer = pu.Y().height * iDistanceIndex;
+
+        for (int iNASPIdx = 0;
+             iNASPIdx < numNACandidate[iDistanceIndex] && affiAMVPInfo.numCand < affiAMVPInfo.maxStorageSize;
+             iNASPIdx++)
+        {
+          switch (idxMap[iDistanceIndex][iNASPIdx])
+          {
+          case 0:
+            offsetX0 = offsetX2 = 4 + iNADistanceHor;
+            offsetY0 = offsetY2 = 4 + iNADistanceVer;
+            offsetX1            = iNADistanceHor;
+            offsetY1            = iNADistanceVer;
+            break;
+          case 1:
+            offsetX0 = 4;
+            offsetY0 = 0;
+            offsetX1 = 0;
+            offsetY1 = 4;
+            break;
+          case 2:
+            offsetX0 = offsetX2;
+            offsetY0 = 4 - offsetY3;
+            offsetX1 = 4 - offsetX3;
+            offsetY1 = offsetY2;
+            break;
+          default:
+            printf("error!");
+            exit(0);
+            break;
+          }
+          isC0Avail = false;
+          if (curSubPic.getTreatedAsPicFlag())
+          {
+            boundaryCond = ((posRB.x + offsetX0) <= curSubPic.getSubPicRight()
+                            && (posRB.y + offsetY0) <= curSubPic.getSubPicBottom());
+          }
+          else
+          {
+            boundaryCond = ((posRB.x + offsetX0) < pcv.lumaWidth) && ((posRB.y + offsetY0) < pcv.lumaHeight);
+          }
+          if (boundaryCond)
+          {
+            posC0     = posRB.offset(offsetX0, offsetY0);
+            isC0Avail = true;
+          }
+
+          if (idxMap[iDistanceIndex][iNASPIdx] == 0)
+          {
+            isC1Avail = false;
+            if (curSubPic.getTreatedAsPicFlag())
+            {
+              boundaryCond = ((posCenter.x + offsetX1) <= curSubPic.getSubPicRight()
+                              && (posCenter.y + offsetY1) <= curSubPic.getSubPicBottom());
+            }
+            else
+            {
+              boundaryCond = ((posCenter.x + offsetX1) < pcv.lumaWidth) && ((posCenter.y + offsetY1) < pcv.lumaHeight);
+            }
+            if (boundaryCond)
+            {
+              posC1     = posCenter.offset(offsetX1, offsetY1);
+              isC1Avail = true;
+            }
+          }
+          else
+          {
+            isC1Avail = false;
+            if (curSubPic.getTreatedAsPicFlag())
+            {
+              boundaryCond = ((posRB.x + offsetX1) <= curSubPic.getSubPicRight()
+                              && (posRB.y + offsetY1) <= curSubPic.getSubPicBottom());
+            }
+            else
+            {
+              boundaryCond = ((posRB.x + offsetX1) < pcv.lumaWidth) && ((posRB.y + offsetY1) < pcv.lumaHeight);
+            }
+            if (boundaryCond)
+            {
+              posC1     = posRB.offset(offsetX1, offsetY1);
+              isC1Avail = true;
+            }
+          }
+          bExistMV0 = false;
+
+          EAffineModel affineType = (EAffineModel) (pu.cu->affineType);
+          bExistMV0               = (isC0Avail
+                       && getColocatedAffineCMVP(pu, eRefPicList, posC0, cColMv0, iRefIdx, false,
+#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
+                                                 pu.cu->slice->isInterB(),
+#endif
+                                                 NULL, &affineType))
+                      || (isC1Avail
+                          && getColocatedAffineCMVP(pu, eRefPicList, posC1, cColMv0, iRefIdx, false,
+#if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
+                                                    pu.cu->slice->isInterB(),
+#endif
+                                                    NULL, &affineType));
+
+          if (bExistMV0)
+          {
+            cColMv0[0].roundAffinePrecInternal2Amvr(pu.cu->imv);
+            affiAMVPInfo.mvCandLT[affiAMVPInfo.numCand] = cColMv0[0];
+            cColMv0[1].roundAffinePrecInternal2Amvr(pu.cu->imv);
+            affiAMVPInfo.mvCandRT[affiAMVPInfo.numCand] = cColMv0[1];
+            cColMv0[2].roundAffinePrecInternal2Amvr(pu.cu->imv);
+            affiAMVPInfo.mvCandLB[affiAMVPInfo.numCand] = cColMv0[2];
+#if JVET_Z0139_HIST_AFF
+            if (checkLastAffineAMVPCandRedundancy(pu, affiAMVPInfo))
+#endif
+            {
+              affiAMVPInfo.numCand++;
+            }
+          }
+        }
+      }
+    }
+#endif
+
 #if JVET_Z0139_HIST_AFF
     if (affiAMVPInfo.numCand < AMVP_MAX_NUM_CANDS)
 #else
@@ -21866,8 +22402,23 @@ void PU::fillAffineMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, co
     affiAMVPInfo.mvCandRT[i].roundAffinePrecInternal2Amvr(pu.cu->imv);
     affiAMVPInfo.mvCandLB[i].roundAffinePrecInternal2Amvr(pu.cu->imv);
   }
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  if (interPred != nullptr)
+  {
+    if ((extAffineAmvpCond >> 4 & 0x0f) == 1)
+    {
+      interPred->tmRefineAffineAMVPCandidates(pu, eRefPicList, refIdx, affiAMVPInfo, extAffineAmvpCond);
+      interPred->adjustAffineAMVPCandidates(pu, eRefPicList, refIdx, affiAMVPInfo, extAffineAmvpCond);
+    }
+    else
+    {
+      interPred->adjustAffineAMVPCandidates(pu, eRefPicList, refIdx, affiAMVPInfo, extAffineAmvpCond);
+      interPred->tmRefineAffineAMVPCandidates(pu, eRefPicList, refIdx, affiAMVPInfo, extAffineAmvpCond);
+    }
+    interPred->writeAffineAmvpBuffer(affiAMVPInfo, *pu.cu, eRefPicList, refIdx);
+  }
+#endif
 }
-
 bool PU::addMVPCandUnscaled( const PredictionUnit &pu, const RefPicList &eRefPicList, const int &iRefIdx, const Position &pos, const MvpDir &eDir, AMVPInfo &info )
 {
         CodingStructure &cs    = *pu.cs;
@@ -22511,7 +23062,11 @@ bool PU::addNonAdjCstAffineMVPCandUnscaled(const PredictionUnit &pu, const RefPi
 
       if (addNonAdjCstAffineMVPConstructedCPMV(pu, miNew, isAvailableNew, posNew, refPicList, refIdx, affiAmvpInfo))
       {
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+        if (affiAmvpInfo.numCand >= affiAmvpInfo.maxStorageSize)
+#else
         if (affiAmvpInfo.numCand >= AMVP_MAX_NUM_CANDS)
+#endif
         {
           return true;
         }
@@ -22673,7 +23228,11 @@ bool PU::addNonAdjCstAffineMVPConstructedCPMV( const PredictionUnit &pu, MotionI
       }
       affiAmvpInfo.numCand++;
       isConverted = true;
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+      if (affiAmvpInfo.numCand >= affiAmvpInfo.maxStorageSize)
+#else
       if (affiAmvpInfo.numCand >= AMVP_MAX_NUM_CANDS)
+#endif
       {
         return true;
       }
@@ -31213,8 +31772,16 @@ AMVPInfo PU::getMultiHypMVPCandsAMVP(PredictionUnit &pu, const RefPicList eRefPi
   {
     AffineAMVPInfo affineAMVPInfo;
     PU::fillAffineMvpCand(pu, RefPicList(refListForAMVP), refIdxForAMVP, affineAMVPInfo);
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    amvpInfo.numCand = (affineAMVPInfo.numCand <= AMVP_MAX_NUM_CANDS) ? affineAMVPInfo.numCand : AMVP_MAX_NUM_CANDS;
+    for (int i = 0; i < amvpInfo.numCand; i++) 
+    {
+      amvpInfo.mvCand[i] = affineAMVPInfo.mvCandLT[i];
+    }
+#else
     amvpInfo.numCand = affineAMVPInfo.numCand;
     memcpy(amvpInfo.mvCand, affineAMVPInfo.mvCandLT, sizeof(amvpInfo.mvCand));
+#endif
   }
   else
   {
@@ -31232,7 +31799,6 @@ AMVPInfo PU::getMultiHypMVPCands(PredictionUnit &pu, const MultiHypPredictionDat
   CHECK(MHRefPics.empty(), "Multi Hyp: MHRefPics.empty()");
   const auto eRefPicList = RefPicList(MHRefPics[mhRefIdxForAMVPList].refList);
   const int iRefIdx = MHRefPics[mhRefIdxForAMVPList].refIdx;
-
   return (pu.mergeFlag ? PU::getMultiHypMVPCandsMerge : PU::getMultiHypMVPCandsAMVP)(pu, eRefPicList, iRefIdx);
 }
 
diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h
index cee2761cc416394ccd0ec33fb7f2cfe96fc753f0..981d4e0e615f1ab634f1b94ee6a80afe1549cea6 100644
--- a/source/Lib/CommonLib/UnitTools.h
+++ b/source/Lib/CommonLib/UnitTools.h
@@ -493,7 +493,11 @@ namespace PU
 #else
   void fillIBCMvpCand                 (PredictionUnit &pu, AMVPInfo &amvpInfo);
 #endif
-  void fillAffineMvpCand              (      PredictionUnit &pu, const RefPicList &eRefPicList, const int &refIdx, AffineAMVPInfo &affiAMVPInfo);
+  void fillAffineMvpCand              (      PredictionUnit &pu, const RefPicList &eRefPicList, const int &refIdx, AffineAMVPInfo &affiAMVPInfo
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+    , InterPrediction* interPred = nullptr
+#endif
+  );
   bool addMVPCandUnscaled             (const PredictionUnit &pu, const RefPicList &eRefPicList, const int &iRefIdx, const Position &pos, const MvpDir &eDir, AMVPInfo &amvpInfo);
   void xInheritedAffineMv             ( const PredictionUnit &pu, const PredictionUnit* puNeighbour, RefPicList eRefPicList, Mv rcMv[3] );
 #if JVET_AA0107_RMVF_AFFINE_MERGE_DERIVATION
@@ -929,6 +933,26 @@ namespace PU
 #if JVET_AF0163_TM_SUBBLOCK_REFINEMENT
   bool checkAffineTMCondition(const PredictionUnit& pu);
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  enum ExtAffineAmvpType
+  {
+    EXT_AFFINE_AMVP_TYPE_NONE = 0,
+    EXT_AFFINE_AMVP_TYPE_NA_TEMP = 1,
+    EXT_AFFINE_AMVP_TYPE_LISTS10 = (1 << 8) + (1 << 4) + 1,
+    EXT_AFFINE_AMVP_TYPE_LISTS4 = (2 << 8) + (1 << 4) + 1,
+    EXT_AFFINE_AMVP_TYPE_LISTS5 = (3 << 8) + (1 << 4) + 1,
+    EXT_AFFINE_AMVP_TYPE_LISTS4_REORDER_FIRST =  (2 << 8) + (2 << 4) + 1
+  };
+  enum ExtRegularAmvpType
+  {
+    EXT_REGULAR_AMVP_TYPE_NONE = 0,
+    EXT_REGULAR_AMVP_TYPE_NA_SPATIAL = (1 << 4),
+    EXT_REGULAR_AMVP_TYPE_LISTS10 = (1 << 4) + 1
+  };
+  int checkExtAffineAmvpCondition(const PredictionUnit& pu);
+  int checkExtRegularAmvpCondition(const PredictionUnit& pu);
+#endif
+
 #if INTER_LIC
   void spanLicFlags(PredictionUnit &pu, const bool LICFlag);
 #endif
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index 920b902b64ad4ef254b8913d4ab439144bc97ebd..2481c9f29523ee404850ab9d3ec24d235fe6ea08 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -2184,7 +2184,6 @@ void CABACReader::cu_pred_data( CodingUnit &cu )
     return;
   }
   MergeCtx mrgCtx;
-
   for( auto &pu : CU::traversePUs( cu ) )
   {
 #if JVET_AD0140_MVD_PREDICTION
diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp
index b6d14b321e96f237a5feec76e86a2e88f3bd8d24..27abad62dd791be910b9fea1cad801e59f1707bb 100644
--- a/source/Lib/DecoderLib/DecCu.cpp
+++ b/source/Lib/DecoderLib/DecCu.cpp
@@ -5247,6 +5247,9 @@ void DecCu::xDeriveCUMV(CodingUnit &cu)
 #endif
 #if JVET_AC0185_ENHANCED_TEMPORAL_MOTION_DERIVATION
         m_pcInterPred->clearAmvpTmvpBuffer();
+#endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+        m_pcInterPred->clearAffineAmvpBuffer();
 #endif
         if (pu.cu->affine)
         {
@@ -5374,7 +5377,6 @@ void DecCu::xDeriveCUMV(CodingUnit &cu)
           pu.refIdx[refListAmvp] = orgRefIdxAMVP;
         }
 #endif
-
         if( pu.cu->affine )
         {
           for ( uint32_t uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++ )
@@ -5383,8 +5385,11 @@ void DecCu::xDeriveCUMV(CodingUnit &cu)
             if ( pu.cs->slice->getNumRefIdx( eRefList ) > 0 && ( pu.interDir & ( 1 << uiRefListIdx ) ) )
             {
               AffineAMVPInfo affineAMVPInfo;
-              PU::fillAffineMvpCand( pu, eRefList, pu.refIdx[eRefList], affineAMVPInfo );
-
+              PU::fillAffineMvpCand( pu, eRefList, pu.refIdx[eRefList], affineAMVPInfo 
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+                , m_pcInterPred
+#endif  
+              );
               const unsigned mvpIdx = pu.mvpIdx[eRefList];
 
               pu.mvpNum[eRefList] = affineAMVPInfo.numCand;
diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp
index e7808d117be586970ebb895481261e369cb1c4c9..69db99fb37d50587ae613116b1f5a0790fcb9684 100644
--- a/source/Lib/DecoderLib/DecSlice.cpp
+++ b/source/Lib/DecoderLib/DecSlice.cpp
@@ -520,6 +520,14 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
 #endif
 #endif
 
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  if (!slice->isIntra())
+  {
+    int picH = slice->getPic()->getPicHeightInLumaSamples();
+    slice->setExtAmvpLevel(picH >= 2160 ? 3 : (picH >= 1080 ? 2 : (picH >= 720 ? 1 : 0)));
+  }
+#endif
+
   // for every CTU in the slice segment...
 
 #if JVET_Z0135_TEMP_CABAC_WIN_WEIGHT
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index f974db44538cd4898d9ee7e5f2a9a49e3424a7e4..99ce96ca89cb0b9b8998a778595a0ebba4b4deff 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -2625,7 +2625,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
   READ_FLAG( uiCode, "sps_alt_cost_enabled_flag");                  pcSPS->setUseAltCost(uiCode != 0);
 #endif
-
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  READ_FLAG( uiCode, "sps_ext_amvp_enabled_flag");                  pcSPS->setUseExtAmvp(uiCode != 0);
+#endif
   READ_FLAG( uiCode,    "sps_bcw_enabled_flag" );                   pcSPS->setUseBcw( uiCode != 0 );
   READ_FLAG( uiCode,     "sps_ciip_enabled_flag" );                           pcSPS->setUseCiip             ( uiCode != 0 );
 #if JVET_X0141_CIIP_TIMD_TM && TM_MRG
@@ -5432,7 +5434,6 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, PicHeader* picHeader, Par
       pcSlice->setCabacInitFlag( uiCode ? true : false );
       pcSlice->setEncCABACTableIdx( pcSlice->getSliceType() == B_SLICE ? ( uiCode ? P_SLICE : B_SLICE ) : ( uiCode ? B_SLICE : P_SLICE ) );
     }
-
     if ( picHeader->getEnableTMVPFlag() )
     {
       if( pcSlice->getSliceType() == P_SLICE )
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 616369020a22ab7bf9eddaa436d81378558df2ae..8658c980a5ab96a85e1220b1cf7fc5ef4a95a3a1 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -430,6 +430,9 @@ protected:
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
   bool      m_useAltCost;
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  bool      m_useExtAmvp;
+#endif
 #if JVET_AF0163_TM_SUBBLOCK_REFINEMENT
   bool      m_useAffineTM; 
 #if JVET_AG0276_NLIC
@@ -1618,6 +1621,10 @@ public:
   void      setUseAltCost(bool b)                            { m_useAltCost = b; }
   bool      getUseAltCost()                            const { return m_useAltCost; }
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  void      setUseExtAmvp(bool b)                            { m_useExtAmvp = b; }
+  bool      getUseExtAmvp()                            const { return m_useExtAmvp; }
+#endif
 #if JVET_AF0163_TM_SUBBLOCK_REFINEMENT
   void      setUseAffineTM( bool b )                         { m_useAffineTM = b; }
   bool      getUseAffineTM()                           const { return  m_useAffineTM; }
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index 4b27948fbd737786ae9a2356c6f0043142b9d13e..a9a7b41a57eba12102bad3053724958e8e519dd7 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -1348,6 +1348,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 
 
   m_pcInterSearch->resetSavedAffineMotion();
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  m_pcInterSearch->clearAffineAmvpBuffer();
+#endif
 #if TM_AMVP
   if (!slice.isIntra())
   {
@@ -1492,7 +1495,6 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
       }
 #endif
 #endif
-
       if( ( currTestMode.opts & ETO_IMV ) != 0 )
       {
         const bool skipAltHpelIF = ( int( ( currTestMode.opts & ETO_IMV ) >> ETO_IMV_SHIFT ) == 4 ) && ( bestIntPelCost > 1.25 * bestCS->cost );
@@ -22753,10 +22755,10 @@ void EncCu::xCheckRDCostInter( CodingStructure *&tempCS, CodingStructure *&bestC
 #endif
   tempCS->initStructData( encTestMode.qp );
   m_pcInterSearch->setAffineModeSelected(false);
+
 #if JVET_AD0213_LIC_IMP
   m_pcInterSearch->setDoAffineLic(true);
 #endif
-
   m_pcInterSearch->resetBufferedUniMotions();
   int bcwLoopNum = (tempCS->slice->isInterB() ? BCW_NUM : 1);
   bcwLoopNum = (tempCS->sps->getUseBcw() ? bcwLoopNum : 1);
@@ -22925,6 +22927,7 @@ void EncCu::xCheckRDCostInter( CodingStructure *&tempCS, CodingStructure *&bestC
 #else
   m_pcInterSearch->predInterSearch( cu, partitioner );
 #endif
+
 #if INTER_LIC
   if (cu.slice->getUseLIC() && lic) { m_pcInterSearch->swapUniMvBuffer(); }
 #endif
@@ -23433,10 +23436,10 @@ bool EncCu::xCheckRDCostInterIMV(CodingStructure *&tempCS, CodingStructure *&bes
 #else
   m_pcInterSearch->predInterSearch( cu, partitioner );
 #endif
+
 #if INTER_LIC
   if (cu.slice->getUseLIC() && lic) { m_pcInterSearch->swapUniMvBuffer(); }
 #endif
-
   if ( cu.firstPU->interDir <= 3 )
   {
     bcwIdx = CU::getValidBcwIdx(cu);
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index d3209d48c5d0393c47f9c28c089ee38f79578fb2..7d7f97fab6e56e20674996fdba490e9c399739cb 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -1904,6 +1904,9 @@ void EncLib::xInitSPS( SPS& sps )
     }
   }
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  sps.setUseExtAmvp            ( m_useExtAmvp );
+#endif
 #if JVET_AF0163_TM_SUBBLOCK_REFINEMENT
   sps.setUseAffineTM           ( m_useAffineTM );
 #if JVET_AG0276_NLIC
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index b61088704df6c3edfa2c90cd38390d6d0b9791fc..ff5ae80e52c6129405eaca997552d08bcac115de 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -1719,6 +1719,13 @@ void EncSlice::compressSlice( Picture* pcPic, const bool bCompressEntireSlice, c
     pcSlice->setAmvpSbTmvpEnabledFlag(false);
   }
 #endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  if (!pcSlice->isIntra())
+  {
+    int picH = pcSlice->getPic()->getPicHeightInLumaSamples();
+    pcSlice->setExtAmvpLevel(picH >= 2160 ? 3 : (picH >= 1080 ? 2 : (picH >= 720 ? 1 : 0)));
+  }
+#endif
 
   if ( bWp_explicit )
   {
diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp
index 05a4785072ddc40780d1d0bf356826b210d270f1..e05a6c3e57db0b65980a0b6deb3ec90fae020cc0 100644
--- a/source/Lib/EncoderLib/InterSearch.cpp
+++ b/source/Lib/EncoderLib/InterSearch.cpp
@@ -6042,7 +6042,6 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
 #if JVET_AD0213_LIC_IMP && TM_AMVP
   resetLicEncCtrlPara();
 #endif
-
 #if MULTI_HYP_PRED
   const bool saveMeResultsForMHP = cs.sps->getUseInterMultiHyp()
     && bcwIdx != BCW_DEFAULT
@@ -6333,7 +6332,6 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           uiMotBits[1] = uiBits[1] - uiMbBits[1];
           uiBits[2] = uiMbBits[2] + uiMotBits[0] + uiMotBits[1];
         }
-
         if( doBiPred )
         {
         // 4-times iteration (default)
@@ -6344,6 +6342,8 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
         {
           iNumIter = 1;
         }
+
+
 #if JVET_X0083_BM_AMVP_MERGE_MODE
         if (amvpMergeModeFlag)
         {
@@ -6404,7 +6404,6 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           }
 
           bool bChanged = false;
-
           iRefStart = 0;
           iRefEnd   = cs.slice->getNumRefIdx(eRefPicList)-1;
           for (int iRefIdxTemp = iRefStart; iRefIdxTemp <= iRefEnd; iRefIdxTemp++)
@@ -6429,6 +6428,7 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
             xCopyAMVPInfo( &amvp[refListAmvp], &aacAMVPInfo[refListAmvp][iRefIdxTemp]); // must always be done ( also when AMVP_MODE = AM_NONE )
             numberBestMvpIdxLoop = amvp[eRefPicList].numCand;
           }
+
           for (int bestMvpIdxLoop = 0; bestMvpIdxLoop < numberBestMvpIdxLoop; bestMvpIdxLoop++)
           {
             if (amvpMergeModeFlag)
@@ -6680,7 +6680,6 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
         }
         cu.refIdxBi[0] = iRefIdxBi[0];
         cu.refIdxBi[1] = iRefIdxBi[1];
-
         if ( cs.slice->getBiDirPred() && trySmvd )
         {
           Distortion symCost;
@@ -6889,7 +6888,6 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           }
         }
       } // if (B_SLICE)
-
 #if JVET_AG0098_AMVP_WITH_SBTMVP
       bool       useAmvpSbTmvpBuf = false;
       int        amvpSbTmvpMvdIdx = -1;
@@ -7419,6 +7417,7 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
     }
 #endif
 #if INTER_LIC
+
 #if JVET_X0083_BM_AMVP_MERGE_MODE && JVET_AD0213_LIC_IMP
 #if JVET_AG0098_AMVP_WITH_SBTMVP
     if (cu.licFlag && !amvpMergeModeFlag && !pu.amvpSbTmvpFlag)
@@ -7696,7 +7695,12 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           && (pu.interDir & (1 << uiRefListIdx)) && (absMvd[0] != Mv(0, 0) || absMvd[1] != Mv(0, 0) || absMvd[2] != Mv(0, 0)) && pu.isMvdPredApplicable())
         {
           AffineAMVPInfo affineAMVPInfo;
-          PU::fillAffineMvpCand(pu, eRefPicList, pu.refIdx[uiRefListIdx], affineAMVPInfo);
+          PU::fillAffineMvpCand(pu, eRefPicList, pu.refIdx[uiRefListIdx], affineAMVPInfo
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+            , this
+#endif    
+          );
+
           const unsigned mvpIdx = pu.mvpIdx[eRefPicList];
 
 #if JVET_AD0140_MVD_PREDICTION
@@ -7760,7 +7764,6 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
         }
       }
 #endif
-
       for (uint32_t uiRefListIdx = 0; uiRefListIdx < 2; uiRefListIdx++)
       {
         RefPicList eRefPicList = RefPicList(uiRefListIdx);
@@ -7778,6 +7781,7 @@ void InterSearch::predInterSearch(CodingUnit& cu, Partitioner& partitioner)
           {
             PU::fillMvpCand(pu, RefPicList(uiRefListIdx), iRefIdx, *amvpCand, this);
           }
+
           Mv cMvPred2 = amvpCand->mvCand[pu.mvpIdx[uiRefListIdx]];
 #else
           auto aMvPred = bi ? cMvPredBi : cMvPred;
@@ -10446,6 +10450,7 @@ void InterSearch::xPatternSearchIntRefine(PredictionUnit& pu, IntTZSearchStruct&
 
   cBaseMvd[0] = (rcMv - amvpInfo.mvCand[0]);
   cBaseMvd[1] = (rcMv - amvpInfo.mvCand[1]);
+
   CHECK( (cBaseMvd[0].getHor() & 0x03) != 0 || (cBaseMvd[0].getVer() & 0x03) != 0 , "xPatternSearchIntRefine(): AMVP cand 0 Mvd issue.");
   CHECK( (cBaseMvd[1].getHor() & 0x03) != 0 || (cBaseMvd[1].getVer() & 0x03) != 0 , "xPatternSearchIntRefine(): AMVP cand 1 Mvd issue.");
 
@@ -11259,6 +11264,7 @@ void InterSearch::xPredAffineInterSearch( PredictionUnit&       pu,
     {
     // 4-times iteration (default)
     int iNumIter = 4;
+
     // fast encoder setting or GPB: only one iteration
     if ( m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE1 || m_pcEncCfg->getFastInterSearchMode()==FASTINTERSEARCH_MODE2 || slice.getPicHeader()->getMvdL1ZeroFlag() )
     {
@@ -11724,9 +11730,7 @@ void InterSearch::xCheckBestAffineMVP( PredictionUnit &pu, AffineAMVPInfo &affin
   {
     return;
   }
-
   int mvNum = pu.cu->affineType ? 3 : 2;
-
   m_pcRdCost->selectMotionLambda( );
   m_pcRdCost->setCostScale ( 0 );
 
@@ -12293,7 +12297,12 @@ void InterSearch::xEstimateAffineAMVP( PredictionUnit&  pu,
   Distortion uiBestCost = std::numeric_limits<Distortion>::max();
 
   // Fill the MV Candidates
-  PU::fillAffineMvpCand( pu, eRefPicList, iRefIdx, affineAMVPInfo );
+  PU::fillAffineMvpCand( pu, eRefPicList, iRefIdx, affineAMVPInfo 
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+                , this
+#endif 
+  );
+
   CHECK( affineAMVPInfo.numCand == 0, "Assertion failed." );
 
   PelUnitBuf predBuf = m_tmpStorageLCU.getBuf( UnitAreaRelative(*pu.cu, pu) );
@@ -12324,6 +12333,7 @@ void InterSearch::xEstimateAffineAMVP( PredictionUnit&  pu,
 
   pu.mvpIdx[eRefPicList] = iBestIdx;
   pu.mvpNum[eRefPicList] = affineAMVPInfo.numCand;
+
   DTRACE( g_trace_ctx, D_COMMON, "#estAffi=%d \n", affineAMVPInfo.numCand );
 }
 
@@ -16367,7 +16377,6 @@ void InterSearch::setEncCtrlParaLicOff(CodingUnit& cu)
 {
   CodingStructure& cs = *cu.cs;
   PredictionUnit&  pu = *cu.firstPU;
-
   isBDOFNotNeeded = (pu.interDir == 1 || pu.interDir == 2 || pu.cu->bcwIdx != BCW_DEFAULT || pu.cu->affine || pu.cu->smvdMode);
   amvpCand0 = &(m_tplAmvpInfo[cu.imv][REF_PIC_LIST_0][pu.refIdx[REF_PIC_LIST_0]]);
   amvpCand1 = &(m_tplAmvpInfo[cu.imv][REF_PIC_LIST_1][pu.refIdx[REF_PIC_LIST_1]]);
@@ -16375,6 +16384,7 @@ void InterSearch::setEncCtrlParaLicOff(CodingUnit& cu)
   amvpCand1Lic = &(m_tplAmvpInfoLIC[cu.imv][REF_PIC_LIST_1][pu.refIdx[REF_PIC_LIST_1]]);
   mvpIdx0 = pu.mvpIdx[REF_PIC_LIST_0];
   mvpIdx1 = pu.mvpIdx[REF_PIC_LIST_1];
+
   if (!cu.affine)
   {
     for (int refList = 0; refList < NUM_REF_PIC_LIST_01; refList++)
@@ -16399,7 +16409,6 @@ void InterSearch::setEncCtrlParaLicOff(CodingUnit& cu)
         pu.cu->licFlag = true;
       }
     }
-
     if (cs.picHeader->getMvdL1ZeroFlag() && pu.interDir == 3)
     {
       if (amvpCand1Lic->mvCand[mvpIdx1] != amvpCand1->mvCand[mvpIdx1])
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index bdb2d71d23654628a9d1001ee3451c316293773d..102e0f83a46eee5fac4eebb66634f9b9699ec1d1 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -1666,6 +1666,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
 
 #if JVET_AI0185_ADAPTIVE_COST_IN_MERGE_MODE
   WRITE_FLAG(pcSPS->getUseAltCost() ? 1 : 0, "sps_alt_cost_enabled_flag");
+#endif
+#if JVET_AJ0126_INTER_AMVP_ENHANCEMENT
+  WRITE_FLAG(pcSPS->getUseExtAmvp() ? 1 : 0, "sps_ext_amvp_enabled_flag");
 #endif
   WRITE_FLAG(pcSPS->getUseBcw() ? 1 : 0, "sps_bcw_enabled_flag");