Coverage Report

Created: 2026-09-01 06:57

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