From f67d9f5b246f94329bf145175a1ceddeec68920b Mon Sep 17 00:00:00 2001
From: zhipin <zhipin.deng@bytedance.com>
Date: Sun, 24 May 2020 15:00:57 +0800
Subject: [PATCH] store sub-picture numbers, sizes, and locations with a
 picture, so that they can be fetched directly from redPic

---
 source/Lib/CommonLib/Picture.cpp   |  3 +++
 source/Lib/CommonLib/Picture.h     |  7 +++++++
 source/Lib/CommonLib/UnitTools.cpp | 14 +++++++-------
 source/Lib/DecoderLib/DecLib.cpp   | 18 ++++++++++++++++++
 source/Lib/DecoderLib/DecSlice.cpp |  4 ++--
 source/Lib/EncoderLib/EncGOP.cpp   | 19 ++++++++++++++++++-
 source/Lib/EncoderLib/EncSlice.cpp |  2 +-
 7 files changed, 56 insertions(+), 11 deletions(-)

diff --git a/source/Lib/CommonLib/Picture.cpp b/source/Lib/CommonLib/Picture.cpp
index 79bf4e9f2f..3f70b6e976 100644
--- a/source/Lib/CommonLib/Picture.cpp
+++ b/source/Lib/CommonLib/Picture.cpp
@@ -195,6 +195,9 @@ Picture::Picture()
   m_spliceIdx = NULL;
   m_ctuNums = 0;
   layerId = NOT_VALID;
+#if JVET_R0058
+  numSubpics = 1;
+#endif
 }
 
 void Picture::create( const ChromaFormat &_chromaFormat, const Size &size, const unsigned _maxCUSize, const unsigned _margin, const bool _decoder, const int _layerId )
diff --git a/source/Lib/CommonLib/Picture.h b/source/Lib/CommonLib/Picture.h
index c7c4b9d4d1..771e69a13f 100644
--- a/source/Lib/CommonLib/Picture.h
+++ b/source/Lib/CommonLib/Picture.h
@@ -222,6 +222,13 @@ public:
   uint32_t layer;
   uint32_t depth;
   int      layerId;
+#if JVET_R0058
+  int  numSubpics;
+  std::vector<int> subpicWidthInCTUs;
+  std::vector<int> subpicHeightInCTUs;
+  std::vector<int> subpicCtuTopLeftX;
+  std::vector<int> subpicCtuTopLeftY;
+#endif
 
   bool subLayerNonReferencePictureDueToSTSA;
 
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 5379edb373..6a7075879b 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -149,7 +149,7 @@ void CU::checkConformanceILRP(Slice *slice)
     {
       const Picture* refPic = slice->getRefPic(eRefPicList, refIdx)->unscaledPic;
 
-      if (refPic->cs->pps->getNumSubPics() != slice->getPic()->cs->pps->getNumSubPics())
+      if (refPic->numSubpics != slice->getPic()->cs->pps->getNumSubPics())
       {
         isAllRefSameSubpicLayout = false;
         refList = numRefList;
@@ -157,12 +157,12 @@ void CU::checkConformanceILRP(Slice *slice)
       }
       else
       {
-        for (int i = 0; i < slice->getPic()->cs->pps->getNumSubPics(); i++)
+        for (int i = 0; i < refPic->numSubpics; i++)
         {
-          if (refPic->cs->pps->getSubPic(i).getSubPicWidthInCTUs() != slice->getPic()->cs->pps->getSubPic(i).getSubPicWidthInCTUs()
-            || refPic->cs->pps->getSubPic(i).getSubPicHeightInCTUs() != slice->getPic()->cs->pps->getSubPic(i).getSubPicHeightInCTUs()
-            || refPic->cs->pps->getSubPic(i).getSubPicCtuTopLeftX() != slice->getPic()->cs->pps->getSubPic(i).getSubPicCtuTopLeftX()
-            || refPic->cs->pps->getSubPic(i).getSubPicCtuTopLeftY() != slice->getPic()->cs->pps->getSubPic(i).getSubPicCtuTopLeftY())
+          if (refPic->subpicWidthInCTUs[i] != slice->getPic()->cs->pps->getSubPic(i).getSubPicWidthInCTUs()
+            || refPic->subpicHeightInCTUs[i] != slice->getPic()->cs->pps->getSubPic(i).getSubPicHeightInCTUs()
+            || refPic->subpicCtuTopLeftX[i] != slice->getPic()->cs->pps->getSubPic(i).getSubPicCtuTopLeftX()
+            || refPic->subpicCtuTopLeftY[i] != slice->getPic()->cs->pps->getSubPic(i).getSubPicCtuTopLeftY())
           {
             isAllRefSameSubpicLayout = false;
             refIdx = slice->getNumRefIdx(eRefPicList);
@@ -183,7 +183,7 @@ void CU::checkConformanceILRP(Slice *slice)
       for (int refIdx = 0; refIdx < slice->getNumRefIdx(eRefPicList); refIdx++)
       {
         const Picture* refPic = slice->getRefPic(eRefPicList, refIdx)->unscaledPic;
-        CHECK(!(refPic->layerId != slice->getPic()->layerId && refPic->cs->pps->getNumSubPics() == 1), "The inter-layer reference shall contain a single subpicture or have same subpicture layout with the current picture");
+        CHECK(!(refPic->layerId != slice->getPic()->layerId && refPic->numSubpics == 1), "The inter-layer reference shall contain a single subpicture or have same subpicture layout with the current picture");
       }
     }
   }
diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp
index 19cab91488..e4a774c071 100644
--- a/source/Lib/DecoderLib/DecLib.cpp
+++ b/source/Lib/DecoderLib/DecLib.cpp
@@ -2091,6 +2091,24 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl
     m_pcPic->setDecodingOrderNumber(m_decodingOrderCounter);
     m_decodingOrderCounter++;
     m_pcPic->setPictureType(nalu.m_nalUnitType);
+#if JVET_R0058
+    // store sub-picture numbers, sizes, and locations with a picture
+    if (sps->getSubPicInfoPresentFlag() && sps->getNumSubPics() > 1)
+    {
+      pcSlice->getPic()->numSubpics = sps->getNumSubPics();
+      pcSlice->getPic()->subpicWidthInCTUs.clear();
+      pcSlice->getPic()->subpicHeightInCTUs.clear();
+      pcSlice->getPic()->subpicCtuTopLeftX.clear();
+      pcSlice->getPic()->subpicCtuTopLeftY.clear();
+      for (int subPicIdx = 0; subPicIdx < sps->getNumSubPics(); subPicIdx++)
+      {
+        pcSlice->getPic()->subpicWidthInCTUs.push_back(pps->getSubPic(subPicIdx).getSubPicWidthInCTUs());
+        pcSlice->getPic()->subpicHeightInCTUs.push_back(pps->getSubPic(subPicIdx).getSubPicHeightInCTUs());
+        pcSlice->getPic()->subpicCtuTopLeftX.push_back(pps->getSubPic(subPicIdx).getSubPicCtuTopLeftX());
+        pcSlice->getPic()->subpicCtuTopLeftY.push_back(pps->getSubPic(subPicIdx).getSubPicCtuTopLeftY());
+      }
+    }
+#endif
   }
   pcSlice->checkCRA(pcSlice->getRPL0(), pcSlice->getRPL1(), m_pocCRA, m_cListPic);
   pcSlice->constructRefPicList(m_cListPic);
diff --git a/source/Lib/DecoderLib/DecSlice.cpp b/source/Lib/DecoderLib/DecSlice.cpp
index 7b4bd8d95a..335b79ae49 100644
--- a/source/Lib/DecoderLib/DecSlice.cpp
+++ b/source/Lib/DecoderLib/DecSlice.cpp
@@ -132,7 +132,7 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
 
 
 #if JVET_R0058
-  if (slice->getSliceType() != I_SLICE && slice->getRefPic(REF_PIC_LIST_0, 0)->cs->pps->getNumSubPics() > 1)
+  if (slice->getSliceType() != I_SLICE && slice->getRefPic(REF_PIC_LIST_0, 0)->numSubpics > 1)
   {
     clipMv = clipMvInSubpic;
   }
@@ -173,7 +173,7 @@ void DecSlice::decompressSlice( Slice* slice, InputBitstream* bitstream, int deb
         {
           Picture *refPic = slice->getRefPic((RefPicList)rlist, idx);
 #if JVET_R0058
-          if (!refPic->getSubPicSaved() && refPic->unscaledPic->cs->pps->getNumSubPics() > 1)
+          if (!refPic->getSubPicSaved() && refPic->numSubpics > 1)
 #else
           if (!refPic->getSubPicSaved())
 #endif
diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp
index 4b5c0f9ffb..fd6403c01f 100644
--- a/source/Lib/EncoderLib/EncGOP.cpp
+++ b/source/Lib/EncoderLib/EncGOP.cpp
@@ -2259,6 +2259,23 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
     pcSlice->constructRefPicList(rcListPic);
 
 #if JVET_R0058
+    // store sub-picture numbers, sizes, and locations with a picture
+    if (pcPic->cs->sps->getSubPicInfoPresentFlag() && pcPic->cs->pps->getNumSubPics() > 1)
+    {
+      pcSlice->getPic()->numSubpics = pcPic->cs->pps->getNumSubPics();
+      pcSlice->getPic()->subpicWidthInCTUs.clear();
+      pcSlice->getPic()->subpicHeightInCTUs.clear();
+      pcSlice->getPic()->subpicCtuTopLeftX.clear();
+      pcSlice->getPic()->subpicCtuTopLeftY.clear();
+      for (int subPicIdx = 0; subPicIdx < pcPic->cs->pps->getNumSubPics(); subPicIdx++)
+      {
+        pcSlice->getPic()->subpicWidthInCTUs.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicWidthInCTUs());
+        pcSlice->getPic()->subpicHeightInCTUs.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicHeightInCTUs());
+        pcSlice->getPic()->subpicCtuTopLeftX.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicCtuTopLeftX());
+        pcSlice->getPic()->subpicCtuTopLeftY.push_back(pcPic->cs->pps->getSubPic(subPicIdx).getSubPicCtuTopLeftY());
+      }
+    }
+
     const VPS* vps = pcPic->cs->vps;
     int layerIdx = vps == nullptr ? 0 : vps->getGeneralLayerIdx(pcPic->layerId);
     if (vps && !vps->getIndependentLayerFlag(layerIdx) && pcPic->cs->pps->getNumSubPics() > 1)
@@ -2743,7 +2760,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic,
 #endif
 
 #if JVET_R0058
-        if (pcSlice->getSliceType() != I_SLICE && pcSlice->getRefPic(REF_PIC_LIST_0, 0)->unscaledPic->cs->pps->getNumSubPics() > 1)
+        if (pcSlice->getSliceType() != I_SLICE && pcSlice->getRefPic(REF_PIC_LIST_0, 0)->numSubpics > 1)
         {
           clipMv = clipMvInSubpic;
           m_pcEncLib->getInterSearch()->setClipMvInSubPic(true);
diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp
index c9601bb47d..a3cabec379 100644
--- a/source/Lib/EncoderLib/EncSlice.cpp
+++ b/source/Lib/EncoderLib/EncSlice.cpp
@@ -1581,7 +1581,7 @@ void EncSlice::encodeCtus( Picture* pcPic, const bool bCompressEntireSlice, cons
         {
           Picture *refPic = pcSlice->getRefPic((RefPicList)rlist, idx);
 #if JVET_R0058
-          if (!refPic->getSubPicSaved() && refPic->unscaledPic->cs->pps->getNumSubPics() > 1)
+          if (!refPic->getSubPicSaved() && refPic->numSubpics > 1)
 #else
           if (!refPic->getSubPicSaved())
 #endif
-- 
GitLab