Coverage Report

Created: 2026-10-17 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/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
3.46k
    : cs                  ( nullptr )
153
3.46k
    , vps                 ( nullptr )
154
3.46k
    , dci                 ( nullptr )
155
3.46k
    , picApsMap           ( MAX_NUM_APS * MAX_NUM_APS_TYPE )
156
3.46k
    , isInitDone          ( false )
157
3.46k
    , isReconstructed     ( false )
158
3.46k
    , isBorderExtended    ( false )
159
3.46k
    , isReferenced        ( false )
160
3.46k
    , isNeededForOutput   ( false )
161
3.46k
    , isFinished          ( false )
162
3.46k
    , isLongTerm          ( false )
163
3.46k
    , isFlush             ( false )
164
3.46k
    , isInProcessList     ( false )
165
3.46k
    , precedingDRAP       ( false )
166
3.46k
    , gopEntry            ( nullptr )
167
3.46k
    , refCounter          ( 0 )
168
3.46k
    , poc                 ( 0 )
169
3.46k
    , TLayer              ( std::numeric_limits<uint32_t>::max() )
170
3.46k
    , layerId             ( 0 )
171
3.46k
    , isSubPicBorderSaved (false)
172
3.46k
    , sliceDataNumBins    ( 0 )
173
3.46k
    , cts                 ( 0 )
174
3.46k
    , ctsValid            ( false )
175
3.46k
    , picsInMissing       ( 0 )
176
3.46k
    , picOutOffset        ( 0 )
177
3.46k
    , isPreAnalysis       ( false )
178
3.46k
    , m_picShared         ( nullptr )
179
3.46k
    , gopAdaptedQP        ( 0 )
180
3.46k
    , force2ndOrder       ( false )
181
3.46k
    , isSceneCutGOP       ( false )
182
3.46k
    , isSceneCutCheckAdjQP( false )
183
3.46k
    , isMeanQPLimited     ( false )
184
3.46k
    , picInitialQP        ( -1 )
185
3.46k
    , picInitialLambda    ( -1.0 )
186
3.46k
    , picMemorySTA        ( -1 )
187
3.46k
    , picVA               ()
188
3.46k
    , isSccWeak           ( false )
189
3.46k
    , isSccStrong         ( false )
190
3.46k
    , useME               ( false )
191
3.46k
    , useMCTF             ( false )
192
3.46k
    , useTS               ( false )
193
3.46k
    , useBDPCM            ( false )
194
3.46k
    , useIBC              ( false )
195
3.46k
    , useSAO              ( false )
196
3.46k
    , useNumRefs          ( false )
197
3.46k
    , useFastMrg          ( 0 )
198
3.46k
    , useQtbttSpeedUpMode ( 0 )
199
3.46k
    , actualHeadBits      ( 0 )
200
3.46k
    , actualTotalBits     ( 0 )
201
3.46k
    , encRCPic            ( nullptr )
202
3.46k
    , picApsGlobal        ( nullptr )
203
3.46k
    , refApsGlobal        ( nullptr )
204
3.46k
{
205
3.46k
  std::fill_n( m_sharedBufs, (int)NUM_PIC_TYPES, nullptr );
206
3.46k
  std::fill_n( m_bufsOrigPrev, NUM_QPA_PREV_FRAMES, nullptr );
207
3.46k
}
208
209
void Picture::create( ChromaFormat _chromaFormat, const Size& size, unsigned _maxCUSize, unsigned _margin, bool _decoder )
210
3.46k
{
211
3.46k
  UnitArea::operator=( UnitArea( _chromaFormat, Area( Position{ 0, 0 }, size ) ) );
212
3.46k
  margin            =  _margin;
213
214
3.46k
  if( _decoder )
215
0
  {
216
0
    m_picBufs[ PIC_RESIDUAL   ].create( _chromaFormat, Area( 0, 0, _maxCUSize, _maxCUSize ) );
217
0
    m_picBufs[ PIC_PREDICTION ].create( _chromaFormat, Area( 0, 0, _maxCUSize, _maxCUSize ) );
218
0
  }
219
3.46k
}
220
221
void Picture::reset()
222
3.46k
{
223
  // reset picture
224
3.46k
  isInitDone           = false;
225
3.46k
  isReconstructed      = false;
226
3.46k
  isBorderExtended     = false;
227
3.46k
  isReferenced         = true;
228
3.46k
  isNeededForOutput    = true;
229
3.46k
  isFinished           = false;
230
3.46k
  isLongTerm           = false;
231
3.46k
  isFlush              = false;
232
3.46k
  isInProcessList      = false;
233
3.46k
  isMeanQPLimited      = false;
234
3.46k
  precedingDRAP        = false;
235
236
3.46k
  gopEntry             = nullptr;
237
3.46k
  refCounter           = 0;
238
3.46k
  poc                  = -1;
239
3.46k
  TLayer               = std::numeric_limits<uint32_t>::max();
240
3.46k
  gopAdaptedQP         = 0;
241
3.46k
  force2ndOrder        = false;
242
3.46k
  isSceneCutGOP        = false;
243
3.46k
  isSceneCutCheckAdjQP = false;
244
3.46k
  actualHeadBits       = 0;
245
3.46k
  actualTotalBits      = 0;
246
3.46k
  encRCPic             = nullptr;
247
3.46k
  picApsGlobal         = nullptr;
248
3.46k
  refApsGlobal         = nullptr;
249
250
3.46k
  cts                  = 0;
251
3.46k
  ctsValid             = false;
252
3.46k
  picsInMissing        = 0;
253
3.46k
  picOutOffset         = 0;
254
255
3.46k
  picVA.reset();
256
257
3.46k
  std::fill_n( m_sharedBufs, (int)NUM_PIC_TYPES, nullptr );
258
3.46k
  std::fill_n( m_bufsOrigPrev, NUM_QPA_PREV_FRAMES, nullptr );
259
260
3.46k
  if( m_tileColsDone )
261
0
    std::fill( m_tileColsDone->begin(), m_tileColsDone->end(), 0 );
262
263
3.46k
  encTime.resetTimer();
264
3.46k
}
265
266
void Picture::destroy( bool bPicHeader )
267
3.46k
{
268
20.8k
  for (uint32_t t = 0; t < NUM_PIC_TYPES; t++)
269
17.3k
  {
270
17.3k
    m_picBufs[  t ].destroy();
271
17.3k
  }
272
3.46k
  if( cs )
273
1.15k
  {
274
1.15k
    if( bPicHeader && cs->picHeader )
275
1.15k
    {
276
1.15k
      delete cs->picHeader;
277
1.15k
    }
278
1.15k
    cs->picHeader = nullptr;
279
1.15k
    cs->destroy();
280
1.15k
    delete cs;
281
1.15k
    cs = nullptr;
282
1.15k
  }
283
284
3.46k
  for( auto &ps : slices )
285
1.15k
  {
286
1.15k
    delete ps;
287
1.15k
  }
288
3.46k
  slices.clear();
289
290
3.46k
  for( auto &psei : SEIs )
291
0
  {
292
0
    delete psei;
293
0
  }
294
295
3.46k
  delete m_tileColsDone;
296
297
3.46k
  SEIs.clear();
298
3.46k
}
299
300
void Picture::linkSharedBuffers( PelStorage* origBuf, PelStorage* filteredBuf, PelStorage* prevOrigBufs[ NUM_QPA_PREV_FRAMES ], PicShared* picShared )
301
3.46k
{
302
3.46k
  m_picShared                      = picShared;
303
3.46k
  m_sharedBufs[ PIC_ORIGINAL ]      = origBuf;
304
3.46k
  m_sharedBufs[ PIC_FILT_ORIGINAL ] = filteredBuf;
305
10.4k
  for( int i = 0; i < NUM_QPA_PREV_FRAMES; i++ )
306
6.93k
    m_bufsOrigPrev[ i ] = prevOrigBufs[ i ];
307
3.46k
}
308
309
void Picture::releasePrevBuffers()
310
6.93k
{
311
20.8k
  for( int i = 0; i < NUM_QPA_PREV_FRAMES; i++ )
312
13.8k
    m_bufsOrigPrev[ i ] = nullptr;
313
6.93k
}
314
315
void Picture::releaseSharedBuffers()
316
3.46k
{
317
3.46k
  m_picShared                      = nullptr;
318
3.46k
  m_sharedBufs[ PIC_ORIGINAL ]     = nullptr;
319
3.46k
  m_sharedBufs[ PIC_FILT_ORIGINAL ] = nullptr;
320
3.46k
}
321
322
void Picture::createEncodingBuffers()
323
1.15k
{
324
1.15k
  CHECK( !cs, "Coding structure is required at this point!" );
325
326
1.15k
  if( !m_picBufs[PIC_RECONSTRUCTION].valid() )
327
1.15k
  {
328
1.15k
    m_picBufs[PIC_RECONSTRUCTION].create( chromaFormat, Area( lumaPos(), lumaSize() ), cs->sps->CTUSize, margin, MEMORY_ALIGN_DEF_SIZE );
329
1.15k
  }
330
1.15k
  cs->createMotionBuf();
331
1.15k
  if( cs->sps->temporalMVPEnabled )
332
1.15k
  {
333
1.15k
    cs->createColocatedMotionBuf();
334
1.15k
  }
335
1.15k
  cs->rebindPicBufs();
336
1.15k
}
337
338
void Picture::releaseEncodingBuffers()
339
1.15k
{
340
1.15k
  m_picBufs[PIC_RECONSTRUCTION].destroy();
341
1.15k
  if( cs )
342
1.15k
  {
343
1.15k
    cs->destroyMotionBuf();
344
1.15k
    cs->rebindPicBufs();
345
1.15k
  }
346
1.15k
}
347
348
13.3k
const CPelBuf     Picture::getOrigBufPrev (const CompArea &blk, const PrevFrameType type) const { return (m_bufsOrigPrev[ type ] && blk.valid() ? m_bufsOrigPrev[ type ]->getBuf (blk) : PelBuf()); }
349
0
const CPelUnitBuf Picture::getOrigBufPrev (const PrevFrameType type) const { return (m_bufsOrigPrev[ type ] ? *m_bufsOrigPrev[ type ] : PelUnitBuf()); }
350
5.78k
const CPelBuf     Picture::getOrigBufPrev (const ComponentID compID, const PrevFrameType type) const { return (m_bufsOrigPrev[ type ] ? m_bufsOrigPrev[ type ]->getBuf (compID) : PelBuf()); }
351
352
void Picture::finalInit( const VPS& _vps, const SPS& sps, const PPS& pps, PicHeader* picHeader, XUCache& unitCache, std::mutex* mutex, APS** alfAps )
353
1.15k
{
354
1.15k
  for( auto &sei : SEIs )
355
0
  {
356
0
    delete sei;
357
0
  }
358
1.15k
  SEIs.clear();
359
360
1.15k
  for( size_t i = 0; i < slices.size(); i++ )
361
0
  {
362
0
    delete slices[i];
363
0
  }
364
1.15k
  slices.clear();
365
1.15k
  ctuSlice.clear();
366
1.15k
  ctuSlice.resize( pps.pcv->sizeInCtus, nullptr );
367
368
1.15k
  const ChromaFormat chromaFormatIDC = sps.chromaFormatIdc;
369
1.15k
  const int          iWidth  = pps.picWidthInLumaSamples;
370
1.15k
  const int          iHeight = pps.picHeightInLumaSamples;
371
372
1.15k
  if( cs )
373
0
  {
374
0
    CHECK( cs->sps != &sps,  "picture initialization error: sps changed" );
375
0
    CHECK( cs->vps != &_vps, "picture initialization error: vps changed" );
376
0
  }
377
1.15k
  else
378
1.15k
  {
379
1.15k
    cs = new CodingStructure( unitCache, mutex );
380
1.15k
    cs->pps = &pps;
381
1.15k
    cs->sps = &sps;
382
1.15k
    cs->vps = &_vps;
383
1.15k
    cs->createPicLevel( UnitArea( chromaFormatIDC, Area( 0, 0, iWidth, iHeight )), pps.pcv );
384
1.15k
  }
385
386
1.15k
  cs->picture   = this;
387
1.15k
  cs->lumaCS    = cs;
388
1.15k
  cs->slice     = nullptr;  // the slices for this picture have not been set at this point. update cs->slice after swapSliceObject()
389
1.15k
  cs->picHeader = picHeader;
390
1.15k
  if( alfAps )
391
0
  {
392
0
    memcpy( cs->alfAps, alfAps, sizeof( cs->alfAps ) );
393
0
  }
394
1.15k
  cs->pcv     = pps.pcv;
395
1.15k
  vps         = &_vps;
396
1.15k
  dci         = nullptr;
397
398
1.15k
  if( !m_tileColsDone )
399
1.15k
  {
400
1.15k
    m_tileColsDone = new std::vector<std::atomic<int>> ( pps.pcv->heightInCtus );
401
1.15k
  }
402
1.15k
  std::fill( m_tileColsDone->begin(), m_tileColsDone->end(), 0 );
403
404
1.15k
  sliceDataStreams.clear();
405
1.15k
  sliceDataNumBins = 0;
406
1.15k
}
407
408
void Picture::setSccFlags( const VVEncCfg* encCfg )
409
2.31k
{
410
2.31k
  useME      = encCfg->m_motionEstimationSearchMethodSCC > 0                          && isSccStrong;
411
2.31k
  useTS      = encCfg->m_TS == 1                || ( encCfg->m_TS == 2                && isSccWeak );
412
2.31k
  useBDPCM   = encCfg->m_useBDPCM == 1          || ( encCfg->m_useBDPCM == 2          && isSccWeak );
413
2.31k
  useMCTF    = encCfg->m_vvencMCTF.MCTF == 1    || ( encCfg->m_vvencMCTF.MCTF == 2    && ! isSccStrong );
414
2.31k
  useIBC     = encCfg->m_IBCMode == 1           || ( encCfg->m_IBCMode == 2           && isSccStrong );
415
2.31k
  useSAO     = encCfg->m_bUseSAO                && ( !encCfg->m_saoScc                || isSccWeak );
416
2.31k
  useSelectiveRdoq = encCfg->m_useSelectiveRDOQ == 2 ? !isSccWeak : !!encCfg->m_useSelectiveRDOQ;
417
2.31k
  useNumRefs = isSccStrong;
418
2.31k
  useFastMrg = isSccStrong ? 0 : std::max(0, encCfg->m_useFastMrg - 2);
419
2.31k
  useQtbttSpeedUpMode = encCfg->m_qtbttSpeedUpMode;
420
421
2.31k
  if( ( encCfg->m_qtbttSpeedUpMode & 2 ) && isSccStrong )
422
0
  {
423
0
    useQtbttSpeedUpMode &= ~1;
424
0
  }
425
2.31k
}
426
427
Slice* Picture::allocateNewSlice()
428
1.15k
{
429
1.15k
  slices.push_back( new Slice );
430
1.15k
  Slice& slice = *slices.back();
431
432
1.15k
  slice.pic     = this;
433
1.15k
  slice.pps     = cs->pps;
434
1.15k
  slice.sps     = cs->sps;
435
1.15k
  slice.vps     = cs->vps;
436
437
1.15k
  memcpy( slice.alfAps, cs->alfAps, sizeof(cs->alfAps) );
438
439
1.15k
  if( slices.size() >= 2 )
440
0
  {
441
0
    slice.copySliceInfo( slices[ slices.size() - 2 ] );
442
0
  }
443
444
1.15k
  return slices.back();
445
1.15k
}
446
447
Slice* Picture::swapSliceObject( Slice*  p, uint32_t i )
448
0
{
449
0
  p->pic     = this;
450
0
  p->pps     = cs->pps;
451
0
  p->sps     = cs->sps;
452
0
  p->vps     = cs->vps;
453
0
  memcpy( p->alfAps, cs->alfAps, sizeof(cs->alfAps) );
454
455
0
  Slice*  pTmp = slices[ i ];
456
0
  slices[ i ] = p;
457
458
0
  pTmp->pic = ( nullptr );
459
0
  pTmp->sps = ( nullptr );
460
0
  pTmp->pps = ( nullptr );
461
0
  memset( pTmp->alfAps, 0, sizeof( *pTmp->alfAps ) * ALF_CTB_MAX_NUM_APS );
462
463
0
  return pTmp;
464
0
}
465
466
void Picture::extendPicBorder()
467
0
{
468
0
  if ( isBorderExtended )
469
0
  {
470
0
    return;
471
0
  }
472
473
0
  for(int comp=0; comp<getNumberValidComponents( cs->area.chromaFormat ); comp++)
474
0
  {
475
0
    ComponentID compID = ComponentID( comp );
476
0
    PelBuf p = m_picBufs[ PIC_RECONSTRUCTION ].get( compID );
477
0
    Pel* piTxt = p.bufAt(0,0);
478
0
    int xmargin = margin >> getComponentScaleX( compID, cs->area.chromaFormat );
479
0
    int ymargin = margin >> getComponentScaleY( compID, cs->area.chromaFormat );
480
481
0
    Pel*  pi = piTxt;
482
    // do left and right margins
483
0
      for (int y = 0; y < p.height; y++)
484
0
      {
485
0
        for (int x = 0; x < xmargin; x++ )
486
0
        {
487
0
          pi[ -xmargin + x ] = pi[0];
488
0
          pi[  p.width + x ] = pi[p.width-1];
489
0
        }
490
0
        pi += p.stride;
491
0
      }
492
493
    // pi is now the (0,height) (bottom left of image within bigger picture
494
0
    pi -= (p.stride + xmargin);
495
    // pi is now the (-marginX, height-1)
496
0
    for (int y = 0; y < ymargin; y++ )
497
0
    {
498
0
      ::memcpy( pi + (y+1)*p.stride, pi, sizeof(Pel)*(p.width + (xmargin << 1)));
499
0
    }
500
501
    // pi is still (-marginX, height-1)
502
0
    pi -= ((p.height-1) * p.stride);
503
    // pi is now (-marginX, 0)
504
0
    for (int y = 0; y < ymargin; y++ )
505
0
    {
506
0
      ::memcpy( pi - (y+1)*p.stride, pi, sizeof(Pel)*(p.width + (xmargin<<1)) );
507
0
    }
508
0
  }
509
510
0
  isBorderExtended = true;
511
0
}
512
513
PelUnitBuf Picture::getPicBuf( const UnitArea& unit, const PictureType type )
514
116k
{
515
116k
  if( chromaFormat == CHROMA_400 )
516
0
  {
517
0
    return PelUnitBuf( chromaFormat, getPicBuf( unit.Y(), type ) );
518
0
  }
519
116k
  else
520
116k
  {
521
116k
    return PelUnitBuf( chromaFormat, getPicBuf( unit.Y(), type ), getPicBuf( unit.Cb(), type ), getPicBuf( unit.Cr(), type ) );
522
116k
  }
523
116k
}
524
525
const CPelUnitBuf Picture::getPicBuf( const UnitArea& unit, const PictureType type ) const
526
0
{
527
0
  if( chromaFormat == CHROMA_400 )
528
0
  {
529
0
    return CPelUnitBuf( chromaFormat, getPicBuf( unit.Y(), type ) );
530
0
  }
531
0
  else
532
0
  {
533
0
    return CPelUnitBuf( chromaFormat, getPicBuf( unit.Y(), type ), getPicBuf( unit.Cb(), type ), getPicBuf( unit.Cr(), type ) );
534
0
  }
535
0
}
536
537
PelUnitBuf Picture::getSharedBuf( const UnitArea& unit, const PictureType type )
538
0
{
539
0
  if( chromaFormat == CHROMA_400 )
540
0
  {
541
0
    return PelUnitBuf( chromaFormat, getSharedBuf( unit.Y(), type ) );
542
0
  }
543
0
  else
544
0
  {
545
0
    return PelUnitBuf( chromaFormat, getSharedBuf( unit.Y(), type ), getSharedBuf( unit.Cb(), type ), getSharedBuf( unit.Cr(), type ) );
546
0
  }
547
0
}
548
549
const CPelUnitBuf Picture::getSharedBuf( const UnitArea& unit, const PictureType type ) const
550
3.50k
{
551
3.50k
  if( chromaFormat == CHROMA_400 )
552
0
  {
553
0
    return CPelUnitBuf( chromaFormat, getSharedBuf( unit.Y(), type ) );
554
0
  }
555
3.50k
  else
556
3.50k
  {
557
3.50k
    return CPelUnitBuf( chromaFormat, getSharedBuf( unit.Y(), type ), getSharedBuf( unit.Cb(), type ), getSharedBuf( unit.Cr(), type ) );
558
3.50k
  }
559
3.50k
}
560
561
void Picture::resizeAlfCtuBuffers( int numEntries )
562
1.15k
{
563
4.62k
  for( int compIdx = 0; compIdx < MAX_NUM_COMP; compIdx++ )
564
3.46k
  {
565
3.46k
    m_alfCtuEnabled[compIdx].resize( numEntries );
566
3.46k
    std::fill( m_alfCtuEnabled[compIdx].begin(), m_alfCtuEnabled[compIdx].end(), 0 );
567
3.46k
  }
568
569
1.15k
  m_alfCtbFilterIndex.resize(numEntries);
570
4.65k
  for (int i = 0; i < numEntries; i++)
571
3.50k
  {
572
3.50k
    m_alfCtbFilterIndex[i] = 0;
573
3.50k
  }
574
575
3.46k
  for( int compIdx = 1; compIdx < MAX_NUM_COMP; compIdx++ )
576
2.31k
  {
577
2.31k
    m_alfCtuAlternative[compIdx].resize( numEntries );
578
2.31k
    std::fill( m_alfCtuAlternative[compIdx].begin(), m_alfCtuAlternative[compIdx].end(), 0 );
579
2.31k
  }
580
1.15k
}
581
582
583
} // namespace vvenc
584
585
//! \}
586