Coverage Report

Created: 2026-10-28 06:18

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