diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index b70cd5767514829112b92041d475f16514f5fd3e..b63b46c9831ddd2f4350674562bd675fc1824224 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -2401,6 +2401,9 @@ SPSRExt::SPSRExt() SPS::SPS() : m_SPSId ( 0) , m_VPSId ( 0 ) +#if JVET_R0194_CONSTRAINT_PS_SHARING_REFERENCING +, m_layerId ( 0 ) +#endif , m_affineAmvrEnabledFlag ( false ) , m_DMVR ( false ) , m_MMVD ( false ) diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index fada6a97b8b94cd614a021fefcc93cc5d6ea151d..61ca297d570a7ce8956b398b278411b3ce2db992 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -1291,7 +1291,9 @@ class SPS private: int m_SPSId; int m_VPSId; - +#if JVET_R0194_CONSTRAINT_PS_SHARING_REFERENCING + int m_layerId; +#endif bool m_affineAmvrEnabledFlag; bool m_DMVR; bool m_MMVD; @@ -1482,7 +1484,10 @@ public: void setSPSId(int i) { m_SPSId = i; } int getVPSId() const { return m_VPSId; } void setVPSId(int i) { m_VPSId = i; } - +#if JVET_R0194_CONSTRAINT_PS_SHARING_REFERENCING + void setLayerId( int i ) { m_layerId = i; } + int getLayerId() const { return m_layerId; } +#endif ChromaFormat getChromaFormatIdc () const { return m_chromaFormatIdc; } void setChromaFormatIdc (ChromaFormat i) { m_chromaFormatIdc = i; } void setSeparateColourPlaneFlag ( bool b ) { m_separateColourPlaneFlag = b; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 2687c367fb58b4bffe68e392f3ae02e6493581d2..8fb480fe5e35f991f0e4121b8612bdf5255f255e 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -51,6 +51,7 @@ #include <cassert> //########### place macros to be removed in next cycle below this line ############### +#define JVET_R0194_CONSTRAINT_PS_SHARING_REFERENCING 1 // JVET-R0194: Constraint that if slice at layer A refer to PS at layer B, then all OLS that contains layer A must contain layer B as well. #define JVET_R0188 1 // JVET-R0188: Signalling slice_width_in_tiles_minus1[i] and slice_height_in_tiles_minus1[i] diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 75e85852a8b768e5852c154532b763d4d09becf8..2889918d26130ae630aa13f5c5319c164b5af1cd 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -2020,6 +2020,54 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl m_pcPic->layerId = nalu.m_nuhLayerId; m_pcPic->subLayerNonReferencePictureDueToSTSA = false; +#if JVET_R0194_CONSTRAINT_PS_SHARING_REFERENCING + if( pcSlice->getNalUnitLayerId() != pcSlice->getSPS()->getLayerId() ) + { + CHECK( pcSlice->getSPS()->getLayerId() > pcSlice->getNalUnitLayerId(), "Layer Id of SPS cannot be greater than layer Id of VCL NAL unit the refer to it" ); + CHECK( pcSlice->getSPS()->getVPSId() == 0, "VPSId of the referred SPS cannot be 0 when layer Id of SPS and layer Id of current slice are different" ); + for (int i = 0; i < pcSlice->getVPS()->getNumOutputLayerSets(); i++ ) + { + bool isCurrLayerInOls = false; + bool isRefLayerInOls = false; + int j = pcSlice->getVPS()->getNumLayersInOls(i) - 1; + for (; j >= 0; j--) + { + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == pcSlice->getNalUnitLayerId() ) + { + isCurrLayerInOls = true; + } + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == pcSlice->getSPS()->getLayerId() ) + { + isRefLayerInOls = true; + } + } + CHECK( isCurrLayerInOls && !isRefLayerInOls, "When VCL NAl unit in layer A refers to SPS in layer B, all OLS that contains layer A shall also contains layer B" ); + } + } + if( pcSlice->getNalUnitLayerId() != pcSlice->getPPS()->getLayerId() ) + { + CHECK( pcSlice->getPPS()->getLayerId() > pcSlice->getNalUnitLayerId(), "Layer Id of PPS cannot be greater than layer Id of VCL NAL unit the refer to it" ); + CHECK( pcSlice->getSPS()->getVPSId() == 0, "VPSId of the referred SPS cannot be 0 when layer Id of PPS and layer Id of current slice are different" ); + for (int i = 0; i < pcSlice->getVPS()->getNumOutputLayerSets(); i++ ) + { + bool isCurrLayerInOls = false; + bool isRefLayerInOls = false; + int j = pcSlice->getVPS()->getNumLayersInOls(i) - 1; + for (; j >= 0; j--) + { + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == pcSlice->getNalUnitLayerId() ) + { + isCurrLayerInOls = true; + } + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == pcSlice->getPPS()->getLayerId() ) + { + isRefLayerInOls = true; + } + } + CHECK( isCurrLayerInOls && !isRefLayerInOls, "When VCL NAl unit in layer A refers to PPS in layer B, all OLS that contains layer A shall also contains layer B" ); + } + } +#endif if (m_bFirstSliceInPicture) { @@ -2212,6 +2260,30 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl if (pcSlice->getExplicitScalingListUsed()) { APS* scalingListAPS = pcSlice->getPicHeader()->getScalingListAPS(); +#if JVET_R0194_CONSTRAINT_PS_SHARING_REFERENCING + if( pcSlice->getNalUnitLayerId() != scalingListAPS->getLayerId() ) + { + CHECK( scalingListAPS->getLayerId() > pcSlice->getNalUnitLayerId(), "Layer Id of APS cannot be greater than layer Id of VCL NAL unit the refer to it" ); + CHECK( pcSlice->getSPS()->getVPSId() == 0, "VPSId of the referred SPS cannot be 0 when layer Id of APS and layer Id of current slice are different" ); + for (int i = 0; i < pcSlice->getVPS()->getNumOutputLayerSets(); i++ ) + { + bool isCurrLayerInOls = false; + bool isRefLayerInOls = false; + for( int j = pcSlice->getVPS()->getNumLayersInOls(i) - 1; j >= 0; j-- ) + { + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == pcSlice->getNalUnitLayerId() ) + { + isCurrLayerInOls = true; + } + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == scalingListAPS->getLayerId() ) + { + isRefLayerInOls = true; + } + } + CHECK( isCurrLayerInOls && !isRefLayerInOls, "When VCL NAl unit in layer A refers to APS in layer B, all OLS that contains layer A shall also contains layer B" ); + } + } +#endif ScalingList scalingList = scalingListAPS->getScalingList(); quant->setScalingListDec(scalingList); quant->setUseScalingList(true); @@ -2236,6 +2308,30 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl { CHECK(lmcsAPS->getAPSId() != m_sliceLmcsApsId, "same APS ID shall be used for all slices in one picture"); } +#if JVET_R0194_CONSTRAINT_PS_SHARING_REFERENCING + if( pcSlice->getNalUnitLayerId() != lmcsAPS->getLayerId() ) + { + CHECK( lmcsAPS->getLayerId() > pcSlice->getNalUnitLayerId(), "Layer Id of APS cannot be greater than layer Id of VCL NAL unit the refer to it" ); + CHECK( pcSlice->getSPS()->getVPSId() == 0, "VPSId of the referred SPS cannot be 0 when layer Id of APS and layer Id of current slice are different" ); + for (int i = 0; i < pcSlice->getVPS()->getNumOutputLayerSets(); i++ ) + { + bool isCurrLayerInOls = false; + bool isRefLayerInOls = false; + for( int j = pcSlice->getVPS()->getNumLayersInOls(i) - 1; j >= 0; j-- ) + { + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == pcSlice->getNalUnitLayerId() ) + { + isCurrLayerInOls = true; + } + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == lmcsAPS->getLayerId() ) + { + isRefLayerInOls = true; + } + } + CHECK( isCurrLayerInOls && !isRefLayerInOls, "When VCL NAl unit in layer A refers to APS in layer B, all OLS that contains layer A shall also contains layer B" ); + } + } +#endif SliceReshapeInfo& sInfo = lmcsAPS->getReshaperAPSInfo(); SliceReshapeInfo& tInfo = m_cReshaper.getSliceReshaperInfo(); tInfo.reshaperModelMaxBinIdx = sInfo.reshaperModelMaxBinIdx; @@ -2347,6 +2443,9 @@ void DecLib::xDecodeSPS( InputNALUnit& nalu ) CHECK( nalu.m_temporalId, "The value of TemporalId of SPS NAL units shall be equal to 0" ); m_HLSReader.parseSPS( sps ); +#if JVET_R0194_CONSTRAINT_PS_SHARING_REFERENCING + sps->setLayerId( nalu.m_nuhLayerId ); +#endif DTRACE( g_trace_ctx, D_QP_PER_CTU, "CTU Size: %dx%d", sps->getMaxCUWidth(), sps->getMaxCUHeight() ); m_parameterSetManager.storeSPS( sps, nalu.getBitstream().getFifo() ); } diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index f67cf62e0b474522a2026c01b1b8bc407bce47f2..a77544217801016f5e7b2f93bce4f88d4624b8d6 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -3465,6 +3465,30 @@ void HLSyntaxReader::checkAlfNaluTidAndPicTid(Slice* pcSlice, PicHeader* picHea { aps = parameterSetManager->getAPS(apsId[i], ALF_APS); CHECK(aps->getTemporalId() > curPicTid, "The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and adaptation_parameter_set_id equal to ph_alf_aps_id_luma[ i ] shall be less than or equal to the TemporalId of the picture associated with the PH."); +#if JVET_R0194_CONSTRAINT_PS_SHARING_REFERENCING + if( pcSlice->getNalUnitLayerId() != aps->getLayerId() ) + { + CHECK( aps->getLayerId() > pcSlice->getNalUnitLayerId(), "Layer Id of APS cannot be greater than layer Id of VCL NAL unit the refer to it" ); + CHECK( pcSlice->getSPS()->getVPSId() == 0, "VPSId of the referred SPS cannot be 0 when layer Id of APS and layer Id of current slice are different" ); + for (int i = 0; i < pcSlice->getVPS()->getNumOutputLayerSets(); i++ ) + { + bool isCurrLayerInOls = false; + bool isRefLayerInOls = false; + for( int j = pcSlice->getVPS()->getNumLayersInOls(i) - 1; j >= 0; j-- ) + { + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == pcSlice->getNalUnitLayerId() ) + { + isCurrLayerInOls = true; + } + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == aps->getLayerId() ) + { + isRefLayerInOls = true; + } + } + CHECK( isCurrLayerInOls && !isRefLayerInOls, "When VCL NAl unit in layer A refers to APS in layer B, all OLS that contains layer A shall also contains layer B" ); + } + } +#endif } //chroma #if JVET_R0225_SEPERATE_FLAGS_ALF_CHROMA @@ -3476,6 +3500,31 @@ void HLSyntaxReader::checkAlfNaluTidAndPicTid(Slice* pcSlice, PicHeader* picHea int chromaAlfApsId = picHeader->getAlfApsIdChroma(); aps = parameterSetManager->getAPS(chromaAlfApsId, ALF_APS); CHECK(aps->getTemporalId() > curPicTid, "The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and adaptation_parameter_set_id equal to ph_alf_aps_id_chroma shall be less than or equal to the TemporalId of the picture associated with the PH."); + CHECK(aps->getTemporalId() > curPicTid, "The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and adaptation_parameter_set_id equal to ph_alf_aps_id_luma[ i ] shall be less than or equal to the TemporalId of the picture associated with the PH."); +#if JVET_R0194_CONSTRAINT_PS_SHARING_REFERENCING + if( pcSlice->getNalUnitLayerId() != aps->getLayerId() ) + { + CHECK( aps->getLayerId() > pcSlice->getNalUnitLayerId(), "Layer Id of APS cannot be greater than layer Id of VCL NAL unit the refer to it" ); + CHECK( pcSlice->getSPS()->getVPSId() == 0, "VPSId of the referred SPS cannot be 0 when layer Id of APS and layer Id of current slice are different" ); + for (int i = 0; i < pcSlice->getVPS()->getNumOutputLayerSets(); i++ ) + { + bool isCurrLayerInOls = false; + bool isRefLayerInOls = false; + for( int j = pcSlice->getVPS()->getNumLayersInOls(i) - 1; j >= 0; j-- ) + { + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == pcSlice->getNalUnitLayerId() ) + { + isCurrLayerInOls = true; + } + if( pcSlice->getVPS()->getLayerIdInOls(i, j) == aps->getLayerId() ) + { + isRefLayerInOls = true; + } + } + CHECK( isCurrLayerInOls && !isRefLayerInOls, "When VCL NAl unit in layer A refers to APS in layer B, all OLS that contains layer A shall also contains layer B" ); + } + } +#endif } } }