From 33d5f72b9ddb6845b7a9347c93c261cd3650b644 Mon Sep 17 00:00:00 2001 From: vdrugeon <virginie.drugeon@eu.panasonic.com> Date: Mon, 28 Oct 2019 12:26:58 +0100 Subject: [PATCH] JVET-P0205: VPS ID 0 Constraint that vps_video_parameter_set_id shall be greater than 0 Added that the bitstream does not contain any VPS when signalled sps_video_parameter_set_id is equal to zero (was already in VVC Draft, but not in VTM) --- source/Lib/CommonLib/Slice.cpp | 32 +++++++++++++++++++++++++++++ source/Lib/CommonLib/Slice.h | 15 ++++++++++++++ source/Lib/CommonLib/TypeDef.h | 2 ++ source/Lib/DecoderLib/VLCReader.cpp | 10 +++++++++ source/Lib/EncoderLib/EncGOP.cpp | 7 +++++++ source/Lib/EncoderLib/VLCWriter.cpp | 3 +++ 6 files changed, 69 insertions(+) diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index a09e25920..ca8864bcc 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -1953,6 +1953,9 @@ SPSRExt::SPSRExt() SPS::SPS() : m_SPSId ( 0) , m_decodingParameterSetId ( 0 ) +#if JVET_P0205_VPS_ID_0 +, m_VPSId ( 0 ) +#endif , m_affineAmvrEnabledFlag ( false ) , m_DMVR ( false ) , m_MMVD ( false ) @@ -2999,8 +3002,14 @@ ParameterSetManager::ParameterSetManager() , m_ppsMap(MAX_NUM_PPS) , m_apsMap(MAX_NUM_APS * MAX_NUM_APS_TYPE) , m_dpsMap(MAX_NUM_DPS) +#if JVET_P0205_VPS_ID_0 +, m_vpsMap(MAX_NUM_VPS) +#endif , m_activeDPSId(-1) , m_activeSPSId(-1) +#if JVET_P0205_VPS_ID_0 +, m_activeVPSId(-1) +#endif { } @@ -3081,6 +3090,29 @@ bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP) } } +#if JVET_P0205_VPS_ID_0 + int vpsId = sps->getVPSId(); + if(vpsId != 0) + { + VPS *vps = m_vpsMap.getPS(vpsId); + if(vps) + { + m_activeVPSId = vpsId; + m_vpsMap.setActive(vpsId); + } + else + { + msg( WARNING, "Warning: tried to activate PPS that refers to non-existing VPS." ); + } + } + else + { + //No actual VPS + m_activeVPSId = -1; + m_vpsMap.clear(); + } +#endif + m_spsMap.clear(); m_spsMap.setActive(spsId); m_activeSPSId = spsId; diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index eaf9f055e..525470cfb 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -883,6 +883,9 @@ class SPS private: int m_SPSId; int m_decodingParameterSetId; +#if JVET_P0205_VPS_ID_0 + int m_VPSId; +#endif bool m_affineAmvrEnabledFlag; bool m_DMVR; @@ -1033,6 +1036,11 @@ public: void setSPSId(int i) { m_SPSId = i; } void setDecodingParameterSetId(int val) { m_decodingParameterSetId = val; } int getDecodingParameterSetId() const { return m_decodingParameterSetId; } +#if JVET_P0205_VPS_ID_0 + int getVPSId() const { return m_VPSId; } + void setVPSId(int i) { m_VPSId = i; } +#endif + ChromaFormat getChromaFormatIdc () const { return m_chromaFormatIdc; } void setChromaFormatIdc (ChromaFormat i) { m_chromaFormatIdc = i; } #if JVET_P1006_PICTURE_HEADER @@ -2744,6 +2752,7 @@ public: bool getDPSChangedFlag(int dpsId) const { return m_dpsMap.getChangedFlag(dpsId); } void clearDPSChangedFlag(int dpsId) { m_dpsMap.clearChangedFlag(dpsId); } DPS* getFirstDPS() { return m_dpsMap.getFirstPS(); }; + //! store sequence parameter set and take ownership of it void storeSPS(SPS *sps, const std::vector<uint8_t> &naluData) { m_spsMap.storePS( sps->getSPSId(), sps, &naluData); }; //! get pointer to existing sequence parameter set @@ -2785,11 +2794,17 @@ protected: ParameterSetMap<PPS> m_ppsMap; ParameterSetMap<APS> m_apsMap; ParameterSetMap<DPS> m_dpsMap; +#if JVET_P0205_VPS_ID_0 + ParameterSetMap<VPS> m_vpsMap; +#endif APS* m_apss[ALF_CTB_MAX_NUM_APS]; int m_activeDPSId; // -1 for nothing active int m_activeSPSId; // -1 for nothing active +#if JVET_P0205_VPS_ID_0 + int m_activeVPSId; // -1 for nothing active +#endif }; class PreCalcValues diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 11a3a8b3c..2ecb66957 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -50,6 +50,8 @@ #include <assert.h> #include <cassert> +#define JVET_P0205_VPS_ID_0 1 // JVET-P0205: VPS ID zero in SPS means no VPS in bitstream + #define JVET_P1006_PICTURE_HEADER 1 // JVET-P1006: Add picture header and related syntax changes #define JVET_P0365_SCALING_MATRIX_LFNST 1 // JVET-P0365: Signal flag to indicate whether scaling matrices are used for LFNST-coded blocks diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index cb58d4d29..b9c50fc07 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -1214,6 +1214,9 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) xTraceSPSHeader (); #endif READ_CODE( 4, uiCode, "sps_decoding_parameter_set_id"); pcSPS->setDecodingParameterSetId( uiCode ); +#if JVET_P0205_VPS_ID_0 + READ_CODE( 4, uiCode, "sps_video_parameter_set_id" ); pcSPS->setVPSId( uiCode ); +#endif READ_CODE(3, uiCode, "sps_max_sub_layers_minus1"); pcSPS->setMaxTLayers (uiCode + 1); CHECK(uiCode > 6, "Invalid maximum number of T-layer signalled"); READ_CODE(5, uiCode, "sps_reserved_zero_5bits"); @@ -1779,7 +1782,14 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS) #endif uint32_t uiCode; +#if JVET_P0205_VPS_ID_0 + READ_CODE(4, uiCode, "vps_video_parameter_set_id"); + CHECK( uiCode == 0, "vps_video_parameter_set_id equal to zero is reserved and shall not be used in a bitstream" ); + pcVPS->setVPSId(uiCode); +#else READ_CODE(4, uiCode, "vps_video_parameter_set_id"); pcVPS->setVPSId(uiCode); +#endif + READ_CODE(8, uiCode, "vps_max_layers_minus1"); pcVPS->setMaxLayers(uiCode + 1); CHECK(uiCode + 1 > MAX_VPS_LAYERS, "Invalid code"); for (uint32_t i = 0; i <= pcVPS->getMaxLayers() - 1; i++) { diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index c3c4526fc..9f85f0a13 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -383,6 +383,9 @@ int EncGOP::xWriteParameterSets( AccessUnit &accessUnit, Slice *slice, const boo #if JVET_N0278_FIXES if( bSeqFirst ) { +#if JVET_P0205_VPS_ID_0 + if (slice->getSPS()->getVPSId() != 0) +#endif actualTotalBits += xWriteVPS( accessUnit, m_pcEncLib->getVPS() ); actualTotalBits += xWriteDPS( accessUnit, m_pcEncLib->getDPS() ); @@ -397,8 +400,12 @@ int EncGOP::xWriteParameterSets( AccessUnit &accessUnit, Slice *slice, const boo { actualTotalBits += xWritePPS( accessUnit, slice->getPPS(), slice->getSPS(), m_pcEncLib->getLayerId() ); } +#if JVET_P0205_VPS_ID_0 + // No VPS in the bitstream if the SPS refers to VPS ID zero + if (bSeqFirst && slice->getSPS()->getVPSId() != 0) #else if (bSeqFirst) +#endif { actualTotalBits += xWriteVPS(accessUnit, m_pcEncLib->getVPS()); } diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index f12911794..0bd805f52 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -740,6 +740,9 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) xTraceSPSHeader (); #endif WRITE_CODE( pcSPS->getDecodingParameterSetId (), 4, "sps_decoding_parameter_set_id" ); +#if JVET_P0205_VPS_ID_0 + WRITE_CODE( pcSPS->getVPSId(), 4, "sps_video_parameter_set_id" ); +#endif CHECK(pcSPS->getMaxTLayers() == 0, "Maximum number of temporal sub-layers is '0'"); WRITE_CODE(pcSPS->getMaxTLayers() - 1, 3, "sps_max_sub_layers_minus1"); -- GitLab