From 63e384ecaf769b60b1cbb18409f501b4b1cb4de6 Mon Sep 17 00:00:00 2001
From: Adam Wieckowski <adam.wieckowski@hhi.fraunhofer.de>
Date: Mon, 4 Mar 2019 18:19:25 +0100
Subject: [PATCH] refactored history based merge candidates

---
 source/Lib/CommonLib/CodingStructure.cpp |  31 ++++
 source/Lib/CommonLib/CodingStructure.h   |   4 +
 source/Lib/CommonLib/MotionInfo.h        |  11 +-
 source/Lib/CommonLib/Slice.cpp           | 165 --------------------
 source/Lib/CommonLib/Slice.h             |  29 ----
 source/Lib/CommonLib/TypeDef.h           |   5 +
 source/Lib/CommonLib/UnitTools.cpp       |  57 +++----
 source/Lib/CommonLib/UnitTools.h         |   4 +-
 source/Lib/DecoderLib/DecCu.cpp          |  18 ++-
 source/Lib/DecoderLib/DecLib.cpp         |   1 -
 source/Lib/DecoderLib/DecSlice.cpp       |  11 +-
 source/Lib/EncoderLib/EncCu.cpp          | 183 ++++-------------------
 source/Lib/EncoderLib/EncCu.h            |  14 +-
 source/Lib/EncoderLib/EncSlice.cpp       |  11 +-
 14 files changed, 134 insertions(+), 410 deletions(-)

diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp
index bf711f3ba..fd2324745 100644
--- a/source/Lib/CommonLib/CodingStructure.cpp
+++ b/source/Lib/CommonLib/CodingStructure.cpp
@@ -708,6 +708,31 @@ void CodingStructure::createInternals( const UnitArea& _unit, const bool isTopLa
   initStructData();
 }
 
+void CodingStructure::addMiToLut(static_vector<MotionInfo, MAX_NUM_HMVP_CANDS> &lut, const MotionInfo &mi)
+{
+  size_t currCnt = lut.size();
+
+  bool pruned      = false;
+  int  sameCandIdx = 0;
+
+  for (int idx = 0; idx < currCnt; idx++)
+  {
+    if (lut[idx] == mi)
+    {
+      sameCandIdx = idx;
+      pruned      = true;
+      break;
+    }
+  }
+
+  if (pruned || currCnt == lut.capacity())
+  {
+    lut.erase(lut.begin() + sameCandIdx);
+  }
+
+  lut.push_back(mi);
+}
+
 void CodingStructure::rebindPicBufs()
 {
   CHECK( parent, "rebindPicBufs can only be used for the top level CodingStructure" );
@@ -785,6 +810,8 @@ void CodingStructure::initSubStructure( CodingStructure& subStruct, const Channe
 
   subStruct.m_isTuEnc = isTuEnc;
 
+  subStruct.motionLut = motionLut;
+
   subStruct.initStructData( currQP[_chType], isLossless );
 
   if( isTuEnc )
@@ -847,6 +874,8 @@ void CodingStructure::useSubStructure( const CodingStructure& subStruct, const C
     CMotionBuf subMB = subStruct.getMotionBuf( clippedArea );
 
     ownMB.copyFrom( subMB );
+
+    motionLut = subStruct.motionLut;
   }
 #if ENABLE_WPP_PARALLELISM
 
@@ -1037,6 +1066,8 @@ void CodingStructure::copyStructure( const CodingStructure& other, const Channel
     CMotionBuf subMB = other.getMotionBuf();
 
     ownMB.copyFrom( subMB );
+
+    motionLut = other.motionLut;
   }
 
   if( copyTUs )
diff --git a/source/Lib/CommonLib/CodingStructure.h b/source/Lib/CommonLib/CodingStructure.h
index 67ca6d947..6dace0a70 100644
--- a/source/Lib/CommonLib/CodingStructure.h
+++ b/source/Lib/CommonLib/CodingStructure.h
@@ -211,6 +211,10 @@ public:
   std::vector<PredictionUnit*> pus;
   std::vector< TransformUnit*> tus;
 
+  LutMotionCand motionLut;
+
+  void addMiToLut(static_vector<MotionInfo, MAX_NUM_HMVP_CANDS>& lut, const MotionInfo &mi);
+
 private:
 
   // needed for TU encoding
diff --git a/source/Lib/CommonLib/MotionInfo.h b/source/Lib/CommonLib/MotionInfo.h
index 2bc0f935d..f8d51f109 100644
--- a/source/Lib/CommonLib/MotionInfo.h
+++ b/source/Lib/CommonLib/MotionInfo.h
@@ -259,10 +259,15 @@ public:
 };
 struct LutMotionCand
 {
-  MotionInfo*   motionCand;
-  int  currCnt;
+  static_vector<MotionInfo, MAX_NUM_HMVP_CANDS> lut;
 #if JVET_M0483_IBC
-  int  currCntIBC;
+  static_vector<MotionInfo, MAX_NUM_HMVP_CANDS> lutIbc;
+#endif
+#if JVET_M0170_MRG_SHARELIST
+  static_vector<MotionInfo, MAX_NUM_HMVP_CANDS> lutShare;
+#if JVET_M0483_IBC
+  static_vector<MotionInfo, MAX_NUM_HMVP_CANDS> lutShareIbc;
+#endif
 #endif
 };
 #endif // __MOTIONINFO__
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index 7debb8476..be8938577 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -139,10 +139,6 @@ Slice::Slice()
 , m_uiMaxBTSizeIChroma            ( 0 )
 , m_uiMaxTTSizeIChroma            ( 0 )
 , m_uiMaxBTSize                   ( 0 )
-, m_MotionCandLut                (NULL)
-#if  JVET_M0170_MRG_SHARELIST
-, m_MotionCandLuTsBkup           (NULL)
-#endif
 {
   for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
   {
@@ -179,8 +175,6 @@ Slice::Slice()
     m_saoEnabledFlag[ch] = false;
   }
 
-  initMotionLUTs();
-
 #if JVET_M0427_INLOOP_RESHAPER
   m_sliceReshapeInfo.setUseSliceReshaper(false);
   m_sliceReshapeInfo.setSliceReshapeModelPresentFlag(false);
@@ -193,7 +187,6 @@ Slice::Slice()
 
 Slice::~Slice()
 {
-  destroyMotionLUTs();
 }
 
 
@@ -233,7 +226,6 @@ void Slice::initSlice()
   m_cabacInitFlag        = false;
   m_cabacWinUpdateMode   = 0;
   m_enableTMVPFlag       = true;
-  resetMotionLUTs();
 }
 
 void Slice::setDefaultClpRng( const SPS& sps )
@@ -1653,163 +1645,6 @@ void Slice::stopProcessingTimer()
   m_dProcessingTime += (double)(clock()-m_iProcessingStartTime) / CLOCKS_PER_SEC;
   m_iProcessingStartTime = 0;
 }
-void Slice::initMotionLUTs()
-{
-  m_MotionCandLut = new LutMotionCand;
-  m_MotionCandLut->currCnt = 0;
-#if JVET_M0483_IBC
-  m_MotionCandLut->currCntIBC = 0;
-#endif
-  m_MotionCandLut->motionCand = nullptr;
-#if JVET_M0483_IBC
-  m_MotionCandLut->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS * 2];
-#else
-  m_MotionCandLut->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS];
-#endif
-#if  JVET_M0170_MRG_SHARELIST
-  m_MotionCandLuTsBkup = new LutMotionCand;
-  m_MotionCandLuTsBkup->currCnt = 0;
-#if JVET_M0483_IBC
-  m_MotionCandLuTsBkup->currCntIBC = 0;
-#endif
-  m_MotionCandLuTsBkup->motionCand = nullptr;
-#if JVET_M0483_IBC
-  m_MotionCandLuTsBkup->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS * 2];
-#else
-  m_MotionCandLuTsBkup->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS];
-#endif
-#endif
-}
-void Slice::destroyMotionLUTs()
-{
-  delete[] m_MotionCandLut->motionCand;
-  m_MotionCandLut->motionCand = nullptr;
-  delete m_MotionCandLut;
-  m_MotionCandLut = NULL;
-#if  JVET_M0170_MRG_SHARELIST
-  delete[] m_MotionCandLuTsBkup->motionCand;
-  m_MotionCandLuTsBkup->motionCand = nullptr;
-  delete m_MotionCandLuTsBkup;
-  m_MotionCandLuTsBkup = NULL;
-#endif
-}
-void Slice::resetMotionLUTs()
-{
-  m_MotionCandLut->currCnt = 0;
-#if JVET_M0483_IBC
-  m_MotionCandLut->currCntIBC = 0;
-#endif
-#if  JVET_M0170_MRG_SHARELIST
-  m_MotionCandLuTsBkup->currCnt = 0;
-#if JVET_M0483_IBC
-  m_MotionCandLuTsBkup->currCntIBC = 0;
-#endif
-#endif
-}
-
-MotionInfo Slice::getMotionInfoFromLUTs(int MotCandIdx) const
-{
-  return m_MotionCandLut->motionCand[MotCandIdx];
-}
-#if JVET_M0170_MRG_SHARELIST
-MotionInfo Slice::getMotionInfoFromLUTBkup(int MotCandIdx) const
-{
-  return m_MotionCandLuTsBkup->motionCand[MotCandIdx];
-}
-#endif
-
-#if JVET_M0483_IBC
-void Slice::addMotionInfoToLUTs(LutMotionCand* lutMC, MotionInfo newMi, bool ibcflag)
-#else
-void Slice::addMotionInfoToLUTs(LutMotionCand* lutMC, MotionInfo newMi)
-#endif
-{
-#if JVET_M0483_IBC
-  int currCntIBC = ibcflag ? lutMC->currCntIBC : lutMC->currCnt;
-  int offset = ibcflag ? MAX_NUM_HMVP_CANDS : 0;
-  bool pruned = false;
-  int  sameCandIdx = 0;
-  for (int idx = 0; idx < currCntIBC; idx++)
-  {
-    if (lutMC->motionCand[idx + offset] == newMi)
-    {
-      sameCandIdx = idx;
-      pruned = true;
-      break;
-    }
-  }
-  if (pruned || currCntIBC == MAX_NUM_HMVP_CANDS)
-  {
-    memmove(&lutMC->motionCand[sameCandIdx + offset], &lutMC->motionCand[sameCandIdx + offset + 1],
-      sizeof(MotionInfo) * (currCntIBC - sameCandIdx - 1));
-    memcpy(&lutMC->motionCand[currCntIBC + offset - 1], &newMi, sizeof(MotionInfo));
-  }
-  else
-  {
-    if (ibcflag)
-    {
-      memcpy(&lutMC->motionCand[currCntIBC + offset], &newMi, sizeof(MotionInfo));
-      lutMC->currCntIBC++;
-    }
-    else
-    {
-      memcpy(&lutMC->motionCand[currCntIBC], &newMi, sizeof(MotionInfo));
-      lutMC->currCnt++;
-    }
-  }
-#else
-  int currCnt = lutMC->currCnt ;
-
-  bool pruned = false;
-  int  sameCandIdx = 0;
-  for (int idx = 0; idx < currCnt; idx++)
-  {
-    if (lutMC->motionCand[idx] == newMi)
-    {
-      sameCandIdx = idx;
-      pruned = true;
-      break;
-    }
-  }
-  if (pruned || lutMC->currCnt == MAX_NUM_HMVP_CANDS)
-  {
-    memmove(&lutMC->motionCand[sameCandIdx], &lutMC->motionCand[sameCandIdx + 1],
-            sizeof(MotionInfo) * (currCnt - sameCandIdx - 1));
-    memcpy(&lutMC->motionCand[lutMC->currCnt-1], &newMi, sizeof(MotionInfo));
-  }
-  else
-  {
-    memcpy(&lutMC->motionCand[lutMC->currCnt++], &newMi, sizeof(MotionInfo));
-  }
-#endif
-}
-
-void Slice::updateMotionLUTs(LutMotionCand* lutMC, CodingUnit & cu)
-{
-  PredictionUnit *selectedPU = cu.firstPU;
-  if (cu.affine) { return; }
-  if (cu.triangle) { return; }
-
-  MotionInfo newMi = selectedPU->getMotionInfo();
-#if JVET_M0264_HMVP_WITH_GBIIDX
-  newMi.GBiIdx = (newMi.interDir == 3) ? cu.GBiIdx : GBI_DEFAULT;
-#endif
-#if JVET_M0483_IBC
-  addMotionInfoToLUTs(lutMC, newMi, CU::isIBC(cu));
-#else
-  addMotionInfoToLUTs(lutMC, newMi);
-#endif
-}
-
-void Slice::copyMotionLUTs(LutMotionCand* Src, LutMotionCand* Dst)
-{
-   memcpy(Dst->motionCand, Src->motionCand, sizeof(MotionInfo)*(std::min(Src->currCnt, MAX_NUM_HMVP_CANDS)));
-   Dst->currCnt = Src->currCnt;
-#if JVET_M0483_IBC
-   memcpy(Dst->motionCand + MAX_NUM_HMVP_CANDS, Src->motionCand + MAX_NUM_HMVP_CANDS, sizeof(MotionInfo)*(std::min(Src->currCntIBC, MAX_NUM_HMVP_CANDS)));
-   Dst->currCntIBC = Src->currCntIBC;
-#endif
-}
 
 unsigned Slice::getMinPictureDistance() const
 {
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index c6ba1c140..778eebb3a 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -1721,14 +1721,9 @@ private:
   uint32_t                       m_uiMaxBTSize;
 
   AlfSliceParam              m_alfSliceParam;
-  LutMotionCand*             m_MotionCandLut;
 #if JVET_M0427_INLOOP_RESHAPER
   SliceReshapeInfo           m_sliceReshapeInfo;
 #endif
-#if JVET_M0170_MRG_SHARELIST
-public:
-  LutMotionCand*             m_MotionCandLuTsBkup;
-#endif
 public:
                               Slice();
   virtual                     ~Slice();
@@ -2009,31 +2004,7 @@ public:
 
   void                        setAlfSliceParam( AlfSliceParam& alfSliceParam ) { m_alfSliceParam = alfSliceParam; }
   AlfSliceParam&              getAlfSliceParam() { return m_alfSliceParam; }
-  void                        initMotionLUTs       ();
-  void                        destroyMotionLUTs    ();
-  void                        resetMotionLUTs();
-#if JVET_M0483_IBC
-  int                         getAvailableLUTIBCMrgNum() const { return m_MotionCandLut->currCntIBC; }
-#endif
-  int                         getAvailableLUTMrgNum() const  { return m_MotionCandLut->currCnt; }
-#if JVET_M0170_MRG_SHARELIST
-  int                         getAvailableLUTBkupMrgNum() const  { return m_MotionCandLuTsBkup->currCnt; }
-  MotionInfo                  getMotionInfoFromLUTBkup(int MotCandIdx) const;
-#if JVET_M0483_IBC
-  int                         getAvailableLUTBkupIBCMrgNum() const { return m_MotionCandLuTsBkup->currCntIBC; }
-#endif
-#endif
-  MotionInfo                  getMotionInfoFromLUTs(int MotCandIdx) const;
-  LutMotionCand*              getMotionLUTs() { return m_MotionCandLut; }
-
-#if JVET_M0483_IBC
-  void                        addMotionInfoToLUTs(LutMotionCand* lutMC, MotionInfo newMi, bool ibcflag);
-#else
-  void                        addMotionInfoToLUTs(LutMotionCand* lutMC, MotionInfo newMi);
-#endif
 
-  void                        updateMotionLUTs(LutMotionCand* lutMC, CodingUnit & cu);
-  void                        copyMotionLUTs(LutMotionCand* Src, LutMotionCand* Dst);
 #if JVET_M0427_INLOOP_RESHAPER
   const SliceReshapeInfo&     getReshapeInfo() const { return m_sliceReshapeInfo; }
         SliceReshapeInfo&     getReshapeInfo()       { return m_sliceReshapeInfo; }
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 3f1e7d90b..ceca9ddcf 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -1424,6 +1424,11 @@ public:
                                                   for ( int k = 0; k < numEl; k++) *it++ = val;
                                                   return const_cast<iterator>( _pos ); }
 #endif
+
+  void            erase( const_iterator _pos )  { iterator it   = const_cast<iterator>( _pos ) - 1;
+                                                  iterator last = end() - 1;
+                                                  while( ++it != last ) *it = *( it + 1 );
+                                                  _size--; }
 };
 
 
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index df6d906f1..19c674020 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -1016,7 +1016,7 @@ bool PU::xCheckSimilarMotion(const int mergeCandIndex, const int prevCnt, const
 
 #if JVET_L0090_PAIR_AVG
 
-bool PU::addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos
+bool PU::addMergeHMVPCand(const CodingStructure &cs, MergeCtx& mrgCtx, bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos
 #if JVET_M0483_IBC==0
   , int mmvdList
 #endif
@@ -1029,7 +1029,7 @@ bool PU::addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool canFastExit
 )
 #else
 
-bool PU::addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool isCandInter[MRG_MAX_NUM_CANDS], bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos
+bool PU::addMergeHMVPCand(const CodingStructure &cs, MergeCtx& mrgCtx, bool isCandInter[MRG_MAX_NUM_CANDS], bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos
   , int mmvdList
 )
 #endif
@@ -1037,6 +1037,7 @@ bool PU::addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool isCandInter
 #if JVET_M0483_IBC==0
   int mrgCandIdxIBC = mrgCandIdx;
 #endif
+  const Slice& slice = *cs.slice;
   MotionInfo miNeighbor;
   bool hasPruned[MRG_MAX_NUM_CANDS];
   memset(hasPruned, 0, MRG_MAX_NUM_CANDS * sizeof(bool));
@@ -1044,38 +1045,24 @@ bool PU::addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool isCandInter
   {
     hasPruned[subPuMvpPos] = true;
   }
-#if JVET_M0170_MRG_SHARELIST
 #if JVET_M0483_IBC
-  int num_avai_candInLUT = ibcFlag ? (isShared ? slice.getAvailableLUTBkupIBCMrgNum() : slice.getAvailableLUTIBCMrgNum()) : (isShared ? slice.getAvailableLUTBkupMrgNum() : slice.getAvailableLUTMrgNum());
-  int offset = ibcFlag ? MAX_NUM_HMVP_CANDS : 0;
+#if JVET_M0170_MRG_SHARELIST
+  auto &lut = ibcFlag ? ( isShared ? cs.motionLut.lutShareIbc : cs.motionLut.lutIbc ) : ( isShared ? cs.motionLut.lutShare : cs.motionLut.lut );
 #else
-  int num_avai_candInLUT = (isShared ? slice.getAvailableLUTBkupMrgNum() : slice.getAvailableLUTMrgNum());
+  auto &lut = ibcFlag ? cs.motionLut.lutIbc : cs.motionLut.lut;
 #endif
 #else
-#if JVET_M0483_IBC
-  int num_avai_candInLUT = ibcFlag ? slice.getAvailableLUTIBCMrgNum() : slice.getAvailableLUTMrgNum();
-  int offset = ibcFlag ? MAX_NUM_HMVP_CANDS : 0;
+#if JVET_M0170_MRG_SHARELIST
+  auto &lut = isShared ? cs.motionLut.lutShare : cs.motionLut.lut;
 #else
-  int num_avai_candInLUT = slice.getAvailableLUTMrgNum();
+  auto &lut = cs.motionLut.lut;
 #endif
 #endif
+  int num_avai_candInLUT = (int) lut.size();
 
   for (int mrgIdx = 1; mrgIdx <= num_avai_candInLUT; mrgIdx++)
   {
-#if JVET_M0170_MRG_SHARELIST
-#if JVET_M0483_IBC
-    miNeighbor = ibcFlag ? (isShared ? slice.getMotionInfoFromLUTBkup(num_avai_candInLUT - mrgIdx + offset) : slice.getMotionInfoFromLUTs(num_avai_candInLUT - mrgIdx + offset))
-      : (isShared ? slice.getMotionInfoFromLUTBkup(num_avai_candInLUT - mrgIdx) : slice.getMotionInfoFromLUTs(num_avai_candInLUT - mrgIdx));
-#else
-    miNeighbor = isShared ? slice.getMotionInfoFromLUTBkup(num_avai_candInLUT - mrgIdx) : slice.getMotionInfoFromLUTs(num_avai_candInLUT - mrgIdx);
-#endif
-#else
-#if JVET_M0483_IBC
-    miNeighbor = slice.getMotionInfoFromLUTs(num_avai_candInLUT - mrgIdx + offset);
-#else
-    miNeighbor = slice.getMotionInfoFromLUTs(num_avai_candInLUT - mrgIdx);
-#endif
-#endif
+    miNeighbor = lut[num_avai_candInLUT - mrgIdx];
     mrgCtx.interDirNeighbours[cnt] = miNeighbor.interDir;
     mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miNeighbor.mv[0], miNeighbor.refIdx[0]);
     if (slice.isInterB())
@@ -1315,7 +1302,7 @@ void PU::getIBCMergeCandidates(const PredictionUnit &pu, MergeCtx& mrgCtx, const
 #endif
 
 #if JVET_L0090_PAIR_AVG
-    bool bFound = addMergeHMVPCand(slice, mrgCtx, canFastExit
+    bool bFound = addMergeHMVPCand(cs, mrgCtx, canFastExit
       , mrgCandIdx
       , maxNumMergeCandMin1, cnt
 #if JVET_M0126_HMVP_MRG_PRUNING
@@ -1859,7 +1846,7 @@ void PU::getInterMergeCandidates( const PredictionUnit &pu, MergeCtx& mrgCtx,
 #if JVET_M0170_MRG_SHARELIST
     bool  isShared = ((pu.Y().lumaSize().width != pu.shareParentSize.width) || (pu.Y().lumaSize().height != pu.shareParentSize.height));
 #endif
-    bool bFound = addMergeHMVPCand(slice, mrgCtx, canFastExit
+    bool bFound = addMergeHMVPCand(cs, mrgCtx, canFastExit
 #if JVET_M0483_IBC==0
       , (mmvdList != 0 && mrgCandIdx != -1) ? (const int) mrgCandIdxIBC : mrgCandIdx
 #else
@@ -3511,11 +3498,11 @@ void PU::addAMVPHMVPCand(const PredictionUnit &pu, const RefPicList eRefPicList,
   int i = 0;
 #endif
 #if JVET_M0483_IBC
-  int offset = CU::isIBC(*pu.cu) ? MAX_NUM_HMVP_CANDS : 0;
-  int num_avai_candInLUT = CU::isIBC(*pu.cu) ? slice.getAvailableLUTIBCMrgNum() : slice.getAvailableLUTMrgNum();
+  auto &lut = CU::isIBC(*pu.cu) ? pu.cs->motionLut.lutIbc : pu.cs->motionLut.lut;
 #else
-  int num_avai_candInLUT = slice.getAvailableLUTMrgNum();
+  auto &lut = pu.cs->motionLut.lut;
 #endif
+  int num_avai_candInLUT = (int) lut.size();
   int num_allowedCand = std::min(MAX_NUM_HMVP_AVMPCANDS, num_avai_candInLUT);
 
   for (int mrgIdx = 1; mrgIdx <= num_allowedCand; mrgIdx++)
@@ -3525,17 +3512,9 @@ void PU::addAMVPHMVPCand(const PredictionUnit &pu, const RefPicList eRefPicList,
       return;
     }
 #if JVET_M0117_AMVP_LIST_GEN
-#if JVET_M0483_IBC
-    neibMi = slice.getMotionInfoFromLUTs(mrgIdx - 1 + offset) ;
+    neibMi = lut[mrgIdx - 1];
 #else
-    neibMi = slice.getMotionInfoFromLUTs(mrgIdx - 1);
-#endif
-#else
-#if JVET_M0483_IBC
-    neibMi = slice.getMotionInfoFromLUTs(num_avai_candInLUT - mrgIdx + offset);
-#else
-    neibMi = slice.getMotionInfoFromLUTs(num_avai_candInLUT - mrgIdx);
-#endif
+    neibMi = lut[num_avai_candInLUT - mrgIdx];
 #endif
 
     for (int predictorSource = 0; predictorSource < 2; predictorSource++)
diff --git a/source/Lib/CommonLib/UnitTools.h b/source/Lib/CommonLib/UnitTools.h
index f285e393b..06b4eefbd 100644
--- a/source/Lib/CommonLib/UnitTools.h
+++ b/source/Lib/CommonLib/UnitTools.h
@@ -157,7 +157,7 @@ namespace PU
   void xInheritedAffineMv             ( const PredictionUnit &pu, const PredictionUnit* puNeighbour, RefPicList eRefPicList, Mv rcMv[3] );
   bool xCheckSimilarMotion(const int mergeCandIndex, const int prevCnt, const MergeCtx mergeCandList, bool hasPruned[MRG_MAX_NUM_CANDS]);
 #if JVET_L0090_PAIR_AVG
-  bool addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos
+  bool addMergeHMVPCand(const CodingStructure &cs, MergeCtx& mrgCtx, bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos
 #if JVET_M0483_IBC==0
     , int mmvdList
 #endif
@@ -169,7 +169,7 @@ namespace PU
 #endif
   );
 #else
-  bool addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool isCandInter[MRG_MAX_NUM_CANDS], bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos
+  bool addMergeHMVPCand(const CodingStructure &cs, MergeCtx& mrgCtx, bool isCandInter[MRG_MAX_NUM_CANDS], bool canFastExit, const int& mrgCandIdx, const uint32_t maxNumMergeCandMin1, int &cnt, const int prevCnt, bool isAvailableSubPu, unsigned subPuMvpPos
 #if JVET_M0483_IBC==0
     , int mmvdList
 #endif
diff --git a/source/Lib/DecoderLib/DecCu.cpp b/source/Lib/DecoderLib/DecCu.cpp
index 9d6b2a035..f3928d67f 100644
--- a/source/Lib/DecoderLib/DecCu.cpp
+++ b/source/Lib/DecoderLib/DecCu.cpp
@@ -131,7 +131,7 @@ void DecCu::decompressCtu( CodingStructure& cs, const UnitArea& ctuArea )
         if ((currCU.shareParentPos.x >= 0) && (!(currCU.shareParentPos.x == prevTmpPos.x && currCU.shareParentPos.y == prevTmpPos.y)))
         {
           m_shareStateDec = GEN_ON_SHARED_BOUND;
-          cs.slice->copyMotionLUTs(cs.slice->getMotionLUTs(), cs.slice->m_MotionCandLuTsBkup);
+          cs.motionLut.lutShare = cs.motionLut.lut;
         }
 
         if (currCU.shareParentPos.x < 0)
@@ -495,7 +495,21 @@ void DecCu::xReconInter(CodingUnit &cu)
   }
   }
   if (cu.Y().valid())
-  cu.slice->updateMotionLUTs(cu.slice->getMotionLUTs(), cu);
+  {
+    const PredictionUnit &pu = *cu.firstPU;
+    if (!cu.affine && !cu.triangle)
+    {
+      MotionInfo mi = pu.getMotionInfo();
+#if JVET_M0264_HMVP_WITH_GBIIDX
+      mi.GBiIdx = (mi.interDir == 3) ? cu.GBiIdx : GBI_DEFAULT;
+#endif
+#if JVET_M0483_IBC
+      cu.cs->addMiToLut(CU::isIBC(cu) ? cu.cs->motionLut.lutIbc : cu.cs->motionLut.lut, mi );
+#else
+      cu.cs->addMiToLut(cu.cs->motionLut.lut, mi);
+#endif
+    }
+  }
 
   if (cu.firstPU->mhIntraFlag)
   {
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index 58632f096..a64a8f6c8 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -202,7 +202,6 @@ bool tryDecodePicture( Picture* pcEncPic, const int expectedPoc, const std::stri
                   {
                     cu->slice = pcEncPic->cs->slice;
                   }
-                  pcEncPic->cs->slice->copyMotionLUTs( pic->slices.back()->getMotionLUTs(), pcEncPic->slices.back()->getMotionLUTs());
                 }
                 else
                 {
diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp
index c2b5416b0..5d28bb41f 100644
--- a/source/Lib/DecoderLib/DecSlice.cpp
+++ b/source/Lib/DecoderLib/DecSlice.cpp
@@ -232,7 +232,16 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream )
 
     if ((cs.slice->getSliceType() != I_SLICE || cs.sps->getIBCFlag()) && ctuXPosInCtus == 0)
     {
-      cs.slice->resetMotionLUTs();
+      cs.motionLut.lut.resize(0);
+#if JVET_M0483_IBC
+      cs.motionLut.lutIbc.resize(0);
+#endif
+#if JVET_M0170_MRG_SHARELIST
+      cs.motionLut.lutShare.resize(0);
+#if JVET_M0483_IBC
+      cs.motionLut.lutShareIbc.resize(0);
+#endif
+#endif
     }
 
 #if JVET_M0445_MCTS_DEC_CHECK
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index b7c5c77ec..9aefa9b4b 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -92,17 +92,10 @@ void EncCu::create( EncCfg* encCfg )
   m_pTempCS = new CodingStructure**  [numWidths];
   m_pBestCS = new CodingStructure**  [numWidths];
 
-  m_pTempMotLUTs = new LutMotionCand**[numWidths];
-  m_pBestMotLUTs = new LutMotionCand**[numWidths];
-  m_pSplitTempMotLUTs = new LutMotionCand**[numWidths];
-
   for( unsigned w = 0; w < numWidths; w++ )
   {
     m_pTempCS[w] = new CodingStructure*  [numHeights];
     m_pBestCS[w] = new CodingStructure*  [numHeights];
-    m_pTempMotLUTs[w] = new LutMotionCand*[numHeights];
-    m_pBestMotLUTs[w] = new LutMotionCand*[numHeights];
-    m_pSplitTempMotLUTs[w] = new LutMotionCand*[numHeights];
 
     for( unsigned h = 0; h < numHeights; h++ )
     {
@@ -116,45 +109,11 @@ void EncCu::create( EncCfg* encCfg )
 
         m_pTempCS[w][h]->create( chromaFormat, Area( 0, 0, width, height ), false );
         m_pBestCS[w][h]->create( chromaFormat, Area( 0, 0, width, height ), false );
-        m_pTempMotLUTs[w][h] = new LutMotionCand ;
-        m_pBestMotLUTs[w][h] = new LutMotionCand ;
-        m_pSplitTempMotLUTs[w][h] = new LutMotionCand;
-#if JVET_M0483_IBC
-        m_pSplitTempMotLUTs[w][h]->currCnt = 0;
-        m_pSplitTempMotLUTs[w][h]->currCntIBC = 0;
-        m_pSplitTempMotLUTs[w][h]->motionCand = nullptr;
-        m_pSplitTempMotLUTs[w][h]->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS * 2];
-
-        m_pTempMotLUTs[w][h]->currCnt = 0;
-        m_pTempMotLUTs[w][h]->currCntIBC = 0;
-        m_pTempMotLUTs[w][h]->motionCand = nullptr;
-        m_pTempMotLUTs[w][h]->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS * 2];
-
-        m_pBestMotLUTs[w][h]->currCnt = 0;
-        m_pBestMotLUTs[w][h]->currCntIBC = 0;
-        m_pBestMotLUTs[w][h]->motionCand = nullptr;
-        m_pBestMotLUTs[w][h]->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS * 2];
-#else
-        m_pSplitTempMotLUTs[w][h]->currCnt = 0;
-        m_pSplitTempMotLUTs[w][h]->motionCand = nullptr;
-        m_pSplitTempMotLUTs[w][h]->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS];
-
-        m_pTempMotLUTs[w][h]->currCnt = 0;
-        m_pTempMotLUTs[w][h]->motionCand = nullptr;
-        m_pTempMotLUTs[w][h]->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS];
-
-        m_pBestMotLUTs[w][h]->currCnt = 0;
-        m_pBestMotLUTs[w][h]->motionCand = nullptr;
-        m_pBestMotLUTs[w][h]->motionCand = new MotionInfo[MAX_NUM_HMVP_CANDS];
-#endif
       }
       else
       {
         m_pTempCS[w][h] = nullptr;
         m_pBestCS[w][h] = nullptr;
-        m_pTempMotLUTs[w][h] = nullptr;
-        m_pBestMotLUTs[w][h] = nullptr;
-        m_pSplitTempMotLUTs[w][h] = nullptr;
       }
     }
   }
@@ -216,39 +175,14 @@ void EncCu::destroy()
 
       delete m_pBestCS[w][h];
       delete m_pTempCS[w][h];
-      if (m_pTempMotLUTs[w][h])
-      {
-        delete[] m_pTempMotLUTs[w][h]->motionCand;
-        m_pTempMotLUTs[w][h]->motionCand = nullptr;
-        delete m_pTempMotLUTs[w][h];
-      }
-      if (m_pBestMotLUTs[w][h])
-      {
-        delete[] m_pBestMotLUTs[w][h]->motionCand;
-        m_pBestMotLUTs[w][h]->motionCand = nullptr;
-        delete m_pBestMotLUTs[w][h];
-      }
-
-      if (m_pSplitTempMotLUTs[w][h])
-      {
-        delete[] m_pSplitTempMotLUTs[w][h]->motionCand;
-        m_pSplitTempMotLUTs[w][h]->motionCand = nullptr;
-        delete m_pSplitTempMotLUTs[w][h];
-      }
     }
 
     delete[] m_pTempCS[w];
     delete[] m_pBestCS[w];
-    delete[] m_pBestMotLUTs[w];
-    delete[] m_pTempMotLUTs[w];
-    delete[] m_pSplitTempMotLUTs[w];
   }
 
   delete[] m_pBestCS; m_pBestCS = nullptr;
   delete[] m_pTempCS; m_pTempCS = nullptr;
-  delete[] m_pSplitTempMotLUTs; m_pSplitTempMotLUTs = nullptr;
-  delete[] m_pBestMotLUTs; m_pBestMotLUTs = nullptr;
-  delete[] m_pTempMotLUTs; m_pTempMotLUTs = nullptr;
 
 #if JVET_M0427_INLOOP_RESHAPER && REUSE_CU_RESULTS
   if (m_tmpStorageLCU)
@@ -435,10 +369,6 @@ void EncCu::compressCtu( CodingStructure& cs, const UnitArea& area, const unsign
 
   CodingStructure *tempCS = m_pTempCS[gp_sizeIdxInfo->idxFrom( area.lumaSize().width )][gp_sizeIdxInfo->idxFrom( area.lumaSize().height )];
   CodingStructure *bestCS = m_pBestCS[gp_sizeIdxInfo->idxFrom( area.lumaSize().width )][gp_sizeIdxInfo->idxFrom( area.lumaSize().height )];
-  LutMotionCand *tempMotCandLUTs = m_pTempMotLUTs[gp_sizeIdxInfo->idxFrom(area.lumaSize().width)][gp_sizeIdxInfo->idxFrom(area.lumaSize().height)];
-  LutMotionCand *bestMotCandLUTs = m_pBestMotLUTs[gp_sizeIdxInfo->idxFrom(area.lumaSize().width)][gp_sizeIdxInfo->idxFrom(area.lumaSize().height)];
-  cs.slice->copyMotionLUTs(cs.slice->getMotionLUTs(), tempMotCandLUTs);
-  cs.slice->copyMotionLUTs(cs.slice->getMotionLUTs(), bestMotCandLUTs);
 
   cs.initSubStructure( *tempCS, partitioner->chType, partitioner->currArea(), false );
   cs.initSubStructure( *bestCS, partitioner->chType, partitioner->currArea(), false );
@@ -446,10 +376,7 @@ void EncCu::compressCtu( CodingStructure& cs, const UnitArea& area, const unsign
   tempCS->baseQP       = bestCS->baseQP       = currQP[CH_L];
   tempCS->prevQP[CH_L] = bestCS->prevQP[CH_L] = prevQP[CH_L];
 
-  xCompressCU( tempCS, bestCS, *partitioner
-    , tempMotCandLUTs
-    , bestMotCandLUTs
-  );
+  xCompressCU( tempCS, bestCS, *partitioner );
 
   // all signals were already copied during compression if the CTU was split - at this point only the structures are copied to the top level CS
 #if JVET_M0427_INLOOP_RESHAPER
@@ -458,7 +385,6 @@ void EncCu::compressCtu( CodingStructure& cs, const UnitArea& area, const unsign
   const bool copyUnsplitCTUSignals = bestCS->cus.size() == 1 && KEEP_PRED_AND_RESI_SIGNALS;
 #endif
   cs.useSubStructure( *bestCS, partitioner->chType, CS::getArea( *bestCS, area, partitioner->chType ), copyUnsplitCTUSignals, false, false, copyUnsplitCTUSignals );
-  cs.slice->copyMotionLUTs(bestMotCandLUTs, cs.slice->getMotionLUTs());
 
   if (CS::isDualITree (cs) && isChromaEnabled (cs.pcv->chrFormat))
   {
@@ -472,10 +398,7 @@ void EncCu::compressCtu( CodingStructure& cs, const UnitArea& area, const unsign
     tempCS->baseQP       = bestCS->baseQP       = currQP[CH_C];
     tempCS->prevQP[CH_C] = bestCS->prevQP[CH_C] = prevQP[CH_C];
 
-    xCompressCU( tempCS, bestCS, *partitioner
-      , tempMotCandLUTs
-      , bestMotCandLUTs
-    );
+    xCompressCU( tempCS, bestCS, *partitioner );
 
 #if JVET_M0427_INLOOP_RESHAPER
     const bool copyUnsplitCTUSignals = bestCS->cus.size() == 1;
@@ -672,10 +595,7 @@ bool EncCu::xCheckBestMode( CodingStructure *&tempCS, CodingStructure *&bestCS,
 
 }
 
-void EncCu::xCompressCU( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner
-  , LutMotionCand *&tempMotCandLUTs
-  , LutMotionCand *&bestMotCandLUTs
-)
+void EncCu::xCompressCU( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner )
 {
 #if JVET_M0170_MRG_SHARELIST
   if (m_shareState == NO_SHARE)
@@ -758,16 +678,6 @@ void EncCu::xCompressCU( CodingStructure *&tempCS, CodingStructure *&bestCS, Par
     m_modeCtrl->finishCULevel( partitioner );
     return;
   }
-#if JVET_M0483_IBC
-  if ((!slice.isIntra() || slice.getSPS()->getIBCFlag())
-#else
-  if (!slice.isIntra()
-#endif
-    && tempCS->chType == CHANNEL_TYPE_LUMA
-    )
-  {
-    tempCS->slice->copyMotionLUTs(tempMotCandLUTs, tempCS->slice->getMotionLUTs());
-  }
 
   DTRACE_UPDATE( g_trace_ctx, std::make_pair( "cux", uiLPelX ) );
   DTRACE_UPDATE( g_trace_ctx, std::make_pair( "cuy", uiTPelY ) );
@@ -892,11 +802,7 @@ void EncCu::xCompressCU( CodingStructure *&tempCS, CodingStructure *&bestCS, Par
     else if( isModeSplit( currTestMode ) )
     {
 
-      xCheckModeSplit( tempCS, bestCS, partitioner, currTestMode
-        , tempMotCandLUTs
-        , bestMotCandLUTs
-        , partitioner.currArea()
-      );
+      xCheckModeSplit( tempCS, bestCS, partitioner, currTestMode );
     }
     else
     {
@@ -945,7 +851,21 @@ void EncCu::xCompressCU( CodingStructure *&tempCS, CodingStructure *&bestCS, Par
     && bestCS->area.Y() == (*bestCS->cus.back()).Y()
     )
   {
-    bestCS->slice->updateMotionLUTs(bestMotCandLUTs, (*bestCS->cus.back()));
+    const CodingUnit&     cu = *bestCS->cus.front();
+    const PredictionUnit& pu = *cu.firstPU;
+
+    if (!cu.affine && !cu.triangle)
+    {
+      MotionInfo mi = pu.getMotionInfo();
+#if JVET_M0264_HMVP_WITH_GBIIDX
+      mi.GBiIdx = (mi.interDir == 3) ? cu.GBiIdx : GBI_DEFAULT;
+#endif
+#if JVET_M0483_IBC
+      cu.cs->addMiToLut(CU::isIBC(cu) ? cu.cs->motionLut.lutIbc : cu.cs->motionLut.lut, mi);
+#else
+      cu.cs->addMiToLut(cu.cs->motionLut.lut, mi);
+#endif
+    }
   }
 #if JVET_M0427_INLOOP_RESHAPER
   bestCS->picture->getPredBuf(currCsArea).copyFrom(bestCS->getPredBuf(currCsArea));
@@ -1204,23 +1124,15 @@ void EncCu::copyState( EncCu* other, Partitioner& partitioner, const UnitArea& c
 }
 #endif
 
-void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode
-  , LutMotionCand* &tempMotCandLUTs
-  , LutMotionCand* &bestMotCandLUTs
-  , UnitArea  parArea
-)
+void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode )
 {
   const int qp                = encTestMode.qp;
   const PPS &pps              = *tempCS->pps;
   const Slice &slice          = *tempCS->slice;
   const bool bIsLosslessMode  = false; // False at this level. Next level down may set it to true.
   const int oldPrevQp         = tempCS->prevQP[partitioner.chType];
-  const uint32_t currDepth        = partitioner.currDepth;
-
-  const unsigned wParIdx = gp_sizeIdxInfo->idxFrom(parArea.lwidth());
-  const unsigned hParIdx = gp_sizeIdxInfo->idxFrom(parArea.lheight());
-  if (tempCS->chType == CHANNEL_TYPE_LUMA)
-  tempCS->slice->copyMotionLUTs(tempMotCandLUTs, m_pSplitTempMotLUTs[wParIdx][hParIdx]);
+  const auto oldMotionLut     = tempCS->motionLut;
+  const uint32_t currDepth = partitioner.currDepth;
 
   const PartSplit split = getPartSplit( encTestMode );
 
@@ -1292,17 +1204,6 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
   }
 
 #if JVET_M0170_MRG_SHARELIST
-#if JVET_M0483_IBC
-  if ((!slice.isIntra() || slice.getSPS()->getIBCFlag())
-#else
-  if (!slice.isIntra()
-#endif
-    && tempCS->chType == CHANNEL_TYPE_LUMA
-    )
-  {
-    tempCS->slice->copyMotionLUTs(tempMotCandLUTs, tempCS->slice->getMotionLUTs());
-  }
-
   int startShareThisLevel = 0;
   const uint32_t uiLPelX = tempCS->area.Y().lumaPos().x;
   const uint32_t uiTPelY = tempCS->area.Y().lumaPos().y;
@@ -1334,7 +1235,10 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
 #endif
   {
 #if JVET_M0170_MRG_SHARELIST
-    tempCS->slice->copyMotionLUTs(tempCS->slice->getMotionLUTs(), tempCS->slice->m_MotionCandLuTsBkup);
+    tempCS->motionLut.lutShare = tempCS->motionLut.lut;
+#if JVET_M0483_IBC
+    tempCS->motionLut.lutShareIbc = tempCS->motionLut.lutIbc;
+#endif
     m_shareBndPosX = uiLPelX;
     m_shareBndPosY = uiTPelY;
     m_shareBndSizeW = tempCS->area.lwidth();
@@ -1375,13 +1279,6 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
 
       tempCS->initSubStructure( *tempSubCS, partitioner.chType, subCUArea, false );
       tempCS->initSubStructure( *bestSubCS, partitioner.chType, subCUArea, false );
-      LutMotionCand *tempSubMotCandLUTs = m_pTempMotLUTs[wIdx][hIdx];
-      LutMotionCand *bestSubMotCandLUTs = m_pBestMotLUTs[wIdx][hIdx];
-      if (tempCS->chType == CHANNEL_TYPE_LUMA)
-      {
-        tempCS->slice->copyMotionLUTs(tempMotCandLUTs, tempSubMotCandLUTs);
-        tempCS->slice->copyMotionLUTs(tempMotCandLUTs, bestSubMotCandLUTs);
-      }
 #if JVET_M0170_MRG_SHARELIST
       tempSubCS->sharedBndPos.x = (m_shareState == SHARING) ? m_shareBndPosX : tempSubCS->area.Y().lumaPos().x;
       tempSubCS->sharedBndPos.y = (m_shareState == SHARING) ? m_shareBndPosY : tempSubCS->area.Y().lumaPos().y;
@@ -1392,10 +1289,7 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
       bestSubCS->sharedBndSize.width = (m_shareState == SHARING) ? m_shareBndSizeW : tempSubCS->area.lwidth();
       bestSubCS->sharedBndSize.height = (m_shareState == SHARING) ? m_shareBndSizeH : tempSubCS->area.lheight();
 #endif
-      xCompressCU( tempSubCS, bestSubCS, partitioner
-        , tempSubMotCandLUTs
-        , bestSubMotCandLUTs
-      );
+      xCompressCU( tempSubCS, bestSubCS, partitioner );
 
       if( bestSubCS->cost == MAX_DOUBLE )
       {
@@ -1409,19 +1303,11 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
         partitioner.exitCurrSplit();
         bool bestCSUpdated =
         xCheckBestMode( tempCS, bestCS, partitioner, encTestMode );
-
-        if (tempCS->chType == CHANNEL_TYPE_LUMA)
-        if (bestCSUpdated)
-        {
-          std::swap(tempMotCandLUTs, bestMotCandLUTs);
-        }
         return;
       }
 
       bool keepResi = KEEP_PRED_AND_RESI_SIGNALS;
       tempCS->useSubStructure( *bestSubCS, partitioner.chType, CS::getArea( *tempCS, subCUArea, partitioner.chType ), KEEP_PRED_AND_RESI_SIGNALS, true, keepResi, keepResi );
-      if (tempCS->chType == CHANNEL_TYPE_LUMA)
-      tempCS->slice->copyMotionLUTs(bestSubMotCandLUTs, tempMotCandLUTs);
 
       if(currDepth < pps.getMaxCuDQPDepth())
       {
@@ -1553,20 +1439,7 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
   if (isAffMVInfoSaved)
     m_pcInterSearch->addAffMVInfo(tmpMVInfo);
 
-#if JVET_M0483_IBC
-  if ((!slice.isIntra() || slice.getSPS()->getIBCFlag())
-#else
-  if (!slice.isIntra()
-#endif
-    && tempCS->chType == CHANNEL_TYPE_LUMA
-    )
-  {
-    if (bestCSUpdated)
-    {
-      std::swap(tempMotCandLUTs, bestMotCandLUTs);
-    }
-    tempCS->slice->copyMotionLUTs(m_pSplitTempMotLUTs[wParIdx][hParIdx], tempMotCandLUTs);
-  }
+  tempCS->motionLut = oldMotionLut;
 
   tempCS->releaseIntermediateData();
 
diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h
index 5707c858b..9a8259056 100644
--- a/source/Lib/EncoderLib/EncCu.h
+++ b/source/Lib/EncoderLib/EncCu.h
@@ -111,9 +111,6 @@ private:
 
   CodingStructure    ***m_pTempCS;
   CodingStructure    ***m_pBestCS;
-  LutMotionCand      ***m_pTempMotLUTs;
-  LutMotionCand      ***m_pBestMotLUTs;
-  LutMotionCand      ***m_pSplitTempMotLUTs;
   //  Access channel
   EncCfg*               m_pcEncCfg;
   IntraSearch*          m_pcIntraSearch;
@@ -204,10 +201,7 @@ protected:
   Distortion getDistortionDb  ( CodingStructure &cs, CPelBuf org, CPelBuf reco, ComponentID compID, const CompArea& compArea, bool afterDb );
 #endif
 
-  void xCompressCU            ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm
-    , LutMotionCand *&tempMotCandLUTs
-    , LutMotionCand *&bestMotCandLUTs
-  );
+  void xCompressCU            ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm );
 #if ENABLE_SPLIT_PARALLELISM
   void xCompressCUParallel    ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm );
   void copyState              ( EncCu* other, Partitioner& pm, const UnitArea& currArea, const bool isDist );
@@ -216,11 +210,7 @@ protected:
   bool
     xCheckBestMode         ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestmode );
 
-  void xCheckModeSplit        ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode
-    , LutMotionCand* &tempMotCandLUTs
-    , LutMotionCand* &bestMotCandLUTs
-    , UnitArea  parArea
-  );
+  void xCheckModeSplit        ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode );
 
   void xCheckRDCostIntra      ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode );
   void xCheckIntraPCM         ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestMode );
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index 6f1dc1114..2eb1d3725 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -1700,7 +1700,16 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
 #endif
     if ((cs.slice->getSliceType() != I_SLICE || cs.sps->getIBCFlag()) && ctuXPosInCtus == 0)
     {
-      pcSlice->resetMotionLUTs();
+      cs.motionLut.lut.resize(0);
+#if JVET_M0483_IBC
+      cs.motionLut.lutIbc.resize(0);
+#endif
+#if JVET_M0170_MRG_SHARELIST
+      cs.motionLut.lutShare.resize(0);
+#if JVET_M0483_IBC
+      cs.motionLut.lutShareIbc.resize(0);
+#endif
+#endif
     }
 
 #if ENABLE_WPP_PARALLELISM
-- 
GitLab