Coverage Report

Created: 2026-07-16 06:32

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.64k
    : cs                  ( nullptr )
153
3.64k
    , vps                 ( nullptr )
154
3.64k
    , dci                 ( nullptr )
155
3.64k
    , picApsMap           ( MAX_NUM_APS * MAX_NUM_APS_TYPE )
156
3.64k
    , isInitDone          ( false )
157
3.64k
    , isReconstructed     ( false )
158
3.64k
    , isBorderExtended    ( false )
159
3.64k
    , isReferenced        ( false )
160
3.64k
    , isNeededForOutput   ( false )
161
3.64k
    , isFinished          ( false )
162
3.64k
    , isLongTerm          ( false )
163
3.64k
    , isFlush             ( false )
164
3.64k
    , isInProcessList     ( false )
165
3.64k
    , precedingDRAP       ( false )
166
3.64k
    , gopEntry            ( nullptr )
167
3.64k
    , refCounter          ( 0 )
168
3.64k
    , poc                 ( 0 )
169
3.64k
    , TLayer              ( std::numeric_limits<uint32_t>::max() )
170
3.64k
    , layerId             ( 0 )
171
3.64k
    , isSubPicBorderSaved (false)
172
3.64k
    , sliceDataNumBins    ( 0 )
173
3.64k
    , cts                 ( 0 )
174
3.64k
    , ctsValid            ( false )
175
3.64k
    , picsInMissing       ( 0 )
176
3.64k
    , picOutOffset        ( 0 )
177
3.64k
    , isPreAnalysis       ( false )
178
3.64k
    , m_picShared         ( nullptr )
179
3.64k
    , gopAdaptedQP        ( 0 )
180
3.64k
    , force2ndOrder       ( false )
181
3.64k
    , isSceneCutGOP       ( false )
182
3.64k
    , isSceneCutCheckAdjQP( false )
183
3.64k
    , isMeanQPLimited     ( false )
184
3.64k
    , picInitialQP        ( -1 )
185
3.64k
    , picInitialLambda    ( -1.0 )
186
3.64k
    , picMemorySTA        ( -1 )
187
3.64k
    , picVA               ()
188
3.64k
    , isSccWeak           ( false )
189
3.64k
    , isSccStrong         ( false )
190
3.64k
    , useME               ( false )
191
3.64k
    , useMCTF             ( false )
192
3.64k
    , useTS               ( false )
193
3.64k
    , useBDPCM            ( false )
194
3.64k
    , useIBC              ( false )
195
3.64k
    , useLMCS             ( false )
196
3.64k
    , useSAO              ( false )
197
3.64k
    , useNumRefs          ( false )
198
3.64k
    , useFastMrg          ( 0 )
199
3.64k
    , useQtbttSpeedUpMode ( 0 )
200
3.64k
    , actualHeadBits      ( 0 )
201
3.64k
    , actualTotalBits     ( 0 )
202
3.64k
    , encRCPic            ( nullptr )
203
3.64k
    , picApsGlobal        ( nullptr )
204
3.64k
    , refApsGlobal        ( nullptr )
205
3.64k
{
206
3.64k
  std::fill_n( m_sharedBufs, (int)NUM_PIC_TYPES, nullptr );
207
3.64k
  std::fill_n( m_bufsOrigPrev, NUM_QPA_PREV_FRAMES, nullptr );
208
3.64k
}
209
210
void Picture::create( ChromaFormat _chromaFormat, const Size& size, unsigned _maxCUSize, unsigned _margin, bool _decoder )
211
3.64k
{
212
3.64k
  UnitArea::operator=( UnitArea( _chromaFormat, Area( Position{ 0, 0 }, size ) ) );
213
3.64k
  margin            =  _margin;
214
215
3.64k
  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
3.64k
}
221
222
void Picture::reset()
223
3.64k
{
224
  // reset picture
225
3.64k
  isInitDone           = false;
226
3.64k
  isReconstructed      = false;
227
3.64k
  isBorderExtended     = false;
228
3.64k
  isReferenced         = true;
229
3.64k
  isNeededForOutput    = true;
230
3.64k
  isFinished           = false;
231
3.64k
  isLongTerm           = false;
232
3.64k
  isFlush              = false;
233
3.64k
  isInProcessList      = false;
234
3.64k
  isMeanQPLimited      = false;
235
3.64k
  precedingDRAP        = false;
236
237
3.64k
  gopEntry             = nullptr;
238
3.64k
  refCounter           = 0;
239
3.64k
  poc                  = -1;
240
3.64k
  TLayer               = std::numeric_limits<uint32_t>::max();
241
3.64k
  gopAdaptedQP         = 0;
242
3.64k
  force2ndOrder        = false;
243
3.64k
  isSceneCutGOP        = false;
244
3.64k
  isSceneCutCheckAdjQP = false;
245
3.64k
  actualHeadBits       = 0;
246
3.64k
  actualTotalBits      = 0;
247
3.64k
  encRCPic             = nullptr;
248
3.64k
  picApsGlobal         = nullptr;
249
3.64k
  refApsGlobal         = nullptr;
250
251
3.64k
  cts                  = 0;
252
3.64k
  ctsValid             = false;
253
3.64k
  picsInMissing        = 0;
254
3.64k
  picOutOffset         = 0;
255
256
3.64k
  picVA.reset();
257
258
3.64k
  std::fill_n( m_sharedBufs, (int)NUM_PIC_TYPES, nullptr );
259
3.64k
  std::fill_n( m_bufsOrigPrev, NUM_QPA_PREV_FRAMES, nullptr );
260
261
3.64k
  if( m_tileColsDone )
262
0
    std::fill( m_tileColsDone->begin(), m_tileColsDone->end(), 0 );
263
264
3.64k
  encTime.resetTimer();
265
3.64k
}
266
267
void Picture::destroy( bool bPicHeader )
268
3.64k
{
269
25.5k
  for (uint32_t t = 0; t < NUM_PIC_TYPES; t++)
270
21.8k
  {
271
21.8k
    m_picBufs[  t ].destroy();
272
21.8k
  }
273
3.64k
  if( cs )
274
1.21k
  {
275
1.21k
    if( bPicHeader && cs->picHeader )
276
1.21k
    {
277
1.21k
      delete cs->picHeader;
278
1.21k
    }
279
1.21k
    cs->picHeader = nullptr;
280
1.21k
    cs->destroy();
281
1.21k
    delete cs;
282
1.21k
    cs = nullptr;
283
1.21k
  }
284
285
3.64k
  for( auto &ps : slices )
286
1.21k
  {
287
1.21k
    delete ps;
288
1.21k
  }
289
3.64k
  slices.clear();
290
291
3.64k
  for( auto &psei : SEIs )
292
0
  {
293
0
    delete psei;
294
0
  }
295
296
3.64k
  delete m_tileColsDone;
297
298
3.64k
  SEIs.clear();
299
3.64k
}
300
301
void Picture::linkSharedBuffers( PelStorage* origBuf, PelStorage* filteredBuf, PelStorage* prevOrigBufs[ NUM_QPA_PREV_FRAMES ], PicShared* picShared )
302
3.64k
{
303
3.64k
  m_picShared                      = picShared;
304
3.64k
  m_sharedBufs[ PIC_ORIGINAL ]     = origBuf;
305
3.64k
  m_sharedBufs[ PIC_ORIGINAL_RSP ] = filteredBuf;
306
10.9k
  for( int i = 0; i < NUM_QPA_PREV_FRAMES; i++ )
307
7.29k
    m_bufsOrigPrev[ i ] = prevOrigBufs[ i ];
308
3.64k
}
309
310
void Picture::releasePrevBuffers()
311
7.29k
{
312
21.8k
  for( int i = 0; i < NUM_QPA_PREV_FRAMES; i++ )
313
14.5k
    m_bufsOrigPrev[ i ] = nullptr;
314
7.29k
}
315
316
void Picture::releaseSharedBuffers()
317
3.64k
{
318
3.64k
  m_picShared                      = nullptr;
319
3.64k
  m_sharedBufs[ PIC_ORIGINAL ]     = nullptr;
320
3.64k
  m_sharedBufs[ PIC_ORIGINAL_RSP ] = nullptr;
321
3.64k
}
322
323
void Picture::createTempBuffers( unsigned _maxCUSize )
324
1.21k
{
325
1.21k
  CHECK( !cs, "Coding structure is required a this point!" );
326
327
  // SAO reads/writes +-1 sample, especially SIMD
328
1.21k
  m_picBufs[PIC_SAO_TEMP].create( chromaFormat, Y(), cs->pcv->maxCUSize, 2, MEMORY_ALIGN_DEF_SIZE );
329
330
1.21k
  if( cs ) cs->rebindPicBufs();
331
1.21k
}
332
333
void Picture::destroyTempBuffers()
334
1.21k
{
335
1.21k
  m_picBufs[PIC_SAO_TEMP].destroy();
336
337
1.21k
  if( cs ) cs->rebindPicBufs();
338
1.21k
}
339
340
15.2k
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
6.08k
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
1.21k
{
346
1.21k
  for( auto &sei : SEIs )
347
0
  {
348
0
    delete sei;
349
0
  }
350
1.21k
  SEIs.clear();
351
352
1.21k
  for( size_t i = 0; i < slices.size(); i++ )
353
0
  {
354
0
    delete slices[i];
355
0
  }
356
1.21k
  slices.clear();
357
1.21k
  ctuSlice.clear();
358
1.21k
  ctuSlice.resize( pps.pcv->sizeInCtus, nullptr );
359
360
1.21k
  const ChromaFormat chromaFormatIDC = sps.chromaFormatIdc;
361
1.21k
  const int          iWidth  = pps.picWidthInLumaSamples;
362
1.21k
  const int          iHeight = pps.picHeightInLumaSamples;
363
364
1.21k
  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
1.21k
  else
370
1.21k
  {
371
1.21k
    cs = new CodingStructure( unitCache, mutex );
372
1.21k
    cs->pps = &pps;
373
1.21k
    cs->sps = &sps;
374
1.21k
    cs->vps = &_vps;
375
1.21k
    cs->createPicLevel( UnitArea( chromaFormatIDC, Area( 0, 0, iWidth, iHeight )), pps.pcv );
376
1.21k
  }
377
378
1.21k
  cs->picture   = this;
379
1.21k
  cs->lumaCS    = cs;
380
1.21k
  cs->slice     = nullptr;  // the slices for this picture have not been set at this point. update cs->slice after swapSliceObject()
381
1.21k
  cs->picHeader = picHeader;
382
1.21k
  if( alfAps )
383
0
  {
384
0
    memcpy( cs->alfAps, alfAps, sizeof( cs->alfAps ) );
385
0
  }
386
1.21k
  cs->lmcsAps = lmcsAps;
387
1.21k
  cs->pcv     = pps.pcv;
388
1.21k
  vps         = &_vps;
389
1.21k
  dci         = nullptr;
390
391
1.21k
  if( !m_picBufs[PIC_RECONSTRUCTION].valid() )
392
1.21k
  {
393
1.21k
    m_picBufs[ PIC_RECONSTRUCTION ].create( chromaFormat, Area( lumaPos(), lumaSize() ), sps.CTUSize, margin, MEMORY_ALIGN_DEF_SIZE );
394
1.21k
  }
395
1.21k
  if( !m_tileColsDone )
396
1.21k
  {
397
1.21k
    m_tileColsDone = new std::vector<std::atomic<int>> ( pps.pcv->heightInCtus );
398
1.21k
  }
399
1.21k
  std::fill( m_tileColsDone->begin(), m_tileColsDone->end(), 0 );
400
401
1.21k
  sliceDataStreams.clear();
402
1.21k
  sliceDataNumBins = 0;
403
1.21k
}
404
405
void Picture::setSccFlags( const VVEncCfg* encCfg )
406
2.43k
{
407
2.43k
  useME      = encCfg->m_motionEstimationSearchMethodSCC > 0                          && isSccStrong;
408
2.43k
  useTS      = encCfg->m_TS == 1                || ( encCfg->m_TS == 2                && isSccWeak );
409
2.43k
  useBDPCM   = encCfg->m_useBDPCM == 1          || ( encCfg->m_useBDPCM == 2          && isSccWeak );
410
2.43k
  useMCTF    = encCfg->m_vvencMCTF.MCTF == 1    || ( encCfg->m_vvencMCTF.MCTF == 2    && ! isSccStrong );
411
2.43k
  useLMCS    = encCfg->m_lumaReshapeEnable == 1 || ( encCfg->m_lumaReshapeEnable == 2 && ! isSccStrong );
412
2.43k
  useIBC     = encCfg->m_IBCMode == 1           || ( encCfg->m_IBCMode == 2           && isSccStrong );
413
2.43k
  useSAO     = encCfg->m_bUseSAO                && ( !encCfg->m_saoScc                || isSccWeak );
414
2.43k
  useSelectiveRdoq = encCfg->m_useSelectiveRDOQ == 2 ? !isSccWeak : !!encCfg->m_useSelectiveRDOQ;
415
2.43k
  useNumRefs = isSccStrong;
416
2.43k
  useFastMrg = isSccStrong ? 0 : std::max(0, encCfg->m_useFastMrg - 2);
417
2.43k
  useQtbttSpeedUpMode = encCfg->m_qtbttSpeedUpMode;
418
419
2.43k
  if( ( encCfg->m_qtbttSpeedUpMode & 2 ) && isSccStrong )
420
0
  {
421
0
    useQtbttSpeedUpMode &= ~1;
422
0
  }
423
2.43k
}
424
425
Slice* Picture::allocateNewSlice()
426
1.21k
{
427
1.21k
  slices.push_back( new Slice );
428
1.21k
  Slice& slice = *slices.back();
429
430
1.21k
  slice.pic     = this;
431
1.21k
  slice.pps     = cs->pps;
432
1.21k
  slice.sps     = cs->sps;
433
1.21k
  slice.vps     = cs->vps;
434
435
1.21k
  memcpy( slice.alfAps, cs->alfAps, sizeof(cs->alfAps) );
436
437
1.21k
  if( slices.size() >= 2 )
438
0
  {
439
0
    slice.copySliceInfo( slices[ slices.size() - 2 ] );
440
0
  }
441
442
1.21k
  return slices.back();
443
1.21k
}
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
123k
{
513
123k
  if( chromaFormat == CHROMA_400 )
514
0
  {
515
0
    return PelUnitBuf( chromaFormat, getPicBuf( unit.Y(), type ) );
516
0
  }
517
123k
  else
518
123k
  {
519
123k
    return PelUnitBuf( chromaFormat, getPicBuf( unit.Y(), type ), getPicBuf( unit.Cb(), type ), getPicBuf( unit.Cr(), type ) );
520
123k
  }
521
123k
}
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
3.78k
{
549
3.78k
  if( chromaFormat == CHROMA_400 )
550
0
  {
551
0
    return CPelUnitBuf( chromaFormat, getSharedBuf( unit.Y(), type ) );
552
0
  }
553
3.78k
  else
554
3.78k
  {
555
3.78k
    return CPelUnitBuf( chromaFormat, getSharedBuf( unit.Y(), type ), getSharedBuf( unit.Cb(), type ), getSharedBuf( unit.Cr(), type ) );
556
3.78k
  }
557
3.78k
}
558
559
void Picture::resizeAlfCtuBuffers( int numEntries )
560
1.21k
{
561
4.86k
  for( int compIdx = 0; compIdx < MAX_NUM_COMP; compIdx++ )
562
3.64k
  {
563
3.64k
    m_alfCtuEnabled[compIdx].resize( numEntries );
564
3.64k
    std::fill( m_alfCtuEnabled[compIdx].begin(), m_alfCtuEnabled[compIdx].end(), 0 );
565
3.64k
  }
566
567
1.21k
  m_alfCtbFilterIndex.resize(numEntries);
568
5.00k
  for (int i = 0; i < numEntries; i++)
569
3.78k
  {
570
3.78k
    m_alfCtbFilterIndex[i] = 0;
571
3.78k
  }
572
573
3.64k
  for( int compIdx = 1; compIdx < MAX_NUM_COMP; compIdx++ )
574
2.43k
  {
575
2.43k
    m_alfCtuAlternative[compIdx].resize( numEntries );
576
2.43k
    std::fill( m_alfCtuAlternative[compIdx].begin(), m_alfCtuAlternative[compIdx].end(), 0 );
577
2.43k
  }
578
1.21k
}
579
580
581
} // namespace vvenc
582
583
//! \}
584