Coverage Report

Created: 2026-10-28 06:18

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
14.3k
  void  resetSigGroup   ()                      { m_sigCoeffGroupFlag.reset( m_subSetPos ); }
76
567k
  void  setSigGroup     ()                      { m_sigCoeffGroupFlag.set( m_subSetPos ); }
77
0
  bool  noneSigGroup    ()                      { return m_sigCoeffGroupFlag.none(); }
78
561k
  int   lastSubSet      ()                      { return ( maxNumCoeff() - 1 ) >> log2CGSize(); }
79
479k
  bool  isLastSubSet    ()                      { return lastSubSet() == m_subSetId; }
80
82.1k
  bool  only1stSigGroup ()                      { return m_sigCoeffGroupFlag.count()-m_sigCoeffGroupFlag[lastSubSet()]==0; }
81
1.10M
  void  setScanPosLast  ( int       posLast )   { m_scanPosLast = posLast; }
82
public:
83
0
  ComponentID     compID          ()                        const { return m_compID; }
84
787k
  int             subSetId        ()                        const { return m_subSetId; }
85
0
  int             subSetPos       ()                        const { return m_subSetPos; }
86
52.3k
  int             cgPosY          ()                        const { return m_subSetPosY; }
87
52.3k
  int             cgPosX          ()                        const { return m_subSetPosX; }
88
2.21M
  unsigned        width           ()                        const { return m_width; }
89
0
  unsigned        height          ()                        const { return m_height; }
90
6.97k
  unsigned        log2CGWidth     ()                        const { return m_log2CGWidth; }
91
0
  unsigned        log2CGHeight    ()                        const { return m_log2CGHeight; }
92
7.94M
  unsigned        log2CGSize      ()                        const { return m_log2CGSize; }
93
6.54M
  int             maxLog2TrDRange ()                        const { return m_maxLog2TrDynamicRange; }
94
9.08M
  unsigned        maxNumCoeff     ()                        const { return m_maxNumCoeff; }
95
15.8M
  int             scanPosLast     ()                        const { return m_scanPosLast; }
96
14.3M
  int             minSubPos       ()                        const { return m_minSubPos; }
97
510k
  int             maxSubPos       ()                        const { return m_maxSubPos; }
98
1.13M
  bool            isLast          ()                        const { return ( ( m_scanPosLast >> m_log2CGSize ) == m_subSetId ); }
99
50.7k
  bool            isNotFirst      ()                        const { return ( m_subSetId != 0 ); }
100
0
  bool            isSigGroup      ( int scanPosCG )         const { return m_sigCoeffGroupFlag[m_scanCG[scanPosCG].idx]; }
101
1.33M
  bool            isSigGroup      ()                        const { return m_sigCoeffGroupFlag[ m_subSetPos ]; }
102
11.1k
  bool            signHiding      ()                        const { return m_signHiding; }
103
  bool            hideSign        ( int       posFirst,
104
1.12M
                                    int       posLast   )   const { return ( m_signHiding && ( posLast - posFirst >= SBH_THRESHOLD ) ); }
105
71.0M
  unsigned        blockPos        ( int scanPos )           const { return m_scan[scanPos].idx; }
106
12.1M
  unsigned        posX            ( int scanPos )           const { return m_scan[scanPos].x; }
107
12.1M
  unsigned        posY            ( int scanPos )           const { return m_scan[scanPos].y; }
108
1.10M
  unsigned        maxLastPosX     ()                        const { return m_maxLastPosX; }
109
1.10M
  unsigned        maxLastPosY     ()                        const { return m_maxLastPosY; }
110
2.54M
  unsigned        lastXCtxId      ( unsigned  posLastX  )   const { return m_CtxSetLastX( m_lastOffsetX + ( posLastX >> m_lastShiftX ) ); }
111
2.60M
  unsigned        lastYCtxId      ( unsigned  posLastY  )   const { return m_CtxSetLastY( m_lastOffsetY + ( posLastY >> m_lastShiftY ) ); }
112
1.26M
  unsigned        sigGroupCtxId   ( bool ts = false     )   const { return ts ? m_sigGroupCtxIdTS : m_sigGroupCtxId; }
113
7.92M
  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
7.89M
  {
161
7.89M
    const auto scanEl       = m_scan[scanPos];
162
7.89M
    const uint32_t posY     = scanEl.y;
163
7.89M
    const uint32_t posX     = scanEl.x;
164
7.89M
    const int32_t blkPos    = scanEl.idx;
165
7.89M
    const int      diag     = posX + posY;
166
7.89M
    const int      tplVal   = m_tplBuf[-blkPos].ctxTpl;
167
7.89M
    const int      numPos   = tplVal >> 5u;
168
7.89M
    const int      sumAbs   = tplVal & 31;
169
170
7.89M
    int ctxOfs = std::min( ( sumAbs + 1 ) >> 1, 3 ) + ( diag < 2 ? 4 : 0 );
171
172
7.89M
    if( isLuma( m_chType ) )
173
508k
    {
174
508k
      ctxOfs += diag < 5 ? 4 : 0;
175
508k
    }
176
7.89M
    m_tmplCpDiag = diag;
177
7.89M
    m_tmplCpSum1 = sumAbs - numPos;
178
7.89M
    return m_sigFlagCtxSet[std::max( 0, state-1 )]( ctxOfs );
179
7.89M
  }
180
181
  ALWAYS_INLINE void absVal1stPass( const int scanPos, const TCoeffSig absLevel1 )
182
8.30M
  {
183
8.30M
    CHECKD( !absLevel1, "Shound not be called if '0'!" );
184
185
8.30M
    const auto scanEl     = m_scan[scanPos];
186
8.30M
    const uint32_t posY   = scanEl.y;
187
8.30M
    const uint32_t posX   = scanEl.x;
188
8.30M
    const int32_t  blkPos = scanEl.idx;
189
190
8.30M
    auto update_deps = [&]( int offset )
191
21.7M
    {
192
21.7M
      auto& ctx   = m_tplBuf[-blkPos + offset];
193
21.7M
      ctx.ctxTpl += uint8_t( 32 + absLevel1 );
194
21.7M
    };
195
196
8.30M
    if( posY > 1 ) update_deps( 2 * m_width );
197
8.30M
    if( posY > 0
198
5.59M
     && posX > 0 ) update_deps( m_width + 1 );
199
8.30M
    if( posY > 0 ) update_deps( m_width );
200
8.30M
    if( posX > 1 ) update_deps( 2 );
201
8.30M
    if( posX > 0 ) update_deps( 1 );
202
8.30M
  }
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
8.30M
  {
230
8.30M
    int offset = 0;
231
8.30M
    if( m_tmplCpDiag != -1 )
232
7.20M
    {
233
7.20M
      offset  = std::min( m_tmplCpSum1, 4 ) + 1;
234
7.20M
      offset += ( !m_tmplCpDiag ? ( m_chType == CH_L ? 15 : 5 ) : m_chType == CH_L ? m_tmplCpDiag < 3 ? 10 : ( m_tmplCpDiag < 10 ? 5 : 0 ) : 0 );
235
7.20M
    }
236
8.30M
    return uint8_t(offset);
237
8.30M
  }
238
239
7.22M
  unsigned parityCtxIdAbs   ( uint8_t offset )  const { return m_parFlagCtxSet   ( offset ); }
240
8.30M
  unsigned greater1CtxIdAbs ( uint8_t offset )  const { return m_gtxFlagCtxSet[1]( offset ); }
241
7.22M
  unsigned greater2CtxIdAbs ( uint8_t offset )  const { return m_gtxFlagCtxSet[0]( offset ); }
242
243
  unsigned templateAbsSum( int scanPos, const TCoeffSig* coeff, int baseLevel )
244
5.88M
  {
245
5.88M
    const uint32_t   posY = m_scan[scanPos].y;
246
5.88M
    const uint32_t   posX = m_scan[scanPos].x;
247
5.88M
    const TCoeffSig* pData = coeff + posX + posY * m_width;
248
5.88M
    int              sum   = 0;
249
5.88M
    if (posX < m_width - 1)
250
5.78M
    {
251
5.78M
      sum += abs(pData[1]);
252
5.78M
      if (posX < m_width - 2)
253
5.57M
      {
254
5.57M
        sum += abs(pData[2]);
255
5.57M
      }
256
5.78M
      if (posY < m_height - 1)
257
5.61M
      {
258
5.61M
        sum += abs(pData[m_width + 1]);
259
5.61M
      }
260
5.78M
    }
261
5.88M
    if (posY < m_height - 1)
262
5.71M
    {
263
5.71M
      sum += abs(pData[m_width]);
264
5.71M
      if (posY < m_height - 2)
265
5.45M
      {
266
5.45M
        sum += abs(pData[m_width << 1]);
267
5.45M
      }
268
5.71M
    }
269
5.88M
    return std::max(std::min(sum - 5 * baseLevel, 31), 0);
270
5.88M
  }
271
272
  unsigned sigCtxIdAbsTS( int scanPos, const TCoeffSig* coeff )
273
15.2M
  {
274
15.2M
    const uint32_t   posY   = m_scan[scanPos].y;
275
15.2M
    const uint32_t   posX   = m_scan[scanPos].x;
276
15.2M
    const TCoeffSig* posC   = coeff + posX + posY * m_width;
277
15.2M
    int              numPos = 0;
278
27.1M
#define UPDATE(x) {int a=abs(x);numPos+=!!a;}
279
15.2M
    if( posX > 0 )
280
13.7M
    {
281
13.7M
      UPDATE( posC[-1] );
282
13.7M
    }
283
15.2M
    if( posY > 0 )
284
13.3M
    {
285
13.3M
      UPDATE( posC[-(int)m_width] );
286
13.3M
    }
287
15.2M
#undef UPDATE
288
289
15.2M
    return m_tsSigFlagCtxSet( numPos );
290
15.2M
  }
291
292
13.2M
  unsigned parityCtxIdAbsTS   ()                  const { return m_tsParFlagCtxSet(      0 ); }
293
4.53M
  unsigned greaterXCtxIdAbsTS ( uint8_t offset )  const { return m_tsGtxFlagCtxSet( offset ); }
294
295
  unsigned lrg1CtxIdAbsTS(int scanPos, const TCoeffSig* coeff, int bdpcm)
296
13.2M
  {
297
13.2M
    const uint32_t   posY = m_scan[scanPos].y;
298
13.2M
    const uint32_t   posX = m_scan[scanPos].x;
299
13.2M
    const TCoeffSig* posC = coeff + posX + posY * m_width;
300
301
13.2M
    int             numPos = 0;
302
13.2M
#define UPDATE(x) {int a=abs(x);numPos+=!!a;}
303
304
13.2M
    if (bdpcm)
305
12.6M
    {
306
12.6M
      numPos = 3;
307
12.6M
    }
308
564k
    else
309
564k
    {
310
564k
      if (posX > 0)
311
520k
      {
312
520k
        UPDATE(posC[-1]);
313
520k
      }
314
564k
      if (posY > 0)
315
519k
      {
316
519k
        UPDATE(posC[-(int)m_width]);
317
519k
      }
318
564k
    }
319
320
13.2M
#undef UPDATE
321
13.2M
    return m_tsLrg1FlagCtxSet(numPos);
322
13.2M
  }
323
324
  unsigned signCtxIdAbsTS(int scanPos, const TCoeffSig* coeff, int bdpcm)
325
13.2M
  {
326
13.2M
    const uint32_t   posY  = m_scan[scanPos].y;
327
13.2M
    const uint32_t   posX  = m_scan[scanPos].x;
328
13.2M
    const TCoeffSig* pData = coeff + posX + posY * m_width;
329
330
13.2M
    int rightSign = 0, belowSign = 0;
331
13.2M
    unsigned signCtx = 0;
332
333
13.2M
    if (posX > 0)
334
11.9M
    {
335
11.9M
      rightSign = pData[-1];
336
11.9M
    }
337
13.2M
    if (posY > 0)
338
11.2M
    {
339
11.2M
      belowSign = pData[-(int)m_width];
340
11.2M
    }
341
342
13.2M
    if ((rightSign == 0 && belowSign == 0) || ((rightSign*belowSign) < 0))
343
11.5M
    {
344
11.5M
      signCtx = 0;
345
11.5M
    }
346
1.70M
    else if (rightSign >= 0 && belowSign >= 0)
347
593
    {
348
593
      signCtx = 1;
349
593
    }
350
1.70M
    else
351
1.70M
    {
352
1.70M
      signCtx = 2;
353
1.70M
    }
354
13.2M
    if (bdpcm)
355
12.6M
    {
356
12.6M
      signCtx += 3;
357
12.6M
    }
358
13.2M
    return m_tsSignFlagCtxSet(signCtx);
359
13.2M
  }
360
361
  void neighTS(int& rightPixel, int& belowPixel, int scanPos, const TCoeffSig* coeff)
362
18.8M
  {
363
18.8M
    const uint32_t   posY = m_scan[scanPos].y;
364
18.8M
    const uint32_t   posX = m_scan[scanPos].x;
365
18.8M
    const TCoeffSig* data = coeff + posX + posY * m_width;
366
367
18.8M
    rightPixel = belowPixel = 0;
368
369
18.8M
    if (posX > 0)
370
17.0M
    {
371
17.0M
      rightPixel = data[-1];
372
17.0M
    }
373
18.8M
    if (posY > 0)
374
15.5M
    {
375
15.5M
      belowPixel = data[-(int)m_width];
376
15.5M
    }
377
18.8M
  }
378
379
  int deriveModCoeff(int rightPixel, int belowPixel, int absCoeff, int bdpcm = 0)
380
9.77M
  {
381
9.77M
    if (absCoeff == 0)
382
4.81M
      return 0;
383
384
4.96M
    int pred1, absBelow = abs(belowPixel), absRight = abs(rightPixel);
385
386
4.96M
    int absCoeffMod = absCoeff;
387
388
4.96M
    if (bdpcm == 0)
389
599k
    {
390
599k
      pred1 = std::max(absBelow, absRight);
391
392
599k
      if (absCoeff == pred1)
393
0
      {
394
0
        absCoeffMod = 1;
395
0
      }
396
599k
      else
397
599k
      {
398
599k
        absCoeffMod = absCoeff < pred1 ? absCoeff + 1 : absCoeff;
399
599k
      }
400
599k
    }
401
402
4.96M
    return(absCoeffMod);
403
9.77M
  }
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
551k
  CUCtx()              : isDQPCoded(false), isChromaQpAdjCoded(false),
489
551k
                         qgStart(false)
490
551k
                         {
491
551k
                           violatesLfnstConstrained[CH_L] = false;
492
551k
                           violatesLfnstConstrained[CH_C] = false;
493
551k
                           violatesMtsCoeffConstraint      = false;
494
551k
                           mtsLastScanPos                  = false;
495
551k
                           lfnstLastScanPos                = false;
496
551k
                         }
497
19.9k
  CUCtx(int _qp)       : isDQPCoded(false), isChromaQpAdjCoded(false),
498
19.9k
                         qgStart(false),
499
19.9k
                         qp(_qp)
500
19.9k
                         {
501
19.9k
                           violatesLfnstConstrained[CH_L] = false;
502
19.9k
                           violatesLfnstConstrained[CH_C] = false;
503
19.9k
                           violatesMtsCoeffConstraint      = false;
504
19.9k
                           mtsLastScanPos                  = false;
505
19.9k
                           lfnstLastScanPos                = false;
506
19.9k
                         }
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
764k
  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
4.65M
  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
123k
  {
580
123k
    const CodingUnit *cuLeft = cuRestrictedLeft[CH_L]; const CodingUnit *cuAbove = cuRestrictedAbove[CH_L];
581
123k
    return (( cuLeft && cuLeft->skip ) ? 1 : 0) + (( cuAbove && cuAbove->skip ) ? 1 : 0);
582
123k
  }
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
357k
  {
592
357k
    const CodingUnit *cuLeft = cuRestrictedLeft[cu.chType]; const CodingUnit *cuAbove = cuRestrictedAbove[cu.chType];
593
357k
    return ((cuLeft && cuLeft->predMode == MODE_IBC) ? 1 : 0) + ((cuAbove && cuAbove->predMode == MODE_IBC) ? 1 : 0);
594
357k
  }
595
596
};
597
598
} // namespace vvenc
599
600
//! \}
601