Coverage Report

Created: 2026-06-16 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vvdec/source/Lib/CommonLib/CodingStructure.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) 2018-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVdeC 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
/** \file     CodingStructure.h
44
 *  \brief    A class managing the coding information for a specific image part
45
 */
46
47
#include "CodingStructure.h"
48
49
#include "Unit.h"
50
#include "Slice.h"
51
#include "Picture.h"
52
#include "UnitTools.h"
53
#include "UnitPartitioner.h"
54
55
namespace vvdec
56
{
57
58
const UnitScale UnitScaleArray[NUM_CHROMA_FORMAT][MAX_NUM_COMPONENT] =
59
{
60
  { {2,2}, {0,0}, {0,0} },  // 4:0:0
61
  { {2,2}, {1,1}, {1,1} },  // 4:2:0
62
  { {2,2}, {1,2}, {1,2} },  // 4:2:2
63
  { {2,2}, {2,2}, {2,2} }   // 4:4:4
64
};
65
66
// ---------------------------------------------------------------------------
67
// coding structure method definitions
68
// ---------------------------------------------------------------------------
69
70
CodingStructure::CodingStructure( CUChunkCache* cuChunkCache, TUChunkCache* tuChunkCache )
71
714
  : area      ()
72
714
  , picture   ( nullptr )
73
714
  , m_ctuData ( nullptr )
74
714
  , m_ctuDataSize( 0 )
75
714
  , m_dmvrMvCache ( nullptr )
76
714
  , m_cuCache ( cuChunkCache )
77
714
  , m_tuCache ( tuChunkCache )
78
714
  , m_cuMap   ( nullptr )
79
714
  , m_cuMapSize( 0 )
80
714
  , m_colMiMap ( nullptr )
81
714
  , m_colMiMapSize ( 0 )
82
714
  , m_IBCBufferWidth( 0 )
83
714
{
84
714
}
85
86
void CodingStructure::destroy()
87
714
{
88
714
  picture   = nullptr;
89
90
714
  m_reco.destroy();
91
714
  m_rec_wrap.destroy();
92
93
714
  m_virtualIBCbuf.clear();
94
95
714
  deallocTempInternals();
96
97
714
  if( m_ctuData ) free( m_ctuData );
98
714
  m_ctuData = nullptr;
99
714
  m_ctuDataSize = 0;
100
101
714
  if( m_colMiMap ) free( m_colMiMap );
102
714
  m_colMiMap = nullptr;
103
714
  m_colMiMapSize = 0;
104
105
714
  if( m_cuMap ) free( m_cuMap );
106
714
  m_cuMap = nullptr;
107
714
  m_cuMapSize = 0;
108
714
}
109
110
void CodingStructure::resetForUse()
111
0
{
112
0
  vps.reset();
113
0
  sps.reset();
114
0
  pps.reset();
115
0
  picHeader.reset();
116
0
  std::fill( std::begin( alfApss ), std::end( alfApss ), nullptr );
117
0
  lmcsAps.reset();
118
0
  pcv = nullptr;
119
0
}
120
121
CodingUnit& CodingStructure::addCU( const UnitArea &unit, const ChannelType chType, const TreeType treeType, const ModeType modeType, const CodingUnit *cuLeft, const CodingUnit *cuAbove )
122
182k
{
123
182k
  CodingUnit *cu = m_cuCache.get();
124
125
182k
  memset( NO_WARNING_class_memaccess( cu ), 0, sizeof( CodingUnit ) );
126
127
182k
  cu->minInit    ( unit );
128
182k
  cu->cs         = this;
129
182k
  cu->setChType  ( chType );
130
182k
  cu->setTreeType( treeType );
131
182k
  cu->setModeType( modeType );
132
133
182k
  const int currRsAddr = ctuRsAddr( unit.blocks[chType].pos(), chType );
134
135
182k
  uint32_t numCh = getNumberValidChannels( area.chromaFormat );
136
137
182k
  CtuData& ctuData = getCtuData( currRsAddr );
138
182k
  cu->ctuData      = &ctuData;
139
140
182k
  if( !ctuData.firstCU )
141
5.42k
  {
142
5.42k
    ctuData.firstCU = cu;
143
5.42k
  }
144
145
182k
  cu->idx = ++ctuData.numCUs;
146
147
182k
  CodingUnit* prevCU = cu;
148
182k
  std::swap( ctuData.lastCU, prevCU );
149
182k
  if( prevCU ) prevCU->next = cu;
150
151
182k
  cu->predBufOff = ctuData.predBufOffset;
152
153
548k
  for( uint32_t i = 0; i < numCh; i++ )
154
365k
  {
155
365k
    if( !cu->blocks[i].valid() )
156
182k
    {
157
182k
      continue;
158
182k
    }
159
160
182k
    const int cuArea = cu->blocks[i].area();
161
162
182k
    if( i )
163
70.0k
    {
164
70.0k
      ctuData.predBufOffset += ( cuArea << 1 );
165
70.0k
    }
166
112k
    else
167
112k
    {
168
112k
      ctuData.predBufOffset += cuArea;
169
112k
    }
170
171
182k
    const ptrdiff_t  stride = ptrdiff_t( 1 ) << m_ctuWidthLog2[i];
172
182k
    const Area&      _blk   = cu->blocks[i];
173
182k
    const UnitScale  scale  = unitScale[i];
174
182k
    const int        sclX   = scale.scaleHor( _blk.x );
175
182k
    const int        sclY   = scale.scaleVer( _blk.y );
176
182k
    const int        sclW   = scale.scaleHor( _blk.width );
177
182k
    const int        sclH   = scale.scaleVer( _blk.height );
178
179
182k
    g_pelBufOP.fillN_CU( ctuData.cuPtr[i] + ( sclX & m_ctuSizeMask[i] ) + ( ( sclY & m_ctuSizeMask[i] ) << m_ctuWidthLog2[i] ), stride, sclW, sclH, cu );
180
181
182k
    if( i == chType )
182
182k
    {
183
182k
      cu->left   = cuLeft;
184
182k
      cu->above  = cuAbove;
185
182k
    }
186
182k
  }
187
188
182k
  cu->setChType( chType );
189
190
182k
  if( isLuma( chType ) && unit.lheight() >= 8 && unit.lwidth()  >= 8 && unit.Y().area() >= 128 )
191
85.9k
  {
192
85.9k
    cu->mvdL0SubPuOff           = ctuData.dmvrMvCacheOffset;
193
85.9k
    ctuData.dmvrMvCacheOffset += std::max<int>( 1, unit.lwidth() >> DMVR_SUBCU_WIDTH_LOG2 ) * std::max<int>( 1, unit.lheight() >> DMVR_SUBCU_HEIGHT_LOG2 );
194
85.9k
  }
195
196
182k
  return *cu;
197
182k
}
198
199
TransformUnit& CodingStructure::addTU( const UnitArea &unit, const ChannelType chType, CodingUnit& cu )
200
202k
{
201
202k
  TransformUnit* tu;
202
203
202k
  if( cu.firstTU.blocks.empty() )
204
182k
  {
205
182k
    tu = cu.lastTU = &cu.firstTU;
206
182k
  }
207
20.2k
  else
208
20.2k
  {
209
20.2k
    tu = m_tuCache.get();
210
211
20.2k
    memset( NO_WARNING_class_memaccess( tu ), 0, sizeof( TransformUnit ) );
212
213
20.2k
    cu.lastTU->next = tu;
214
20.2k
    cu.lastTU       = tu;
215
20.2k
  }
216
217
202k
  tu->idx               = ++cu.ctuData->numTUs;
218
202k
  tu->cu                =  &cu;
219
202k
  tu->setChType         (   chType );
220
202k
  tu->UnitArea::operator=(  unit );
221
222
202k
  return *tu;
223
202k
}
224
225
void CodingStructure::addEmptyTUs( Partitioner &partitioner, CodingUnit& cu )
226
13.0k
{
227
13.0k
  const bool split = partitioner.canSplit( TU_MAX_TR_SPLIT, *this );
228
229
13.0k
  if( split )
230
0
  {
231
0
    partitioner.splitCurrArea( TU_MAX_TR_SPLIT, *this );
232
233
0
    do
234
0
    {
235
0
      addTU( partitioner.currArea(), partitioner.chType, cu );
236
0
    } while( partitioner.nextPart( *this ) );
237
238
0
    partitioner.exitCurrSplit( *this );
239
0
  }
240
13.0k
  else
241
13.0k
  {
242
13.0k
    addTU( partitioner.currArea(), partitioner.chType, cu );
243
13.0k
  }
244
13.0k
}
245
246
CUTraverser CodingStructure::traverseCUs( const int ctuRsAddr )
247
11.8k
{
248
11.8k
  CtuData& ctuData = m_ctuData[ctuRsAddr];
249
250
11.8k
  return CUTraverser( ctuData.firstCU, ctuData.lastCU->next );
251
11.8k
}
252
253
// coding utilities
254
255
void CodingStructure::create(const ChromaFormat &_chromaFormat, const Area& _area)
256
714
{
257
714
  createInternals( UnitArea( _chromaFormat, _area ) );
258
714
}
259
260
void CodingStructure::create(const UnitArea& _unit)
261
0
{
262
0
  createInternals( _unit );
263
0
}
264
265
void CodingStructure::createInternals( const UnitArea& _unit )
266
714
{
267
714
  area = _unit;
268
269
714
  memcpy( unitScale, UnitScaleArray[area.chromaFormat], sizeof( unitScale ) );
270
271
714
  picture = nullptr;
272
714
}
273
274
275
void CodingStructure::rebindPicBufs()
276
717
{
277
717
  if( !picture->m_bufs[PIC_RECONSTRUCTION].bufs.empty() ) m_reco.createFromBuf( picture->m_bufs[PIC_RECONSTRUCTION] );
278
0
  else                                                    m_reco.destroy();
279
717
  if( !picture->m_bufs[PIC_RECON_WRAP    ].bufs.empty() ) m_rec_wrap.createFromBuf( picture->m_bufs[PIC_RECON_WRAP] );
280
711
  else                                                    m_rec_wrap.destroy();
281
717
}
282
283
void CodingStructure::allocTempInternals()
284
714
{
285
714
  const ptrdiff_t ctuCuMapSize    = pcv->num4x4CtuBlks;
286
714
  const ptrdiff_t ctuColMiMapSize = pcv->num8x8CtuBlks;
287
288
714
  if( m_cuMapSize != ctuCuMapSize * pcv->sizeInCtus * 2 )
289
714
  {
290
714
    if( m_cuMap ) free( m_cuMap );
291
714
    m_cuMapSize = ctuCuMapSize * pcv->sizeInCtus * 2;
292
714
    m_cuMap     = ( CodingUnit** ) malloc( sizeof( CodingUnit* ) * m_cuMapSize );
293
714
  }
294
295
714
  if( m_colMiMapSize != ctuColMiMapSize * pcv->sizeInCtus )
296
714
  {
297
714
    if( m_colMiMap ) free( m_colMiMap );
298
714
    m_colMiMapSize = ctuColMiMapSize * pcv->sizeInCtus;
299
714
    m_colMiMap     = ( ColocatedMotionInfo* ) malloc( sizeof( ColocatedMotionInfo ) * m_colMiMapSize );
300
714
  }
301
  
302
714
  if( m_ctuDataSize != pcv->sizeInCtus )
303
714
  {
304
714
    m_ctuDataSize = pcv->sizeInCtus;
305
714
    if( m_ctuData ) free( m_ctuData );
306
714
    m_ctuData = ( CtuData* ) malloc( m_ctuDataSize * sizeof( CtuData ) );
307
714
  }
308
714
}
309
310
void CodingStructure::deallocTempInternals()
311
717
{
312
717
  m_cuCache.releaseAll();
313
717
  m_tuCache.releaseAll();
314
315
717
  if( m_cuMap ) free( m_cuMap );
316
717
  m_cuMap     = nullptr;
317
717
  m_cuMapSize = 0;
318
717
}
319
320
void CodingStructure::initStructData()
321
713
{
322
713
  m_cuCache.releaseAll();
323
713
  m_tuCache.releaseAll();
324
325
713
  m_widthInCtus = pcv->widthInCtus;
326
327
713
  m_ctuSizeMask[0] = pcv->maxCUWidthMask >> unitScale[CH_L].posx;
328
713
  m_ctuSizeMask[1] = pcv->maxCUWidthMask >> ( getChannelTypeScaleX( CH_C, area.chromaFormat ) + unitScale[CH_C].posx );
329
330
713
  m_ctuWidthLog2[0] = pcv->maxCUWidthLog2 - unitScale[CH_L].posx;
331
713
  m_ctuWidthLog2[1] = m_ctuWidthLog2[0]; // same for luma and chroma, because of the 2x2 blocks
332
333
713
  memset( NO_WARNING_class_memaccess( m_ctuData ),             0, sizeof( CtuData             ) * m_ctuDataSize );
334
713
  memset( NO_WARNING_class_memaccess( m_cuMap ),               0, sizeof( CodingUnit*         ) * m_cuMapSize );
335
713
  memset( NO_WARNING_class_memaccess( m_colMiMap ), CO_NOT_VALID, sizeof( ColocatedMotionInfo ) * m_colMiMapSize );
336
337
713
  const ptrdiff_t ctuSampleSizeL  = pcv->maxCUHeight * pcv->maxCUWidth;
338
713
  const ptrdiff_t ctuSampleSizeC  = isChromaEnabled( pcv->chrFormat ) ? ( ctuSampleSizeL >> ( getChannelTypeScaleX( CH_C, pcv->chrFormat) + getChannelTypeScaleY( CH_C, pcv->chrFormat ) ) ) : 0;
339
713
  const ptrdiff_t ctuSampleSize   = ctuSampleSizeL + 2 * ctuSampleSizeC;
340
713
  const ptrdiff_t ctuCuMapSize    = pcv->num4x4CtuBlks;
341
713
  const ptrdiff_t ctuColMiMapSize = pcv->num8x8CtuBlks;
342
343
713
  hasIbcBlock.clear();
344
713
  hasIbcBlock.resize( pcv->heightInCtus, 0 );
345
346
3.13k
  for( int y = 0; y < pcv->heightInCtus; y++ )
347
2.42k
  {
348
11.6k
    for( int x = 0; x < pcv->widthInCtus; x++ )
349
9.24k
    {
350
9.24k
      int i = y * pcv->widthInCtus + x;
351
352
9.24k
      m_ctuData[i].lineIdx = y;
353
9.24k
      m_ctuData[i].colIdx  = x;
354
9.24k
      m_ctuData[i].ctuIdx  = i;
355
356
27.7k
      for( int j = 0; j < 2; j++ )
357
18.4k
      {
358
18.4k
        m_ctuData[i].cuPtr[j] = &m_cuMap[( 2 * i + j ) * ctuCuMapSize];
359
18.4k
      }
360
361
9.24k
      m_ctuData[i].colMotion         = &m_colMiMap[i * ctuColMiMapSize];
362
9.24k
      m_ctuData[i].predBufOffset     = i * ctuSampleSize;
363
9.24k
      m_ctuData[i].dmvrMvCacheOffset = i * pcv->num8x8CtuBlks;
364
9.24k
    }
365
2.42k
  }
366
713
}
367
368
MotionBuf CodingStructure::getMotionBuf( const Area& _area )
369
0
{
370
0
  CtuData&        ctuData = getCtuData( ctuRsAddr( _area.pos(), CH_L ) );
371
372
0
  const ptrdiff_t  stride = ptrdiff_t( 1 ) << m_ctuWidthLog2[CH_L];
373
0
  const UnitScale  scale  = g_miScaling;
374
375
0
  return MotionBuf( ctuData.motion + inCtuPos( _area, CH_L ), stride, scale.scaleHor( _area.width ), scale.scaleVer( _area.height ) );
376
0
}
377
378
const CMotionBuf CodingStructure::getMotionBuf( const Area& _area ) const
379
0
{
380
0
  const CtuData& ctuData  = getCtuData( ctuRsAddr( _area.pos(), CH_L ) );
381
382
0
  const ptrdiff_t  stride = ptrdiff_t( 1 ) << m_ctuWidthLog2[CH_L];
383
0
  const UnitScale  scale  = g_miScaling;
384
385
0
  return CMotionBuf( ctuData.motion + inCtuPos( _area, CH_L ), stride, scale.scaleHor( _area.width ), scale.scaleVer( _area.height ) );
386
0
}
387
388
PelUnitBuf CodingStructure::getPredBuf(const CodingUnit &unit)          
389
54.9k
{
390
54.9k
  PelUnitBuf ret;
391
54.9k
  ret.chromaFormat = unit.chromaFormat;
392
54.9k
  ret.bufs.resize_noinit( getNumberValidComponents( unit.chromaFormat ) );
393
394
54.9k
  if( unit.Y().valid() )
395
36.3k
  {
396
36.3k
    ret.bufs[0].buf    = m_predBuf + unit.predBufOff;
397
36.3k
    ret.bufs[0].stride = unit.blocks[0].width;
398
36.3k
    ret.bufs[0].width  = unit.blocks[0].width;
399
36.3k
    ret.bufs[0].height = unit.blocks[0].height;
400
36.3k
  }
401
402
54.9k
  if( isChromaEnabled( unit.chromaFormat ) )
403
54.9k
  {
404
54.9k
    if( unit.Cb().valid() )
405
18.6k
    {
406
18.6k
      ret.bufs[1].buf    = m_predBuf + unit.predBufOff + unit.Y().area();
407
18.6k
      ret.bufs[1].stride = unit.blocks[1].width;
408
18.6k
      ret.bufs[1].width  = unit.blocks[1].width;
409
18.6k
      ret.bufs[1].height = unit.blocks[1].height;
410
18.6k
    }
411
412
54.9k
    if( unit.Cr().valid() )
413
18.6k
    {
414
18.6k
      ret.bufs[2].buf    = m_predBuf + unit.predBufOff + unit.Y().area() + unit.Cb().area();
415
18.6k
      ret.bufs[2].stride = unit.blocks[2].width;
416
18.6k
      ret.bufs[2].width  = unit.blocks[2].width;
417
18.6k
      ret.bufs[2].height = unit.blocks[2].height;
418
18.6k
    }
419
54.9k
  }
420
421
54.9k
  return ret;
422
54.9k
}
423
424
const CPelUnitBuf CodingStructure::getPredBuf(const CodingUnit &unit) const
425
0
{
426
0
  CPelUnitBuf ret;
427
0
  ret.chromaFormat = unit.chromaFormat;
428
0
  ret.bufs.resize( 3 );
429
430
0
  if( unit.Y().valid() )
431
0
  {
432
0
    ret.bufs[0].buf    = m_predBuf + unit.predBufOff;
433
0
    ret.bufs[0].stride = unit.blocks[0].width;
434
0
    ret.bufs[0].width  = unit.blocks[0].width;
435
0
    ret.bufs[0].height = unit.blocks[0].height;
436
0
  }
437
438
0
  if( unit.Cb().valid() )
439
0
  {
440
0
    ret.bufs[1].buf    = m_predBuf + unit.predBufOff + unit.Y().area();
441
0
    ret.bufs[1].stride = unit.blocks[1].width;
442
0
    ret.bufs[1].width  = unit.blocks[1].width;
443
0
    ret.bufs[1].height = unit.blocks[1].height;
444
0
  }
445
446
0
  if( unit.Cr().valid() )
447
0
  {
448
0
    ret.bufs[2].buf    = m_predBuf + unit.predBufOff + unit.Y().area() + unit.Cb().area();
449
0
    ret.bufs[2].stride = unit.blocks[2].width;
450
0
    ret.bufs[2].width  = unit.blocks[2].width;
451
0
    ret.bufs[2].height = unit.blocks[2].height;
452
0
  }
453
454
0
  return ret;
455
0
}
456
457
const ColocatedMotionInfo& CodingStructure::getColInfo( const Position &pos, const Slice*& pColSlice ) const
458
0
{
459
0
  const CtuData& ctuData    = getCtuData( ctuRsAddr( pos, CH_L ) );
460
0
  const ptrdiff_t rsPos     = colMotPos( pos );
461
0
  const ColocatedMotionInfo&
462
0
                 colMi      = ctuData.colMotion[rsPos];
463
0
                 pColSlice  = ctuData.slice;
464
  
465
0
  return colMi;
466
0
}
467
468
const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const CodingUnit& curCu, const ChannelType _chType, const CodingUnit* guess ) const
469
241k
{
470
241k
  if( guess && guess->blocks[_chType].contains( pos ) ) return guess;
471
472
102k
  const int yshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleY( _chType, curCu.chromaFormat );
473
102k
  const int ydiff      = ( pos.y >> yshift ) - ( curCu.blocks[_chType].y >> yshift ); // ( a <= b ) ==> a - b <= 0
474
102k
  const int xshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleX( _chType, curCu.chromaFormat );
475
102k
  const int xdiff      = ( pos.x >> xshift ) - ( curCu.blocks[_chType].x >> xshift );
476
102k
  const bool sameCTU   = !ydiff && !xdiff;
477
478
102k
  const CodingUnit* cu = nullptr;
479
480
102k
  if( sameCTU )
481
59.0k
  {
482
59.0k
    cu = curCu.ctuData->cuPtr[_chType][inCtuPos( pos, _chType )];
483
59.0k
  }
484
43.4k
  else if( ydiff > 0 || xdiff > ( 1 - sps->getEntropyCodingSyncEnabledFlag() ) || ( ydiff == 0 && xdiff > 0 ) )
485
12.9k
  {
486
12.9k
    return nullptr;
487
12.9k
  }
488
30.5k
  else
489
30.5k
  {
490
30.5k
    cu = getCU( pos, _chType );
491
30.5k
  }
492
493
89.5k
  if( !cu || ( sameCTU && cu->idx > curCu.idx ) ) return nullptr;
494
47.4k
  else if( sameCTU ) return cu;
495
496
10.5k
  if( cu->slice->getIndependentSliceIdx() == curCu.slice->getIndependentSliceIdx() && cu->tileIdx == curCu.tileIdx )
497
10.5k
  {
498
10.5k
    return cu;
499
10.5k
  }
500
18.4E
  else
501
18.4E
  {
502
18.4E
    return nullptr;
503
18.4E
  }
504
10.1k
}
505
506
const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const Position curPos, const unsigned curSliceIdx, const unsigned curTileIdx, const ChannelType _chType ) const
507
386k
{
508
386k
  const int yshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleY( _chType, area.chromaFormat );
509
386k
  const int ydiff      = ( pos.y >> yshift ) - ( curPos.y >> yshift ); // ( a <= b ) ==> a - b <= 0
510
386k
  const int xshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleX( _chType, area.chromaFormat );
511
386k
  const int xdiff      = ( pos.x >> xshift ) - ( curPos.x >> xshift );
512
386k
  const bool sameCTU   = !ydiff && !xdiff;
513
514
386k
  const CodingUnit* cu = nullptr;
515
  
516
386k
  if( sameCTU )
517
294k
  {
518
294k
    return getCU( pos, _chType );
519
294k
  }
520
92.4k
  else if( ydiff > 0 || xdiff > ( 1 - sps->getEntropyCodingSyncEnabledFlag() ) )
521
0
  {
522
0
    return nullptr;
523
0
  }
524
92.4k
  else
525
92.4k
  {
526
92.4k
    cu = getCU( pos, _chType );
527
92.4k
  }
528
529
92.4k
  if( cu && cu->slice->getIndependentSliceIdx() == curSliceIdx && cu->tileIdx == curTileIdx )
530
59.1k
  {
531
59.1k
    return cu;
532
59.1k
  }
533
33.3k
  else
534
33.3k
  {
535
33.3k
    return nullptr;
536
33.3k
  }
537
92.4k
}
538
539
540
void CodingStructure::initVIbcBuf( int numCtuLines, ChromaFormat chromaFormatIDC, int ctuSize )
541
706
{
542
706
  m_virtualIBCbuf.resize( numCtuLines );
543
706
  for( auto& buf: m_virtualIBCbuf )
544
2.41k
  {
545
2.41k
    if( buf.bufs.empty() )
546
2.41k
    {
547
2.41k
      m_IBCBufferWidth = g_IBCBufferSize / ctuSize;
548
2.41k
      buf.create( UnitArea( chromaFormatIDC, Area( 0, 0, m_IBCBufferWidth, ctuSize ) ) );
549
2.41k
    }
550
2.41k
  }
551
706
}
552
553
void CodingStructure::fillIBCbuffer( CodingUnit &cu, int lineIdx )
554
44.6k
{
555
44.6k
  for( const CompArea &area : cu.blocks )
556
134k
  {
557
134k
    if (!area.valid())
558
73.5k
      continue;
559
560
60.5k
    const unsigned int lcuWidth = sps->getMaxCUWidth();
561
60.5k
    const int shiftSampleHor = getComponentScaleX(area.compID(), cu.chromaFormat);
562
60.5k
    const int shiftSampleVer = getComponentScaleY(area.compID(), cu.chromaFormat);
563
60.5k
    const int ctuSizeVerLog2 = getLog2(lcuWidth) - shiftSampleVer;
564
60.5k
    const int pux = area.x & ((m_IBCBufferWidth >> shiftSampleHor) - 1);
565
60.5k
    const int puy = area.y & (( 1 << ctuSizeVerLog2 ) - 1);
566
60.5k
    const CompArea dstArea = CompArea(area.compID(), Position(pux, puy), Size(area.width, area.height));
567
60.5k
    CPelBuf srcBuf = getRecoBuf(area);
568
60.5k
    PelBuf dstBuf = m_virtualIBCbuf[lineIdx].getBuf(dstArea);
569
570
60.5k
    dstBuf.copyFrom(srcBuf);
571
60.5k
  }
572
44.6k
}
573
574
}