Coverage Report

Created: 2026-04-01 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vvenc/source/Lib/CommonLib/Unit.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     Unit.cpp
45
 *  \brief    defines unit as a set of blocks and basic unit types (coding, prediction, transform)
46
 */
47
48
#include "Unit.h"
49
#include "Picture.h"
50
#include "UnitTools.h"
51
#include "UnitPartitioner.h"
52
53
//! \ingroup CommonLib
54
//! \{
55
56
namespace vvenc {
57
58
 // ---------------------------------------------------------------------------
59
 // block method definitions
60
 // ---------------------------------------------------------------------------
61
62
void CompArea::xRecalcLumaToChroma()
63
0
{
64
0
  const uint32_t csx = getComponentScaleX(compID, chromaFormat);
65
0
  const uint32_t csy = getComponentScaleY(compID, chromaFormat);
66
67
0
  x      >>= csx;
68
0
  y      >>= csy;
69
0
  width  >>= csx;
70
0
  height >>= csy;
71
0
}
72
73
Position CompArea::chromaPos() const
74
0
{
75
0
  if (isLuma(compID))
76
0
  {
77
0
    uint32_t scaleX = getComponentScaleX(compID, chromaFormat);
78
0
    uint32_t scaleY = getComponentScaleY(compID, chromaFormat);
79
80
0
    return Position(x >> scaleX, y >> scaleY);
81
0
  }
82
0
  else
83
0
  {
84
0
    return *this;
85
0
  }
86
0
}
87
88
Size CompArea::lumaSize() const
89
0
{
90
0
  if( isChroma( compID ) )
91
0
  {
92
0
    uint32_t scaleX = getComponentScaleX( compID, chromaFormat );
93
0
    uint32_t scaleY = getComponentScaleY( compID, chromaFormat );
94
95
0
    return Size( width << scaleX, height << scaleY );
96
0
  }
97
0
  else
98
0
  {
99
0
    return *this;
100
0
  }
101
0
}
102
103
Size CompArea::chromaSize() const
104
0
{
105
0
  if( isLuma( compID ) )
106
0
  {
107
0
    uint32_t scaleX = getComponentScaleX( compID, chromaFormat );
108
0
    uint32_t scaleY = getComponentScaleY( compID, chromaFormat );
109
110
0
    return Size( width >> scaleX, height >> scaleY );
111
0
  }
112
0
  else
113
0
  {
114
0
    return *this;
115
0
  }
116
0
}
117
118
Position CompArea::lumaPos() const
119
0
{
120
0
  if( isChroma( compID ) )
121
0
  {
122
0
    uint32_t scaleX = getComponentScaleX( compID, chromaFormat );
123
0
    uint32_t scaleY = getComponentScaleY( compID, chromaFormat );
124
125
0
    return Position( x << scaleX, y << scaleY );
126
0
  }
127
0
  else
128
0
  {
129
0
    return *this;
130
0
  }
131
0
}
132
133
Position CompArea::compPos( const ComponentID compID ) const
134
0
{
135
0
  return isLuma( compID ) ? lumaPos() : chromaPos();
136
0
}
137
138
Position CompArea::chanPos( const ChannelType chType ) const
139
0
{
140
0
  return isLuma( chType ) ? lumaPos() : chromaPos();
141
0
}
142
143
// ---------------------------------------------------------------------------
144
// unit method definitions
145
// ---------------------------------------------------------------------------
146
147
0
UnitArea::UnitArea(const ChromaFormat _chromaFormat) : chromaFormat(_chromaFormat) { }
148
149
0
UnitArea::UnitArea(const ChromaFormat _chromaFormat, const Area& _area) : chromaFormat(_chromaFormat), blocks(getNumberValidComponents(_chromaFormat))
150
0
{
151
0
  const uint32_t numCh = getNumberValidComponents(chromaFormat);
152
153
0
  for (uint32_t i = 0; i < numCh; i++)
154
0
  {
155
0
    new (&blocks[i]) CompArea(ComponentID(i), chromaFormat, _area, true);
156
0
  }
157
0
}
158
159
0
UnitArea::UnitArea(const ChromaFormat _chromaFormat, const CompArea&  blkY) : chromaFormat(_chromaFormat), blocks { blkY } {}
160
161
0
UnitArea::UnitArea(const ChromaFormat _chromaFormat,       CompArea&& blkY) : chromaFormat(_chromaFormat), blocks { std::forward<CompArea>(blkY) } {}
162
163
0
UnitArea::UnitArea(const ChromaFormat _chromaFormat, const CompArea&  blkY, const CompArea& blkCb, const CompArea& blkCr)  : chromaFormat(_chromaFormat), blocks { blkY, blkCb, blkCr } {}
164
165
0
UnitArea::UnitArea(const ChromaFormat _chromaFormat,       CompArea&& blkY,      CompArea&& blkCb,      CompArea&& blkCr) : chromaFormat(_chromaFormat), blocks { std::forward<CompArea>(blkY), std::forward<CompArea>(blkCb), std::forward<CompArea>(blkCr) } {}
166
167
bool UnitArea::contains(const UnitArea& other) const
168
0
{
169
0
  bool ret = true;
170
0
  bool any = false;
171
172
0
  for( const auto &blk : other.blocks )
173
0
  {
174
0
    if( blk.valid() && blocks[blk.compID].valid() )
175
0
    {
176
0
      ret &= blocks[blk.compID].contains( blk );
177
0
      any = true;
178
0
    }
179
0
  }
180
181
0
  return any && ret;
182
0
}
183
184
bool UnitArea::contains( const UnitArea& other, const ChannelType chType ) const
185
0
{
186
0
  bool ret = true;
187
0
  bool any = false;
188
189
0
  for( const auto &blk : other.blocks )
190
0
  {
191
0
    if( toChannelType( blk.compID ) == chType && blk.valid() && blocks[blk.compID].valid() )
192
0
    {
193
0
      ret &= blocks[blk.compID].contains( blk );
194
0
      any = true;
195
0
    }
196
0
  }
197
198
0
  return any && ret;
199
0
}
200
201
void UnitArea::repositionTo(const UnitArea& unitArea)
202
0
{
203
0
  for(uint32_t i = 0; i < blocks.size(); i++)
204
0
  {
205
0
    blocks[i].repositionTo(unitArea.blocks[i]);
206
0
  }
207
0
}
208
209
const UnitArea UnitArea::singleComp(const ComponentID compID) const
210
0
{
211
0
  UnitArea ret(chromaFormat);
212
213
0
  for (const auto &blk : blocks)
214
0
  {
215
0
    if (blk.compID == compID)
216
0
    {
217
0
      ret.blocks.push_back(blk);
218
0
    }
219
0
    else
220
0
    {
221
0
      ret.blocks.push_back(CompArea());
222
0
    }
223
0
  }
224
225
0
  return ret;
226
0
}
227
228
const UnitArea UnitArea::singleChan(const ChannelType chType) const
229
0
{
230
0
  UnitArea ret(chromaFormat);
231
232
0
  for (const auto &blk : blocks)
233
0
  {
234
0
    if (toChannelType(blk.compID) == chType)
235
0
    {
236
0
      ret.blocks.push_back(blk);
237
0
    }
238
0
    else
239
0
    {
240
0
      ret.blocks.push_back(CompArea());
241
0
    }
242
0
  }
243
244
0
  return ret;
245
0
}
246
247
// ---------------------------------------------------------------------------
248
// coding unit method definitions
249
// ---------------------------------------------------------------------------
250
251
0
CodingUnit::CodingUnit(const UnitArea& unit)                                : UnitArea(unit),                 cs(nullptr), slice(nullptr), chType( CH_L ), next(nullptr), firstTU(nullptr), lastTU(nullptr) { initData(); initPuData(); }
252
0
CodingUnit::CodingUnit(const ChromaFormat _chromaFormat, const Area& _area) : UnitArea(_chromaFormat, _area), cs(nullptr), slice(nullptr), chType( CH_L ), next(nullptr), firstTU(nullptr), lastTU(nullptr) { initData(); initPuData(); }
253
254
CodingUnit& CodingUnit::operator=( const CodingUnit& other )
255
0
{
256
0
  slice             = other.slice;
257
0
  predMode          = other.predMode;
258
0
  qtDepth           = other.qtDepth;
259
0
  depth             = other.depth;
260
0
  btDepth           = other.btDepth;
261
0
  mtDepth           = other.mtDepth;
262
0
  splitSeries       = other.splitSeries;
263
0
  skip              = other.skip;
264
0
  mmvdSkip          = other.mmvdSkip;
265
0
  affine            = other.affine;
266
0
  affineType        = other.affineType;
267
0
  colorTransform    = other.colorTransform;
268
0
  geo               = other.geo;
269
0
  geo               = other.geo;
270
0
  bdpcmM[CH_L]      = other.bdpcmM[CH_L];
271
0
  bdpcmM[CH_C]      = other.bdpcmM[CH_C];
272
0
  qp                = other.qp;
273
0
  chromaQpAdj       = other.chromaQpAdj;
274
0
  rootCbf           = other.rootCbf;
275
0
  sbtInfo           = other.sbtInfo;
276
0
  mtsFlag           = other.mtsFlag;
277
0
  lfnstIdx          = other.lfnstIdx;
278
0
  tileIdx           = other.tileIdx;
279
0
  imv               = other.imv;
280
0
  imvNumCand        = other.imvNumCand;
281
0
  BcwIdx            = other.BcwIdx;
282
283
0
  smvdMode          = other.smvdMode;
284
0
  ispMode           = other.ispMode;
285
0
  mipFlag           = other.mipFlag;
286
287
0
  treeType          = other.treeType;
288
0
  modeType          = other.modeType;
289
0
  modeTypeSeries    = other.modeTypeSeries;
290
291
0
  const IntraPredictionData& ipd = other;
292
0
  *this = ipd;
293
294
0
  const InterPredictionData& tpd = other;
295
0
  *this = tpd;
296
0
  return *this;
297
0
}
298
299
void CodingUnit::initData()
300
0
{
301
0
  predMode          = NUMBER_OF_PREDICTION_MODES;
302
0
  qtDepth           = 0;
303
0
  depth             = 0;
304
0
  btDepth           = 0;
305
0
  mtDepth           = 0;
306
0
  splitSeries       = 0;
307
0
  skip              = false;
308
0
  mmvdSkip          = false;
309
0
  affine            = false;
310
0
  affineType        = 0;
311
0
  colorTransform    = false;
312
0
  geo               = false;
313
0
  bdpcmM[CH_L]      = 0;
314
0
  bdpcmM[CH_C]      = 0;
315
0
  qp                = 0;
316
0
  chromaQpAdj       = 0;
317
0
  rootCbf           = true;
318
0
  sbtInfo           = 0;
319
0
  mtsFlag           = 0;
320
0
  lfnstIdx          = 0;
321
0
  tileIdx           = 0;
322
0
  imv               = IMV_OFF;
323
0
  imvNumCand        = 0;
324
0
  BcwIdx            = BCW_DEFAULT;
325
0
  smvdMode          = 0;
326
0
  ispMode           = 0;
327
0
  mipFlag           = false;
328
329
0
  treeType          = TREE_D;
330
0
  modeType          = MODE_TYPE_ALL;
331
0
  modeTypeSeries    = 0;
332
0
  mcControl         = 0;
333
0
}
334
335
336
337
338
// ---------------------------------------------------------------------------
339
// prediction unit method definitions
340
// ---------------------------------------------------------------------------
341
342
void CodingUnit::initPuData()
343
0
{
344
  // intra data - need this default initialization for PCM
345
0
  intraDir[0]       = DC_IDX;
346
0
  intraDir[1]       = PLANAR_IDX;
347
0
  multiRefIdx       = 0;
348
0
  mipTransposedFlag = false;
349
350
  // inter data
351
0
  mergeFlag         = false;
352
0
  ciip              = false;
353
0
  mvRefine          = false;
354
0
  mmvdMergeFlag     = false;
355
0
  mergeIdx          = MAX_UCHAR;
356
0
  geoSplitDir       = MAX_UCHAR;
357
0
  geoMergeIdx       = { MAX_SCHAR, MAX_SCHAR };
358
359
0
  mcControl         = 0;
360
361
0
  interDir          = MAX_UCHAR;
362
0
  mmvdMergeIdx.val  = MmvdIdx::INVALID;
363
0
  mergeType         = MRG_TYPE_DEFAULT_N;
364
365
0
  if( mvdL0SubPu )
366
0
  {
367
0
    int maxDmvrMvds = std::max<int>( 1, lwidth() >> DMVR_SUBCU_SIZE_LOG2 ) * std::max<int>( 1, lheight() >> DMVR_SUBCU_SIZE_LOG2 );
368
0
    for (uint32_t i = 0; i < maxDmvrMvds; i++)
369
0
    {
370
0
      mvdL0SubPu[i].setZero();
371
0
    }
372
0
  }
373
374
0
  for (uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++)
375
0
  {
376
0
    mvpIdx[i] = MAX_UCHAR;
377
0
    mvpNum[i] = MAX_UCHAR;
378
0
    refIdx[i] = -1;
379
0
    for( uint32_t j = 0; j < 3; j++ )
380
0
    {
381
0
      mvd[i][j].setZero();
382
0
      mv [i][j].setZero();
383
0
    }
384
0
  }
385
0
}
386
387
CodingUnit& CodingUnit::operator=( const IntraPredictionData& other )
388
0
{
389
0
  for( uint32_t i = 0; i < MAX_NUM_CH; i++ )
390
0
  {
391
0
    intraDir[ i ] = other.intraDir[ i ];
392
0
  }
393
0
  mipTransposedFlag = other.mipTransposedFlag;
394
0
  multiRefIdx       = other.multiRefIdx;
395
0
  return *this;
396
0
}
397
398
CodingUnit& CodingUnit::operator=( const InterPredictionData& other )
399
0
{
400
0
  mergeFlag         = other.mergeFlag;
401
0
  mergeIdx          = other.mergeIdx;
402
0
  geoSplitDir       = other.geoSplitDir;
403
0
  geoMergeIdx       = other.geoMergeIdx;
404
0
  mmvdMergeFlag     = other.mmvdMergeFlag;
405
0
  mmvdMergeIdx      = other.mmvdMergeIdx;
406
0
  interDir          = other.interDir;
407
0
  mergeType         = other.mergeType;
408
0
  mvRefine          = other.mvRefine;
409
410
0
  if( other.mergeFlag && mvdL0SubPu )
411
0
  {
412
0
    const int maxDmvrMvds = std::max<int>( 1, lwidth() >> DMVR_SUBCU_SIZE_LOG2 ) * std::max<int>( 1, lheight() >> DMVR_SUBCU_SIZE_LOG2 );
413
414
0
    memcpy( mvdL0SubPu, other.mvdL0SubPu, sizeof( Mv ) * maxDmvrMvds );
415
0
  }
416
417
0
  for (uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++)
418
0
  {
419
0
    mvpIdx[i]   = other.mvpIdx[i];
420
0
    mvpNum[i]   = other.mvpNum[i];
421
0
    refIdx[i]   = other.refIdx[i];
422
0
    for( uint32_t j = 0; j < 3; j++ )
423
0
    {
424
0
      mvd[i][j] = other.mvd[i][j];
425
0
      mv [i][j] = other.mv [i][j];
426
0
    }
427
0
  }
428
0
  ciip = other.ciip;
429
0
  return *this;
430
0
}
431
432
CodingUnit& CodingUnit::operator=( const MotionInfo& mi )
433
0
{
434
0
  interDir = mi.interDir();
435
436
0
  for( uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++ )
437
0
  {
438
0
    refIdx[i] = mi.miRefIdx[i];
439
0
    mv [i][0] = mi.mv[i];
440
0
  }
441
442
0
  return *this;
443
0
}
444
445
const MotionInfo& CodingUnit::getMotionInfo() const
446
0
{
447
0
  return cs->getMotionInfo( lumaPos() );
448
0
}
449
450
const MotionInfo& CodingUnit::getMotionInfo( const Position& pos ) const
451
0
{
452
0
  CHECKD( !Y().contains( pos ), "Trying to access motion info outsied of PU" );
453
0
  return cs->getMotionInfo( pos );
454
0
}
455
456
MotionBuf CodingUnit::getMotionBuf()
457
0
{
458
0
  return cs->getMotionBuf( *this );
459
0
}
460
461
CMotionBuf CodingUnit::getMotionBuf() const
462
0
{
463
0
  return cs->getMotionBuf( *this );
464
0
}
465
466
467
// ---------------------------------------------------------------------------
468
// transform unit method definitions
469
// ---------------------------------------------------------------------------
470
471
0
TransformUnit::TransformUnit(const UnitArea& unit) : UnitArea(unit), cu(nullptr), cs(nullptr), chType( CH_L ), next( nullptr )
472
0
{
473
0
  for( unsigned i = 0; i < MAX_NUM_TBLOCKS; i++ )
474
0
  {
475
0
    m_coeffs[i] = nullptr;
476
0
  }
477
478
0
  initData();
479
0
}
480
481
0
TransformUnit::TransformUnit(const ChromaFormat _chromaFormat, const Area& _area) : UnitArea(_chromaFormat, _area), cu(nullptr), cs(nullptr), chType( CH_L ), next( nullptr )
482
0
{
483
0
  for( unsigned i = 0; i < MAX_NUM_TBLOCKS; i++ )
484
0
  {
485
0
    m_coeffs[i] = nullptr;
486
0
  }
487
488
0
  initData();
489
0
}
490
491
void TransformUnit::initData()
492
0
{
493
0
  for( unsigned i = 0; i < MAX_NUM_TBLOCKS; i++ )
494
0
  {
495
0
    cbf[i]      = 0;
496
0
    mtsIdx[i]   = MTS_DCT2_DCT2;
497
0
    lastPos[i]  = 0;
498
0
  }
499
0
  depth       = 0;
500
0
  noResidual  = false;
501
0
  jointCbCr   = 0;
502
0
  chromaAdj   = 0;
503
0
}
504
505
void TransformUnit::init(TCoeffSig** coeffs)
506
0
{
507
0
  uint32_t numBlocks = getNumberValidComponents( chromaFormat );
508
509
0
  for (uint32_t i = 0; i < numBlocks; i++)
510
0
  {
511
0
    m_coeffs[i] = coeffs[i];
512
0
  }
513
0
}
514
515
TransformUnit& TransformUnit::operator=( const TransformUnit& other )
516
0
{
517
0
  CHECK( chromaFormat != other.chromaFormat, "Incompatible formats" );
518
519
0
  unsigned numBlocks = getNumberValidTBlocks(*cs->pcv);
520
0
  for( unsigned i = 0; i < numBlocks; i++ )
521
0
  {
522
0
    CHECKD( blocks[i].area() != other.blocks[i].area(), "Transformation units cover different areas" );
523
524
0
    cbf[i]      = other.cbf[i];
525
0
    bool cpyRsi = other.cbf[i] || ( i && other.jointCbCr && numBlocks > 1 && ( TU::getCbf( other, COMP_Cb ) || TU::getCbf( other, COMP_Cr ) ) );
526
0
    if( m_coeffs[i] && other.m_coeffs[i] && m_coeffs[i] != other.m_coeffs[i] && cpyRsi )
527
0
    {
528
0
      uint32_t area = blocks[i].area();
529
0
      memcpy( m_coeffs[i], other.m_coeffs[i], sizeof( TCoeffSig ) * area );
530
0
    }
531
0
    mtsIdx[i]   = other.mtsIdx[i];
532
0
    lastPos[i]  = other.lastPos[i];
533
0
  }
534
0
  depth         = other.depth;
535
0
  noResidual    = other.noResidual;
536
0
  jointCbCr     = other.jointCbCr;
537
0
  return *this;
538
0
}
539
540
void TransformUnit::copyComponentFrom( const TransformUnit& other, const ComponentID i )
541
0
{
542
0
  CHECK( chromaFormat != other.chromaFormat, "Incompatible formats" );
543
0
  CHECKD( blocks[i].area() != other.blocks[i].area(), "Transformation units cover different areas" );
544
545
0
  bool cpyRsi = other.cbf[i] || ( i && other.jointCbCr && blocks.size() > 1 && ( TU::getCbf( other, COMP_Cb ) || TU::getCbf( other, COMP_Cr ) ) );
546
0
  if( m_coeffs[i] && other.m_coeffs[i] && m_coeffs[i] != other.m_coeffs[i] && cpyRsi )
547
0
  {
548
0
    uint32_t area = blocks[i].area();
549
0
    memcpy( m_coeffs[i], other.m_coeffs[i], sizeof( TCoeffSig ) * area );
550
0
  }
551
552
0
  cbf[i]      = other.cbf[i];
553
554
0
  depth       = other.depth;
555
0
  mtsIdx[i]   = other.mtsIdx[i];
556
0
  noResidual  = other.noResidual;
557
0
  jointCbCr   = isChroma( i ) ? other.jointCbCr : jointCbCr;
558
0
  lastPos[i]  = other.lastPos[i];
559
0
}
560
561
void TransformUnit::checkTuNoResidual( unsigned idx )
562
0
{
563
0
  if( CU::getSbtIdx( cu->sbtInfo ) == SBT_OFF_DCT )
564
0
  {
565
0
    return;
566
0
  }
567
568
0
  if( ( CU::getSbtPos( cu->sbtInfo ) == SBT_POS0 && idx == 1 ) || ( CU::getSbtPos( cu->sbtInfo ) == SBT_POS1 && idx == 0 ) )
569
0
  {
570
0
    noResidual = true;
571
0
  }
572
0
}
573
574
int TransformUnit::getTbAreaAfterCoefZeroOut(ComponentID compID) const
575
0
{
576
0
  int tbArea = blocks[compID].width * blocks[compID].height;
577
0
  int tbZeroOutWidth = blocks[compID].width;
578
0
  int tbZeroOutHeight = blocks[compID].height;
579
580
0
  if (cs->sps->MTS && cu->sbtInfo != 0 && blocks[compID].width <= 32 && blocks[compID].height <= 32 && compID == COMP_Y)
581
0
  {
582
0
    tbZeroOutWidth = (blocks[compID].width == 32) ? 16 : tbZeroOutWidth;
583
0
    tbZeroOutHeight = (blocks[compID].height == 32) ? 16 : tbZeroOutHeight;
584
0
  }
585
0
  tbZeroOutWidth = std::min<int>(JVET_C0024_ZERO_OUT_TH, tbZeroOutWidth);
586
0
  tbZeroOutHeight = std::min<int>(JVET_C0024_ZERO_OUT_TH, tbZeroOutHeight);
587
0
  tbArea = tbZeroOutWidth * tbZeroOutHeight;
588
0
  return tbArea;
589
0
}
590
591
} // namespace vvenc
592
593
//! \}
594