Coverage Report

Created: 2026-04-01 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vvenc/source/Lib/CommonLib/Picture.cpp
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) 2019-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVenC 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
44
/** \file     Picture.cpp
45
 *  \brief    Description of a coded picture
46
 */
47
48
#include "Picture.h"
49
#include "SEI.h"
50
51
#include <algorithm>
52
#include <math.h>
53
54
//! \ingroup CommonLib
55
//! \{
56
57
namespace vvenc {
58
59
// ---------------------------------------------------------------------------
60
// picture methods
61
// ---------------------------------------------------------------------------
62
63
64
65
66
// ====================================================================================================================
67
// AMaxBT block statistics
68
// ====================================================================================================================
69
70
71
void BlkStat::storeBlkSize( const Picture& pic )
72
0
{
73
0
  const Slice& slice = *(pic.slices[ 0 ]);
74
75
0
  ::memset( m_uiBlkSize, 0, sizeof( m_uiBlkSize ) );
76
0
  ::memset( m_uiNumBlk,  0, sizeof( m_uiNumBlk ) );
77
78
0
  if ( ! slice.isIRAP() )
79
0
  {
80
0
    const int refLayer = std::min<int>( slice.TLayer, NUM_AMAXBT_LAYER - 1 );
81
0
    for ( const CodingUnit *cu : pic.cs->cus )
82
0
    {
83
0
      m_uiBlkSize[ refLayer ] += cu->Y().area();
84
0
      m_uiNumBlk [ refLayer ] += 1;
85
0
    }
86
0
  }
87
0
}
88
89
void BlkStat::updateMaxBT( const Slice& slice, const BlkStat& blkStat )
90
0
{
91
0
  if ( ! slice.isIRAP() )
92
0
  {
93
0
    const int refLayer = std::min<int>( slice.TLayer, NUM_AMAXBT_LAYER - 1 );
94
0
    m_uiBlkSize[ refLayer ] += blkStat.m_uiBlkSize[ refLayer ];
95
0
    m_uiNumBlk [ refLayer ] += blkStat.m_uiNumBlk [ refLayer ];
96
0
  }
97
0
}
98
99
void BlkStat::setSliceMaxBT( Slice& slice )
100
0
{
101
0
  if( ! slice.isIRAP() )
102
0
  {
103
0
    const int refLayer = std::min<int>( slice.TLayer, NUM_AMAXBT_LAYER - 1 );
104
0
    if( m_bResetAMaxBT && slice.poc > m_uiPrevISlicePOC )
105
0
    {
106
0
      ::memset( m_uiBlkSize, 0, sizeof( m_uiBlkSize ) );
107
0
      ::memset( m_uiNumBlk,  0, sizeof( m_uiNumBlk ) );
108
0
      m_bResetAMaxBT = false;
109
0
    }
110
111
0
    if( refLayer >= 0 && m_uiNumBlk[ refLayer ] != 0 )
112
0
    {
113
0
      slice.picHeader->splitConsOverride = true;
114
0
      double dBlkSize = sqrt( ( double ) m_uiBlkSize[refLayer] / m_uiNumBlk[refLayer] );
115
0
      if( dBlkSize < AMAXBT_TH32 || slice.sps->CTUSize == 32 )
116
0
      {
117
0
        slice.picHeader->maxBTSize[1] = ( 32 > MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER : 32 );
118
0
      }
119
0
      else if( dBlkSize < AMAXBT_TH64 || slice.sps->CTUSize == 64 )
120
0
      {
121
0
        slice.picHeader->maxBTSize[1] = ( 64 > MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER : 64 );
122
0
      }
123
0
      else
124
0
      {
125
0
        slice.picHeader->maxBTSize[1] = ( 128 > MAX_BT_SIZE_INTER ? MAX_BT_SIZE_INTER : 128 );
126
0
      }
127
128
0
      m_uiBlkSize[ refLayer ] = 0;
129
0
      m_uiNumBlk [ refLayer ] = 0;
130
0
    }
131
0
  }
132
0
  else
133
0
  {
134
0
    if( m_bResetAMaxBT )
135
0
    {
136
0
      ::memset( m_uiBlkSize, 0, sizeof( m_uiBlkSize ) );
137
0
      ::memset( m_uiNumBlk,  0, sizeof( m_uiNumBlk ) );
138
0
    }
139
140
0
    m_uiPrevISlicePOC = slice.poc;
141
0
    m_bResetAMaxBT    = true;
142
0
  }
143
0
}
144
145
146
// ====================================================================================================================
147
// Picture
148
// ====================================================================================================================
149
150
151
Picture::Picture()
152
0
    : cs                  ( nullptr )
153
0
    , vps                 ( nullptr )
154
0
    , dci                 ( nullptr )
155
0
    , picApsMap           ( MAX_NUM_APS * MAX_NUM_APS_TYPE )
156
0
    , isInitDone          ( false )
157
0
    , isReconstructed     ( false )
158
0
    , isBorderExtended    ( false )
159
0
    , isReferenced        ( false )
160
0
    , isNeededForOutput   ( false )
161
0
    , isFinished          ( false )
162
0
    , isLongTerm          ( false )
163
0
    , isFlush             ( false )
164
0
    , isInProcessList     ( false )
165
0
    , precedingDRAP       ( false )
166
0
    , gopEntry            ( nullptr )
167
0
    , refCounter          ( 0 )
168
0
    , poc                 ( 0 )
169
0
    , TLayer              ( std::numeric_limits<uint32_t>::max() )
170
0
    , layerId             ( 0 )
171
0
    , isSubPicBorderSaved (false)
172
0
    , sliceDataNumBins    ( 0 )
173
0
    , cts                 ( 0 )
174
0
    , ctsValid            ( false )
175
0
    , picsInMissing       ( 0 )
176
0
    , picOutOffset        ( 0 )
177
0
    , isPreAnalysis       ( false )
178
0
    , m_picShared         ( nullptr )
179
0
    , gopAdaptedQP        ( 0 )
180
0
    , force2ndOrder       ( false )
181
0
    , isSceneCutGOP       ( false )
182
0
    , isSceneCutCheckAdjQP( false )
183
0
    , isMeanQPLimited     ( false )
184
0
    , picInitialQP        ( -1 )
185
0
    , picInitialLambda    ( -1.0 )
186
0
    , picMemorySTA        ( -1 )
187
0
    , picVA               ()
188
0
    , isSccWeak           ( false )
189
0
    , isSccStrong         ( false )
190
0
    , useME               ( false )
191
0
    , useMCTF             ( false )
192
0
    , useTS               ( false )
193
0
    , useBDPCM            ( false )
194
0
    , useIBC              ( false )
195
0
    , useLMCS             ( false )
196
0
    , useSAO              ( false )
197
0
    , useNumRefs          ( false )
198
0
    , useFastMrg          ( 0 )
199
0
    , useQtbttSpeedUpMode ( 0 )
200
0
    , actualHeadBits      ( 0 )
201
0
    , actualTotalBits     ( 0 )
202
0
    , encRCPic            ( nullptr )
203
0
    , picApsGlobal        ( nullptr )
204
0
    , refApsGlobal        ( nullptr )
205
0
{
206
0
  std::fill_n( m_sharedBufs, (int)NUM_PIC_TYPES, nullptr );
207
0
  std::fill_n( m_bufsOrigPrev, NUM_QPA_PREV_FRAMES, nullptr );
208
0
}
209
210
void Picture::create( ChromaFormat _chromaFormat, const Size& size, unsigned _maxCUSize, unsigned _margin, bool _decoder )
211
0
{
212
0
  UnitArea::operator=( UnitArea( _chromaFormat, Area( Position{ 0, 0 }, size ) ) );
213
0
  margin            =  _margin;
214
215
0
  if( _decoder )
216
0
  {
217
0
    m_picBufs[ PIC_RESIDUAL   ].create( _chromaFormat, Area( 0, 0, _maxCUSize, _maxCUSize ) );
218
0
    m_picBufs[ PIC_PREDICTION ].create( _chromaFormat, Area( 0, 0, _maxCUSize, _maxCUSize ) );
219
0
  }
220
0
}
221
222
void Picture::reset()
223
0
{
224
  // reset picture
225
0
  isInitDone           = false;
226
0
  isReconstructed      = false;
227
0
  isBorderExtended     = false;
228
0
  isReferenced         = true;
229
0
  isNeededForOutput    = true;
230
0
  isFinished           = false;
231
0
  isLongTerm           = false;
232
0
  isFlush              = false;
233
0
  isInProcessList      = false;
234
0
  isMeanQPLimited      = false;
235
0
  precedingDRAP        = false;
236
237
0
  gopEntry             = nullptr;
238
0
  refCounter           = 0;
239
0
  poc                  = -1;
240
0
  TLayer               = std::numeric_limits<uint32_t>::max();
241
0
  gopAdaptedQP         = 0;
242
0
  force2ndOrder        = false;
243
0
  isSceneCutGOP        = false;
244
0
  isSceneCutCheckAdjQP = false;
245
0
  actualHeadBits       = 0;
246
0
  actualTotalBits      = 0;
247
0
  encRCPic             = nullptr;
248
0
  picApsGlobal         = nullptr;
249
0
  refApsGlobal         = nullptr;
250
251
0
  cts                  = 0;
252
0
  ctsValid             = false;
253
0
  picsInMissing        = 0;
254
0
  picOutOffset         = 0;
255
256
0
  picVA.reset();
257
258
0
  std::fill_n( m_sharedBufs, (int)NUM_PIC_TYPES, nullptr );
259
0
  std::fill_n( m_bufsOrigPrev, NUM_QPA_PREV_FRAMES, nullptr );
260
261
0
  if( m_tileColsDone )
262
0
    std::fill( m_tileColsDone->begin(), m_tileColsDone->end(), 0 );
263
264
0
  encTime.resetTimer();
265
0
}
266
267
void Picture::destroy( bool bPicHeader )
268
0
{
269
0
  for (uint32_t t = 0; t < NUM_PIC_TYPES; t++)
270
0
  {
271
0
    m_picBufs[  t ].destroy();
272
0
  }
273
0
  if( cs )
274
0
  {
275
0
    if( bPicHeader && cs->picHeader )
276
0
    {
277
0
      delete cs->picHeader;
278
0
    }
279
0
    cs->picHeader = nullptr;
280
0
    cs->destroy();
281
0
    delete cs;
282
0
    cs = nullptr;
283
0
  }
284
285
0
  for( auto &ps : slices )
286
0
  {
287
0
    delete ps;
288
0
  }
289
0
  slices.clear();
290
291
0
  for( auto &psei : SEIs )
292
0
  {
293
0
    delete psei;
294
0
  }
295
296
0
  delete m_tileColsDone;
297
298
0
  SEIs.clear();
299
0
}
300
301
void Picture::linkSharedBuffers( PelStorage* origBuf, PelStorage* filteredBuf, PelStorage* prevOrigBufs[ NUM_QPA_PREV_FRAMES ], PicShared* picShared )
302
0
{
303
0
  m_picShared                      = picShared;
304
0
  m_sharedBufs[ PIC_ORIGINAL ]     = origBuf;
305
0
  m_sharedBufs[ PIC_ORIGINAL_RSP ] = filteredBuf;
306
0
  for( int i = 0; i < NUM_QPA_PREV_FRAMES; i++ )
307
0
    m_bufsOrigPrev[ i ] = prevOrigBufs[ i ];
308
0
}
309
310
void Picture::releasePrevBuffers()
311
0
{
312
0
  for( int i = 0; i < NUM_QPA_PREV_FRAMES; i++ )
313
0
    m_bufsOrigPrev[ i ] = nullptr;
314
0
}
315
316
void Picture::releaseSharedBuffers()
317
0
{
318
0
  m_picShared                      = nullptr;
319
0
  m_sharedBufs[ PIC_ORIGINAL ]     = nullptr;
320
0
  m_sharedBufs[ PIC_ORIGINAL_RSP ] = nullptr;
321
0
}
322
323
void Picture::createTempBuffers( unsigned _maxCUSize )
324
0
{
325
0
  CHECK( !cs, "Coding structure is required a this point!" );
326
327
  // SAO reads/writes +-1 sample, especially SIMD
328
0
  m_picBufs[PIC_SAO_TEMP].create( chromaFormat, Y(), cs->pcv->maxCUSize, 2, MEMORY_ALIGN_DEF_SIZE );
329
330
0
  if( cs ) cs->rebindPicBufs();
331
0
}
332
333
void Picture::destroyTempBuffers()
334
0
{
335
0
  m_picBufs[PIC_SAO_TEMP].destroy();
336
337
0
  if( cs ) cs->rebindPicBufs();
338
0
}
339
340
0
const CPelBuf     Picture::getOrigBufPrev (const CompArea &blk, const PrevFrameType type) const { return (m_bufsOrigPrev[ type ] && blk.valid() ? m_bufsOrigPrev[ type ]->getBuf (blk) : PelBuf()); }
341
0
const CPelUnitBuf Picture::getOrigBufPrev (const PrevFrameType type) const { return (m_bufsOrigPrev[ type ] ? *m_bufsOrigPrev[ type ] : PelUnitBuf()); }
342
0
const CPelBuf     Picture::getOrigBufPrev (const ComponentID compID, const PrevFrameType type) const { return (m_bufsOrigPrev[ type ] ? m_bufsOrigPrev[ type ]->getBuf (compID) : PelBuf()); }
343
344
void Picture::finalInit( const VPS& _vps, const SPS& sps, const PPS& pps, PicHeader* picHeader, XUCache& unitCache, std::mutex* mutex, APS** alfAps, APS* lmcsAps )
345
0
{
346
0
  for( auto &sei : SEIs )
347
0
  {
348
0
    delete sei;
349
0
  }
350
0
  SEIs.clear();
351
352
0
  for( size_t i = 0; i < slices.size(); i++ )
353
0
  {
354
0
    delete slices[i];
355
0
  }
356
0
  slices.clear();
357
0
  ctuSlice.clear();
358
0
  ctuSlice.resize( pps.pcv->sizeInCtus, nullptr );
359
360
0
  const ChromaFormat chromaFormatIDC = sps.chromaFormatIdc;
361
0
  const int          iWidth  = pps.picWidthInLumaSamples;
362
0
  const int          iHeight = pps.picHeightInLumaSamples;
363
364
0
  if( cs )
365
0
  {
366
0
    CHECK( cs->sps != &sps,  "picture initialization error: sps changed" );
367
0
    CHECK( cs->vps != &_vps, "picture initialization error: vps changed" );
368
0
  }
369
0
  else
370
0
  {
371
0
    cs = new CodingStructure( unitCache, mutex );
372
0
    cs->pps = &pps;
373
0
    cs->sps = &sps;
374
0
    cs->vps = &_vps;
375
0
    cs->createPicLevel( UnitArea( chromaFormatIDC, Area( 0, 0, iWidth, iHeight )), pps.pcv );
376
0
  }
377
378
0
  cs->picture   = this;
379
0
  cs->lumaCS    = cs;
380
0
  cs->slice     = nullptr;  // the slices for this picture have not been set at this point. update cs->slice after swapSliceObject()
381
0
  cs->picHeader = picHeader;
382
0
  if( alfAps )
383
0
  {
384
0
    memcpy( cs->alfAps, alfAps, sizeof( cs->alfAps ) );
385
0
  }
386
0
  cs->lmcsAps = lmcsAps;
387
0
  cs->pcv     = pps.pcv;
388
0
  vps         = &_vps;
389
0
  dci         = nullptr;
390
391
0
  if( !m_picBufs[PIC_RECONSTRUCTION].valid() )
392
0
  {
393
0
    m_picBufs[ PIC_RECONSTRUCTION ].create( chromaFormat, Area( lumaPos(), lumaSize() ), sps.CTUSize, margin, MEMORY_ALIGN_DEF_SIZE );
394
0
  }
395
0
  if( !m_tileColsDone )
396
0
  {
397
0
    m_tileColsDone = new std::vector<std::atomic<int>> ( pps.pcv->heightInCtus );
398
0
  }
399
0
  std::fill( m_tileColsDone->begin(), m_tileColsDone->end(), 0 );
400
401
0
  sliceDataStreams.clear();
402
0
  sliceDataNumBins = 0;
403
0
}
404
405
void Picture::setSccFlags( const VVEncCfg* encCfg )
406
0
{
407
0
  useME      = encCfg->m_motionEstimationSearchMethodSCC > 0                          && isSccStrong;
408
0
  useTS      = encCfg->m_TS == 1                || ( encCfg->m_TS == 2                && isSccWeak );
409
0
  useBDPCM   = encCfg->m_useBDPCM == 1          || ( encCfg->m_useBDPCM == 2          && isSccWeak );
410
0
  useMCTF    = encCfg->m_vvencMCTF.MCTF == 1    || ( encCfg->m_vvencMCTF.MCTF == 2    && ! isSccStrong );
411
0
  useLMCS    = encCfg->m_lumaReshapeEnable == 1 || ( encCfg->m_lumaReshapeEnable == 2 && ! isSccStrong );
412
0
  useIBC     = encCfg->m_IBCMode == 1           || ( encCfg->m_IBCMode == 2           && isSccStrong );
413
0
  useSAO     = encCfg->m_bUseSAO                && ( !encCfg->m_saoScc                || isSccWeak );
414
0
  useSelectiveRdoq = encCfg->m_useSelectiveRDOQ == 2 ? !isSccWeak : !!encCfg->m_useSelectiveRDOQ;
415
0
  useNumRefs = isSccStrong;
416
0
  useFastMrg = isSccStrong ? 0 : std::max(0, encCfg->m_useFastMrg - 2);
417
0
  useQtbttSpeedUpMode = encCfg->m_qtbttSpeedUpMode;
418
419
0
  if( ( encCfg->m_qtbttSpeedUpMode & 2 ) && isSccStrong )
420
0
  {
421
0
    useQtbttSpeedUpMode &= ~1;
422
0
  }
423
0
}
424
425
Slice* Picture::allocateNewSlice()
426
0
{
427
0
  slices.push_back( new Slice );
428
0
  Slice& slice = *slices.back();
429
430
0
  slice.pic     = this;
431
0
  slice.pps     = cs->pps;
432
0
  slice.sps     = cs->sps;
433
0
  slice.vps     = cs->vps;
434
435
0
  memcpy( slice.alfAps, cs->alfAps, sizeof(cs->alfAps) );
436
437
0
  if( slices.size() >= 2 )
438
0
  {
439
0
    slice.copySliceInfo( slices[ slices.size() - 2 ] );
440
0
  }
441
442
0
  return slices.back();
443
0
}
444
445
Slice* Picture::swapSliceObject( Slice*  p, uint32_t i )
446
0
{
447
0
  p->pic     = this;
448
0
  p->pps     = cs->pps;
449
0
  p->sps     = cs->sps;
450
0
  p->vps     = cs->vps;
451
0
  memcpy( p->alfAps, cs->alfAps, sizeof(cs->alfAps) );
452
453
0
  Slice*  pTmp = slices[ i ];
454
0
  slices[ i ] = p;
455
456
0
  pTmp->pic = ( nullptr );
457
0
  pTmp->sps = ( nullptr );
458
0
  pTmp->pps = ( nullptr );
459
0
  memset( pTmp->alfAps, 0, sizeof( *pTmp->alfAps ) * ALF_CTB_MAX_NUM_APS );
460
461
0
  return pTmp;
462
0
}
463
464
void Picture::extendPicBorder()
465
0
{
466
0
  if ( isBorderExtended )
467
0
  {
468
0
    return;
469
0
  }
470
471
0
  for(int comp=0; comp<getNumberValidComponents( cs->area.chromaFormat ); comp++)
472
0
  {
473
0
    ComponentID compID = ComponentID( comp );
474
0
    PelBuf p = m_picBufs[ PIC_RECONSTRUCTION ].get( compID );
475
0
    Pel* piTxt = p.bufAt(0,0);
476
0
    int xmargin = margin >> getComponentScaleX( compID, cs->area.chromaFormat );
477
0
    int ymargin = margin >> getComponentScaleY( compID, cs->area.chromaFormat );
478
479
0
    Pel*  pi = piTxt;
480
    // do left and right margins
481
0
      for (int y = 0; y < p.height; y++)
482
0
      {
483
0
        for (int x = 0; x < xmargin; x++ )
484
0
        {
485
0
          pi[ -xmargin + x ] = pi[0];
486
0
          pi[  p.width + x ] = pi[p.width-1];
487
0
        }
488
0
        pi += p.stride;
489
0
      }
490
491
    // pi is now the (0,height) (bottom left of image within bigger picture
492
0
    pi -= (p.stride + xmargin);
493
    // pi is now the (-marginX, height-1)
494
0
    for (int y = 0; y < ymargin; y++ )
495
0
    {
496
0
      ::memcpy( pi + (y+1)*p.stride, pi, sizeof(Pel)*(p.width + (xmargin << 1)));
497
0
    }
498
499
    // pi is still (-marginX, height-1)
500
0
    pi -= ((p.height-1) * p.stride);
501
    // pi is now (-marginX, 0)
502
0
    for (int y = 0; y < ymargin; y++ )
503
0
    {
504
0
      ::memcpy( pi - (y+1)*p.stride, pi, sizeof(Pel)*(p.width + (xmargin<<1)) );
505
0
    }
506
0
  }
507
508
0
  isBorderExtended = true;
509
0
}
510
511
PelUnitBuf Picture::getPicBuf( const UnitArea& unit, const PictureType type )
512
0
{
513
0
  if( chromaFormat == CHROMA_400 )
514
0
  {
515
0
    return PelUnitBuf( chromaFormat, getPicBuf( unit.Y(), type ) );
516
0
  }
517
0
  else
518
0
  {
519
0
    return PelUnitBuf( chromaFormat, getPicBuf( unit.Y(), type ), getPicBuf( unit.Cb(), type ), getPicBuf( unit.Cr(), type ) );
520
0
  }
521
0
}
522
523
const CPelUnitBuf Picture::getPicBuf( const UnitArea& unit, const PictureType type ) const
524
0
{
525
0
  if( chromaFormat == CHROMA_400 )
526
0
  {
527
0
    return CPelUnitBuf( chromaFormat, getPicBuf( unit.Y(), type ) );
528
0
  }
529
0
  else
530
0
  {
531
0
    return CPelUnitBuf( chromaFormat, getPicBuf( unit.Y(), type ), getPicBuf( unit.Cb(), type ), getPicBuf( unit.Cr(), type ) );
532
0
  }
533
0
}
534
535
PelUnitBuf Picture::getSharedBuf( const UnitArea& unit, const PictureType type )
536
0
{
537
0
  if( chromaFormat == CHROMA_400 )
538
0
  {
539
0
    return PelUnitBuf( chromaFormat, getSharedBuf( unit.Y(), type ) );
540
0
  }
541
0
  else
542
0
  {
543
0
    return PelUnitBuf( chromaFormat, getSharedBuf( unit.Y(), type ), getSharedBuf( unit.Cb(), type ), getSharedBuf( unit.Cr(), type ) );
544
0
  }
545
0
}
546
547
const CPelUnitBuf Picture::getSharedBuf( const UnitArea& unit, const PictureType type ) const
548
0
{
549
0
  if( chromaFormat == CHROMA_400 )
550
0
  {
551
0
    return CPelUnitBuf( chromaFormat, getSharedBuf( unit.Y(), type ) );
552
0
  }
553
0
  else
554
0
  {
555
0
    return CPelUnitBuf( chromaFormat, getSharedBuf( unit.Y(), type ), getSharedBuf( unit.Cb(), type ), getSharedBuf( unit.Cr(), type ) );
556
0
  }
557
0
}
558
559
void Picture::resizeAlfCtuBuffers( int numEntries )
560
0
{
561
0
  for( int compIdx = 0; compIdx < MAX_NUM_COMP; compIdx++ )
562
0
  {
563
0
    m_alfCtuEnabled[compIdx].resize( numEntries );
564
0
    std::fill( m_alfCtuEnabled[compIdx].begin(), m_alfCtuEnabled[compIdx].end(), 0 );
565
0
  }
566
567
0
  m_alfCtbFilterIndex.resize(numEntries);
568
0
  for (int i = 0; i < numEntries; i++)
569
0
  {
570
0
    m_alfCtbFilterIndex[i] = 0;
571
0
  }
572
573
0
  for( int compIdx = 1; compIdx < MAX_NUM_COMP; compIdx++ )
574
0
  {
575
0
    m_alfCtuAlternative[compIdx].resize( numEntries );
576
0
    std::fill( m_alfCtuAlternative[compIdx].begin(), m_alfCtuAlternative[compIdx].end(), 0 );
577
0
  }
578
0
}
579
580
581
} // namespace vvenc
582
583
//! \}
584