diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 76ba94a57a03215bc2ed51e952a163e51f1d639f..f9f0594f89182bb4e17ce1b37730c2ffcd39c73f 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -746,6 +746,9 @@ class VPS private: int m_VPSId; uint32_t m_uiMaxLayers; +#if JVET_P0185 + uint32_t m_vpsMaxSubLayers; +#endif uint32_t m_vpsIncludedLayerId[MAX_VPS_LAYERS]; bool m_vpsExtensionFlag; @@ -761,6 +764,11 @@ public: uint32_t getMaxLayers() const { return m_uiMaxLayers; } void setMaxLayers(uint32_t l) { m_uiMaxLayers = l; } +#if JVET_P0185 + uint32_t getMaxSubLayers() const { return m_vpsMaxSubLayers; } + void setMaxSubLayers(uint32_t value) { m_vpsMaxSubLayers = value; } +#endif + bool getVPSExtensionFlag() const { return m_vpsExtensionFlag; } void setVPSExtensionFlag(bool t) { m_vpsExtensionFlag = t; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 64ed1f879b078b81edc96ff11de09716d5171316..4d2b1625babeaa1753bb4a4ed262e83d080efb13 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -269,6 +269,8 @@ #define JVET_P0171_SUBPICTURE_LAYOUT 1 //JVET-P0171: subpicture layout +#define JVET_P0185 1 // Infer vps_max_layers_minus1 to be equal to 0 when not present and also signal vps_max_sub_layers_minus1 + #define HEVC_SEI 0 // SEI messages that are defined in HEVC, but not in VVC typedef std::pair<int, bool> TrMode; diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 006550aeedd2b457ad4f078a6c7a6ef79ee1d30c..a542e91c70ce64c9d25471017e194049e99c2081 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -2052,6 +2052,19 @@ bool DecLib::decode(InputNALUnit& nalu, int& iSkipFrame, int& iPOCLastDisplay) case NAL_UNIT_SPS: xDecodeSPS( nalu ); +#if JVET_P0185 + { + const SPS* pcSPS = m_parameterSetManager.getActiveSPS(); + if (0 == pcSPS->getVPSId()) + { + if (m_vps != nullptr) + { + delete m_vps; + } + m_vps = new VPS(); + } + } +#endif return false; case NAL_UNIT_PPS: diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 563799eb0bf378d8f422f973d3999262ecc53fc8..1f43bb595f8d35b940e1b2d627c2a7a7ecb26f21 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -2147,7 +2147,19 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS) READ_CODE(4, uiCode, "vps_video_parameter_set_id"); pcVPS->setVPSId(uiCode); #endif +#if JVET_P0185 + if (0 == pcVPS->getVPSId()) + { + pcVPS->setMaxLayers(1); + } + else + { + READ_CODE(8, uiCode, "vps_max_layers_minus1"); pcVPS->setMaxLayers(uiCode + 1); CHECK(uiCode + 1 > MAX_VPS_LAYERS, "Invalid code"); + } + READ_CODE(8, uiCode, "vps_max_sub_layers_minus1"); pcVPS->setMaxSubLayers(uiCode + 1); +#else READ_CODE(8, uiCode, "vps_max_layers_minus1"); pcVPS->setMaxLayers(uiCode + 1); CHECK(uiCode + 1 > MAX_VPS_LAYERS, "Invalid code"); +#endif for (uint32_t i = 0; i <= pcVPS->getMaxLayers() - 1; i++) { READ_CODE(7, uiCode, "vps_included_layer_id"); pcVPS->setVPSIncludedLayerId(uiCode, i); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index c5d620fd1bfec70a0cadfb4ec32e8669dde345d6..c38ef30789b736aaa92e9de29b432bd27d79711b 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -244,7 +244,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) // initialize SPS xInitSPS(sps0); +#if JVET_P0185 + xInitVPS(m_cVPS, sps0); +#else xInitVPS(m_cVPS); +#endif int dpsId = getDecodingParameterSetEnabled() ? 1 : 0; xInitDPS(m_dps, sps0, dpsId); @@ -1335,7 +1339,11 @@ void EncLib::xGetNewPicBuffer ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Pict } -void EncLib::xInitVPS(VPS &vps) +#if JVET_P0185 +void EncLib::xInitVPS(VPS& vps, const SPS& sps) +#else +void EncLib::xInitVPS(VPS& vps) +#endif { // The SPS must have already been set up. // set the VPS profile information. @@ -1346,6 +1354,10 @@ void EncLib::xInitVPS(VPS &vps) { vps.setVPSIncludedLayerId(0, i); } +#if JVET_P0185 + vps.setMaxSubLayers(sps.getMaxTLayers()); +#endif + } void EncLib::xInitDPS(DPS &dps, const SPS &sps, const int dpsId) diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h index 6bfa2db54c2fe68715839c8cdd789762f21b8e68..c5b338d5f5910878c6882445a93955a767e1e194 100644 --- a/source/Lib/EncoderLib/EncLib.h +++ b/source/Lib/EncoderLib/EncLib.h @@ -178,7 +178,11 @@ public: protected: void xGetNewPicBuffer ( std::list<PelUnitBuf*>& rcListPicYuvRecOut, Picture*& rpcPic, int ppsId ); ///< get picture buffer which will be processed. If ppsId<0, then the ppsMap will be queried for the first match. - void xInitVPS (VPS &vps); ///< initialize VPS from encoder options +#if JVET_P0185 + void xInitVPS(VPS& vps, const SPS& sps); ///< initialize VPS from encoder options +#else + void xInitVPS(VPS& vps); ///< initialize VPS from encoder options +#endif void xInitDPS (DPS &dps, const SPS &sps, const int dpsId); ///< initialize DPS from encoder options void xInitSPS (SPS &sps); ///< initialize SPS from encoder options void xInitPPS (PPS &pps, const SPS &sps); ///< initialize PPS from encoder options diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index 2b8341f36dd56ab4a60fa22650e354110b12e663..0dace977d98b91cff3582be559cbf25e38b47fee 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -1446,6 +1446,10 @@ void HLSWriter::codeVPS(const VPS* pcVPS) #endif WRITE_CODE(pcVPS->getVPSId(), 4, "vps_video_parameter_set_id"); WRITE_CODE(pcVPS->getMaxLayers() - 1, 8, "vps_max_layers_minus1"); +#if JVET_P0185 + CHECK(pcVPS->getMaxSubLayers() < 1 || pcVPS->getMaxSubLayers() > 7, "vps_max_sub_layers_minus1 must be in range 0..6"); + WRITE_CODE(pcVPS->getMaxSubLayers() - 1, 3, "vps_max_sub_layers_minus1"); +#endif for (uint32_t i = 0; i <= pcVPS->getMaxLayers() - 1; i++) { WRITE_CODE(pcVPS->getVPSIncludedLayerId(i), 7, "vps_included_layer_id");