From f2ccc1eac993d319f1e78d81eb11ab6d48b5272f Mon Sep 17 00:00:00 2001
From: yonghe <yonghe@qti.qualcomm.com>
Date: Wed, 7 Oct 2020 13:37:05 -0700
Subject: [PATCH] JVET-S0115 aspect 2 (JVET-S0142 item 4): Change the name and
 semantics of vps_all_layers_same_num_sublayers_flag (to be
 vps_default_ptl_dpb_hrd_max_tid_flag) to only control VPS syntax without
 requiring the number of sublayers to be the same for all layers.

---
 doc/software-manual.tex             |  4 ++--
 source/App/EncoderApp/EncApp.cpp    |  4 ++++
 source/App/EncoderApp/EncAppCfg.cpp |  4 ++++
 source/App/EncoderApp/EncAppCfg.h   |  4 ++++
 source/Lib/CommonLib/Slice.cpp      |  6 +++++-
 source/Lib/CommonLib/Slice.h        | 10 +++++++++-
 source/Lib/CommonLib/TypeDef.h      |  4 ++++
 source/Lib/DecoderLib/VLCReader.cpp | 20 +++++++++++++++++++
 source/Lib/EncoderLib/EncLib.cpp    |  4 ++++
 source/Lib/EncoderLib/VLCWriter.cpp | 31 +++++++++++++++++++++++++++++
 10 files changed, 87 insertions(+), 4 deletions(-)

diff --git a/doc/software-manual.tex b/doc/software-manual.tex
index 28b101031..a03303996 100644
--- a/doc/software-manual.tex
+++ b/doc/software-manual.tex
@@ -1434,10 +1434,10 @@ Specifies the value to use to derive the vps_max_layers_minus1 for layered codin
 Specifies the maximum number of temporal sublayers to signal in the VPS
 \\
 
-\Option{AllLayersSameNumSublayersFlag} &
+\Option{DefaultPtlDpbHrdMaxTidFlag} &
 %\ShortOption{\None} &
 \Default{true} &
-Specifies the value of vps_all_layers_same_num_sublayers_flag in the VPS
+Specifies the value of vps_default_ptl_dpb_hrd_max_tid_flag in the VPS
 \\
 
 \Option{AllowablePredDirection} &
diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp
index a8e6f25ff..d1ce75161 100644
--- a/source/App/EncoderApp/EncApp.cpp
+++ b/source/App/EncoderApp/EncApp.cpp
@@ -95,7 +95,11 @@ void EncApp::xInitLibCfg()
   vps.setMaxSubLayers(m_maxSublayers);
   if (vps.getMaxLayers() > 1 && vps.getMaxSubLayers() > 1)
   {
+#if JVET_S0115_VPS
+    vps.setDefaultPtlDpbHrdMaxTidFlag(m_defaultPtlDpbHrdMaxTidFlag);
+#else
     vps.setAllLayersSameNumSublayersFlag(m_allLayersSameNumSublayersFlag);
+#endif
   }
   if (vps.getMaxLayers() > 1)
   {
diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp
index 6debc104a..e2c592481 100644
--- a/source/App/EncoderApp/EncAppCfg.cpp
+++ b/source/App/EncoderApp/EncAppCfg.cpp
@@ -1471,7 +1471,11 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] )
   ;
   opts.addOptions()
   ( "MaxSublayers",                                   m_maxSublayers,                               7, "Max number of Sublayers")
+#if JVET_S0115_VPS
+  ( "DefaultPtlDpbHrdMaxTidFlag",                     m_defaultPtlDpbHrdMaxTidFlag,              true, "specifies that the syntax elements vps_ptl_max_tid[ i ], vps_dpb_max_tid[ i ], and vps_hrd_max_tid[ i ] are not present and are inferred to be equal to the default value vps_max_sublayers_minus1")
+#else
   ( "AllLayersSameNumSublayersFlag",                  m_allLayersSameNumSublayersFlag,           true, "All layers same num sublayersflag")
+#endif
   ( "AllIndependentLayersFlag",                       m_allIndependentLayersFlag,                true, "All layers are independent layer")
   ("AllowablePredDirection",                          m_predDirectionArray, string(""),                "prediction directions allowed for i-th temporal layer")
   ( "LayerId%d",                                      m_layerId,                    0, MAX_VPS_LAYERS, "Max number of Sublayers")
diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h
index 8337d391e..b51d4ed9e 100644
--- a/source/App/EncoderApp/EncAppCfg.h
+++ b/source/App/EncoderApp/EncAppCfg.h
@@ -753,7 +753,11 @@ protected:
   int         m_layerId[MAX_VPS_LAYERS];
   int         m_layerIdx;
   int         m_maxSublayers;
+#if JVET_S0115_VPS
+  bool        m_defaultPtlDpbHrdMaxTidFlag;
+#else
   bool        m_allLayersSameNumSublayersFlag;
+#endif
   bool        m_allIndependentLayersFlag;
   std::string m_predDirectionArray;
 
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index 1f65e12e2..91f2da85a 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -2427,7 +2427,11 @@ VPS::VPS()
   : m_VPSId(0)
   , m_maxLayers(1)
   , m_vpsMaxSubLayers(7)
-  , m_vpsAllLayersSameNumSubLayersFlag (true)
+#if JVET_S0115_VPS
+  , m_vpsDefaultPtlDpbHrdMaxTidFlag (true)
+#else
+  , m_vpsAllLayersSameNumSubLayersFlag(true)
+#endif
   , m_vpsAllIndependentLayersFlag(true)
   , m_vpsEachLayerIsAnOlsFlag (1)
   , m_vpsOlsModeIdc (0)
diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h
index fc5c2d30c..5651573c4 100644
--- a/source/Lib/CommonLib/Slice.h
+++ b/source/Lib/CommonLib/Slice.h
@@ -1054,7 +1054,11 @@ private:
 
   uint32_t              m_vpsMaxSubLayers;
   uint32_t              m_vpsLayerId[MAX_VPS_LAYERS];
+#if JVET_S0115_VPS
+  bool                  m_vpsDefaultPtlDpbHrdMaxTidFlag;
+#else
   bool                  m_vpsAllLayersSameNumSubLayersFlag;
+#endif
   bool                  m_vpsAllIndependentLayersFlag;
   uint32_t              m_vpsCfgPredDirection[MAX_VPS_SUBLAYERS];
   bool                  m_vpsIndependentLayerFlag[MAX_VPS_LAYERS];
@@ -1122,9 +1126,13 @@ public:
 
   uint32_t          getMaxSubLayers() const                              { return m_vpsMaxSubLayers;                                        }
   void              setMaxSubLayers(uint32_t value)                      { m_vpsMaxSubLayers = value;                                       }
-
+#if JVET_S0115_VPS
+  bool              getDefaultPtlDpbHrdMaxTidFlag() const { return m_vpsDefaultPtlDpbHrdMaxTidFlag; }
+  void              setDefaultPtlDpbHrdMaxTidFlag(bool t) { m_vpsDefaultPtlDpbHrdMaxTidFlag = t; }
+#else
   bool              getAllLayersSameNumSublayersFlag() const { return m_vpsAllLayersSameNumSubLayersFlag; }
   void              setAllLayersSameNumSublayersFlag(bool t) { m_vpsAllLayersSameNumSubLayersFlag = t; }
+#endif
 
   uint32_t          getLayerId(uint32_t layerIdx) const { return m_vpsLayerId[layerIdx]; }
   void              setLayerId(uint32_t layerIdx, uint32_t layerId) { m_vpsLayerId[layerIdx] = layerId; }
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 69a3d9b79..1bf76942d 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -188,6 +188,10 @@
                                                             // JVET-S0195: replace one_subpic_per_pic_constraint_flag with no_subpic_info_constraint_flag and its semantics
                                                             //             add no_idr_rpl_constraint_flag
 
+#define JVET_S0115_VPS                                    1 // JVET-S0115 aspect 2 (JVET-S0142 item 4): Change the name and semantics of vps_all_layers_same_num_sublayers_flag 
+                                                            // (to be vps_default_ptl_dpb_hrd_max_tid_flag) to only control VPS syntax without requiring the number of sublayers 
+                                                            // to be the same for all layers.
+
 #define JVET_S0182_RPL_SIGNALLING                         1 // JVET-S0182: modifications to rpl information signalling
 
 #define JVET_S0185_PROPOSAl1_PICTURE_TIMING_CLEANUP       1 // JVET-S0185: Proposal 1, put syntax element pt_cpb_removal_delay_minus1[] first, followed by similar information for sub-layers, followed by pt_dpb_output_delay
diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp
index 33a25a188..4a75a41ba 100644
--- a/source/Lib/DecoderLib/VLCReader.cpp
+++ b/source/Lib/DecoderLib/VLCReader.cpp
@@ -2463,11 +2463,19 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS)
   READ_CODE(3, uiCode, "vps_max_sublayers_minus1");           pcVPS->setMaxSubLayers(uiCode + 1); CHECK(uiCode + 1 > MAX_VPS_SUBLAYERS, "Signalled number of sublayers larger than MAX_VPS_SUBLAYERS.");
   if( pcVPS->getMaxLayers() > 1 && pcVPS->getMaxSubLayers() > 1)
   {
+#if JVET_S0115_VPS
+    READ_FLAG(uiCode, "vps_default_ptl_dpb_hrd_max_tid_flag"); pcVPS->setDefaultPtlDpbHrdMaxTidFlag(uiCode);
+#else
     READ_FLAG(uiCode, "vps_all_layers_same_num_sublayers_flag"); pcVPS->setAllLayersSameNumSublayersFlag(uiCode);
+#endif
   }
   else
   {
+#if JVET_S0115_VPS
+    pcVPS->setDefaultPtlDpbHrdMaxTidFlag(1);
+#else
     pcVPS->setAllLayersSameNumSublayersFlag(1);
+#endif
   }
   if( pcVPS->getMaxLayers() > 1 )
   {
@@ -2571,7 +2579,11 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS)
     }
     else
       pcVPS->setPtPresentFlag(0, 1);
+#if JVET_S0115_VPS
+    if (!pcVPS->getDefaultPtlDpbHrdMaxTidFlag())
+#else
     if (!pcVPS->getAllLayersSameNumSublayersFlag())
+#endif
     {
       READ_CODE(3, uiCode, "vps_ptl_max_tid");
       pcVPS->setPtlMaxTemporalId(i, uiCode);
@@ -2636,7 +2648,11 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS)
 
     for( int i = 0; i < pcVPS->m_numDpbParams; i++ )
     {
+#if JVET_S0115_VPS
+      if (!pcVPS->getDefaultPtlDpbHrdMaxTidFlag())
+#else
       if (!pcVPS->getAllLayersSameNumSublayersFlag())
+#endif
       {
         READ_CODE(3, uiCode, "vps_dpb_max_tid[i]");
         pcVPS->m_dpbMaxTemporalId.push_back(uiCode);
@@ -2730,7 +2746,11 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS)
     pcVPS->m_olsHrdParams.resize(pcVPS->getNumOlsTimingHrdParamsMinus1(), std::vector<OlsHrdParams>(pcVPS->getMaxSubLayers()));
     for (int i = 0; i <= pcVPS->getNumOlsTimingHrdParamsMinus1(); i++)
     {
+#if JVET_S0115_VPS
+      if (!pcVPS->getDefaultPtlDpbHrdMaxTidFlag())
+#else
       if (!pcVPS->getAllLayersSameNumSublayersFlag())
+#endif
       {
         READ_CODE(3, uiCode, "vps_hrd_max_tid[i]");  pcVPS->setHrdMaxTid(i, uiCode);
 #if JVET_S0100_ASPECT3
diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp
index 2d5f26806..857c006cf 100644
--- a/source/Lib/EncoderLib/EncLib.cpp
+++ b/source/Lib/EncoderLib/EncLib.cpp
@@ -1061,7 +1061,11 @@ void EncLib::xInitVPS( const SPS& sps )
       }
       else
       {
+#if JVET_S0115_VPS
+        if( m_vps->getDefaultPtlDpbHrdMaxTidFlag() )
+#else
         if( m_vps->getAllLayersSameNumSublayersFlag() )
+#endif
         {
           // When vps_max_sublayers_minus1 is greater than 0 and vps_all_layers_same_num_sublayers_flag is equal to 1, the value of vps_dpb_max_tid[ dpbIdx ] is inferred to be equal to vps_max_sublayers_minus1.
           m_vps->m_dpbMaxTemporalId[dpbIdx] = m_vps->getMaxSubLayers() - 1;
diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp
index 34d6fa228..cd8cd615b 100644
--- a/source/Lib/EncoderLib/VLCWriter.cpp
+++ b/source/Lib/EncoderLib/VLCWriter.cpp
@@ -1531,7 +1531,11 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
   WRITE_CODE(pcVPS->getMaxSubLayers() - 1, 3, "vps_max_sublayers_minus1");
   if (pcVPS->getMaxLayers() > 1 && pcVPS->getMaxSubLayers() > 1)
   {
+#if JVET_S0115_VPS
+    WRITE_FLAG(pcVPS->getDefaultPtlDpbHrdMaxTidFlag(), "vps_default_ptl_dpb_hrd_max_tid_flag");
+#else
     WRITE_FLAG(pcVPS->getAllLayersSameNumSublayersFlag(), "vps_all_layers_same_num_sublayers_flag");
+#endif
   }
   if (pcVPS->getMaxLayers() > 1)
   {
@@ -1599,8 +1603,17 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
   {
     if(i > 0)
       WRITE_FLAG(pcVPS->getPtPresentFlag(i), "vps_pt_present_flag");
+#if JVET_S0115_VPS
+    if (!pcVPS->getDefaultPtlDpbHrdMaxTidFlag()) {
+      WRITE_CODE(pcVPS->getPtlMaxTemporalId(i), 3, "vps_ptl_max_tid");
+    }
+    else {
+      CHECK(pcVPS->getPtlMaxTemporalId(i) != pcVPS->getMaxSubLayers() - 1, "When vps_default_ptl_dpb_hrd_max_tid_flag is equal to 1, the value of vps_ptl_max_tid[ i ] is inferred to be equal to vps_max_sublayers_minus1");
+    }
+#else
     if (!pcVPS->getAllLayersSameNumSublayersFlag())
       WRITE_CODE(pcVPS->getPtlMaxTemporalId(i) ,3, "vps_ptl_max_tid");
+#endif
   }
   int cnt = 0;
   while (m_pcBitIf->getNumBitsUntilByteAligned())
@@ -1634,13 +1647,21 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
 
     for( int i = 0; i < pcVPS->m_numDpbParams; i++ )
     {
+#if JVET_S0115_VPS
+      if (!pcVPS->getDefaultPtlDpbHrdMaxTidFlag())
+#else
       if (!pcVPS->getAllLayersSameNumSublayersFlag())
+#endif
       {
         WRITE_CODE(pcVPS->m_dpbMaxTemporalId[i], 3, "vps_dpb_max_tid[i]");
       }
       else
       {
+#if JVET_S0115_VPS
+        CHECK(pcVPS->m_dpbMaxTemporalId[i] != pcVPS->getMaxSubLayers() - 1, "When vps_default_ptl_dpb_hrd_max_tid_flag is equal to 1, the value of vps_dpb_max_tid[ i ] is inferred to be equal to vps_max_sublayers_minus1");
+#else
         CHECK(pcVPS->m_dpbMaxTemporalId[i] != pcVPS->getMaxSubLayers() - 1, "When vps_all_layers_same_num_sublayers_flag is equal to 1, the value of vps_dpb_max_tid[ i ] is inferred to be equal to vps_max_sublayers_minus1");
+#endif
       }
 
       for( int j = ( pcVPS->m_sublayerDpbParamsPresentFlag ? 0 : pcVPS->m_dpbMaxTemporalId[i] ); j <= pcVPS->m_dpbMaxTemporalId[i]; j++ )
@@ -1688,10 +1709,20 @@ void HLSWriter::codeVPS(const VPS* pcVPS)
     WRITE_UVLC(pcVPS->getNumOlsTimingHrdParamsMinus1(), "vps_num_ols_timing_hrd_params_minus1");
     for (int i = 0; i <= pcVPS->getNumOlsTimingHrdParamsMinus1(); i++)
     {
+#if JVET_S0115_VPS
+      if (!pcVPS->getDefaultPtlDpbHrdMaxTidFlag())
+      {
+        WRITE_CODE(pcVPS->getHrdMaxTid(i), 3, "vps_hrd_max_tid[i]");
+      }
+      else {
+        CHECK(pcVPS->getHrdMaxTid(i) != pcVPS->getMaxSubLayers() - 1, "When vps_default_ptl_dpb_hrd_max_tid_flag is equal to 1, the value of vps_hrd_max_tid[ i ] is inferred to be equal to vps_max_sublayers_minus1");
+      }
+#else
       if (!pcVPS->getAllLayersSameNumSublayersFlag())
       {
         WRITE_CODE(pcVPS->getHrdMaxTid(i), 3, "vps_hrd_max_tid[i]");
       }
+#endif
       uint32_t firstSublayer = pcVPS->getVPSSublayerCpbParamsPresentFlag() ? 0 : pcVPS->getHrdMaxTid(i);
       codeOlsHrdParameters(pcVPS->getGeneralHrdParameters(), pcVPS->getOlsHrdParameters(i),firstSublayer, pcVPS->getHrdMaxTid(i));
     }
-- 
GitLab