/src/vvdec/source/Lib/CommonLib/Unit.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 Unit.h |
44 | | * \brief defines unit as a set of blocks and basic unit types (coding, prediction, transform) |
45 | | */ |
46 | | |
47 | | #pragma once |
48 | | |
49 | | #include "CommonDef.h" |
50 | | #include "Common.h" |
51 | | #include "Mv.h" |
52 | | #include "MotionInfo.h" |
53 | | #include "ChromaFormat.h" |
54 | | |
55 | | #include <mutex> |
56 | | |
57 | | namespace vvdec |
58 | | { |
59 | | |
60 | | // --------------------------------------------------------------------------- |
61 | | // tools |
62 | | // --------------------------------------------------------------------------- |
63 | | inline Position recalcPosition(const ChromaFormat _cf, const ComponentID srcCId, const ComponentID dstCId, const Position &pos) |
64 | 0 | { |
65 | 0 | if( toChannelType( srcCId ) == toChannelType( dstCId ) ) |
66 | 0 | { |
67 | 0 | return pos; |
68 | 0 | } |
69 | 0 | else if (isLuma(srcCId) && isChroma(dstCId)) |
70 | 0 | { |
71 | 0 | return Position(pos.x >> getComponentScaleX(dstCId, _cf), pos.y >> getComponentScaleY(dstCId, _cf)); |
72 | 0 | } |
73 | 0 | else |
74 | 0 | { |
75 | 0 | return Position(pos.x << getComponentScaleX(srcCId, _cf), pos.y << getComponentScaleY(srcCId, _cf)); |
76 | 0 | } |
77 | 0 | } |
78 | | |
79 | | inline Position recalcPosition( const ChromaFormat _cf, const ChannelType srcCHt, const ChannelType dstCHt, const Position &pos ) |
80 | 0 | { |
81 | 0 | if( srcCHt == dstCHt ) |
82 | 0 | { |
83 | 0 | return pos; |
84 | 0 | } |
85 | 0 | else if( isLuma( srcCHt ) && isChroma( dstCHt ) ) |
86 | 0 | { |
87 | 0 | return Position( pos.x >> getChannelTypeScaleX( dstCHt, _cf ), pos.y >> getChannelTypeScaleY( dstCHt, _cf ) ); |
88 | 0 | } |
89 | 0 | else |
90 | 0 | { |
91 | 0 | return Position( pos.x << getChannelTypeScaleX( srcCHt, _cf ), pos.y << getChannelTypeScaleY( srcCHt, _cf ) ); |
92 | 0 | } |
93 | 0 | } |
94 | | |
95 | | inline Size recalcSize( const ChromaFormat _cf, const ComponentID srcCId, const ComponentID dstCId, const Size &size ) |
96 | 0 | { |
97 | 0 | if( toChannelType( srcCId ) == toChannelType( dstCId ) ) |
98 | 0 | { |
99 | 0 | return size; |
100 | 0 | } |
101 | 0 | else if( isLuma( srcCId ) && isChroma( dstCId ) ) |
102 | 0 | { |
103 | 0 | return Size( size.width >> getComponentScaleX( dstCId, _cf ), size.height >> getComponentScaleY( dstCId, _cf ) ); |
104 | 0 | } |
105 | 0 | else |
106 | 0 | { |
107 | 0 | return Size( size.width << getComponentScaleX( srcCId, _cf ), size.height << getComponentScaleY( srcCId, _cf ) ); |
108 | 0 | } |
109 | 0 | } |
110 | | |
111 | | inline Size recalcSize( const ChromaFormat _cf, const ChannelType srcCHt, const ChannelType dstCHt, const Size &size ) |
112 | 0 | { |
113 | 0 | if( srcCHt == dstCHt ) |
114 | 0 | { |
115 | 0 | return size; |
116 | 0 | } |
117 | 0 | else if( isLuma( srcCHt ) && isChroma( dstCHt ) ) |
118 | 0 | { |
119 | 0 | return Size( size.width >> getChannelTypeScaleX( dstCHt, _cf ), size.height >> getChannelTypeScaleY( dstCHt, _cf ) ); |
120 | 0 | } |
121 | 0 | else |
122 | 0 | { |
123 | 0 | return Size( size.width << getChannelTypeScaleX( srcCHt, _cf ), size.height << getChannelTypeScaleY( srcCHt, _cf ) ); |
124 | 0 | } |
125 | 0 | } |
126 | | |
127 | | // --------------------------------------------------------------------------- |
128 | | // block definition |
129 | | // --------------------------------------------------------------------------- |
130 | | |
131 | | struct CompArea : public Area |
132 | | { |
133 | 0 | CompArea() : Area() { } |
134 | 0 | CompArea(const ComponentID _compID, const Area &_area) : Area(_area.x, _area.y, _area.width, _area.height, _compID) { } |
135 | 0 | CompArea(const ComponentID _compID, const Position& _pos, const Size& _size) : Area(_pos, Size( _size.width, _size.height, _compID)) { } |
136 | 0 | CompArea(const ComponentID _compID, const uint32_t _x, const uint32_t _y, const uint32_t _w, const uint32_t _h) : Area(_x, _y, _w, _h, _compID) { } |
137 | | |
138 | | Position chromaPos(const ChromaFormat chromaFormat) const; |
139 | | Position lumaPos(const ChromaFormat chromaFormat) const; |
140 | | |
141 | | Size chromaSize(const ChromaFormat chromaFormat) const; |
142 | | Size lumaSize(const ChromaFormat chromaFormat) const; |
143 | | |
144 | | Position compPos(const ChromaFormat chromaFormat, const ComponentID compID) const; |
145 | | Position chanPos(const ChromaFormat chromaFormat, const ChannelType chType) const; |
146 | | |
147 | 0 | Position topLeftComp (const ChromaFormat chromaFormat, const ComponentID _compID) const { return recalcPosition(chromaFormat, compID(), _compID, *this); } |
148 | 0 | Position topRightComp (const ChromaFormat chromaFormat, const ComponentID _compID) const { return recalcPosition(chromaFormat, compID(), _compID, { (PosType) (x + width - 1), y }); } |
149 | 0 | Position bottomLeftComp (const ChromaFormat chromaFormat, const ComponentID _compID) const { return recalcPosition(chromaFormat, compID(), _compID, { x , (PosType) (y + height - 1 )}); } |
150 | 0 | Position bottomRightComp(const ChromaFormat chromaFormat, const ComponentID _compID) const { return recalcPosition(chromaFormat, compID(), _compID, { (PosType) (x + width - 1), (PosType) (y + height - 1 )}); } |
151 | | |
152 | 0 | bool valid() const { return compID() < MAX_NUM_TBLOCKS && width != 0 && height != 0; } |
153 | | |
154 | | bool operator==(const CompArea &other) const |
155 | 0 | { |
156 | 0 | if (compID() != other.compID()) return false; |
157 | 0 |
|
158 | 0 | return Position::operator==(other) && Size::operator==(other); |
159 | 0 | } |
160 | | |
161 | 0 | bool operator!=(const CompArea &other) const { return !(operator==(other)); } |
162 | | |
163 | 0 | void repositionTo (const Position& newPos) { Position::repositionTo(newPos); } |
164 | 0 | void positionRelativeTo(const CompArea& origCompArea) { Position::relativeTo(origCompArea); } |
165 | | }; |
166 | | |
167 | | inline CompArea clipArea(const CompArea &compArea, const Area &boundingBox) |
168 | 0 | { |
169 | 0 | return CompArea(compArea.compID(), clipArea((const Area&) compArea, boundingBox)); |
170 | 0 | } |
171 | | |
172 | | // --------------------------------------------------------------------------- |
173 | | // unit definition |
174 | | // --------------------------------------------------------------------------- |
175 | | |
176 | | typedef static_vector<CompArea, MAX_NUM_TBLOCKS> UnitBlocksType; |
177 | | |
178 | | struct UnitArea |
179 | | { |
180 | | ChromaFormat chromaFormat; |
181 | | UnitBlocksType blocks; |
182 | | |
183 | 0 | UnitArea() : chromaFormat(NUM_CHROMA_FORMAT) { } |
184 | | UnitArea(const ChromaFormat _chromaFormat); |
185 | | UnitArea(const ChromaFormat _chromaFormat, const Area &area); |
186 | | UnitArea(const ChromaFormat _chromaFormat, const CompArea &blkY); |
187 | | UnitArea(const ChromaFormat _chromaFormat, CompArea &&blkY); |
188 | | UnitArea(const ChromaFormat _chromaFormat, const CompArea &blkY, const CompArea &blkCb, const CompArea &blkCr); |
189 | | UnitArea(const ChromaFormat _chromaFormat, CompArea &&blkY, CompArea &&blkCb, CompArea &&blkCr); |
190 | | |
191 | 0 | CompArea& Y() { return blocks[COMPONENT_Y]; } |
192 | 0 | const CompArea& Y() const { return blocks[COMPONENT_Y]; } |
193 | 0 | CompArea& Cb() { return blocks[COMPONENT_Cb]; } |
194 | 0 | const CompArea& Cb() const { return blocks[COMPONENT_Cb]; } |
195 | 0 | CompArea& Cr() { return blocks[COMPONENT_Cr]; } |
196 | 0 | const CompArea& Cr() const { return blocks[COMPONENT_Cr]; } |
197 | | |
198 | 0 | CompArea& block(const ComponentID comp) { return blocks[comp]; } |
199 | 0 | const CompArea& block(const ComponentID comp) const { return blocks[comp]; } |
200 | | |
201 | | bool contains(const UnitArea& other) const; |
202 | | bool contains(const UnitArea& other, const ChannelType chType) const; |
203 | | |
204 | 0 | CompArea& operator[]( const int n ) { return blocks[n]; } |
205 | 0 | const CompArea& operator[]( const int n ) const { return blocks[n]; } |
206 | | |
207 | | bool operator==(const UnitArea &other) const |
208 | 0 | { |
209 | 0 | if (chromaFormat != other.chromaFormat) return false; |
210 | 0 | if (blocks.size() != other.blocks.size()) return false; |
211 | 0 |
|
212 | 0 | for (uint32_t i = 0; i < blocks.size(); i++) |
213 | 0 | { |
214 | 0 | if (blocks[i] != other.blocks[i]) return false; |
215 | 0 | } |
216 | 0 |
|
217 | 0 | return true; |
218 | 0 | } |
219 | | |
220 | | void repositionTo(const UnitArea& unit); |
221 | | |
222 | 0 | bool operator!=(const UnitArea &other) const { return !(*this == other); } |
223 | | |
224 | 0 | const Position& lumaPos () const { return Y(); } |
225 | 0 | const Size& lumaSize() const { return Y(); } |
226 | 0 | const Area& lumaArea() const { return Y(); } |
227 | | |
228 | 0 | const Position& chromaPos () const { return Cb(); } |
229 | 0 | const Size& chromaSize() const { return Cb(); } |
230 | 0 | const Area& chromaArea() const { return Cb(); } |
231 | | |
232 | | const UnitArea singleComp(const ComponentID compID) const; |
233 | | const UnitArea singleChan(const ChannelType chType) const; |
234 | | |
235 | 0 | SizeType lwidth() const { return Y().width; } /*! luma width */ |
236 | 0 | SizeType lheight() const { return Y().height; } /*! luma height */ |
237 | | |
238 | 0 | PosType lx() const { return Y().x; } /*! luma x-pos */ |
239 | 0 | PosType ly() const { return Y().y; } /*! luma y-pos */ |
240 | | |
241 | 0 | bool valid() const { return chromaFormat != NUM_CHROMA_FORMAT && blocks.size() > 0; } |
242 | | }; |
243 | | |
244 | | inline UnitArea clipArea(const UnitArea &area, const UnitArea &boundingBox) |
245 | 0 | { |
246 | 0 | UnitArea ret(area.chromaFormat); |
247 | |
|
248 | 0 | for (uint32_t i = 0; i < area.blocks.size(); i++) |
249 | 0 | { |
250 | 0 | ret.blocks.push_back(clipArea(area.blocks[i], boundingBox.blocks[i])); |
251 | 0 | } |
252 | |
|
253 | 0 | return ret; |
254 | 0 | } |
255 | | |
256 | | struct UnitAreaRelative : public UnitArea |
257 | | { |
258 | | UnitAreaRelative(const UnitArea& origUnit, const UnitArea& unit) |
259 | 0 | { |
260 | 0 | *((UnitArea*)this) = unit; |
261 | 0 | for(uint32_t i = 0; i < blocks.size(); i++) |
262 | 0 | { |
263 | 0 | blocks[i].positionRelativeTo(origUnit.blocks[i]); |
264 | 0 | } |
265 | 0 | } |
266 | | }; |
267 | | |
268 | | class SPS; |
269 | | class VPS; |
270 | | class PPS; |
271 | | class Slice; |
272 | | struct CodingUnit; |
273 | | |
274 | | } |
275 | | |
276 | | #include "Buffer.h" |
277 | | |
278 | | namespace vvdec |
279 | | { |
280 | | |
281 | | // --------------------------------------------------------------------------- |
282 | | // transform unit |
283 | | // --------------------------------------------------------------------------- |
284 | | |
285 | | struct TransformUnit : public UnitArea |
286 | | { |
287 | | CodingUnit *cu; |
288 | | TransformUnit *next; |
289 | | unsigned idx; |
290 | | |
291 | | uint8_t maxScanPosX [MAX_NUM_TBLOCKS]; |
292 | | uint8_t maxScanPosY [MAX_NUM_TBLOCKS]; |
293 | | int8_t chromaQp [2]; |
294 | | |
295 | | uint8_t _chType : 2; |
296 | | uint8_t jointCbCr : 2; |
297 | | uint8_t cbf : 3; |
298 | | uint8_t _mtsIdxL : 3; |
299 | | uint8_t _mtsIdxU : 1; |
300 | | uint8_t _mtsIdxV : 1; |
301 | | |
302 | 0 | ChannelType chType() const { return ChannelType( _chType ); } |
303 | 0 | void setChType( ChannelType ch ) { _chType = ch; } |
304 | 0 | uint8_t mtsIdx ( int c ) const { return !c ? _mtsIdxL : c == 1 ? _mtsIdxU : _mtsIdxV; } |
305 | 0 | void setMtsIdx( int c, uint8_t v ) { if ( !c ) _mtsIdxL = v; else if( c == 1 ) _mtsIdxU = v; else _mtsIdxV = v; } |
306 | | }; |
307 | | |
308 | | // --------------------------------------------------------------------------- |
309 | | // coding unit |
310 | | // --------------------------------------------------------------------------- |
311 | | |
312 | | class CodingStructure; |
313 | | |
314 | | struct CodingUnit : public UnitArea |
315 | | { |
316 | | TransformUnit firstTU; |
317 | | TransformUnit *lastTU; |
318 | | |
319 | | struct CtuData *ctuData; |
320 | | CodingStructure *cs; |
321 | | const Slice *slice; |
322 | | const PPS *pps; |
323 | | const SPS *sps; |
324 | | CodingUnit *next; |
325 | | const CodingUnit *above; |
326 | | const CodingUnit *left; |
327 | | ptrdiff_t mvdL0SubPuOff; // 7 ptr (8 byte) |
328 | | ptrdiff_t predBufOff; |
329 | | uint32_t idx; |
330 | | uint32_t tileIdx; |
331 | | |
332 | | Mv mv [NUM_REF_PIC_LIST_01][3]; |
333 | | |
334 | | uint8_t mvpIdx [NUM_REF_PIC_LIST_01]; |
335 | | int8_t refIdx [NUM_REF_PIC_LIST_01]; |
336 | | int8_t intraDir [MAX_NUM_CHANNEL_TYPE]; |
337 | | |
338 | | SplitSeries splitSeries; |
339 | | |
340 | | uint8_t geoSplitDir; |
341 | | uint8_t mmvdIdx; |
342 | | |
343 | | int8_t chromaQpAdj; |
344 | | int8_t qp; |
345 | | uint8_t _interDir : 2; |
346 | | uint8_t _imv : 2; |
347 | | uint8_t _bcw : 3; |
348 | | uint8_t _mergeType : 2; |
349 | | bool _dmvrCond; // avoid data races in a separate bit |
350 | | |
351 | | uint8_t _sbtInfo; |
352 | | uint8_t qtDepth : 3; |
353 | | uint8_t depth : 4; |
354 | | uint8_t _chType : 1; |
355 | | |
356 | | bool _rootCbf : 1; |
357 | | bool _skip : 1; |
358 | | bool _colorTransform : 1; |
359 | | bool _mipTranspose : 1; |
360 | | uint8_t _treeType : 2; |
361 | | uint8_t _modeType : 2; |
362 | | |
363 | | uint8_t _predMode : 2; |
364 | | uint8_t _bdpcmL : 2; |
365 | | uint8_t _bdpcmC : 2; |
366 | | uint8_t _lfnstIdx : 2; |
367 | | |
368 | | uint8_t _ispIdx : 2; |
369 | | bool _ciipFlag : 1; |
370 | | bool _mergeFlag : 1; |
371 | | bool _mmvdFlag : 1; |
372 | | bool _affineFlag : 1; |
373 | | bool _geoFlag : 1; |
374 | | |
375 | | uint8_t _mrgIdx : 3; |
376 | | uint8_t _geoMrgIdx0 : 3; |
377 | | |
378 | | uint8_t _geoMrgIdx1 : 3; |
379 | | uint8_t _affineType : 2; |
380 | | bool _mipFlag : 1; |
381 | | |
382 | | uint8_t _multiRefIdx : 2; |
383 | | bool planeCbfY : 1; |
384 | | bool planeCbfU : 1; |
385 | | bool planeCbfV : 1; |
386 | | |
387 | | uint8_t _smvd : 2; |
388 | | |
389 | | uint8_t _geoDir0, _geoDir1; |
390 | | |
391 | 0 | uint8_t sbtInfo() const { return _sbtInfo; } |
392 | 0 | ChannelType chType() const { return ChannelType( _chType ); } |
393 | 0 | bool rootCbf() const { return _rootCbf; } |
394 | 0 | bool skip() const { return _skip; } |
395 | 0 | bool colorTransform() const { return _colorTransform; } |
396 | 0 | TreeType treeType() const { return TreeType( _treeType ); } |
397 | 0 | ModeType modeType() const { return ModeType( _modeType ); } |
398 | 0 | PredMode predMode() const { return PredMode( _predMode ); } |
399 | 0 | uint8_t ispMode() const { return _ispIdx; } |
400 | 0 | uint8_t bdpcmMode() const { return _bdpcmL; } |
401 | 0 | uint8_t bdpcmModeChroma() const { return _bdpcmC; } |
402 | 0 | uint8_t lfnstIdx() const { return _lfnstIdx; } |
403 | 0 | bool planeCbf( int c ) const { return !c ? planeCbfY : c == 1 ? planeCbfU : planeCbfV; } |
404 | | |
405 | 0 | void setChType( ChannelType ch ) { _chType = ch ; } |
406 | 0 | void setRootCbf( bool b ) { _rootCbf = b ; } |
407 | 0 | void setSkip( bool b ) { _skip = b ; } |
408 | 0 | void setColorTransform( bool b ) { _colorTransform = b ; } |
409 | 0 | void setTreeType( TreeType n ) { _treeType = n ; } |
410 | 0 | void setModeType( ModeType n ) { _modeType = n ; } |
411 | 0 | void setPredMode( PredMode n ) { _predMode = n ; } |
412 | 0 | void setIspMode( uint8_t n ) { _ispIdx = n ; } |
413 | 0 | void setBdpcmMode( uint8_t n ) { _bdpcmL = n ; } |
414 | 0 | void setBdpcmModeChroma( uint8_t n ) { _bdpcmC = n ; } |
415 | 0 | void setLfnstIdx( uint8_t n ) { _lfnstIdx = n ; } |
416 | 0 | void setSbtInfo( uint8_t n ) { _sbtInfo = n ; } |
417 | 0 | void setPlaneCbf( int c, bool b ) { if( !c ) planeCbfY = b; else if( c == 1 ) planeCbfU = b; else planeCbfV = b; } |
418 | | |
419 | | // Prediction Unit Part |
420 | | |
421 | 0 | bool dmvrCondition() const { return _dmvrCond; } |
422 | 0 | bool mipTransposedFlag() const { return _mipTranspose; } |
423 | 0 | bool ciipFlag() const { return _ciipFlag; } |
424 | 0 | bool mergeFlag() const { return _mergeFlag; } |
425 | 0 | bool mmvdFlag() const { return _mmvdFlag; } |
426 | 0 | bool affineFlag() const { return _affineFlag; } |
427 | 0 | MergeType mergeType() const { return MergeType( _mergeType ); } |
428 | 0 | AffineModel affineType() const { return AffineModel( _affineType ); } |
429 | 0 | bool geoFlag() const { return _geoFlag; } |
430 | 0 | uint8_t mergeIdx() const { return _mrgIdx; } |
431 | 0 | uint8_t geoMergeIdx0() const { return _geoMrgIdx0; } |
432 | 0 | uint8_t geoMergeIdx1() const { return _geoMrgIdx1; } |
433 | 0 | uint8_t interDir() const { return _interDir; } |
434 | 0 | uint8_t multiRefIdx() const { return _multiRefIdx; } |
435 | 0 | bool mipFlag() const { return _mipFlag; } |
436 | 0 | uint8_t imv() const { return _imv; } |
437 | 0 | uint8_t smvdMode() const { return _smvd; } |
438 | 0 | uint8_t BcwIdx() const { return _bcw; } |
439 | | |
440 | 0 | uint8_t interDirrefIdxGeo0() const { return _geoDir0; } |
441 | 0 | uint8_t interDirrefIdxGeo1() const { return _geoDir1; } |
442 | | |
443 | 0 | void setDmvrCondition( bool b ) { _dmvrCond = b ; } |
444 | 0 | void setMipTransposedFlag( bool b ) { _mipTranspose = b ; } |
445 | 0 | void setCiipFlag( bool b ) { _ciipFlag = b ; } |
446 | 0 | void setMergeFlag( bool b ) { _mergeFlag = b ; } |
447 | 0 | void setMmvdFlag( bool b ) { _mmvdFlag = b ; } |
448 | 0 | void setAffineFlag( bool b ) { _affineFlag = b ; } |
449 | 0 | void setMergeType( MergeType mt ) { _mergeType = mt; } |
450 | 0 | void setAffineType( AffineModel at ) { _affineType = at; CHECKD( at >= AFFINE_MODEL_NUM, "Needs to be '0' or '1'!" ); } |
451 | 0 | void setGeoFlag( bool b ) { _geoFlag = b ; } |
452 | 0 | void setMergeIdx( uint8_t id ) { _mrgIdx = id; CHECKD( id >= 8, "Merge index needs to be smaller than '8'!"); } |
453 | 0 | void setGeoMergeIdx0( uint8_t id ) { _geoMrgIdx0 = id; CHECKD( id >= 8, "Merge index needs to be smaller than '8'!"); } |
454 | 0 | void setGeoMergeIdx1( uint8_t id ) { _geoMrgIdx1 = id; CHECKD( id >= 8, "Merge index needs to be smaller than '8'!"); } |
455 | 0 | void setInterDir( uint8_t id ) { _interDir = id; CHECKD( id >= 4, "Inter dir needs to be smaller than '4'!"); } |
456 | 0 | void setMultiRefIdx( uint8_t id ) { _multiRefIdx = id; CHECKD( id >= 3, "Multi-ref. index needs to be smaller than '3'!"); } |
457 | 0 | void setMipFlag( bool b ) { _mipFlag = b ; } |
458 | 0 | void setImv( uint8_t id ) { _imv = id; CHECKD( id >= 4, "IMV needs to be smaller than '4'!"); } |
459 | 0 | void setSmvdMode( uint8_t id ) { _smvd = id; CHECKD( id >= 4, "SMVD mode needs to be smaller than '4'!"); } |
460 | 0 | void setBcwIdx( uint8_t id ) { _bcw = id; CHECKD( id >= 5, "BCW idx needs to be smaller than '5'!"); } |
461 | | |
462 | 0 | void setInterDirrefIdxGeo0( uint8_t id ) { _geoDir0 = id; } |
463 | 0 | void setInterDirrefIdxGeo1( uint8_t id ) { _geoDir1 = id; } |
464 | | |
465 | | CodingUnit& operator=(const MotionInfo& mi); |
466 | | |
467 | | // for accessing motion information, which can have higher resolution than PUs (should always be used, when accessing neighboring motion information) |
468 | | const MotionInfo& getMotionInfo() const; |
469 | | const MotionInfo& getMotionInfo( const Position& pos ) const; |
470 | | MotionBuf getMotionBuf(); |
471 | | CMotionBuf getMotionBuf() const; |
472 | | |
473 | | void minInit( const UnitArea& unit ); |
474 | | }; |
475 | | |
476 | | // --------------------------------------------------------------------------- |
477 | | // Utility class for easy for-each like unit traversing |
478 | | // --------------------------------------------------------------------------- |
479 | | |
480 | | } |
481 | | |
482 | | #include <iterator> |
483 | | |
484 | | namespace vvdec { |
485 | | |
486 | | template<typename T> |
487 | | class UnitIterator |
488 | | { |
489 | | private: |
490 | | T* m_punit = nullptr; |
491 | | |
492 | | public: |
493 | 0 | explicit UnitIterator( T* _punit ) : m_punit( _punit ) {}Unexecuted instantiation: vvdec::UnitIterator<vvdec::CodingUnit>::UnitIterator(vvdec::CodingUnit*) Unexecuted instantiation: vvdec::UnitIterator<vvdec::TransformUnit const>::UnitIterator(vvdec::TransformUnit const*) Unexecuted instantiation: vvdec::UnitIterator<vvdec::TransformUnit>::UnitIterator(vvdec::TransformUnit*) |
494 | | |
495 | | using iterator_category = std::forward_iterator_tag; |
496 | | using value_type = T; |
497 | | using pointer = T*; |
498 | | using const_pointer = T const*; |
499 | | using reference = T&; |
500 | | using const_reference = T const&; |
501 | | using difference_type = ptrdiff_t; |
502 | | |
503 | 0 | reference operator*() { return *m_punit; }Unexecuted instantiation: vvdec::UnitIterator<vvdec::CodingUnit>::operator*() Unexecuted instantiation: vvdec::UnitIterator<vvdec::TransformUnit const>::operator*() Unexecuted instantiation: vvdec::UnitIterator<vvdec::TransformUnit>::operator*() |
504 | | const_reference operator*() const { return *m_punit; } |
505 | | pointer operator->() { return m_punit; } |
506 | | const_pointer operator->() const { return m_punit; } |
507 | | |
508 | 0 | UnitIterator<T>& operator++() { m_punit = m_punit->next; return *this; }Unexecuted instantiation: vvdec::UnitIterator<vvdec::CodingUnit>::operator++() Unexecuted instantiation: vvdec::UnitIterator<vvdec::TransformUnit const>::operator++() Unexecuted instantiation: vvdec::UnitIterator<vvdec::TransformUnit>::operator++() |
509 | | UnitIterator<T> operator++( int ) { auto x = *this; ++( *this ); return x; } |
510 | 0 | bool operator!=( const UnitIterator<T>& other ) const { return m_punit != other.m_punit; }Unexecuted instantiation: vvdec::UnitIterator<vvdec::CodingUnit>::operator!=(vvdec::UnitIterator<vvdec::CodingUnit> const&) const Unexecuted instantiation: vvdec::UnitIterator<vvdec::TransformUnit const>::operator!=(vvdec::UnitIterator<vvdec::TransformUnit const> const&) const Unexecuted instantiation: vvdec::UnitIterator<vvdec::TransformUnit>::operator!=(vvdec::UnitIterator<vvdec::TransformUnit> const&) const |
511 | | bool operator==( const UnitIterator<T>& other ) const { return m_punit == other.m_punit; } |
512 | | }; |
513 | | |
514 | | template<typename T> |
515 | | class UnitTraverser |
516 | | { |
517 | | private: |
518 | | T* m_begin; |
519 | | T* m_end; |
520 | | |
521 | | public: |
522 | | UnitTraverser( ) : m_begin( nullptr ), m_end( nullptr ) { } |
523 | 0 | UnitTraverser( T* _begin, T* _end ) : m_begin( _begin ), m_end( _end ) { }Unexecuted instantiation: vvdec::UnitTraverser<vvdec::TransformUnit const>::UnitTraverser(vvdec::TransformUnit const*, vvdec::TransformUnit const*) Unexecuted instantiation: vvdec::UnitTraverser<vvdec::CodingUnit>::UnitTraverser(vvdec::CodingUnit*, vvdec::CodingUnit*) Unexecuted instantiation: vvdec::UnitTraverser<vvdec::TransformUnit>::UnitTraverser(vvdec::TransformUnit*, vvdec::TransformUnit*) |
524 | | |
525 | | typedef T value_type; |
526 | | typedef size_t size_type; |
527 | | typedef T& reference; |
528 | | typedef T const& const_reference; |
529 | | typedef T* pointer; |
530 | | typedef T const* const_pointer; |
531 | | typedef UnitIterator<T> iterator; |
532 | | typedef UnitIterator<const T> const_iterator; |
533 | | |
534 | 0 | iterator begin() { return UnitIterator<T>( m_begin ); }Unexecuted instantiation: vvdec::UnitTraverser<vvdec::CodingUnit>::begin() Unexecuted instantiation: vvdec::UnitTraverser<vvdec::TransformUnit const>::begin() Unexecuted instantiation: vvdec::UnitTraverser<vvdec::TransformUnit>::begin() |
535 | | const_iterator begin() const { return UnitIterator<T>( m_begin ); } |
536 | | const_iterator cbegin() const { return UnitIterator<T>( m_begin ); } |
537 | 0 | iterator end() { return UnitIterator<T>( m_end ); }Unexecuted instantiation: vvdec::UnitTraverser<vvdec::CodingUnit>::end() Unexecuted instantiation: vvdec::UnitTraverser<vvdec::TransformUnit const>::end() Unexecuted instantiation: vvdec::UnitTraverser<vvdec::TransformUnit>::end() |
538 | | const_iterator end() const { return UnitIterator<T>( m_end ); } |
539 | | const_iterator cend() const { return UnitIterator<T>( m_end ); } |
540 | | }; |
541 | | |
542 | | typedef UnitTraverser<CodingUnit> CUTraverser; |
543 | | typedef UnitTraverser<const CodingUnit> cCUTraverser; |
544 | | |
545 | | typedef UnitTraverser< TransformUnit> TUTraverser; |
546 | | typedef UnitTraverser<const TransformUnit> cTUTraverser; |
547 | | |
548 | | } |
549 | | |
550 | | #include <memory> |
551 | | #include <mutex> |
552 | | |
553 | | namespace vvdec { |
554 | | |
555 | | // --------------------------------------------------------------------------- |
556 | | // dynamic cache |
557 | | // --------------------------------------------------------------------------- |
558 | | |
559 | | static constexpr size_t DYN_CACHE_CHUNK_SIZE = 1024; |
560 | | |
561 | | template<typename T> |
562 | | class thread_safe_chunk_cache |
563 | | { |
564 | | std::vector<T*> m_cacheChunks; |
565 | | std::mutex m_mutex; |
566 | | |
567 | | public: |
568 | | |
569 | | ~thread_safe_chunk_cache() |
570 | 0 | { |
571 | 0 | clear_chunks(); |
572 | 0 | } Unexecuted instantiation: vvdec::thread_safe_chunk_cache<vvdec::CodingUnit>::~thread_safe_chunk_cache() Unexecuted instantiation: vvdec::thread_safe_chunk_cache<vvdec::TransformUnit>::~thread_safe_chunk_cache() |
573 | | |
574 | | void clear_chunks() |
575 | 0 | { |
576 | 0 | for( auto& chunk : m_cacheChunks ) |
577 | 0 | { |
578 | 0 | free( chunk ); |
579 | 0 | } |
580 | |
|
581 | 0 | m_cacheChunks.clear(); |
582 | 0 | } Unexecuted instantiation: vvdec::thread_safe_chunk_cache<vvdec::CodingUnit>::clear_chunks() Unexecuted instantiation: vvdec::thread_safe_chunk_cache<vvdec::TransformUnit>::clear_chunks() |
583 | | |
584 | | T* get() |
585 | 0 | { |
586 | 0 | std::unique_lock<std::mutex> l( m_mutex ); |
587 | |
|
588 | 0 | if( m_cacheChunks.empty() ) |
589 | 0 | { |
590 | 0 | l.unlock(); |
591 | 0 | return ( T* ) malloc( DYN_CACHE_CHUNK_SIZE * sizeof( T ) ); |
592 | 0 | } |
593 | 0 | else |
594 | 0 | { |
595 | 0 | T* chunk = m_cacheChunks.back(); |
596 | 0 | m_cacheChunks.pop_back(); |
597 | 0 | return chunk; |
598 | 0 | } |
599 | 0 | } Unexecuted instantiation: vvdec::thread_safe_chunk_cache<vvdec::CodingUnit>::get() Unexecuted instantiation: vvdec::thread_safe_chunk_cache<vvdec::TransformUnit>::get() |
600 | | |
601 | | void cache( std::vector<T*>& chunks ) |
602 | 0 | { |
603 | 0 | std::unique_lock<std::mutex> l( m_mutex ); |
604 | |
|
605 | 0 | m_cacheChunks.insert( m_cacheChunks.end(), chunks.begin(), chunks.end() ); |
606 | 0 | chunks.clear(); |
607 | 0 | } Unexecuted instantiation: vvdec::thread_safe_chunk_cache<vvdec::TransformUnit>::cache(std::__1::vector<vvdec::TransformUnit*, std::__1::allocator<vvdec::TransformUnit*> >&) Unexecuted instantiation: vvdec::thread_safe_chunk_cache<vvdec::CodingUnit>::cache(std::__1::vector<vvdec::CodingUnit*, std::__1::allocator<vvdec::CodingUnit*> >&) |
608 | | }; |
609 | | |
610 | | template<typename T> |
611 | | class dynamic_cache |
612 | | { |
613 | | ptrdiff_t m_lastIdx; |
614 | | std::vector<T*> m_cache; |
615 | | |
616 | | thread_safe_chunk_cache<T> *m_chunkCache; |
617 | | |
618 | | void clear_chunks() |
619 | 0 | { |
620 | 0 | m_chunkCache->cache( m_cache ); |
621 | 0 | } Unexecuted instantiation: vvdec::dynamic_cache<vvdec::TransformUnit>::clear_chunks() Unexecuted instantiation: vvdec::dynamic_cache<vvdec::CodingUnit>::clear_chunks() |
622 | | |
623 | | public: |
624 | | |
625 | 0 | explicit dynamic_cache( thread_safe_chunk_cache<T>* chunkCache ) : m_lastIdx( DYN_CACHE_CHUNK_SIZE ), m_chunkCache( chunkCache ) |
626 | 0 | { |
627 | 0 | } Unexecuted instantiation: vvdec::dynamic_cache<vvdec::CodingUnit>::dynamic_cache(vvdec::thread_safe_chunk_cache<vvdec::CodingUnit>*) Unexecuted instantiation: vvdec::dynamic_cache<vvdec::TransformUnit>::dynamic_cache(vvdec::thread_safe_chunk_cache<vvdec::TransformUnit>*) |
628 | | |
629 | | ~dynamic_cache() |
630 | 0 | { |
631 | 0 | clear_chunks(); |
632 | 0 | } Unexecuted instantiation: vvdec::dynamic_cache<vvdec::TransformUnit>::~dynamic_cache() Unexecuted instantiation: vvdec::dynamic_cache<vvdec::CodingUnit>::~dynamic_cache() |
633 | | |
634 | | T* get() |
635 | 0 | { |
636 | 0 | T* ret; |
637 | |
|
638 | 0 | if( m_lastIdx < DYN_CACHE_CHUNK_SIZE ) |
639 | 0 | { |
640 | 0 | ret = &m_cache.back()[m_lastIdx++]; |
641 | 0 | } |
642 | 0 | else |
643 | 0 | { |
644 | 0 | T* chunk = m_chunkCache->get(); |
645 | |
|
646 | 0 | m_cache.push_back( chunk ); |
647 | |
|
648 | 0 | ret = &chunk[0]; |
649 | 0 | m_lastIdx = 1; |
650 | 0 | } |
651 | |
|
652 | 0 | return ret; |
653 | 0 | } Unexecuted instantiation: vvdec::dynamic_cache<vvdec::CodingUnit>::get() Unexecuted instantiation: vvdec::dynamic_cache<vvdec::TransformUnit>::get() |
654 | | |
655 | | void releaseAll() |
656 | 0 | { |
657 | 0 | clear_chunks(); |
658 | 0 | m_lastIdx = DYN_CACHE_CHUNK_SIZE; |
659 | 0 | } Unexecuted instantiation: vvdec::dynamic_cache<vvdec::CodingUnit>::releaseAll() Unexecuted instantiation: vvdec::dynamic_cache<vvdec::TransformUnit>::releaseAll() |
660 | | }; |
661 | | |
662 | | typedef dynamic_cache<struct CodingUnit> CUCache; |
663 | | typedef dynamic_cache<struct TransformUnit> TUCache; |
664 | | |
665 | | typedef thread_safe_chunk_cache<struct CodingUnit> CUChunkCache; |
666 | | typedef thread_safe_chunk_cache<struct TransformUnit> TUChunkCache; |
667 | | |
668 | | } |
669 | | |