From 234e2fd921dad8331aa136ebc016a7f06d8256d4 Mon Sep 17 00:00:00 2001
From: Philip Cowan <cowanp@sharplabs.com>
Date: Thu, 9 Jul 2020 02:10:10 +0200
Subject: [PATCH] JVET-R0107 Proposal 3: Modifications to bitstream extractor

---
 .../BitstreamExtractorApp.cpp                 | 55 +++++++++++++++++++
 .../BitstreamExtractorApp.h                   |  5 ++
 source/Lib/CommonLib/TypeDef.h                |  2 +
 3 files changed, 62 insertions(+)

diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp
index a8ef7870f..998482946 100644
--- a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp
+++ b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.cpp
@@ -105,6 +105,42 @@ void BitstreamExtractorApp::xReadPicHeader(InputNALUnit &nalu)
 }
 
 
+#if JVET_R0107_BITSTREAM_EXTACTION
+Slice BitstreamExtractorApp::xParseSliceHeader(InputNALUnit &nalu)
+{
+  m_hlSynaxReader.setBitstream(&nalu.getBitstream());
+  Slice slice;
+  slice.initSlice();
+  slice.setNalUnitType(nalu.m_nalUnitType);
+  slice.setNalUnitLayerId(nalu.m_nuhLayerId);
+  slice.setTLayer(nalu.m_temporalId);
+
+  m_hlSynaxReader.parseSliceHeader(&slice, &m_picHeader, &m_parameterSetManager, m_prevTid0Poc, m_prevPicPOC);
+  
+  return slice;
+}
+
+bool BitstreamExtractorApp::xCheckSliceSubpicture(Slice &slice, int targetSubPicId)
+{
+  PPS *pps = m_parameterSetManager.getPPS(m_picHeader.getPPSId());
+  CHECK(nullptr == pps, "referenced PPS not found");
+  SPS *sps = m_parameterSetManager.getSPS(pps->getSPSId());
+  CHECK(nullptr == sps, "referenced SPS not found");
+
+  if (sps->getSubPicInfoPresentFlag())
+  {
+    // subpic ID is explicitly indicated
+    msg(VERBOSE, "found slice subpic id %d\n", slice.getSliceSubPicId());
+    return (targetSubPicId == slice.getSliceSubPicId());
+  }
+  else
+  {
+    THROW("Subpicture signalling disbled, cannot extract.");
+  }
+
+  return true;
+}
+#else
 bool BitstreamExtractorApp::xCheckSliceSubpicture(InputNALUnit &nalu, int targetSubPicId)
 {
   m_hlSynaxReader.setBitstream(&nalu.getBitstream());
@@ -134,6 +170,7 @@ bool BitstreamExtractorApp::xCheckSliceSubpicture(InputNALUnit &nalu, int target
 
   return true;
 }
+#endif
 
 void BitstreamExtractorApp::xRewriteSPS (SPS &targetSPS, const SPS &sourceSPS, SubPic &subPic)
 {
@@ -353,7 +390,14 @@ void BitstreamExtractorApp::xWritePPS(PPS *pps, std::ostream& out, int layerId,
 // returns true, if the NAL unit is to be discarded
 bool BitstreamExtractorApp::xCheckNumSubLayers(InputNALUnit &nalu, VPS *vps)
 {
+#if JVET_R0107_BITSTREAM_EXTACTION
+  bool retval = (nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_IDR_N_LP)
+                && (nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_IDR_W_RADL)
+                && (nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_CRA)
+                && !( (nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_GDR) && (m_picHeader.getRecoveryPocCnt() == 0) );
+#else
   bool retval = (nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_IDR_N_LP) && (nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_IDR_W_RADL) && (nalu.m_nalUnitType != NAL_UNIT_CODED_SLICE_CRA);
+#endif
 
   retval &= nalu.m_temporalId >= vps->getNumSubLayersInLayerInOLS(m_targetOlsIdx, vps->getGeneralLayerIdx(nalu.m_nuhLayerId));
 
@@ -624,12 +668,23 @@ uint32_t BitstreamExtractorApp::decode()
           delete vps;
         }
       }
+#if JVET_R0107_BITSTREAM_EXTACTION
+      Slice slice;
+      if (nalu.isSlice())
+      {
+         slice = xParseSliceHeader(nalu);
+      }
+#endif
       if (m_subPicId>=0)
       {
         if ( nalu.isSlice() )
         {
           // check for subpicture ID
+#if JVET_R0107_BITSTREAM_EXTACTION
+          writeInpuNalUnitToStream = xCheckSliceSubpicture(slice, m_subPicId);
+#else
           writeInpuNalUnitToStream = xCheckSliceSubpicture(nalu, m_subPicId);
+#endif
         }
         if (nalu.m_nalUnitType == NAL_UNIT_FD)
         {
diff --git a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h
index 5ba460b39..748189bb3 100644
--- a/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h
+++ b/source/App/BitstreamExtractorApp/BitstreamExtractorApp.h
@@ -66,7 +66,12 @@ protected:
   void xRewriteSPS (SPS &targetSPS, const SPS &sourceSPS, SubPic &subPic);
   void xRewritePPS (PPS &targetPPS, const PPS &sourcePPS, SubPic &subPic);
 
+#if JVET_R0107_BITSTREAM_EXTACTION
+  Slice xParseSliceHeader(InputNALUnit &nalu);
+  bool  xCheckSliceSubpicture(Slice &slice, int subPicId);
+#else
   bool xCheckSliceSubpicture(InputNALUnit &nalu, int subPicId);
+#endif
   void xReadPicHeader(InputNALUnit &nalu);
 
   void xSetSPSUpdated(int spsId)   { return m_updatedSPSList.push_back(spsId); }
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 4a8190ad9..2bc42cbfe 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -66,6 +66,8 @@
 
 #define JVET_M0497_MATRIX_MULT                            0 // 0: Fast method; 1: Matrix multiplication
 
+#define JVET_R0107_BITSTREAM_EXTACTION                    1 // JVET-R0107 Proposal 3:Bitsteam extraction modifications
+
 #define APPLY_SBT_SL_ON_MTS                               1 // apply save & load fast algorithm on inter MTS when SBT is on
 
 typedef std::pair<int, bool> TrMode;
-- 
GitLab