1 /* -----------------------------------------------------------------------------
2 The copyright in this software is being made available under the 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 For any license concerning other Intellectual Property rights than the software,
8 especially patent licenses, a separate Agreement needs to be closed.
9 For more information please contact:
10
11 Fraunhofer Heinrich Hertz Institute
12 Einsteinufer 37
13 10587 Berlin, Germany
14 www.hhi.fraunhofer.de/vvc
15 vvc@hhi.fraunhofer.de
16
17 Copyright (c) 2018-2021, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V.
18 All rights reserved.
19
20 Redistribution and use in source and binary forms, with or without
21 modification, are permitted provided that the following conditions are met:
22
23 * Redistributions of source code must retain the above copyright notice,
24 this list of conditions and the following disclaimer.
25 * Redistributions in binary form must reproduce the above copyright notice,
26 this list of conditions and the following disclaimer in the documentation
27 and/or other materials provided with the distribution.
28 * Neither the name of Fraunhofer nor the names of its contributors may
29 be used to endorse or promote products derived from this software without
30 specific prior written permission.
31
32 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
33 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
35 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
36 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
37 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
38 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
39 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
40 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
41 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
42 THE POSSIBILITY OF SUCH DAMAGE.
43
44
45 ------------------------------------------------------------------------------------------- */
46
47 /** \file Unit.h
48 * \brief defines unit as a set of blocks and basic unit types (coding, prediction, transform)
49 */
50
51 #pragma once
52
53 #include "CommonDef.h"
54 #include "Common.h"
55 #include "Mv.h"
56 #include "MotionInfo.h"
57 #include "ChromaFormat.h"
58
59 namespace vvdec
60 {
61
62 // ---------------------------------------------------------------------------
63 // tools
64 // ---------------------------------------------------------------------------
recalcPosition(const ChromaFormat _cf,const ComponentID srcCId,const ComponentID dstCId,const Position & pos)65 inline Position recalcPosition(const ChromaFormat _cf, const ComponentID srcCId, const ComponentID dstCId, const Position &pos)
66 {
67 if( toChannelType( srcCId ) == toChannelType( dstCId ) )
68 {
69 return pos;
70 }
71 else if (isLuma(srcCId) && isChroma(dstCId))
72 {
73 return Position(pos.x >> getComponentScaleX(dstCId, _cf), pos.y >> getComponentScaleY(dstCId, _cf));
74 }
75 else
76 {
77 return Position(pos.x << getComponentScaleX(srcCId, _cf), pos.y << getComponentScaleY(srcCId, _cf));
78 }
79 }
80
recalcPosition(const ChromaFormat _cf,const ChannelType srcCHt,const ChannelType dstCHt,const Position & pos)81 inline Position recalcPosition( const ChromaFormat _cf, const ChannelType srcCHt, const ChannelType dstCHt, const Position &pos )
82 {
83 if( srcCHt == dstCHt )
84 {
85 return pos;
86 }
87 else if( isLuma( srcCHt ) && isChroma( dstCHt ) )
88 {
89 return Position( pos.x >> getChannelTypeScaleX( dstCHt, _cf ), pos.y >> getChannelTypeScaleY( dstCHt, _cf ) );
90 }
91 else
92 {
93 return Position( pos.x << getChannelTypeScaleX( srcCHt, _cf ), pos.y << getChannelTypeScaleY( srcCHt, _cf ) );
94 }
95 }
96
recalcSize(const ChromaFormat _cf,const ComponentID srcCId,const ComponentID dstCId,const Size & size)97 inline Size recalcSize( const ChromaFormat _cf, const ComponentID srcCId, const ComponentID dstCId, const Size &size )
98 {
99 if( toChannelType( srcCId ) == toChannelType( dstCId ) )
100 {
101 return size;
102 }
103 else if( isLuma( srcCId ) && isChroma( dstCId ) )
104 {
105 return Size( size.width >> getComponentScaleX( dstCId, _cf ), size.height >> getComponentScaleY( dstCId, _cf ) );
106 }
107 else
108 {
109 return Size( size.width << getComponentScaleX( srcCId, _cf ), size.height << getComponentScaleY( srcCId, _cf ) );
110 }
111 }
112
recalcSize(const ChromaFormat _cf,const ChannelType srcCHt,const ChannelType dstCHt,const Size & size)113 inline Size recalcSize( const ChromaFormat _cf, const ChannelType srcCHt, const ChannelType dstCHt, const Size &size )
114 {
115 if( srcCHt == dstCHt )
116 {
117 return size;
118 }
119 else if( isLuma( srcCHt ) && isChroma( dstCHt ) )
120 {
121 return Size( size.width >> getChannelTypeScaleX( dstCHt, _cf ), size.height >> getChannelTypeScaleY( dstCHt, _cf ) );
122 }
123 else
124 {
125 return Size( size.width << getChannelTypeScaleX( srcCHt, _cf ), size.height << getChannelTypeScaleY( srcCHt, _cf ) );
126 }
127 }
128
129 // ---------------------------------------------------------------------------
130 // block definition
131 // ---------------------------------------------------------------------------
132
133 struct CompArea : public Area
134 {
CompAreaCompArea135 CompArea() : Area() { }
CompAreaCompArea136 CompArea(const ComponentID _compID, const Area &_area) : Area(_area.x, _area.y, _area.width, _area.height, _compID) { }
CompAreaCompArea137 CompArea(const ComponentID _compID, const Position& _pos, const Size& _size) : Area(_pos, Size( _size.width, _size.height, _compID)) { }
CompAreaCompArea138 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) { }
139
140 Position chromaPos(const ChromaFormat chromaFormat) const;
141 Position lumaPos(const ChromaFormat chromaFormat) const;
142
143 Size chromaSize(const ChromaFormat chromaFormat) const;
144 Size lumaSize(const ChromaFormat chromaFormat) const;
145
146 Position compPos(const ChromaFormat chromaFormat, const ComponentID compID) const;
147 Position chanPos(const ChromaFormat chromaFormat, const ChannelType chType) const;
148
topLeftCompCompArea149 Position topLeftComp (const ChromaFormat chromaFormat, const ComponentID _compID) const { return recalcPosition(chromaFormat, compID(), _compID, *this); }
topRightCompCompArea150 Position topRightComp (const ChromaFormat chromaFormat, const ComponentID _compID) const { return recalcPosition(chromaFormat, compID(), _compID, { (PosType) (x + width - 1), y }); }
bottomLeftCompCompArea151 Position bottomLeftComp (const ChromaFormat chromaFormat, const ComponentID _compID) const { return recalcPosition(chromaFormat, compID(), _compID, { x , (PosType) (y + height - 1 )}); }
bottomRightCompCompArea152 Position bottomRightComp(const ChromaFormat chromaFormat, const ComponentID _compID) const { return recalcPosition(chromaFormat, compID(), _compID, { (PosType) (x + width - 1), (PosType) (y + height - 1 )}); }
153
validCompArea154 bool valid() const { return compID() < MAX_NUM_TBLOCKS && width != 0 && height != 0; }
155
156 bool operator==(const CompArea &other) const
157 {
158 if (compID() != other.compID()) return false;
159
160 return Position::operator==(other) && Size::operator==(other);
161 }
162
163 bool operator!=(const CompArea &other) const { return !(operator==(other)); }
164
repositionToCompArea165 void repositionTo (const Position& newPos) { Position::repositionTo(newPos); }
positionRelativeToCompArea166 void positionRelativeTo(const CompArea& origCompArea) { Position::relativeTo(origCompArea); }
167 };
168
clipArea(const CompArea & compArea,const Area & boundingBox)169 inline CompArea clipArea(const CompArea &compArea, const Area &boundingBox)
170 {
171 return CompArea(compArea.compID(), clipArea((const Area&) compArea, boundingBox));
172 }
173
174 // ---------------------------------------------------------------------------
175 // unit definition
176 // ---------------------------------------------------------------------------
177
178 typedef static_vector<CompArea, MAX_NUM_TBLOCKS> UnitBlocksType;
179
180 struct UnitArea
181 {
182 ChromaFormat chromaFormat;
183 UnitBlocksType blocks;
184
UnitAreaUnitArea185 UnitArea() : chromaFormat(NUM_CHROMA_FORMAT) { }
186 UnitArea(const ChromaFormat _chromaFormat);
187 UnitArea(const ChromaFormat _chromaFormat, const Area &area);
188 UnitArea(const ChromaFormat _chromaFormat, const CompArea &blkY);
189 UnitArea(const ChromaFormat _chromaFormat, CompArea &&blkY);
190 UnitArea(const ChromaFormat _chromaFormat, const CompArea &blkY, const CompArea &blkCb, const CompArea &blkCr);
191 UnitArea(const ChromaFormat _chromaFormat, CompArea &&blkY, CompArea &&blkCb, CompArea &&blkCr);
192
YUnitArea193 CompArea& Y() { return blocks[COMPONENT_Y]; }
YUnitArea194 const CompArea& Y() const { return blocks[COMPONENT_Y]; }
CbUnitArea195 CompArea& Cb() { return blocks[COMPONENT_Cb]; }
CbUnitArea196 const CompArea& Cb() const { return blocks[COMPONENT_Cb]; }
CrUnitArea197 CompArea& Cr() { return blocks[COMPONENT_Cr]; }
CrUnitArea198 const CompArea& Cr() const { return blocks[COMPONENT_Cr]; }
199
blockUnitArea200 CompArea& block(const ComponentID comp) { return blocks[comp]; }
blockUnitArea201 const CompArea& block(const ComponentID comp) const { return blocks[comp]; }
202
203 bool contains(const UnitArea& other) const;
204 bool contains(const UnitArea& other, const ChannelType chType) const;
205
206 CompArea& operator[]( const int n ) { return blocks[n]; }
207 const CompArea& operator[]( const int n ) const { return blocks[n]; }
208
209 bool operator==(const UnitArea &other) const
210 {
211 if (chromaFormat != other.chromaFormat) return false;
212 if (blocks.size() != other.blocks.size()) return false;
213
214 for (uint32_t i = 0; i < blocks.size(); i++)
215 {
216 if (blocks[i] != other.blocks[i]) return false;
217 }
218
219 return true;
220 }
221
222 void repositionTo(const UnitArea& unit);
223
224 bool operator!=(const UnitArea &other) const { return !(*this == other); }
225
lumaPosUnitArea226 const Position& lumaPos () const { return Y(); }
lumaSizeUnitArea227 const Size& lumaSize() const { return Y(); }
lumaAreaUnitArea228 const Area& lumaArea() const { return Y(); }
229
chromaPosUnitArea230 const Position& chromaPos () const { return Cb(); }
chromaSizeUnitArea231 const Size& chromaSize() const { return Cb(); }
chromaAreaUnitArea232 const Area& chromaArea() const { return Cb(); }
233
234 const UnitArea singleComp(const ComponentID compID) const;
235 const UnitArea singleChan(const ChannelType chType) const;
236
lwidthUnitArea237 SizeType lwidth() const { return Y().width; } /*! luma width */
lheightUnitArea238 SizeType lheight() const { return Y().height; } /*! luma height */
239
lxUnitArea240 PosType lx() const { return Y().x; } /*! luma x-pos */
lyUnitArea241 PosType ly() const { return Y().y; } /*! luma y-pos */
242
validUnitArea243 bool valid() const { return chromaFormat != NUM_CHROMA_FORMAT && blocks.size() > 0; }
244 };
245
clipArea(const UnitArea & area,const UnitArea & boundingBox)246 inline UnitArea clipArea(const UnitArea &area, const UnitArea &boundingBox)
247 {
248 UnitArea ret(area.chromaFormat);
249
250 for (uint32_t i = 0; i < area.blocks.size(); i++)
251 {
252 ret.blocks.push_back(clipArea(area.blocks[i], boundingBox.blocks[i]));
253 }
254
255 return ret;
256 }
257
258 struct UnitAreaRelative : public UnitArea
259 {
UnitAreaRelativeUnitAreaRelative260 UnitAreaRelative(const UnitArea& origUnit, const UnitArea& unit)
261 {
262 *((UnitArea*)this) = unit;
263 for(uint32_t i = 0; i < blocks.size(); i++)
264 {
265 blocks[i].positionRelativeTo(origUnit.blocks[i]);
266 }
267 }
268 };
269
270 class SPS;
271 class VPS;
272 class PPS;
273 class Slice;
274 struct CodingUnit;
275
276 }
277
278 #include "Buffer.h"
279
280 namespace vvdec
281 {
282
283 // ---------------------------------------------------------------------------
284 // transform unit
285 // ---------------------------------------------------------------------------
286
287 struct TransformUnit : public UnitArea
288 {
289 CodingUnit *cu;
290 TransformUnit *next;
291 unsigned idx;
292
293 uint8_t maxScanPosX [MAX_NUM_TBLOCKS];
294 uint8_t maxScanPosY [MAX_NUM_TBLOCKS];
295 int8_t chromaQp [2];
296
297 uint8_t _chType : 2;
298 uint8_t jointCbCr : 2;
299 uint8_t cbf : 3;
300 uint8_t _mtsIdxL : 3;
301 uint8_t _mtsIdxU : 1;
302 uint8_t _mtsIdxV : 1;
303
chTypeTransformUnit304 ChannelType chType() const { return ChannelType( _chType ); }
setChTypeTransformUnit305 void setChType( ChannelType ch ) { _chType = ch; }
mtsIdxTransformUnit306 uint8_t mtsIdx ( int c ) const { return !c ? _mtsIdxL : c == 1 ? _mtsIdxU : _mtsIdxV; }
setMtsIdxTransformUnit307 void setMtsIdx( int c, uint8_t v ) { if ( !c ) _mtsIdxL = v; else if( c == 1 ) _mtsIdxU = v; else _mtsIdxV = v; }
308 };
309
310 // ---------------------------------------------------------------------------
311 // coding unit
312 // ---------------------------------------------------------------------------
313
314 class CodingStructure;
315
316 struct CodingUnit : public UnitArea
317 {
318 TransformUnit firstTU;
319 TransformUnit *lastTU;
320
321 struct CtuData *ctuData;
322 CodingStructure *cs;
323 const Slice *slice;
324 const PPS *pps;
325 const SPS *sps;
326 CodingUnit *next;
327 const CodingUnit *above;
328 const CodingUnit *left;
329 Mv *mvdL0SubPu; // 7 ptr (8 byte)
330 Pel *predBuf;
331 uint32_t idx;
332 uint32_t tileIdx;
333
334 Mv mv [NUM_REF_PIC_LIST_01][3];
335
336 uint8_t mvpIdx [NUM_REF_PIC_LIST_01];
337 int8_t refIdx [NUM_REF_PIC_LIST_01];
338 int8_t intraDir [MAX_NUM_CHANNEL_TYPE];
339
340 SplitSeries splitSeries;
341
342 uint8_t geoSplitDir;
343 uint8_t mmvdIdx;
344
345 int8_t chromaQpAdj;
346 int8_t qp;
347
348 uint8_t _sbtInfo;
349 uint8_t qtDepth : 3;
350 uint8_t depth : 4;
351 uint8_t _chType : 1;
352
353 bool _rootCbf : 1;
354 bool _skip : 1;
355 bool _colorTransform : 1;
356 bool _mipTranspose : 1;
357 uint8_t _treeType : 2;
358 uint8_t _modeType : 2;
359
360 uint8_t _predMode : 2;
361 uint8_t _bdpcmL : 2;
362 uint8_t _bdpcmC : 2;
363 uint8_t _lfnstIdx : 2;
364
365 uint8_t _ispIdx : 2;
366 bool _dmvrCond : 1;
367 bool _ciipFlag : 1;
368 bool _mergeFlag : 1;
369 bool _mmvdFlag : 1;
370 bool _affineFlag : 1;
371 bool _geoFlag : 1;
372
373 uint8_t _mergeType : 2;
374 uint8_t _mrgIdx : 3;
375 uint8_t _geoMrgIdx0 : 3;
376
377 uint8_t _geoMrgIdx1 : 3;
378 uint8_t _affineType : 2;
379 uint8_t _interDir : 2;
380 bool _mipFlag : 1;
381
382 uint8_t _bcw : 3;
383 uint8_t _multiRefIdx : 2;
384 bool planeCbfY : 1;
385 bool planeCbfU : 1;
386 bool planeCbfV : 1;
387
388 uint8_t _imv : 2;
389 uint8_t _smvd : 2;
390
391 uint8_t _geoDir0, _geoDir1;
392
sbtInfoCodingUnit393 uint8_t sbtInfo() const { return _sbtInfo; }
chTypeCodingUnit394 ChannelType chType() const { return ChannelType( _chType ); }
rootCbfCodingUnit395 bool rootCbf() const { return _rootCbf; }
skipCodingUnit396 bool skip() const { return _skip; }
colorTransformCodingUnit397 bool colorTransform() const { return _colorTransform; }
treeTypeCodingUnit398 TreeType treeType() const { return TreeType( _treeType ); }
modeTypeCodingUnit399 ModeType modeType() const { return ModeType( _modeType ); }
predModeCodingUnit400 PredMode predMode() const { return PredMode( _predMode ); }
ispModeCodingUnit401 uint8_t ispMode() const { return _ispIdx; }
bdpcmModeCodingUnit402 uint8_t bdpcmMode() const { return _bdpcmL; }
bdpcmModeChromaCodingUnit403 uint8_t bdpcmModeChroma() const { return _bdpcmC; }
lfnstIdxCodingUnit404 uint8_t lfnstIdx() const { return _lfnstIdx; }
planeCbfCodingUnit405 bool planeCbf( int c ) const { return !c ? planeCbfY : c == 1 ? planeCbfU : planeCbfV; }
406
setChTypeCodingUnit407 void setChType( ChannelType ch ) { _chType = ch ; }
setRootCbfCodingUnit408 void setRootCbf( bool b ) { _rootCbf = b ; }
setSkipCodingUnit409 void setSkip( bool b ) { _skip = b ; }
setColorTransformCodingUnit410 void setColorTransform( bool b ) { _colorTransform = b ; }
setTreeTypeCodingUnit411 void setTreeType( TreeType n ) { _treeType = n ; }
setModeTypeCodingUnit412 void setModeType( ModeType n ) { _modeType = n ; }
setPredModeCodingUnit413 void setPredMode( PredMode n ) { _predMode = n ; }
setIspModeCodingUnit414 void setIspMode( uint8_t n ) { _ispIdx = n ; }
setBdpcmModeCodingUnit415 void setBdpcmMode( uint8_t n ) { _bdpcmL = n ; }
setBdpcmModeChromaCodingUnit416 void setBdpcmModeChroma( uint8_t n ) { _bdpcmC = n ; }
setLfnstIdxCodingUnit417 void setLfnstIdx( uint8_t n ) { _lfnstIdx = n ; }
setSbtInfoCodingUnit418 void setSbtInfo( uint8_t n ) { _sbtInfo = n ; }
setPlaneCbfCodingUnit419 void setPlaneCbf( int c, bool b ) { if( !c ) planeCbfY = b; else if( c == 1 ) planeCbfU = b; else planeCbfV = b; }
420
421 // Prediction Unit Part
422
dmvrConditionCodingUnit423 bool dmvrCondition() const { return _dmvrCond; }
mipTransposedFlagCodingUnit424 bool mipTransposedFlag() const { return _mipTranspose; }
ciipFlagCodingUnit425 bool ciipFlag() const { return _ciipFlag; }
mergeFlagCodingUnit426 bool mergeFlag() const { return _mergeFlag; }
mmvdFlagCodingUnit427 bool mmvdFlag() const { return _mmvdFlag; }
affineFlagCodingUnit428 bool affineFlag() const { return _affineFlag; }
mergeTypeCodingUnit429 MergeType mergeType() const { return MergeType( _mergeType ); }
affineTypeCodingUnit430 AffineModel affineType() const { return AffineModel( _affineType ); }
geoFlagCodingUnit431 bool geoFlag() const { return _geoFlag; }
mergeIdxCodingUnit432 uint8_t mergeIdx() const { return _mrgIdx; }
geoMergeIdx0CodingUnit433 uint8_t geoMergeIdx0() const { return _geoMrgIdx0; }
geoMergeIdx1CodingUnit434 uint8_t geoMergeIdx1() const { return _geoMrgIdx1; }
interDirCodingUnit435 uint8_t interDir() const { return _interDir; }
multiRefIdxCodingUnit436 uint8_t multiRefIdx() const { return _multiRefIdx; }
mipFlagCodingUnit437 bool mipFlag() const { return _mipFlag; }
imvCodingUnit438 uint8_t imv() const { return _imv; }
smvdModeCodingUnit439 uint8_t smvdMode() const { return _smvd; }
BcwIdxCodingUnit440 uint8_t BcwIdx() const { return _bcw; }
441
interDirrefIdxGeo0CodingUnit442 uint8_t interDirrefIdxGeo0() const { return _geoDir0; }
interDirrefIdxGeo1CodingUnit443 uint8_t interDirrefIdxGeo1() const { return _geoDir1; }
444
setDmvrConditionCodingUnit445 void setDmvrCondition( bool b ) { _dmvrCond = b ; }
setMipTransposedFlagCodingUnit446 void setMipTransposedFlag( bool b ) { _mipTranspose = b ; }
setCiipFlagCodingUnit447 void setCiipFlag( bool b ) { _ciipFlag = b ; }
setMergeFlagCodingUnit448 void setMergeFlag( bool b ) { _mergeFlag = b ; }
setMmvdFlagCodingUnit449 void setMmvdFlag( bool b ) { _mmvdFlag = b ; }
setAffineFlagCodingUnit450 void setAffineFlag( bool b ) { _affineFlag = b ; }
setMergeTypeCodingUnit451 void setMergeType( MergeType mt ) { _mergeType = mt; }
setAffineTypeCodingUnit452 void setAffineType( AffineModel at ) { _affineType = at; CHECKD( at >= AFFINE_MODEL_NUM, "Needs to be '0' or '1'!" ); }
setGeoFlagCodingUnit453 void setGeoFlag( bool b ) { _geoFlag = b ; }
setMergeIdxCodingUnit454 void setMergeIdx( uint8_t id ) { _mrgIdx = id; CHECKD( id >= 8, "Merge index needs to be smaller than '8'!"); }
setGeoMergeIdx0CodingUnit455 void setGeoMergeIdx0( uint8_t id ) { _geoMrgIdx0 = id; CHECKD( id >= 8, "Merge index needs to be smaller than '8'!"); }
setGeoMergeIdx1CodingUnit456 void setGeoMergeIdx1( uint8_t id ) { _geoMrgIdx1 = id; CHECKD( id >= 8, "Merge index needs to be smaller than '8'!"); }
setInterDirCodingUnit457 void setInterDir( uint8_t id ) { _interDir = id; CHECKD( id >= 4, "Inter dir needs to be smaller than '4'!"); }
setMultiRefIdxCodingUnit458 void setMultiRefIdx( uint8_t id ) { _multiRefIdx = id; CHECKD( id >= 3, "Multi-ref. index needs to be smaller than '3'!"); }
setMipFlagCodingUnit459 void setMipFlag( bool b ) { _mipFlag = b ; }
setImvCodingUnit460 void setImv( uint8_t id ) { _imv = id; CHECKD( id >= 4, "IMV needs to be smaller than '4'!"); }
setSmvdModeCodingUnit461 void setSmvdMode( uint8_t id ) { _smvd = id; CHECKD( id >= 4, "SMVD mode needs to be smaller than '4'!"); }
setBcwIdxCodingUnit462 void setBcwIdx( uint8_t id ) { _bcw = id; CHECKD( id >= 5, "BCW idx needs to be smaller than '5'!"); }
463
setInterDirrefIdxGeo0CodingUnit464 void setInterDirrefIdxGeo0( uint8_t id ) { _geoDir0 = id; }
setInterDirrefIdxGeo1CodingUnit465 void setInterDirrefIdxGeo1( uint8_t id ) { _geoDir1 = id; }
466
467 CodingUnit& operator=(const MotionInfo& mi);
468
469 // for accessing motion information, which can have higher resolution than PUs (should always be used, when accessing neighboring motion information)
470 const MotionInfo& getMotionInfo() const;
471 const MotionInfo& getMotionInfo( const Position& pos ) const;
472 MotionBuf getMotionBuf();
473 CMotionBuf getMotionBuf() const;
474
475 void minInit( const UnitArea& unit );
476 };
477
478 typedef CodingUnit PredictionUnit;
479
480 // ---------------------------------------------------------------------------
481 // Utility class for easy for-each like unit traversing
482 // ---------------------------------------------------------------------------
483
484 }
485
486 #include <iterator>
487
488 namespace vvdec {
489
490 template<typename T>
491 class UnitIterator : public std::iterator<std::forward_iterator_tag, T>
492 {
493 private:
494 T* m_punit;
495
496 public:
UnitIterator()497 UnitIterator( ) : m_punit( nullptr ) { }
UnitIterator(T * _punit)498 UnitIterator( T* _punit ) : m_punit( _punit ) { }
499
500 typedef T& reference;
501 typedef T const& const_reference;
502 typedef T* pointer;
503 typedef T const* const_pointer;
504
505 reference operator*() { return *m_punit; }
506 const_reference operator*() const { return *m_punit; }
507 pointer operator->() { return m_punit; }
508 const_pointer operator->() const { return m_punit; }
509
510 UnitIterator<T>& operator++() { m_punit = m_punit->next; return *this; }
511 UnitIterator<T> operator++( int ) { auto x = *this; ++( *this ); return x; }
512 bool operator!=( const UnitIterator<T>& other ) const { return m_punit != other.m_punit; }
513 bool operator==( const UnitIterator<T>& other ) const { return m_punit == other.m_punit; }
514 };
515
516 template<typename T>
517 class UnitTraverser
518 {
519 private:
520 T* m_begin;
521 T* m_end;
522
523 public:
UnitTraverser()524 UnitTraverser( ) : m_begin( nullptr ), m_end( nullptr ) { }
UnitTraverser(T * _begin,T * _end)525 UnitTraverser( T* _begin, T* _end ) : m_begin( _begin ), m_end( _end ) { }
526
527 typedef T value_type;
528 typedef size_t size_type;
529 typedef T& reference;
530 typedef T const& const_reference;
531 typedef T* pointer;
532 typedef T const* const_pointer;
533 typedef UnitIterator<T> iterator;
534 typedef UnitIterator<const T> const_iterator;
535
begin()536 iterator begin() { return UnitIterator<T>( m_begin ); }
begin()537 const_iterator begin() const { return UnitIterator<T>( m_begin ); }
cbegin()538 const_iterator cbegin() const { return UnitIterator<T>( m_begin ); }
end()539 iterator end() { return UnitIterator<T>( m_end ); }
end()540 const_iterator end() const { return UnitIterator<T>( m_end ); }
cend()541 const_iterator cend() const { return UnitIterator<T>( m_end ); }
542 };
543
544 typedef UnitTraverser<CodingUnit> CUTraverser;
545 typedef UnitTraverser<const CodingUnit> cCUTraverser;
546
547 typedef UnitTraverser< TransformUnit> TUTraverser;
548 typedef UnitTraverser<const TransformUnit> cTUTraverser;
549
550 }
551
552 #include <memory>
553 #include <mutex>
554
555 namespace vvdec {
556
557 // ---------------------------------------------------------------------------
558 // dynamic cache
559 // ---------------------------------------------------------------------------
560
561 static constexpr size_t DYN_CACHE_CHUNK_SIZE = 1024;
562
563 template<typename T>
564 class dynamic_cache
565 {
566 std::vector<T*> m_cache;
567 std::vector<T*> m_cacheChunks;
568
569 public:
570
~dynamic_cache()571 ~dynamic_cache()
572 {
573 deleteEntries();
574 }
575
deleteEntries()576 void deleteEntries()
577 {
578 for( auto &chunk : m_cacheChunks )
579 {
580 free( chunk );
581 }
582
583 m_cache .clear();
584 m_cacheChunks.clear();
585 }
586
get()587 T* get()
588 {
589 T* ret;
590
591 if( !m_cache.empty() )
592 {
593 ret = m_cache.back();
594 m_cache.pop_back();
595 }
596 else
597 {
598 T* chunk = (T*) malloc( DYN_CACHE_CHUNK_SIZE * sizeof( T ) );
599
600 //GCC_WARNING_DISABLE_class_memaccess
601 //memset( chunk, 0, DYN_CACHE_CHUNK_SIZE * sizeof( T ) );
602 //GCC_WARNING_RESET
603
604 m_cacheChunks.push_back( chunk );
605 m_cache .reserve( m_cache.size() + DYN_CACHE_CHUNK_SIZE );
606
607 for( ptrdiff_t p = 0; p < DYN_CACHE_CHUNK_SIZE; p++ )
608 {
609 //m_cache.push_back( &chunk[DYN_CACHE_CHUNK_SIZE - p - 1] );
610 m_cache.push_back( &chunk[p] );
611 }
612
613 ret = m_cache.back();
614 m_cache.pop_back();
615 }
616
617 return ret;
618 }
619
defragment()620 void defragment()
621 {
622 m_cache.clear();
623
624 for( T* chunk : m_cacheChunks )
625 {
626 //GCC_WARNING_DISABLE_class_memaccess
627 //memset( chunk, 0, DYN_CACHE_CHUNK_SIZE * sizeof( T ) );
628 //GCC_WARNING_RESET
629
630 for( ptrdiff_t p = 0; p < DYN_CACHE_CHUNK_SIZE; p++ )
631 {
632 //m_cache.push_back( &chunk[DYN_CACHE_CHUNK_SIZE - p - 1] );
633 m_cache.push_back( &chunk[p] );
634 }
635 }
636 }
637
cache(std::vector<T * > & vel)638 void cache( std::vector<T*>& vel )
639 {
640 m_cache.insert( m_cache.end(), vel.begin(), vel.end() );
641 vel.clear();
642 }
643 };
644
645 typedef dynamic_cache<struct CodingUnit> CUCache;
646 typedef dynamic_cache<struct TransformUnit> TUCache;
647
648 struct ThreadSafeCUCache
649 {
650 std::shared_ptr<CUCache> getCuCache();
651 std::shared_ptr<TUCache> getTuCache();
652
653 private:
654 std::mutex m_mutex;
655
656 // we use the shared_ptr reference-count to track if a cache is in use or available
657 std::vector< std::shared_ptr<CUCache> > m_cuCaches;
658 std::vector< std::shared_ptr<TUCache> > m_tuCaches;
659 };
660
661 }
662
663