diff --git a/source/Lib/CommonLib/ParameterSetManager.cpp b/source/Lib/CommonLib/ParameterSetManager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e1760f7dec2964fc160f556e327d7888e2784a75 --- /dev/null +++ b/source/Lib/CommonLib/ParameterSetManager.cpp @@ -0,0 +1,230 @@ +/* The copyright in this software is being made available under the BSD +* License, included below. This software may be subject to other third party +* and contributor rights, including patent rights, and no such rights are +* granted under this license. +* +* Copyright (c) 2010-2020, ITU/ISO/IEC +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* * Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* * Neither the name of the ITU/ISO/IEC nor the names of its contributors may +* be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS +* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +* THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "CommonDef.h" +#include "ParameterSetManager.h" + +ParameterSetManager::ParameterSetManager() +: m_spsMap(MAX_NUM_SPS) +, m_ppsMap(MAX_NUM_PPS) +, m_apsMap(MAX_NUM_APS * MAX_NUM_APS_TYPE) +#if !JVET_Q0117_PARAMETER_SETS_CLEANUP +, m_dpsMap(MAX_NUM_DPS) +#endif +, m_vpsMap(MAX_NUM_VPS) +#if !JVET_Q0117_PARAMETER_SETS_CLEANUP +, m_activeDPSId(-1) +#endif +, m_activeSPSId(-1) +, m_activeVPSId(-1) +{ +} + + +ParameterSetManager::~ParameterSetManager() +{ +} + +// activate a PPS and depending on isIRAP parameter also SPS +// returns true, if activation is successful +bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP) +{ + PPS *pps = m_ppsMap.getPS(ppsId); + if (pps) + { + int spsId = pps->getSPSId(); +#if !ENABLING_MULTI_SPS + if (!isIRAP && (spsId != m_activeSPSId )) + { + msg( WARNING, "Warning: tried to activate a PPS referring to an inactive SPS at non-IDR."); + } + else +#endif + { + SPS *sps = m_spsMap.getPS(spsId); + + if (sps) + { +#if !JVET_Q0117_PARAMETER_SETS_CLEANUP + int dpsId = sps->getDecodingParameterSetId(); + if ((m_activeDPSId!=-1) && (dpsId != m_activeDPSId )) + { + msg( WARNING, "Warning: tried to activate a DPS with different ID than the currently active DPS. This should not happen within the same bitstream!"); + } + else + { + if (dpsId != 0) + { + DPS *dps =m_dpsMap.getPS(dpsId); + if (dps) + { + m_activeDPSId = dpsId; + m_dpsMap.setActive(dpsId); + } + else + { + msg( WARNING, "Warning: tried to activate a PPS that refers to a non-existing DPS."); + } + } + else + { + // set zero as active DPS ID (special reserved value, no actual DPS) + m_activeDPSId = dpsId; + m_dpsMap.setActive(dpsId); + } + } +#endif + 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 a PPS that refers to a non-existing VPS." ); + } + } + else + { + m_vpsMap.clear(); + m_vpsMap.allocatePS(0); + m_activeVPSId = 0; + m_vpsMap.setActive(0); + } + + m_spsMap.clear(); + m_spsMap.setActive(spsId); + m_activeSPSId = spsId; + m_ppsMap.clear(); + m_ppsMap.setActive(ppsId); + return true; + } + else + { + msg( WARNING, "Warning: tried to activate a PPS that refers to a non-existing SPS."); + } + } + } + else + { + msg( WARNING, "Warning: tried to activate a non-existing PPS."); + } + + // Failed to activate if reach here. + m_activeSPSId=-1; +#if !JVET_Q0117_PARAMETER_SETS_CLEANUP + m_activeDPSId=-1; +#endif + return false; +} + +bool ParameterSetManager::activateAPS(int apsId, int apsType) +{ + APS *aps = m_apsMap.getPS(apsId + (MAX_NUM_APS * apsType)); + if (aps) + { + m_apsMap.setActive(apsId + (MAX_NUM_APS * apsType)); + return true; + } + else + { + msg(WARNING, "Warning: tried to activate a non-existing APS."); + } + return false; +} + +template <> +void ParameterSetMap<APS>::setID(APS* parameterSet, const int psId) +{ + parameterSet->setAPSId(psId); +} +template <> +void ParameterSetMap<PPS>::setID(PPS* parameterSet, const int psId) +{ + parameterSet->setPPSId(psId); +} + +template <> +void ParameterSetMap<SPS>::setID(SPS* parameterSet, const int psId) +{ + parameterSet->setSPSId(psId); +} + +template <> +void ParameterSetMap<VPS>::setID(VPS* parameterSet, const int psId) +{ + parameterSet->setVPSId(psId); +} + +ProfileTierLevel::ProfileTierLevel() + : m_tierFlag (Level::MAIN) + , m_profileIdc (Profile::NONE) + , m_numSubProfile(0) + , m_subProfileIdc(0) + , m_levelIdc (Level::NONE) +{ + ::memset(m_subLayerLevelPresentFlag, 0, sizeof(m_subLayerLevelPresentFlag )); + ::memset(m_subLayerLevelIdc, Level::NONE, sizeof(m_subLayerLevelIdc )); +} + +void calculateParameterSetChangedFlag(bool &changed, const std::vector<uint8_t> *oldData, const std::vector<uint8_t> *newData) +{ + if (!changed) + { + if ((oldData==0 && newData!=0) || (oldData!=0 && newData==0)) + { + changed=true; + } + else if (oldData!=0 && newData!=0) + { + // compare the two + if (oldData->size() != newData->size()) + { + changed=true; + } + else + { + const uint8_t *pNewDataArray=&(*newData)[0]; + const uint8_t *pOldDataArray=&(*oldData)[0]; + if (memcmp(pOldDataArray, pNewDataArray, oldData->size())) + { + changed=true; + } + } + } + } +} diff --git a/source/Lib/CommonLib/ParameterSetManager.h b/source/Lib/CommonLib/ParameterSetManager.h new file mode 100644 index 0000000000000000000000000000000000000000..ce63f798a68d838da22a4f41e5166d778408ffb6 --- /dev/null +++ b/source/Lib/CommonLib/ParameterSetManager.h @@ -0,0 +1,287 @@ +/* The copyright in this software is being made available under the BSD + * License, included below. This software may be subject to other third party + * and contributor rights, including patent rights, and no such rights are + * granted under this license. + * + * Copyright (c) 2010-2020, ITU/ISO/IEC + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * * Neither the name of the ITU/ISO/IEC nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#ifndef __PARAMETERSETMANAGER__ +#define __PARAMETERSETMANAGER__ + +#include "Slice.h" +#include <map> + +void calculateParameterSetChangedFlag(bool &bChanged, const std::vector<uint8_t> *pOldData, const std::vector<uint8_t> *pNewData); + +template <class T> class ParameterSetMap +{ +public: + template <class Tm> + struct MapData + { + bool bChanged; + std::vector<uint8_t> *pNaluData; // Can be null + Tm* parameterSet; + }; + + ParameterSetMap(int maxId) + :m_maxId (maxId) + ,m_lastActiveParameterSet(NULL) + { + m_activePsId.clear(); + } + + ~ParameterSetMap() + { + for (typename std::map<int,MapData<T> >::iterator i = m_paramsetMap.begin(); i!= m_paramsetMap.end(); i++) + { + delete (*i).second.pNaluData; + delete (*i).second.parameterSet; + } + delete m_lastActiveParameterSet; m_lastActiveParameterSet = NULL; + } + + T *allocatePS(const int psId) + { + CHECK( psId >= m_maxId, "Invalid PS id" ); + if ( m_paramsetMap.find(psId) == m_paramsetMap.end() ) + { + m_paramsetMap[psId].bChanged = true; + m_paramsetMap[psId].pNaluData=0; + m_paramsetMap[psId].parameterSet = new T; + setID(m_paramsetMap[psId].parameterSet, psId); + } + return m_paramsetMap[psId].parameterSet; + } + + void clearMap() + { + m_paramsetMap.clear(); + } + + void storePS(int psId, T *ps, const std::vector<uint8_t> *pNaluData) + { + CHECK( psId >= m_maxId, "Invalid PS id" ); + if ( m_paramsetMap.find(psId) != m_paramsetMap.end() ) + { + MapData<T> &mapData=m_paramsetMap[psId]; + + // work out changed flag + calculateParameterSetChangedFlag(mapData.bChanged, mapData.pNaluData, pNaluData); + + if( ! mapData.bChanged ) + { + // just keep the old one + delete ps; + return; + } + + if (find(m_activePsId.begin(), m_activePsId.end(), psId) != m_activePsId.end()) + { + std::swap( m_paramsetMap[psId].parameterSet, m_lastActiveParameterSet ); + } + delete m_paramsetMap[psId].pNaluData; + delete m_paramsetMap[psId].parameterSet; + + m_paramsetMap[psId].parameterSet = ps; + } + else + { + m_paramsetMap[psId].parameterSet = ps; + m_paramsetMap[psId].bChanged = false; + } + if (pNaluData != 0) + { + m_paramsetMap[psId].pNaluData=new std::vector<uint8_t>; + *(m_paramsetMap[psId].pNaluData) = *pNaluData; + } + else + { + m_paramsetMap[psId].pNaluData=0; + } + } + + void checkAuApsContent( APS *aps, std::vector<int>& accessUnitApsNals ) + { + int apsId = ( aps->getAPSId() << NUM_APS_TYPE_LEN ) + (int)aps->getAPSType(); + + if( std::find( accessUnitApsNals.begin(), accessUnitApsNals.end(), apsId ) != accessUnitApsNals.end() ) + { + CHECK( m_paramsetMap.find( apsId ) == m_paramsetMap.end(), "APS does not exist" ); + APS* existedAPS = m_paramsetMap[apsId].parameterSet; + + if( aps->getAPSType() == LMCS_APS ) + { + CHECK( aps->getReshaperAPSInfo() != existedAPS->getReshaperAPSInfo(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" ); + } + else if( aps->getAPSType() == ALF_APS ) + { + CHECK( aps->getAlfAPSParam() != existedAPS->getAlfAPSParam(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" ); + } + else if( aps->getAPSType() == SCALING_LIST_APS ) + { + CHECK( aps->getScalingList() != existedAPS->getScalingList(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" ); + } + else + { + CHECK( true, "Wrong APS type" ); + } + } + else + { + accessUnitApsNals.push_back( apsId ); + } + } + + + void setChangedFlag(int psId, bool bChanged=true) + { + if ( m_paramsetMap.find(psId) != m_paramsetMap.end() ) + { + m_paramsetMap[psId].bChanged=bChanged; + } + } + + void clearChangedFlag(int psId) + { + if ( m_paramsetMap.find(psId) != m_paramsetMap.end() ) + { + m_paramsetMap[psId].bChanged=false; + } + } + + bool getChangedFlag(int psId) const + { + const typename std::map<int,MapData<T> >::const_iterator constit=m_paramsetMap.find(psId); + if ( constit != m_paramsetMap.end() ) + { + return constit->second.bChanged; + } + return false; + } + + T* getPS(int psId) + { + typename std::map<int,MapData<T> >::iterator it=m_paramsetMap.find(psId); + return ( it == m_paramsetMap.end() ) ? NULL : (it)->second.parameterSet; + } + + const T* getPS(int psId) const + { + typename std::map<int,MapData<T> >::const_iterator it=m_paramsetMap.find(psId); + return ( it == m_paramsetMap.end() ) ? NULL : (it)->second.parameterSet; + } + + T* getFirstPS() + { + return (m_paramsetMap.begin() == m_paramsetMap.end() ) ? NULL : m_paramsetMap.begin()->second.parameterSet; + } + + void setActive(int psId) { m_activePsId.push_back(psId); } + void clear() { m_activePsId.clear(); } + +private: + std::map<int,MapData<T> > m_paramsetMap; + int m_maxId; + std::vector<int> m_activePsId; + T* m_lastActiveParameterSet; + static void setID(T* parameterSet, const int psId); +}; + +class ParameterSetManager +{ +public: + ParameterSetManager(); + virtual ~ParameterSetManager(); + + void storeVPS(VPS *vps, const std::vector<uint8_t> &naluData) { m_vpsMap.storePS(vps->getVPSId(), vps, &naluData); } + VPS* getVPS( int vpsId ) { return m_vpsMap.getPS( vpsId ); }; + +#if !JVET_Q0117_PARAMETER_SETS_CLEANUP + void storeDPS(DPS *dps, const std::vector<uint8_t> &naluData) { m_dpsMap.storePS( dps->getDecodingParameterSetId(), dps, &naluData); }; + // get pointer to existing video parameter set + DPS* getDPS(int dpsId) { return m_dpsMap.getPS(dpsId); }; + bool getDPSChangedFlag(int dpsId) const { return m_dpsMap.getChangedFlag(dpsId); } + void clearDPSChangedFlag(int dpsId) { m_dpsMap.clearChangedFlag(dpsId); } + DPS* getFirstDPS() { return m_dpsMap.getFirstPS(); }; +#endif + // 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 + SPS* getSPS(int spsId) { return m_spsMap.getPS(spsId); }; + bool getSPSChangedFlag(int spsId) const { return m_spsMap.getChangedFlag(spsId); } + void clearSPSChangedFlag(int spsId) { m_spsMap.clearChangedFlag(spsId); } + SPS* getFirstSPS() { return m_spsMap.getFirstPS(); }; + + // store picture parameter set and take ownership of it + void storePPS(PPS *pps, const std::vector<uint8_t> &naluData) { m_ppsMap.storePS( pps->getPPSId(), pps, &naluData); }; + // get pointer to existing picture parameter set + PPS* getPPS(int ppsId) { return m_ppsMap.getPS(ppsId); }; + bool getPPSChangedFlag(int ppsId) const { return m_ppsMap.getChangedFlag(ppsId); } + void clearPPSChangedFlag(int ppsId) { m_ppsMap.clearChangedFlag(ppsId); } + PPS* getFirstPPS() { return m_ppsMap.getFirstPS(); }; + + // activate a PPS and depending on isIRAP parameter also SPS + // returns true, if activation is successful + bool activatePPS(int ppsId, bool isIRAP); + APS** getAPSs() { return &m_apss[0]; } + ParameterSetMap<APS>* getApsMap() { return &m_apsMap; } + void storeAPS(APS *aps, const std::vector<uint8_t> &naluData) { m_apsMap.storePS(aps->getAPSId() + (MAX_NUM_APS * aps->getAPSType()), aps, &naluData); }; + APS* getAPS(int apsId, int apsType) { return m_apsMap.getPS(apsId + (MAX_NUM_APS * apsType)); }; + bool getAPSChangedFlag(int apsId, int apsType) const { return m_apsMap.getChangedFlag(apsId + (MAX_NUM_APS * apsType)); } + void clearAPSChangedFlag(int apsId, int apsType) { m_apsMap.clearChangedFlag(apsId + ( MAX_NUM_APS * apsType)); } + APS* getFirstAPS() { return m_apsMap.getFirstPS(); }; + bool activateAPS(int apsId, int apsType); + const SPS* getActiveSPS()const { return m_spsMap.getPS(m_activeSPSId); }; +#if !JVET_Q0117_PARAMETER_SETS_CLEANUP + const DPS* getActiveDPS()const { return m_dpsMap.getPS(m_activeDPSId); }; +#endif + void checkAuApsContent( APS *aps, std::vector<int>& accessUnitApsNals ) { m_apsMap.checkAuApsContent( aps, accessUnitApsNals ); } + +protected: + ParameterSetMap<SPS> m_spsMap; + ParameterSetMap<PPS> m_ppsMap; + ParameterSetMap<APS> m_apsMap; +#if !JVET_Q0117_PARAMETER_SETS_CLEANUP + ParameterSetMap<DPS> m_dpsMap; +#endif + ParameterSetMap<VPS> m_vpsMap; + + APS* m_apss[ALF_CTB_MAX_NUM_APS]; +#if !JVET_Q0117_PARAMETER_SETS_CLEANUP + int m_activeDPSId; // -1 for nothing active +#endif + int m_activeSPSId; // -1 for nothing active + int m_activeVPSId; // -1 for nothing active +}; + + +#endif diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index cea3e294a3a189ddd45b71fb8646a6adcc4eb092..01eae73096e4b78917976d4ef093c43fc8aff906 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -3604,231 +3604,6 @@ bool ScalingList::isLumaScalingList( int scalingListId) const } #endif -ParameterSetManager::ParameterSetManager() -: m_spsMap(MAX_NUM_SPS) -, m_ppsMap(MAX_NUM_PPS) -, m_apsMap(MAX_NUM_APS * MAX_NUM_APS_TYPE) -#if !JVET_Q0117_PARAMETER_SETS_CLEANUP -, m_dpsMap(MAX_NUM_DPS) -#endif -, m_vpsMap(MAX_NUM_VPS) -#if !JVET_Q0117_PARAMETER_SETS_CLEANUP -, m_activeDPSId(-1) -#endif -, m_activeSPSId(-1) -, m_activeVPSId(-1) -{ -} - - -ParameterSetManager::~ParameterSetManager() -{ -} - -//! activate a SPS from a active parameter sets SEI message -//! \returns true, if activation is successful -//bool ParameterSetManager::activateSPSWithSEI(int spsId) -//{ -// SPS *sps = m_spsMap.getPS(spsId); -// if (sps) -// { -// int vpsId = sps->getVPSId(); -// VPS *vps = m_vpsMap.getPS(vpsId); -// if (vps) -// { -// m_activeVPS = *(vps); -// m_activeSPS = *(sps); -// return true; -// } -// else -// { -// msg( WARNING, "Warning: tried to activate SPS using an Active parameter sets SEI message. Referenced VPS does not exist."); -// } -// } -// else -// { -// msg( WARNING, "Warning: tried to activate non-existing SPS using an Active parameter sets SEI message."); -// } -// return false; -//} - -//! activate a PPS and depending on isIDR parameter also SPS -//! \returns true, if activation is successful -bool ParameterSetManager::activatePPS(int ppsId, bool isIRAP) -{ - PPS *pps = m_ppsMap.getPS(ppsId); - 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) - { -#if !JVET_Q0117_PARAMETER_SETS_CLEANUP - int dpsId = sps->getDecodingParameterSetId(); - if ((m_activeDPSId!=-1) && (dpsId != m_activeDPSId )) - { - msg( WARNING, "Warning: tried to activate DPS with different ID than the currently active DPS. This should not happen within the same bitstream!"); - } - else - { - if (dpsId != 0) - { - DPS *dps =m_dpsMap.getPS(dpsId); - if (dps) - { - m_activeDPSId = dpsId; - m_dpsMap.setActive(dpsId); - } - else - { - msg( WARNING, "Warning: tried to activate PPS that refers to a non-existing DPS."); - } - } - else - { - // set zero as active DPS ID (special reserved value, no actual DPS) - m_activeDPSId = dpsId; - m_dpsMap.setActive(dpsId); - } - } -#endif - 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 - { - m_vpsMap.clear(); - m_vpsMap.allocatePS(0); - m_activeVPSId = 0; - m_vpsMap.setActive(0); - } - - m_spsMap.clear(); - m_spsMap.setActive(spsId); - m_activeSPSId = spsId; - m_ppsMap.clear(); - m_ppsMap.setActive(ppsId); - return true; - } - else - { - msg( WARNING, "Warning: tried to activate a PPS that refers to a non-existing SPS."); - } - } - } - else - { - msg( WARNING, "Warning: tried to activate non-existing PPS."); - } - - // Failed to activate if reach here. - m_activeSPSId=-1; -#if !JVET_Q0117_PARAMETER_SETS_CLEANUP - m_activeDPSId=-1; -#endif - return false; -} - -bool ParameterSetManager::activateAPS(int apsId, int apsType) -{ - APS *aps = m_apsMap.getPS(apsId + (MAX_NUM_APS * apsType)); - if (aps) - { - m_apsMap.setActive(apsId + (MAX_NUM_APS * apsType)); - return true; - } - else - { - msg(WARNING, "Warning: tried to activate non-existing APS."); - } - return false; -} - -template <> -void ParameterSetMap<APS>::setID(APS* parameterSet, const int psId) -{ - parameterSet->setAPSId(psId); -} -template <> -void ParameterSetMap<PPS>::setID(PPS* parameterSet, const int psId) -{ - parameterSet->setPPSId(psId); -} - -template <> -void ParameterSetMap<SPS>::setID(SPS* parameterSet, const int psId) -{ - parameterSet->setSPSId(psId); -} - -template <> -void ParameterSetMap<VPS>::setID(VPS* parameterSet, const int psId) -{ - parameterSet->setVPSId(psId); -} - -ProfileTierLevel::ProfileTierLevel() - : m_tierFlag (Level::MAIN) - , m_profileIdc (Profile::NONE) - , m_numSubProfile(0) - , m_subProfileIdc(0) - , m_levelIdc (Level::NONE) -{ - ::memset(m_subLayerLevelPresentFlag, 0, sizeof(m_subLayerLevelPresentFlag )); - ::memset(m_subLayerLevelIdc, Level::NONE, sizeof(m_subLayerLevelIdc )); -} - - -void calculateParameterSetChangedFlag(bool &bChanged, const std::vector<uint8_t> *pOldData, const std::vector<uint8_t> *pNewData) -{ - if (!bChanged) - { - if ((pOldData==0 && pNewData!=0) || (pOldData!=0 && pNewData==0)) - { - bChanged=true; - } - else if (pOldData!=0 && pNewData!=0) - { - // compare the two - if (pOldData->size() != pNewData->size()) - { - bChanged=true; - } - else - { - const uint8_t *pNewDataArray=&(*pNewData)[0]; - const uint8_t *pOldDataArray=&(*pOldData)[0]; - if (memcmp(pOldDataArray, pNewDataArray, pOldData->size())) - { - bChanged=true; - } - } - } - } -} - -//! \} - uint32_t PreCalcValues::getValIdx( const Slice &slice, const ChannelType chType ) const { return slice.isIntra() ? ( ISingleTree ? 0 : ( chType << 1 ) ) : 1; diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index ee507d16c236d4a4ba103ccceb4b602285893e82..5f9a7939b0f70fdc836c7cf338a80a21a775c335 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -3196,253 +3196,6 @@ public: private: };// END CLASS DEFINITION Slice -void calculateParameterSetChangedFlag(bool &bChanged, const std::vector<uint8_t> *pOldData, const std::vector<uint8_t> *pNewData); - -template <class T> class ParameterSetMap -{ -public: - template <class Tm> - struct MapData - { - bool bChanged; - std::vector<uint8_t> *pNaluData; // Can be null - Tm* parameterSet; - }; - - ParameterSetMap(int maxId) - :m_maxId (maxId) - ,m_lastActiveParameterSet(NULL) - { - m_activePsId.clear(); - } - - ~ParameterSetMap() - { - for (typename std::map<int,MapData<T> >::iterator i = m_paramsetMap.begin(); i!= m_paramsetMap.end(); i++) - { - delete (*i).second.pNaluData; - delete (*i).second.parameterSet; - } - delete m_lastActiveParameterSet; m_lastActiveParameterSet = NULL; - } - - T *allocatePS(const int psId) - { - CHECK( psId >= m_maxId, "Invalid PS id" ); - if ( m_paramsetMap.find(psId) == m_paramsetMap.end() ) - { - m_paramsetMap[psId].bChanged = true; - m_paramsetMap[psId].pNaluData=0; - m_paramsetMap[psId].parameterSet = new T; - setID(m_paramsetMap[psId].parameterSet, psId); - } - return m_paramsetMap[psId].parameterSet; - } - - void clearMap() - { - m_paramsetMap.clear(); - } - - void storePS(int psId, T *ps, const std::vector<uint8_t> *pNaluData) - { - CHECK( psId >= m_maxId, "Invalid PS id" ); - if ( m_paramsetMap.find(psId) != m_paramsetMap.end() ) - { - MapData<T> &mapData=m_paramsetMap[psId]; - - // work out changed flag - calculateParameterSetChangedFlag(mapData.bChanged, mapData.pNaluData, pNaluData); - - if( ! mapData.bChanged ) - { - // just keep the old one - delete ps; - return; - } - - if (find(m_activePsId.begin(), m_activePsId.end(), psId) != m_activePsId.end()) - { - std::swap( m_paramsetMap[psId].parameterSet, m_lastActiveParameterSet ); - } - delete m_paramsetMap[psId].pNaluData; - delete m_paramsetMap[psId].parameterSet; - - m_paramsetMap[psId].parameterSet = ps; - } - else - { - m_paramsetMap[psId].parameterSet = ps; - m_paramsetMap[psId].bChanged = false; - } - if (pNaluData != 0) - { - m_paramsetMap[psId].pNaluData=new std::vector<uint8_t>; - *(m_paramsetMap[psId].pNaluData) = *pNaluData; - } - else - { - m_paramsetMap[psId].pNaluData=0; - } - } - - void checkAuApsContent( APS *aps, std::vector<int>& accessUnitApsNals ) - { - int apsId = ( aps->getAPSId() << NUM_APS_TYPE_LEN ) + (int)aps->getAPSType(); - - if( std::find( accessUnitApsNals.begin(), accessUnitApsNals.end(), apsId ) != accessUnitApsNals.end() ) - { - CHECK( m_paramsetMap.find( apsId ) == m_paramsetMap.end(), "APS does not exist" ); - APS* existedAPS = m_paramsetMap[apsId].parameterSet; - - if( aps->getAPSType() == LMCS_APS ) - { - CHECK( aps->getReshaperAPSInfo() != existedAPS->getReshaperAPSInfo(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" ); - } - else if( aps->getAPSType() == ALF_APS ) - { - CHECK( aps->getAlfAPSParam() != existedAPS->getAlfAPSParam(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" ); - } - else if( aps->getAPSType() == SCALING_LIST_APS ) - { - CHECK( aps->getScalingList() != existedAPS->getScalingList(), "All APS NAL units with a particular value of adaptation_parameter_set_id and a particular value of aps_params_type within an access unit shall have the same content" ); - } - else - { - CHECK( true, "Wrong APS type" ); - } - } - else - { - accessUnitApsNals.push_back( apsId ); - } - } - - - void setChangedFlag(int psId, bool bChanged=true) - { - if ( m_paramsetMap.find(psId) != m_paramsetMap.end() ) - { - m_paramsetMap[psId].bChanged=bChanged; - } - } - - void clearChangedFlag(int psId) - { - if ( m_paramsetMap.find(psId) != m_paramsetMap.end() ) - { - m_paramsetMap[psId].bChanged=false; - } - } - - bool getChangedFlag(int psId) const - { - const typename std::map<int,MapData<T> >::const_iterator constit=m_paramsetMap.find(psId); - if ( constit != m_paramsetMap.end() ) - { - return constit->second.bChanged; - } - return false; - } - - T* getPS(int psId) - { - typename std::map<int,MapData<T> >::iterator it=m_paramsetMap.find(psId); - return ( it == m_paramsetMap.end() ) ? NULL : (it)->second.parameterSet; - } - - const T* getPS(int psId) const - { - typename std::map<int,MapData<T> >::const_iterator it=m_paramsetMap.find(psId); - return ( it == m_paramsetMap.end() ) ? NULL : (it)->second.parameterSet; - } - - T* getFirstPS() - { - return (m_paramsetMap.begin() == m_paramsetMap.end() ) ? NULL : m_paramsetMap.begin()->second.parameterSet; - } - - void setActive(int psId) { m_activePsId.push_back(psId); } - void clear() { m_activePsId.clear(); } - -private: - std::map<int,MapData<T> > m_paramsetMap; - int m_maxId; - std::vector<int> m_activePsId; - T* m_lastActiveParameterSet; - static void setID(T* parameterSet, const int psId); -}; - -class ParameterSetManager -{ -public: - ParameterSetManager(); - virtual ~ParameterSetManager(); - - void storeVPS(VPS *vps, const std::vector<uint8_t> &naluData) { m_vpsMap.storePS(vps->getVPSId(), vps, &naluData); } - VPS* getVPS( int vpsId ) { return m_vpsMap.getPS( vpsId ); }; - -#if !JVET_Q0117_PARAMETER_SETS_CLEANUP - void storeDPS(DPS *dps, const std::vector<uint8_t> &naluData) { m_dpsMap.storePS( dps->getDecodingParameterSetId(), dps, &naluData); }; - //! get pointer to existing video parameter set - DPS* getDPS(int dpsId) { return m_dpsMap.getPS(dpsId); }; - bool getDPSChangedFlag(int dpsId) const { return m_dpsMap.getChangedFlag(dpsId); } - void clearDPSChangedFlag(int dpsId) { m_dpsMap.clearChangedFlag(dpsId); } - DPS* getFirstDPS() { return m_dpsMap.getFirstPS(); }; -#endif - //! 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 - SPS* getSPS(int spsId) { return m_spsMap.getPS(spsId); }; - bool getSPSChangedFlag(int spsId) const { return m_spsMap.getChangedFlag(spsId); } - void clearSPSChangedFlag(int spsId) { m_spsMap.clearChangedFlag(spsId); } - SPS* getFirstSPS() { return m_spsMap.getFirstPS(); }; - - //! store picture parameter set and take ownership of it - void storePPS(PPS *pps, const std::vector<uint8_t> &naluData) { m_ppsMap.storePS( pps->getPPSId(), pps, &naluData); }; - //! get pointer to existing picture parameter set - PPS* getPPS(int ppsId) { return m_ppsMap.getPS(ppsId); }; - bool getPPSChangedFlag(int ppsId) const { return m_ppsMap.getChangedFlag(ppsId); } - void clearPPSChangedFlag(int ppsId) { m_ppsMap.clearChangedFlag(ppsId); } - PPS* getFirstPPS() { return m_ppsMap.getFirstPS(); }; - - //! activate a SPS from a active parameter sets SEI message - //! \returns true, if activation is successful - // bool activateSPSWithSEI(int SPSId); - - //! activate a PPS and depending on isIDR parameter also SPS - //! \returns true, if activation is successful - bool activatePPS(int ppsId, bool isIRAP); - APS** getAPSs() { return &m_apss[0]; } - ParameterSetMap<APS>* getApsMap() { return &m_apsMap; } - void storeAPS(APS *aps, const std::vector<uint8_t> &naluData) { m_apsMap.storePS(aps->getAPSId() + (MAX_NUM_APS * aps->getAPSType()), aps, &naluData); }; - APS* getAPS(int apsId, int apsType) { return m_apsMap.getPS(apsId + (MAX_NUM_APS * apsType)); }; - bool getAPSChangedFlag(int apsId, int apsType) const { return m_apsMap.getChangedFlag(apsId + (MAX_NUM_APS * apsType)); } - void clearAPSChangedFlag(int apsId, int apsType) { m_apsMap.clearChangedFlag(apsId + ( MAX_NUM_APS * apsType)); } - APS* getFirstAPS() { return m_apsMap.getFirstPS(); }; - bool activateAPS(int apsId, int apsType); - const SPS* getActiveSPS()const { return m_spsMap.getPS(m_activeSPSId); }; -#if !JVET_Q0117_PARAMETER_SETS_CLEANUP - const DPS* getActiveDPS()const { return m_dpsMap.getPS(m_activeDPSId); }; -#endif - void checkAuApsContent( APS *aps, std::vector<int>& accessUnitApsNals ) { m_apsMap.checkAuApsContent( aps, accessUnitApsNals ); } - -protected: - ParameterSetMap<SPS> m_spsMap; - ParameterSetMap<PPS> m_ppsMap; - ParameterSetMap<APS> m_apsMap; -#if !JVET_Q0117_PARAMETER_SETS_CLEANUP - ParameterSetMap<DPS> m_dpsMap; -#endif - ParameterSetMap<VPS> m_vpsMap; - - APS* m_apss[ALF_CTB_MAX_NUM_APS]; -#if !JVET_Q0117_PARAMETER_SETS_CLEANUP - int m_activeDPSId; // -1 for nothing active -#endif - int m_activeSPSId; // -1 for nothing active - int m_activeVPSId; // -1 for nothing active -}; class PreCalcValues { diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h index 104374a2d753fb2c974010893a10fc60ea91c572..e160db1999fe6889f5c3e05a9e1030b5d1f42541 100644 --- a/source/Lib/DecoderLib/VLCReader.h +++ b/source/Lib/DecoderLib/VLCReader.h @@ -42,6 +42,7 @@ #include "CommonLib/BitStream.h" #include "CommonLib/Slice.h" #include "CommonLib/SampleAdaptiveOffset.h" +#include "CommonLib/ParameterSetManager.h" #include "CABACReader.h" #if ENABLE_TRACING diff --git a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h index 5c620b053c1cb0eaa42b79c06d7b5674dda76e5e..b477b532484c5f5ad72f220007bce9d28d0b8731 100644 --- a/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h +++ b/source/Lib/EncoderLib/EncAdaptiveLoopFilter.h @@ -39,6 +39,7 @@ #define __ENCADAPTIVELOOPFILTER__ #include "CommonLib/AdaptiveLoopFilter.h" +#include "CommonLib/ParameterSetManager.h" #include "CABACWriter.h" #include "EncCfg.h" diff --git a/source/Lib/EncoderLib/EncLibCommon.h b/source/Lib/EncoderLib/EncLibCommon.h index 353b7410f33d59f53f76e1c4d3c05fefe9161869..a422beda396f3fbf0fad974f1f5a35b649708645 100644 --- a/source/Lib/EncoderLib/EncLibCommon.h +++ b/source/Lib/EncoderLib/EncLibCommon.h @@ -39,6 +39,7 @@ #include <list> #include <fstream> #include "CommonLib/Slice.h" +#include "CommonLib/ParameterSetManager.h" class EncLibCommon {