Coverage Report

Created: 2026-06-10 07:00

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