From 13dae86c574fec13b1cab8229920e0143eb5c145 Mon Sep 17 00:00:00 2001
From: Karsten Suehring <karsten.suehring@hhi.fraunhofer.de>
Date: Fri, 15 Feb 2019 15:47:56 +0100
Subject: [PATCH] Allow sending of parameter sets at every RAP

Merge functionality from HM (macro JCTVC_Y0038_PARAMS). Add an additional
configuration file parameter that allows re-sending parameter sets at every
random access point.
---
 source/App/EncoderApp/EncApp.cpp    |  3 +++
 source/App/EncoderApp/EncAppCfg.cpp |  5 +++++
 source/App/EncoderApp/EncAppCfg.h   |  3 +++
 source/Lib/CommonLib/TypeDef.h      |  2 ++
 source/Lib/EncoderLib/EncCfg.h      |  9 +++++++++
 source/Lib/EncoderLib/EncGOP.cpp    | 11 +++++++++++
 source/Lib/EncoderLib/EncLib.cpp    |  8 ++++++++
 source/Lib/EncoderLib/EncLib.h      |  3 +++
 8 files changed, 44 insertions(+)

diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index 26753f941..a3f8e4b3f 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -116,6 +116,9 @@ void EncApp::xInitLibCfg()
   m_cEncLib.setIntraPeriod                                       ( m_iIntraPeriod );
   m_cEncLib.setDecodingRefreshType                               ( m_iDecodingRefreshType );
   m_cEncLib.setGOPSize                                           ( m_iGOPSize );
+#if JCTVC_Y0038_PARAMS
+  m_cEncLib.setReWriteParamSets                                  ( m_rewriteParamSets );
+#endif
   m_cEncLib.setGopList                                           ( m_GOPList );
   m_cEncLib.setExtraRPSs                                         ( m_extraRPSs );
   for(int i = 0; i < MAX_TLAYER; i++)
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index eb18b7e63..733a913d8 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -923,6 +923,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ("IntraPeriod,-ip",                                 m_iIntraPeriod,                                      -1, "Intra period in frames, (-1: only first frame)")
   ("DecodingRefreshType,-dr",                         m_iDecodingRefreshType,                               0, "Intra refresh type (0:none 1:CRA 2:IDR 3:RecPointSEI)")
   ("GOPSize,g",                                       m_iGOPSize,                                           1, "GOP size of temporal structure")
+#if JCTVC_Y0038_PARAMS
+  ("ReWriteParamSets",                                m_rewriteParamSets,                           false, "Enable rewriting of Parameter sets before every (intra) random access point")
+  //Alias with same name as in HM
+  ("ReWriteParamSetsFlag",                            m_rewriteParamSets,                           false, "Alias for ReWriteParamSets")
+#endif
 
   // motion search options
   ("DisableIntraInInter",                             m_bDisableIntraPUsInInterSlices,                  false, "Flag to disable intra PUs in inter slices")
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 45895dc47..ad9930adf 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -135,6 +135,9 @@ protected:
   int       m_iIntraPeriod;                                   ///< period of I-slice (random access period)
   int       m_iDecodingRefreshType;                           ///< random access type
   int       m_iGOPSize;                                       ///< GOP size of hierarchical structure
+#if JCTVC_Y0038_PARAMS
+  bool      m_rewriteParamSets;                              ///< Flag to enable rewriting of parameter sets at random access points
+#endif
   int       m_extraRPSs;                                      ///< extra RPSs added to handle CRA
   GOPEntry  m_GOPList[MAX_GOP];                               ///< the coding structure entries from the config file
   int       m_numReorderPics[MAX_TLAYER];                     ///< total number of reorder pictures
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index b77ddfde2..b313f177c 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -50,6 +50,8 @@
 #include <assert.h>
 #include <cassert>
 
+#define JCTVC_Y0038_PARAMS                                1
+
 #define JVET_M0451_INTEROPERABILITY_POINT_SYNTAX          1 
 
 #define JVET_M0055_DEBUG_CTU                              1 // DebugCTU encoder debug option
diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h
index 3bf9fe72e..12a54c460 100644
--- a/source/Lib/EncoderLib/EncCfg.h
+++ b/source/Lib/EncoderLib/EncCfg.h
@@ -184,6 +184,9 @@ protected:
   //====== Coding Structure ========
   uint32_t      m_uiIntraPeriod;                    // TODO: make this an int - it can be -1!
   uint32_t      m_uiDecodingRefreshType;            ///< the type of decoding refresh employed for the random access.
+#if JCTVC_Y0038_PARAMS
+  bool      m_rewriteParamSets;
+#endif
   int       m_iGOPSize;
   GOPEntry  m_GOPList[MAX_GOP];
   int       m_extraRPSs;
@@ -703,6 +706,9 @@ public:
   //====== Coding Structure ========
   void      setIntraPeriod                  ( int   i )      { m_uiIntraPeriod = (uint32_t)i; }
   void      setDecodingRefreshType          ( int   i )      { m_uiDecodingRefreshType = (uint32_t)i; }
+#if JCTVC_Y0038_PARAMS
+  void      setReWriteParamSets             ( bool  b )      { m_rewriteParamSets = b; }
+#endif
   void      setGOPSize                      ( int   i )      { m_iGOPSize = i; }
   void      setGopList                      ( const GOPEntry GOPList[MAX_GOP] ) {  for ( int i = 0; i < MAX_GOP; i++ ) m_GOPList[i] = GOPList[i]; }
   void      setExtraRPSs                    ( int   i )      { m_extraRPSs = i; }
@@ -973,6 +979,9 @@ public:
   //==== Coding Structure ========
   uint32_t      getIntraPeriod                  () const     { return  m_uiIntraPeriod; }
   uint32_t      getDecodingRefreshType          () const     { return  m_uiDecodingRefreshType; }
+#if JCTVC_Y0038_PARAMS
+  bool      getReWriteParamSets             ()  const    { return m_rewriteParamSets; }
+#endif
   int       getGOPSize                      () const     { return  m_iGOPSize; }
   int       getMaxDecPicBuffering           (uint32_t tlayer) { return m_maxDecPicBuffering[tlayer]; }
   int       getNumReorderPics               (uint32_t tlayer) { return m_numReorderPics[tlayer]; }
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 626f8be0f..ac8c86733 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -2512,9 +2512,20 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
       /////////////////////////////////////////////////////////////////////////////////////////////////// File writing
 
       // write various parameter sets
+#if JCTVC_Y0038_PARAMS
+      bool writePS = m_bSeqFirst || (m_pcCfg->getReWriteParamSets() && (pcSlice->isIRAP()));
+      if (writePS)
+      {
+        m_pcEncLib->setParamSetChanged(pcSlice->getSPS()->getSPSId(), pcSlice->getPPS()->getPPSId());
+      }
+      actualTotalBits += xWriteParameterSets(accessUnit, pcSlice, writePS);
+      
+      if (writePS)
+#else
       actualTotalBits += xWriteParameterSets( accessUnit, pcSlice, m_bSeqFirst );
 
       if ( m_bSeqFirst )
+#endif
       {
         // create prefix SEI messages at the beginning of the sequence
         CHECK(!(leadingSeiMessages.empty()), "Unspecified error");
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index 86220ff6c..e6a11e25e 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -1852,6 +1852,14 @@ void  EncCfg::xCheckGSParameters()
 #endif
 }
 
+#if JCTVC_Y0038_PARAMS
+void EncLib::setParamSetChanged(int spsId, int ppsId)
+{
+  m_ppsMap.setChangedFlag(ppsId);
+  m_spsMap.setChangedFlag(spsId);
+}
+#endif
+
 bool EncLib::PPSNeedsWriting(int ppsId)
 {
   bool bChanged=m_ppsMap.getChangedFlag(ppsId);
diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h
index f966d8277..d143e79b2 100644
--- a/source/Lib/EncoderLib/EncLib.h
+++ b/source/Lib/EncoderLib/EncLib.h
@@ -217,6 +217,9 @@ public:
   );
   int getReferencePictureSetIdxForSOP(int POCCurr, int GOPid );
 
+#if JCTVC_Y0038_PARAMS
+  void                   setParamSetChanged(int spsId, int ppsId);
+#endif
   bool                   PPSNeedsWriting(int ppsId);
   bool                   SPSNeedsWriting(int spsId);
   const PPS* getPPS( int Id ) { return m_ppsMap.getPS( Id); }
-- 
GitLab