Coverage Report

Created: 2026-04-01 07:49

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
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
  if( m_ctuData ) free( m_ctuData );
98
0
  m_ctuData = nullptr;
99
0
  m_ctuDataSize = 0;
100
101
0
  if( m_colMiMap ) free( m_colMiMap );
102
0
  m_colMiMap = nullptr;
103
0
  m_colMiMapSize = 0;
104
105
0
  if( m_cuMap ) free( m_cuMap );
106
0
  m_cuMap = nullptr;
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
  for( uint32_t i = 0; i < numCh; i++ )
154
0
  {
155
0
    if( !cu->blocks[i].valid() )
156
0
    {
157
0
      continue;
158
0
    }
159
160
0
    const int cuArea = cu->blocks[i].area();
161
162
0
    if( i )
163
0
    {
164
0
      ctuData.predBufOffset += ( cuArea << 1 );
165
0
    }
166
0
    else
167
0
    {
168
0
      ctuData.predBufOffset += cuArea;
169
0
    }
170
171
0
    const ptrdiff_t  stride = ptrdiff_t( 1 ) << m_ctuWidthLog2[i];
172
0
    const Area&      _blk   = cu->blocks[i];
173
0
    const UnitScale  scale  = unitScale[i];
174
0
    const int        sclX   = scale.scaleHor( _blk.x );
175
0
    const int        sclY   = scale.scaleVer( _blk.y );
176
0
    const int        sclW   = scale.scaleHor( _blk.width );
177
0
    const int        sclH   = scale.scaleVer( _blk.height );
178
179
0
    g_pelBufOP.fillN_CU( ctuData.cuPtr[i] + ( sclX & m_ctuSizeMask[i] ) + ( ( sclY & m_ctuSizeMask[i] ) << m_ctuWidthLog2[i] ), stride, sclW, sclH, cu );
180
181
0
    if( i == chType )
182
0
    {
183
0
      cu->left   = cuLeft;
184
0
      cu->above  = cuAbove;
185
0
    }
186
0
  }
187
188
0
  cu->setChType( chType );
189
190
0
  if( isLuma( chType ) && unit.lheight() >= 8 && unit.lwidth()  >= 8 && unit.Y().area() >= 128 )
191
0
  {
192
0
    cu->mvdL0SubPuOff           = ctuData.dmvrMvCacheOffset;
193
0
    ctuData.dmvrMvCacheOffset += std::max<int>( 1, unit.lwidth() >> DMVR_SUBCU_WIDTH_LOG2 ) * std::max<int>( 1, unit.lheight() >> DMVR_SUBCU_HEIGHT_LOG2 );
194
0
  }
195
196
0
  return *cu;
197
0
}
198
199
TransformUnit& CodingStructure::addTU( const UnitArea &unit, const ChannelType chType, CodingUnit& cu )
200
0
{
201
0
  TransformUnit* tu;
202
203
0
  if( cu.firstTU.blocks.empty() )
204
0
  {
205
0
    tu = cu.lastTU = &cu.firstTU;
206
0
  }
207
0
  else
208
0
  {
209
0
    tu = m_tuCache.get();
210
211
0
    memset( NO_WARNING_class_memaccess( tu ), 0, sizeof( TransformUnit ) );
212
213
0
    cu.lastTU->next = tu;
214
0
    cu.lastTU       = tu;
215
0
  }
216
217
0
  tu->idx               = ++cu.ctuData->numTUs;
218
0
  tu->cu                =  &cu;
219
0
  tu->setChType         (   chType );
220
0
  tu->UnitArea::operator=(  unit );
221
222
0
  return *tu;
223
0
}
224
225
void CodingStructure::addEmptyTUs( Partitioner &partitioner, CodingUnit& cu )
226
0
{
227
0
  const bool split = partitioner.canSplit( TU_MAX_TR_SPLIT, *this );
228
229
0
  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
0
  else
241
0
  {
242
0
    addTU( partitioner.currArea(), partitioner.chType, cu );
243
0
  }
244
0
}
245
246
CUTraverser CodingStructure::traverseCUs( const int ctuRsAddr )
247
0
{
248
0
  CtuData& ctuData = m_ctuData[ctuRsAddr];
249
250
0
  return CUTraverser( ctuData.firstCU, ctuData.lastCU->next );
251
0
}
252
253
// coding utilities
254
255
void CodingStructure::create(const ChromaFormat &_chromaFormat, const Area& _area)
256
0
{
257
0
  createInternals( UnitArea( _chromaFormat, _area ) );
258
0
}
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
0
{
267
0
  area = _unit;
268
269
0
  memcpy( unitScale, UnitScaleArray[area.chromaFormat], sizeof( unitScale ) );
270
271
0
  picture = nullptr;
272
0
}
273
274
275
void CodingStructure::rebindPicBufs()
276
0
{
277
0
  if( !picture->m_bufs[PIC_RECONSTRUCTION].bufs.empty() ) m_reco.createFromBuf( picture->m_bufs[PIC_RECONSTRUCTION] );
278
0
  else                                                    m_reco.destroy();
279
0
  if( !picture->m_bufs[PIC_RECON_WRAP    ].bufs.empty() ) m_rec_wrap.createFromBuf( picture->m_bufs[PIC_RECON_WRAP] );
280
0
  else                                                    m_rec_wrap.destroy();
281
0
}
282
283
void CodingStructure::allocTempInternals()
284
0
{
285
0
  const ptrdiff_t ctuCuMapSize    = pcv->num4x4CtuBlks;
286
0
  const ptrdiff_t ctuColMiMapSize = pcv->num8x8CtuBlks;
287
288
0
  if( m_cuMapSize != ctuCuMapSize * pcv->sizeInCtus * 2 )
289
0
  {
290
0
    if( m_cuMap ) free( m_cuMap );
291
0
    m_cuMapSize = ctuCuMapSize * pcv->sizeInCtus * 2;
292
0
    m_cuMap     = ( CodingUnit** ) malloc( sizeof( CodingUnit* ) * m_cuMapSize );
293
0
  }
294
295
0
  if( m_colMiMapSize != ctuColMiMapSize * pcv->sizeInCtus )
296
0
  {
297
0
    if( m_colMiMap ) free( m_colMiMap );
298
0
    m_colMiMapSize = ctuColMiMapSize * pcv->sizeInCtus;
299
0
    m_colMiMap     = ( ColocatedMotionInfo* ) malloc( sizeof( ColocatedMotionInfo ) * m_colMiMapSize );
300
0
  }
301
  
302
0
  if( m_ctuDataSize != pcv->sizeInCtus )
303
0
  {
304
0
    m_ctuDataSize = pcv->sizeInCtus;
305
0
    if( m_ctuData ) free( m_ctuData );
306
0
    m_ctuData = ( CtuData* ) malloc( m_ctuDataSize * sizeof( CtuData ) );
307
0
  }
308
0
}
309
310
void CodingStructure::deallocTempInternals()
311
0
{
312
0
  m_cuCache.releaseAll();
313
0
  m_tuCache.releaseAll();
314
315
0
  if( m_cuMap ) free( m_cuMap );
316
0
  m_cuMap     = nullptr;
317
0
  m_cuMapSize = 0;
318
0
}
319
320
void CodingStructure::initStructData()
321
0
{
322
0
  m_cuCache.releaseAll();
323
0
  m_tuCache.releaseAll();
324
325
0
  m_widthInCtus = pcv->widthInCtus;
326
327
0
  m_ctuSizeMask[0] = pcv->maxCUWidthMask >> unitScale[CH_L].posx;
328
0
  m_ctuSizeMask[1] = pcv->maxCUWidthMask >> ( getChannelTypeScaleX( CH_C, area.chromaFormat ) + unitScale[CH_C].posx );
329
330
0
  m_ctuWidthLog2[0] = pcv->maxCUWidthLog2 - unitScale[CH_L].posx;
331
0
  m_ctuWidthLog2[1] = m_ctuWidthLog2[0]; // same for luma and chroma, because of the 2x2 blocks
332
333
0
  memset( NO_WARNING_class_memaccess( m_ctuData ),             0, sizeof( CtuData             ) * m_ctuDataSize );
334
0
  memset( NO_WARNING_class_memaccess( m_cuMap ),               0, sizeof( CodingUnit*         ) * m_cuMapSize );
335
0
  memset( NO_WARNING_class_memaccess( m_colMiMap ), CO_NOT_VALID, sizeof( ColocatedMotionInfo ) * m_colMiMapSize );
336
337
0
  const ptrdiff_t ctuSampleSizeL  = pcv->maxCUHeight * pcv->maxCUWidth;
338
0
  const ptrdiff_t ctuSampleSizeC  = isChromaEnabled( pcv->chrFormat ) ? ( ctuSampleSizeL >> ( getChannelTypeScaleX( CH_C, pcv->chrFormat) + getChannelTypeScaleY( CH_C, pcv->chrFormat ) ) ) : 0;
339
0
  const ptrdiff_t ctuSampleSize   = ctuSampleSizeL + 2 * ctuSampleSizeC;
340
0
  const ptrdiff_t ctuCuMapSize    = pcv->num4x4CtuBlks;
341
0
  const ptrdiff_t ctuColMiMapSize = pcv->num8x8CtuBlks;
342
343
0
  hasIbcBlock.clear();
344
0
  hasIbcBlock.resize( pcv->heightInCtus, 0 );
345
346
0
  for( int y = 0; y < pcv->heightInCtus; y++ )
347
0
  {
348
0
    for( int x = 0; x < pcv->widthInCtus; x++ )
349
0
    {
350
0
      int i = y * pcv->widthInCtus + x;
351
352
0
      m_ctuData[i].lineIdx = y;
353
0
      m_ctuData[i].colIdx  = x;
354
0
      m_ctuData[i].ctuIdx  = i;
355
356
0
      for( int j = 0; j < 2; j++ )
357
0
      {
358
0
        m_ctuData[i].cuPtr[j] = &m_cuMap[( 2 * i + j ) * ctuCuMapSize];
359
0
      }
360
361
0
      m_ctuData[i].colMotion         = &m_colMiMap[i * ctuColMiMapSize];
362
0
      m_ctuData[i].predBufOffset     = i * ctuSampleSize;
363
0
      m_ctuData[i].dmvrMvCacheOffset = i * pcv->num8x8CtuBlks;
364
0
    }
365
0
  }
366
0
}
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
0
{
390
0
  PelUnitBuf ret;
391
0
  ret.chromaFormat = unit.chromaFormat;
392
0
  ret.bufs.resize_noinit( getNumberValidComponents( unit.chromaFormat ) );
393
394
0
  if( unit.Y().valid() )
395
0
  {
396
0
    ret.bufs[0].buf    = m_predBuf + unit.predBufOff;
397
0
    ret.bufs[0].stride = unit.blocks[0].width;
398
0
    ret.bufs[0].width  = unit.blocks[0].width;
399
0
    ret.bufs[0].height = unit.blocks[0].height;
400
0
  }
401
402
0
  if( isChromaEnabled( unit.chromaFormat ) )
403
0
  {
404
0
    if( unit.Cb().valid() )
405
0
    {
406
0
      ret.bufs[1].buf    = m_predBuf + unit.predBufOff + unit.Y().area();
407
0
      ret.bufs[1].stride = unit.blocks[1].width;
408
0
      ret.bufs[1].width  = unit.blocks[1].width;
409
0
      ret.bufs[1].height = unit.blocks[1].height;
410
0
    }
411
412
0
    if( unit.Cr().valid() )
413
0
    {
414
0
      ret.bufs[2].buf    = m_predBuf + unit.predBufOff + unit.Y().area() + unit.Cb().area();
415
0
      ret.bufs[2].stride = unit.blocks[2].width;
416
0
      ret.bufs[2].width  = unit.blocks[2].width;
417
0
      ret.bufs[2].height = unit.blocks[2].height;
418
0
    }
419
0
  }
420
421
0
  return ret;
422
0
}
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
0
{
470
0
  if( guess && guess->blocks[_chType].contains( pos ) ) return guess;
471
472
0
  const int yshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleY( _chType, curCu.chromaFormat );
473
0
  const int ydiff      = ( pos.y >> yshift ) - ( curCu.blocks[_chType].y >> yshift ); // ( a <= b ) ==> a - b <= 0
474
0
  const int xshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleX( _chType, curCu.chromaFormat );
475
0
  const int xdiff      = ( pos.x >> xshift ) - ( curCu.blocks[_chType].x >> xshift );
476
0
  const bool sameCTU   = !ydiff && !xdiff;
477
478
0
  const CodingUnit* cu = nullptr;
479
480
0
  if( sameCTU )
481
0
  {
482
0
    cu = curCu.ctuData->cuPtr[_chType][inCtuPos( pos, _chType )];
483
0
  }
484
0
  else if( ydiff > 0 || xdiff > ( 1 - sps->getEntropyCodingSyncEnabledFlag() ) || ( ydiff == 0 && xdiff > 0 ) )
485
0
  {
486
0
    return nullptr;
487
0
  }
488
0
  else
489
0
  {
490
0
    cu = getCU( pos, _chType );
491
0
  }
492
493
0
  if( !cu || ( sameCTU && cu->idx > curCu.idx ) ) return nullptr;
494
0
  else if( sameCTU ) return cu;
495
496
0
  if( cu->slice->getIndependentSliceIdx() == curCu.slice->getIndependentSliceIdx() && cu->tileIdx == curCu.tileIdx )
497
0
  {
498
0
    return cu;
499
0
  }
500
0
  else
501
0
  {
502
0
    return nullptr;
503
0
  }
504
0
}
505
506
const CodingUnit* CodingStructure::getCURestricted( const Position &pos, const Position curPos, const unsigned curSliceIdx, const unsigned curTileIdx, const ChannelType _chType ) const
507
0
{
508
0
  const int yshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleY( _chType, area.chromaFormat );
509
0
  const int ydiff      = ( pos.y >> yshift ) - ( curPos.y >> yshift ); // ( a <= b ) ==> a - b <= 0
510
0
  const int xshift     = pcv->maxCUWidthLog2 - getChannelTypeScaleX( _chType, area.chromaFormat );
511
0
  const int xdiff      = ( pos.x >> xshift ) - ( curPos.x >> xshift );
512
0
  const bool sameCTU   = !ydiff && !xdiff;
513
514
0
  const CodingUnit* cu = nullptr;
515
  
516
0
  if( sameCTU )
517
0
  {
518
0
    return getCU( pos, _chType );
519
0
  }
520
0
  else if( ydiff > 0 || xdiff > ( 1 - sps->getEntropyCodingSyncEnabledFlag() ) )
521
0
  {
522
0
    return nullptr;
523
0
  }
524
0
  else
525
0
  {
526
0
    cu = getCU( pos, _chType );
527
0
  }
528
529
0
  if( cu && cu->slice->getIndependentSliceIdx() == curSliceIdx && cu->tileIdx == curTileIdx )
530
0
  {
531
0
    return cu;
532
0
  }
533
0
  else
534
0
  {
535
0
    return nullptr;
536
0
  }
537
0
}
538
539
540
void CodingStructure::initVIbcBuf( int numCtuLines, ChromaFormat chromaFormatIDC, int ctuSize )
541
0
{
542
0
  m_virtualIBCbuf.resize( numCtuLines );
543
0
  for( auto &buf: m_virtualIBCbuf )
544
545
0
  if (buf.bufs.empty())
546
0
  {
547
0
    m_IBCBufferWidth = g_IBCBufferSize / ctuSize;
548
0
    buf.create(UnitArea(chromaFormatIDC, Area(0, 0, m_IBCBufferWidth, ctuSize)));
549
0
  }
550
551
0
}
552
553
void CodingStructure::fillIBCbuffer( CodingUnit &cu, int lineIdx )
554
0
{
555
0
  for( const CompArea &area : cu.blocks )
556
0
  {
557
0
    if (!area.valid())
558
0
      continue;
559
560
0
    const unsigned int lcuWidth = sps->getMaxCUWidth();
561
0
    const int shiftSampleHor = getComponentScaleX(area.compID(), cu.chromaFormat);
562
0
    const int shiftSampleVer = getComponentScaleY(area.compID(), cu.chromaFormat);
563
0
    const int ctuSizeVerLog2 = getLog2(lcuWidth) - shiftSampleVer;
564
0
    const int pux = area.x & ((m_IBCBufferWidth >> shiftSampleHor) - 1);
565
0
    const int puy = area.y & (( 1 << ctuSizeVerLog2 ) - 1);
566
0
    const CompArea dstArea = CompArea(area.compID(), Position(pux, puy), Size(area.width, area.height));
567
0
    CPelBuf srcBuf = getRecoBuf(area);
568
0
    PelBuf dstBuf = m_virtualIBCbuf[lineIdx].getBuf(dstArea);
569
570
0
    dstBuf.copyFrom(srcBuf);
571
0
  }
572
0
}
573
574
}