From e329b87f74f11f1a3cd55ddbe97d800de2b620fe Mon Sep 17 00:00:00 2001
From: Philip Cowan <cowanp@sharplabs.com>
Date: Wed, 4 Sep 2019 10:41:16 -0700
Subject: [PATCH] Initial update to support JVET_N0865 syntax

---
 source/App/Parcat/parcat.cpp        | 10 ++--
 source/Lib/CommonLib/Slice.cpp      |  4 ++
 source/Lib/CommonLib/Slice.h        | 18 ++++++++
 source/Lib/CommonLib/TypeDef.h      |  1 +
 source/Lib/DecoderLib/VLCReader.cpp | 72 ++++++++++++++++++++++++++---
 source/Lib/EncoderLib/VLCWriter.cpp | 31 +++++++++++--
 6 files changed, 123 insertions(+), 13 deletions(-)

diff --git a/source/App/Parcat/parcat.cpp b/source/App/Parcat/parcat.cpp
index 7198e05adf..f5929cc16e 100644
--- a/source/App/Parcat/parcat.cpp
+++ b/source/App/Parcat/parcat.cpp
@@ -59,11 +59,13 @@ bool ParcatHLSyntaxReader::parseSliceHeaderUpToPoc ( ParameterSetManager *parame
   SPS* sps = NULL;
 
   uint32_t firstSliceSegmentInPic;
-  if( isRapPic )
+#if !JVET_N0865_SYNTAX
+  if (isRapPic)
   {
-    READ_FLAG( uiCode, "no_output_of_prior_pics_flag" );  //ignored -- updated already
+    READ_FLAG(uiCode, "no_output_of_prior_pics_flag");   // ignored -- updated already
   }
-  READ_UVLC (    uiCode, "slice_pic_parameter_set_id" );
+#endif
+  READ_UVLC(uiCode, "slice_pic_parameter_set_id");
   pps = parameterSetManager->getPPS(uiCode);
   //!KS: need to add error handling code here, if PPS is not available
   CHECK(pps==0, "Invalid PPS");
@@ -117,10 +119,12 @@ bool ParcatHLSyntaxReader::parseSliceHeaderUpToPoc ( ParameterSetManager *parame
   }
 
   READ_UVLC (    uiCode, "slice_type" );
+#if !JVET_N0865_SYNTAX
   if( pps->getOutputFlagPresentFlag() )
   {
     READ_FLAG( uiCode, "pic_output_flag" );
   }
+#endif
 
 
   return firstSliceSegmentInPic;
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index 64a2a402ce..25ff505ec5 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -1497,6 +1497,10 @@ SPS::SPS()
 , m_LadfIntervalLowerBound    { 0 }
 #endif
 , m_MIP                       ( false )
+#if JVET_N0865_SYNTAX
+    ,m_GDREnabledFlag         (1)
+#endif
+
 {
   for(int ch=0; ch<MAX_NUM_CHANNEL_TYPE; ch++)
   {
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index 9b9e55a811..84431823d5 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -896,6 +896,9 @@ private:
 #if JVET_O0650_SIGNAL_CHROMAQP_MAPPING_TABLE
   ChromaQpMappingTable m_chromaQpMappingTable;
 #endif
+#if JVET_N0865_SYNTAX
+  bool m_GDREnabledFlag;
+#endif
 
 public:
 
@@ -1185,6 +1188,10 @@ public:
   const ChromaQpMappingTable& getChromaQpMappingTable()                   const     { return m_chromaQpMappingTable;}
   int       getMappedChromaQpValue(ComponentID compID, int qpVal)         const     { return m_chromaQpMappingTable.getMappedChromaQpValue(compID, qpVal); }
 #endif
+#if JVET_N0865_SYNTAX
+  void setGDREnabledFlag(bool flag) { m_GDREnabledFlag = flag; }
+  bool getGDREnabledFlag() const { return m_GDREnabledFlag; }
+#endif
 };
 
 
@@ -1752,6 +1759,10 @@ private:
   uint32_t                   m_uiMaxTTSizeIChroma;
   uint32_t                   m_uiMaxBTSize;
 
+#if JVET_N0865_SYNTAX
+  int                        m_recoveryPocCnt;
+  int                        m_rpPicOrderCntVal;
+#endif
 #if JVET_O_MAX_NUM_ALF_APS_8
   APS*                       m_alfApss[ALF_CTB_MAX_NUM_APS];
 #else
@@ -2086,6 +2097,13 @@ public:
   bool                        checkRPR();
   const std::pair<int, int>&  getScalingRatio( const RefPicList refPicList, const int refIdx )  const { return m_scalingRatio[refPicList][refIdx]; }
 #endif
+#if JVET_N0865_SYNTAX
+  void                        setRecoveryPocCnt(int value) { m_recoveryPocCnt = value; }
+  int                         getRecoveryPocCnt() const { return m_recoveryPocCnt; }
+  void                        setRpPicOrderCntVal(int value) { m_rpPicOrderCntVal = value; }
+  int                         getRpPicOrderCntVal() const { return m_rpPicOrderCntVal; }
+#endif
+
 protected:
   Picture*              xGetRefPic        (PicList& rcListPic, int poc);
   Picture*              xGetLongTermRefPic(PicList& rcListPic, int poc, bool pocHasMsb);
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 30184a08fa..66e97527bd 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -273,6 +273,7 @@
 
 #define JVET_N0100_PROPOSAL1                              1 // JVET-N0100: ltrp picture signalling
 
+#define JVET_N0865_SYNTAX                                 1 // JVET_N0865 syntax elements
 
 #define EMULATION_PREVENTION_FIX                          1 // fix for start code emulation reported in #270. Diverges from specification text
 
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index ee8adc7b12..c433d516d3 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -1169,6 +1169,11 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS)
 
   parseProfileTierLevel(pcSPS->getProfileTierLevel(), pcSPS->getMaxTLayers() - 1);
 
+#if JVET_N0865_SYNTAX
+  READ_FLAG(uiCode, "gdr_enabled_flag");
+  pcSPS->setGDREnabledFlag(uiCode);
+#endif
+
   READ_UVLC(uiCode, "sps_seq_parameter_set_id");           pcSPS->setSPSId(uiCode);
 
   READ_UVLC(     uiCode, "chroma_format_idc" );                  pcSPS->setChromaFormatIdc( ChromaFormat(uiCode) );
@@ -1715,12 +1720,15 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
   PPS* pps = NULL;
   SPS* sps = NULL;
 
-  if( pcSlice->getRapPicFlag())
+#if !JVET_N0865_SYNTAX
+  if (pcSlice->getRapPicFlag())
   {
-    READ_FLAG( uiCode, "no_output_of_prior_pics_flag" );  //ignored -- updated already
+    READ_FLAG(uiCode, "no_output_of_prior_pics_flag");   // ignored -- updated already
     pcSlice->setNoOutputPriorPicsFlag(uiCode ? true : false);
   }
-  READ_UVLC (    uiCode, "slice_pic_parameter_set_id" );  pcSlice->setPPSId(uiCode);
+#endif
+  READ_UVLC(uiCode, "slice_pic_parameter_set_id");
+  pcSlice->setPPSId(uiCode);
   pps = parameterSetManager->getPPS(uiCode);
   //!KS: need to add error handling code here, if PPS is not available
   CHECK(pps==0, "Invalid PPS");
@@ -1793,14 +1801,17 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
     }
 
     READ_UVLC (    uiCode, "slice_type" );            pcSlice->setSliceType((SliceType)uiCode);
-    if( pps->getOutputFlagPresentFlag() )
+#if !JVET_N0865_SYNTAX
+    if (pps->getOutputFlagPresentFlag())
     {
-      READ_FLAG( uiCode, "pic_output_flag" );    pcSlice->setPicOutputFlag( uiCode ? true : false );
+      READ_FLAG(uiCode, "pic_output_flag");
+      pcSlice->setPicOutputFlag(uiCode ? true : false);
     }
     else
     {
-      pcSlice->setPicOutputFlag( true );
+      pcSlice->setPicOutputFlag(true);
     }
+#endif
 
     // if (separate_colour_plane_flag == 1)
     //   read colour_plane_id
@@ -1810,6 +1821,31 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
     {
       READ_CODE(sps->getBitsForPOC(), uiCode, "slice_pic_order_cnt_lsb");
       pcSlice->setPOC(uiCode);
+#if JVET_N0865_SYNTAX
+      if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_GRA)
+      {
+        READ_UVLC(uiCode, "recovery_poc_cnt");
+        int maxPicOrderCntLsb = (int) pow(2, pcSlice->getSPS()->getBitsForPOC());
+        CHECK(uiCode < maxPicOrderCntLsb, "recovery_poc_cnt > MaxPicOrderCntLsb ? 1");
+        pcSlice->setRecoveryPocCnt(uiCode);
+        pcSlice->setRpPicOrderCntVal(pcSlice->getPOC() + pcSlice->getRecoveryPocCnt());
+      }
+      if (pcSlice->getRapPicFlag() || (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_GRA))
+      {
+        READ_FLAG(uiCode, "no_output_of_prior_pics_flag");
+        pcSlice->setNoOutputPriorPicsFlag(uiCode);
+      }
+      if (pps->getOutputFlagPresentFlag())
+      {
+        READ_FLAG(uiCode, "pic_output_flag");
+        pcSlice->setPicOutputFlag(uiCode ? true : false);
+      }
+      else
+      {
+        pcSlice->setPicOutputFlag(true);
+      }
+#endif
+
       ReferencePictureList* rpl0 = pcSlice->getLocalRPL0();
       (*rpl0) = ReferencePictureList();
       pcSlice->setRPL0(rpl0);
@@ -1839,6 +1875,30 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para
         iPOCmsb = iPrevPOCmsb;
       }
       pcSlice->setPOC              (iPOCmsb+iPOClsb);
+#if JVET_N0865_SYNTAX
+      if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_GRA)
+      {
+        READ_UVLC(uiCode, "recovery_poc_cnt");
+        int maxPicOrderCntLsb = (int) pow(2, pcSlice->getSPS()->getBitsForPOC());
+        CHECK(uiCode < maxPicOrderCntLsb, "recovery_poc_cnt > MaxPicOrderCntLsb ? 1");
+        pcSlice->setRecoveryPocCnt(uiCode);
+        pcSlice->setRpPicOrderCntVal(pcSlice->getPOC() + pcSlice->getRecoveryPocCnt());
+      }
+      if (pcSlice->getRapPicFlag() || (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_GRA))
+      {
+        READ_FLAG(uiCode, "no_output_of_prior_pics_flag");
+        pcSlice->setNoOutputPriorPicsFlag(uiCode);
+      }
+      if (pps->getOutputFlagPresentFlag())
+      {
+        READ_FLAG(uiCode, "pic_output_flag");
+        pcSlice->setPicOutputFlag(uiCode ? true : false);
+      }
+      else
+      {
+        pcSlice->setPicOutputFlag(true);
+      }
+#endif
 
       //Read L0 related syntax elements
       if (sps->getNumRPL0() > 0)
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index ccefb18d04..c33e623e90 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -788,6 +788,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS )
   WRITE_CODE(0,                          5, "sps_reserved_zero_5bits");
 
   codeProfileTierLevel( pcSPS->getProfileTierLevel(), pcSPS->getMaxTLayers() - 1 );
+#if JVET_N0865_SYNTAX
+  WRITE_FLAG(pcSPS->getGDREnabledFlag(), "gdr_enabled_flag");
+#endif
 
   WRITE_UVLC(pcSPS->getSPSId (), "sps_seq_parameter_set_id");
 
@@ -1220,10 +1223,12 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
   const uint32_t         numberValidComponents = getNumberValidComponents(format);
   const bool         chromaEnabled         = isChromaEnabled(format);
 
-  if ( pcSlice->getRapPicFlag() )
+#if !JVET_N0865_SYNTAX
+  if (pcSlice->getRapPicFlag())
   {
-    WRITE_FLAG( pcSlice->getNoOutputPriorPicsFlag() ? 1 : 0, "no_output_of_prior_pics_flag" );
+    WRITE_FLAG(pcSlice->getNoOutputPriorPicsFlag() ? 1 : 0, "no_output_of_prior_pics_flag");
   }
+#endif
   WRITE_UVLC( pcSlice->getPPS()->getPPSId(), "slice_pic_parameter_set_id" );
   int bitsSliceAddress = 1;
   if (!pcSlice->getPPS()->getRectSliceFlag())
@@ -1270,14 +1275,32 @@ void HLSWriter::codeSliceHeader         ( Slice* pcSlice )
 
     WRITE_UVLC( pcSlice->getSliceType(), "slice_type" );
 
-    if( pcSlice->getPPS()->getOutputFlagPresentFlag() )
+#if !JVET_N0865_SYNTAX
+    if (pcSlice->getPPS()->getOutputFlagPresentFlag())
     {
-      WRITE_FLAG( pcSlice->getPicOutputFlag() ? 1 : 0, "pic_output_flag" );
+      WRITE_FLAG(pcSlice->getPicOutputFlag() ? 1 : 0, "pic_output_flag");
     }
+#endif
 
     int pocBits = pcSlice->getSPS()->getBitsForPOC();
     int pocMask = (1 << pocBits) - 1;
     WRITE_CODE(pcSlice->getPOC() & pocMask, pocBits, "slice_pic_order_cnt_lsb");
+#if JVET_N0865_SYNTAX
+    if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_GRA)
+    {
+      int maxPicOrderCntLsb = (int) pow(2, pcSlice->getSPS()->getBitsForPOC());
+      CHECK((pcSlice->getRecoveryPocCnt() < maxPicOrderCntLsb), "recovery_poc_cnt > MaxPicOrderCntLsb ? 1");
+      WRITE_UVLC(pcSlice->getRecoveryPocCnt(), "recovery_poc_cnt");
+    }
+    if (pcSlice->getRapPicFlag() || (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_GRA))
+    {
+      WRITE_FLAG(pcSlice->getNoOutputPriorPicsFlag() ? 1 : 0, "no_output_of_prior_pics_flag");
+    }
+    if (pcSlice->getPPS()->getOutputFlagPresentFlag())
+    {
+      WRITE_FLAG(pcSlice->getPicOutputFlag() ? 1 : 0, "pic_output_flag");
+    }
+#endif
     if( !pcSlice->getIdrPicFlag() || pcSlice->getSPS()->getIDRRefParamListPresent())
     {
       //Write L0 related syntax elements
-- 
GitLab