Coverage Report

Created: 2026-08-31 06:22

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