/src/vvdec/source/Lib/CommonLib/ParameterSetManager.h
Line | Count | Source |
1 | | /* ----------------------------------------------------------------------------- |
2 | | The copyright in this software is being made available under the Clear BSD |
3 | | License, included below. No patent rights, trademark rights and/or |
4 | | other Intellectual Property Rights other than the copyrights concerning |
5 | | the Software are granted under this license. |
6 | | |
7 | | The Clear BSD License |
8 | | |
9 | | Copyright (c) 2018-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVdeC Authors. |
10 | | All rights reserved. |
11 | | |
12 | | Redistribution and use in source and binary forms, with or without modification, |
13 | | are permitted (subject to the limitations in the disclaimer below) provided that |
14 | | the following conditions are met: |
15 | | |
16 | | * Redistributions of source code must retain the above copyright notice, |
17 | | this list of conditions and the following disclaimer. |
18 | | |
19 | | * Redistributions in binary form must reproduce the above copyright |
20 | | notice, this list of conditions and the following disclaimer in the |
21 | | documentation and/or other materials provided with the distribution. |
22 | | |
23 | | * Neither the name of the copyright holder nor the names of its |
24 | | contributors may be used to endorse or promote products derived from this |
25 | | software without specific prior written permission. |
26 | | |
27 | | NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY |
28 | | THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
29 | | CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
30 | | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
31 | | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR |
32 | | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
33 | | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
34 | | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR |
35 | | BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
36 | | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
37 | | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
38 | | POSSIBILITY OF SUCH DAMAGE. |
39 | | |
40 | | |
41 | | ------------------------------------------------------------------------------------------- */ |
42 | | |
43 | | #pragma once |
44 | | |
45 | | #include "CommonDef.h" |
46 | | #include "Slice.h" |
47 | | |
48 | | #include <map> |
49 | | #include <vector> |
50 | | #include <array> |
51 | | |
52 | | namespace vvdec |
53 | | { |
54 | | |
55 | | template<class T, int MAX_ID> |
56 | | class ParameterSetMap |
57 | | { |
58 | | public: |
59 | | struct MapData |
60 | | { |
61 | | AlignedByteVec cNaluData; // Can be empty |
62 | | std::shared_ptr<T> parameterSet; |
63 | | bool bChanged = false; |
64 | | }; |
65 | | |
66 | | ~ParameterSetMap() |
67 | 0 | { |
68 | 0 | m_paramsetMap.clear(); |
69 | 0 | m_lastActiveParameterSet.reset(); |
70 | 0 | } Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::VPS, 16>::~ParameterSetMap() Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::APS, 64>::~ParameterSetMap() Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::PPS, 64>::~ParameterSetMap() Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::SPS, 16>::~ParameterSetMap() |
71 | | |
72 | | void storePS( int psId, T* ps, AlignedByteVec&& cNaluData ) |
73 | 0 | { |
74 | 0 | CHECK( psId >= MAX_ID, "Invalid PS id" ); |
75 | 0 | if( m_paramsetMap.find( psId ) != m_paramsetMap.end() ) |
76 | 0 | { |
77 | 0 | MapData& mapData = m_paramsetMap[psId]; |
78 | | |
79 | | // work out changed flag |
80 | 0 | mapData.parameterSet->m_changedFlag |= ( mapData.cNaluData != cNaluData ); |
81 | | |
82 | | // Don't throw away identical parameter sets as VTM does: |
83 | | // The PPS can be identical to a previous one, but the SPS changed, so it needs to be interpreted differently. |
84 | | // |
85 | | // if( !mapData.parameterSet->m_changedFlag ) |
86 | | // { |
87 | | // // just keep the old one |
88 | | // delete ps; |
89 | | // return; |
90 | | // } |
91 | |
|
92 | 0 | if( find( m_activePsId.begin(), m_activePsId.end(), psId ) != m_activePsId.end() ) |
93 | 0 | { |
94 | 0 | std::swap( m_paramsetMap[psId].parameterSet, m_lastActiveParameterSet ); |
95 | 0 | } |
96 | 0 | m_paramsetMap[psId].cNaluData.clear(); |
97 | 0 | m_paramsetMap[psId].parameterSet.reset(ps); |
98 | 0 | } |
99 | 0 | else |
100 | 0 | { |
101 | 0 | m_paramsetMap[psId].parameterSet.reset(ps); |
102 | 0 | ps->m_changedFlag = false; |
103 | 0 | } |
104 | |
|
105 | 0 | if( !cNaluData.empty() ) |
106 | 0 | { |
107 | 0 | m_paramsetMap[psId].cNaluData = std::move( cNaluData ); |
108 | 0 | } |
109 | 0 | else |
110 | 0 | { |
111 | 0 | m_paramsetMap[psId].cNaluData.clear(); |
112 | 0 | } |
113 | 0 | } Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::VPS, 16>::storePS(int, vvdec::VPS*, std::__1::vector<unsigned char, vvdec::AlignedAllocator<unsigned char> >&&) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::SPS, 16>::storePS(int, vvdec::SPS*, std::__1::vector<unsigned char, vvdec::AlignedAllocator<unsigned char> >&&) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::PPS, 64>::storePS(int, vvdec::PPS*, std::__1::vector<unsigned char, vvdec::AlignedAllocator<unsigned char> >&&) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::APS, 64>::storePS(int, vvdec::APS*, std::__1::vector<unsigned char, vvdec::AlignedAllocator<unsigned char> >&&) |
114 | | |
115 | | T* getPS_nothrow( int psId ) |
116 | 0 | { |
117 | 0 | auto it = m_paramsetMap.find( psId ); |
118 | 0 | return it == m_paramsetMap.end() ? nullptr : it->second.parameterSet.get(); |
119 | 0 | } Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::SPS, 16>::getPS_nothrow(int) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::PPS, 64>::getPS_nothrow(int) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::APS, 64>::getPS_nothrow(int) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::VPS, 16>::getPS_nothrow(int) |
120 | | |
121 | | const T* getPS_nothrow( int psId ) const |
122 | 0 | { |
123 | 0 | auto it = m_paramsetMap.find( psId ); |
124 | 0 | return it == m_paramsetMap.end() ? nullptr : it->second.parameterSet.get(); |
125 | 0 | } Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::VPS, 16>::getPS_nothrow(int) const Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::SPS, 16>::getPS_nothrow(int) const Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::PPS, 64>::getPS_nothrow(int) const Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::APS, 64>::getPS_nothrow(int) const |
126 | | |
127 | | T* getPS( int psId ) |
128 | 0 | { |
129 | 0 | T* ps = getPS_nothrow( psId ); |
130 | 0 | constexpr static int apsIdShift = std::is_same<T, APS>::value ? NUM_APS_TYPE_LEN : 0; |
131 | 0 | CHECK( !ps, "Missing Parameter Set (id:" << ( psId >> apsIdShift ) << ')' ); |
132 | 0 | return ps; |
133 | 0 | } Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::SPS, 16>::getPS(int) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::PPS, 64>::getPS(int) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::APS, 64>::getPS(int) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::VPS, 16>::getPS(int) |
134 | | |
135 | | const T* getPS( int psId ) const |
136 | 0 | { |
137 | 0 | const T* ps = getPS_nothrow( psId ); |
138 | 0 | constexpr static int apsIdShift = std::is_same<T, APS>::value ? NUM_APS_TYPE_LEN : 0; |
139 | 0 | CHECK( !ps, "Missing Parameter Set (id:" << ( psId >> apsIdShift ) << ')' ); |
140 | 0 | return ps; |
141 | 0 | } Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::VPS, 16>::getPS(int) const Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::SPS, 16>::getPS(int) const Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::PPS, 64>::getPS(int) const Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::APS, 64>::getPS(int) const |
142 | | |
143 | | T* getFirstPS() const |
144 | 0 | { |
145 | 0 | return ( m_paramsetMap.begin() == m_paramsetMap.end() ) ? NULL : m_paramsetMap.begin()->second.parameterSet.get(); |
146 | 0 | } Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::SPS, 16>::getFirstPS() const Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::PPS, 64>::getFirstPS() const Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::APS, 64>::getFirstPS() const |
147 | | |
148 | 0 | void setActive( int psId ) { m_activePsId.push_back( psId ); }Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::VPS, 16>::setActive(int) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::SPS, 16>::setActive(int) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::PPS, 64>::setActive(int) Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::APS, 64>::setActive(int) |
149 | 0 | void clearActive() { m_activePsId.clear(); }Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::APS, 64>::clearActive() Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::VPS, 16>::clearActive() Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::SPS, 16>::clearActive() Unexecuted instantiation: vvdec::ParameterSetMap<vvdec::PPS, 64>::clearActive() |
150 | | void clearMap() { m_paramsetMap.clear(); } |
151 | | |
152 | | private: |
153 | | std::map<int, MapData> m_paramsetMap; |
154 | | std::shared_ptr<T> m_lastActiveParameterSet; |
155 | | std::vector<int> m_activePsId; |
156 | | }; |
157 | | |
158 | | |
159 | | class ParameterSetManager |
160 | | { |
161 | | public: |
162 | 0 | ParameterSetManager() = default; |
163 | 0 | ~ParameterSetManager() = default; |
164 | | |
165 | | using APSArray = std::array<const APS*, ALF_CTB_MAX_NUM_APS>; |
166 | | |
167 | | struct ActivePSs |
168 | | { |
169 | | const SPS* sps; |
170 | | const PPS* pps; |
171 | | APSArray* alfAPSs; |
172 | | const APS* lmcsAps; |
173 | | const APS* scalingListAps; |
174 | | }; |
175 | | |
176 | | ActivePSs xActivateParameterSets( const bool isFirstSlice, const Slice* pPilot, const PicHeader* picHeader ); |
177 | | |
178 | | //! store sequence parameter set and take ownership of it |
179 | | //! store picture parameter set and take ownership of it |
180 | 0 | void storeVPS( VPS* vps, AlignedByteVec& naluData ) { m_vpsMap.storePS( vps->getVPSId(), vps, std::move( naluData ) ); } |
181 | 0 | void storeSPS( SPS* sps, AlignedByteVec& naluData ) { m_spsMap.storePS( sps->getSPSId(), sps, std::move( naluData ) ); } |
182 | 0 | void storePPS( PPS* pps, AlignedByteVec& naluData ) { m_ppsMap.storePS( pps->getPPSId(), pps, std::move( naluData ) ); } |
183 | 0 | void storeAPS( APS* aps, AlignedByteVec& naluData ) { m_apsMap.storePS( ( aps->getAPSId() << NUM_APS_TYPE_LEN ) + aps->getAPSType(), aps, std::move( naluData ) ); } |
184 | | |
185 | | //! get pointer to existing sequence parameter set |
186 | 0 | const VPS* getVPS ( int vpsId ) const { if( !vpsId ) return nullptr; return m_vpsMap.getPS( vpsId ); } |
187 | 0 | const SPS* getSPS ( int spsId ) const { return m_spsMap.getPS ( spsId ); } |
188 | 0 | const PPS* getPPS ( int ppsId ) const { return m_ppsMap.getPS ( ppsId ); } |
189 | 0 | const APS* getAPS ( int apsId, int apsType ) const { return m_apsMap.getPS ( ( apsId << NUM_APS_TYPE_LEN ) + apsType ); } |
190 | 0 | const APS* getAPS_nothrow( int apsId, int apsType ) const { return m_apsMap.getPS_nothrow( ( apsId << NUM_APS_TYPE_LEN ) + apsType ); } |
191 | | // getter only used by DecLibParser::prepareLostPicture(). Is it really needed? |
192 | 0 | const APSArray& getAlfAPSs() const { return m_alfAPSs; } |
193 | | |
194 | 0 | const SPS* getFirstSPS() const { return m_spsMap.getFirstPS(); } |
195 | 0 | const PPS* getFirstPPS() const { return m_ppsMap.getFirstPS(); } |
196 | 0 | const APS* getFirstAPS() const { return m_apsMap.getFirstPS(); } |
197 | | |
198 | | //! activate a PPS and, depending on isIDR parameter, also SPS. returns true, if activation is successful |
199 | | bool activatePPS( int ppsId, bool isIRAP ); |
200 | | bool activateAPS( int apsId, int apsType ); |
201 | | |
202 | 0 | const SPS* getActiveSPS() const { return m_spsMap.getPS( m_activeSPSId ); } |
203 | | |
204 | | private: |
205 | 0 | SPS* getSPS( int spsId ) { return m_spsMap.getPS( spsId ); } |
206 | 0 | PPS* getPPS( int ppsId ) { return m_ppsMap.getPS( ppsId ); } |
207 | 0 | APS* getAPS( int apsId, int apsType ) { return m_apsMap.getPS( ( apsId << NUM_APS_TYPE_LEN ) + apsType ); } |
208 | | |
209 | | ParameterSetMap<SPS, MAX_NUM_SPS> m_spsMap; |
210 | | ParameterSetMap<PPS, MAX_NUM_PPS> m_ppsMap; |
211 | | ParameterSetMap<APS, ALF_CTB_MAX_NUM_APS * MAX_NUM_APS_TYPE> m_apsMap; |
212 | | ParameterSetMap<VPS, MAX_NUM_VPS> m_vpsMap; |
213 | | |
214 | | APSArray m_alfAPSs; |
215 | | |
216 | | int m_activeSPSId = -1; // -1 for nothing active |
217 | | int m_activeVPSId = -1; // -1 for nothing active |
218 | | }; |
219 | | |
220 | | } |