/src/vvdec/source/Lib/CommonLib/CodingStructure.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 | | /** \file CodingStructure.h |
44 | | * \brief A class managing the coding information for a specific image part |
45 | | */ |
46 | | |
47 | | #pragma once |
48 | | |
49 | | #include "Rom.h" |
50 | | #include "Unit.h" |
51 | | #include "Buffer.h" |
52 | | #include "CommonDef.h" |
53 | | #include "UnitPartitioner.h" |
54 | | #include "Slice.h" |
55 | | |
56 | | #include <vector> |
57 | | |
58 | | namespace vvdec |
59 | | { |
60 | | |
61 | | struct Picture; |
62 | | |
63 | | enum PictureType |
64 | | { |
65 | | PIC_RECONSTRUCTION, |
66 | | PIC_RECON_WRAP, |
67 | | NUM_PIC_TYPES |
68 | | }; |
69 | | |
70 | | #define NUM_PARTS_IN_CTU ( MAX_CU_SIZE * MAX_CU_SIZE ) >> ( MIN_CU_LOG2 << 1 ) |
71 | | // num collocated motion |
72 | | #define NUM_COMOT_IN_CTU ( MAX_CU_SIZE * MAX_CU_SIZE ) >> ( ( MIN_CU_LOG2 + 1 ) << 1 ) |
73 | | |
74 | | |
75 | | struct CtuAlfData |
76 | | { |
77 | | uint8_t ccAlfFilterControl[MAX_NUM_COMPONENT - 1]; |
78 | | uint8_t alfCtuEnableFlag [MAX_NUM_COMPONENT]; |
79 | | uint8_t alfCtuAlternative [MAX_NUM_COMPONENT - 1]; |
80 | | short alfCtbFilterIndex; |
81 | | |
82 | 0 | CtuAlfData() : ccAlfFilterControl{ 0, 0 }, alfCtuEnableFlag{ 0, 0, 0 } {} |
83 | | }; |
84 | | |
85 | | struct CtuData |
86 | | { |
87 | | SAOBlkParam saoParam; |
88 | | CtuAlfData alfParam; |
89 | | const Slice* slice; |
90 | | const PPS* pps; |
91 | | const SPS* sps; |
92 | | const PicHeader* ph; |
93 | | int lineIdx, colIdx, ctuIdx; |
94 | | |
95 | | CodingUnit *firstCU, *lastCU; |
96 | | unsigned numCUs, numTUs; |
97 | | |
98 | | ptrdiff_t predBufOffset; |
99 | | ptrdiff_t dmvrMvCacheOffset; |
100 | | |
101 | | CodingUnit** cuPtr [MAX_NUM_CHANNEL_TYPE]; |
102 | | LoopFilterParam* lfParam[NUM_EDGE_DIR]; |
103 | | MotionInfo* motion; |
104 | | ColocatedMotionInfo* colMotion; |
105 | | }; |
106 | | // --------------------------------------------------------------------------- |
107 | | // coding structure |
108 | | // --------------------------------------------------------------------------- |
109 | | |
110 | | class CodingStructure |
111 | | { |
112 | | public: |
113 | | |
114 | | UnitArea area; |
115 | | |
116 | | Picture *picture; |
117 | | |
118 | | UnitScale unitScale[MAX_NUM_COMPONENT]; |
119 | | int chromaQpAdj; |
120 | | std::shared_ptr<const VPS> vps; |
121 | | std::shared_ptr<const SPS> sps; |
122 | | std::shared_ptr<const PPS> pps; |
123 | | std::shared_ptr<PicHeader> picHeader; |
124 | | std::shared_ptr<const APS> alfApss[ALF_CTB_MAX_NUM_APS]; |
125 | | std::shared_ptr<const APS> lmcsAps; |
126 | | const PreCalcValues* pcv; |
127 | | |
128 | | // data for which memory is partially borrowed from DecLibRecon |
129 | | CtuData* m_ctuData; |
130 | | size_t m_ctuDataSize; |
131 | | |
132 | | Pel* m_predBuf; |
133 | | Mv* m_dmvrMvCache; |
134 | | // end of partially borrowed data |
135 | | |
136 | | CodingStructure( CUChunkCache* cuChunkCache, TUChunkCache* tuChunkCache ); |
137 | | |
138 | | void create(const UnitArea &_unit); |
139 | | void create(const ChromaFormat &_chromaFormat, const Area& _area); |
140 | | void destroy(); |
141 | | |
142 | | void resetForUse(); |
143 | | void rebindPicBufs(); |
144 | | |
145 | | // --------------------------------------------------------------------------- |
146 | | // global accessors |
147 | | // --------------------------------------------------------------------------- |
148 | | |
149 | | #if _DEBUG |
150 | | const CodingUnit* getCU(Position pos, ChannelType _chType) const |
151 | 0 | { |
152 | 0 | if( area.blocks[_chType].contains( pos ) ) |
153 | 0 | { |
154 | 0 | int rsAddr = ctuRsAddr( pos, _chType ); |
155 | 0 | int inCtu = inCtuPos ( pos, _chType ); |
156 | 0 | return getCtuData( rsAddr ).cuPtr[_chType][inCtu]; |
157 | 0 | } |
158 | 0 | else return nullptr; |
159 | 0 | } |
160 | | |
161 | | CodingUnit* getCU(Position pos, ChannelType _chType) |
162 | 0 | { |
163 | 0 | if( area.blocks[_chType].contains( pos ) ) |
164 | 0 | { |
165 | 0 | int rsAddr = ctuRsAddr( pos, _chType ); |
166 | 0 | int inCtu = inCtuPos ( pos, _chType ); |
167 | 0 | return getCtuData( rsAddr ).cuPtr[_chType][inCtu]; |
168 | 0 | } |
169 | 0 | else return nullptr; |
170 | 0 | } |
171 | | #else |
172 | | const CodingUnit* getCU(Position pos, ChannelType _chType) const { if( area.blocks[_chType].contains( pos ) ) return getCtuData( ctuRsAddr( pos, _chType ) ).cuPtr[_chType][inCtuPos( pos, _chType )]; else return nullptr; } |
173 | | CodingUnit* getCU(Position pos, ChannelType _chType) { if( area.blocks[_chType].contains( pos ) ) return getCtuData( ctuRsAddr( pos, _chType ) ).cuPtr[_chType][inCtuPos( pos, _chType )]; else return nullptr; } |
174 | | #endif |
175 | | |
176 | | const CodingUnit* getCURestricted(const Position &pos, const Position curPos, const unsigned curSliceIdx, const unsigned curTileIdx, const ChannelType _chType) const; |
177 | | const CodingUnit* getCURestricted(const Position &pos, const CodingUnit& curCu, const ChannelType _chType, const CodingUnit* guess = nullptr) const; |
178 | | |
179 | | CodingUnit& addCU(const UnitArea &unit, const ChannelType _chType, const TreeType treeType, const ModeType modeType, const CodingUnit* cuLeft, const CodingUnit* cuAbove ); |
180 | | TransformUnit& addTU(const UnitArea &unit, const ChannelType _chType, CodingUnit &cu); |
181 | | void addEmptyTUs(Partitioner &partitioner, CodingUnit& cu); |
182 | | CUTraverser traverseCUs(const int ctuRsAddr); |
183 | | |
184 | | void initStructData(); |
185 | | |
186 | | void allocTempInternals(); |
187 | | void deallocTempInternals(); |
188 | | |
189 | | void createInternals(const UnitArea& _unit); |
190 | | |
191 | | CUCache m_cuCache; |
192 | | TUCache m_tuCache; |
193 | | |
194 | | PelStorage m_reco; |
195 | | PelStorage m_rec_wrap; |
196 | | |
197 | | unsigned int m_widthInCtus; |
198 | | PosType m_ctuSizeMask[2]; |
199 | | PosType m_ctuWidthLog2[2]; |
200 | | |
201 | | CodingUnit** m_cuMap; |
202 | | ptrdiff_t m_cuMapSize; |
203 | | ColocatedMotionInfo* m_colMiMap; |
204 | | ptrdiff_t m_colMiMapSize; |
205 | | |
206 | | public: |
207 | | |
208 | | // in CTU coordinates |
209 | 0 | int ctuRsAddr( int col, int line ) const { return col + ( line * m_widthInCtus ); } |
210 | | // in sample coordinates |
211 | 0 | int ctuRsAddr( Position pos, ChannelType chType ) const { Position posL = recalcPosition( area.chromaFormat, chType, CH_L, pos ); return ctuRsAddr( posL.x >> pcv->maxCUWidthLog2, posL.y >> pcv->maxCUHeightLog2 ); } |
212 | | // 4x4 luma block position within the CTU |
213 | 0 | int inCtuPos ( Position pos, ChannelType chType ) const { return ( unitScale[chType].scaleHor( pos.x ) & m_ctuSizeMask[chType] ) + ( ( unitScale[chType].scaleVer( pos.y ) & m_ctuSizeMask[chType] ) << m_ctuWidthLog2[chType] ); } |
214 | | // 8x8 luma block position within the CTU |
215 | 0 | int colMotPos( Position pos ) const { return ( g_colMiScaling.scaleHor( pos.x ) & ( m_ctuSizeMask[CH_L] >> 1 ) ) + ( ( g_colMiScaling.scaleVer( pos.y ) & ( m_ctuSizeMask[CH_L] >> 1 ) ) << ( m_ctuWidthLog2[CH_L] - 1 ) ); } |
216 | | |
217 | 0 | CtuData& getCtuData( int col, int line ) { return m_ctuData[ctuRsAddr( col, line )]; } |
218 | 0 | const CtuData& getCtuData( int col, int line ) const { return m_ctuData[ctuRsAddr( col, line )]; } |
219 | | |
220 | 0 | CtuData& getCtuData( int addr ) { return m_ctuData[addr]; } |
221 | 0 | const CtuData& getCtuData( int addr ) const { return m_ctuData[addr]; } |
222 | | |
223 | | int m_IBCBufferWidth; |
224 | | std::vector<PelStorage> m_virtualIBCbuf; |
225 | | std::vector<char> hasIbcBlock; |
226 | | void initVIbcBuf( int numCtuLines, ChromaFormat chromaFormatIDC, int ctuSize ); |
227 | | void fillIBCbuffer( CodingUnit &cu, int lineIdx ); |
228 | | |
229 | | MotionBuf getMotionBuf( const Area& _area ); |
230 | 0 | MotionBuf getMotionBuf( const UnitArea& _area ) { return getMotionBuf( _area.Y() ); } |
231 | | |
232 | | const CMotionBuf getMotionBuf( const Area& _area ) const; |
233 | 0 | const CMotionBuf getMotionBuf( const UnitArea& _area ) const { return getMotionBuf( _area.Y() ); } |
234 | | |
235 | 0 | MotionInfo& getMotionInfo( const Position& pos ) { return getCtuData( ctuRsAddr( pos, CH_L ) ).motion[inCtuPos( pos, CH_L )]; } |
236 | 0 | const MotionInfo& getMotionInfo( const Position& pos ) const { return getCtuData( ctuRsAddr( pos, CH_L ) ).motion[inCtuPos( pos, CH_L )]; } |
237 | | |
238 | | |
239 | | const ColocatedMotionInfo& getColInfo( const Position &pos, const Slice*& pColSlice ) const; |
240 | | |
241 | 0 | LoopFilterParam const* getLFPMapPtr ( const DeblockEdgeDir edgeDir, ptrdiff_t _ctuRsAddr ) const { return m_ctuData[_ctuRsAddr].lfParam[edgeDir]; } |
242 | 0 | LoopFilterParam * getLFPMapPtr ( const DeblockEdgeDir edgeDir, ptrdiff_t _ctuRsAddr ) { return m_ctuData[_ctuRsAddr].lfParam[edgeDir]; } |
243 | 0 | ptrdiff_t get4x4MapStride() const { return ( ptrdiff_t( 1 ) << m_ctuWidthLog2[CH_L] ); } |
244 | | |
245 | | UnitScale getScaling( const UnitScale::ScaliningType type, const ChannelType chType = CH_L ) const |
246 | 0 | { |
247 | 0 | return type == UnitScale::MI_MAP ? g_miScaling : unitScale[chType]; |
248 | 0 | } |
249 | | |
250 | | public: |
251 | | |
252 | 0 | PelBuf getRecoBuf(const CompArea &blk) { return m_reco.bufs[blk.compID()].subBuf( blk ); } |
253 | 0 | const CPelBuf getRecoBuf(const CompArea &blk) const { return m_reco.bufs[blk.compID()].subBuf( blk ); } |
254 | 0 | PelUnitBuf getRecoBuf(const UnitArea &unit) { return m_reco.subBuf( unit ); } |
255 | 0 | const CPelUnitBuf getRecoBuf(const UnitArea &unit) const { return m_reco.subBuf( unit ); } |
256 | | |
257 | | |
258 | | |
259 | | // reco buffer |
260 | 0 | PelBuf getRecoBuf(const ComponentID compID, bool wrap=false) { return wrap ? m_rec_wrap.get(compID) : m_reco.get(compID); } |
261 | 0 | const CPelBuf getRecoBuf(const ComponentID compID, bool wrap=false) const { return wrap ? m_rec_wrap.get(compID) : m_reco.get(compID); } |
262 | 0 | PelUnitBuf getRecoBuf(bool wrap=false) { return wrap ? m_rec_wrap : m_reco; } |
263 | 0 | const CPelUnitBuf getRecoBuf(bool wrap=false) const { return wrap ? m_rec_wrap : m_reco; } |
264 | | |
265 | | PelUnitBuf getPredBuf(const CodingUnit &cu); |
266 | | const CPelUnitBuf getPredBuf(const CodingUnit &cu) const; |
267 | | }; |
268 | | |
269 | | } |