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/Buffer.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     Buffer.h
44
 *  \brief    Low-overhead class describing 2D memory layout
45
 */
46
47
#pragma once
48
49
#include "Common.h"
50
#include "CommonDef.h"
51
#include "ChromaFormat.h"
52
#include "MotionInfo.h"
53
54
#include <string.h>
55
#include <type_traits>
56
#include <utility>
57
58
namespace vvdec
59
{
60
61
struct CodingUnit;
62
63
#if ENABLE_SIMD_OPT_BUFFER && defined(TARGET_SIMD_X86)
64
using namespace x86_simd;
65
#endif
66
#if ENABLE_SIMD_OPT_BUFFER && defined(TARGET_SIMD_ARM)
67
using namespace arm_simd;
68
#endif
69
70
struct PelBufferOps
71
{
72
  PelBufferOps();
73
74
#if defined( TARGET_SIMD_X86 ) && ENABLE_SIMD_OPT_BUFFER
75
  void initPelBufOpsX86();
76
  template<X86_VEXT vext>
77
  void _initPelBufOpsX86();
78
#endif
79
80
#if defined( TARGET_SIMD_ARM ) && ENABLE_SIMD_OPT_BUFFER
81
  void initPelBufOpsARM();
82
  template<ARM_VEXT vext>
83
  void _initPelBufOpsARM();
84
#endif
85
86
  void ( *addAvg4 )       ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height,            int shift, int offset,      const ClpRng& clpRng );
87
  void ( *addAvg8 )       ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height,            int shift, int offset,      const ClpRng& clpRng );
88
  void ( *addAvg16 )      ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height,            int shift, int offset,      const ClpRng& clpRng );
89
  void ( *reco4 )         ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height,                                        const ClpRng& clpRng );
90
  void ( *reco8 )         ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height,                                        const ClpRng& clpRng );
91
  void ( *linTf4 )        ( const Pel* src0, ptrdiff_t src0Stride,                                        Pel *dst, ptrdiff_t dstStride, int width, int height, int scale, int shift, int offset,      const ClpRng& clpRng, bool bClip );
92
  void ( *linTf8 )        ( const Pel* src0, ptrdiff_t src0Stride,                                        Pel *dst, ptrdiff_t dstStride, int width, int height, int scale, int shift, int offset,      const ClpRng& clpRng, bool bClip );
93
  void ( *wghtAvg4 )      ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height, int shift, int offset, int w0, int w1, const ClpRng& clpRng );
94
  void ( *wghtAvg8 )      ( const Pel* src0, ptrdiff_t src0Stride, const Pel* src1, ptrdiff_t src1Stride, Pel *dst, ptrdiff_t dstStride, int width, int height, int shift, int offset, int w0, int w1, const ClpRng& clpRng );
95
  void ( *copyBuffer  )    ( const char*src,  ptrdiff_t srcStride,        char* dst, ptrdiff_t  dstStride,                                int width, int height );
96
  void ( *transpose4x4 )  ( const Pel* src,  ptrdiff_t srcStride, Pel* dst, ptrdiff_t dstStride );
97
  void ( *transpose8x8 )  ( const Pel* src,  ptrdiff_t srcStride, Pel* dst, ptrdiff_t dstStride );
98
  void ( *applyLut )      (       Pel* ptr,  ptrdiff_t ptrStride, int width, int height, const Pel* lut );
99
  void ( *rspFwd )        (       Pel* ptr,  ptrdiff_t ptrStride, int width, int height, const int bd,                   const Pel OrgCW,  const Pel* LmcsPivot, const Pel* ScaleCoeff, const Pel* InputPivot );
100
  void ( *rspBcw )        (       Pel* ptr,  ptrdiff_t ptrStride, int width, int height, const int bd, const int minBin, const int maxBin, const Pel* LmcsPivot, const Pel* InvScCoeff, const Pel* InputPivot );
101
  void ( *fillN_CU )      (       CodingUnit** ptr, ptrdiff_t ptrStride, int width, int height, CodingUnit* cuPtr );
102
103
  void (*sampleRateConv)  ( const std::pair<int, int> scalingRatio, const std::pair<int, int> compScale,
104
                            const Pel* orgSrc, const ptrdiff_t orgStride, const int orgWidth, const int orgHeight,
105
                            const int beforeScaleLeftOffset, const int beforeScaleTopOffset,
106
                            Pel* scaledSrc, const ptrdiff_t scaledStride, const int scaledWidth, const int scaledHeight,
107
                            const int afterScaleLeftOffset, const int afterScaleTopOffset,
108
                            const int bitDepth, const bool useLumaFilter, const bool horCollocatedPositionFlag, const bool verCollocatedPositionFlag );
109
};
110
111
extern PelBufferOps g_pelBufOP;
112
113
void sampleRateConvCore( const std::pair<int, int> scalingRatio, const std::pair<int, int> compScale,
114
                         const Pel* orgSrc, const ptrdiff_t orgStride, const int orgWidth, const int orgHeight,
115
                         const int beforeScaleLeftOffset, const int beforeScaleTopOffset,
116
                         Pel* scaledSrc, const ptrdiff_t scaledStride, const int scaledWidth, const int scaledHeight,
117
                         const int afterScaleLeftOffset, const int afterScaleTopOffset,
118
                         const int bitDepth, const bool useLumaFilter,
119
                         const bool horCollocatedPositionFlag, const bool verCollocatedPositionFlag );
120
121
0
#define INCX( ptr, stride ) { ptr++; }
122
0
#define INCY( ptr, stride ) { ptr += ( stride ); }
123
0
#define OFFSETX( ptr, stride, x ) { ptr += ( x ); }
124
0
#define OFFSETY( ptr, stride, y ) { ptr += ( y ) * ( stride ); }
125
0
#define OFFSET( ptr, stride, x, y ) { ptr += ( x ) + ( y ) * ( stride ); }
126
0
#define GET_OFFSETX( ptr, stride, x ) ( ( ptr ) + ( x ) )
127
0
#define GET_OFFSETY( ptr, stride, y ) ( ( ptr ) + ( y ) * ( stride ) )
128
0
#define GET_OFFSET( ptr, stride, x, y ) ( ( ptr ) + ( x ) + ( y ) * ( stride ) )
129
130
class Window;
131
struct BitDepths;
132
133
template<typename T>
134
struct AreaBuf : public Size
135
{
136
  T*        buf;
137
  ptrdiff_t stride;
138
139
0
  AreaBuf()                                                                                     : Size(),                  buf( NULL ), stride( 0 )          { }
Unexecuted instantiation: vvdec::AreaBuf<short const>::AreaBuf()
Unexecuted instantiation: vvdec::AreaBuf<short>::AreaBuf()
Unexecuted instantiation: vvdec::AreaBuf<vvdec::MotionInfo>::AreaBuf()
140
0
  AreaBuf( T *_buf, const Size &size )                                                          : Size( size ),            buf( _buf ), stride( size.width ) { }
141
0
  AreaBuf( T *_buf, const ptrdiff_t &_stride, const Size &size )                                : Size( size ),            buf( _buf ), stride( _stride )    { }
Unexecuted instantiation: vvdec::AreaBuf<short const>::AreaBuf(short const*, long const&, vvdec::Size const&)
Unexecuted instantiation: vvdec::AreaBuf<short>::AreaBuf(short*, long const&, vvdec::Size const&)
142
0
  AreaBuf( T *_buf, const SizeType &_width, const SizeType &_height )                           : Size( _width, _height ), buf( _buf ), stride( _width )     { }
Unexecuted instantiation: vvdec::AreaBuf<short>::AreaBuf(short*, unsigned int const&, unsigned int const&)
Unexecuted instantiation: vvdec::AreaBuf<short const>::AreaBuf(short const*, unsigned int const&, unsigned int const&)
Unexecuted instantiation: vvdec::AreaBuf<int>::AreaBuf(int*, unsigned int const&, unsigned int const&)
143
0
  AreaBuf( T *_buf, const ptrdiff_t &_stride, const SizeType &_width, const SizeType &_height ) : Size( _width, _height ), buf( _buf ), stride( _stride )    { }
Unexecuted instantiation: vvdec::AreaBuf<short>::AreaBuf(short*, long const&, unsigned int const&, unsigned int const&)
Unexecuted instantiation: vvdec::AreaBuf<vvdec::MotionInfo>::AreaBuf(vvdec::MotionInfo*, long const&, unsigned int const&, unsigned int const&)
Unexecuted instantiation: vvdec::AreaBuf<vvdec::MotionInfo const>::AreaBuf(vvdec::MotionInfo const*, long const&, unsigned int const&, unsigned int const&)
Unexecuted instantiation: vvdec::AreaBuf<short const>::AreaBuf(short const*, long const&, unsigned int const&, unsigned int const&)
144
145
  AreaBuf( const AreaBuf& )  = default;
146
  AreaBuf(       AreaBuf&& ) = default;
147
  AreaBuf& operator=( const AreaBuf& )  = default;
148
  AreaBuf& operator=(       AreaBuf&& ) = default;
149
150
  // conversion from AreaBuf<const T> to AreaBuf<T>
151
  template<bool T_IS_CONST = std::is_const<T>::value>
152
0
  AreaBuf( const AreaBuf<typename std::remove_const_t<T>>& other, std::enable_if_t<T_IS_CONST>* = 0) : Size( other ), buf( other.buf ), stride( other.stride ) { }
Unexecuted instantiation: vvdec::AreaBuf<short const>::AreaBuf<true>(vvdec::AreaBuf<short> const&, std::__1::enable_if<true, void>::type*)
Unexecuted instantiation: vvdec::AreaBuf<int const>::AreaBuf<true>(vvdec::AreaBuf<int> const&, std::__1::enable_if<true, void>::type*)
153
154
  void fill                 ( const T &val );
155
  void memset               ( const int val );
156
157
  void copyFrom             ( const AreaBuf<const T> &other );
158
  
159
  void reconstruct          ( const AreaBuf<const T> &pred, const AreaBuf<const T> &resi, const ClpRng& clpRng);
160
  
161
  void subtract             ( const AreaBuf<const T> &other );
162
  void extendBorderPel      ( unsigned margin );
163
  void extendBorderPel      ( unsigned margin, bool left, bool right, bool top, bool bottom );
164
  void addWeightedAvg       ( const AreaBuf<const T> &other1, const AreaBuf<const T> &other2, const ClpRng& clpRng, const int8_t bcwIdx);
165
  void addAvg               ( const AreaBuf<const T> &other1, const AreaBuf<const T> &other2, const ClpRng& clpRng );
166
  void padBorderPel         ( unsigned marginX, unsigned marginY, int dir );
167
  
168
  void linearTransform      ( const int scale, const int shift, const int offset, bool bClip, const ClpRng& clpRng );
169
170
  void transposedFrom       ( const AreaBuf<const T> &other );
171
172
  void scaleSignal          ( const int scale, const ClpRng& clpRng );
173
174
0
        T& at( const int &x, const int &y )          { return buf[y * stride + x]; }
Unexecuted instantiation: vvdec::AreaBuf<vvdec::MotionInfo>::at(int const&, int const&)
Unexecuted instantiation: vvdec::AreaBuf<short>::at(int const&, int const&)
175
0
  const T& at( const int &x, const int &y ) const    { return buf[y * stride + x]; }
Unexecuted instantiation: vvdec::AreaBuf<short const>::at(int const&, int const&) const
Unexecuted instantiation: vvdec::AreaBuf<int const>::at(int const&, int const&) const
176
177
        T& at( const Position &pos )                 { return buf[pos.y * stride + pos.x]; }
178
  const T& at( const Position &pos ) const           { return buf[pos.y * stride + pos.x]; }
179
180
181
0
        T* bufAt( const int &x, const int &y )       { return GET_OFFSET( buf, stride,     x,     y ); }
Unexecuted instantiation: vvdec::AreaBuf<short>::bufAt(int const&, int const&)
Unexecuted instantiation: vvdec::AreaBuf<short const>::bufAt(int const&, int const&)
182
0
  const T* bufAt( const int &x, const int &y ) const { return GET_OFFSET( buf, stride,     x,     y ); }
Unexecuted instantiation: vvdec::AreaBuf<short>::bufAt(int const&, int const&) const
Unexecuted instantiation: vvdec::AreaBuf<short const>::bufAt(int const&, int const&) const
183
0
        T* bufAt( const Position& pos )              { return GET_OFFSET( buf, stride, pos.x, pos.y ); }
Unexecuted instantiation: vvdec::AreaBuf<short>::bufAt(vvdec::Position const&)
Unexecuted instantiation: vvdec::AreaBuf<short const>::bufAt(vvdec::Position const&)
184
0
  const T* bufAt( const Position& pos ) const        { return GET_OFFSET( buf, stride, pos.x, pos.y ); }
Unexecuted instantiation: vvdec::AreaBuf<short>::bufAt(vvdec::Position const&) const
Unexecuted instantiation: vvdec::AreaBuf<short const>::bufAt(vvdec::Position const&) const
185
186
0
  AreaBuf<      T> subBuf( const Area &area )                                                         { return subBuf( area.pos(), area.size() ); }
187
0
  AreaBuf<const T> subBuf( const Area &area )                                                   const { return subBuf( area.pos(), area.size() ); }
Unexecuted instantiation: vvdec::AreaBuf<short>::subBuf(vvdec::Area const&) const
Unexecuted instantiation: vvdec::AreaBuf<short const>::subBuf(vvdec::Area const&) const
188
0
  AreaBuf<      T> subBuf( const Position &pos, const Size &size )                                    { return AreaBuf<      T>( bufAt( pos  ), stride, size   ); }
189
0
  AreaBuf<const T> subBuf( const Position &pos, const Size &size )                              const { return AreaBuf<const T>( bufAt( pos  ), stride, size   ); }
Unexecuted instantiation: vvdec::AreaBuf<short>::subBuf(vvdec::Position const&, vvdec::Size const&) const
Unexecuted instantiation: vvdec::AreaBuf<short const>::subBuf(vvdec::Position const&, vvdec::Size const&) const
190
  AreaBuf<      T> subBuf( const int &x, const int &y, const unsigned &_w, const unsigned &_h )       { return AreaBuf<      T>( bufAt( x, y ), stride, _w, _h ); }
191
  AreaBuf<const T> subBuf( const int &x, const int &y, const unsigned &_w, const unsigned &_h ) const { return AreaBuf<const T>( bufAt( x, y ), stride, _w, _h ); }
192
};
193
194
typedef AreaBuf<      Pel>  PelBuf;
195
typedef AreaBuf<const Pel> CPelBuf;
196
197
typedef AreaBuf<      TCoeff>  CoeffBuf;
198
typedef AreaBuf<const TCoeff> CCoeffBuf;
199
200
typedef AreaBuf<TCoeffSig>        CoeffSigBuf;
201
typedef AreaBuf<const TCoeffSig> CCoeffSigBuf;
202
203
typedef AreaBuf<      MotionInfo>  MotionBuf;
204
typedef AreaBuf<const MotionInfo> CMotionBuf;
205
206
typedef AreaBuf<      LoopFilterParam>  LFPBuf;
207
typedef AreaBuf<const LoopFilterParam> CLFPBuf;
208
209
0
#define SIZE_AWARE_PER_EL_OP( OP, INC )                     \
210
0
if( ( width & 7 ) == 0 )                                    \
211
0
{                                                           \
212
0
  for( int y = 0; y < height; y++ )                         \
213
0
  {                                                         \
214
0
    for( int x = 0; x < width; x += 8 )                     \
215
0
    {                                                       \
216
0
      OP( x + 0 );                                          \
217
0
      OP( x + 1 );                                          \
218
0
      OP( x + 2 );                                          \
219
0
      OP( x + 3 );                                          \
220
0
      OP( x + 4 );                                          \
221
0
      OP( x + 5 );                                          \
222
0
      OP( x + 6 );                                          \
223
0
      OP( x + 7 );                                          \
224
0
    }                                                       \
225
0
                                                            \
226
0
    INC;                                                    \
227
0
  }                                                         \
228
0
}                                                           \
229
0
else if( ( width & 3 ) == 0 )                               \
230
0
{                                                           \
231
0
  for( int y = 0; y < height; y++ )                         \
232
0
  {                                                         \
233
0
    for( int x = 0; x < width; x += 4 )                     \
234
0
    {                                                       \
235
0
      OP( x + 0 );                                          \
236
0
      OP( x + 1 );                                          \
237
0
      OP( x + 2 );                                          \
238
0
      OP( x + 3 );                                          \
239
0
    }                                                       \
240
0
                                                            \
241
0
    INC;                                                    \
242
0
  }                                                         \
243
0
}                                                           \
244
0
else if( ( width & 1 ) == 0 )                               \
245
0
{                                                           \
246
0
  for( int y = 0; y < height; y++ )                         \
247
0
  {                                                         \
248
0
    for( int x = 0; x < width; x += 2 )                     \
249
0
    {                                                       \
250
0
      OP( x + 0 );                                          \
251
0
      OP( x + 1 );                                          \
252
0
    }                                                       \
253
0
                                                            \
254
0
    INC;                                                    \
255
0
  }                                                         \
256
0
}                                                           \
257
0
else                                                        \
258
0
{                                                           \
259
0
  for( int y = 0; y < height; y++ )                         \
260
0
  {                                                         \
261
0
    for( int x = 0; x < width; x++ )                        \
262
0
    {                                                       \
263
0
      OP( x );                                              \
264
0
    }                                                       \
265
0
                                                            \
266
0
    INC;                                                    \
267
0
  }                                                         \
268
0
}
269
270
271
template<typename TOP, typename TINC>
272
static inline void size_aware_pel_op( TOP op, TINC inc, int width, int height )
273
{
274
  if( ( width & 7 ) == 0 )
275
  {
276
    for( int y = 0; y < height; y++ )
277
    {
278
      for( int x = 0; x < width; x += 8 )
279
      {
280
        op( x + 0 );
281
        op( x + 1 );
282
        op( x + 2 );
283
        op( x + 3 );
284
        op( x + 4 );
285
        op( x + 5 );
286
        op( x + 6 );
287
        op( x + 7 );
288
      }
289
290
      inc();
291
    }
292
  }
293
  else if( ( width & 3 ) == 0 )
294
  {
295
    for( int y = 0; y < height; y++ )
296
    {
297
      for( int x = 0; x < width; x += 4 )
298
      {
299
        op( x + 0 );
300
        op( x + 1 );
301
        op( x + 2 );
302
        op( x + 3 );
303
      }
304
305
      inc();
306
    }
307
  }
308
  else if( ( width & 1 ) == 0 )
309
  {
310
    for( int y = 0; y < height; y++ )
311
    {
312
      for( int x = 0; x < width; x += 2 )
313
      {
314
        op( x + 0 );
315
        op( x + 1 );
316
      }
317
318
      inc();
319
    }
320
  }
321
  else
322
  {
323
    for( int y = 0; y < height; y++ )
324
    {
325
      for( int x = 0; x < width; x++ )
326
      {
327
        op( x );
328
      }
329
330
      inc();
331
    }
332
  }
333
}
334
335
template<>
336
void AreaBuf<MotionInfo>::fill( const MotionInfo& val );
337
338
template<typename T>
339
void AreaBuf<T>::fill(const T &val)
340
0
{
341
0
  if( T( 0 ) == val )
342
0
  {
343
0
    if( width == stride )
344
0
    {
345
0
      ::memset( buf, 0, width * height * sizeof( T ) );
346
0
    }
347
0
    else
348
0
    {
349
0
      T* dest = buf;
350
0
      size_t line = width * sizeof( T );
351
352
0
      for( unsigned y = 0; y < height; y++ )
353
0
      {
354
0
        ::memset( dest, 0, line );
355
356
0
        dest += stride;
357
0
      }
358
0
    }
359
0
  }
360
0
  else
361
0
  {
362
0
    if( width == stride )
363
0
    {
364
0
      std::fill_n( buf, width * height, val );
365
0
    }
366
0
    else
367
0
    {
368
0
      T* dest = buf;
369
370
0
      for( int y = 0; y < height; y++, dest += stride )
371
0
      {
372
0
        std::fill_n( dest, width, val );
373
0
      }
374
0
    }
375
0
  }
376
0
}
377
378
template<typename T>
379
void AreaBuf<T>::memset( const int val )
380
0
{
381
0
  if( width == stride )
382
0
  {
383
0
    ::memset( NO_WARNING_class_memaccess( buf ), val, width * height * sizeof( T ) );
384
0
  }
385
0
  else
386
0
  {
387
0
    T* dest = buf;
388
0
    size_t line = width * sizeof( T );
389
390
0
    for( int y = 0; y < height; y++ )
391
0
    {
392
0
      ::memset( NO_WARNING_class_memaccess( dest ), val, line );
393
394
0
      dest += stride;
395
0
    }
396
0
  }
397
0
}
Unexecuted instantiation: vvdec::AreaBuf<int>::memset(int)
Unexecuted instantiation: vvdec::AreaBuf<short>::memset(int)
Unexecuted instantiation: vvdec::AreaBuf<vvdec::MotionInfo>::memset(int)
398
399
#if ENABLE_SIMD_OPT_BUFFER
400
template<typename T>
401
void AreaBuf<T>::copyFrom( const AreaBuf<const T> &other )
402
0
{
403
#if !defined(__GNUC__) || __GNUC__ > 5
404
  static_assert( std::is_trivially_copyable<T>::value, "Type T is not trivially_copyable" );
405
#endif
406
407
0
  g_pelBufOP.copyBuffer( (const char *) other.buf, sizeof( T ) * other.stride, (char *) buf, sizeof( T ) * stride, sizeof( T ) * width, height );
408
0
}
409
#else
410
template<typename T>
411
void AreaBuf<T>::copyFrom( const AreaBuf<const T> &other )
412
{
413
#if !defined(__GNUC__) || __GNUC__ > 5
414
  static_assert( std::is_trivially_copyable<T>::value, "Type T is not trivially_copyable" );
415
#endif
416
417
  CHECK_FATAL( width  != other.width,  "Incompatible size" );
418
  CHECK_FATAL( height != other.height, "Incompatible size" );
419
420
  if( buf == other.buf )
421
  {
422
    return;
423
  }
424
425
  if( ptrdiff_t( width ) == stride && stride == other.stride )
426
  {
427
    memcpy( buf, other.buf, width * height * sizeof( T ) );
428
  }
429
  else
430
  {
431
          T* dst              =       buf;
432
    const T* src              = other.buf;
433
    const ptrdiff_t srcStride = other.stride;
434
435
    for( unsigned y = 0; y < height; y++ )
436
    {
437
      memcpy( dst, src, width * sizeof( T ) );
438
439
      dst += stride;
440
      src += srcStride;
441
    }
442
  }
443
}
444
#endif
445
446
447
template<typename T>
448
void AreaBuf<T>::subtract( const AreaBuf<const T> &other )
449
{
450
  CHECK( width  != other.width,  "Incompatible size" );
451
  CHECK( height != other.height, "Incompatible size" );
452
453
        T* dest =       buf;
454
  const T* subs = other.buf;
455
456
#define SUBS_INC        \
457
  dest +=       stride; \
458
  subs += other.stride; \
459
460
#define SUBS_OP( ADDR ) dest[ADDR] -= subs[ADDR]
461
462
  SIZE_AWARE_PER_EL_OP( SUBS_OP, SUBS_INC );
463
464
#undef SUBS_OP
465
#undef SUBS_INC
466
}
467
468
template<typename T>
469
void AreaBuf<T>::reconstruct( const AreaBuf<const T> &pred, const AreaBuf<const T> &resi, const ClpRng& clpRng )
470
{
471
  THROW_FATAL( "Type not supported" );
472
}
473
474
template<>
475
void AreaBuf<Pel>::reconstruct( const AreaBuf<const Pel> &pred, const AreaBuf<const Pel> &resi, const ClpRng& clpRng );
476
477
478
template<typename T>
479
void AreaBuf<T>::addAvg( const AreaBuf<const T> &other1, const AreaBuf<const T> &other2, const ClpRng& clpRng )
480
{
481
  THROW_FATAL( "Type not supported" );
482
}
483
484
template<>
485
void AreaBuf<Pel>::addAvg( const AreaBuf<const Pel> &other1, const AreaBuf<const Pel> &other2, const ClpRng& clpRng );
486
487
template<typename T>
488
void AreaBuf<T>::linearTransform( const int scale, const int shift, const int offset, bool bClip, const ClpRng& clpRng )
489
{
490
  THROW_FATAL( "Type not supported" );
491
}
492
493
template<>
494
void AreaBuf<Pel>::linearTransform( const int scale, const int shift, const int offset, bool bClip, const ClpRng& clpRng );
495
496
template<typename T>
497
void AreaBuf<T>::extendBorderPel( unsigned margin )
498
0
{
499
0
  T*        p = buf;
500
0
  int       h = height;
501
0
  int       w = width;
502
0
  ptrdiff_t s = stride;
503
504
0
  CHECK( ( w + 2 * margin ) > s, "Size of buffer too small to extend" );
505
  // do left and right margins
506
0
  for( int y = 0; y < h; y++ )
507
0
  {
508
0
    for( int x = 0; x < margin; x++ )
509
0
    {
510
0
      *( p - margin + x ) = p[0];
511
0
      p[w + x]            = p[w - 1];
512
0
    }
513
0
    p += s;
514
0
  }
515
516
  // p is now the (0,height) (bottom left of image within bigger picture
517
0
  p -= ( s + margin );
518
  // p is now the (-margin, height-1)
519
0
  for( int y = 0; y < margin; y++ )
520
0
  {
521
0
    ::memcpy( p + ( y + 1 ) * s, p, sizeof( T ) * ( w + ( margin << 1 ) ) );
522
0
  }
523
524
  // pi is still (-marginX, height-1)
525
0
  p -= ( ( h - 1 ) * s );
526
  // pi is now (-marginX, 0)
527
0
  for( int y = 0; y < margin; y++ )
528
0
  {
529
0
    ::memcpy( p - ( y + 1 ) * s, p, sizeof( T ) * ( w + ( margin << 1 ) ) );
530
0
  }
531
0
}
532
533
template<typename T>
534
void AreaBuf<T>::extendBorderPel(unsigned margin, bool left, bool right, bool top, bool bottom)
535
0
{
536
0
  CHECK( ( width + left*margin + right*margin) > stride, "Size of buffer too small to extend" );
537
  // do left and right margins
538
539
0
  if( left && right )
540
0
  {
541
0
    T* p = buf;
542
0
    for( int y = 0; y < height; y++ )
543
0
    {
544
0
      for( int x = 0; x < margin; x++ )
545
0
      {
546
0
        p[-(int)margin + x] = p[0];
547
0
        p[width + x]   = p[width - 1];
548
0
      }
549
0
      p += stride;
550
0
    }
551
0
  }
552
553
0
  else if( left )
554
0
  {
555
0
    T* p = buf;
556
0
    for( int y = 0; y < height; y++ )
557
0
    {
558
0
      for( int x = 0; x < margin; x++ )
559
0
      {
560
0
        p[-(int)margin + x] = p[0];
561
0
      }
562
0
      p += stride;
563
0
    }
564
0
  }
565
566
0
  else if( right )
567
0
  {
568
0
    T* p = buf;
569
0
    for( int y = 0; y < height; y++ )
570
0
    {
571
0
      for( int x = 0; x < margin; x++ )
572
0
      {
573
0
        p[width + x] = p[width - 1];
574
0
      }
575
0
      p += stride;
576
0
    }
577
0
  }
578
579
0
  const int copylen = width + ( left ? margin : 0 ) + ( right ? margin : 0 );
580
0
  if( bottom )
581
0
  {
582
0
    T* p = buf + stride * height;
583
0
    if( left )
584
0
      p -= margin;
585
586
    // p is now the (-margin, height)
587
0
    for( int y = 0; y < margin; y++ )
588
0
    {
589
0
      ::memcpy( p + y * stride, p - stride, sizeof( T ) * copylen );
590
0
    }
591
0
  }
592
593
0
  if( top )
594
0
  {
595
0
    T* p = buf;
596
0
    if( left )
597
0
      p -= margin;
598
599
    // pi is now (-marginX, 0)
600
0
    for( int y = -(int)margin; y < 0; y++ )
601
0
    {
602
0
      ::memcpy( p + y * stride, p, sizeof( T ) * copylen );
603
0
    }
604
0
  }
605
0
}
606
607
template<typename T>
608
void AreaBuf<T>::padBorderPel( unsigned marginX, unsigned marginY, int dir )
609
0
{
610
0
  T*   p = buf;
611
0
  auto s = stride;
612
0
  int  h = height;
613
0
  int  w = width;
614
615
0
  CHECK( w  > s, "Size of buffer too small to extend" );
616
617
  // top-left margin
618
0
  if ( dir == 1 )
619
0
  {
620
0
    for( int y = 0; y < marginY; y++ )
621
0
    {
622
0
      for( int x = 0; x < marginX; x++ )
623
0
      {
624
0
        p[x] = p[marginX];
625
0
      }
626
0
      p += s;
627
0
    }
628
0
  }
629
630
  // bottom-right margin
631
0
  if ( dir == 2 )
632
0
  {
633
0
    p = buf + s * ( h - marginY ) + w - marginX;
634
635
0
    for( int y = 0; y < marginY; y++ )
636
0
    {
637
0
      for( int x = 0; x < marginX; x++ )
638
0
      {
639
0
        p[x] = p[-1];
640
0
      }
641
0
      p += s;
642
0
    }
643
0
  }
644
0
}
645
646
#if ENABLE_SIMD_OPT_BUFFER && defined(TARGET_SIMD_X86)
647
template<> void AreaBuf<Pel>::transposedFrom( const AreaBuf<const Pel> &other );
648
#endif
649
650
template<typename T>
651
void AreaBuf<T>::transposedFrom( const AreaBuf<const T> &other )
652
{
653
  CHECK( width * height != other.width * other.height, "Incompatible size" );
654
655
        T* dst  =       buf;
656
  const T* src  = other.buf;
657
  width         = other.height;
658
  height        = other.width;
659
  stride        = stride < width ? width : stride;
660
661
  for( unsigned y = 0; y < other.height; y++ )
662
  {
663
    for( unsigned x = 0; x < other.width; x++ )
664
    {
665
      dst[y + x*stride] = src[x + y * other.stride];
666
    }
667
  }
668
}
669
670
#ifndef DONT_UNDEF_SIZE_AWARE_PER_EL_OP
671
#undef SIZE_AWARE_PER_EL_OP
672
#endif // !DONT_UNDEF_SIZE_AWARE_PER_EL_OP
673
674
// ---------------------------------------------------------------------------
675
// UnitBuf struct
676
// ---------------------------------------------------------------------------
677
678
struct UnitArea;
679
680
template<typename T>
681
struct UnitBuf
682
{
683
  typedef static_vector<AreaBuf<T>,       MAX_NUM_COMPONENT> UnitBufBuffers;
684
685
  ChromaFormat chromaFormat;
686
  UnitBufBuffers bufs;
687
688
0
  UnitBuf() : chromaFormat( NUM_CHROMA_FORMAT ) { }
Unexecuted instantiation: vvdec::UnitBuf<short>::UnitBuf()
Unexecuted instantiation: vvdec::UnitBuf<short const>::UnitBuf()
689
  UnitBuf( const ChromaFormat &_chromaFormat, const UnitBufBuffers&  _bufs ) : chromaFormat( _chromaFormat ), bufs( _bufs ) { }
690
  UnitBuf( const ChromaFormat &_chromaFormat,       UnitBufBuffers&& _bufs ) : chromaFormat( _chromaFormat ), bufs( std::forward<UnitBufBuffers>( _bufs ) ) { }
691
0
  UnitBuf( const ChromaFormat &_chromaFormat, const AreaBuf<T>  &blkY ) : chromaFormat( _chromaFormat ), bufs{ blkY } { }
692
0
  UnitBuf( const ChromaFormat &_chromaFormat,       AreaBuf<T> &&blkY ) : chromaFormat( _chromaFormat ), bufs{ std::forward<AreaBuf<T> >(blkY) } { }
693
0
  UnitBuf( const ChromaFormat &_chromaFormat, const AreaBuf<T>  &blkY, const AreaBuf<T>  &blkCb, const AreaBuf<T>  &blkCr ) : chromaFormat( _chromaFormat ), bufs{ blkY, blkCb, blkCr } { if( chromaFormat == CHROMA_400 ) bufs.resize( 1 ); }
694
0
  UnitBuf( const ChromaFormat &_chromaFormat,       AreaBuf<T> &&blkY,       AreaBuf<T> &&blkCb,       AreaBuf<T> &&blkCr ) : chromaFormat( _chromaFormat ), bufs{ std::forward<AreaBuf<T> >(blkY), std::forward<AreaBuf<T> >(blkCb), std::forward<AreaBuf<T> >(blkCr) } { if( chromaFormat == CHROMA_400 ) bufs.resize( 1 ); }
695
696
  UnitBuf( const UnitBuf& other )  = default;
697
  UnitBuf(       UnitBuf&& other ) = default;
698
  UnitBuf& operator=( const UnitBuf& other )  = default;
699
  UnitBuf& operator=(       UnitBuf&& other ) = default;
700
701
  // conversion from UnitBuf<const T> to UnitBuf<T>
702
  template<bool T_IS_COST = std::is_const<T>::value>
703
0
  UnitBuf( const UnitBuf<typename std::remove_const_t<T>>& other, std::enable_if_t<T_IS_COST>* = 0 ) : chromaFormat( other.chromaFormat ), bufs( other.bufs ) { }
704
705
0
        AreaBuf<T>& get( const ComponentID comp )        { return bufs[comp]; }
706
0
  const AreaBuf<T>& get( const ComponentID comp )  const { return bufs[comp]; }
Unexecuted instantiation: vvdec::UnitBuf<short>::get(vvdec::ComponentID) const
Unexecuted instantiation: vvdec::UnitBuf<short const>::get(vvdec::ComponentID) const
707
708
0
        AreaBuf<T>& Y()        { return bufs[0]; }
709
0
  const AreaBuf<T>& Y()  const { return bufs[0]; }
710
0
        AreaBuf<T>& Cb()       { return bufs[1]; }
711
  const AreaBuf<T>& Cb() const { return bufs[1]; }
712
0
        AreaBuf<T>& Cr()       { return bufs[2]; }
713
  const AreaBuf<T>& Cr() const { return bufs[2]; }
714
715
  void fill                 ( const T &val );
716
  void copyFrom             ( const UnitBuf<const T> &other );
717
  void reconstruct          ( const UnitBuf<const T> &pred, const UnitBuf<const T> &resi, const ClpRngs& clpRngs );
718
  void subtract             ( const UnitBuf<const T> &other );
719
  void addWeightedAvg       ( const UnitBuf<      T> &other1, const UnitBuf<      T> &other2, const ClpRngs& clpRngs, const uint8_t bcwIdx = BCW_DEFAULT, const bool chromaOnly = false, const bool lumaOnly = false);
720
  void addAvg               ( const UnitBuf<      T> &other1, const UnitBuf<      T> &other2, const ClpRngs& clpRngs, const bool chromaOnly = false, const bool lumaOnly = false);
721
  void extendBorderPel      ( unsigned margin );
722
  void extendBorderPel      ( unsigned margin, bool left, bool right, bool top, bool bottom );
723
  void padBorderPel         ( unsigned margin, int dir );
724
725
        UnitBuf<      T> subBuf (const Area& subArea);
726
  const UnitBuf<const T> subBuf (const Area& subArea) const;
727
        UnitBuf<      T> subBuf (const UnitArea& subArea);
728
  const UnitBuf<const T> subBuf (const UnitArea& subArea) const;
729
  void colorSpaceConvert    ( const UnitBuf<T> &other, const ClpRng& clpRng );
730
731
  void writeToFile( std::string filename ) const;   // for debug purposes
732
};
733
734
typedef UnitBuf<      Pel>  PelUnitBuf;
735
typedef UnitBuf<const Pel> CPelUnitBuf;
736
737
typedef UnitBuf<      TCoeff>  CoeffUnitBuf;
738
typedef UnitBuf<const TCoeff> CCoeffUnitBuf;
739
740
}   // namespace vvdec
741
742
#include <Unit.h>
743
744
namespace vvdec
745
{
746
template<typename T>
747
void UnitBuf<T>::fill( const T &val )
748
{
749
  for( unsigned i = 0; i < bufs.size(); i++ )
750
  {
751
    bufs[i].fill( val );
752
  }
753
}
754
755
template<typename T>
756
void UnitBuf<T>::copyFrom( const UnitBuf<const T> &other )
757
0
{
758
0
  CHECK( chromaFormat != other.chromaFormat, "Incompatible formats" );
759
760
0
  for( unsigned i = 0; i < bufs.size(); i++ )
761
0
  {
762
0
    bufs[i].copyFrom( other.bufs[i] );
763
0
  }
764
0
}
765
766
767
768
template<typename T>
769
void UnitBuf<T>::subtract( const UnitBuf<const T> &other )
770
{
771
  CHECK( chromaFormat != other.chromaFormat, "Incompatible formats" );
772
773
  for( unsigned i = 0; i < bufs.size(); i++ )
774
  {
775
    bufs[i].subtract( other.bufs[i] );
776
  }
777
}
778
779
template<typename T>
780
void UnitBuf<T>::reconstruct(const UnitBuf<const T> &pred, const UnitBuf<const T> &resi, const ClpRngs& clpRngs)
781
{
782
  CHECK( chromaFormat != pred.chromaFormat, "Incompatible formats" );
783
  CHECK( chromaFormat != resi.chromaFormat, "Incompatible formats" );
784
785
  for( unsigned i = 0; i < bufs.size(); i++ )
786
  {
787
    bufs[i].reconstruct( pred.bufs[i], resi.bufs[i], clpRngs );
788
  }
789
}
790
791
template<typename T>
792
void UnitBuf<T>::addWeightedAvg(const UnitBuf<T> &other1, const UnitBuf<T> &other2, const ClpRngs& clpRngs, const uint8_t bcwIdx /* = BCW_DEFAULT */, const bool chromaOnly /* = false */, const bool lumaOnly /* = false */)
793
0
{
794
0
  const size_t istart = chromaOnly ? 1 : 0;
795
0
  const size_t iend   = lumaOnly   ? 1 : bufs.size();
796
797
0
  CHECK(lumaOnly && chromaOnly, "should not happen");
798
799
0
  for(size_t i = istart; i < iend; i++)
800
0
  {
801
0
    bufs[i].addWeightedAvg(other1.bufs[i], other2.bufs[i], clpRngs, bcwIdx);
802
0
  }
803
0
}
804
805
template<typename T>
806
void UnitBuf<T>::addAvg(const UnitBuf<T> &other1, const UnitBuf<T> &other2, const ClpRngs& clpRngs, const bool chromaOnly /* = false */, const bool lumaOnly /* = false */)
807
0
{
808
0
  const size_t istart = chromaOnly ? 1 : 0;
809
0
  const size_t iend   = lumaOnly   ? 1 : bufs.size();
810
811
0
  CHECK( lumaOnly && chromaOnly, "should not happen" );
812
813
0
  for( size_t i = istart; i < iend; i++)
814
0
  {
815
0
    bufs[i].addAvg( other1.bufs[i], other2.bufs[i], clpRngs );
816
0
  }
817
0
}
818
819
template<typename T>
820
void UnitBuf<T>::colorSpaceConvert( const UnitBuf<T> &other, const ClpRng& clpRng )
821
{
822
  THROW_FATAL( "Type not supported" );
823
}
824
825
template<>
826
void UnitBuf<Pel>::colorSpaceConvert( const UnitBuf<Pel> &other, const ClpRng& clpRng );
827
828
template<typename T>
829
void UnitBuf<T>::extendBorderPel( unsigned margin )
830
0
{
831
0
  for( unsigned i = 0; i < bufs.size(); i++ )
832
0
  {
833
0
    bufs[i].extendBorderPel( margin );
834
0
  }
835
0
}
836
837
template<typename T>
838
void UnitBuf<T>::extendBorderPel(unsigned margin, bool left, bool right, bool top, bool bottom)
839
0
{
840
0
  for( unsigned i = 0; i < bufs.size(); i++ )
841
0
  {
842
0
    bufs[i].extendBorderPel( margin, left, right, top, bottom );
843
0
  }
844
0
}
845
846
template<typename T>
847
void UnitBuf<T>::padBorderPel( unsigned margin, int dir )
848
0
{
849
0
  for( unsigned i = 0; i < bufs.size(); i++ )
850
0
  {
851
0
    bufs[i].padBorderPel( margin >> getComponentScaleX( ComponentID( i ), chromaFormat ), margin >> getComponentScaleY( ComponentID( i ), chromaFormat ), dir );
852
0
  }
853
0
}
854
855
template<typename T>
856
UnitBuf<T> UnitBuf<T>::subBuf( const UnitArea& subArea )
857
0
{
858
0
  UnitBuf<T> subBuf;
859
0
  subBuf.chromaFormat = chromaFormat;
860
0
  unsigned blockIdx = 0;
861
862
0
  for( auto &subAreaBuf : bufs )
863
0
  {
864
0
    subBuf.bufs.push_back( subAreaBuf.subBuf( subArea.blocks[blockIdx].pos(), subArea.blocks[blockIdx].size() ) );
865
0
    blockIdx++;
866
0
  }
867
868
0
  return subBuf;
869
0
}
870
871
872
template<typename T>
873
const UnitBuf<const T> UnitBuf<T>::subBuf( const UnitArea& subArea ) const
874
0
{
875
0
  UnitBuf<const T> subBuf;
876
0
  subBuf.chromaFormat = chromaFormat;
877
0
  unsigned blockIdx = 0;
878
0
879
0
  for( const auto &subAreaBuf : bufs )
880
0
  {
881
0
    subBuf.bufs.push_back( subAreaBuf.subBuf( subArea.blocks[blockIdx].pos(), subArea.blocks[blockIdx].size() ) );
882
0
    blockIdx++;
883
0
  }
884
0
885
0
  return subBuf;
886
0
}
887
888
template<typename T>
889
UnitBuf<T> UnitBuf<T>::subBuf( const Area & subArea )
890
0
{
891
0
  UnitBuf<T> subBuf;
892
0
  subBuf.chromaFormat = chromaFormat;
893
0
  unsigned blockIdx = 0;
894
895
0
  for( auto &subAreaBuf : bufs )
896
0
  {
897
0
    const int scaleX = getComponentScaleX( ComponentID(blockIdx), chromaFormat);
898
0
    const int scaleY = getComponentScaleY( ComponentID(blockIdx), chromaFormat);
899
0
    const Area scaledArea( subArea.pos().x >> scaleX, subArea.pos().y >> scaleY, subArea.size().width >> scaleX, subArea.size().height >> scaleY );
900
0
    subBuf.bufs.push_back( subAreaBuf.subBuf( scaledArea.pos(), scaledArea.size() ) );
901
0
    blockIdx++;
902
0
  }
903
904
0
  return subBuf;
905
0
}
906
907
template<typename T>
908
const UnitBuf<const T> UnitBuf<T>::subBuf( const Area & subArea ) const
909
0
{
910
0
  UnitBuf<T> subBuf;
911
0
  subBuf.chromaFormat = chromaFormat;
912
0
  unsigned blockIdx = 0;
913
914
0
  for( auto &subAreaBuf : bufs )
915
0
  {
916
0
    const int scaleX = getComponentScaleX( ComponentID(blockIdx), chromaFormat);
917
0
    const int scaleY = getComponentScaleY( ComponentID(blockIdx), chromaFormat);
918
0
    const Area scaledArea( subArea.pos().x >> scaleX, subArea.pos().y >> scaleY, subArea.size().width >> scaleX, subArea.size().height >> scaleY );
919
0
    subBuf.bufs.push_back( subAreaBuf.subBuf( scaledArea.pos(), scaledArea.size() ) );
920
0
    blockIdx++;
921
0
  }
922
923
0
  return subBuf;
924
0
}
925
926
// ---------------------------------------------------------------------------
927
// PelStorage struct (PelUnitBuf which allocates its own memory)
928
// ---------------------------------------------------------------------------
929
930
struct UnitArea;
931
struct CompArea;
932
933
struct PelStorage : public PelUnitBuf
934
{
935
  PelStorage();
936
  ~PelStorage();
937
938
  void swap( PelStorage& other );
939
  void createFromBuf( PelUnitBuf buf );
940
  void create( const UnitArea &_unit );
941
  void create( const ChromaFormat _chromaFormat, const Size& _size, const unsigned _maxCUSize = 0, const unsigned _margin = 0, const unsigned _alignment = 0, const bool _scaleChromaMargin = true, const UserAllocator* userAlloc = nullptr );
942
  void destroy();
943
944
         PelBuf getBuf( const CompArea &blk );
945
  const CPelBuf getBuf( const CompArea &blk ) const;
946
947
         PelBuf getBuf( const ComponentID CompID );
948
  const CPelBuf getBuf( const ComponentID CompID ) const;
949
950
         PelUnitBuf getBuf( const UnitArea &unit );
951
  const CPelUnitBuf getBuf( const UnitArea &unit ) const;
952
0
  Pel *getOrigin( const int id ) const { return m_origin[id]; }
953
0
  PelBuf getOriginBuf( const int id ) { return PelBuf( m_origin[id], m_origSi[id] ); }
954
955
0
  Size  getBufSize( const int id )      const { return  m_origSi[id];     }
956
0
  void *getBufAllocator( const int id ) const { return m_allocator[id];   }
957
0
  bool  isExternAllocator()             const { return m_externAllocator; }
958
959
0
  const UserAllocator* getUserAllocator() const { return m_userAlloc; }
960
961
private:
962
963
  Size    m_origSi[MAX_NUM_COMPONENT];
964
  Pel    *m_origin[MAX_NUM_COMPONENT];
965
  void   *m_allocator[MAX_NUM_COMPONENT];
966
  bool    m_externAllocator = false;
967
  const UserAllocator* m_userAlloc  = nullptr;
968
};
969
970
}   // namespace vvdec