diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 87a2b2403da90c786b7ed99b4529f2f6b9bb358b..a0c5ad62daf2eb12ba5b6c5984a393f4f321001d 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -1607,7 +1607,7 @@ VPS::VPS() for (int i = 0; i < MAX_VPS_LAYERS; i++) { m_vpsLayerId[i] = 0; - m_vpsIndependentLayerFlag[i] = 1; + m_vpsIndependentLayerFlag[i] = true; #if JVET_Q0172_CHROMA_FORMAT_BITDEPTH_CONSTRAINT m_vpsLayerChromaFormatIDC[i] = NOT_VALID; m_vpsLayerBitDepth[i] = NOT_VALID; @@ -3371,11 +3371,13 @@ bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP) if (pps) { int spsId = pps->getSPSId(); +#if !ENABLING_MULTI_SPS if (!isIRAP && (spsId != m_activeSPSId )) { msg( WARNING, "Warning: tried to activate PPS referring to a inactive SPS at non-IDR."); } else +#endif { SPS *sps = m_spsMap.getPS(spsId); if (sps) diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 113c937c81a0334148e9848a3b6cd3dc9a69f5d0..209f4f6a4833c0f005e8d485ea2a239296c5e4db 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -111,6 +111,7 @@ #define JVET_Q0820_ACT 1 // JVET-Q0820: ACT bug fixes and reversible ACT transform #define JVET_Q0814_DPB 1 // JVET-Q0814: DPB capacity is based on picture units regardless of the resoltuion +#define ENABLING_MULTI_SPS 1 // Bug fix to enable multiple SPS #define SPS_ID_CHECK 1 // add SPS id check to be the same within CLVS, related to mixed_nalu_types_in_pic_flag #define JVET_Q0353_ACT_SW_FIX 1 // JVET-Q0353: Bug fix of ACT diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index 8a743fe3b98c628bd5873fb7a1390f13909883cb..e415c7d6a883945e4c164f9ad7bb0caef966e66b 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -371,17 +371,32 @@ int EncGOP::xWriteAPS( AccessUnit &accessUnit, APS *aps, const int layerId, cons return (int)(accessUnit.back()->m_nalUnitData.str().size()) * 8; } -int EncGOP::xWriteParameterSets( AccessUnit &accessUnit, Slice *slice, const bool bSeqFirst ) +#if ENABLING_MULTI_SPS +int EncGOP::xWriteParameterSets(AccessUnit &accessUnit, Slice *slice, const bool bSeqFirst, const int layerIdx) +#else +int EncGOP::xWriteParameterSets(AccessUnit &accessUnit, Slice *slice, const bool bSeqFirst) +#endif { int actualTotalBits = 0; if( bSeqFirst ) { +#if ENABLING_MULTI_SPS + if (layerIdx == 0) + { + actualTotalBits += xWriteDPS(accessUnit, m_pcEncLib->getDPS()); + if (slice->getSPS()->getVPSId() != 0) + { + actualTotalBits += xWriteVPS(accessUnit, m_pcEncLib->getVPS()); + } + } +#else if (slice->getSPS()->getVPSId() != 0) { actualTotalBits += xWriteVPS(accessUnit, m_pcEncLib->getVPS()); } actualTotalBits += xWriteDPS( accessUnit, m_pcEncLib->getDPS() ); +#endif if( m_pcEncLib->SPSNeedsWriting( slice->getSPS()->getSPSId() ) ) // Note this assumes that all changes to the SPS are made at the EncLib level prior to picture creation (EncLib::xGetNewPicBuffer). { @@ -2988,8 +3003,11 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, int layerIdx = m_pcEncLib->getVPS() == nullptr ? 0 : m_pcEncLib->getVPS()->getGeneralLayerIdx( m_pcEncLib->getLayerId() ); // it is assumed that layerIdx equal to 0 is always present - actualTotalBits += xWriteParameterSets( accessUnit, pcSlice, writePS && !layerIdx ); - +#if ENABLING_MULTI_SPS + actualTotalBits += xWriteParameterSets(accessUnit, pcSlice, writePS, layerIdx); +#else + actualTotalBits += xWriteParameterSets(accessUnit, pcSlice, writePS && !layerIdx); +#endif if (writePS) { // create prefix SEI messages at the beginning of the sequence diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h index 36d28e5145f3f48c470e2208b5905491ed4754ee..0561fadad96ef7ebc59a2dcf5ff5b76595db4321 100644 --- a/source/Lib/EncoderLib/EncGOP.h +++ b/source/Lib/EncoderLib/EncGOP.h @@ -323,7 +323,11 @@ protected: int xWriteSPS( AccessUnit &accessUnit, const SPS *sps, const int layerId = 0 ); int xWritePPS( AccessUnit &accessUnit, const PPS *pps, const SPS *sps, const int layerId = 0 ); int xWriteAPS( AccessUnit &accessUnit, APS *aps, const int layerId, const bool isPrefixNUT ); - int xWriteParameterSets (AccessUnit &accessUnit, Slice *slice, const bool bSeqFirst); +#if ENABLING_MULTI_SPS + int xWriteParameterSets(AccessUnit &accessUnit, Slice *slice, const bool bSeqFirst, const int layerIdx); +#else + int xWriteParameterSets(AccessUnit &accessUnit, Slice *slice, const bool bSeqFirst); +#endif int xWritePicHeader( AccessUnit &accessUnit, PicHeader *picHeader ); void applyDeblockingFilterMetric( Picture* pcPic, uint32_t uiNumSlices ); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index 0f32956dd353ef4662b460f1f4f31b207451568b..f5661cb03418b4d232f368e60bb9de417edb5245 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -241,7 +241,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) { m_AUWriterIf = auWriterIf; - SPS &sps0=*(m_spsMap.allocatePS(0)); // NOTE: implementations that use more than 1 SPS need to be aware of activation issues. +#if ENABLING_MULTI_SPS + SPS &sps0 = *(m_spsMap.allocatePS(m_layerId)); // NOTE: implementations that use more than 1 SPS need to be aware of activation issues. +#else + SPS &sps0 = *(m_spsMap.allocatePS(0)); // NOTE: implementations that use more than 1 SPS need to be aware of activation issues. +#endif PPS &pps0 = *( m_ppsMap.allocatePS( m_layerId ) ); APS &aps0 = *( m_apsMap.allocatePS( SCALING_LIST_APS ) ); aps0.setAPSId( 0 ); @@ -1496,18 +1500,28 @@ void EncLib::xInitSPS( SPS& sps, VPS& vps ) } #if JVET_Q0814_DPB +#if ENABLING_MULTI_SPS + sps.setInterLayerPresentFlag( m_layerId > 0 && m_vps->getMaxLayers() > 1 && !m_vps->getAllIndependentLayersFlag() && !m_vps->getIndependentLayerFlag( m_vps->getGeneralLayerIdx( m_layerId ) ) ); + CHECK( m_vps->getIndependentLayerFlag( m_vps->getGeneralLayerIdx( m_layerId ) ) && sps.getInterLayerPresentFlag(), " When vps_independent_layer_flag[GeneralLayerIdx[nuh_layer_id ]] is equal to 1, the value of inter_layer_ref_pics_present_flag shall be equal to 0." ); +#else sps.setInterLayerPresentFlag( m_vps->getMaxLayers() > 1 && !m_vps->getAllIndependentLayersFlag() ); for( int i = 0; i < m_vps->getMaxLayers(); ++i ) { CHECK((m_vps->getIndependentLayerFlag(i) == 1) && (sps.getInterLayerPresentFlag() != 0), " When vps_independent_layer_flag[GeneralLayerIdx[nuh_layer_id ]] is equal to 1, the value of inter_layer_ref_pics_present_flag shall be equal to 0."); } +#endif +#else +#if ENABLING_MULTI_SPS + sps.setInterLayerPresentFlag( m_layerId > 0 && vps.getMaxLayers() > 1 && !vps.getAllIndependentLayersFlag() && !vps.getIndependentLayerFlag( vps.getGeneralLayerIdx( m_layerId ) ) ); + CHECK( vps.getIndependentLayerFlag( vps.getGeneralLayerIdx( m_layerId ) ) && sps.getInterLayerPresentFlag(), " When vps_independent_layer_flag[GeneralLayerIdx[nuh_layer_id ]] is equal to 1, the value of inter_layer_ref_pics_present_flag shall be equal to 0." ); #else sps.setInterLayerPresentFlag( vps.getMaxLayers() > 1 && !vps.getAllIndependentLayersFlag() ); for (unsigned int i = 0; i < vps.getMaxLayers(); ++i) { CHECK((vps.getIndependentLayerFlag(i) == 1) && (sps.getInterLayerPresentFlag() != 0), " When vps_independent_layer_flag[GeneralLayerIdx[nuh_layer_id ]] is equal to 1, the value of inter_layer_ref_pics_present_flag shall be equal to 0."); } +#endif #endif sps.setRprEnabledFlag( m_rprEnabled || sps.getInterLayerPresentFlag() );