Coverage Report

Created: 2026-05-30 06:10

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