diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index 35a114176aaf6f6610610a9fc32e90220c1d7ff7..4638f6dc7e8442a9ee51156562805e1b02799194 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -199,24 +199,25 @@ void EncApp::xInitLibCfg( int layerIdx ) } } } - CHECK( m_numPtlsInVps == 0, "There has to be at least one PTL structure in the VPS." ); - vps.setNumPtls ( m_numPtlsInVps ); - vps.setPtPresentFlag (0, 1); + CHECK(m_numPtlsInVps == 0, "There has to be at least one PTL structure in the VPS."); + vps.setNumPtls(m_numPtlsInVps); + vps.setPtPresentFlag(0, true); for (int i = 0; i < vps.getNumPtls(); i++) { if( i > 0 ) - vps.setPtPresentFlag(i, m_ptPresentInPtl[i]); + { + vps.setPtPresentFlag(i, m_ptPresentInPtl[i] != 0); + } vps.setPtlMaxTemporalId (i, vps.getMaxSubLayers() - 1); } for (int i = 0; i < vps.getNumOutputLayerSets(); i++) { vps.setOlsPtlIdx (i, m_olsPtlIdx[i]); } - if (layerIdx == 0) - { - vps.resizePTL(vps.getNumPtls()); - } - ProfileTierLevel ptl; + + CHECK(layerIdx >= vps.getNumPtls(), + "Insufficient number of Profile/Tier/Level entries in VPS. Consider increasing NumPTLsInVPS"); + ProfileTierLevel &ptl = vps.getProfileTierLevel(layerIdx); ptl.setLevelIdc ( m_level ); ptl.setProfileIdc ( m_profile); ptl.setTierFlag ( m_levelTier ); @@ -235,8 +236,9 @@ void EncApp::xInitLibCfg( int layerIdx ) ptl.setSubProfileIdc (i, m_subProfile[i]); } if ( 0 < layerIdx ) + { ptl.setLevelIdc ( m_levelPtl[layerIdx] ); - vps.setProfileTierLevel(layerIdx, ptl); + } vps.setVPSExtensionFlag ( false ); m_cEncLib.setProfile ( m_profile); m_cEncLib.setLevel ( m_levelTier, m_level); diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 1637f07a3721313a4cff473e7afe6be677829c1c..776538e069aa0851aa5a4ece96ed891decaf48a1 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -1014,6 +1014,7 @@ protected: int m_numPtlsInVps; int m_ptPresentInPtl[MAX_NUM_OLSS]; + EncCfgParam::CfgVPSParameters m_cfgVPSParameters; Level::Name m_levelPtl[MAX_NUM_OLSS]; int m_olsPtlIdx[MAX_NUM_OLSS]; diff --git a/source/App/StreamMergeApp/StreamMergeApp.cpp b/source/App/StreamMergeApp/StreamMergeApp.cpp index 1db95048fa2d55f3ca829428c1e9a09f6459fb20..fa1ba45992296c9b235b405aa0d1f87cabd3363f 100644 --- a/source/App/StreamMergeApp/StreamMergeApp.cpp +++ b/source/App/StreamMergeApp/StreamMergeApp.cpp @@ -409,9 +409,7 @@ bool StreamMergeApp::preInjectNalu(MergeLayer &layer, InputNALUnit &inNalu, Outp vps->setLayerId(i, i); // Because we use layer IDs that are layer indices. } vps->setMaxLayers(m_numInputStreams); - vector<ProfileTierLevel> ptls; - ptls.push_back(ProfileTierLevel()); - vps->setProfileTierLevel(ptls); + vps->setNumPtls(1); layer.vpsIdMapping[0] = vps->getVPSId(); layer.psManager.storeVPS(vps, hlsReader.getBitstream()->getFifo()); hlsWriter.codeVPS(vps); diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index 4e2d4264daeb7d0ea66d5bf58ae4186081e4a264..a10376a296bbea1d16c371627bb5d2400d33c581 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -601,6 +601,13 @@ public: void setSubLayerLevelIdc(int i, Level::Name x) { m_subLayerLevelIdc[i] = x; } friend bool operator == (const ProfileTierLevel& op1, const ProfileTierLevel& op2); friend bool operator != (const ProfileTierLevel& op1, const ProfileTierLevel& op2); + + void copyProfileTierConstraintsFrom(const ProfileTierLevel &ptl) + { + m_profileIdc = ptl.m_profileIdc; + m_tierFlag = ptl.m_tierFlag; + m_constraintInfo = ptl.m_constraintInfo; + } }; @@ -1117,8 +1124,8 @@ public: bool getOlsOutputLayerFlag(uint32_t ols, uint32_t layer) const { return m_vpsOlsOutputLayerFlag[ols][layer]; } void setOlsOutputLayerFlag(uint32_t ols, uint32_t layer, bool t) { m_vpsOlsOutputLayerFlag[ols][layer] = t; } - uint32_t getNumPtls() const { return m_vpsNumPtls; } - void setNumPtls(uint32_t val) { m_vpsNumPtls = val; } + uint32_t getNumPtls() const { return (uint32_t) m_vpsProfileTierLevel.size(); } + void setNumPtls(uint32_t val) { m_vpsProfileTierLevel.resize(val); } bool getPtPresentFlag(int idx) const { return m_ptPresentFlag[idx]; } void setPtPresentFlag(int idx, bool val) { m_ptPresentFlag[idx] = val; } @@ -1126,10 +1133,8 @@ public: uint32_t getPtlMaxTemporalId(int idx) const { return m_ptlMaxTemporalId[idx]; } void setPtlMaxTemporalId(int idx, uint32_t val) { m_ptlMaxTemporalId[idx] = val; } - void setProfileTierLevel(const std::vector<ProfileTierLevel> &val) { m_vpsProfileTierLevel = val; } - void setProfileTierLevel(int layerIdx, const ProfileTierLevel val) { m_vpsProfileTierLevel[layerIdx] = val; } - void resizePTL(int val) { m_vpsProfileTierLevel.resize(val); } - const ProfileTierLevel& getProfileTierLevel(int idx) const { return m_vpsProfileTierLevel[idx]; } + ProfileTierLevel &getProfileTierLevel(int idx) { return m_vpsProfileTierLevel[idx]; } + const ProfileTierLevel &getProfileTierLevel(int idx) const { return m_vpsProfileTierLevel[idx]; } uint32_t getOlsPtlIdx(int idx) const { return m_olsPtlIdx[idx]; } void setOlsPtlIdx(int idx, uint32_t val) { m_olsPtlIdx[idx] = val; } diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 42dc74c2845a07a4196aa9ca7755d81e8d43a7dd..ca2d98925b03d48c56e7c6b8739a2127abcfbf9e 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -2359,11 +2359,11 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS) if(i > 0) { xReadFlag(uiCode, "vps_pt_present_flag"); - pcVPS->setPtPresentFlag(i, uiCode); + pcVPS->setPtPresentFlag(i, uiCode != 0); } else { - pcVPS->setPtPresentFlag(0, 1); + pcVPS->setPtPresentFlag(0, true); } if (!pcVPS->getDefaultPtlDpbHrdMaxTidFlag()) { @@ -2383,19 +2383,20 @@ void HLSyntaxReader::parseVPS(VPS* pcVPS) cnt++; } CHECK(cnt >= 8, "Read more than '8' alignment bits"); - std::vector<ProfileTierLevel> ptls; - ptls.resize(pcVPS->getNumPtls()); + for (int i = 0; i < pcVPS->getNumPtls(); i++) { - parseProfileTierLevel(&ptls[i], pcVPS->getPtPresentFlag(i), pcVPS->getPtlMaxTemporalId(i)); + ProfileTierLevel &ptl = pcVPS->getProfileTierLevel(i); + parseProfileTierLevel(&ptl, pcVPS->getPtPresentFlag(i), pcVPS->getPtlMaxTemporalId(i)); + if (!pcVPS->getPtPresentFlag(i)) { - ptls[i].setProfileIdc(ptls[i - 1].getProfileIdc()); - ptls[i].setTierFlag(ptls[i - 1].getTierFlag()); - *ptls[i].getConstraintInfo() = *ptls[i - 1].getConstraintInfo(); + CHECK(i == 0, "Profile/Tier should always be present for first entry"); + + ptl.copyProfileTierConstraintsFrom(pcVPS->getProfileTierLevel(i - 1)); } } - pcVPS->setProfileTierLevel(ptls); + for (int i = 0; i < pcVPS->getTotalNumOLSs(); i++) { if (pcVPS->getNumPtls() > 1 && pcVPS->getNumPtls() != pcVPS->getTotalNumOLSs())