diff --git a/source/App/DecoderApp/DecApp.cpp b/source/App/DecoderApp/DecApp.cpp index 59e04ddc1ab28f12e4fe1360a7e07c4ff7399347..100720131d4cbc9c568ac9d999673a934c193c2c 100644 --- a/source/App/DecoderApp/DecApp.cpp +++ b/source/App/DecoderApp/DecApp.cpp @@ -490,6 +490,11 @@ uint32_t DecApp::decode() m_cDecLib.CheckNoOutputPriorPicFlagsInAccessUnit(); m_cDecLib.resetAccessUnitNoOutputPriorPicFlags(); m_cDecLib.checkLayerIdIncludedInCvss(); +#if JVET_S0176_ITEM5 + m_cDecLib.checkSEIInAccessUnit(); + m_cDecLib.resetAccessUnitNestedSliSeiInfo(); + m_cDecLib.resetIsFirstAuInCvs(); +#endif m_cDecLib.resetAccessUnitEos(); m_cDecLib.resetAudIrapOrGdrAuFlag(); } @@ -497,7 +502,9 @@ uint32_t DecApp::decode() { m_cDecLib.checkTidLayerIdInAccessUnit(); m_cDecLib.resetAccessUnitSeiTids(); +#if !JVET_S0176_ITEM5 m_cDecLib.checkSEIInAccessUnit(); +#endif m_cDecLib.resetAccessUnitSeiPayLoadTypes(); m_cDecLib.resetAccessUnitNals(); m_cDecLib.resetAccessUnitApsNals(); diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index 6c883c8abb864ece7d6950e17a60ec06423075ce..57ba502bfcacb724ffdc23b9bac954ce3d406c7e 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -57,6 +57,8 @@ #define JVET_T0055_ITEM2 1 // JVET-T0055 item 2: Remove the step 9 of the general sub-bitstream extraction process. +#define JVET_S0176_ITEM5 1 // JVET-S0176 #5: When an SLI SEI message is present for a CVS, the value of sps_num_subpics_minus1 shall be the same for all the SPSs referenced by the pictures in the layers with multiple subpictures per picture. + #define JVET_W0078_MVP_SEI 1 // JVET-W0078 Multiview view position SEI message #define JVET_W0129_ENABLE_ALF_TRUEORG 1 // Using true original samples for ALF as default setting diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index 8933874c1a2f77f4ffda56cdbeb7c2bf452146a4..1347b946c11bea680c009af19d52d77be915c05b 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -475,6 +475,9 @@ DecLib::DecLib() std::fill_n(m_prevGDRInSameLayerRecoveryPOC, MAX_VPS_LAYERS, -MAX_INT); std::fill_n(m_firstSliceInSequence, MAX_VPS_LAYERS, true); std::fill_n(m_pocCRA, MAX_VPS_LAYERS, -MAX_INT); +#if JVET_S0176_ITEM5 + std::fill_n(m_accessUnitSpsNumSubpic, MAX_VPS_LAYERS, 1); +#endif for (int i = 0; i < MAX_VPS_LAYERS; i++) { m_associatedIRAPType[i] = NAL_UNIT_INVALID; @@ -1116,6 +1119,7 @@ void DecLib::checkLayerIdIncludedInCvss() } } +#if !JVET_S0176_ITEM5 // update the value of m_isFirstAuInCvs for the next AU according to NAL_UNIT_EOS in each layer for (auto pic = m_accessUnitPicInfo.begin(); pic != m_accessUnitPicInfo.end(); pic++) { @@ -1125,7 +1129,23 @@ void DecLib::checkLayerIdIncludedInCvss() break; } } +#endif +} + +#if JVET_S0176_ITEM5 +void DecLib::resetIsFirstAuInCvs() +{ + // update the value of m_isFirstAuInCvs for the next AU according to NAL_UNIT_EOS in each layer + for (auto pic = m_accessUnitPicInfo.begin(); pic != m_accessUnitPicInfo.end(); pic++) + { + m_isFirstAuInCvs = m_accessUnitEos[pic->m_nuhLayerId] ? true : false; + if (!m_isFirstAuInCvs) + { + break; + } + } } +#endif void DecLib::CheckNoOutputPriorPicFlagsInAccessUnit() { @@ -1190,6 +1210,11 @@ void DecLib::checkTidLayerIdInAccessUnit() void DecLib::checkSEIInAccessUnit() { +#if JVET_S0176_ITEM5 + int olsIdxIncludeAllLayes = -1; + bool isNonNestedSliFound = false; +#endif + bool bSdiPresentInAu = false; #if JVET_W0078_MVP_SEI bool bAuxSEIsBeforeSdiSEIPresent[4] = { false, false, false, false }; @@ -1223,6 +1248,13 @@ void DecLib::checkSEIInAccessUnit() } if (olsIncludeAllLayersFind) { +#if JVET_S0176_ITEM5 + olsIdxIncludeAllLayes = i; + if (payloadType == SEI::SUBPICTURE_LEVEL_INFO) + { + isNonNestedSliFound = true; + } +#endif break; } } @@ -1251,10 +1283,54 @@ void DecLib::checkSEIInAccessUnit() } #endif } + CHECK(bSdiPresentInAu && bAuxSEIsBeforeSdiSEIPresent[0], "When an AU contains both an SDI SEI message and an MAI SEI message, the SDI SEI message shall precede the MAI SEI message in decoding order."); CHECK(bSdiPresentInAu && bAuxSEIsBeforeSdiSEIPresent[1], "When an AU contains both an SDI SEI message with sdi_aux_id[i] equal to 1 for at least one value of i and an ACI SEI message, the SDI SEI message shall precede the ACI SEI message in decoding order."); CHECK(bSdiPresentInAu && bAuxSEIsBeforeSdiSEIPresent[2], "When an AU contains both an SDI SEI message with sdi_aux_id[i] equal to 2 for at least one value of i and a DRI SEI message, the SDI SEI message shall precede the DRI SEI message in decoding order."); + +#if JVET_S0176_ITEM5 + if (m_isFirstAuInCvs) + { + // when a non-nested SLI SEI shows up, check sps_num_subpics_minus1 for the OLS contains all layers with multiple subpictures per picture + if (isNonNestedSliFound) + { + checkMultiSubpicNum(olsIdxIncludeAllLayes); + } + + // when a nested SLI SEI shows up, loop over all applicable OLSs, and for layers in the each applicable OLS, check sps_num_subpics_minus1 for these layers with multiple subpictures per picture + for (auto sliInfo = m_accessUnitNestedSliSeiInfo.begin(); sliInfo != m_accessUnitNestedSliSeiInfo.end(); sliInfo++) + { + if (sliInfo->m_nestedSliPresent) + { + for (uint32_t olsIdxNestedSei = 0; olsIdxNestedSei < sliInfo->m_numOlssNestedSli; olsIdxNestedSei++) + { + int olsIdx = sliInfo->m_olsIdxNestedSLI[olsIdxNestedSei]; + checkMultiSubpicNum(olsIdx); + } + } + } + } +#endif +} + +#if JVET_S0176_ITEM5 +void DecLib::checkMultiSubpicNum(int olsIdx) +{ + int multiSubpicNum = 0; + for (int layerIdx = 0; layerIdx < m_vps->getNumLayersInOls(olsIdx); layerIdx++) + { + uint32_t layerId = m_vps->getLayerIdInOls(olsIdx, layerIdx); + if (m_accessUnitSpsNumSubpic[layerId] > 1) + { + if (multiSubpicNum == 0) + { + multiSubpicNum = m_accessUnitSpsNumSubpic[layerId]; + } + CHECK(multiSubpicNum != m_accessUnitSpsNumSubpic[layerId], "When an SLI SEI message is present for a CVS, the value of sps_num_subpics_minus1 shall be the same for all the SPSs referenced by the pictures in the layers with multiple subpictures per picture.") + } + } } +#endif #define SEI_REPETITION_CONSTRAINT_LIST_SIZE 21 @@ -2166,8 +2242,26 @@ void DecLib::xParsePrefixSEImessages() m_prefixSEINALUs.pop_front(); } xCheckPrefixSEIMessages(m_SEIs); +#if JVET_S0176_ITEM5 + SEIMessages scalableNestingSEIs = getSeisByType(m_SEIs, SEI::SCALABLE_NESTING); + if (scalableNestingSEIs.size()) + { + SEIScalableNesting *nestedSei = (SEIScalableNesting*)scalableNestingSEIs.front(); + SEIMessages nestedSliSei = getSeisByType(nestedSei->m_nestedSEIs, SEI::SUBPICTURE_LEVEL_INFO); + if (nestedSliSei.size() > 0) + { + AccessUnitNestedSliSeiInfo sliSeiInfo; + sliSeiInfo.m_nestedSliPresent = true; + sliSeiInfo.m_numOlssNestedSli = nestedSei->m_snNumOlssMinus1 + 1; + for (uint32_t olsIdxNestedSei = 0; olsIdxNestedSei <= nestedSei->m_snNumOlssMinus1; olsIdxNestedSei++) + { + sliSeiInfo.m_olsIdxNestedSLI[olsIdxNestedSei] = nestedSei->m_snOlsIdx[olsIdxNestedSei]; + } + m_accessUnitNestedSliSeiInfo.push_back(sliSeiInfo); + } + } +#endif xCheckDUISEIMessages(m_SEIs); - } void DecLib::xCheckPrefixSEIMessages( SEIMessages& prefixSEIs ) @@ -3227,6 +3321,9 @@ void DecLib::xDecodeSPS( InputNALUnit& nalu ) sps->setLayerId( nalu.m_nuhLayerId ); DTRACE( g_trace_ctx, D_QP_PER_CTU, "CTU Size: %dx%d", sps->getMaxCUWidth(), sps->getMaxCUHeight() ); m_parameterSetManager.storeSPS( sps, nalu.getBitstream().getFifo() ); +#if JVET_S0176_ITEM5 + m_accessUnitSpsNumSubpic[nalu.m_nuhLayerId] = sps->getNumSubPics(); +#endif } void DecLib::xDecodePPS( InputNALUnit& nalu ) diff --git a/source/Lib/DecoderLib/DecLib.h b/source/Lib/DecoderLib/DecLib.h index d81dc50e29b22e01e20a7db30d5b165e04c108c4..5e61927540dac5022d83b7ee65d94a549472ff1f 100644 --- a/source/Lib/DecoderLib/DecLib.h +++ b/source/Lib/DecoderLib/DecLib.h @@ -177,6 +177,16 @@ private: }; std::vector<AccessUnitPicInfo> m_accessUnitPicInfo; std::vector<AccessUnitPicInfo> m_firstAccessUnitPicInfo; +#if JVET_S0176_ITEM5 + struct AccessUnitNestedSliSeiInfo + { + bool m_nestedSliPresent; + uint32_t m_numOlssNestedSli; + uint32_t m_olsIdxNestedSLI[MAX_NUM_OLSS]; + }; + std::vector<AccessUnitNestedSliSeiInfo> m_accessUnitNestedSliSeiInfo; + int m_accessUnitSpsNumSubpic[MAX_VPS_LAYERS]; +#endif struct NalUnitInfo { NalUnitType m_nalUnitType; ///< nal_unit_type @@ -272,6 +282,11 @@ public: void checkLayerIdIncludedInCvss(); void CheckNoOutputPriorPicFlagsInAccessUnit(); void resetAccessUnitNoOutputPriorPicFlags() { m_accessUnitNoOutputPriorPicFlags.clear(); } +#if JVET_S0176_ITEM5 + void checkMultiSubpicNum(int olsIdx); + void resetAccessUnitNestedSliSeiInfo() { m_accessUnitNestedSliSeiInfo.clear(); } + void resetIsFirstAuInCvs(); +#endif void checkSeiInPictureUnit(); void resetPictureSeiNalus(); bool isSliceNaluFirstInAU( bool newPicture, InputNALUnit &nalu );