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/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) 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     ContextModelling.h
44
 *  \brief    Classes providing probability descriptions and contexts (header)
45
 */
46
47
#pragma once
48
49
#include "CommonDef.h"
50
#include "Contexts.h"
51
#include "Slice.h"
52
#include "Unit.h"
53
#include "UnitPartitioner.h"
54
55
#include <bitset>
56
57
#include "CommonLib/dtrace_next.h"
58
59
namespace vvdec
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, CtxTpl *tplBuf );
72
public:
73
  void  initSubblock     ( int SubsetId, bool sigGroupFlag = false );
74
public:
75
0
  void  setSigGroup     ()                      { m_sigCoeffGroupFlag.set( m_subSetPos ); }
76
0
  bool  noneSigGroup    ()                      { return m_sigCoeffGroupFlag.none(); }
77
0
  int   lastSubSet      ()                      { return ( maxNumCoeff() - 1 ) >> log2CGSize(); }
78
0
  bool  isLastSubSet    ()                      { return lastSubSet() == m_subSetId; }
79
0
  bool  only1stSigGroup ()                      { return m_sigCoeffGroupFlag.count()-m_sigCoeffGroupFlag[lastSubSet()]==0; }
80
0
  void  setScanPosLast  ( int       posLast )   { m_scanPosLast = posLast; }
81
public:
82
0
  int             subSetId        ()                        const { return m_subSetId; }
83
0
  int             subSetPos       ()                        const { return m_subSetPos; }
84
0
  int             cgPosY          ()                        const { return m_subSetPosY; }
85
0
  int             cgPosX          ()                        const { return m_subSetPosX; }
86
0
  unsigned        width           ()                        const { return m_width; }
87
0
  unsigned        height          ()                        const { return m_height; }
88
0
  unsigned        log2CGSize      ()                        const { return m_log2CGSize; }
89
0
  unsigned        log2CGWidth     ()                        const { return m_log2CGWidth; }
90
0
  unsigned        log2CGHeight    ()                        const { return m_log2CGHeight; }
91
0
  unsigned        log2BlockWidth  ()                        const { return m_log2BlockWidth; }
92
0
  unsigned        log2BlockHeight ()                        const { return m_log2BlockHeight; }
93
0
  unsigned        log2BlockSize   ()                        const { return m_log2BlockSize; }
94
0
  int             maxLog2TrDRange ()                        const { return m_maxLog2TrDynamicRange; }
95
0
  unsigned        maxNumCoeff     ()                        const { return m_maxNumCoeff; }
96
0
  int             scanPosLast     ()                        const { return m_scanPosLast; }
97
0
  int             minSubPos       ()                        const { return m_minSubPos; }
98
0
  int             maxSubPos       ()                        const { return m_maxSubPos; }
99
0
  bool            isLast          ()                        const { return ( ( m_scanPosLast >> m_log2CGSize ) == m_subSetId ); }
100
0
  bool            isNotFirst      ()                        const { return ( m_subSetId != 0 ); }
101
0
  bool            isSigGroup      ()                        const { return m_sigCoeffGroupFlag[ m_subSetPos ]; }
102
0
  bool            signHiding      ()                        const { return m_signHiding; }
103
  bool            hideSign        ( int       posFirst,
104
0
                                    int       posLast   )   const { return ( m_signHiding && ( posLast - posFirst >= SBH_THRESHOLD ) ); }
105
0
  unsigned        blockPos        ( int       scanPos   )   const { return m_scan[ scanPos ]; }
106
0
  unsigned        posX            ( int       blkPos    )   const { return blkPos & ( ( 1 << m_log2BlockWidth ) - 1 ); }
107
0
  unsigned        posY            ( int       blkPos    )   const { return blkPos >> m_log2BlockWidth; }
108
0
  unsigned        maxLastPosX     ()                        const { return m_maxLastPosX; }
109
0
  unsigned        maxLastPosY     ()                        const { return m_maxLastPosY; }
110
0
  unsigned        lastXCtxId      ( unsigned  posLastX  )   const { return m_CtxSetLastX( m_lastOffsetX + ( posLastX >> m_lastShiftX ) ); }
111
0
  unsigned        lastYCtxId      ( unsigned  posLastY  )   const { return m_CtxSetLastY( m_lastOffsetY + ( posLastY >> m_lastShiftY ) ); }
112
0
  int             numCtxBins      ()                        const { return   m_remainingContextBins;      }
113
0
  void            setNumCtxBins   ( int n )                       {          m_remainingContextBins  = n; }
114
0
  unsigned        sigGroupCtxId   ( bool ts = false     )   const { return ts ? m_sigGroupCtxIdTS : m_sigGroupCtxId; }
115
0
  bool            bdpcm           ()                        const { return m_bdpcm; }
116
0
  int             regBinLimit     ()                        const { return m_regBinLimit; }
117
0
  void            setRegBinLimit  ( int n )                       {        m_regBinLimit = n; }
118
119
0
  void            decNumCtxBins   (int n)                         { m_remainingContextBins -= n; }
120
0
  void            incNumCtxBins   (int n)                         { m_remainingContextBins += n; }
121
122
  unsigned sigCtxIdAbs( const int blkPos, const int state )
123
0
  {
124
0
    const uint32_t posY     = blkPos >> m_log2BlockWidth;
125
0
    const uint32_t posX     = blkPos & ( ( 1 << m_log2BlockWidth ) - 1 );
126
0
    const int      diag     = posX + posY;
127
0
    const int      tplVal   = m_tplBuf[blkPos].ctxTpl;
128
0
    const int      numPos   = tplVal >> 5;
129
0
    const int      sumAbs   = tplVal & 31;
130
131
0
    int ctxOfs = std::min( ( sumAbs + 1 ) >> 1, 3 ) + ( diag < 2 ? 4 : 0 );
132
133
0
    if( isLuma( m_chType ) )
134
0
    {
135
0
      ctxOfs += diag < 5 ? 4 : 0;
136
0
    }
137
0
    m_tmplCpDiag = diag;
138
0
    m_tmplCpSum1 = sumAbs - numPos;
139
0
    return m_sigFlagCtxSet[std::max( 0, state-1 )]( ctxOfs );
140
0
  }
141
142
  void absVal1stPass( const int blkPos, TCoeffSig* coeff, const TCoeffSig absLevel1 )
143
0
  {
144
0
    CHECKD( !absLevel1, "absLevel1 has to non-zero!" );
145
146
0
    coeff[blkPos] = absLevel1;
147
148
0
    const uint32_t posY = blkPos >> m_log2BlockWidth;
149
0
    const uint32_t posX = blkPos & ( ( 1 << m_log2BlockWidth ) - 1 );
150
151
0
    auto update_deps = [&]( int offset )
152
0
    {
153
0
      auto& ctx   = m_tplBuf[blkPos - offset];
154
0
      ctx.ctxTpl += uint8_t( 32 + absLevel1 );
155
0
    };
156
157
0
    if( posY > 1 ) update_deps( 2 * m_width );
158
0
    if( posY > 0
159
0
     && posX > 0 ) update_deps( m_width + 1 );
160
0
    if( posY > 0 ) update_deps( m_width );
161
0
    if( posX > 1 ) update_deps( 2 );
162
0
    if( posX > 0 ) update_deps( 1 );
163
0
  }
164
165
  uint8_t ctxOffsetAbs()
166
0
  {
167
0
    int offset = 0;
168
0
    if( m_tmplCpDiag != -1 )
169
0
    {
170
0
      offset  = std::min( m_tmplCpSum1, 4 ) + 1;
171
0
      offset += ( !m_tmplCpDiag ? ( m_chType == CHANNEL_TYPE_LUMA ? 15 : 5 ) : m_chType == CHANNEL_TYPE_LUMA ? m_tmplCpDiag < 3 ? 10 : ( m_tmplCpDiag < 10 ? 5 : 0 ) : 0 );
172
0
    }
173
0
    return uint8_t(offset);
174
0
  }
175
176
0
  unsigned parityCtxIdAbs   ( uint8_t offset )  const { return m_parFlagCtxSet   ( offset ); }
177
0
  unsigned greater1CtxIdAbs ( uint8_t offset )  const { return m_gtxFlagCtxSet[1]( offset ); }
178
0
  unsigned greater2CtxIdAbs ( uint8_t offset )  const { return m_gtxFlagCtxSet[0]( offset ); }
179
180
  unsigned templateAbsSum( int blkPos, const TCoeffSig* coeff, int baseLevel )
181
0
  {
182
0
    const uint32_t   posY  = blkPos >> m_log2BlockWidth;
183
0
    const uint32_t   posX  = blkPos & ( ( 1 << m_log2BlockWidth ) - 1 );
184
0
    const TCoeffSig* pData = coeff + posX + ( posY << m_log2BlockWidth );
185
0
    int              sum   = 0;
186
187
0
    if (posX+2 < m_width)
188
0
    {
189
0
      sum += pData[1];
190
0
      sum += pData[2];
191
0
      if (posY+1 < m_height)
192
0
      {
193
0
        sum += pData[m_width + 1];
194
0
      }
195
0
    }
196
0
    else if (posX+1 < m_width)
197
0
    {
198
0
      sum += pData[1];
199
0
      if (posY+1 < m_height)
200
0
      {
201
0
        sum += pData[m_width + 1];
202
0
      }
203
0
    }
204
0
    if (posY+2 < m_height)
205
0
    {
206
0
      sum += pData[m_width];
207
0
      sum += pData[m_width << 1];
208
0
    }
209
0
    else if (posY+1 < m_height)
210
0
    {
211
0
      sum += pData[m_width];
212
0
    }
213
0
    return std::max(std::min(sum - 5 * baseLevel, 31), 0);
214
0
  }
215
216
  unsigned sigCtxIdAbsTS( int blkPos, const TCoeffSig* coeff )
217
0
  {
218
0
    const uint32_t   posY  = blkPos >> m_log2BlockWidth;
219
0
    const uint32_t   posX  = blkPos & ( ( 1 << m_log2BlockWidth ) - 1 );
220
0
    const TCoeffSig* posC  = coeff + posX + posY * m_width;
221
0
    int             numPos = 0;
222
0
#define UPDATE(x) {numPos+=!!x;}
223
0
    if( posX > 0 )
224
0
    {
225
0
      UPDATE( posC[-1] );
226
0
    }
227
0
    if( posY > 0 )
228
0
    {
229
0
      UPDATE( posC[-(int)m_width] );
230
0
    }
231
0
#undef UPDATE
232
233
0
    return m_tsSigFlagCtxSet( numPos );
234
0
  }
235
236
0
  unsigned parityCtxIdAbsTS   ()                  const { return m_tsParFlagCtxSet(      0 ); }
237
0
  unsigned greaterXCtxIdAbsTS ( uint8_t offset )  const { return m_tsGtxFlagCtxSet( offset ); }
238
239
  unsigned lrg1CtxIdAbsTS(int blkPos, const TCoeffSig* coeff, int bdpcm)
240
0
  {
241
0
    const uint32_t  posY = blkPos >> m_log2BlockWidth;
242
0
    const uint32_t  posX = blkPos & ( ( 1 << m_log2BlockWidth ) - 1 );
243
0
    const TCoeffSig*   posC = coeff + posX + posY * m_width;
244
245
0
    int             numPos = 0;
246
0
#define UPDATE(x) {numPos+=!!x;}
247
248
0
    if (bdpcm)
249
0
    {
250
0
      numPos = 3;
251
0
    }
252
0
    else
253
0
    {
254
0
      if (posX > 0)
255
0
      {
256
0
        UPDATE(posC[-1]);
257
0
      }
258
0
      if (posY > 0)
259
0
      {
260
0
        UPDATE(posC[-(int)m_width]);
261
0
      }
262
0
    }
263
264
0
#undef UPDATE
265
0
    return m_tsLrg1FlagCtxSet(numPos);
266
0
  }
267
268
  unsigned signCtxIdAbsTS(int blkPos, const TCoeffSig* coeff, int bdpcm)
269
0
  {
270
0
    const uint32_t  posY = blkPos >> m_log2BlockWidth;
271
0
    const uint32_t  posX = blkPos & ( ( 1 << m_log2BlockWidth ) - 1 );
272
    
273
0
    const TCoeffSig*   pData = coeff + posX + posY * m_width;
274
275
0
    int rightSign = 0, belowSign = 0;
276
0
    unsigned signCtx = 0;
277
278
0
    if (posX > 0)
279
0
    {
280
0
      rightSign = pData[-1];
281
0
    }
282
0
    if (posY > 0)
283
0
    {
284
0
      belowSign = pData[-(int)m_width];
285
0
    }
286
287
0
    if ((rightSign == 0 && belowSign == 0) || ((rightSign*belowSign) < 0))
288
0
    {
289
0
      signCtx = 0;
290
0
    }
291
0
    else if (rightSign >= 0 && belowSign >= 0)
292
0
    {
293
0
      signCtx = 1;
294
0
    }
295
0
    else
296
0
    {
297
0
      signCtx = 2;
298
0
    }
299
0
    if (bdpcm)
300
0
    {
301
0
      signCtx += 3;
302
0
    }
303
304
0
    DTRACE( g_trace_ctx, D_SYNTAX_RESI, "signCtxIdAbsTS() pos=(%d;%d)  signCtx=%d  rightSign=%d belowSign=%d\n", posX, posY, signCtx, rightSign, belowSign );
305
306
0
    return m_tsSignFlagCtxSet(signCtx);
307
0
  }
308
309
  void neighTS(int &rightPixel, int &belowPixel, int blkPos, const TCoeffSig* coeff)
310
0
  {
311
0
    const uint32_t  posY = blkPos >> m_log2BlockWidth;
312
0
    const uint32_t  posX = blkPos & ( ( 1 << m_log2BlockWidth ) - 1 );
313
0
    const TCoeffSig*   data = coeff + posX + posY * m_width;
314
315
0
    rightPixel = belowPixel = 0;
316
317
0
    if (posX > 0)
318
0
    {
319
0
      rightPixel = data[-1];
320
0
    }
321
0
    if (posY > 0)
322
0
    {
323
0
      belowPixel = data[-(int)m_width];
324
0
    }
325
0
  }
326
327
  int deriveModCoeff(int rightPixel, int belowPixel, int absCoeff, int bdpcm = 0)
328
0
  {
329
0
    if (absCoeff == 0)
330
0
      return 0;
331
0
    int pred1, absBelow = abs(belowPixel), absRight = abs(rightPixel);
332
0
333
0
    int absCoeffMod = absCoeff;
334
0
335
0
    if (bdpcm == 0)
336
0
    {
337
0
      pred1 = std::max(absBelow, absRight);
338
0
339
0
      if (absCoeff == pred1)
340
0
      {
341
0
        absCoeffMod = 1;
342
0
      }
343
0
      else
344
0
      {
345
0
        absCoeffMod = absCoeff < pred1 ? absCoeff + 1 : absCoeff;
346
0
      }
347
0
    }
348
0
349
0
    return(absCoeffMod);
350
0
  }
351
352
  int decDeriveModCoeff(int rightPixel, int belowPixel, int absCoeff)
353
0
  {
354
0
    if (absCoeff == 0)
355
0
      return 0;
356
357
0
    int pred1, absBelow = abs(belowPixel), absRight = abs(rightPixel);
358
0
    pred1 = std::max(absBelow, absRight);
359
360
0
    int absCoeffMod;
361
362
0
    if (absCoeff == 1 && pred1 > 0)
363
0
    {
364
0
      absCoeffMod = pred1;
365
0
    }
366
0
    else
367
0
    {
368
0
      absCoeffMod = absCoeff - (absCoeff <= pred1);
369
0
    }
370
0
    return(absCoeffMod);
371
0
  }
372
373
  unsigned templateAbsSumTS( int blkPos, const TCoeffSig* coeff )
374
0
  {
375
0
    return 1;
376
0
  }
377
378
private:
379
  // constant
380
  const ChannelType         m_chType;
381
  const unsigned            m_width;
382
  const unsigned            m_height;
383
  const unsigned            m_log2CGWidth;
384
  const unsigned            m_log2CGHeight;
385
  const unsigned            m_log2CGSize;
386
  const unsigned            m_widthInGroups;
387
  const unsigned            m_heightInGroups;
388
  const unsigned            m_log2BlockWidth;
389
  const unsigned            m_log2BlockHeight;
390
  const unsigned            m_log2BlockSize;
391
  const unsigned            m_maxNumCoeff;
392
  const bool                m_signHiding;
393
  const int                 m_maxLog2TrDynamicRange;
394
  const uint16_t*           m_scan;
395
  const uint16_t*           m_scanCG;
396
  const CtxSet              m_CtxSetLastX;
397
  const CtxSet              m_CtxSetLastY;
398
  const unsigned            m_maxLastPosX;
399
  const unsigned            m_maxLastPosY;
400
  const int                 m_lastOffsetX;
401
  const int                 m_lastOffsetY;
402
  const int                 m_lastShiftX;
403
  const int                 m_lastShiftY;
404
  // modified
405
  int                       m_scanPosLast;
406
  int                       m_subSetId;
407
  int                       m_subSetPos;
408
  int                       m_subSetPosX;
409
  int                       m_subSetPosY;
410
  int                       m_minSubPos;
411
  int                       m_maxSubPos;
412
  unsigned                  m_sigGroupCtxId;
413
  int                       m_tmplCpSum1;
414
  int                       m_tmplCpDiag;
415
  CtxSet                    m_sigFlagCtxSet[3];
416
  CtxSet                    m_parFlagCtxSet;
417
  CtxSet                    m_gtxFlagCtxSet[2];
418
  unsigned                  m_sigGroupCtxIdTS;
419
  CtxSet                    m_tsSigFlagCtxSet;
420
  CtxSet                    m_tsParFlagCtxSet;
421
  CtxSet                    m_tsGtxFlagCtxSet;
422
  CtxSet                    m_tsLrg1FlagCtxSet;
423
  CtxSet                    m_tsSignFlagCtxSet;
424
  int                       m_remainingContextBins;
425
  std::bitset<MLS_GRP_NUM>  m_sigCoeffGroupFlag;
426
  const bool                m_bdpcm;
427
  int                       m_regBinLimit;
428
  const bool                m_ts;
429
  CtxTpl*                   m_tplBuf;
430
};
431
432
433
class CUCtx
434
{
435
public:
436
  CUCtx()              : isDQPCoded(false), isChromaQpAdjCoded(false), qgStart(false), lfnstLastScanPos(false)
437
0
                         {
438
0
                           violatesLfnstConstrained[CHANNEL_TYPE_LUMA  ] = false;
439
0
                           violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false;
440
0
                           violatesMtsCoeffConstraint                    = false;
441
0
                           mtsLastScanPos                                = false;
442
0
                         }
443
0
  CUCtx(int _qp)       : isDQPCoded(false), isChromaQpAdjCoded(false), qgStart(false), lfnstLastScanPos(false), qp(_qp)
444
0
                         {
445
0
                           violatesLfnstConstrained[CHANNEL_TYPE_LUMA  ] = false;
446
0
                           violatesLfnstConstrained[CHANNEL_TYPE_CHROMA] = false;
447
0
                           violatesMtsCoeffConstraint                    = false;
448
0
                           mtsLastScanPos                                = false;
449
0
                         }
450
0
  ~CUCtx() {}
451
public:
452
  bool      isDQPCoded;
453
  bool      isChromaQpAdjCoded;
454
  bool      qgStart;
455
  bool      lfnstLastScanPos;
456
  int8_t    qp;                   // used as a previous(last) QP and for QP prediction
457
  bool      violatesLfnstConstrained[MAX_NUM_CHANNEL_TYPE];
458
  bool      violatesMtsCoeffConstraint;
459
  bool      mtsLastScanPos;
460
};
461
462
class MergeCtx
463
{
464
public:
465
0
  MergeCtx() : numValidMergeCand( 0 ) { memset( mrgTypeNeighbours, 0, sizeof( mrgTypeNeighbours ) ); }
466
0
  ~MergeCtx() {}
467
public:
468
  MvField       mvFieldNeighbours [ MRG_MAX_NUM_CANDS << 1 ]; // double length for mv of both lists
469
  uint8_t       BcwIdx            [ MRG_MAX_NUM_CANDS      ];
470
  unsigned char interDirNeighbours[ MRG_MAX_NUM_CANDS      ];
471
  MergeType     mrgTypeNeighbours [ MRG_MAX_NUM_CANDS      ];
472
  int           numValidMergeCand;
473
474
  MvField       mmvdBaseMv        [MMVD_BASE_MV_NUM        ][2];
475
476
  void setMmvdMergeCandiInfo( CodingUnit& cu, int candIdx );
477
  bool          mmvdUseAltHpelIf  [ MMVD_BASE_MV_NUM ];
478
  bool          useAltHpelIf      [ MRG_MAX_NUM_CANDS ];
479
  void setMergeInfo         ( CodingUnit& cu, int candIdx );
480
0
  void init()               { numValidMergeCand = 0; memset( mrgTypeNeighbours, 0, sizeof( mrgTypeNeighbours ) ); }
481
};
482
483
class AffineMergeCtx
484
{
485
public:
486
0
  AffineMergeCtx() : numValidMergeCand( 0 ) { for ( unsigned i = 0; i < AFFINE_MRG_MAX_NUM_CANDS; i++ ) affineType[i] = AFFINEMODEL_4PARAM; }
487
0
  ~AffineMergeCtx() {}
488
public:
489
  MvField       mvFieldNeighbours [AFFINE_MRG_MAX_NUM_CANDS << 1][3]; // double length for mv of both lists
490
  unsigned char interDirNeighbours[AFFINE_MRG_MAX_NUM_CANDS     ];
491
  AffineModel   affineType        [AFFINE_MRG_MAX_NUM_CANDS     ];
492
  uint8_t       BcwIdx            [AFFINE_MRG_MAX_NUM_CANDS     ];
493
  int           numValidMergeCand;
494
  int           maxNumMergeCand;
495
496
  MotionBuf     subPuMvpMiBuf;
497
  MergeType     mergeType         [AFFINE_MRG_MAX_NUM_CANDS     ];
498
};
499
500
501
namespace DeriveCtx
502
{
503
void     CtxSplit     ( const CodingStructure& cs, Partitioner& partitioner, unsigned& ctxSpl, unsigned& ctxQt, unsigned& ctxHv, unsigned& ctxHorBt, unsigned& ctxVerBt, bool* canSplit = nullptr );
504
unsigned CtxModeConsFlag( const CodingStructure& cs, Partitioner& partitioner );
505
unsigned CtxQtCbf     ( const ComponentID compID, const bool prevCbCbf = false, const int ispIdx = 0 );
506
unsigned CtxInterDir  ( const CodingUnit& cu );
507
unsigned CtxSkipFlag  ( const CodingUnit& cu );
508
unsigned CtxAffineFlag( const CodingUnit& cu );
509
unsigned CtxPredModeFlag( const CodingUnit& cu );
510
unsigned CtxIBCFlag   (const CodingUnit& cu);
511
unsigned CtxMipFlag   ( const CodingUnit& cu );
512
}
513
514
}