From 6a93f799a1a2e8451bed73dc973a1ee276a427b5 Mon Sep 17 00:00:00 2001
From: Seungwook Hong <seungwook.hong@nokia.com>
Date: Mon, 29 Aug 2022 15:55:36 +0000
Subject: [PATCH] Fix: RPR crash caused by picHeader creation/deletion

---
 source/Lib/CommonLib/CodingStructure.cpp | 57 ++++++++++++++++++++++++
 source/Lib/CommonLib/CodingStructure.h   | 10 +++++
 source/Lib/CommonLib/Picture.cpp         | 27 +++++++----
 source/Lib/DecoderLib/DecLib.cpp         | 14 +++---
 source/Lib/EncoderLib/EncCu.cpp          | 10 +++++
 source/Lib/EncoderLib/IntraSearch.cpp    | 17 +++++++
 6 files changed, 121 insertions(+), 14 deletions(-)

diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp
index bcadb1837..7d04b7add 100644
--- a/source/Lib/CommonLib/CodingStructure.cpp
+++ b/source/Lib/CommonLib/CodingStructure.cpp
@@ -1533,8 +1533,16 @@ void CodingStructure::allocateVectorsAtPicLevel()
   tus.reserve( allocSize );
 }
 
+#if GDR_ENABLED
+void CodingStructure::create(const ChromaFormat &_chromaFormat, const Area& _area, const bool isTopLayer, const bool isPLTused, const bool isGdrEnabled)
+#else
 void CodingStructure::create(const ChromaFormat &_chromaFormat, const Area& _area, const bool isTopLayer, const bool isPLTused)
+#endif
 {
+#if GDR_ENABLED
+  m_gdrEnabled = isGdrEnabled;
+#endif
+
   createInternals(UnitArea(_chromaFormat, _area), isTopLayer, isPLTused);
 
   if (isTopLayer)
@@ -1542,14 +1550,30 @@ void CodingStructure::create(const ChromaFormat &_chromaFormat, const Area& _are
     return;
   }
 
+#if GDR_ENABLED
+  if (m_gdrEnabled)
+  {    
+    picHeader = new PicHeader();
+    picHeader->initPicHeader();
+  }
+#endif
+
   m_reco.create( area );
   m_pred.create( area );
   m_resi.create( area );
   m_orgr.create( area );
 }
 
+#if GDR_ENABLED
+void CodingStructure::create(const UnitArea& _unit, const bool isTopLayer, const bool isPLTused, const bool isGdrEnabled)
+#else
 void CodingStructure::create(const UnitArea& _unit, const bool isTopLayer, const bool isPLTused)
+#endif
 {
+#if GDR_ENABLED
+  m_gdrEnabled = isGdrEnabled;
+#endif
+
   createInternals(_unit, isTopLayer, isPLTused);
 
   if (isTopLayer)
@@ -1557,6 +1581,14 @@ void CodingStructure::create(const UnitArea& _unit, const bool isTopLayer, const
     return;
   }
 
+#if GDR_ENABLED  
+  if (m_gdrEnabled)
+  {  
+    picHeader = new PicHeader();
+    picHeader->initPicHeader();
+  }
+#endif
+
   m_reco.create( area );
   m_pred.create( area );
   m_resi.create( area );
@@ -1803,6 +1835,15 @@ void CodingStructure::destroyCoeffs()
       m_runType[i] = nullptr;
     }
   }
+
+#if GDR_ENABLED
+  if (picHeader && m_gdrEnabled)
+  {
+    delete picHeader;
+  }
+
+  picHeader = nullptr;
+#endif
 }
 
 void CodingStructure::initSubStructure( CodingStructure& subStruct, const ChannelType _chType, const UnitArea &subArea, const bool &isTuEnc )
@@ -1831,7 +1872,23 @@ void CodingStructure::initSubStructure( CodingStructure& subStruct, const Channe
   subStruct.sps       = sps;
   subStruct.vps       = vps;
   subStruct.pps       = pps;
+#if GDR_ENABLED
+  if (m_gdrEnabled)
+  {
+    if (!subStruct.picHeader)
+    {
+      subStruct.picHeader = new PicHeader;
+      subStruct.picHeader->initPicHeader();
+    }
+    *subStruct.picHeader = *picHeader;
+  }
+  else
+  {
+    subStruct.picHeader = picHeader;
+  }
+#else
   subStruct.picHeader = picHeader;
+#endif
 
   memcpy(subStruct.alfApss, alfApss, sizeof(alfApss));
 
diff --git a/source/Lib/CommonLib/CodingStructure.h b/source/Lib/CommonLib/CodingStructure.h
index 988f2e21f..ddf84f075 100644
--- a/source/Lib/CommonLib/CodingStructure.h
+++ b/source/Lib/CommonLib/CodingStructure.h
@@ -102,8 +102,14 @@ public:
 
   CodingStructure(CUCache&, PUCache&, TUCache&);
 
+#if GDR_ENABLED
+  bool isGdrEnabled() { return m_gdrEnabled; }
+  void create(const UnitArea &_unit, const bool isTopLayer, const bool isPLTused, const bool isGdrEnabled = false);
+  void create(const ChromaFormat &_chromaFormat, const Area& _area, const bool isTopLayer, const bool isPLTused, const bool isGdrEnabeld = false);
+#else
   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);
+#endif
 
   void destroy();
   void releaseIntermediateData();
@@ -272,6 +278,10 @@ private:
 
   MotionInfo *m_motionBuf;
 
+#if GDR_ENABLED
+  bool m_gdrEnabled;
+#endif
+
 public:
   CodingStructure *bestParent;
   double        tmpColorSpaceCost;
diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index 28beae0dc..145e68393 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -128,13 +128,6 @@ void Picture::destroy()
   m_hashMap.clearAll();
   if (cs)
   {
-#if GDR_ENABLED
-    if (cs->picHeader)
-    {
-      delete cs->picHeader;
-    }
-    cs->picHeader = nullptr;
-#endif
     cs->destroy();
     delete cs;
     cs = nullptr;
@@ -260,7 +253,11 @@ void Picture::finalInit( const VPS* vps, const SPS& sps, const PPS& pps, PicHead
   {
     cs = new CodingStructure( g_globalUnitCache.cuCache, g_globalUnitCache.puCache, g_globalUnitCache.tuCache );
     cs->sps = &sps;
+#if GDR_ENABLED
+    cs->create(chromaFormatIDC, Area(0, 0, width, height), true, (bool)sps.getPLTMode(), sps.getGDREnabledFlag());
+#else
     cs->create(chromaFormatIDC, Area(0, 0, width, height), true, (bool) sps.getPLTMode());
+#endif
   }
 
   cs->vps = vps;
@@ -271,8 +268,22 @@ void Picture::finalInit( const VPS* vps, const SPS& sps, const PPS& pps, PicHead
   picHeader->setPPSId( pps.getPPSId() );
 #if GDR_ENABLED
   picHeader->setPic(this);
-#endif
+
+  PicHeader *ph = new PicHeader;
+  ph->initPicHeader();
+  *ph = *picHeader;
+  ph->setPic(this);
+
+  if (cs->picHeader)
+  {
+    delete cs->picHeader;
+    cs->picHeader = nullptr;
+  }
+
+  cs->picHeader = ph;
+#else
   cs->picHeader = picHeader;
+#endif
   memcpy(cs->alfApss, alfApss, sizeof(cs->alfApss));
   cs->lmcsAps = lmcsAps;
   cs->scalinglistAps = scalingListAps;
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index f6f11b936..71e712d6c 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -960,7 +960,9 @@ void DecLib::finishPicture(int &poc, PicList *&rpcListPic, MsgLevel msgl, bool a
   m_pcPic->destroyTempBuffers();
   m_pcPic->cs->destroyCoeffs();
   m_pcPic->cs->releaseIntermediateData();
+#if !GDR_ENABLED
   m_pcPic->cs->picHeader->initPicHeader();
+#endif
   m_puCounter++;
 }
 
@@ -1974,14 +1976,11 @@ void DecLib::xActivateParameterSets( const InputNALUnit nalu )
     //  Get a new picture buffer. This will also set up m_pcPic, and therefore give us a SPS and PPS pointer that we can use.
     m_pcPic = xGetNewPicBuffer( *sps, *pps, m_apcSlicePilot->getTLayer(), layerId );
 
-#if GDR_ENABLED
-    PicHeader *picHeader = new PicHeader;
-    *picHeader = m_picHeader;
-    m_apcSlicePilot->setPicHeader(picHeader);
-    m_pcPic->finalInit(vps, *sps, *pps, picHeader, apss, lmcsAPS, scalinglistAPS);
-#else
     m_pcPic->finalInit( vps, *sps, *pps, &m_picHeader, apss, lmcsAPS, scalinglistAPS );
+#if GDR_ENABLED
+    m_apcSlicePilot->setPicHeader(m_pcPic->cs->picHeader);
 #endif
+
     m_pcPic->createGrainSynthesizer(m_firstPictureInSequence, &m_grainCharacteristic, &m_grainBuf, pps->getPicWidthInLumaSamples(), pps->getPicHeightInLumaSamples(), sps->getChromaFormatIdc(), sps->getBitDepth(CHANNEL_TYPE_LUMA));
     m_pcPic->createColourTransfProcessor(m_firstPictureInSequence, &m_colourTranfParams, &m_invColourTransfBuf, pps->getPicWidthInLumaSamples(), pps->getPicHeightInLumaSamples(), sps->getChromaFormatIdc(), sps->getBitDepth(CHANNEL_TYPE_LUMA));
     m_firstPictureInSequence = false;
@@ -1995,6 +1994,9 @@ void DecLib::xActivateParameterSets( const InputNALUnit nalu )
 
     // we now have a real slice:
     Slice *pSlice = m_pcPic->slices[m_uiSliceSegmentIdx];
+#if GDR_ENABLED
+    pSlice->setPicHeader(m_pcPic->cs->picHeader);
+#endif
 
     // Update the PPS and SPS pointers with the ones of the picture.
     pps=pSlice->getPPS();
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index 0b0d3c5b9..c41ff695e 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -100,14 +100,24 @@ void EncCu::create( EncCfg* encCfg )
         m_pTempCS[w][h] = new CodingStructure( m_unitCache.cuCache, m_unitCache.puCache, m_unitCache.tuCache );
         m_pBestCS[w][h] = new CodingStructure( m_unitCache.cuCache, m_unitCache.puCache, m_unitCache.tuCache );
 
+#if GDR_ENABLED
+        m_pTempCS[w][h]->create(chromaFormat, Area(0, 0, width, height), false, (bool)encCfg->getPLTMode(), encCfg->getGdrEnabled());
+        m_pBestCS[w][h]->create(chromaFormat, Area(0, 0, width, height), false, (bool)encCfg->getPLTMode(), encCfg->getGdrEnabled());
+#else
         m_pTempCS[w][h]->create(chromaFormat, Area(0, 0, width, height), false, (bool)encCfg->getPLTMode());
         m_pBestCS[w][h]->create(chromaFormat, Area(0, 0, width, height), false, (bool)encCfg->getPLTMode());
+#endif
 
         m_pTempCS2[w][h] = new CodingStructure( m_unitCache.cuCache, m_unitCache.puCache, m_unitCache.tuCache );
         m_pBestCS2[w][h] = new CodingStructure( m_unitCache.cuCache, m_unitCache.puCache, m_unitCache.tuCache );
 
+#if GDR_ENABLED
+        m_pTempCS2[w][h]->create(chromaFormat, Area(0, 0, width, height), false, (bool)encCfg->getPLTMode(), encCfg->getGdrEnabled());
+        m_pBestCS2[w][h]->create(chromaFormat, Area(0, 0, width, height), false, (bool)encCfg->getPLTMode(), encCfg->getGdrEnabled());
+#else
         m_pTempCS2[w][h]->create(chromaFormat, Area(0, 0, width, height), false, (bool)encCfg->getPLTMode());
         m_pBestCS2[w][h]->create(chromaFormat, Area(0, 0, width, height), false, (bool)encCfg->getPLTMode());
+#endif
       }
       else
       {
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index fbd5cd9bd..61d3ae917 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -242,8 +242,13 @@ void IntraSearch::init(EncCfg *pcEncCfg, TrQuant *pcTrQuant, RdCost *pcRdCost, C
         m_pBestCS[width][height] = new CodingStructure( m_unitCache.cuCache, m_unitCache.puCache, m_unitCache.tuCache );
         m_pTempCS[width][height] = new CodingStructure( m_unitCache.cuCache, m_unitCache.puCache, m_unitCache.tuCache );
 
+#if GDR_ENABLED
+        m_pBestCS[width][height]->create(m_pcEncCfg->getChromaFormatIdc(), Area(0, 0, gp_sizeIdxInfo->sizeFrom(width), gp_sizeIdxInfo->sizeFrom(height)), false, (bool)pcEncCfg->getPLTMode(), pcEncCfg->getGdrEnabled());
+        m_pTempCS[width][height]->create(m_pcEncCfg->getChromaFormatIdc(), Area(0, 0, gp_sizeIdxInfo->sizeFrom(width), gp_sizeIdxInfo->sizeFrom(height)), false, (bool)pcEncCfg->getPLTMode(), pcEncCfg->getGdrEnabled());
+#else
         m_pBestCS[width][height]->create(m_pcEncCfg->getChromaFormatIdc(), Area(0, 0, gp_sizeIdxInfo->sizeFrom(width), gp_sizeIdxInfo->sizeFrom(height)), false, (bool)pcEncCfg->getPLTMode());
         m_pTempCS[width][height]->create(m_pcEncCfg->getChromaFormatIdc(), Area(0, 0, gp_sizeIdxInfo->sizeFrom(width), gp_sizeIdxInfo->sizeFrom(height)), false, (bool)pcEncCfg->getPLTMode());
+#endif
 
         m_pFullCS[width][height]  = new CodingStructure *[numLayersToAllocateFull];
         m_pSplitCS[width][height] = new CodingStructure *[numLayersToAllocateSplit];
@@ -252,13 +257,21 @@ void IntraSearch::init(EncCfg *pcEncCfg, TrQuant *pcTrQuant, RdCost *pcRdCost, C
         {
           m_pFullCS [width][height][layer] = new CodingStructure( m_unitCache.cuCache, m_unitCache.puCache, m_unitCache.tuCache );
 
+#if GDR_ENABLED
+          m_pFullCS[width][height][layer]->create(m_pcEncCfg->getChromaFormatIdc(), Area(0, 0, gp_sizeIdxInfo->sizeFrom(width), gp_sizeIdxInfo->sizeFrom(height)), false, (bool)pcEncCfg->getPLTMode(), pcEncCfg->getGdrEnabled());
+#else
           m_pFullCS[width][height][layer]->create(m_pcEncCfg->getChromaFormatIdc(), Area(0, 0, gp_sizeIdxInfo->sizeFrom(width), gp_sizeIdxInfo->sizeFrom(height)), false, (bool)pcEncCfg->getPLTMode());
+#endif
         }
 
         for (uint32_t layer = 0; layer < numLayersToAllocateSplit; layer++)
         {
           m_pSplitCS[width][height][layer] = new CodingStructure( m_unitCache.cuCache, m_unitCache.puCache, m_unitCache.tuCache );
+#if GDR_ENABLED
+          m_pSplitCS[width][height][layer]->create(m_pcEncCfg->getChromaFormatIdc(), Area(0, 0, gp_sizeIdxInfo->sizeFrom(width), gp_sizeIdxInfo->sizeFrom(height)), false, (bool)pcEncCfg->getPLTMode(), pcEncCfg->getGdrEnabled());
+#else
           m_pSplitCS[width][height][layer]->create(m_pcEncCfg->getChromaFormatIdc(), Area(0, 0, gp_sizeIdxInfo->sizeFrom(width), gp_sizeIdxInfo->sizeFrom(height)), false, (bool)pcEncCfg->getPLTMode());
+#endif
         }
       }
       else
@@ -279,7 +292,11 @@ void IntraSearch::init(EncCfg *pcEncCfg, TrQuant *pcTrQuant, RdCost *pcRdCost, C
   for (uint32_t depth = 0; depth < numSaveLayersToAllocate; depth++)
   {
     m_pSaveCS[depth] = new CodingStructure( m_unitCache.cuCache, m_unitCache.puCache, m_unitCache.tuCache );
+#if GDR_ENABLED
+    m_pSaveCS[depth]->create(UnitArea(cform, Area(0, 0, maxCUWidth, maxCUHeight)), false, (bool)pcEncCfg->getPLTMode(), pcEncCfg->getGdrEnabled());
+#else
     m_pSaveCS[depth]->create(UnitArea(cform, Area(0, 0, maxCUWidth, maxCUHeight)), false, (bool)pcEncCfg->getPLTMode());
+#endif
   }
 
   m_isInitialized = true;
-- 
GitLab