Coverage Report

Created: 2026-10-17 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/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, CUMapCache* cuMapCache, CUMapCache* chromaCuMapCache )
71
0
  : area      ()
72
0
  , picture   ( nullptr )
73
0
  , m_ctuData ( nullptr )
74
0
  , m_ctuDataSize( 0 )
75
0
  , m_dmvrMvCache ( nullptr )
76
0
  , m_cuCache ( cuChunkCache )
77
0
  , m_tuCache ( tuChunkCache )
78
0
  , m_cuMapCache( cuMapCache )
79
0
  , m_chromaCuMapCache( chromaCuMapCache )
80
0
  , m_chromaCuMapSize( 0 )
81
0
  , m_cuMap   ( nullptr )
82
0
  , m_cuMapSize( 0 )
83
0
  , m_colMiMap ( nullptr )
84
0
  , m_colMiMapSize ( 0 )
85
0
  , m_IBCBufferWidth( 0 )
86
0
{
87
0
}
88
89
void CodingStructure::destroy()
90
0
{
91
0
  picture   = nullptr;
92
93
0
  m_reco.destroy();
94
0
  m_rec_wrap.destroy();
95
96
0
  m_virtualIBCbuf.clear();
97
98
0
  deallocTempInternals();
99
100
0
  m_ctuData.reset();
101
0
  m_ctuDataSize = 0;
102
103
0
  m_colMiMap.reset();
104
0
  m_colMiMapSize = 0;
105
106
0
  m_cuMap.reset();
107
0
  m_cuMapSize = 0;
108
0
}
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
0
{
123
0
  CodingUnit *cu = m_cuCache.get();
124
125
0
  memset( NO_WARNING_class_memaccess( cu ), 0, sizeof( CodingUnit ) );
126
127
0
  cu->minInit    ( unit );
128
0
  cu->cs         = this;
129
0
  cu->setChType  ( chType );
130
0
  cu->setTreeType( treeType );
131
0
  cu->setModeType( modeType );
132
133
0
  const int currRsAddr = ctuRsAddr( unit.blocks[chType].pos(), chType );
134
135
0
  uint32_t numCh = getNumberValidChannels( area.chromaFormat );
136
137
0
  CtuData& ctuData = getCtuData( currRsAddr );
138
0
  cu->ctuData      = &ctuData;
139
140
0
  if( !ctuData.firstCU )
141
0
  {
142
0
    ctuData.firstCU = cu;
143
0
  }
144
145
0
  cu->idx = ++ctuData.numCUs;
146
147
0
  CodingUnit* prevCU = cu;
148
0
  std::swap( ctuData.lastCU, prevCU );
149
0
  if( prevCU ) prevCU->next = cu;
150
151
0
  cu->predBufOff = ctuData.predBufOffset;
152
153
0
  const bool sharedCuMap = ctuData.cuPtr[CH_C] == ctuData.cuPtr[CH_L];
154
0
  if( sharedCuMap && numCh > 1 && !( cu->blocks[CH_L].valid() && cu->blocks[CH_C].valid() ) )
155
0
  {
156
0
    separateChromaCuMap( ctuData );
157
0
  }
158
159
0
  for( uint32_t i = 0; i < numCh; i++ )
160
0
  {
161
0
    if( !cu->blocks[i].valid() )
162
0
    {
163
0
      continue;
164
0
    }
165
166
0
    const int cuArea = cu->blocks[i].area();
167
168
0
    if( i )
169
0
    {
170
0
      ctuData.predBufOffset += ( cuArea << 1 );
171
0
    }
172
0
    else
173
0
    {
174
0
      ctuData.predBufOffset += cuArea;
175
0
    }
176
177
0
    const ptrdiff_t  stride = ptrdiff_t( 1 ) << m_ctuWidthLog2[i];
178
0
    const Area&      _blk   = cu->blocks[i];
179
0
    const UnitScale  scale  = unitScale[i];
180
0
    const int        sclX   = scale.scaleHor( _blk.x );
181
0
    const int        sclY   = scale.scaleVer( _blk.y );
182
0
    const int        sclW   = scale.scaleHor( _blk.width );
183
0
    const int        sclH   = scale.scaleVer( _blk.height );
184
185
    // a CU of both channel types covers the same entries in both maps, so a shared map is filled only once
186
0
    if( i == CH_L || ctuData.cuPtr[CH_C] != ctuData.cuPtr[CH_L] )
187
0
    {
188
0
      g_pelBufOP.fillN_CU( ctuData.cuPtr[i] + ( sclX & m_ctuSizeMask[i] ) + ( ( sclY & m_ctuSizeMask[i] ) << m_ctuWidthLog2[i] ), stride, sclW, sclH, cu );
189
0
    }
190
191
0
    if( i == chType )
192
0
    {
193
0
      cu->left   = cuLeft;
194
0
      cu->above  = cuAbove;
195
0
    }
196
0
  }
197
198
0
  cu->setChType( chType );
199
200
0
  if( isLuma( chType ) && unit.lheight() >= 8 && unit.lwidth()  >= 8 && unit.Y().area() >= 128 )
201
0
  {
202
0
    cu->mvdL0SubPuOff           = ctuData.dmvrMvCacheOffset;
203
0
    ctuData.dmvrMvCacheOffset += std::max<int>( 1, unit.lwidth() >> DMVR_SUBCU_WIDTH_LOG2 ) * std::max<int>( 1, unit.lheight() >> DMVR_SUBCU_HEIGHT_LOG2 );
204
0
  }
205
206
0
  return *cu;
207
0
}
208
209
TransformUnit& CodingStructure::addTU( const UnitArea &unit, const ChannelType chType, CodingUnit& cu )
210
0
{
211
0
  TransformUnit* tu;
212
213
0
  if( cu.firstTU.blocks.empty() )
214
0
  {
215
0
    tu = cu.lastTU = &cu.firstTU;
216
0
  }
217
0
  else
218
0
  {
219
0
    tu = m_tuCache.get();
220
221
0
    memset( NO_WARNING_class_memaccess( tu ), 0, sizeof( TransformUnit ) );
222
223
0
    cu.lastTU->next = tu;
224
0
    cu.lastTU       = tu;
225
0
  }
226
227
0
  tu->idx               = ++cu.ctuData->numTUs;
228
0
  tu->cu                =  &cu;
229
0
  tu->setChType         (   chType );
230
0
  tu->UnitArea::operator=(  unit );
231
232
0
  return *tu;
233
0
}
234
235
void CodingStructure::addEmptyTUs( Partitioner &partitioner, CodingUnit& cu )
236
0
{
237
0
  const bool split = partitioner.canSplit( TU_MAX_TR_SPLIT, *this );
238
239
0
  if( split )
240
0
  {
241
0
    partitioner.splitCurrArea( TU_MAX_TR_SPLIT, *this );
242
243
0
    do
244
0
    {
245
0
      addTU( partitioner.currArea(), partitioner.chType, cu );
246
0
    } while( partitioner.nextPart( *this ) );
247
248
0
    partitioner.exitCurrSplit( *this );
249
0
  }
250
0
  else
251
0
  {
252
0
    addTU( partitioner.currArea(), partitioner.chType, cu );
253
0
  }
254
0
}
255
256
CUTraverser CodingStructure::traverseCUs( const int ctuRsAddr )
257
0
{
258
0
  CtuData& ctuData = m_ctuData[ctuRsAddr];
259
260
0
  return CUTraverser( ctuData.firstCU, ctuData.lastCU->next );
261
0
}
262
263
// coding utilities
264
265
void CodingStructure::create(const ChromaFormat &_chromaFormat, const Area& _area)
266
0
{
267
0
  createInternals( UnitArea( _chromaFormat, _area ) );
268
0
}
269
270
void CodingStructure::create(const UnitArea& _unit)
271
0
{
272
0
  createInternals( _unit );
273
0
}
274
275
void CodingStructure::createInternals( const UnitArea& _unit )
276
0
{
277
0
  area = _unit;
278
279
0
  memcpy( unitScale, UnitScaleArray[area.chromaFormat], sizeof( unitScale ) );
280
281
0
  picture = nullptr;
282
0
}
283
284
285
void CodingStructure::rebindPicBufs()
286
0
{
287
0
  if( !picture->m_bufs[PIC_RECONSTRUCTION].bufs.empty() ) m_reco.createFromBuf( picture->m_bufs[PIC_RECONSTRUCTION] );
288
0
  else                                                    m_reco.destroy();
289
0
  if( !picture->m_bufs[PIC_RECON_WRAP    ].bufs.empty() ) m_rec_wrap.createFromBuf( picture->m_bufs[PIC_RECON_WRAP] );
290
0
  else                                                    m_rec_wrap.destroy();
291
0
}
292
293
void CodingStructure::allocTempInternals()
294
0
{
295
0
  const ptrdiff_t ctuCuMapSize    = pcv->num4x4CtuBlks;
296
0
  const ptrdiff_t ctuColMiMapSize = pcv->num8x8CtuBlks;
297
298
  // m_ctuData may be reallocated below, and initStructData() clears it
299
0
  releaseChromaCuMaps();
300
301
  // The CU map is only needed while the picture is parsed and reconstructed, so it is borrowed from a cache shared by
302
  // all pictures. initStructData() clears it. It is one map for both channel types, see separateChromaCuMap().
303
0
  const ptrdiff_t newCuMapSize = ctuCuMapSize * pcv->sizeInCtus;
304
0
  if( m_cuMapSize != newCuMapSize )
305
0
  {
306
0
    releaseCuMap();
307
0
    m_cuMap     = m_cuMapCache->get( newCuMapSize );
308
0
    m_cuMapSize = newCuMapSize;
309
0
  }
310
311
0
  const ptrdiff_t newColMiMapSize = ctuColMiMapSize * pcv->sizeInCtus;
312
0
  if( m_colMiMapSize != newColMiMapSize )
313
0
  {
314
0
    m_colMiMap     = std::make_unique<ColocatedMotionInfo[]>( newColMiMapSize );
315
0
    m_colMiMapSize = newColMiMapSize;
316
0
  }
317
318
0
  const size_t newCtuDataSize = pcv->sizeInCtus;
319
0
  if( m_ctuDataSize != newCtuDataSize )
320
0
  {
321
0
    m_ctuData     = std::make_unique<CtuData[]>( newCtuDataSize );
322
0
    m_ctuDataSize = newCtuDataSize;
323
0
  }
324
0
}
325
326
void CodingStructure::deallocTempInternals()
327
0
{
328
0
  m_cuCache.releaseAll();
329
0
  m_tuCache.releaseAll();
330
331
0
  releaseChromaCuMaps();
332
0
  releaseCuMap();
333
0
}
334
335
void CodingStructure::releaseCuMap()
336
0
{
337
0
  if( m_cuMap )
338
0
  {
339
0
    m_cuMapCache->cache( std::move( m_cuMap ), m_cuMapSize );
340
0
  }
341
0
  m_cuMapSize = 0;
342
0
}
343
344
void CodingStructure::separateChromaCuMap( CtuData& ctuData )
345
0
{
346
  // The CUs added so far cover both channel types, so the chroma map starts as a copy of the luma map.
347
  // The CTU keeps the plain pointer, releaseChromaCuMaps() gives the map back to the cache.
348
0
  CodingUnit** chromaCuMap = m_chromaCuMapCache->get( m_chromaCuMapSize ).release();
349
0
  std::copy_n( ctuData.cuPtr[CH_L], m_chromaCuMapSize, chromaCuMap );
350
0
  ctuData.cuPtr[CH_C] = chromaCuMap;
351
0
}
352
353
void CodingStructure::releaseChromaCuMaps()
354
0
{
355
0
  for( size_t i = 0; i < m_ctuDataSize; i++ )
356
0
  {
357
0
    CtuData& ctuData = m_ctuData[i];
358
0
    if( ctuData.cuPtr[CH_C] != ctuData.cuPtr[CH_L] )
359
0
    {
360
0
      m_chromaCuMapCache->cache( std::unique_ptr<CodingUnit*[]>( ctuData.cuPtr[CH_C] ), m_chromaCuMapSize );
361
0
      ctuData.cuPtr[CH_C] = ctuData.cuPtr[CH_L];
362
0
    }
363
0
  }
364
0
}
365
366
void CodingStructure::initStructData()
367
0
{
368
0
  m_cuCache.releaseAll();
369
0
  m_tuCache.releaseAll();
370
371
0
  m_widthInCtus = pcv->widthInCtus;
372
373
0
  m_ctuSizeMask[0] = pcv->maxCUWidthMask >> unitScale[CH_L].posx;
374
0
  m_ctuSizeMask[1] = pcv->maxCUWidthMask >> ( getChannelTypeScaleX( CH_C, area.chromaFormat ) + unitScale[CH_C].posx );
375
376
0
  m_ctuWidthLog2[0] = pcv->maxCUWidthLog2 - unitScale[CH_L].posx;
377
0
  m_ctuWidthLog2[1] = m_ctuWidthLog2[0]; // same for luma and chroma, because of the 2x2 blocks
378
379
  // the separate chroma maps of the previous picture have its CTU size
380
0
  releaseChromaCuMaps();
381
0
  m_chromaCuMapSize = pcv->num4x4CtuBlks;
382
383
0
  memset( NO_WARNING_class_memaccess( m_ctuData.get() ),             0, sizeof( CtuData             ) * m_ctuDataSize );
384
0
  memset( NO_WARNING_class_memaccess( m_cuMap.get() ),               0, sizeof( CodingUnit*         ) * m_cuMapSize );
385
0
  memset( NO_WARNING_class_memaccess( m_colMiMap.get() ), CO_NOT_VALID, sizeof( ColocatedMotionInfo ) * m_colMiMapSize );
386
387
0
  const ptrdiff_t ctuSampleSizeL  = pcv->maxCUHeight * pcv->maxCUWidth;
388
0
  const ptrdiff_t ctuSampleSizeC  = isChromaEnabled( pcv->chrFormat ) ? ( ctuSampleSizeL >> ( getChannelTypeScaleX( CH_C, pcv->chrFormat) + getChannelTypeScaleY( CH_C, pcv->chrFormat ) ) ) : 0;
389
0
  const ptrdiff_t ctuSampleSize   = ctuSampleSizeL + 2 * ctuSampleSizeC;
390
0
  const ptrdiff_t ctuCuMapSize    = pcv->num4x4CtuBlks;
391
0
  const ptrdiff_t ctuColMiMapSize = pcv->num8x8CtuBlks;
392
393
0
  hasIbcBlock.clear();
394
0
  hasIbcBlock.resize( pcv->heightInCtus, 0 );
395
396
0
  for( int y = 0; y < pcv->heightInCtus; y++ )
397
0
  {
398
0
    for( int x = 0; x < pcv->widthInCtus; x++ )
399
0
    {
400
0
      int i = y * pcv->widthInCtus + x;
401
402
0
      m_ctuData[i].lineIdx = y;
403
0
      m_ctuData[i].colIdx  = x;
404
0
      m_ctuData[i].ctuIdx  = i;
405
406
      // Both channel types use the same CU map, because a CU of both channel types covers the same entries in the luma
407
      // and the chroma map. separateChromaCuMap() gives a CTU its own chroma map, if it has a CU of only one channel type.
408
0
      m_ctuData[i].cuPtr[CH_L] = &m_cuMap[i * ctuCuMapSize];
409
0
      m_ctuData[i].cuPtr[CH_C] = m_ctuData[i].cuPtr[CH_L];
410
411
0
      m_ctuData[i].colMotion         = &m_colMiMap[i * ctuColMiMapSize];
412
0
      m_ctuData[i].predBufOffset     = i * ctuSampleSize;
413
0
      m_ctuData[i].dmvrMvCacheOffset = i * pcv->num8x8CtuBlks;
414
0
    }
415
0
  }
416
0
}
417
418
MotionBuf CodingStructure::getMotionBuf( const Area& _area )
419
0
{
420
0
  CtuData&        ctuData = getCtuData( ctuRsAddr( _area.pos(), CH_L ) );
421
422
0
  const ptrdiff_t  stride = ptrdiff_t( 1 ) << m_ctuWidthLog2[CH_L];
423
0
  const UnitScale  scale  = g_miScaling;
424
425
0
  return MotionBuf( ctuData.motion + inCtuPos( _area, CH_L ), stride, scale.scaleHor( _area.width ), scale.scaleVer( _area.height ) );
426
0
}
427
428
const CMotionBuf CodingStructure::getMotionBuf( const Area& _area ) const
429
0
{
430
0
  const CtuData& ctuData  = getCtuData( ctuRsAddr( _area.pos(), CH_L ) );
431
432
0
  const ptrdiff_t  stride = ptrdiff_t( 1 ) << m_ctuWidthLog2[CH_L];
433
0
  const UnitScale  scale  = g_miScaling;
434
435
0
  return CMotionBuf( ctuData.motion + inCtuPos( _area, CH_L ), stride, scale.scaleHor( _area.width ), scale.scaleVer( _area.height ) );
436
0
}
437
438
PelUnitBuf CodingStructure::getPredBuf(const CodingUnit &unit)          
439
0
{
440
0
  PelUnitBuf ret;
441
0
  ret.chromaFormat = unit.chromaFormat;
442
0
  ret.bufs.resize_noinit( getNumberValidComponents( unit.chromaFormat ) );
443
444
0
  if( unit.Y().valid() )
445
0
  {
446
0
    ret.bufs[0].buf    = m_predBuf + unit.predBufOff;
447
0
    ret.bufs[0].stride = unit.blocks[0].width;
448
0
    ret.bufs[0].width  = unit.blocks[0].width;
449
0
    ret.bufs[0].height = unit.blocks[0].height;
450
0
  }
451
452
0
  if( isChromaEnabled( unit.chromaFormat ) )
453
0
  {
454
0
    if( unit.Cb().valid() )
455
0
    {
456
0
      ret.bufs[1].buf    = m_predBuf + unit.predBufOff + unit.Y().area();
457
0
      ret.bufs[1].stride = unit.blocks[1].width;
458
0
      ret.bufs[1].width  = unit.blocks[1].width;
459
0
      ret.bufs[1].height = unit.blocks[1].height;
460
0
    }
461
462
0
    if( unit.Cr().valid() )
463
0
    {
464
0
      ret.bufs[2].buf    = m_predBuf + unit.predBufOff + unit.Y().area() + unit.Cb().area();
465
0
      ret.bufs[2].stride = unit.blocks[2].width;
466
0
      ret.bufs[2].width  = unit.blocks[2].width;
467
0
      ret.bufs[2].height = unit.blocks[2].height;
468
0
    }
469
0
  }
470
471
0
  return ret;
472
0
}
473
474
const CPelUnitBuf CodingStructure::getPredBuf(const CodingUnit &unit) const
475
0
{
476
0
  CPelUnitBuf ret;
477
0
  ret.chromaFormat = unit.chromaFormat;
478
0
  ret.bufs.resize( 3 );
479
480
0
  if( unit.Y().valid() )
481
0
  {
482
0
    ret.bufs[0].buf    = m_predBuf + unit.predBufOff;
483
0
    ret.bufs[0].stride = unit.blocks[0].width;
484
0
    ret.bufs[0].width  = unit.blocks[0].width;
485
0
    ret.bufs[0].height = unit.blocks[0].height;
486
0
  }
487
488
0
  if( unit.Cb().valid() )
489
0
  {
490
0
    ret.bufs[1].buf    = m_predBuf + unit.predBufOff + unit.Y().area();
491
0
    ret.bufs[1].stride = unit.blocks[1].width;
492
0
    ret.bufs[1].width  = unit.blocks[1].width;
493
0
    ret.bufs[1].height = unit.blocks[1].height;
494
0
  }
495
496
0
  if( unit.Cr().valid() )
497
0
  {
498
0
    ret.bufs[2].buf    = m_predBuf + unit.predBufOff + unit.Y().area() + unit.Cb().area();
499
0
    ret.bufs[2].stride = unit.blocks[2].width;
500
0
    ret.bufs[2].width  = unit.blocks[2].width;
501
0
    ret.bufs[2].height = unit.blocks[2].height;
502
0
  }
503
504
0
  return ret;
505
0
}
506
507
const ColocatedMotionInfo& CodingStructure::getColInfo( const Position &pos, const Slice*& pColSlice ) const
508
0
{
509
0
  const CtuData& ctuData    = getCtuData( ctuRsAddr( pos, CH_L ) );
510
0
  const ptrdiff_t rsPos     = colMotPos( pos );
511
0
  const ColocatedMotionInfo&
512
0
                 colMi      = ctuData.colMotion[rsPos];
513
0
                 pColSlice  = ctuData.slice;
514
  
515
0
  return colMi;
516
0
}
517
518
const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const CodingUnit& curCu, const ChannelType _chType, const CodingUnit* guess ) const
519
0
{
520
0
  if( guess && guess->blocks[_chType].contains( pos ) ) return guess;
521
522
0
  const int yshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleY( _chType, curCu.chromaFormat );
523
0
  const int ydiff      = ( pos.y >> yshift ) - ( curCu.blocks[_chType].y >> yshift ); // ( a <= b ) ==> a - b <= 0
524
0
  const int xshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleX( _chType, curCu.chromaFormat );
525
0
  const int xdiff      = ( pos.x >> xshift ) - ( curCu.blocks[_chType].x >> xshift );
526
0
  const bool sameCTU   = !ydiff && !xdiff;
527
528
0
  const CodingUnit* cu = nullptr;
529
530
0
  if( sameCTU )
531
0
  {
532
0
    cu = curCu.ctuData->cuPtr[_chType][inCtuPos( pos, _chType )];
533
0
  }
534
0
  else if( ydiff > 0 || xdiff > ( 1 - sps->getEntropyCodingSyncEnabledFlag() ) || ( ydiff == 0 && xdiff > 0 ) )
535
0
  {
536
0
    return nullptr;
537
0
  }
538
0
  else
539
0
  {
540
0
    cu = getCU( pos, _chType );
541
0
  }
542
543
0
  if( !cu || ( sameCTU && cu->idx > curCu.idx ) ) return nullptr;
544
0
  else if( sameCTU ) return cu;
545
546
0
  if( cu->slice->getIndependentSliceIdx() == curCu.slice->getIndependentSliceIdx() && cu->tileIdx == curCu.tileIdx )
547
0
  {
548
0
    return cu;
549
0
  }
550
0
  else
551
0
  {
552
0
    return nullptr;
553
0
  }
554
0
}
555
556
const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const Position curPos, const unsigned curSliceIdx, const unsigned curTileIdx, const ChannelType _chType ) const
557
0
{
558
0
  const int yshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleY( _chType, area.chromaFormat );
559
0
  const int ydiff      = ( pos.y >> yshift ) - ( curPos.y >> yshift ); // ( a <= b ) ==> a - b <= 0
560
0
  const int xshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleX( _chType, area.chromaFormat );
561
0
  const int xdiff      = ( pos.x >> xshift ) - ( curPos.x >> xshift );
562
0
  const bool sameCTU   = !ydiff && !xdiff;
563
564
0
  const CodingUnit* cu = nullptr;
565
  
566
0
  if( sameCTU )
567
0
  {
568
0
    return getCU( pos, _chType );
569
0
  }
570
0
  else if( ydiff > 0 || xdiff > ( 1 - sps->getEntropyCodingSyncEnabledFlag() ) )
571
0
  {
572
0
    return nullptr;
573
0
  }
574
0
  else
575
0
  {
576
0
    cu = getCU( pos, _chType );
577
0
  }
578
579
0
  if( cu && cu->slice->getIndependentSliceIdx() == curSliceIdx && cu->tileIdx == curTileIdx )
580
0
  {
581
0
    return cu;
582
0
  }
583
0
  else
584
0
  {
585
0
    return nullptr;
586
0
  }
587
0
}
588
589
590
void CodingStructure::initVIbcBuf( int numCtuLines, ChromaFormat chromaFormatIDC, int ctuSize )
591
0
{
592
0
  m_virtualIBCbuf.resize( numCtuLines );
593
0
  for( auto& buf: m_virtualIBCbuf )
594
0
  {
595
0
    if( buf.bufs.empty() || m_IBCBufferWidth != g_IBCBufferSize / ctuSize )
596
0
    {
597
0
      m_IBCBufferWidth = g_IBCBufferSize / ctuSize;
598
0
      buf.destroy();
599
0
      buf.create( UnitArea( chromaFormatIDC, Area( 0, 0, m_IBCBufferWidth, ctuSize ) ) );
600
0
    }
601
0
  }
602
0
}
603
604
void CodingStructure::fillIBCbuffer( CodingUnit &cu, int lineIdx )
605
0
{
606
0
  for( const CompArea &area : cu.blocks )
607
0
  {
608
0
    if (!area.valid())
609
0
      continue;
610
611
0
    const unsigned int lcuWidth = sps->getMaxCUWidth();
612
0
    const int shiftSampleHor = getComponentScaleX(area.compID(), cu.chromaFormat);
613
0
    const int shiftSampleVer = getComponentScaleY(area.compID(), cu.chromaFormat);
614
0
    const int ctuSizeVerLog2 = getLog2(lcuWidth) - shiftSampleVer;
615
0
    const int pux = area.x & ((m_IBCBufferWidth >> shiftSampleHor) - 1);
616
0
    const int puy = area.y & (( 1 << ctuSizeVerLog2 ) - 1);
617
0
    const CompArea dstArea = CompArea(area.compID(), Position(pux, puy), Size(area.width, area.height));
618
0
    CPelBuf srcBuf = getRecoBuf(area);
619
0
    PelBuf dstBuf = m_virtualIBCbuf[lineIdx].getBuf(dstArea);
620
621
0
    dstBuf.copyFrom(srcBuf);
622
0
  }
623
0
}
624
625
}