Coverage Report

Created: 2026-04-01 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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