From 4758822d7002ea907167e2a6716dadb726c3499d Mon Sep 17 00:00:00 2001
From: Xiang Li <xlxiangli@google.com>
Date: Mon, 9 Oct 2023 21:43:03 -0700
Subject: [PATCH] Port CS mem reduction from ECM !525

---
 source/Lib/CommonLib/CodingStructure.cpp | 54 +++++++++++++++---------
 source/Lib/CommonLib/CodingStructure.h   |  7 +--
 source/Lib/CommonLib/Picture.cpp         |  8 +---
 source/Lib/DecoderLib/DecLib.cpp         |  6 +--
 source/Lib/EncoderLib/EncGOP.cpp         |  5 +--
 5 files changed, 46 insertions(+), 34 deletions(-)

diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp
index 1d2003baf..a35acb90a 100644
--- a/source/Lib/CommonLib/CodingStructure.cpp
+++ b/source/Lib/CommonLib/CodingStructure.cpp
@@ -94,38 +94,61 @@ void CodingStructure::destroy()
   m_reco.destroy();
   m_orgr.destroy();
 
+  destroyTemporaryCsData();
+
+  delete[] m_motionBuf;
+  m_motionBuf = nullptr;
+}
+
+void CodingStructure::destroyTemporaryCsData()
+{
   destroyCoeffs();
 
-  for (auto &ptr: m_isDecomp)
+  for (auto &ptr : m_isDecomp)
   {
     delete[] ptr;
     ptr = nullptr;
   }
 
-  for (auto &ptr: m_tuIdx)
+  for (auto &ptr : m_tuIdx)
   {
     delete[] ptr;
     ptr = nullptr;
   }
 
-  for (auto &ptr: m_puIdx)
+  for (auto &ptr : m_puIdx)
   {
     delete[] ptr;
     ptr = nullptr;
   }
 
-  for (auto &ptr: m_cuIdx)
+  for (auto &ptr : m_cuIdx)
   {
     delete[] ptr;
     ptr = nullptr;
   }
 
-  delete[] m_motionBuf;
-  m_motionBuf = nullptr;
-
   m_tuPool.giveBack(tus);
   m_puPool.giveBack(pus);
   m_cuPool.giveBack(cus);
+  m_numTUs = 0;
+  m_numPUs = 0;
+  m_numCUs = 0;
+}
+
+void CodingStructure::createTemporaryCsData(bool isPLTused)
+{
+  createCoeffs(isPLTused);
+
+  for (auto chType = ChannelType::LUMA; chType <= ::getLastChannel(area.chromaFormat); chType++)
+  {
+    unsigned _area = unitScale[getFirstComponentOfChannel(chType)].scale(area.block(chType).size()).area();
+
+    m_cuIdx[chType] = _area > 0 ? new unsigned[_area] : nullptr;
+    m_puIdx[chType] = _area > 0 ? new unsigned[_area] : nullptr;
+    m_tuIdx[chType] = _area > 0 ? new unsigned[_area] : nullptr;
+    m_isDecomp[chType] = _area > 0 ? new bool[_area] : nullptr;
+  }
 }
 
 void CodingStructure::releaseIntermediateData()
@@ -1331,16 +1354,6 @@ void CodingStructure::createInternals(const UnitArea& _unit, const bool isTopLay
   picture = nullptr;
   parent  = nullptr;
 
-  for (auto chType = ChannelType::LUMA; chType <= ::getLastChannel(area.chromaFormat); chType++)
-  {
-    unsigned _area = unitScale[getFirstComponentOfChannel(chType)].scale(area.block(chType).size()).area();
-
-    m_cuIdx[chType]    = _area > 0 ? new unsigned[_area] : nullptr;
-    m_puIdx[chType]    = _area > 0 ? new unsigned[_area] : nullptr;
-    m_tuIdx[chType]    = _area > 0 ? new unsigned[_area] : nullptr;
-    m_isDecomp[chType] = _area > 0 ? new bool[_area] : nullptr;
-  }
-
   const int numComp = getNumberValidComponents(area.chromaFormat);
 
   for (int i = 0; i < numComp; i++)
@@ -1350,12 +1363,15 @@ void CodingStructure::createInternals(const UnitArea& _unit, const bool isTopLay
 
   if (!isTopLayer)
   {
-    createCoeffs(isPLTused);
+    createTemporaryCsData(isPLTused);
   }
 
   unsigned _lumaAreaScaled = g_miScaling.scale( area.lumaSize() ).area();
   m_motionBuf       = new MotionInfo[_lumaAreaScaled];
-  initStructData();
+  if (!isTopLayer)
+  {
+    initStructData();
+  }
 }
 
 void CodingStructure::addMiToLut(static_vector<MotionInfo, MAX_NUM_HMVP_CANDS> &lut, const MotionInfo &mi)
diff --git a/source/Lib/CommonLib/CodingStructure.h b/source/Lib/CommonLib/CodingStructure.h
index 5529fd950..e2389d218 100644
--- a/source/Lib/CommonLib/CodingStructure.h
+++ b/source/Lib/CommonLib/CodingStructure.h
@@ -103,9 +103,11 @@ public:
 
   void create(const UnitArea &_unit, const bool isTopLayer, const bool isPLTused);
   void create(const ChromaFormat &_chromaFormat, const Area& _area, const bool isTopLayer, const bool isPLTused);
+  void createTemporaryCsData(bool isPLTused);
 
   void destroy();
   void releaseIntermediateData();
+  void destroyTemporaryCsData();
 
 #if GDR_ENABLED
   bool containRefresh(int begX, int endX) const;
@@ -134,9 +136,6 @@ public:
 #endif
   void rebindPicBufs();
 
-  void createCoeffs(const bool isPLTused);
-  void destroyCoeffs();
-
   void allocateVectorsAtPicLevel();
 
   // ---------------------------------------------------------------------------
@@ -222,6 +221,8 @@ public:
 
 
 private:
+  void createCoeffs(const bool isPLTused);
+  void destroyCoeffs();
   void createInternals(const UnitArea& _unit, const bool isTopLayer, const bool isPLTused);
 
 public:
diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index ba2ed107e..399543627 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -250,17 +250,13 @@ void Picture::finalInit( const VPS* vps, const SPS& sps, const PPS& pps, PicHead
   const int          width           = pps.getPicWidthInLumaSamples();
   const int          height          = pps.getPicHeightInLumaSamples();
 
-  if( cs )
-  {
-    cs->initStructData();
-  }
-  else
+  if (cs == nullptr)
   {
     cs      = new CodingStructure(g_xuPool);
-    cs->sps = &sps;
     cs->create(chromaFormatIdc, Area(0, 0, width, height), true, (bool) sps.getPLTMode());
   }
 
+  cs->sps = &sps;
   cs->vps = vps;
   cs->picture = this;
   cs->slice   = nullptr;  // the slices for this picture have not been set at this point. update cs->slice after swapSliceObject()
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index 8f1ea6224..99a7fe2df 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -959,8 +959,7 @@ void DecLib::finishPicture(int &poc, PicList *&rpcListPic, MsgLevel msgl, bool a
   m_maxDecSliceAddrInSubPic = -1;
 
   m_pcPic->destroyTempBuffers();
-  m_pcPic->cs->destroyCoeffs();
-  m_pcPic->cs->releaseIntermediateData();
+  m_pcPic->cs->destroyTemporaryCsData();
 #if !GDR_ENABLED
   m_pcPic->cs->picHeader->initPicHeader();
 #endif
@@ -2058,7 +2057,8 @@ void DecLib::xActivateParameterSets( const InputNALUnit nalu )
                                          sps->getChromaFormatIdc(), sps->getBitDepth(ChannelType::LUMA));
     m_firstPictureInSequence = false;
     m_pcPic->createTempBuffers( m_pcPic->cs->pps->pcv->maxCUWidth );
-    m_pcPic->cs->createCoeffs((bool)m_pcPic->cs->sps->getPLTMode());
+    m_pcPic->cs->createTemporaryCsData((bool)m_pcPic->cs->sps->getPLTMode());
+    m_pcPic->cs->initStructData();
 
     m_pcPic->allocateNewSlice();
     // make the slice-pilot a real slice, and set up the slice-pilot for the next slice
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 47cd4c5fc..f66349520 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -2476,7 +2476,7 @@ void EncGOP::compressGOP(int pocLast, int numPicRcvd, PicList &rcListPic, std::l
     m_pcSliceEncoder->create(picWidth, picHeight, chromaFormatIdc, maxCUWidth, maxCUHeight, maxTotalCUDepth);
 
     pcPic->createTempBuffers( pcPic->cs->pps->pcv->maxCUWidth );
-    pcPic->cs->createCoeffs((bool)pcPic->cs->sps->getPLTMode());
+    pcPic->cs->createTemporaryCsData((bool)pcPic->cs->sps->getPLTMode());
 
     //  Slice data initialization
     pcPic->clearSliceBuffer();
@@ -4537,8 +4537,7 @@ void EncGOP::compressGOP(int pocLast, int numPicRcvd, PicList &rcListPic, std::l
     }
 
     pcPic->destroyTempBuffers();
-    pcPic->cs->destroyCoeffs();
-    pcPic->cs->releaseIntermediateData();
+    pcPic->cs->destroyTemporaryCsData();
   }   // gopId-loop
 
   delete pcBitstreamRedirect;
-- 
GitLab