Coverage Report

Created: 2026-10-17 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/vvenc/source/Lib/CommonLib/ContextModelling.h
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
/** \file     ContextModelling.h
43
 *  \brief    Classes providing probability descriptions and contexts (header)
44
 */
45
46
#pragma once
47
48
#include "CommonDef.h"
49
#include "Contexts.h"
50
#include "Slice.h"
51
#include "Unit.h"
52
#include "UnitPartitioner.h"
53
54
#include <bitset>
55
56
//! \ingroup CommonLib
57
//! \{
58
59
namespace vvenc
60
{
61
62
struct CtxTpl
63
{
64
  // lower 5 bits are absSum1, upper 3 bits are numPos
65
  uint8_t ctxTpl;
66
};
67
68
struct CoeffCodingContext
69
{
70
public:
71
  CoeffCodingContext( const TransformUnit& tu, ComponentID component, bool signHide, bool bdpcm = false, CtxTpl* tplBuf = nullptr );
72
public:
73
  void  initSubblock    ( int SubsetId, bool sigGroupFlag = false );
74
public:
75
10.7k
  void  resetSigGroup   ()                      { m_sigCoeffGroupFlag.reset( m_subSetPos ); }
76
432k
  void  setSigGroup     ()                      { m_sigCoeffGroupFlag.set( m_subSetPos ); }
77
0
  bool  noneSigGroup    ()                      { return m_sigCoeffGroupFlag.none(); }
78
426k
  int   lastSubSet      ()                      { return ( maxNumCoeff() - 1 ) >> log2CGSize(); }
79
362k
  bool  isLastSubSet    ()                      { return lastSubSet() == m_subSetId; }
80
63.9k
  bool  only1stSigGroup ()                      { return m_sigCoeffGroupFlag.count()-m_sigCoeffGroupFlag[lastSubSet()]==0; }
81
844k
  void  setScanPosLast  ( int       posLast )   { m_scanPosLast = posLast; }
82
public:
83
0
  ComponentID     compID          ()                        const { return m_compID; }
84
596k
  int             subSetId        ()                        const { return m_subSetId; }
85
0
  int             subSetPos       ()                        const { return m_subSetPos; }
86
43.4k
  int             cgPosY          ()                        const { return m_subSetPosY; }
87
43.4k
  int             cgPosX          ()                        const { return m_subSetPosX; }
88
1.68M
  unsigned        width           ()                        const { return m_width; }
89
0
  unsigned        height          ()                        const { return m_height; }
90
5.63k
  unsigned        log2CGWidth     ()                        const { return m_log2CGWidth; }
91
0
  unsigned        log2CGHeight    ()                        const { return m_log2CGHeight; }
92
6.06M
  unsigned        log2CGSize      ()                        const { return m_log2CGSize; }
93
4.95M
  int             maxLog2TrDRange ()                        const { return m_maxLog2TrDynamicRange; }
94
6.86M
  unsigned        maxNumCoeff     ()                        const { return m_maxNumCoeff; }
95
12.0M
  int             scanPosLast     ()                        const { return m_scanPosLast; }
96
10.8M
  int             minSubPos       ()                        const { return m_minSubPos; }
97
387k
  int             maxSubPos       ()                        const { return m_maxSubPos; }
98
869k
  bool            isLast          ()                        const { return ( ( m_scanPosLast >> m_log2CGSize ) == m_subSetId ); }
99
43.4k
  bool            isNotFirst      ()                        const { return ( m_subSetId != 0 ); }
100
0
  bool            isSigGroup      ( int scanPosCG )         const { return m_sigCoeffGroupFlag[m_scanCG[scanPosCG].idx]; }
101
1.01M
  bool            isSigGroup      ()                        const { return m_sigCoeffGroupFlag[ m_subSetPos ]; }
102
9.01k
  bool            signHiding      ()                        const { return m_signHiding; }
103
  bool            hideSign        ( int       posFirst,
104
861k
                                    int       posLast   )   const { return ( m_signHiding && ( posLast - posFirst >= SBH_THRESHOLD ) ); }
105
54.0M
  unsigned        blockPos        ( int scanPos )           const { return m_scan[scanPos].idx; }
106
9.14M
  unsigned        posX            ( int scanPos )           const { return m_scan[scanPos].x; }
107
9.14M
  unsigned        posY            ( int scanPos )           const { return m_scan[scanPos].y; }
108
844k
  unsigned        maxLastPosX     ()                        const { return m_maxLastPosX; }
109
844k
  unsigned        maxLastPosY     ()                        const { return m_maxLastPosY; }
110
1.92M
  unsigned        lastXCtxId      ( unsigned  posLastX  )   const { return m_CtxSetLastX( m_lastOffsetX + ( posLastX >> m_lastShiftX ) ); }
111
1.97M
  unsigned        lastYCtxId      ( unsigned  posLastY  )   const { return m_CtxSetLastY( m_lastOffsetY + ( posLastY >> m_lastShiftY ) ); }
112
958k
  unsigned        sigGroupCtxId   ( bool ts = false     )   const { return ts ? m_sigGroupCtxIdTS : m_sigGroupCtxId; }
113
6.06M
  bool            bdpcm           ()                        const { return m_bdpcm; }
114
115
  unsigned sigCtxIdAbs( int scanPos, const TCoeffSig* coeff, const int state )
116
0
  {
117
0
    const uint32_t   posY      = m_scan[scanPos].y;
118
0
    const uint32_t   posX      = m_scan[scanPos].x;
119
0
    const TCoeffSig* pData     = coeff + posX + posY * m_width;
120
0
    const int        diag      = posX + posY;
121
0
    int              numPos    = 0;
122
0
    int              sumAbs    = 0;
123
0
#define UPDATE(x) {int a=abs(x);sumAbs+=std::min(4+(a&1),a);numPos+=!!a;}
124
0
    if( posX < m_width-1 )
125
0
    {
126
0
      UPDATE( pData[1] );
127
0
      if( posX < m_width-2 )
128
0
      {
129
0
        UPDATE( pData[2] );
130
0
      }
131
0
      if( posY < m_height-1 )
132
0
      {
133
0
        UPDATE( pData[m_width+1] );
134
0
      }
135
0
    }
136
0
    if( posY < m_height-1 )
137
0
    {
138
0
      UPDATE( pData[m_width] );
139
0
      if( posY < m_height-2 )
140
0
      {
141
0
        UPDATE( pData[m_width<<1] );
142
0
      }
143
0
    }
144
0
#undef UPDATE
145
146
0
    int ctxOfs = std::min((sumAbs+1)>>1, 3) + ( diag < 2 ? 4 : 0 );
147
148
0
    if( m_chType == CH_L )
149
0
    {
150
0
      ctxOfs += diag < 5 ? 4 : 0;
151
0
    }
152
153
0
    m_tmplCpDiag = diag;
154
0
    m_tmplCpSum1 = sumAbs - numPos;
155
0
    return m_sigFlagCtxSet[std::max( 0, state-1 )]( ctxOfs );
156
0
  }
157
158
  // sigCtxIdAbsWithAcc and absVal1stPass run for every coefficient position of residual coding
159
  ALWAYS_INLINE unsigned sigCtxIdAbsWithAcc( const int scanPos, const int state )
160
5.99M
  {
161
5.99M
    const auto scanEl       = m_scan[scanPos];
162
5.99M
    const uint32_t posY     = scanEl.y;
163
5.99M
    const uint32_t posX     = scanEl.x;
164
5.99M
    const int32_t blkPos    = scanEl.idx;
165
5.99M
    const int      diag     = posX + posY;
166
5.99M
    const int      tplVal   = m_tplBuf[-blkPos].ctxTpl;
167
5.99M
    const int      numPos   = tplVal >> 5u;
168
5.99M
    const int      sumAbs   = tplVal & 31;
169
170
5.99M
    int ctxOfs = std::min( ( sumAbs + 1 ) >> 1, 3 ) + ( diag < 2 ? 4 : 0 );
171
172
5.99M
    if( isLuma( m_chType ) )
173
423k
    {
174
423k
      ctxOfs += diag < 5 ? 4 : 0;
175
423k
    }
176
5.99M
    m_tmplCpDiag = diag;
177
5.99M
    m_tmplCpSum1 = sumAbs - numPos;
178
5.99M
    return m_sigFlagCtxSet[std::max( 0, state-1 )]( ctxOfs );
179
5.99M
  }
180
181
  ALWAYS_INLINE void absVal1stPass( const int scanPos, const TCoeffSig absLevel1 )
182
6.31M
  {
183
6.31M
    CHECKD( !absLevel1, "Shound not be called if '0'!" );
184
185
6.31M
    const auto scanEl     = m_scan[scanPos];
186
6.31M
    const uint32_t posY   = scanEl.y;
187
6.31M
    const uint32_t posX   = scanEl.x;
188
6.31M
    const int32_t  blkPos = scanEl.idx;
189
190
6.31M
    auto update_deps = [&]( int offset )
191
16.5M
    {
192
16.5M
      auto& ctx   = m_tplBuf[-blkPos + offset];
193
16.5M
      ctx.ctxTpl += uint8_t( 32 + absLevel1 );
194
16.5M
    };
195
196
6.31M
    if( posY > 1 ) update_deps( 2 * m_width );
197
6.31M
    if( posY > 0
198
4.24M
     && posX > 0 ) update_deps( m_width + 1 );
199
6.31M
    if( posY > 0 ) update_deps( m_width );
200
6.31M
    if( posX > 1 ) update_deps( 2 );
201
6.31M
    if( posX > 0 ) update_deps( 1 );
202
6.31M
  }
203
  
204
205
  void remAbsVal1stPass( const int scanPos, const TCoeffSig absLevel1 )
206
0
  {
207
0
    CHECKD( !absLevel1, "Shound not be called if '0'!" );
208
209
0
    const auto scanEl     = m_scan[scanPos];
210
0
    const uint32_t posY   = scanEl.y;
211
0
    const uint32_t posX   = scanEl.x;
212
0
    const int32_t  blkPos = scanEl.idx;
213
214
0
    auto update_deps = [&]( int offset )
215
0
    {
216
0
      auto& ctx   = m_tplBuf[-blkPos + offset];
217
0
      ctx.ctxTpl -= uint8_t( 32 + absLevel1 );
218
0
    };
219
220
0
    if( posY > 1 ) update_deps( 2 * m_width );
221
0
    if( posY > 0
222
0
     && posX > 0 ) update_deps( m_width + 1 );
223
0
    if( posY > 0 ) update_deps( m_width );
224
0
    if( posX > 1 ) update_deps( 2 );
225
0
    if( posX > 0 ) update_deps( 1 );
226
0
  }
227
228
  uint8_t ctxOffsetAbs()
229
6.31M
  {
230
6.31M
    int offset = 0;
231
6.31M
    if( m_tmplCpDiag != -1 )
232
5.46M
    {
233
5.46M
      offset  = std::min( m_tmplCpSum1, 4 ) + 1;
234
5.46M
      offset += ( !m_tmplCpDiag ? ( m_chType == CH_L ? 15 : 5 ) : m_chType == CH_L ? m_tmplCpDiag < 3 ? 10 : ( m_tmplCpDiag < 10 ? 5 : 0 ) : 0 );
235
5.46M
    }
236
6.31M
    return uint8_t(offset);
237
6.31M
  }
238
239
5.45M
  unsigned parityCtxIdAbs   ( uint8_t offset )  const { return m_parFlagCtxSet   ( offset ); }
240
6.31M
  unsigned greater1CtxIdAbs ( uint8_t offset )  const { return m_gtxFlagCtxSet[1]( offset ); }
241
5.45M
  unsigned greater2CtxIdAbs ( uint8_t offset )  const { return m_gtxFlagCtxSet[0]( offset ); }
242
243
  unsigned templateAbsSum( int scanPos, const TCoeffSig* coeff, int baseLevel )
244
4.44M
  {
245
4.44M
    const uint32_t   posY = m_scan[scanPos].y;
246
4.44M
    const uint32_t   posX = m_scan[scanPos].x;
247
4.44M
    const TCoeffSig* pData = coeff + posX + posY * m_width;
248
4.44M
    int              sum   = 0;
249
4.44M
    if (posX < m_width - 1)
250
4.36M
    {
251
4.36M
      sum += abs(pData[1]);
252
4.36M
      if (posX < m_width - 2)
253
4.19M
      {
254
4.19M
        sum += abs(pData[2]);
255
4.19M
      }
256
4.36M
      if (posY < m_height - 1)
257
4.22M
      {
258
4.22M
        sum += abs(pData[m_width + 1]);
259
4.22M
      }
260
4.36M
    }
261
4.44M
    if (posY < m_height - 1)
262
4.31M
    {
263
4.31M
      sum += abs(pData[m_width]);
264
4.31M
      if (posY < m_height - 2)
265
4.10M
      {
266
4.10M
        sum += abs(pData[m_width << 1]);
267
4.10M
      }
268
4.31M
    }
269
4.44M
    return std::max(std::min(sum - 5 * baseLevel, 31), 0);
270
4.44M
  }
271
272
  unsigned sigCtxIdAbsTS( int scanPos, const TCoeffSig* coeff )
273
11.6M
  {
274
11.6M
    const uint32_t   posY   = m_scan[scanPos].y;
275
11.6M
    const uint32_t   posX   = m_scan[scanPos].x;
276
11.6M
    const TCoeffSig* posC   = coeff + posX + posY * m_width;
277
11.6M
    int              numPos = 0;
278
20.5M
#define UPDATE(x) {int a=abs(x);numPos+=!!a;}
279
11.6M
    if( posX > 0 )
280
10.4M
    {
281
10.4M
      UPDATE( posC[-1] );
282
10.4M
    }
283
11.6M
    if( posY > 0 )
284
10.1M
    {
285
10.1M
      UPDATE( posC[-(int)m_width] );
286
10.1M
    }
287
11.6M
#undef UPDATE
288
289
11.6M
    return m_tsSigFlagCtxSet( numPos );
290
11.6M
  }
291
292
10.0M
  unsigned parityCtxIdAbsTS   ()                  const { return m_tsParFlagCtxSet(      0 ); }
293
3.43M
  unsigned greaterXCtxIdAbsTS ( uint8_t offset )  const { return m_tsGtxFlagCtxSet( offset ); }
294
295
  unsigned lrg1CtxIdAbsTS(int scanPos, const TCoeffSig* coeff, int bdpcm)
296
10.0M
  {
297
10.0M
    const uint32_t   posY = m_scan[scanPos].y;
298
10.0M
    const uint32_t   posX = m_scan[scanPos].x;
299
10.0M
    const TCoeffSig* posC = coeff + posX + posY * m_width;
300
301
10.0M
    int             numPos = 0;
302
10.0M
#define UPDATE(x) {int a=abs(x);numPos+=!!a;}
303
304
10.0M
    if (bdpcm)
305
9.55M
    {
306
9.55M
      numPos = 3;
307
9.55M
    }
308
473k
    else
309
473k
    {
310
473k
      if (posX > 0)
311
436k
      {
312
436k
        UPDATE(posC[-1]);
313
436k
      }
314
473k
      if (posY > 0)
315
436k
      {
316
436k
        UPDATE(posC[-(int)m_width]);
317
436k
      }
318
473k
    }
319
320
10.0M
#undef UPDATE
321
10.0M
    return m_tsLrg1FlagCtxSet(numPos);
322
10.0M
  }
323
324
  unsigned signCtxIdAbsTS(int scanPos, const TCoeffSig* coeff, int bdpcm)
325
10.0M
  {
326
10.0M
    const uint32_t   posY  = m_scan[scanPos].y;
327
10.0M
    const uint32_t   posX  = m_scan[scanPos].x;
328
10.0M
    const TCoeffSig* pData = coeff + posX + posY * m_width;
329
330
10.0M
    int rightSign = 0, belowSign = 0;
331
10.0M
    unsigned signCtx = 0;
332
333
10.0M
    if (posX > 0)
334
9.04M
    {
335
9.04M
      rightSign = pData[-1];
336
9.04M
    }
337
10.0M
    if (posY > 0)
338
8.54M
    {
339
8.54M
      belowSign = pData[-(int)m_width];
340
8.54M
    }
341
342
10.0M
    if ((rightSign == 0 && belowSign == 0) || ((rightSign*belowSign) < 0))
343
8.72M
    {
344
8.72M
      signCtx = 0;
345
8.72M
    }
346
1.30M
    else if (rightSign >= 0 && belowSign >= 0)
347
497
    {
348
497
      signCtx = 1;
349
497
    }
350
1.30M
    else
351
1.30M
    {
352
1.30M
      signCtx = 2;
353
1.30M
    }
354
10.0M
    if (bdpcm)
355
9.55M
    {
356
9.55M
      signCtx += 3;
357
9.55M
    }
358
10.0M
    return m_tsSignFlagCtxSet(signCtx);
359
10.0M
  }
360
361
  void neighTS(int& rightPixel, int& belowPixel, int scanPos, const TCoeffSig* coeff)
362
14.3M
  {
363
14.3M
    const uint32_t   posY = m_scan[scanPos].y;
364
14.3M
    const uint32_t   posX = m_scan[scanPos].x;
365
14.3M
    const TCoeffSig* data = coeff + posX + posY * m_width;
366
367
14.3M
    rightPixel = belowPixel = 0;
368
369
14.3M
    if (posX > 0)
370
12.8M
    {
371
12.8M
      rightPixel = data[-1];
372
12.8M
    }
373
14.3M
    if (posY > 0)
374
11.7M
    {
375
11.7M
      belowPixel = data[-(int)m_width];
376
11.7M
    }
377
14.3M
  }
378
379
  int deriveModCoeff(int rightPixel, int belowPixel, int absCoeff, int bdpcm = 0)
380
7.48M
  {
381
7.48M
    if (absCoeff == 0)
382
3.66M
      return 0;
383
384
3.82M
    int pred1, absBelow = abs(belowPixel), absRight = abs(rightPixel);
385
386
3.82M
    int absCoeffMod = absCoeff;
387
388
3.82M
    if (bdpcm == 0)
389
503k
    {
390
503k
      pred1 = std::max(absBelow, absRight);
391
392
503k
      if (absCoeff == pred1)
393
0
      {
394
0
        absCoeffMod = 1;
395
0
      }
396
503k
      else
397
503k
      {
398
503k
        absCoeffMod = absCoeff < pred1 ? absCoeff + 1 : absCoeff;
399
503k
      }
400
503k
    }
401
402
3.82M
    return(absCoeffMod);
403
7.48M
  }
404
405
  int decDeriveModCoeff(int rightPixel, int belowPixel, int absCoeff)
406
0
  {
407
0
    if (absCoeff == 0)
408
0
      return 0;
409
0
410
0
    int pred1, absBelow = abs(belowPixel), absRight = abs(rightPixel);
411
0
    pred1 = std::max(absBelow, absRight);
412
0
413
0
    int absCoeffMod;
414
0
415
0
    if (absCoeff == 1 && pred1 > 0)
416
0
    {
417
0
      absCoeffMod = pred1;
418
0
    }
419
0
    else
420
0
    {
421
0
      absCoeffMod = absCoeff - (absCoeff <= pred1);
422
0
    }
423
0
    return(absCoeffMod);
424
0
  }
425
426
  //unsigned templateAbsSumTS( int scanPos, const TCoeffSig* coeff )
427
  //{
428
  //  return 1;
429
  //}
430
431
  int                       remRegBins;
432
433
private:
434
  // constant
435
  const ComponentID         m_compID;
436
  const ChannelType         m_chType;
437
  const unsigned            m_width;
438
  const unsigned            m_height;
439
  const unsigned            m_log2CGWidth;
440
  const unsigned            m_log2CGHeight;
441
  const unsigned            m_log2CGSize;
442
  const unsigned            m_widthInGroups;
443
  const unsigned            m_heightInGroups;
444
  const unsigned            m_log2WidthInGroups;
445
  const unsigned            m_log2BlockWidth;
446
  const unsigned            m_log2BlockHeight;
447
  const unsigned            m_maxNumCoeff;
448
  const bool                m_signHiding;
449
  const int                 m_maxLog2TrDynamicRange;
450
  const ScanElement *       m_scan;
451
  const ScanElement *       m_scanCG;
452
  const CtxSet              m_CtxSetLastX;
453
  const CtxSet              m_CtxSetLastY;
454
  const unsigned            m_maxLastPosX;
455
  const unsigned            m_maxLastPosY;
456
  const int                 m_lastOffsetX;
457
  const int                 m_lastOffsetY;
458
  const int                 m_lastShiftX;
459
  const int                 m_lastShiftY;
460
  // modified
461
  int                       m_scanPosLast;
462
  int                       m_subSetId;
463
  int                       m_subSetPos;
464
  int                       m_subSetPosX;
465
  int                       m_subSetPosY;
466
  int                       m_minSubPos;
467
  int                       m_maxSubPos;
468
  unsigned                  m_sigGroupCtxId;
469
  int                       m_tmplCpSum1;
470
  int                       m_tmplCpDiag;
471
  CtxSet                    m_sigFlagCtxSet[3];
472
  CtxSet                    m_parFlagCtxSet;
473
  CtxSet                    m_gtxFlagCtxSet[2];
474
  unsigned                  m_sigGroupCtxIdTS;
475
  CtxSet                    m_tsSigFlagCtxSet;
476
  CtxSet                    m_tsParFlagCtxSet;
477
  CtxSet                    m_tsGtxFlagCtxSet;
478
  CtxSet                    m_tsLrg1FlagCtxSet;
479
  CtxSet                    m_tsSignFlagCtxSet;
480
  std::bitset<MLS_GRP_NUM>  m_sigCoeffGroupFlag;
481
  const bool                m_bdpcm;
482
  CtxTpl*                   m_tplBuf;
483
};
484
485
486
struct CUCtx
487
{
488
412k
  CUCtx()              : isDQPCoded(false), isChromaQpAdjCoded(false),
489
412k
                         qgStart(false)
490
412k
                         {
491
412k
                           violatesLfnstConstrained[CH_L] = false;
492
412k
                           violatesLfnstConstrained[CH_C] = false;
493
412k
                           violatesMtsCoeffConstraint      = false;
494
412k
                           mtsLastScanPos                  = false;
495
412k
                           lfnstLastScanPos                = false;
496
412k
                         }
497
14.0k
  CUCtx(int _qp)       : isDQPCoded(false), isChromaQpAdjCoded(false),
498
14.0k
                         qgStart(false),
499
14.0k
                         qp(_qp)
500
14.0k
                         {
501
14.0k
                           violatesLfnstConstrained[CH_L] = false;
502
14.0k
                           violatesLfnstConstrained[CH_C] = false;
503
14.0k
                           violatesMtsCoeffConstraint      = false;
504
14.0k
                           mtsLastScanPos                  = false;
505
14.0k
                           lfnstLastScanPos                = false;
506
14.0k
                         }
507
508
  bool      isDQPCoded;
509
  bool      isChromaQpAdjCoded;
510
  bool      qgStart;
511
  bool      lfnstLastScanPos;
512
  int8_t    qp;                   // used as a previous(last) QP and for QP prediction
513
  bool      violatesLfnstConstrained[MAX_NUM_CH];
514
  bool      violatesMtsCoeffConstraint;
515
  bool      mtsLastScanPos;
516
};
517
518
struct MergeCtx
519
{
520
563k
  MergeCtx() : numValidMergeCand( 0 ), hasMergedCandList( false ) { for( unsigned i = 0; i < MRG_MAX_NUM_CANDS; i++ ) mrgTypeNeighbours[i] = MRG_TYPE_DEFAULT_N; }
521
522
  void          setMmvdMergeCandiInfo ( CodingUnit& cu, const MmvdIdx candIdx) const;
523
  void          setMergeInfo          ( CodingUnit& cu, const int     candIdx) const;
524
  void          getMmvdDeltaMv        ( const Slice& slice, const MmvdIdx candIdx, Mv deltaMv[NUM_REF_PIC_LIST_01] ) const;
525
526
  MvField       mvFieldNeighbours [MRG_MAX_NUM_CANDS][NUM_REF_PIC_LIST_01];
527
  uint8_t       BcwIdx            [MRG_MAX_NUM_CANDS];
528
  unsigned char interDirNeighbours[MRG_MAX_NUM_CANDS];
529
  MergeType     mrgTypeNeighbours [MRG_MAX_NUM_CANDS];
530
  int           numValidMergeCand;
531
  bool          hasMergedCandList;
532
533
  MvField       mmvdBaseMv        [MMVD_BASE_MV_NUM][NUM_REF_PIC_LIST_01];
534
  bool          mmvdUseAltHpelIf  [MMVD_BASE_MV_NUM];
535
  bool          useAltHpelIf      [MRG_MAX_NUM_CANDS];
536
};
537
538
struct AffineMergeCtx
539
{
540
0
  AffineMergeCtx() : numValidMergeCand( 0 ) { for ( unsigned i = 0; i < AFFINE_MRG_MAX_NUM_CANDS; i++ ) affineType[i] = AFFINEMODEL_4PARAM; }
541
542
  MvField       mvFieldNeighbours [AFFINE_MRG_MAX_NUM_CANDS][NUM_REF_PIC_LIST_01][3];
543
  unsigned char interDirNeighbours[AFFINE_MRG_MAX_NUM_CANDS];
544
  EAffineModel  affineType        [AFFINE_MRG_MAX_NUM_CANDS];
545
  uint8_t       BcwIdx            [AFFINE_MRG_MAX_NUM_CANDS];
546
  int           numValidMergeCand;
547
  int           maxNumMergeCand;
548
549
  MergeType     mergeType[AFFINE_MRG_MAX_NUM_CANDS];
550
  MotionBuf     subPuMvpMiBuf;
551
};
552
553
554
struct DeriveCtx
555
{
556
  const CodingUnit* cuRestrictedLeft[MAX_NUM_CH];
557
  const CodingUnit* cuRestrictedAbove[MAX_NUM_CH];
558
559
  void determineNeighborCus       ( const CodingStructure& cs, const UnitArea& ua, const ChannelType ch, const TreeType treeType );
560
561
3.48M
  inline static unsigned CtxQtCbf ( const ComponentID compID, const bool prevCbf = false, const int ispIdx = 0 )   { return ( ispIdx && isLuma( compID ) ) ? (2 + (int)prevCbf) : (((compID == COMP_Cr) && prevCbf) ? 1 : 0); }
562
  void     CtxSplit               ( const Partitioner& partitioner, unsigned& ctxSpl, unsigned& ctxQt, unsigned& ctxHv, unsigned& ctxHorBt, unsigned& ctxVerBt, const bool canSplit[6] ) const;
563
  unsigned CtxMipFlag             ( const CodingUnit& cu ) const;
564
0
  unsigned CtxInterDir            ( const CodingUnit& cu ) const { return ( 7 - ((Log2(cu.lumaSize().area()) + 1) >> 1) ); }
565
566
  unsigned CtxModeConsFlag() const
567
0
  {
568
0
    const CodingUnit* cuLeft  = cuRestrictedLeft[CH_L]; const CodingUnit* cuAbove = cuRestrictedAbove[CH_L];
569
0
    return ((cuAbove && cuAbove->predMode == MODE_INTRA) || (cuLeft && cuLeft->predMode == MODE_INTRA)) ? 1 : 0;
570
0
  }
571
572
  unsigned CtxAffineFlag() const
573
0
  {
574
0
    const CodingUnit *cuLeft = cuRestrictedLeft[CH_L]; const CodingUnit *cuAbove = cuRestrictedAbove[CH_L];
575
0
    return (( cuLeft && cuLeft->affine ) ? 1 : 0) + (( cuAbove && cuAbove->affine ) ? 1 : 0);
576
0
  }
577
578
  unsigned CtxSkipFlag() const
579
89.4k
  {
580
89.4k
    const CodingUnit *cuLeft = cuRestrictedLeft[CH_L]; const CodingUnit *cuAbove = cuRestrictedAbove[CH_L];
581
89.4k
    return (( cuLeft && cuLeft->skip ) ? 1 : 0) + (( cuAbove && cuAbove->skip ) ? 1 : 0);
582
89.4k
  }
583
584
  unsigned CtxPredModeFlag() const
585
0
  {
586
0
    const CodingUnit *cuLeft = cuRestrictedLeft[CH_L]; const CodingUnit *cuAbove = cuRestrictedAbove[CH_L];
587
0
    return ((cuAbove && cuAbove->predMode == MODE_INTRA) || (cuLeft && cuLeft->predMode == MODE_INTRA)) ? 1 : 0;
588
0
  }
589
590
  unsigned CtxIBCFlag(const CodingUnit& cu) const
591
262k
  {
592
262k
    const CodingUnit *cuLeft = cuRestrictedLeft[cu.chType]; const CodingUnit *cuAbove = cuRestrictedAbove[cu.chType];
593
262k
    return ((cuLeft && cuLeft->predMode == MODE_IBC) ? 1 : 0) + ((cuAbove && cuAbove->predMode == MODE_IBC) ? 1 : 0);
594
262k
  }
595
596
};
597
598
} // namespace vvenc
599
600
//! \}
601