Coverage Report

Created: 2026-06-16 07:20

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
984k
{
81
984k
  if( srcCHt == dstCHt )
82
690k
  {
83
690k
    return pos;
84
690k
  }
85
293k
  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
293k
  else
90
293k
  {
91
293k
    return Position( pos.x << getChannelTypeScaleX( srcCHt, _cf ), pos.y << getChannelTypeScaleY( srcCHt, _cf ) );
92
293k
  }
93
984k
}
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
12.4k
{
113
12.4k
  if( srcCHt == dstCHt )
114
0
  {
115
0
    return size;
116
0
  }
117
12.4k
  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
12.4k
  else
122
12.4k
  {
123
12.4k
    return Size( size.width << getChannelTypeScaleX( srcCHt, _cf ), size.height << getChannelTypeScaleY( srcCHt, _cf ) );
124
12.4k
  }
125
12.4k
}
126
127
// ---------------------------------------------------------------------------
128
// block definition
129
// ---------------------------------------------------------------------------
130
131
struct CompArea : public Area
132
{
133
1.96M
  CompArea() : Area()                                                                                                                                                          { }
134
39.5k
  CompArea(const ComponentID _compID, const Area &_area)                                                          : Area(_area.x, _area.y, _area.width, _area.height, _compID) { }
135
220k
  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
5.77M
  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
780
{
169
780
  return CompArea(compArea.compID(), clipArea((const Area&) compArea, boundingBox));
170
780
}
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
245k
  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
811k
        CompArea& Y()                                  { return blocks[COMPONENT_Y];  }
192
6.42M
  const CompArea& Y()                            const { return blocks[COMPONENT_Y];  }
193
327k
        CompArea& Cb()                                 { return blocks[COMPONENT_Cb]; }
194
2.01M
  const CompArea& Cb()                           const { return blocks[COMPONENT_Cb]; }
195
315k
        CompArea& Cr()                                 { return blocks[COMPONENT_Cr]; }
196
54.9k
  const CompArea& Cr()                           const { return blocks[COMPONENT_Cr]; }
197
198
62.5k
        CompArea& block(const ComponentID comp)       { return blocks[comp]; }
199
426k
  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
424k
  const Position& lumaPos () const { return Y(); }
225
698k
  const Size&     lumaSize() const { return Y(); }
226
0
  const Area&     lumaArea() const { return Y(); }
227
228
203k
  const Position& chromaPos () const { return Cb(); }
229
305k
  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
1.52M
  SizeType  lwidth()  const { return Y().width; }  /*! luma width  */
236
1.28M
  SizeType  lheight() const { return Y().height; } /*! luma height */
237
238
5.23k
  PosType   lx() const { return Y().x; }           /*! luma x-pos */
239
60.6k
  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
261
{
246
261
  UnitArea ret(area.chromaFormat);
247
248
1.04k
  for (uint32_t i = 0; i < area.blocks.size(); i++)
249
782
  {
250
782
    ret.blocks.push_back(clipArea(area.blocks[i], boundingBox.blocks[i]));
251
782
  }
252
253
261
  return ret;
254
261
}
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
300k
  ChannelType     chType()                const { return ChannelType( _chType ); }
303
202k
  void            setChType( ChannelType ch )   { _chType = ch; }
304
1.63M
  uint8_t         mtsIdx   ( int c )      const { return !c ? _mtsIdxL :             c == 1 ? _mtsIdxU :         _mtsIdxV; }
305
313k
  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
1.22M
  uint8_t           sbtInfo()                const        { return _sbtInfo; }
392
5.90M
  ChannelType       chType()                 const        { return ChannelType( _chType ); }
393
198k
  bool              rootCbf()                const        { return _rootCbf; }
394
429k
  bool              skip()                   const        { return _skip; }
395
329k
  bool              colorTransform()         const        { return _colorTransform; }
396
1.33M
  TreeType          treeType()               const        { return TreeType( _treeType ); }
397
177k
  ModeType          modeType()               const        { return ModeType( _modeType ); }
398
5.18M
  PredMode          predMode()               const        { return PredMode( _predMode ); }
399
3.67M
  uint8_t           ispMode()                const        { return _ispIdx; }
400
1.99M
  uint8_t           bdpcmMode()              const        { return _bdpcmL; }
401
1.24M
  uint8_t           bdpcmModeChroma()        const        { return _bdpcmC; }
402
200k
  uint8_t           lfnstIdx()               const        { return _lfnstIdx; }
403
889k
  bool              planeCbf( int c )        const        { return !c ? planeCbfY : c == 1 ? planeCbfU : planeCbfV; }
404
405
365k
  void              setChType( ChannelType ch )           { _chType         = ch ; }
406
346k
  void              setRootCbf( bool b )                  { _rootCbf        =  b ; }
407
4.86k
  void              setSkip( bool b )                     { _skip           =  b ; }
408
4.86k
  void              setColorTransform( bool b )           { _colorTransform =  b ; }
409
182k
  void              setTreeType( TreeType n )             { _treeType       =  n ; }
410
182k
  void              setModeType( ModeType n )             { _modeType       =  n ; }
411
214k
  void              setPredMode( PredMode n )             { _predMode       =  n ; }
412
6.97k
  void              setIspMode( uint8_t n )               { _ispIdx         =  n ; }
413
37.5k
  void              setBdpcmMode( uint8_t n )             { _bdpcmL         =  n ; }
414
50.4k
  void              setBdpcmModeChroma( uint8_t n )       { _bdpcmC         =  n ; }
415
41.2k
  void              setLfnstIdx( uint8_t n )              { _lfnstIdx       =  n ; }
416
0
  void              setSbtInfo( uint8_t n )               { _sbtInfo        =  n ; }
417
597k
  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
2.77k
  bool              mipTransposedFlag()      const         { return _mipTranspose; }
423
468k
  bool              ciipFlag()               const         { return _ciipFlag; }
424
266k
  bool              mergeFlag()              const         { return _mergeFlag; }
425
23.5k
  bool              mmvdFlag()               const         { return _mmvdFlag; }
426
545k
  bool              affineFlag()             const         { return _affineFlag; }
427
33.0k
  MergeType         mergeType()              const         { return MergeType( _mergeType ); }
428
0
  AffineModel       affineType()             const         { return AffineModel( _affineType ); }
429
87.2k
  bool              geoFlag()                const         { return _geoFlag; }
430
22.0k
  uint8_t           mergeIdx()               const         { return _mrgIdx; }
431
0
  uint8_t           geoMergeIdx0()           const         { return _geoMrgIdx0; }
432
0
  uint8_t           geoMergeIdx1()           const         { return _geoMrgIdx1; }
433
85.4k
  uint8_t           interDir()               const         { return _interDir; }
434
205k
  uint8_t           multiRefIdx()            const         { return _multiRefIdx; }
435
523k
  bool              mipFlag()                const         { return _mipFlag; }
436
82.2k
  uint8_t           imv()                    const         { return _imv; }
437
36.7k
  uint8_t           smvdMode()               const         { return _smvd; }
438
19.8k
  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
10.9k
  void              setMipTransposedFlag( bool b )         { _mipTranspose  = b ; }
445
0
  void              setCiipFlag( bool b )                  { _ciipFlag      = b ; }
446
36.8k
  void              setMergeFlag( bool b )                 { _mergeFlag     = b ; }
447
0
  void              setMmvdFlag( bool b )                  { _mmvdFlag      = b ; }
448
0
  void              setAffineFlag( bool b )                { _affineFlag    = b ; }
449
11.0k
  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
16.7k
  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
31.0k
  void              setInterDir( uint8_t id )              { _interDir      = id; CHECKD( id >=  4, "Inter dir needs to be smaller than '4'!"); }
456
45.7k
  void              setMultiRefIdx( uint8_t id )           { _multiRefIdx   = id; CHECKD( id >=  3, "Multi-ref. index needs to be smaller than '3'!"); }
457
65.7k
  void              setMipFlag( bool b )                   { _mipFlag       = b ; }
458
44.5k
  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
11.0k
  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
938k
  explicit UnitIterator( T* _punit ) : m_punit( _punit ) {}
vvdec::UnitIterator<vvdec::CodingUnit>::UnitIterator(vvdec::CodingUnit*)
Line
Count
Source
493
23.6k
  explicit UnitIterator( T* _punit ) : m_punit( _punit ) {}
vvdec::UnitIterator<vvdec::TransformUnit const>::UnitIterator(vvdec::TransformUnit const*)
Line
Count
Source
493
336k
  explicit UnitIterator( T* _punit ) : m_punit( _punit ) {}
vvdec::UnitIterator<vvdec::TransformUnit>::UnitIterator(vvdec::TransformUnit*)
Line
Count
Source
493
578k
  explicit UnitIterator( T* _punit ) : m_punit( _punit ) {}
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
884k
  reference        operator*()                                      { return *m_punit; }
vvdec::UnitIterator<vvdec::CodingUnit>::operator*()
Line
Count
Source
503
354k
  reference        operator*()                                      { return *m_punit; }
vvdec::UnitIterator<vvdec::TransformUnit const>::operator*()
Line
Count
Source
503
205k
  reference        operator*()                                      { return *m_punit; }
vvdec::UnitIterator<vvdec::TransformUnit>::operator*()
Line
Count
Source
503
323k
  reference        operator*()                                      { return *m_punit; }
504
  const_reference  operator*()                                const { return *m_punit; }
505
  pointer          operator->()                                     { return  m_punit; }
506
  const_pointer    operator->()                               const { return  m_punit; }
507
508
884k
  UnitIterator<T>& operator++()                                     { m_punit = m_punit->next; return *this; }
vvdec::UnitIterator<vvdec::CodingUnit>::operator++()
Line
Count
Source
508
354k
  UnitIterator<T>& operator++()                                     { m_punit = m_punit->next; return *this; }
vvdec::UnitIterator<vvdec::TransformUnit const>::operator++()
Line
Count
Source
508
205k
  UnitIterator<T>& operator++()                                     { m_punit = m_punit->next; return *this; }
vvdec::UnitIterator<vvdec::TransformUnit>::operator++()
Line
Count
Source
508
324k
  UnitIterator<T>& operator++()                                     { m_punit = m_punit->next; return *this; }
509
  UnitIterator<T>  operator++( int )                                { auto x = *this; ++( *this ); return x; }
510
1.35M
  bool             operator!=( const UnitIterator<T>& other ) const { return m_punit != other.m_punit; }
vvdec::UnitIterator<vvdec::CodingUnit>::operator!=(vvdec::UnitIterator<vvdec::CodingUnit> const&) const
Line
Count
Source
510
365k
  bool             operator!=( const UnitIterator<T>& other ) const { return m_punit != other.m_punit; }
vvdec::UnitIterator<vvdec::TransformUnit const>::operator!=(vvdec::UnitIterator<vvdec::TransformUnit const> const&) const
Line
Count
Source
510
374k
  bool             operator!=( const UnitIterator<T>& other ) const { return m_punit != other.m_punit; }
vvdec::UnitIterator<vvdec::TransformUnit>::operator!=(vvdec::UnitIterator<vvdec::TransformUnit> const&) const
Line
Count
Source
510
611k
  bool             operator!=( const UnitIterator<T>& other ) const { return m_punit != other.m_punit; }
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
469k
  UnitTraverser( T* _begin, T* _end ) : m_begin( _begin  ), m_end( _end    ) { }
vvdec::UnitTraverser<vvdec::TransformUnit const>::UnitTraverser(vvdec::TransformUnit const*, vvdec::TransformUnit const*)
Line
Count
Source
523
168k
  UnitTraverser( T* _begin, T* _end ) : m_begin( _begin  ), m_end( _end    ) { }
vvdec::UnitTraverser<vvdec::CodingUnit>::UnitTraverser(vvdec::CodingUnit*, vvdec::CodingUnit*)
Line
Count
Source
523
11.8k
  UnitTraverser( T* _begin, T* _end ) : m_begin( _begin  ), m_end( _end    ) { }
vvdec::UnitTraverser<vvdec::TransformUnit>::UnitTraverser(vvdec::TransformUnit*, vvdec::TransformUnit*)
Line
Count
Source
523
289k
  UnitTraverser( T* _begin, T* _end ) : m_begin( _begin  ), m_end( _end    ) { }
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
469k
  iterator        begin()        { return UnitIterator<T>( m_begin ); }
vvdec::UnitTraverser<vvdec::CodingUnit>::begin()
Line
Count
Source
534
11.8k
  iterator        begin()        { return UnitIterator<T>( m_begin ); }
vvdec::UnitTraverser<vvdec::TransformUnit const>::begin()
Line
Count
Source
534
168k
  iterator        begin()        { return UnitIterator<T>( m_begin ); }
vvdec::UnitTraverser<vvdec::TransformUnit>::begin()
Line
Count
Source
534
289k
  iterator        begin()        { return UnitIterator<T>( m_begin ); }
535
  const_iterator  begin()  const { return UnitIterator<T>( m_begin ); }
536
  const_iterator  cbegin() const { return UnitIterator<T>( m_begin ); }
537
469k
  iterator        end()          { return UnitIterator<T>( m_end   ); }
vvdec::UnitTraverser<vvdec::CodingUnit>::end()
Line
Count
Source
537
11.8k
  iterator        end()          { return UnitIterator<T>( m_end   ); }
vvdec::UnitTraverser<vvdec::TransformUnit const>::end()
Line
Count
Source
537
168k
  iterator        end()          { return UnitIterator<T>( m_end   ); }
vvdec::UnitTraverser<vvdec::TransformUnit>::end()
Line
Count
Source
537
289k
  iterator        end()          { return UnitIterator<T>( m_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
3.74k
  {
571
3.74k
    clear_chunks();
572
3.74k
  }
vvdec::thread_safe_chunk_cache<vvdec::CodingUnit>::~thread_safe_chunk_cache()
Line
Count
Source
570
1.87k
  {
571
1.87k
    clear_chunks();
572
1.87k
  }
vvdec::thread_safe_chunk_cache<vvdec::TransformUnit>::~thread_safe_chunk_cache()
Line
Count
Source
570
1.87k
  {
571
1.87k
    clear_chunks();
572
1.87k
  }
573
574
  void clear_chunks()
575
3.74k
  {
576
3.74k
    for( auto& chunk : m_cacheChunks )
577
1.29k
    {
578
1.29k
      free( chunk );
579
1.29k
    }
580
581
3.74k
    m_cacheChunks.clear();
582
3.74k
  }
vvdec::thread_safe_chunk_cache<vvdec::CodingUnit>::clear_chunks()
Line
Count
Source
575
1.87k
  {
576
1.87k
    for( auto& chunk : m_cacheChunks )
577
712
    {
578
712
      free( chunk );
579
712
    }
580
581
1.87k
    m_cacheChunks.clear();
582
1.87k
  }
vvdec::thread_safe_chunk_cache<vvdec::TransformUnit>::clear_chunks()
Line
Count
Source
575
1.87k
  {
576
1.87k
    for( auto& chunk : m_cacheChunks )
577
580
    {
578
580
      free( chunk );
579
580
    }
580
581
1.87k
    m_cacheChunks.clear();
582
1.87k
  }
583
584
  T* get()
585
1.29k
  {
586
1.29k
    std::unique_lock<std::mutex> l( m_mutex );
587
588
1.29k
    if( m_cacheChunks.empty() )
589
1.29k
    {
590
1.29k
      l.unlock();
591
1.29k
      return ( T* ) malloc( DYN_CACHE_CHUNK_SIZE * sizeof( T ) );
592
1.29k
    }
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
1.29k
  }
vvdec::thread_safe_chunk_cache<vvdec::CodingUnit>::get()
Line
Count
Source
585
712
  {
586
712
    std::unique_lock<std::mutex> l( m_mutex );
587
588
712
    if( m_cacheChunks.empty() )
589
712
    {
590
712
      l.unlock();
591
712
      return ( T* ) malloc( DYN_CACHE_CHUNK_SIZE * sizeof( T ) );
592
712
    }
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
712
  }
vvdec::thread_safe_chunk_cache<vvdec::TransformUnit>::get()
Line
Count
Source
585
580
  {
586
580
    std::unique_lock<std::mutex> l( m_mutex );
587
588
580
    if( m_cacheChunks.empty() )
589
580
    {
590
580
      l.unlock();
591
580
      return ( T* ) malloc( DYN_CACHE_CHUNK_SIZE * sizeof( T ) );
592
580
    }
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
580
  }
600
601
  void cache( std::vector<T*>& chunks )
602
4.28k
  {
603
4.28k
    std::unique_lock<std::mutex> l( m_mutex );
604
605
4.28k
    m_cacheChunks.insert( m_cacheChunks.end(), chunks.begin(), chunks.end() );
606
4.28k
    chunks.clear();
607
4.28k
  }
vvdec::thread_safe_chunk_cache<vvdec::TransformUnit>::cache(std::__1::vector<vvdec::TransformUnit*, std::__1::allocator<vvdec::TransformUnit*> >&)
Line
Count
Source
602
2.14k
  {
603
2.14k
    std::unique_lock<std::mutex> l( m_mutex );
604
605
2.14k
    m_cacheChunks.insert( m_cacheChunks.end(), chunks.begin(), chunks.end() );
606
2.14k
    chunks.clear();
607
2.14k
  }
vvdec::thread_safe_chunk_cache<vvdec::CodingUnit>::cache(std::__1::vector<vvdec::CodingUnit*, std::__1::allocator<vvdec::CodingUnit*> >&)
Line
Count
Source
602
2.14k
  {
603
2.14k
    std::unique_lock<std::mutex> l( m_mutex );
604
605
2.14k
    m_cacheChunks.insert( m_cacheChunks.end(), chunks.begin(), chunks.end() );
606
2.14k
    chunks.clear();
607
2.14k
  }
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
4.28k
  {
620
4.28k
    m_chunkCache->cache( m_cache );
621
4.28k
  }
vvdec::dynamic_cache<vvdec::TransformUnit>::clear_chunks()
Line
Count
Source
619
2.14k
  {
620
2.14k
    m_chunkCache->cache( m_cache );
621
2.14k
  }
vvdec::dynamic_cache<vvdec::CodingUnit>::clear_chunks()
Line
Count
Source
619
2.14k
  {
620
2.14k
    m_chunkCache->cache( m_cache );
621
2.14k
  }
622
623
public:
624
625
1.42k
  explicit dynamic_cache( thread_safe_chunk_cache<T>* chunkCache ) : m_lastIdx( DYN_CACHE_CHUNK_SIZE ), m_chunkCache( chunkCache )
626
1.42k
  {
627
1.42k
  }
vvdec::dynamic_cache<vvdec::CodingUnit>::dynamic_cache(vvdec::thread_safe_chunk_cache<vvdec::CodingUnit>*)
Line
Count
Source
625
714
  explicit dynamic_cache( thread_safe_chunk_cache<T>* chunkCache ) : m_lastIdx( DYN_CACHE_CHUNK_SIZE ), m_chunkCache( chunkCache )
626
714
  {
627
714
  }
vvdec::dynamic_cache<vvdec::TransformUnit>::dynamic_cache(vvdec::thread_safe_chunk_cache<vvdec::TransformUnit>*)
Line
Count
Source
625
714
  explicit dynamic_cache( thread_safe_chunk_cache<T>* chunkCache ) : m_lastIdx( DYN_CACHE_CHUNK_SIZE ), m_chunkCache( chunkCache )
626
714
  {
627
714
  }
628
629
  ~dynamic_cache()
630
1.42k
  {
631
1.42k
    clear_chunks();
632
1.42k
  }
vvdec::dynamic_cache<vvdec::TransformUnit>::~dynamic_cache()
Line
Count
Source
630
714
  {
631
714
    clear_chunks();
632
714
  }
vvdec::dynamic_cache<vvdec::CodingUnit>::~dynamic_cache()
Line
Count
Source
630
714
  {
631
714
    clear_chunks();
632
714
  }
633
634
  T* get()
635
203k
  {
636
203k
    T* ret;
637
638
203k
    if( m_lastIdx < DYN_CACHE_CHUNK_SIZE )
639
201k
    {
640
201k
      ret = &m_cache.back()[m_lastIdx++];
641
201k
    }
642
1.29k
    else
643
1.29k
    {
644
1.29k
      T* chunk = m_chunkCache->get();
645
646
1.29k
      m_cache.push_back( chunk );
647
648
1.29k
      ret = &chunk[0];
649
1.29k
      m_lastIdx = 1;
650
1.29k
    }
651
652
203k
    return ret;
653
203k
  }
vvdec::dynamic_cache<vvdec::CodingUnit>::get()
Line
Count
Source
635
182k
  {
636
182k
    T* ret;
637
638
182k
    if( m_lastIdx < DYN_CACHE_CHUNK_SIZE )
639
182k
    {
640
182k
      ret = &m_cache.back()[m_lastIdx++];
641
182k
    }
642
712
    else
643
712
    {
644
712
      T* chunk = m_chunkCache->get();
645
646
712
      m_cache.push_back( chunk );
647
648
712
      ret = &chunk[0];
649
712
      m_lastIdx = 1;
650
712
    }
651
652
182k
    return ret;
653
182k
  }
vvdec::dynamic_cache<vvdec::TransformUnit>::get()
Line
Count
Source
635
20.2k
  {
636
20.2k
    T* ret;
637
638
20.2k
    if( m_lastIdx < DYN_CACHE_CHUNK_SIZE )
639
19.6k
    {
640
19.6k
      ret = &m_cache.back()[m_lastIdx++];
641
19.6k
    }
642
580
    else
643
580
    {
644
580
      T* chunk = m_chunkCache->get();
645
646
580
      m_cache.push_back( chunk );
647
648
580
      ret = &chunk[0];
649
580
      m_lastIdx = 1;
650
580
    }
651
652
20.2k
    return ret;
653
20.2k
  }
654
655
  void releaseAll()
656
2.86k
  {
657
2.86k
    clear_chunks();
658
2.86k
    m_lastIdx = DYN_CACHE_CHUNK_SIZE;
659
2.86k
  }
vvdec::dynamic_cache<vvdec::CodingUnit>::releaseAll()
Line
Count
Source
656
1.43k
  {
657
1.43k
    clear_chunks();
658
1.43k
    m_lastIdx = DYN_CACHE_CHUNK_SIZE;
659
1.43k
  }
vvdec::dynamic_cache<vvdec::TransformUnit>::releaseAll()
Line
Count
Source
656
1.43k
  {
657
1.43k
    clear_chunks();
658
1.43k
    m_lastIdx = DYN_CACHE_CHUNK_SIZE;
659
1.43k
  }
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