From ea661f01ef6e8013975e603b3114f176572380ae Mon Sep 17 00:00:00 2001
From: Philip Cowan <cowanp@sharplabs.com>
Date: Sun, 8 Dec 2019 14:24:03 -0800
Subject: [PATCH] JVET P0181 implementation

---
 source/Lib/CommonLib/SEI.cpp       |  3 +++
 source/Lib/CommonLib/SEI.h         |  6 ++++++
 source/Lib/CommonLib/TypeDef.h     |  3 +++
 source/Lib/DecoderLib/SEIread.cpp  | 15 ++++++++++++++-
 source/Lib/EncoderLib/SEIwrite.cpp | 11 +++++++++--
 5 files changed, 35 insertions(+), 3 deletions(-)

diff --git a/source/Lib/CommonLib/SEI.cpp b/source/Lib/CommonLib/SEI.cpp
index b4e2ae744..d1540cde5 100644
--- a/source/Lib/CommonLib/SEI.cpp
+++ b/source/Lib/CommonLib/SEI.cpp
@@ -118,6 +118,9 @@ void SEIBufferingPeriod::copyTo (SEIBufferingPeriod& target) const
   target.m_bpDecodingUnitHrdParamsPresentFlag = m_bpDecodingUnitHrdParamsPresentFlag;
   target.m_decodingUnitCpbParamsInPicTimingSeiFlag = m_decodingUnitCpbParamsInPicTimingSeiFlag;
 #endif
+#if JVET_P0181
+  target.m_sublayerInitialCpbRemovalDelayPresentFlag = m_sublayerInitialCpbRemovalDelayPresentFlag;
+#endif
 }
 
 void SEIPictureTiming::copyTo (SEIPictureTiming& target) const
diff --git a/source/Lib/CommonLib/SEI.h b/source/Lib/CommonLib/SEI.h
index 0f19ff32d..68236540e 100644
--- a/source/Lib/CommonLib/SEI.h
+++ b/source/Lib/CommonLib/SEI.h
@@ -196,6 +196,9 @@ public:
 #if JVET_P0202_P0203_FIX_HRD_RELATED_SEI
   , m_bpDecodingUnitHrdParamsPresentFlag (false)
   , m_decodingUnitCpbParamsInPicTimingSeiFlag (false)
+#endif
+#if JVET_P0181
+    , m_sublayerInitialCpbRemovalDelayPresentFlag(false)
 #endif
   {
     ::memset(m_initialCpbRemovalDelay, 0, sizeof(m_initialCpbRemovalDelay));
@@ -229,6 +232,9 @@ public:
   bool m_bpDecodingUnitHrdParamsPresentFlag;
   bool m_decodingUnitCpbParamsInPicTimingSeiFlag;
 #endif
+#if JVET_P0181
+  bool m_sublayerInitialCpbRemovalDelayPresentFlag;
+#endif
 };
 
 class SEIPictureTiming : public SEI
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index c9b72c627..5fba4a2d4 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -234,6 +234,9 @@
 
 #define JVET_M0497_MATRIX_MULT                            0 // 0: Fast method; 1: Matrix multiplication
 
+#define JVET_P0181                                        1 // JVET-P0181 : Modifications to HRD information signalling
+
+
 #define APPLY_SBT_SL_ON_MTS                               1 // apply save & load fast algorithm on inter MTS when SBT is on
 
 #define HEVC_SEI                                          0 // SEI messages that are defined in HEVC, but not in VVC
diff --git a/source/Lib/DecoderLib/SEIread.cpp b/source/Lib/DecoderLib/SEIread.cpp
index 085546b46..ae948b5c7 100644
--- a/source/Lib/DecoderLib/SEIread.cpp
+++ b/source/Lib/DecoderLib/SEIread.cpp
@@ -618,6 +618,13 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
     }
   }
 #endif
+#if JVET_P0181
+  else
+  {
+    sei.m_duCpbRemovalDelayIncrementLength = 24;
+    sei.m_dpbOutputDelayDuLength = 24;
+  }
+#endif
 
   sei_read_flag( pDecodedMessageOutputStream, code, "concatenation_flag");
   sei.m_concatenationFlag = code;
@@ -634,7 +641,13 @@ void SEIReader::xParseSEIBufferingPeriod(SEIBufferingPeriod& sei, uint32_t paylo
     }
   }
   sei_read_code( pDecodedMessageOutputStream, 3, code, "bp_max_sub_layers_minus1" );     sei.m_bpMaxSubLayers = code + 1;
-  for( i = 0; i < sei.m_bpMaxSubLayers; i ++ )
+#if JVET_P0181
+  sei_read_flag(pDecodedMessageOutputStream, code, "sublayer_initial_cpb_removal_delay_present_flag");
+  sei.m_sublayerInitialCpbRemovalDelayPresentFlag = code;
+  for (i = (sei.m_sublayerInitialCpbRemovalDelayPresentFlag ? 0 : sei.m_bpMaxSubLayers - 1); i < sei.m_bpMaxSubLayers; i++)
+#else
+  for (i = 0; i < sei.m_bpMaxSubLayers; i++)
+#endif
   {
     sei_read_uvlc( pDecodedMessageOutputStream, code, "bp_cpb_cnt_minus1[i]" ); sei.m_bpCpbCnt[i] = code + 1;
     for( nalOrVcl = 0; nalOrVcl < 2; nalOrVcl ++ )
diff --git a/source/Lib/EncoderLib/SEIwrite.cpp b/source/Lib/EncoderLib/SEIwrite.cpp
index 8b57a40df..849292935 100644
--- a/source/Lib/EncoderLib/SEIwrite.cpp
+++ b/source/Lib/EncoderLib/SEIwrite.cpp
@@ -328,7 +328,9 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SP
 {
   WRITE_FLAG( sei.m_bpNalCpbParamsPresentFlag, "bp_nal_hrd_parameters_present_flag");
   WRITE_FLAG( sei.m_bpVclCpbParamsPresentFlag, "bp_vcl_hrd_parameters_present_flag");
-
+#if JVET_P0181
+  CHECK(!sei.m_bpNalCpbParamsPresentFlag && !sei.m_bpVclCpbParamsPresentFlag, "bp_nal_hrd_parameters_present_flag and/or bp_vcl_hrd_parameters_present_flag must be true");
+#endif
 #if JVET_P0202_P0203_FIX_HRD_RELATED_SEI 
   CHECK (sei.m_initialCpbRemovalDelayLength < 1, "sei.m_initialCpbRemovalDelayLength must be > 0");
   WRITE_CODE( sei.m_initialCpbRemovalDelayLength - 1, 5, "initial_cpb_removal_delay_length_minus1" );
@@ -381,7 +383,12 @@ void SEIWriter::xWriteSEIBufferingPeriod(const SEIBufferingPeriod& sei, const SP
     CHECK (sei.m_bpMaxSubLayers < 1, "bp_max_sub_layers_minus1 must be > 0");
     WRITE_CODE( sei.m_bpMaxSubLayers - 1,        3, "bp_max_sub_layers_minus1" );
   }
-  for( int i = 0; i < sei.m_bpMaxSubLayers; i ++ )
+#if JVET_P0181
+  WRITE_FLAG(sei.m_sublayerInitialCpbRemovalDelayPresentFlag, "sublayer_initial_cpb_removal_delay_present_flag");
+  for (int i = (sei.m_sublayerInitialCpbRemovalDelayPresentFlag ? 0 : sei.m_bpMaxSubLayers - 1); i < sei.m_bpMaxSubLayers; i++)
+#else
+  for (int i = 0; i < sei.m_bpMaxSubLayers; i++)
+#endif
   {
     CHECK (sei.m_bpCpbCnt[i] < 1, "sei.m_bpCpbCnt[i] must be > 0");
     WRITE_UVLC( sei.m_bpCpbCnt[i] - 1, "bp_cpb_cnt_minus1[i]");
-- 
GitLab