Coverage Report

Created: 2026-06-15 06:25

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