Coverage Report

Created: 2026-10-28 06:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/vvenc/source/Lib/EncoderLib/CABACWriter.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     CABACWriter.cpp
45
 *  \brief    Writer for low level syntax
46
 */
47
48
#include "CABACWriter.h"
49
#include "EncLib.h"
50
#include "CommonLib/Contexts.h"
51
#include "CommonLib/UnitTools.h"
52
#include "CommonLib/SampleAdaptiveOffset.h"
53
#include "CommonLib/dtrace_buffer.h"
54
55
#include <map>
56
#include <algorithm>
57
58
//! \ingroup EncoderLib
59
//! \{
60
61
namespace vvenc {
62
63
void CABACWriter::initCtxModels( const Slice& slice )
64
15.2k
{
65
15.2k
  int       qp                = slice.sliceQp;
66
15.2k
  SliceType sliceType         = slice.sliceType;
67
15.2k
  SliceType encCABACTableIdx  = slice.encCABACTableIdx;
68
15.2k
  if( !slice.isIntra() && (encCABACTableIdx==VVENC_B_SLICE || encCABACTableIdx==VVENC_P_SLICE) && slice.pps->cabacInitPresent )
69
0
  {
70
0
    sliceType = encCABACTableIdx;
71
0
  }
72
15.2k
  m_BinEncoder.reset( qp, (int)sliceType );
73
15.2k
}
74
75
76
77
SliceType xGetCtxInitId( const Slice& slice, const BinEncIf& binEncoder, Ctx& ctxTest )
78
0
{
79
0
  const CtxStore& ctxStoreTest = static_cast<const CtxStore&>( ctxTest );
80
0
  const CtxStore& ctxStoreRef  = static_cast<const CtxStore&>( binEncoder.getCtx() );
81
0
  int qp = slice.sliceQp;
82
0
  if( !slice.isIntra() )
83
0
  {
84
0
    SliceType aSliceTypeChoices[] = { VVENC_B_SLICE, VVENC_P_SLICE };
85
0
    uint64_t  bestCost                 = std::numeric_limits<uint64_t>::max();
86
0
    SliceType bestSliceType       = aSliceTypeChoices[0];
87
0
    for (uint32_t idx=0; idx<2; idx++)
88
0
    {
89
0
      uint64_t  curCost           = 0;
90
0
      SliceType curSliceType = aSliceTypeChoices[idx];
91
0
      ctxTest.init( qp, (int)curSliceType );
92
0
      for( int k = 0; k < Ctx::NumberOfContexts; k++ )
93
0
      {
94
0
        if( binEncoder.getNumBins(k) > 0 )
95
0
        {
96
0
          curCost += uint64_t( binEncoder.getNumBins(k) ) * ctxStoreRef[k].estFracExcessBits( ctxStoreTest[k] );
97
0
        }
98
0
      }
99
0
      if (curCost < bestCost)
100
0
      {
101
0
        bestSliceType = curSliceType;
102
0
        bestCost      = curCost;
103
0
      }
104
0
    }
105
0
    return bestSliceType;
106
0
  }
107
0
  else
108
0
  {
109
0
    return VVENC_I_SLICE;
110
0
  }
111
0
}
112
113
114
SliceType CABACWriter::getCtxInitId( const Slice& slice )
115
0
{
116
0
  return  xGetCtxInitId( slice, m_BinEncoder, m_TestCtx );
117
0
}
118
119
120
unsigned estBits( BinEncIf& binEnc, const std::vector<bool>& bins, const Ctx& ctx, const int ctxId, const uint8_t winSize )
121
0
{
122
0
  binEnc.initCtxAndWinSize( ctxId, ctx, winSize );
123
0
  binEnc.start();
124
0
  const std::size_t numBins   = bins.size();
125
0
  unsigned          startBits = binEnc.getNumWrittenBits();
126
0
  for( std::size_t binId = 0; binId < numBins; binId++ )
127
0
  {
128
0
    unsigned  bin = ( bins[binId] ? 1 : 0 );
129
0
    binEnc.encodeBin( bin, ctxId );
130
0
  }
131
0
  unsigned endBits    = binEnc.getNumWrittenBits();
132
0
  unsigned codedBits  = endBits - startBits;
133
0
  return   codedBits;
134
0
}
135
136
137
//================================================================================
138
//  clause 7.3.8.1
139
//--------------------------------------------------------------------------------
140
//    void  end_of_slice()
141
//================================================================================
142
143
void CABACWriter::end_of_slice()
144
1.49k
{
145
1.49k
  m_BinEncoder.encodeBinTrm ( 1 );
146
1.49k
  m_BinEncoder.finish       ();
147
1.49k
}
148
149
150
//================================================================================
151
//  clause 7.3.8.2
152
//--------------------------------------------------------------------------------
153
//    bool  coding_tree_unit( cs, area, qp, ctuRsAddr, skipSao, skipAlf )
154
//================================================================================
155
156
void CABACWriter::coding_tree_unit( CodingStructure& cs, const UnitArea& area, int (&qps)[2], unsigned ctuRsAddr, bool skipSao /* = false */, bool skipAlf /* = false */ )
157
9.95k
{
158
9.95k
  CUCtx cuCtx( qps[CH_L] );
159
9.95k
  Partitioner *partitioner = &m_partitioner[0];
160
161
9.95k
  partitioner->initCtu( area, CH_L, *cs.slice );
162
163
9.95k
  if( !skipSao )
164
4.97k
  {
165
4.97k
    sao( *cs.slice, ctuRsAddr );
166
4.97k
  }
167
168
9.95k
  if (!skipAlf)
169
4.97k
  {
170
19.9k
    for (int compIdx = 0; compIdx < MAX_NUM_COMP; compIdx++)
171
14.9k
    {
172
14.9k
      if(cs.slice->alfEnabled[compIdx])
173
0
      {
174
0
        codeAlfCtuEnabledFlag(cs, ctuRsAddr, compIdx);
175
0
        if (isLuma(ComponentID(compIdx)))
176
0
        {
177
0
          codeAlfCtuFilterIndex(cs, ctuRsAddr);
178
0
        }
179
0
        if (isChroma(ComponentID(compIdx)))
180
0
        {
181
0
          codeAlfCtuAlternative(cs, ctuRsAddr, compIdx, &cs.slice->alfAps[cs.slice->chromaApsId]->alfParam );
182
0
        }
183
0
      }
184
14.9k
    }
185
4.97k
  }
186
187
9.95k
  if ( !skipAlf )
188
4.97k
  {
189
14.9k
    for ( int compIdx = 1; compIdx < getNumberValidComponents( cs.pcv->chrFormat ); compIdx++ )
190
9.95k
    {
191
9.95k
      if (cs.slice->ccAlfFilterParam.ccAlfFilterEnabled[compIdx - 1])
192
0
      {
193
0
        const int filterCount   = cs.slice->ccAlfFilterParam.ccAlfFilterCount[compIdx - 1];
194
195
0
        const int      ry = ctuRsAddr / cs.pcv->widthInCtus;
196
0
        const int      rx = ctuRsAddr % cs.pcv->widthInCtus;
197
0
        const Position lumaPos(rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize);
198
199
0
        codeCcAlfFilterControlIdc(cs.slice->ccAlfFilterControl[compIdx - 1][ctuRsAddr], cs, ComponentID(compIdx),
200
0
                                  ctuRsAddr, cs.slice->ccAlfFilterControl[compIdx - 1], lumaPos, filterCount);
201
0
      }
202
9.95k
    }
203
4.97k
  }
204
205
9.95k
  if ( CS::isDualITree(cs) && cs.pcv->chrFormat != CHROMA_400 && cs.pcv->maxCUSize > 64 )
206
9.95k
  {
207
9.95k
    CUCtx chromaCuCtx(qps[CH_C]);
208
9.95k
    Partitioner *chromaPartitioner = &m_partitioner[1];
209
9.95k
    chromaPartitioner->initCtu(area, CH_C, *cs.slice);
210
9.95k
    coding_tree(cs, *partitioner, cuCtx, chromaPartitioner, &chromaCuCtx);
211
9.95k
    qps[CH_L] = cuCtx.qp;
212
9.95k
    qps[CH_C] = chromaCuCtx.qp;
213
9.95k
  }
214
0
  else
215
0
  {
216
0
    coding_tree( cs, *partitioner, cuCtx );
217
0
    qps[CH_L] = cuCtx.qp;
218
0
    if( CS::isDualITree( cs ) && cs.pcv->chrFormat != CHROMA_400 )
219
0
    {
220
0
      CUCtx cuCtxChroma( qps[CH_C] );
221
0
      partitioner->initCtu( area, CH_C, *cs.slice );
222
0
      coding_tree( cs, *partitioner, cuCtxChroma );
223
0
      qps[CH_C] = cuCtxChroma.qp;
224
0
    }
225
0
  }
226
9.95k
}
227
228
229
//================================================================================
230
//  clause 7.3.8.3
231
//--------------------------------------------------------------------------------
232
//    void  sao             ( slice, ctuRsAddr )
233
//    void  sao_block_pars  ( saoPars, bitDepths, sliceEnabled, leftMergeAvail, aboveMergeAvail, onlyEstMergeInfo )
234
//    void  sao_offset_pars ( ctbPars, compID, sliceEnabled, bitDepth )
235
//================================================================================
236
237
void CABACWriter::sao( const Slice& slice, unsigned ctuRsAddr )
238
4.97k
{
239
4.97k
  const SPS& sps = *slice.sps;
240
4.97k
  if( !sps.saoEnabled )
241
0
  {
242
0
    return;
243
0
  }
244
245
4.97k
  CodingStructure&     cs                     = *slice.pic->cs;
246
4.97k
  const PreCalcValues& pcv                    = *cs.pcv;
247
4.97k
  const SAOBlkParam&  sao_ctu_pars            = cs.picture->getSAO()[ctuRsAddr];
248
4.97k
  bool                slice_sao_luma_flag     = ( slice.saoEnabled[ CH_L ] );
249
4.97k
  bool                slice_sao_chroma_flag   = ( slice.saoEnabled[ CH_C ] && sps.chromaFormatIdc != CHROMA_400 );
250
4.97k
  if( !slice_sao_luma_flag && !slice_sao_chroma_flag )
251
0
  {
252
0
    return;
253
0
  }
254
255
4.97k
  bool                sliceEnabled[3]         = { slice_sao_luma_flag, slice_sao_chroma_flag, slice_sao_chroma_flag };
256
4.97k
  int                 frame_width_in_ctus     = pcv.widthInCtus;
257
4.97k
  int                 ry                      = ctuRsAddr      / frame_width_in_ctus;
258
4.97k
  int                 rx                      = ctuRsAddr - ry * frame_width_in_ctus;
259
4.97k
  const Position      pos                     ( rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize );
260
4.97k
  const unsigned      curSliceIdx             = slice.independentSliceIdx;
261
4.97k
  const unsigned      curTileIdx              = cs.pps->getTileIdx( pos );
262
4.97k
  bool                leftMergeAvail          = cs.getCURestricted( pos.offset( -(int)pcv.maxCUSize, 0  ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
263
4.97k
  bool                aboveMergeAvail         = cs.getCURestricted( pos.offset( 0, -(int)pcv.maxCUSize ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
264
4.97k
  sao_block_pars( sao_ctu_pars, sps.bitDepths, sliceEnabled, leftMergeAvail, aboveMergeAvail, false );
265
4.97k
}
266
267
268
void CABACWriter::sao_block_pars( const SAOBlkParam& saoPars, const BitDepths& bitDepths, const bool* sliceEnabled, bool leftMergeAvail, bool aboveMergeAvail, bool onlyEstMergeInfo )
269
19.5k
{
270
19.5k
  bool isLeftMerge  = false;
271
19.5k
  bool isAboveMerge = false;
272
19.5k
  if( leftMergeAvail )
273
10.2k
  {
274
    // sao_merge_left_flag
275
10.2k
    isLeftMerge   = ( saoPars[COMP_Y].modeIdc == SAO_MODE_MERGE && saoPars[COMP_Y].typeIdc == SAO_MERGE_LEFT );
276
10.2k
    m_BinEncoder.encodeBin( (isLeftMerge), Ctx::SaoMergeFlag() );
277
10.2k
  }
278
19.5k
  if( aboveMergeAvail && !isLeftMerge )
279
8.19k
  {
280
    // sao_merge_above_flag
281
8.19k
    isAboveMerge  = ( saoPars[COMP_Y].modeIdc == SAO_MODE_MERGE && saoPars[COMP_Y].typeIdc == SAO_MERGE_ABOVE );
282
8.19k
    m_BinEncoder.encodeBin( (isAboveMerge), Ctx::SaoMergeFlag() );
283
8.19k
  }
284
19.5k
  if( onlyEstMergeInfo )
285
4.97k
  {
286
4.97k
    return; //only for RDO
287
4.97k
  }
288
14.5k
  if( !isLeftMerge && !isAboveMerge )
289
6.46k
  {
290
    // explicit parameters
291
25.8k
    for( int compIdx=0; compIdx < MAX_NUM_COMP; compIdx++ )
292
19.4k
    {
293
19.4k
      sao_offset_pars( saoPars[compIdx], ComponentID(compIdx), sliceEnabled[compIdx], bitDepths[ toChannelType(ComponentID(compIdx)) ] );
294
19.4k
    }
295
6.46k
  }
296
14.5k
}
297
298
299
void CABACWriter::sao_offset_pars( const SAOOffset& ctbPars, ComponentID compID, bool sliceEnabled, int bitDepth )
300
108k
{
301
108k
  if( !sliceEnabled )
302
0
  {
303
0
    CHECK( ctbPars.modeIdc != SAO_MODE_OFF, "Sao must be off, if it is disabled on slice level" );
304
0
    return;
305
0
  }
306
108k
  const bool isFirstCompOfChType = ( getFirstComponentOfChannel( toChannelType(compID) ) == compID );
307
308
108k
  if( isFirstCompOfChType )
309
72.6k
  {
310
    // sao_type_idx_luma / sao_type_idx_chroma
311
72.6k
    if( ctbPars.modeIdc == SAO_MODE_OFF )
312
22.8k
    {
313
22.8k
      m_BinEncoder.encodeBin  ( 0, Ctx::SaoTypeIdx() );
314
22.8k
    }
315
49.7k
    else if( ctbPars.typeIdc == SAO_TYPE_BO )
316
9.99k
    {
317
9.99k
      m_BinEncoder.encodeBin  ( 1, Ctx::SaoTypeIdx() );
318
9.99k
      m_BinEncoder.encodeBinEP( 0 );
319
9.99k
    }
320
39.7k
    else
321
39.7k
    {
322
39.7k
      CHECK(!( ctbPars.typeIdc < SAO_TYPE_START_BO ), "Unspecified error");
323
39.7k
      m_BinEncoder.encodeBin  ( 1, Ctx::SaoTypeIdx() );
324
39.7k
      m_BinEncoder.encodeBinEP( 1 );
325
39.7k
    }
326
72.6k
  }
327
328
108k
  if( ctbPars.modeIdc == SAO_MODE_NEW )
329
74.6k
  {
330
74.6k
    const int maxOffsetQVal = SampleAdaptiveOffset::getMaxOffsetQVal( bitDepth );
331
74.6k
    int       numClasses    = ( ctbPars.typeIdc == SAO_TYPE_BO ? 4 : NUM_SAO_EO_CLASSES );
332
74.6k
    int       k             = 0;
333
74.6k
    int       offset[4];
334
432k
    for( int i = 0; i < numClasses; i++ )
335
358k
    {
336
358k
      if( ctbPars.typeIdc != SAO_TYPE_BO && i == SAO_CLASS_EO_PLAIN )
337
59.6k
      {
338
59.6k
        continue;
339
59.6k
      }
340
298k
      int classIdx = ( ctbPars.typeIdc == SAO_TYPE_BO ? ( ctbPars.typeAuxInfo + i ) % NUM_SAO_BO_CLASSES : i );
341
298k
      offset[k++]  = ctbPars.offset[classIdx];
342
298k
    }
343
344
    // sao_offset_abs
345
373k
    for( int i = 0; i < 4; i++ )
346
298k
    {
347
298k
      unsigned absOffset = ( offset[i] < 0 ? -offset[i] : offset[i] );
348
298k
      unary_max_eqprob( absOffset, maxOffsetQVal );
349
298k
    }
350
351
    // band offset mode
352
74.6k
    if( ctbPars.typeIdc == SAO_TYPE_BO )
353
14.9k
    {
354
      // sao_offset_sign
355
74.8k
      for( int i = 0; i < 4; i++ )
356
59.9k
      {
357
59.9k
        if( offset[i] )
358
349
        {
359
349
          m_BinEncoder.encodeBinEP( (offset[i] < 0) );
360
349
        }
361
59.9k
      }
362
      // sao_band_position
363
14.9k
      m_BinEncoder.encodeBinsEP( ctbPars.typeAuxInfo, NUM_SAO_BO_CLASSES_LOG2 );
364
14.9k
    }
365
    // edge offset mode
366
59.6k
    else
367
59.6k
    {
368
59.6k
      if( isFirstCompOfChType )
369
39.7k
      {
370
        // sao_eo_class_luma / sao_eo_class_chroma
371
39.7k
        CHECK( ctbPars.typeIdc - SAO_TYPE_START_EO < 0, "sao edge offset class is outside valid range" );
372
39.7k
        m_BinEncoder.encodeBinsEP( ctbPars.typeIdc - SAO_TYPE_START_EO, NUM_SAO_EO_TYPES_LOG2 );
373
39.7k
      }
374
59.6k
    }
375
74.6k
  }
376
108k
}
377
378
379
//================================================================================
380
//  clause 7.3.8.4
381
//--------------------------------------------------------------------------------
382
//    void  coding_tree       ( cs, partitioner, cuCtx )
383
//    void  split_cu_flag     ( split, cs, partitioner )
384
//    void  split_cu_mode_mt  ( split, cs, partitioner )
385
//================================================================================
386
387
void CABACWriter::coding_tree(const CodingStructure& cs, Partitioner& partitioner, CUCtx& cuCtx, Partitioner* pPartitionerChroma, CUCtx* pCuCtxChroma)
388
211k
{
389
211k
  const PPS      &pps         = *cs.pps;
390
211k
  const UnitArea& currArea    = partitioner.currArea();
391
211k
  const CodingUnit &cu        = *cs.getCU( currArea.blocks[partitioner.chType], partitioner.chType, partitioner.treeType );
392
393
  // Reset delta QP coding flag and ChromaQPAdjustemt coding flag
394
  //Note: do not reset qg at chroma CU
395
211k
  if( pps.useDQP && partitioner.currQgEnable() && !isChroma( partitioner.chType ) )
396
19.1k
  {
397
19.1k
    cuCtx.qgStart    = true;
398
19.1k
    cuCtx.isDQPCoded          = false;
399
19.1k
  }
400
211k
  if( cs.slice->chromaQpAdjEnabled && partitioner.currQgChromaEnable() )
401
0
  {
402
0
    cuCtx.isChromaQpAdjCoded  = false;
403
0
  }
404
  // Reset delta QP coding flag and ChromaQPAdjustemt coding flag
405
211k
  if (CS::isDualITree(cs) && pPartitionerChroma != nullptr)
406
9.95k
  {
407
9.95k
    if (pps.useDQP && pPartitionerChroma->currQgEnable())
408
9.95k
    {
409
9.95k
      pCuCtxChroma->qgStart    = true;
410
9.95k
      pCuCtxChroma->isDQPCoded = false;
411
9.95k
    }
412
9.95k
    if (cs.slice->chromaQpAdjEnabled && pPartitionerChroma->currQgChromaEnable())
413
0
    {
414
0
      pCuCtxChroma->isChromaQpAdjCoded = false;
415
0
    }
416
9.95k
  }
417
418
211k
  determineNeighborCus( cs, partitioner.currArea(), partitioner.chType, partitioner.treeType );
419
420
211k
  const PartSplit splitMode = CU::getSplitAtDepth( cu, partitioner.currDepth );
421
422
211k
  split_cu_mode( splitMode, cs, partitioner );
423
424
211k
  CHECK( !partitioner.canSplit( splitMode, cs ), "The chosen split mode is invalid!" );
425
426
211k
  if( splitMode != CU_DONT_SPLIT )
427
108k
  {
428
108k
    if (CS::isDualITree(cs) && pPartitionerChroma != nullptr && (partitioner.currArea().lwidth() >= 64 || partitioner.currArea().lheight() >= 64))
429
9.95k
    {
430
9.95k
      partitioner.splitCurrArea(CU_QUAD_SPLIT, cs);
431
9.95k
      pPartitionerChroma->splitCurrArea(CU_QUAD_SPLIT, cs);
432
9.95k
      bool beContinue = true;
433
9.95k
      bool lumaContinue = true;
434
9.95k
      bool chromaContinue = true;
435
436
49.7k
      while (beContinue)
437
39.8k
      {
438
39.8k
        if (partitioner.currArea().lwidth() > 64 || partitioner.currArea().lheight() > 64)
439
0
        {
440
0
          if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos()))
441
0
          {
442
0
            coding_tree(cs, partitioner, cuCtx, pPartitionerChroma, pCuCtxChroma);
443
0
          }
444
0
          lumaContinue = partitioner.nextPart(cs);
445
0
          chromaContinue = pPartitionerChroma->nextPart(cs);
446
0
          CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched");
447
0
          beContinue = lumaContinue;
448
0
        }
449
39.8k
        else
450
39.8k
        {
451
          //dual tree coding under 64x64 block
452
39.8k
          if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos()))
453
27.2k
          {
454
27.2k
            coding_tree(cs, partitioner, cuCtx);
455
27.2k
          }
456
39.8k
          lumaContinue = partitioner.nextPart(cs);
457
39.8k
          if (cs.picture->blocks[pPartitionerChroma->chType].contains(pPartitionerChroma->currArea().blocks[pPartitionerChroma->chType].pos()))
458
27.2k
          {
459
27.2k
            coding_tree(cs, *pPartitionerChroma, *pCuCtxChroma);
460
27.2k
          }
461
39.8k
          chromaContinue = pPartitionerChroma->nextPart(cs);
462
39.8k
          CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched");
463
39.8k
          beContinue = lumaContinue;
464
39.8k
        }
465
39.8k
      }
466
9.95k
      partitioner.exitCurrSplit();
467
9.95k
      pPartitionerChroma->exitCurrSplit();
468
469
9.95k
    }
470
98.3k
    else
471
98.3k
    {
472
98.3k
      const ModeType modeTypeParent = partitioner.modeType;
473
98.3k
      const ModeType modeTypeChild = CU::getModeTypeAtDepth( cu, partitioner.currDepth );
474
98.3k
      mode_constraint( splitMode, cs, partitioner, modeTypeChild );
475
98.3k
      partitioner.modeType = modeTypeChild;
476
477
98.3k
      bool chromaNotSplit = modeTypeParent == MODE_TYPE_ALL && modeTypeChild == MODE_TYPE_INTRA ? true : false;
478
98.3k
      CHECK( chromaNotSplit && partitioner.chType != CH_L, "chType must be luma" );
479
98.3k
      if( partitioner.treeType == TREE_D )
480
98.3k
      {
481
98.3k
        partitioner.treeType = chromaNotSplit ? TREE_L : TREE_D;
482
98.3k
      }
483
98.3k
      partitioner.splitCurrArea( splitMode, cs );
484
485
98.3k
      do
486
243k
      {
487
243k
        if( cs.picture->blocks[partitioner.chType].contains( partitioner.currArea().blocks[partitioner.chType].pos() ) )
488
147k
        {
489
147k
          coding_tree( cs, partitioner, cuCtx );
490
147k
        }
491
243k
      } while( partitioner.nextPart( cs ) );
492
493
98.3k
      partitioner.exitCurrSplit();
494
98.3k
      if( chromaNotSplit )
495
0
      {
496
0
        if (isChromaEnabled(cs.pcv->chrFormat))
497
0
        {
498
0
          CHECK( partitioner.chType != CH_L, "must be luma status" );
499
0
          partitioner.chType = CH_C;
500
0
          partitioner.treeType = TREE_C;
501
502
0
          if( cs.picture->blocks[partitioner.chType].contains( partitioner.currArea().blocks[partitioner.chType].pos() ) )
503
0
          {
504
0
            coding_tree( cs, partitioner, cuCtx );
505
0
          }
506
0
        }
507
        //recover
508
0
        partitioner.chType = CH_L;
509
0
        partitioner.treeType = TREE_D;
510
0
      }
511
98.3k
      partitioner.modeType = modeTypeParent;
512
98.3k
    }
513
108k
    return;
514
108k
  }
515
516
  // Predict QP on start of quantization group
517
103k
  if( cuCtx.qgStart )
518
25.7k
  {
519
25.7k
    cuCtx.qgStart = false;
520
25.7k
    cuCtx.qp = CU::predictQP( cu, cuCtx.qp );
521
25.7k
  }
522
103k
  CHECK( cu.treeType != partitioner.treeType, "treeType mismatch" );
523
524
525
  // coding unit
526
103k
  coding_unit( cu, partitioner, cuCtx );
527
528
103k
  if( cu.chType == CH_C )
529
41.6k
  {
530
41.6k
    DTRACE_COND( (isEncoding()), g_trace_ctx, D_QP, "[chroma CU]x=%d, y=%d, w=%d, h=%d, qp=%d\n", cu.Cb().x, cu.Cb().y, cu.Cb().width, cu.Cb().height, cu.qp );
531
41.6k
  }
532
61.6k
  else
533
61.6k
  {
534
61.6k
    DTRACE_COND( ( isEncoding() ), g_trace_ctx, D_QP, "x=%d, y=%d, w=%d, h=%d, qp=%d\n", cu.Y().x, cu.Y().y, cu.Y().width, cu.Y().height, cu.qp );
535
61.6k
  }
536
103k
  DTRACE_BLOCK_REC_COND( ( !isEncoding() ), cs.picture->getRecoBuf( cu ), cu, cu.predMode );
537
103k
}
538
539
540
void CABACWriter::mode_constraint( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner, const ModeType modeType )
541
326k
{
542
326k
  CHECK( split == CU_DONT_SPLIT, "splitMode shall not be no split" );
543
326k
  int val = CS::signalModeCons( cs, partitioner.currArea(), split, partitioner.modeType);
544
326k
  if( val == LDT_MODE_TYPE_SIGNAL )
545
0
  {
546
0
    CHECK( modeType == MODE_TYPE_ALL, "shall not be no constraint case" );
547
0
    bool flag = modeType == MODE_TYPE_INTRA;
548
0
    int ctxIdx = DeriveCtx::CtxModeConsFlag();
549
0
    m_BinEncoder.encodeBin( flag, Ctx::ModeConsFlag( ctxIdx ) );
550
0
    DTRACE( g_trace_ctx, D_SYNTAX, "mode_cons_flag() flag=%d\n", flag );
551
0
  }
552
326k
  else if( val == LDT_MODE_TYPE_INFER )
553
0
  {
554
0
    CHECK( modeType != MODE_TYPE_INTRA, "Wrong mode type" );
555
0
  }
556
326k
  else
557
326k
  {
558
326k
    CHECK( modeType != partitioner.modeType, "Wrong mode type" );
559
326k
  }
560
326k
}
561
562
563
void CABACWriter::split_cu_mode( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner )
564
573k
{
565
573k
  bool canNo, canQt, canBh, canBv, canTh, canTv;
566
573k
  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv );
567
568
573k
  const bool canSpl[6] = { canNo, canQt, canBh, canBv, canTh, canTv };
569
570
573k
  unsigned ctxSplit = 0, ctxQtSplit = 0, ctxBttHV = 0, ctxBttH12 = 0, ctxBttV12;
571
573k
  DeriveCtx::CtxSplit( partitioner, ctxSplit, ctxQtSplit, ctxBttHV, ctxBttH12, ctxBttV12, canSpl );
572
573
573k
  const bool canSplit = canBh || canBv || canTh || canTv || canQt;
574
573k
  const bool isNo     = split == CU_DONT_SPLIT;
575
576
573k
  if( canNo && canSplit )
577
351k
  {
578
351k
    m_BinEncoder.encodeBin( !isNo, Ctx::SplitFlag( ctxSplit ) );
579
351k
  }
580
581
573k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d split=%d\n", ctxSplit, !isNo );
582
583
573k
  if( isNo )
584
237k
  {
585
237k
    return;
586
237k
  }
587
588
336k
  const bool canBtt = canBh || canBv || canTh || canTv;
589
336k
  const bool isQt   = split == CU_QUAD_SPLIT;
590
591
336k
  if( canQt && canBtt )
592
132k
  {
593
132k
    m_BinEncoder.encodeBin( isQt, Ctx::SplitQtFlag( ctxQtSplit ) );
594
132k
  }
595
596
336k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d qt=%d\n", ctxQtSplit, isQt );
597
598
336k
  if( isQt )
599
86.3k
  {
600
86.3k
    return;
601
86.3k
  }
602
603
250k
  const bool canHor = canBh || canTh;
604
250k
  const bool canVer = canBv || canTv;
605
250k
  const bool  isVer = split == CU_VERT_SPLIT || split == CU_TRIV_SPLIT;
606
607
250k
  if( canVer && canHor )
608
129k
  {
609
129k
    m_BinEncoder.encodeBin( isVer, Ctx::SplitHvFlag( ctxBttHV ) );
610
129k
  }
611
612
250k
  const bool can14 = isVer ? canTv : canTh;
613
250k
  const bool can12 = isVer ? canBv : canBh;
614
250k
  const bool  is12 = isVer ? ( split == CU_VERT_SPLIT ) : ( split == CU_HORZ_SPLIT );
615
616
250k
  if( can12 && can14 )
617
68.2k
  {
618
68.2k
    m_BinEncoder.encodeBin( is12, Ctx::Split12Flag( isVer ? ctxBttV12 : ctxBttH12 ) );
619
68.2k
  }
620
621
250k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctxHv=%d ctx12=%d mode=%d\n", ctxBttHV, isVer ? ctxBttV12 : ctxBttH12, split );
622
250k
}
623
624
625
//================================================================================
626
//  clause 7.3.8.5
627
//--------------------------------------------------------------------------------
628
//    void  coding_unit               ( cu, partitioner, cuCtx )
629
//    void  cu_skip_flag              ( cu )
630
//    void  pred_mode                 ( cu )
631
//    void  part_mode                 ( cu )
632
//    void  cu_pred_data              ( pus )
633
//    void  cu_lic_flag               ( cu )
634
//    void  intra_luma_pred_modes     ( pus )
635
//    void  intra_chroma_pred_mode    ( cu )
636
//    void  cu_residual               ( cu, partitioner, cuCtx )
637
//    void  rqt_root_cbf              ( cu )
638
//    void  end_of_ctu                ( cu, cuCtx )
639
//================================================================================
640
641
void CABACWriter::coding_unit( const CodingUnit& cu, Partitioner& partitioner, CUCtx& cuCtx )
642
103k
{
643
103k
  DTRACE( g_trace_ctx, D_SYNTAX, "coding_unit() treeType=%d modeType=%d\n", cu.treeType, cu.modeType );
644
103k
  STAT_COUNT_CU_MODES( isEncoding() && partitioner.chType == CH_L, g_cuCounters1D[CU_CODED_FINALLY][0][!cu.slice->isIntra() + cu.slice->depth] );
645
103k
  STAT_COUNT_CU_MODES( isEncoding() && partitioner.chType == CH_L && !cu.slice->isIntra(), g_cuCounters2D[CU_CODED_FINALLY][Log2( cu.lheight() )][Log2( cu.lwidth() )] );
646
647
103k
  CodingStructure& cs = *cu.cs;
648
649
  // skip flag
650
103k
  if ((!cs.slice->isIntra() || cs.slice->sps->IBC) && cu.Y().valid())
651
61.6k
  {
652
61.6k
    cu_skip_flag( cu );
653
61.6k
  }
654
  
655
  // skip data
656
103k
  if( cu.skip )
657
0
  {
658
0
    CHECK( !cu.mergeFlag, "Merge flag has to be on!" );
659
0
    prediction_unit ( cu );
660
0
    CHECK(cu.colorTransform, "ACT should not be enabled for skip mode");
661
0
    end_of_ctu      ( cu, cuCtx );
662
0
    return;
663
0
  }
664
665
  // prediction mode and partitioning data
666
103k
  pred_mode ( cu );
667
103k
  if (CU::isIntra(cu))
668
103k
  {
669
103k
    adaptive_color_transform(cu);
670
103k
  }
671
103k
  if (CU::isPLT(cu))
672
0
  {
673
0
    THROW("no support");
674
0
    return;
675
0
  }
676
677
  // prediction data ( intra prediction modes / reference indexes + motion vectors )
678
103k
  cu_pred_data( cu );
679
680
  // residual data ( coded block flags + transform coefficient levels )
681
103k
  cu_residual( cu, partitioner, cuCtx );
682
683
  // end of cu
684
103k
  end_of_ctu( cu, cuCtx );
685
103k
}
686
687
688
void CABACWriter::cu_skip_flag( const CodingUnit& cu )
689
123k
{
690
123k
  unsigned ctxId = DeriveCtx::CtxSkipFlag();
691
692
123k
  if ((cu.slice->isIntra() || CU::isConsIntra(cu)) && cu.cs->slice->sps->IBC)
693
123k
  {
694
123k
    if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64
695
123k
    {
696
123k
      m_BinEncoder.encodeBin((cu.skip), Ctx::SkipFlag(ctxId));
697
123k
      DTRACE(g_trace_ctx, D_SYNTAX, "cu_skip_flag() ctx=%d skip=%d\n", ctxId, cu.skip ? 1 : 0);
698
123k
    }
699
123k
    return;
700
123k
  }
701
0
  if ( !cu.cs->slice->sps->IBC && cu.lwidth() == 4 && cu.lheight() == 4 )
702
0
  {
703
0
    return;
704
0
  }
705
0
  if( !cu.cs->slice->sps->IBC && CU::isConsIntra(cu) )
706
0
  {
707
0
    return;
708
0
  }
709
0
  m_BinEncoder.encodeBin( ( cu.skip ), Ctx::SkipFlag( ctxId ) );
710
711
0
  DTRACE( g_trace_ctx, D_SYNTAX, "cu_skip_flag() ctx=%d skip=%d\n", ctxId, cu.skip ? 1 : 0 );
712
0
  if (cu.skip && cu.cs->slice->sps->IBC)
713
0
  {
714
0
    if (cu.lwidth() < 128 && cu.lheight() < 128 && !CU::isConsInter(cu)) // disable IBC mode larger than 64x64 and disable IBC when only allowing inter mode
715
0
    {
716
0
      if ( cu.lwidth() == 4 && cu.lheight() == 4 )
717
0
      {
718
0
        return;
719
0
      }
720
0
      unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
721
0
      m_BinEncoder.encodeBin(CU::isIBC(cu) ? 1 : 0, Ctx::IBCFlag(ctxidx));
722
0
      DTRACE(g_trace_ctx, D_SYNTAX, "ibc() ctx=%d cu.predMode=%d\n", ctxidx, cu.predMode);
723
0
    }
724
0
  }
725
0
}
726
727
728
void CABACWriter::pred_mode( const CodingUnit& cu )
729
471k
{
730
471k
  if (cu.cs->slice->sps->IBC && cu.chType != CH_C)
731
357k
  {
732
357k
    if( CU::isConsInter(cu) )
733
0
    {
734
0
      assert( CU::isInter( cu ) );
735
0
      return;
736
0
    }
737
738
357k
    if ( cu.cs->slice->isIntra() || ( cu.lwidth() == 4 && cu.lheight() == 4 ) || CU::isConsIntra(cu) )
739
357k
    {
740
357k
      if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64
741
357k
      {
742
357k
        unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
743
357k
        m_BinEncoder.encodeBin(CU::isIBC(cu), Ctx::IBCFlag(ctxidx));
744
357k
      }
745
357k
      if (!CU::isIBC(cu) && cu.cs->slice->sps->PLT && cu.lwidth() <= 64 && cu.lheight() <= 64 && (cu.lumaSize().width * cu.lumaSize().height > 16))
746
0
      {
747
0
        m_BinEncoder.encodeBin(CU::isPLT(cu), Ctx::PLTFlag(0));
748
0
      }
749
357k
    }
750
1
    else
751
1
    {
752
1
      if( CU::isConsInter(cu) )
753
0
      {
754
0
        return;
755
0
      }
756
1
      m_BinEncoder.encodeBin((CU::isIntra(cu) || CU::isPLT(cu)), Ctx::PredMode(DeriveCtx::CtxPredModeFlag()));
757
1
      if (CU::isIntra(cu) || CU::isPLT(cu))
758
0
      {
759
0
        if (cu.cs->slice->sps->PLT && cu.lwidth() <= 64 && cu.lheight() <= 64 && (cu.lumaSize().width * cu.lumaSize().height > 16))
760
0
        {
761
0
          m_BinEncoder.encodeBin(CU::isPLT(cu), Ctx::PLTFlag(0));
762
0
        }
763
0
      }
764
1
      else
765
1
      {
766
1
        if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64
767
0
        {
768
0
          unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
769
0
          m_BinEncoder.encodeBin(CU::isIBC(cu), Ctx::IBCFlag(ctxidx));
770
0
        }
771
1
      }
772
1
    }
773
357k
  }
774
114k
  else
775
114k
  {
776
114k
    if( CU::isConsInter(cu) )
777
0
    {
778
0
      assert( CU::isInter( cu ) );
779
0
      return;
780
0
    }
781
782
114k
    if ( cu.cs->slice->isIntra() || ( cu.lwidth() == 4 && cu.lheight() == 4 ) || CU::isConsIntra(cu) )
783
114k
    {
784
114k
      if (cu.cs->slice->sps->PLT && cu.lwidth() <= 64 && cu.lheight() <= 64 && ( ( (!isLuma(cu.chType)) && (cu.chromaSize().width * cu.chromaSize().height > 16) ) || ((isLuma(cu.chType)) && ((cu.lumaSize().width * cu.lumaSize().height) > 16 ) ) ) && (!CU::isLocalSepTree(cu) || isLuma(cu.chType) ) )
785
0
      {
786
0
        m_BinEncoder.encodeBin((CU::isPLT(cu)), Ctx::PLTFlag(0));
787
0
      }
788
114k
      return;
789
114k
    }
790
0
    m_BinEncoder.encodeBin((CU::isIntra(cu) || CU::isPLT(cu)), Ctx::PredMode(DeriveCtx::CtxPredModeFlag()));
791
0
    if ((CU::isIntra(cu) || CU::isPLT(cu)) && cu.cs->slice->sps->PLT && cu.lwidth() <= 64 && cu.lheight() <= 64&& ( ( (!isLuma(cu.chType)) && (cu.chromaSize().width * cu.chromaSize().height > 16) ) || ((isLuma(cu.chType)) && ((cu.lumaSize().width * cu.lumaSize().height) > 16 ) ) ) && (!CU::isLocalSepTree(cu) || isLuma(cu.chType)  ) )
792
0
    {
793
0
      m_BinEncoder.encodeBin((CU::isPLT(cu)), Ctx::PLTFlag(0));
794
0
    }
795
0
  }
796
471k
}
797
798
799
void CABACWriter::bdpcm_mode( const CodingUnit& cu, const ComponentID compID )
800
800k
{
801
800k
  if( !cu.cs->sps->BDPCM) return;
802
800k
  if( !CU::bdpcmAllowed( cu, compID ) ) return;
803
804
347k
  int bdpcmMode = cu.bdpcmM[toChannelType(compID)];
805
806
347k
  unsigned ctxId = isLuma(compID) ? 0 : 2; 
807
347k
  m_BinEncoder.encodeBin(bdpcmMode > 0 ? 1 : 0, Ctx::BDPCMMode(ctxId));
808
347k
  if (bdpcmMode)
809
62.0k
  {
810
62.0k
    m_BinEncoder.encodeBin(bdpcmMode > 1 ? 1 : 0, Ctx::BDPCMMode(ctxId+1));
811
62.0k
  }
812
347k
  if (isLuma(compID))
813
48.7k
  {
814
48.7k
    DTRACE(g_trace_ctx, D_SYNTAX, "bdpcm_mode(%d) x=%d, y=%d, w=%d, h=%d, bdpcm=%d\n", CH_L, cu.lumaPos().x, cu.lumaPos().y, cu.lwidth(), cu.lheight(), cu.bdpcmM[CH_L]);
815
48.7k
  }
816
298k
  else
817
298k
  {
818
298k
    DTRACE(g_trace_ctx, D_SYNTAX, "bdpcm_mode(%d) x=%d, y=%d, w=%d, h=%d, bdpcm=%d\n", CH_C, cu.chromaPos().x, cu.chromaPos().y, cu.chromaSize().width, cu.chromaSize().height, cu.bdpcmM[CH_C]);
819
298k
  }
820
347k
}
821
822
823
void CABACWriter::cu_pred_data( const CodingUnit& cu )
824
237k
{
825
237k
  if( CU::isIntra( cu ) )
826
208k
  {
827
208k
    if( cu.Y().valid() )
828
94.0k
    {
829
94.0k
      bdpcm_mode( cu, COMP_Y );
830
94.0k
    }
831
208k
    intra_luma_pred_modes  ( cu );
832
208k
    if( ( !cu.Y().valid() || ( !CU::isSepTree(cu) && cu.Y().valid() ) ) && isChromaEnabled(cu.chromaFormat) )
833
114k
    {
834
114k
      bdpcm_mode( cu, ComponentID(CH_C) );
835
114k
    } 
836
208k
    intra_chroma_pred_modes( cu );
837
208k
    return;
838
208k
  }
839
29.1k
  if (!cu.Y().valid()) // dual tree chroma CU
840
0
  {
841
0
    return;
842
0
  }
843
844
29.1k
  prediction_unit ( cu );
845
29.1k
  imv_mode        ( cu );
846
29.1k
  affine_amvr_mode( cu );
847
29.1k
  cu_bcw_flag     ( cu );
848
29.1k
}
849
850
851
void CABACWriter::cu_bcw_flag(const CodingUnit& cu)
852
29.1k
{
853
29.1k
  if(!CU::isBcwIdxCoded(cu))
854
29.1k
  {
855
29.1k
    return;
856
29.1k
  }
857
858
0
  CHECK(!(BCW_NUM > 1 && (BCW_NUM == 2 || (BCW_NUM & 0x01) == 1)), " !( BCW_NUM > 1 && ( BCW_NUM == 2 || ( BCW_NUM & 0x01 ) == 1 ) ) ");
859
0
  const uint8_t bcwCodingIdx = (uint8_t)g_BcwCodingOrder[CU::getValidBcwIdx(cu)];
860
861
0
  const int32_t numBcw = (cu.slice->checkLDC) ? 5 : 3;
862
0
  m_BinEncoder.encodeBin((bcwCodingIdx == 0 ? 0 : 1), Ctx::BcwIdx(0));
863
0
  if(numBcw > 2 && bcwCodingIdx != 0)
864
0
  {
865
0
    const uint32_t prefixNumBits = numBcw - 2;
866
0
    const uint32_t step = 1;
867
868
0
    uint8_t idx = 1;
869
0
    for(int ui = 0; ui < prefixNumBits; ++ui)
870
0
    {
871
0
      if (bcwCodingIdx == idx)
872
0
      {
873
0
        m_BinEncoder.encodeBinEP(0);
874
0
        break;
875
0
      }
876
0
      else
877
0
      {
878
0
        m_BinEncoder.encodeBinEP(1);
879
0
        idx += step;
880
0
      }
881
0
    }
882
0
  }
883
884
0
  DTRACE(g_trace_ctx, D_SYNTAX, "cu_bcw_flag() bcw_idx=%d\n", cu.BcwIdx ? 1 : 0);
885
0
}
886
887
888
void CABACWriter::xWriteTruncBinCode(uint32_t symbol, uint32_t maxSymbol)
889
1.08M
{
890
1.08M
  int thresh;
891
1.08M
  if (maxSymbol > 256)
892
0
  {
893
0
    int threshVal = 1 << 8;
894
0
    thresh = 8;
895
0
    while (threshVal <= maxSymbol)
896
0
    {
897
0
      thresh++;
898
0
      threshVal <<= 1;
899
0
    }
900
0
    thresh--;
901
0
  }
902
1.08M
  else
903
1.08M
  {
904
1.08M
    thresh = g_tbMax[maxSymbol];
905
1.08M
  }
906
907
1.08M
  int val = 1 << thresh;
908
1.08M
  assert(val <= maxSymbol);
909
1.08M
  assert((val << 1) > maxSymbol);
910
1.08M
  assert(symbol < maxSymbol);
911
1.08M
  int b = maxSymbol - val;
912
1.08M
  assert(b < val);
913
1.08M
  if (symbol < val - b)
914
340k
  {
915
340k
    m_BinEncoder.encodeBinsEP(symbol, thresh);
916
340k
  }
917
746k
  else
918
746k
  {
919
746k
    symbol += val - b;
920
746k
    assert(symbol < (val << 1));
921
746k
    assert((symbol >> 1) >= val - b);
922
746k
    m_BinEncoder.encodeBinsEP(symbol, thresh + 1);
923
746k
  }
924
1.08M
}
925
926
927
void CABACWriter::extend_ref_line(const CodingUnit& cu)
928
1.16M
{
929
1.16M
  if ( !cu.Y().valid() || cu.predMode != MODE_INTRA || !isLuma(cu.chType) || cu.bdpcmM[CH_L] )
930
0
  {
931
0
    return;
932
0
  }
933
1.16M
  if( !cu.cs->sps->MRL )
934
0
  {
935
0
    return;
936
0
  }
937
938
1.16M
  bool isFirstLineOfCtu = (((cu.block(COMP_Y).y)&((cu.cs->sps)->CTUSize - 1)) == 0);
939
1.16M
  if (isFirstLineOfCtu)
940
385k
  {
941
385k
    return;
942
385k
  }
943
780k
  int multiRefIdx = cu.multiRefIdx;
944
780k
  if (MRL_NUM_REF_LINES > 1)
945
780k
  {
946
780k
    m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[0], Ctx::MultiRefLineIdx(0));
947
780k
    if (MRL_NUM_REF_LINES > 2 && multiRefIdx != MULTI_REF_LINE_IDX[0])
948
213k
    {
949
213k
      m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], Ctx::MultiRefLineIdx(1));
950
213k
    }
951
780k
  }
952
780k
}
953
954
955
void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
956
208k
{
957
208k
  if( !cu.Y().valid() || cu.bdpcmM[CH_L] )
958
119k
  {
959
119k
    return;
960
119k
  }
961
962
88.2k
  mip_flag(cu);
963
88.2k
  if (cu.mipFlag)
964
1.73k
  {
965
1.73k
    mip_pred_modes(cu);
966
1.73k
    return;
967
1.73k
  }
968
86.4k
  extend_ref_line( cu );
969
970
86.4k
  isp_mode( cu );
971
972
86.4k
  const int numMPMs   = NUM_MOST_PROBABLE_MODES;
973
86.4k
  unsigned  mpm_pred   [numMPMs];
974
86.4k
  unsigned  mpm_idx;
975
86.4k
  unsigned  ipred_mode ;
976
977
  // prev_intra_luma_pred_flag
978
86.4k
  {
979
86.4k
    CU::getIntraMPMs( cu, mpm_pred );
980
981
86.4k
    ipred_mode = cu.intraDir[0];
982
86.4k
    mpm_idx    = numMPMs;
983
86.5k
    for( unsigned idx = 0; idx < numMPMs; idx++ )
984
86.5k
    {
985
86.5k
      if( ipred_mode == mpm_pred[idx] )
986
86.4k
      {
987
86.4k
        mpm_idx = idx;
988
86.4k
        break;
989
86.4k
      }
990
86.5k
    }
991
86.4k
    if ( cu.multiRefIdx )
992
0
    {
993
0
      CHECK(mpm_idx >= numMPMs, "use of non-MPM");
994
0
    }
995
86.4k
    else
996
86.4k
    {
997
86.4k
      m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
998
86.4k
    }
999
86.4k
  }
1000
1001
  // mpm_idx / rem_intra_luma_pred_mode
1002
86.4k
  {
1003
86.4k
    if( mpm_idx < numMPMs )
1004
86.4k
    {
1005
86.4k
      {
1006
86.4k
        unsigned ctx = (cu.ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
1007
86.4k
        if (cu.multiRefIdx == 0)
1008
86.4k
          m_BinEncoder.encodeBin(mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx));
1009
86.4k
        if( mpm_idx )
1010
99
        {
1011
99
          m_BinEncoder.encodeBinEP( mpm_idx > 1 );
1012
99
        }
1013
86.4k
        if (mpm_idx > 1)
1014
0
        {
1015
0
          m_BinEncoder.encodeBinEP(mpm_idx > 2);
1016
0
        }
1017
86.4k
        if (mpm_idx > 2)
1018
0
        {
1019
0
          m_BinEncoder.encodeBinEP(mpm_idx > 3);
1020
0
        }
1021
86.4k
        if (mpm_idx > 3)
1022
0
        {
1023
0
          m_BinEncoder.encodeBinEP(mpm_idx > 4);
1024
0
        }
1025
86.4k
      }
1026
86.4k
    }
1027
0
    else
1028
0
    {
1029
      // sorting of MPMs
1030
0
      std::sort( mpm_pred, mpm_pred + numMPMs );
1031
1032
0
      {
1033
0
        for (int idx = numMPMs - 1; idx >= 0; idx--)
1034
0
        {
1035
0
          if (ipred_mode > mpm_pred[idx])
1036
0
          {
1037
0
            ipred_mode--;
1038
0
          }
1039
0
        }
1040
0
        CHECK(ipred_mode >= 64, "Incorrect mode");
1041
0
        xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
1042
0
      }
1043
0
    }
1044
1045
86.4k
    DTRACE( g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) mode=%d\n", 0, cu.lumaPos().x, cu.lumaPos().y, cu.intraDir[0] );
1046
86.4k
  }
1047
86.4k
}
1048
1049
1050
void CABACWriter::intra_luma_pred_mode( const CodingUnit& cu, const unsigned *mpmLst )
1051
1.44M
{
1052
1.44M
  if( cu.bdpcmM[CH_L] ) 
1053
8.65k
  {
1054
8.65k
    return;
1055
8.65k
  }
1056
1057
1.43M
  mip_flag(cu);
1058
1.43M
  if (cu.mipFlag)
1059
357k
  {
1060
357k
    mip_pred_mode(cu);
1061
357k
    return;
1062
357k
  }
1063
1.08M
  extend_ref_line( cu );
1064
1065
1.08M
  isp_mode( cu );
1066
1067
  // prev_intra_luma_pred_flag
1068
1.08M
  unsigned ipred_mode = cu.intraDir[0];
1069
1.08M
  static constexpr int numMPMs = NUM_MOST_PROBABLE_MODES;
1070
1.08M
  unsigned mpm_idx = numMPMs;
1071
1.08M
  unsigned  mpm_pred[numMPMs];
1072
1073
1.08M
  if (mpmLst)
1074
1.08M
  {
1075
1.08M
    memcpy(mpm_pred, mpmLst, sizeof(unsigned) * numMPMs);
1076
1.08M
  }
1077
18
  else
1078
18
  {
1079
18
    CU::getIntraMPMs(cu, mpm_pred);
1080
18
  }
1081
1082
5.66M
  for (int idx = 0; idx < numMPMs; idx++)
1083
5.02M
  {
1084
5.02M
    if (ipred_mode == mpm_pred[idx])
1085
432k
    {
1086
432k
      mpm_idx = idx;
1087
432k
      break;
1088
432k
    }
1089
5.02M
  }
1090
1.08M
  if (cu.multiRefIdx)
1091
213k
  {
1092
213k
    CHECK(mpm_idx >= numMPMs, "use of non-MPM");
1093
213k
  }
1094
867k
  else
1095
867k
  {
1096
867k
    m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
1097
867k
  }
1098
1099
  // mpm_idx / rem_intra_luma_pred_mode
1100
1.08M
  if( mpm_idx < numMPMs )
1101
432k
  {
1102
432k
    unsigned ctx = (cu.ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
1103
432k
    if (cu.multiRefIdx == 0)
1104
218k
      m_BinEncoder.encodeBin( mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx) );
1105
432k
    if( mpm_idx )
1106
290k
    {
1107
290k
      m_BinEncoder.encodeBinEP( mpm_idx > 1 );
1108
290k
    }
1109
432k
    if (mpm_idx > 1)
1110
164k
    {
1111
164k
      m_BinEncoder.encodeBinEP(mpm_idx > 2);
1112
164k
    }
1113
432k
    if (mpm_idx > 2)
1114
122k
    {
1115
122k
      m_BinEncoder.encodeBinEP(mpm_idx > 3);
1116
122k
    }
1117
432k
    if (mpm_idx > 3)
1118
81.2k
    {
1119
81.2k
      m_BinEncoder.encodeBinEP(mpm_idx > 4);
1120
81.2k
    }
1121
432k
  }
1122
648k
  else
1123
648k
  {
1124
    // mpm_pred[0] is always 0, i.e. PLANAR, so its always first in the list
1125
648k
    std::sort( mpm_pred + 1, mpm_pred + numMPMs );
1126
1127
4.53M
    for (int idx = numMPMs - 1; idx >= 0; idx--)
1128
3.88M
    {
1129
3.88M
      if (ipred_mode > mpm_pred[idx])
1130
2.10M
      {
1131
2.10M
        ipred_mode--;
1132
2.10M
      }
1133
3.88M
    }
1134
1135
648k
    xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
1136
648k
  }
1137
1.08M
}
1138
1139
1140
void CABACWriter::intra_chroma_pred_modes( const CodingUnit& cu )
1141
208k
{
1142
208k
  if( cu.chromaFormat == CHROMA_400 || ( CU::isSepTree(cu) && cu.chType == CH_L ) || cu.bdpcmM[CH_C] )
1143
94.0k
  {
1144
94.0k
    return;
1145
94.0k
  }
1146
1147
114k
  intra_chroma_pred_mode( cu );
1148
114k
}
1149
1150
1151
void CABACWriter::intra_chroma_lmc_mode(const CodingUnit& cu)
1152
42.6k
{
1153
42.6k
  const unsigned intraDir = cu.intraDir[1];
1154
42.6k
  int lmModeList[10];
1155
42.6k
  CU::getLMSymbolList(cu, lmModeList);
1156
42.6k
  int symbol = -1;
1157
42.6k
  for (int k = 0; k < LM_SYMBOL_NUM; k++)
1158
42.6k
  {
1159
42.6k
    if (lmModeList[k] == intraDir)
1160
42.6k
    {
1161
42.6k
      symbol = k;
1162
42.6k
      break;
1163
42.6k
    }
1164
42.6k
  }
1165
42.6k
  CHECK(symbol < 0, "invalid symbol found");
1166
1167
42.6k
  m_BinEncoder.encodeBin(symbol == 0 ? 0 : 1, Ctx::CclmModeIdx(0));
1168
1169
42.6k
  if (symbol > 0)
1170
0
  {
1171
0
    CHECK(symbol > 2, "invalid symbol for MMLM");
1172
0
    unsigned int symbol_minus_1 = symbol - 1;
1173
0
    m_BinEncoder.encodeBinEP(symbol_minus_1);
1174
0
  }
1175
42.6k
}
1176
1177
1178
void CABACWriter::intra_chroma_pred_mode(const CodingUnit& cu)
1179
472k
{
1180
472k
  if (cu.colorTransform)
1181
0
  {
1182
0
    CHECK(cu.intraDir[CH_C] != DM_CHROMA_IDX, "chroma should use DM for adaptive color transform");
1183
0
    return;
1184
0
  }
1185
1186
472k
  const unsigned intraDir = cu.intraDir[1];
1187
472k
  if (cu.cs->sps->LMChroma && CU::checkCCLMAllowed(cu))
1188
324k
  {
1189
324k
    m_BinEncoder.encodeBin(CU::isLMCMode(intraDir) ? 1 : 0, Ctx::CclmModeFlag(0));
1190
324k
    if (CU::isLMCMode(intraDir))
1191
42.6k
    {
1192
42.6k
      intra_chroma_lmc_mode(cu);
1193
42.6k
      return;
1194
42.6k
    }
1195
324k
  }
1196
1197
429k
  const bool     isDerivedMode = intraDir == DM_CHROMA_IDX;
1198
429k
  m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0));
1199
429k
  if (isDerivedMode)
1200
97.3k
  {
1201
97.3k
    return;
1202
97.3k
  }
1203
1204
  // chroma candidate index
1205
332k
  unsigned chromaCandModes[NUM_CHROMA_MODE];
1206
332k
  CU::getIntraChromaCandModes(cu, chromaCandModes);
1207
1208
332k
  int candId = 0;
1209
788k
  for (; candId < NUM_CHROMA_MODE; candId++)
1210
788k
  {
1211
788k
    if (intraDir == chromaCandModes[candId])
1212
332k
    {
1213
332k
      break;
1214
332k
    }
1215
788k
  }
1216
1217
332k
  CHECK(candId >= NUM_CHROMA_MODE, "Chroma prediction mode index out of bounds");
1218
332k
  CHECK(chromaCandModes[candId] == DM_CHROMA_IDX, "The intra dir cannot be DM_CHROMA for this path");
1219
332k
  {
1220
332k
    m_BinEncoder.encodeBinsEP(candId, 2);
1221
332k
  }
1222
332k
}
1223
1224
1225
void CABACWriter::cu_residual( const CodingUnit& cu, Partitioner& partitioner, CUCtx& cuCtx )
1226
237k
{
1227
237k
  if (!CU::isIntra(cu))
1228
29.1k
  {
1229
29.1k
    if( !cu.mergeFlag )
1230
29.1k
    {
1231
29.1k
      rqt_root_cbf( cu );
1232
29.1k
    }
1233
29.1k
    if( cu.rootCbf )
1234
161
    {
1235
161
      sbt_mode( cu );
1236
161
    }
1237
1238
29.1k
    if( !cu.rootCbf )
1239
28.9k
    {
1240
28.9k
      CHECK(cu.colorTransform, "ACT should not be enabled for root_cbf = 0");
1241
28.9k
      return;
1242
28.9k
    }
1243
29.1k
  }
1244
1245
208k
  if( CU::isInter( cu ) || CU::isIBC( cu ) )
1246
161
  {
1247
161
    adaptive_color_transform(cu);
1248
161
  }
1249
1250
208k
  cuCtx.violatesLfnstConstrained[CH_L] = false;
1251
208k
  cuCtx.violatesLfnstConstrained[CH_C] = false;
1252
208k
  cuCtx.lfnstLastScanPos               = false;
1253
208k
  cuCtx.violatesMtsCoeffConstraint     = false;
1254
208k
  cuCtx.mtsLastScanPos                                = false;
1255
1256
208k
  if( cu.ispMode && isLuma( partitioner.chType ) )
1257
36
  {
1258
36
    transform_tree( *cu.cs, partitioner, cuCtx, CU::getISPType( cu, getFirstComponentOfChannel( partitioner.chType ) ), 0 );
1259
36
  }
1260
208k
  else
1261
208k
  {
1262
208k
    transform_tree( *cu.cs, partitioner, cuCtx );
1263
208k
  }
1264
1265
208k
  residual_lfnst_mode( cu, cuCtx );
1266
208k
  mts_idx            ( cu, &cuCtx );
1267
208k
}
1268
1269
1270
void CABACWriter::rqt_root_cbf( const CodingUnit& cu )
1271
58.2k
{
1272
58.2k
  m_BinEncoder.encodeBin( cu.rootCbf, Ctx::QtRootCbf() );
1273
1274
58.2k
  DTRACE( g_trace_ctx, D_SYNTAX, "rqt_root_cbf() ctx=0 root_cbf=%d pos=(%d,%d)\n", cu.rootCbf ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y );
1275
58.2k
}
1276
1277
1278
void CABACWriter::adaptive_color_transform(const CodingUnit& cu)
1279
103k
{
1280
103k
  if (!cu.slice->sps->useColorTrans )
1281
103k
  {
1282
103k
    return;
1283
103k
  }
1284
1285
0
  if (CU::isSepTree(cu))
1286
0
  {
1287
0
    CHECK(cu.colorTransform, "adaptive color transform should be disabled when dualtree and localtree are enabled");
1288
0
    return;
1289
0
  }
1290
1291
0
  if (CU::isInter(cu) || CU::isIBC(cu) || CU::isIntra(cu))
1292
0
  {
1293
0
    m_BinEncoder.encodeBin(cu.colorTransform, Ctx::ACTFlag());
1294
0
  }
1295
0
}
1296
1297
1298
void CABACWriter::sbt_mode( const CodingUnit& cu )
1299
161
{
1300
161
  uint8_t sbtAllowed = CU::checkAllowedSbt(cu);
1301
161
  if( !sbtAllowed )
1302
161
  {
1303
161
    return;
1304
161
  }
1305
1306
0
  SizeType cuWidth = cu.lwidth();
1307
0
  SizeType cuHeight = cu.lheight();
1308
0
  uint8_t sbtIdx = CU::getSbtIdx( cu.sbtInfo );
1309
0
  uint8_t sbtPos = CU::getSbtPos( cu.sbtInfo );
1310
1311
  //bin - flag
1312
0
  bool sbtFlag = cu.sbtInfo != 0;
1313
0
  uint8_t ctxIdx = ( cuWidth * cuHeight <= 256 ) ? 1 : 0;
1314
0
  m_BinEncoder.encodeBin( sbtFlag, Ctx::SbtFlag( ctxIdx ) );
1315
0
  if( !sbtFlag )
1316
0
  {
1317
0
    return;
1318
0
  }
1319
1320
0
  bool sbtQuadFlag = sbtIdx == SBT_HOR_QUAD || sbtIdx == SBT_VER_QUAD;
1321
0
  bool sbtHorFlag = sbtIdx == SBT_HOR_HALF || sbtIdx == SBT_HOR_QUAD;
1322
0
  bool sbtPosFlag = sbtPos == SBT_POS1;
1323
1324
0
  uint8_t sbtVerHalfAllow = CU::targetSbtAllowed( SBT_VER_HALF, sbtAllowed );
1325
0
  uint8_t sbtHorHalfAllow = CU::targetSbtAllowed( SBT_HOR_HALF, sbtAllowed );
1326
0
  uint8_t sbtVerQuadAllow = CU::targetSbtAllowed( SBT_VER_QUAD, sbtAllowed );
1327
0
  uint8_t sbtHorQuadAllow = CU::targetSbtAllowed( SBT_HOR_QUAD, sbtAllowed );
1328
  //bin - type
1329
0
  if( ( sbtHorHalfAllow || sbtVerHalfAllow ) && ( sbtHorQuadAllow || sbtVerQuadAllow ) )
1330
0
  {
1331
0
    m_BinEncoder.encodeBin( sbtQuadFlag, Ctx::SbtQuadFlag( 0 ) );
1332
0
  }
1333
0
  else
1334
0
  {
1335
0
    assert( sbtQuadFlag == 0 );
1336
0
  }
1337
1338
  //bin - dir
1339
0
  if( ( sbtQuadFlag && sbtVerQuadAllow && sbtHorQuadAllow ) || ( !sbtQuadFlag && sbtVerHalfAllow && sbtHorHalfAllow ) ) //both direction allowed
1340
0
  {
1341
0
    uint8_t ctxIdx = ( cuWidth == cuHeight ) ? 0 : ( cuWidth < cuHeight ? 1 : 2 );
1342
0
    m_BinEncoder.encodeBin( sbtHorFlag, Ctx::SbtHorFlag( ctxIdx ) );
1343
0
  }
1344
0
  else
1345
0
  {
1346
0
    assert( sbtHorFlag == ( ( sbtQuadFlag && sbtHorQuadAllow ) || ( !sbtQuadFlag && sbtHorHalfAllow ) ) );
1347
0
  }
1348
1349
  //bin - pos
1350
0
  m_BinEncoder.encodeBin( sbtPosFlag, Ctx::SbtPosFlag( 0 ) );
1351
1352
0
  DTRACE( g_trace_ctx, D_SYNTAX, "sbt_mode() pos=(%d,%d) sbtInfo=%d\n", cu.lx(), cu.ly(), (int)cu.sbtInfo );
1353
0
}
1354
1355
1356
void CABACWriter::end_of_ctu( const CodingUnit& cu, CUCtx& cuCtx )
1357
103k
{
1358
103k
  const bool    isLastSubCUOfCtu  = CU::isLastSubCUOfCtu( cu );
1359
1360
103k
  if ( isLastSubCUOfCtu
1361
19.9k
    && ( !CU::isSepTree(cu) || cu.chromaFormat == CHROMA_400 || isChroma( cu.chType ) )
1362
103k
      )
1363
9.95k
  {
1364
9.95k
    cuCtx.isDQPCoded = ( cu.cs->pps->useDQP && !cuCtx.isDQPCoded );
1365
1366
9.95k
  }
1367
103k
}
1368
1369
1370
void CABACWriter::cu_palette_info(const CodingUnit& cu, ComponentID compBegin, uint32_t numComp, CUCtx& cuCtx)
1371
0
{
1372
0
  THROW("no support");
1373
0
}
1374
1375
1376
//================================================================================
1377
//  clause 7.3.8.6
1378
//--------------------------------------------------------------------------------
1379
//    void  prediction_unit ( cu );
1380
//    void  merge_flag      ( cu );
1381
//    void  merge_idx       ( cu );
1382
//    void  inter_pred_idc  ( cu );
1383
//    void  ref_idx         ( cu, refList );
1384
//    void  mvp_flag        ( cu, refList );
1385
//================================================================================
1386
1387
void CABACWriter::prediction_unit( const CodingUnit& cu )
1388
29.1k
{
1389
29.1k
  CHECK( cu.treeType == TREE_C, "cannot be chroma CU" );
1390
29.1k
  if( cu.skip )
1391
0
  {
1392
0
    CHECK( !cu.mergeFlag, "merge_flag must be true for skipped CUs" );
1393
0
  }
1394
29.1k
  else
1395
29.1k
  {
1396
29.1k
    merge_flag( cu );
1397
29.1k
  }
1398
29.1k
  if( cu.mergeFlag )
1399
0
  {
1400
0
    merge_data(cu);
1401
0
  }
1402
29.1k
  else if (CU::isIBC(cu))
1403
29.1k
  {
1404
29.1k
    ref_idx(cu, REF_PIC_LIST_0);
1405
29.1k
    Mv mvd = cu.mvd[REF_PIC_LIST_0][0];
1406
29.1k
    mvd.changeIbcPrecInternal2Amvr(cu.imv);
1407
29.1k
    mvd_coding(mvd, 0); // already changed to signaling precision
1408
29.1k
    if ( cu.slice->sps->maxNumIBCMergeCand == 1 )
1409
0
    {
1410
0
      CHECK( cu.mvpIdx[REF_PIC_LIST_0], "mvpIdx for IBC mode should be 0" );
1411
0
    }
1412
29.1k
    else
1413
29.1k
    mvp_flag(cu, REF_PIC_LIST_0);
1414
29.1k
  }
1415
0
  else
1416
0
  {
1417
0
    inter_pred_idc( cu );
1418
0
    affine_flag   ( cu );
1419
0
    smvd_mode( cu );
1420
0
    if( cu.interDir != 2 /* PRED_L1 */ )
1421
0
    {
1422
0
      ref_idx     ( cu, REF_PIC_LIST_0 );
1423
0
      if ( cu.affine )
1424
0
      {
1425
0
        Mv mvd = cu.mvd[REF_PIC_LIST_0][0];
1426
0
        mvd.changeAffinePrecInternal2Amvr(cu.imv);
1427
0
        mvd_coding(mvd, 0); // already changed to signaling precision
1428
0
        mvd = cu.mvd[REF_PIC_LIST_0][1];
1429
0
        mvd.changeAffinePrecInternal2Amvr(cu.imv);
1430
0
        mvd_coding(mvd, 0); // already changed to signaling precision
1431
0
        if ( cu.affineType == AFFINEMODEL_6PARAM )
1432
0
        {
1433
0
          mvd = cu.mvd[REF_PIC_LIST_0][2];
1434
0
          mvd.changeAffinePrecInternal2Amvr(cu.imv);
1435
0
          mvd_coding(mvd, 0); // already changed to signaling precision
1436
0
        }
1437
0
      }
1438
0
      else
1439
0
      {
1440
0
        Mv mvd = cu.mvd[REF_PIC_LIST_0][0];
1441
0
        mvd.changeTransPrecInternal2Amvr(cu.imv);
1442
0
        mvd_coding(mvd, 0); // already changed to signaling precision
1443
0
      }
1444
0
      mvp_flag    ( cu, REF_PIC_LIST_0 );
1445
0
    }
1446
0
    if( cu.interDir != 1 /* PRED_L0 */ )
1447
0
    {
1448
0
      if ( cu.smvdMode != 1 )
1449
0
      {
1450
0
        ref_idx     ( cu, REF_PIC_LIST_1 );
1451
0
        if( !cu.cs->picHeader->mvdL1Zero || cu.interDir != 3 /* PRED_BI */ )
1452
0
        {
1453
0
          if ( cu.affine )
1454
0
          {
1455
0
            Mv mvd = cu.mvd[REF_PIC_LIST_1][0];
1456
0
            mvd.changeAffinePrecInternal2Amvr(cu.imv);
1457
0
            mvd_coding(mvd, 0); // already changed to signaling precision
1458
0
            mvd = cu.mvd[REF_PIC_LIST_1][1];
1459
0
            mvd.changeAffinePrecInternal2Amvr(cu.imv);
1460
0
            mvd_coding(mvd, 0); // already changed to signaling precision
1461
0
            if ( cu.affineType == AFFINEMODEL_6PARAM )
1462
0
            {
1463
0
              mvd = cu.mvd[REF_PIC_LIST_1][2];
1464
0
              mvd.changeAffinePrecInternal2Amvr(cu.imv);
1465
0
              mvd_coding(mvd, 0); // already changed to signaling precision
1466
0
            }
1467
0
          }
1468
0
          else
1469
0
          {
1470
0
            Mv mvd = cu.mvd[REF_PIC_LIST_1][0];
1471
0
            mvd.changeTransPrecInternal2Amvr(cu.imv);
1472
0
            mvd_coding(mvd, 0); // already changed to signaling precision
1473
0
          }
1474
0
        }
1475
0
      }
1476
0
      mvp_flag    ( cu, REF_PIC_LIST_1 );
1477
0
    }
1478
0
  }
1479
29.1k
}
1480
1481
1482
void CABACWriter::smvd_mode( const CodingUnit& cu )
1483
0
{
1484
0
  if ( cu.interDir != 3 || cu.affine )
1485
0
  {
1486
0
    return;
1487
0
  }
1488
1489
0
  if ( cu.cs->slice->biDirPred == false )
1490
0
  {
1491
0
    return;
1492
0
  }
1493
1494
0
  m_BinEncoder.encodeBin( cu.smvdMode ? 1 : 0, Ctx::SmvdFlag() );
1495
1496
0
  DTRACE( g_trace_ctx, D_SYNTAX, "symmvd_flag() symmvd=%d pos=(%d,%d) size=%dx%d\n", cu.smvdMode ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height );
1497
0
}
1498
1499
1500
void CABACWriter::subblock_merge_flag( const CodingUnit& cu )
1501
0
{
1502
1503
0
  if ( !cu.cs->slice->isIntra() && (cu.slice->picHeader->maxNumAffineMergeCand > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
1504
0
  {
1505
0
    unsigned ctxId = DeriveCtx::CtxAffineFlag();
1506
0
    m_BinEncoder.encodeBin( cu.affine, Ctx::SubblockMergeFlag( ctxId ) );
1507
0
    DTRACE( g_trace_ctx, D_SYNTAX, "subblock_merge_flag() subblock_merge_flag=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
1508
0
  }
1509
0
}
1510
1511
1512
void CABACWriter::affine_flag( const CodingUnit& cu )
1513
0
{
1514
0
  if ( !cu.cs->slice->isIntra() && cu.cs->sps->Affine && cu.lumaSize().width > 8 && cu.lumaSize().height > 8 )
1515
0
  {
1516
0
    unsigned ctxId = DeriveCtx::CtxAffineFlag();
1517
0
    m_BinEncoder.encodeBin( cu.affine, Ctx::AffineFlag( ctxId ) );
1518
0
    DTRACE( g_trace_ctx, D_SYNTAX, "affine_flag() affine=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
1519
1520
0
    if ( cu.affine && cu.cs->sps->AffineType )
1521
0
    {
1522
0
      unsigned ctxId = 0;
1523
0
      m_BinEncoder.encodeBin( cu.affineType, Ctx::AffineType( ctxId ) );
1524
0
      DTRACE( g_trace_ctx, D_SYNTAX, "affine_type() affine_type=%d ctx=%d pos=(%d,%d)\n", cu.affineType ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
1525
0
    }
1526
0
  }
1527
0
}
1528
1529
1530
void CABACWriter::merge_flag( const CodingUnit& cu )
1531
29.1k
{
1532
29.1k
  m_BinEncoder.encodeBin( cu.mergeFlag, Ctx::MergeFlag() );
1533
1534
29.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "merge_flag() merge=%d pos=(%d,%d) size=%dx%d\n", cu.mergeFlag ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height );
1535
29.1k
}
1536
1537
1538
void CABACWriter::merge_data(const CodingUnit& cu)
1539
0
{
1540
0
  if (CU::isIBC(cu))
1541
0
  {
1542
0
    merge_idx(cu);
1543
0
    return;
1544
0
  }
1545
0
  subblock_merge_flag(cu);
1546
0
  if (cu.affine)
1547
0
  {
1548
0
    merge_idx(cu);
1549
0
    return;
1550
0
  }
1551
1552
0
  const bool ciipAvailable = cu.cs->sps->CIIP && !cu.skip && cu.Y().maxDim() < MAX_CU_SIZE && cu.Y().area() >= 64;
1553
0
  const bool geoAvailable = cu.cs->slice->sps->GEO && cu.cs->slice->isInterB() && cu.cs->sps->maxNumGeoCand > 1
1554
0
                                                   && cu.Y().minDim() >= GEO_MIN_CU_SIZE && cu.Y().maxDim() <= GEO_MAX_CU_SIZE
1555
0
                                                   && cu.Y().maxDim() < 8 * cu.Y().minDim();
1556
1557
0
  if (geoAvailable || ciipAvailable)
1558
0
  {
1559
0
    m_BinEncoder.encodeBin(!cu.geo && !cu.ciip, Ctx::RegularMergeFlag(cu.skip ? 0 : 1));
1560
0
  }
1561
0
  if (!cu.geo && !cu.ciip)
1562
0
  {
1563
0
    if (cu.cs->sps->MMVD)
1564
0
    {
1565
0
      m_BinEncoder.encodeBin(cu.mmvdMergeFlag, Ctx::MmvdFlag(0));
1566
0
      DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_flag() mmvd_merge=%d pos=(%d,%d) size=%dx%d\n", cu.mmvdMergeFlag ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height);
1567
0
    }
1568
0
    if (cu.mmvdMergeFlag || cu.mmvdSkip)
1569
0
    {
1570
0
      mmvd_merge_idx(cu);
1571
0
    }
1572
0
    else
1573
0
    {
1574
0
      merge_idx(cu);
1575
0
    }
1576
0
  }
1577
0
  else
1578
0
  {
1579
0
    if (geoAvailable && ciipAvailable)
1580
0
    {
1581
0
      ciip_flag(cu);
1582
0
    }
1583
0
    merge_idx(cu);
1584
0
  }
1585
0
}
1586
1587
1588
void CABACWriter::imv_mode( const CodingUnit& cu )
1589
29.1k
{
1590
29.1k
  const SPS *sps = cu.cs->sps;
1591
1592
29.1k
  if( !sps->AMVR )
1593
0
  {
1594
0
    return;
1595
0
  }
1596
29.1k
  if ( cu.affine )
1597
0
  {
1598
0
    return;
1599
0
  }
1600
1601
29.1k
  bool bNonZeroMvd = CU::hasSubCUNonZeroMVd( cu );
1602
29.1k
  if( !bNonZeroMvd )
1603
0
  {
1604
0
    return;
1605
0
  }
1606
1607
29.1k
  if (CU::isIBC(cu) == false)
1608
0
    m_BinEncoder.encodeBin( (cu.imv > 0), Ctx::ImvFlag( 0 ) );
1609
29.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 0), 0 );
1610
1611
29.1k
  if( sps->AMVR && cu.imv > 0 )
1612
29.1k
  {
1613
29.1k
    if (!CU::isIBC(cu))
1614
0
    {
1615
0
      m_BinEncoder.encodeBin(cu.imv < IMV_HPEL, Ctx::ImvFlag(4));
1616
0
      DTRACE(g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", cu.imv < 3, 4);
1617
0
    }
1618
29.1k
    if (cu.imv < IMV_HPEL)
1619
29.1k
    {
1620
29.1k
    m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 1 ) );
1621
29.1k
    DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 1), 1 );
1622
29.1k
    }
1623
29.1k
  }
1624
1625
29.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() IMVFlag=%d\n", cu.imv );
1626
29.1k
}
1627
1628
1629
void CABACWriter::affine_amvr_mode( const CodingUnit& cu )
1630
29.1k
{
1631
29.1k
  const SPS* sps = cu.slice->sps;
1632
1633
29.1k
  if( !sps->AffineAmvr || !cu.affine )
1634
29.1k
  {
1635
29.1k
    return;
1636
29.1k
  }
1637
1638
0
  if ( !CU::hasSubCUNonZeroAffineMVd( cu ) )
1639
0
  {
1640
0
    return;
1641
0
  }
1642
1643
0
  m_BinEncoder.encodeBin( (cu.imv > 0), Ctx::ImvFlag( 2 ) );
1644
0
  DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", (cu.imv > 0), 2 );
1645
1646
0
  if( cu.imv > 0 )
1647
0
  {
1648
0
    m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 3 ) );
1649
0
    DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", (cu.imv > 1), 3 );
1650
0
  }
1651
0
  DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() IMVFlag=%d\n", cu.imv );
1652
0
}
1653
1654
1655
void CABACWriter::merge_idx( const CodingUnit& cu )
1656
0
{
1657
0
  if ( cu.affine )
1658
0
  {
1659
0
    int numCandminus1 = int( cu.cs->picHeader->maxNumAffineMergeCand ) - 1;
1660
0
    if ( numCandminus1 > 0 )
1661
0
    {
1662
0
      if ( cu.mergeIdx == 0 )
1663
0
      {
1664
0
        m_BinEncoder.encodeBin( 0, Ctx::AffMergeIdx() );
1665
0
        DTRACE( g_trace_ctx, D_SYNTAX, "aff_merge_idx() aff_merge_idx=%d\n", cu.mergeIdx );
1666
0
        return;
1667
0
      }
1668
0
      else
1669
0
      {
1670
0
        m_BinEncoder.encodeBin( 1, Ctx::AffMergeIdx() );
1671
0
        for ( unsigned idx = 1; idx < numCandminus1; idx++ )
1672
0
        {
1673
0
            m_BinEncoder.encodeBinEP( cu.mergeIdx == idx ? 0 : 1 );
1674
0
          if ( cu.mergeIdx == idx )
1675
0
          {
1676
0
            break;
1677
0
          }
1678
0
        }
1679
0
      }
1680
0
    }
1681
0
    DTRACE( g_trace_ctx, D_SYNTAX, "aff_merge_idx() aff_merge_idx=%d\n", cu.mergeIdx );
1682
0
  }
1683
0
  else
1684
0
  {
1685
0
    if( cu.geo )
1686
0
    {
1687
0
      uint8_t splitDir = cu.geoSplitDir;
1688
0
      uint8_t candIdx0 = cu.geoMergeIdx[0];
1689
0
      uint8_t candIdx1 = cu.geoMergeIdx[1];
1690
0
      DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_split_dir=%d\n", splitDir );
1691
0
      DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_idx0=%d\n", candIdx0 );
1692
0
      DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_idx1=%d\n", candIdx1 );
1693
0
      xWriteTruncBinCode(splitDir, GEO_NUM_PARTITION_MODE);
1694
0
      candIdx1 -= candIdx1 < candIdx0 ? 0 : 1;
1695
0
      const int maxNumGeoCand = cu.cs->sps->maxNumGeoCand;
1696
0
      CHECK(maxNumGeoCand < 2, "Incorrect max number of geo candidates");
1697
0
      CHECK(candIdx0 >= maxNumGeoCand, "Incorrect candIdx0");
1698
0
      CHECK(candIdx1 >= maxNumGeoCand, "Incorrect candIdx1");
1699
0
      int numCandminus2 = maxNumGeoCand - 2;
1700
0
      m_BinEncoder.encodeBin( candIdx0 == 0 ? 0 : 1, Ctx::MergeIdx() );
1701
0
      if( candIdx0 > 0 )
1702
0
      {
1703
0
        unary_max_eqprob(candIdx0 - 1, numCandminus2);
1704
0
      }
1705
0
      if (numCandminus2 > 0)
1706
0
      {
1707
0
        m_BinEncoder.encodeBin(candIdx1 == 0 ? 0 : 1, Ctx::MergeIdx());
1708
0
        if (candIdx1 > 0)
1709
0
        {
1710
0
          unary_max_eqprob(candIdx1 - 1, numCandminus2 - 1);
1711
0
        }
1712
0
      }
1713
0
      return;
1714
0
    }
1715
0
    int numCandminus1 = (cu.predMode == MODE_IBC) ? (int(cu.cs->sps->maxNumIBCMergeCand) - 1) : (int(cu.cs->sps->maxNumMergeCand) - 1);
1716
0
    if( numCandminus1 > 0 )
1717
0
    {
1718
0
      if( cu.mergeIdx == 0 )
1719
0
      {
1720
0
        m_BinEncoder.encodeBin( 0, Ctx::MergeIdx() );
1721
0
        DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", cu.mergeIdx );
1722
0
        return;
1723
0
      }
1724
0
      else
1725
0
      {
1726
0
        m_BinEncoder.encodeBin( 1, Ctx::MergeIdx() );
1727
0
        for( unsigned idx = 1; idx < numCandminus1; idx++ )
1728
0
        {
1729
0
          m_BinEncoder.encodeBinEP( cu.mergeIdx == idx ? 0 : 1 );
1730
0
          if( cu.mergeIdx == idx )
1731
0
          {
1732
0
            break;
1733
0
          }
1734
0
        }
1735
0
      }
1736
0
    }
1737
0
    DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", cu.mergeIdx );
1738
0
  }
1739
0
}
1740
1741
1742
void CABACWriter::mmvd_merge_idx( const CodingUnit &cu )
1743
0
{
1744
0
  const int mvdBaseIdx  = cu.mmvdMergeIdx.pos.baseIdx;
1745
0
  const int mvdStep     = cu.mmvdMergeIdx.pos.step;
1746
0
  const int mvdPosition = cu.mmvdMergeIdx.pos.position;
1747
1748
0
  if( cu.cs->sps->maxNumMergeCand > 1 )
1749
0
  {
1750
0
    static_assert( MMVD_BASE_MV_NUM == 2, "" );
1751
0
    CHECK( mvdBaseIdx >= 2, "Invalid mvdBaseIdx" );
1752
0
    m_BinEncoder.encodeBin( mvdBaseIdx, Ctx::MmvdMergeIdx() );
1753
0
  }
1754
0
  DTRACE( g_trace_ctx, D_SYNTAX, "base_mvp_idx() base_mvp_idx=%d\n", mvdBaseIdx );
1755
1756
0
  int numCandminus1_step = MMVD_REFINE_STEP - 1;
1757
0
  if( numCandminus1_step > 0 )
1758
0
  {
1759
0
    if( mvdStep == 0 )
1760
0
    {
1761
0
      m_BinEncoder.encodeBin( 0, Ctx::MmvdStepMvpIdx() );
1762
0
    }
1763
0
    else
1764
0
    {
1765
0
      m_BinEncoder.encodeBin( 1, Ctx::MmvdStepMvpIdx() );
1766
0
      for( unsigned idx = 1; idx < numCandminus1_step; idx++ )
1767
0
      {
1768
0
        m_BinEncoder.encodeBinEP( mvdStep == idx ? 0 : 1 );
1769
0
        if( mvdStep == idx )
1770
0
        {
1771
0
          break;
1772
0
        }
1773
0
      }
1774
0
    }
1775
0
  }
1776
0
  DTRACE( g_trace_ctx, D_SYNTAX, "MmvdStepMvpIdx() MmvdStepMvpIdx=%d\n", mvdStep );
1777
1778
0
  m_BinEncoder.encodeBinsEP( mvdPosition, 2 );
1779
1780
0
  DTRACE( g_trace_ctx, D_SYNTAX, "pos() pos=%d\n", mvdPosition );
1781
0
  DTRACE( g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", cu.mmvdMergeIdx.val );
1782
0
}
1783
1784
1785
void CABACWriter::inter_pred_idc( const CodingUnit& cu )
1786
0
{
1787
0
  if( !cu.cs->slice->isInterB() )
1788
0
  {
1789
0
    return;
1790
0
  }
1791
0
  if( !(CU::isBipredRestriction(cu)) )
1792
0
  {
1793
0
    unsigned ctxId = DeriveCtx::CtxInterDir(cu);
1794
0
    if( cu.interDir == 3 )
1795
0
    {
1796
0
      m_BinEncoder.encodeBin( 1, Ctx::InterDir(ctxId) );
1797
0
      DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=%d value=%d pos=(%d,%d)\n", ctxId, cu.interDir, cu.lumaPos().x, cu.lumaPos().y );
1798
0
      return;
1799
0
    }
1800
0
    else
1801
0
    {
1802
0
      m_BinEncoder.encodeBin( 0, Ctx::InterDir(ctxId) );
1803
0
    }
1804
0
  }
1805
0
  m_BinEncoder.encodeBin( ( cu.interDir == 2 ), Ctx::InterDir( 5 ) );
1806
0
  DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=5 value=%d pos=(%d,%d)\n", cu.interDir, cu.lumaPos().x, cu.lumaPos().y );
1807
0
}
1808
1809
1810
void CABACWriter::ref_idx( const CodingUnit& cu, RefPicList eRefList )
1811
29.1k
{
1812
29.1k
  if ( cu.smvdMode )
1813
0
  {
1814
0
    CHECK( cu.refIdx[eRefList] != cu.cs->slice->symRefIdx[ eRefList ], "Invalid reference index!\n" );
1815
0
    return;
1816
0
  }
1817
1818
29.1k
  int numRef  = cu.cs->slice->numRefIdx[eRefList];
1819
1820
29.1k
  if (eRefList == REF_PIC_LIST_0 && cu.cs->sps->IBC)
1821
29.1k
  {
1822
29.1k
    if (CU::isIBC(cu))
1823
29.1k
      return;
1824
29.1k
  }
1825
1826
0
  if( numRef <= 1 )
1827
0
  {
1828
0
    return;
1829
0
  }
1830
0
  int refIdx  = cu.refIdx[eRefList];
1831
0
  m_BinEncoder.encodeBin( (refIdx > 0), Ctx::RefPic() );
1832
0
  if( numRef <= 2 || refIdx == 0 )
1833
0
  {
1834
0
    DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y );
1835
0
    return;
1836
0
  }
1837
0
  m_BinEncoder.encodeBin( (refIdx > 1), Ctx::RefPic(1) );
1838
0
  if( numRef <= 3 || refIdx == 1 )
1839
0
  {
1840
0
    DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y );
1841
0
    return;
1842
0
  }
1843
0
  for( int idx = 3; idx < numRef; idx++ )
1844
0
  {
1845
0
    if( refIdx > idx - 1 )
1846
0
    {
1847
0
      m_BinEncoder.encodeBinEP( 1 );
1848
0
    }
1849
0
    else
1850
0
    {
1851
0
      m_BinEncoder.encodeBinEP( 0 );
1852
0
      break;
1853
0
    }
1854
0
  }
1855
0
  DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y );
1856
0
}
1857
1858
1859
void CABACWriter::mvp_flag( const CodingUnit& cu, RefPicList eRefList )
1860
29.1k
{
1861
29.1k
  m_BinEncoder.encodeBin( cu.mvpIdx[eRefList], Ctx::MVPIdx() );
1862
29.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "mvp_flag() value=%d pos=(%d,%d)\n", cu.mvpIdx[eRefList], cu.lumaPos().x, cu.lumaPos().y );
1863
29.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "mvpIdx(refList:%d)=%d\n", eRefList, cu.mvpIdx[eRefList] );
1864
29.1k
}
1865
1866
1867
void CABACWriter::ciip_flag(const CodingUnit& cu)
1868
0
{
1869
0
  if (!cu.cs->sps->CIIP)
1870
0
  {
1871
0
    CHECK(cu.ciip == true, "invalid Ciip SPS");
1872
0
    return;
1873
0
  }
1874
0
  if (cu.skip)
1875
0
  {
1876
0
    CHECK(cu.ciip == true, "invalid Ciip and skip");
1877
0
    return;
1878
0
  }
1879
0
  m_BinEncoder.encodeBin(cu.ciip, Ctx::CiipFlag());
1880
0
  DTRACE(g_trace_ctx, D_SYNTAX, "Ciip_flag() Ciip=%d pos=(%d,%d) size=%dx%d\n", cu.ciip ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height);
1881
0
}
1882
1883
1884
//================================================================================
1885
//  clause 7.3.8.8
1886
//--------------------------------------------------------------------------------
1887
//    void  transform_tree      ( cs, area, cuCtx, chromaCbfs )
1888
//    bool  split_transform_flag( split, depth )
1889
//    bool  cbf_comp            ( cbf, area, depth )
1890
//================================================================================
1891
1892
void CABACWriter::transform_tree( const CodingStructure& cs, Partitioner& partitioner, CUCtx& cuCtx, const PartSplit ispType, const int subTuIdx )
1893
208k
{
1894
208k
  const UnitArea&       area = partitioner.currArea();
1895
208k
  int             subTuCounter = subTuIdx;
1896
208k
  const TransformUnit&  tu = *cs.getTU(area.blocks[partitioner.chType].pos(), partitioner.chType, subTuIdx);
1897
208k
  const CodingUnit&     cu = *tu.cu;
1898
208k
  const unsigned        trDepth = partitioner.currTrDepth;
1899
208k
  const bool            split = (tu.depth > trDepth);
1900
208k
  if( split )
1901
36
  {
1902
36
    PartSplit partSplit;
1903
1904
36
    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
1905
0
    {
1906
#if ENABLE_TRACING
1907
      const CompArea& tuArea = partitioner.currArea().blocks[partitioner.chType];
1908
      DTRACE( g_trace_ctx, D_SYNTAX, "transform_tree() maxTrSplit chType=%d pos=(%d,%d) size=%dx%d\n", partitioner.chType, tuArea.x, tuArea.y, tuArea.width, tuArea.height );
1909
1910
#endif
1911
0
      partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );
1912
0
    }
1913
36
    else if( cu.ispMode )
1914
36
    {
1915
36
      partitioner.splitCurrArea( ispType, cs );
1916
36
    }
1917
0
    else if( cu.sbtInfo && partitioner.canSplit( partSplit = CU::getSbtTuSplit( cu.sbtInfo ), cs ) )
1918
0
    {
1919
0
      partitioner.splitCurrArea( partSplit, cs );
1920
0
    }
1921
0
    else
1922
0
      THROW( "Implicit TU split not available" );
1923
1924
36
    do
1925
144
    {
1926
144
      transform_tree( cs, partitioner, cuCtx,                ispType, subTuCounter );
1927
144
      subTuCounter += subTuCounter != -1 ? 1 : 0;
1928
144
    } while( partitioner.nextPart( cs ) );
1929
1930
36
    partitioner.exitCurrSplit();
1931
36
  }
1932
208k
  else
1933
208k
  {
1934
    // split_transform_flag
1935
208k
    CHECK( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) || (cu.sbtInfo && partitioner.canSplit( CU::getSbtTuSplit( cu.sbtInfo ), cs)),  "transform split implied" );
1936
208k
    DTRACE( g_trace_ctx, D_SYNTAX, "transform_unit() pos=(%d,%d) size=%dx%d depth=%d trDepth=%d\n", tu.blocks[tu.chType].x, tu.blocks[tu.chType].y, tu.blocks[tu.chType].width, tu.blocks[tu.chType].height, cu.depth, partitioner.currTrDepth );
1937
1938
208k
    transform_unit( tu, cuCtx, partitioner, subTuCounter);
1939
208k
  }
1940
208k
}
1941
1942
1943
void CABACWriter::cbf_comp( const CodingUnit& cu, bool cbf, const CompArea& area, unsigned depth, const bool prevCbf, const bool useISP )
1944
3.90M
{
1945
3.90M
  const CtxSet&   ctxSet  = Ctx::QtCbf[ area.compID ];
1946
3.90M
  unsigned  ctxId;
1947
3.90M
  if( cu.bdpcmM[toChannelType(area.compID)] )
1948
243k
  {
1949
243k
    ctxId = (area.compID != COMP_Cr) ? 1 : 2;
1950
243k
    m_BinEncoder.encodeBin(cbf, ctxSet(ctxId));
1951
243k
  }
1952
3.66M
  else
1953
3.66M
  {
1954
3.66M
    ctxId = DeriveCtx::CtxQtCbf(area.compID, prevCbf, useISP && isLuma(area.compID));
1955
3.66M
    m_BinEncoder.encodeBin( cbf, ctxSet( ctxId ) );
1956
3.66M
  }
1957
3.90M
  DTRACE( g_trace_ctx, D_SYNTAX, "cbf_comp() etype=%d pos=(%d,%d) ctx=%d cbf=%d\n", area.compID, area.x, area.y, ctxId, cbf );
1958
3.90M
}
1959
1960
1961
1962
//================================================================================
1963
//  clause 7.3.8.9
1964
//--------------------------------------------------------------------------------
1965
//    void  mvd_coding( cu, refList )
1966
//================================================================================
1967
void CABACWriter::mvd_coding( const Mv &rMvd, int8_t imv )
1968
29.1k
{
1969
29.1k
  int       horMvd = rMvd.hor;
1970
29.1k
  int       verMvd = rMvd.ver;
1971
29.1k
  if ( imv > 0 )
1972
0
  {
1973
0
    int shift = 1;
1974
0
    if (imv < IMV_HPEL)
1975
0
    {
1976
0
      shift = 2;
1977
0
      if (imv == IMV_4PEL)
1978
0
      {
1979
0
        shift = 4;
1980
0
      }
1981
0
    }
1982
1983
0
    CHECK((horMvd % (1<<shift)) != 0 && (verMvd % (4<<shift)) != 0, "IMV: MVD is not a multiple of 2^N ");
1984
0
    horMvd >>= shift;
1985
0
    verMvd >>= shift;
1986
0
  }
1987
29.1k
  unsigned  horAbs  = unsigned( horMvd < 0 ? -horMvd : horMvd );
1988
29.1k
  unsigned  verAbs  = unsigned( verMvd < 0 ? -verMvd : verMvd );
1989
1990
1991
  // abs_mvd_greater0_flag[ 0 | 1 ]
1992
29.1k
  m_BinEncoder.encodeBin( (horAbs > 0), Ctx::Mvd() );
1993
29.1k
  m_BinEncoder.encodeBin( (verAbs > 0), Ctx::Mvd() );
1994
1995
  // abs_mvd_greater1_flag[ 0 | 1 ]
1996
29.1k
  if( horAbs > 0 )
1997
18.3k
  {
1998
18.3k
    m_BinEncoder.encodeBin( (horAbs > 1), Ctx::Mvd(1) );
1999
18.3k
  }
2000
29.1k
  if( verAbs > 0 )
2001
10.7k
  {
2002
10.7k
    m_BinEncoder.encodeBin( (verAbs > 1), Ctx::Mvd(1) );
2003
10.7k
  }
2004
2005
  // abs_mvd_minus2[ 0 | 1 ] and mvd_sign_flag[ 0 | 1 ]
2006
29.1k
  if( horAbs > 0 )
2007
18.3k
  {
2008
18.3k
    if( horAbs > 1 )
2009
18.3k
    {
2010
18.3k
      m_BinEncoder.encodeRemAbsEP(horAbs - 2, 1, 0, MV_BITS - 1);
2011
18.3k
    }
2012
18.3k
    m_BinEncoder.encodeBinEP( (horMvd < 0) );
2013
18.3k
  }
2014
29.1k
  if( verAbs > 0 )
2015
10.7k
  {
2016
10.7k
    if( verAbs > 1 )
2017
10.6k
    {
2018
10.6k
      m_BinEncoder.encodeRemAbsEP(verAbs - 2, 1, 0, MV_BITS - 1);
2019
10.6k
    }
2020
10.7k
    m_BinEncoder.encodeBinEP( (verMvd < 0) );
2021
10.7k
  }
2022
29.1k
}
2023
2024
2025
//================================================================================
2026
//  clause 7.3.8.10
2027
//--------------------------------------------------------------------------------
2028
//    void  transform_unit      ( tu, cuCtx, chromaCbfs )
2029
//    void  cu_qp_delta         ( cu )
2030
//    void  cu_chroma_qp_offset ( cu )
2031
//================================================================================
2032
void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, Partitioner& partitioner, const int subTuCounter)
2033
208k
{
2034
208k
  const CodingUnit&       cu = *tu.cu;
2035
208k
  const UnitArea&         area = partitioner.currArea();
2036
208k
  const unsigned          trDepth = partitioner.currTrDepth;
2037
208k
  ChromaCbfs              chromaCbfs;
2038
208k
  CHECK(tu.depth != trDepth, " transform unit should be not be futher partitioned");
2039
2040
  // cbf_cb & cbf_cr
2041
208k
  if (area.chromaFormat != CHROMA_400)
2042
208k
  {
2043
208k
    const bool              chromaCbfISP = area.blocks[COMP_Cb].valid() && cu.ispMode;
2044
208k
    if (area.blocks[COMP_Cb].valid() && (!CU::isSepTree(cu) || partitioner.chType == CH_C) && (!cu.ispMode || chromaCbfISP))
2045
114k
    {
2046
114k
      unsigned cbfDepth = chromaCbfISP ? trDepth - 1 : trDepth;
2047
114k
      {
2048
114k
        chromaCbfs.Cb = TU::getCbfAtDepth(tu, COMP_Cb, trDepth);
2049
        //if (!(cu.sbtInfo && trDepth == 1))
2050
114k
        if (!(cu.sbtInfo && tu.noResidual))
2051
114k
          cbf_comp(*tu.cu, chromaCbfs.Cb, area.blocks[COMP_Cb], cbfDepth);
2052
114k
      }
2053
2054
114k
      {
2055
114k
        chromaCbfs.Cr = TU::getCbfAtDepth(tu, COMP_Cr, trDepth);
2056
        //if (!(cu.sbtInfo && trDepth == 1))
2057
114k
        if (!(cu.sbtInfo && tu.noResidual))
2058
114k
          cbf_comp(*tu.cu, chromaCbfs.Cr, area.blocks[COMP_Cr], cbfDepth, chromaCbfs.Cb);
2059
114k
      }
2060
114k
    }
2061
94.3k
    else if (CU::isSepTree(cu))
2062
94.3k
    {
2063
94.3k
      chromaCbfs = ChromaCbfs(false);
2064
94.3k
    }
2065
208k
  }
2066
0
  else if (CU::isSepTree(cu))
2067
0
  {
2068
0
    chromaCbfs = ChromaCbfs(false);
2069
0
  }
2070
2071
208k
  if (!isChroma(partitioner.chType))
2072
94.3k
  {
2073
94.3k
    if (!CU::isIntra(cu) && trDepth == 0 && !chromaCbfs.sigChroma(area.chromaFormat))
2074
161
    {
2075
161
      CHECK(!TU::getCbfAtDepth(tu, COMP_Y, trDepth), "Luma cbf must be true for inter units with no chroma coeffs");
2076
161
    }
2077
94.1k
    else if (cu.sbtInfo && tu.noResidual)
2078
0
    {
2079
0
      CHECK(TU::getCbfAtDepth(tu, COMP_Y, trDepth), "Luma cbf must be false for inter sbt no-residual tu");
2080
0
    }
2081
94.1k
    else if (cu.sbtInfo && !chromaCbfs.sigChroma(area.chromaFormat))
2082
0
    {
2083
0
      assert(!tu.noResidual);
2084
0
      CHECK(!TU::getCbfAtDepth(tu, COMP_Y, trDepth), "Luma cbf must be true for inter sbt residual tu");
2085
0
    }
2086
94.1k
    else
2087
94.1k
    {
2088
94.1k
      bool previousCbf = false;
2089
94.1k
      bool rootCbfSoFar = false;
2090
94.1k
      bool lumaCbfIsInferredACT = (cu.colorTransform && cu.predMode == MODE_INTRA && trDepth == 0 && !chromaCbfs.sigChroma(area.chromaFormat));
2091
94.1k
      CHECK(lumaCbfIsInferredACT && !TU::getCbfAtDepth(tu, COMP_Y, trDepth), "adaptive color transform cannot have all zero coefficients");
2092
94.1k
      bool lastCbfIsInferred    = lumaCbfIsInferredACT; // ISP and ACT are mutually exclusive
2093
94.1k
      if (cu.ispMode)
2094
144
      {
2095
144
        uint32_t nTus = cu.ispMode == HOR_INTRA_SUBPARTITIONS ? cu.lheight() >> Log2(tu.lheight()) : cu.lwidth() >> Log2(tu.lwidth());
2096
144
        if (subTuCounter == nTus - 1)
2097
36
        {
2098
36
          TransformUnit* tuPointer = cu.firstTU;
2099
144
          for (int tuIdx = 0; tuIdx < subTuCounter; tuIdx++)
2100
108
          {
2101
108
            rootCbfSoFar |= TU::getCbfAtDepth(*tuPointer, COMP_Y, trDepth);
2102
108
            tuPointer = tuPointer->next;
2103
108
          }
2104
36
          if (!rootCbfSoFar)
2105
0
          {
2106
0
            lastCbfIsInferred = true;
2107
0
          }
2108
36
        }
2109
144
        if (!lastCbfIsInferred)
2110
144
        {
2111
144
          previousCbf = TU::getPrevTuCbfAtDepth(tu, COMP_Y, partitioner.currTrDepth);
2112
144
        }
2113
144
      }
2114
94.1k
      if (!lastCbfIsInferred)
2115
94.1k
      {
2116
94.1k
        cbf_comp(*tu.cu, TU::getCbfAtDepth(tu, COMP_Y, trDepth), tu.Y(), trDepth, previousCbf, cu.ispMode);
2117
94.1k
      }
2118
94.1k
    }
2119
94.3k
  }
2120
208k
  bool        lumaOnly  = ( cu.chromaFormat == CHROMA_400 || !tu.blocks[COMP_Cb].valid() );
2121
208k
  bool        cbf[3]    = { TU::getCbf( tu, COMP_Y ), chromaCbfs.Cb, chromaCbfs.Cr };
2122
208k
  bool        cbfLuma   = ( cbf[ COMP_Y ] != 0 );
2123
208k
  bool        cbfChroma = false;
2124
2125
208k
  if( !lumaOnly )
2126
114k
  {
2127
114k
    if( tu.blocks[COMP_Cb].valid() )
2128
114k
    {
2129
114k
      cbf   [ COMP_Cb  ] = TU::getCbf( tu, COMP_Cb );
2130
114k
      cbf   [ COMP_Cr  ] = TU::getCbf( tu, COMP_Cr );
2131
114k
    }
2132
114k
    cbfChroma = ( cbf[ COMP_Cb ] || cbf[ COMP_Cr ] );
2133
114k
  }
2134
2135
208k
  if( ( cu.lwidth() > 64 || cu.lheight() > 64 || cbfLuma || cbfChroma ) &&
2136
34.6k
    (!CU::isSepTree(*tu.cu) || isLuma(tu.chType)) )
2137
5.98k
  {
2138
5.98k
    if( cu.cs->pps->useDQP && !cuCtx.isDQPCoded )
2139
3.00k
    {
2140
3.00k
      cu_qp_delta(cu, cuCtx.qp, cu.qp);
2141
3.00k
      cuCtx.qp = cu.qp;
2142
3.00k
      cuCtx.isDQPCoded = true;
2143
3.00k
    }
2144
5.98k
  }
2145
208k
  if (cu.cs->slice->chromaQpAdjEnabled && cbfChroma && !cuCtx.isChromaQpAdjCoded)
2146
0
  {
2147
0
    cu_chroma_qp_offset( cu );
2148
0
    cuCtx.isChromaQpAdjCoded = true;
2149
0
  }
2150
2151
208k
  if( !lumaOnly )
2152
114k
  {
2153
114k
    joint_cb_cr( tu, ( cbf[COMP_Cb] ? 2 : 0 ) + ( cbf[COMP_Cr] ? 1 : 0 ) );
2154
114k
  }
2155
2156
208k
  if( cbfLuma )
2157
5.98k
  {
2158
5.98k
    residual_coding( tu, COMP_Y, &cuCtx );
2159
5.98k
  }
2160
208k
  if( !lumaOnly )
2161
114k
  {
2162
342k
    for( ComponentID compID = COMP_Cb; compID <= COMP_Cr; compID = ComponentID( compID + 1 ) )
2163
228k
    {
2164
228k
      if( cbf[ compID ] )
2165
56.7k
      {
2166
56.7k
        residual_coding( tu, compID, &cuCtx );
2167
56.7k
      }
2168
228k
    }
2169
114k
  }
2170
208k
}
2171
2172
2173
void CABACWriter::cu_qp_delta( const CodingUnit& cu, int predQP, const int8_t qp )
2174
4.50k
{
2175
4.50k
  CHECK(!( predQP != std::numeric_limits<int>::max()), "Unspecified error");
2176
4.50k
  int       DQp         = qp - predQP;
2177
4.50k
  int       qpBdOffsetY = cu.cs->sps->qpBDOffset[ CH_L ];
2178
4.50k
  DQp                   = ( DQp + (MAX_QP + 1) + (MAX_QP + 1) / 2 + qpBdOffsetY + (qpBdOffsetY / 2)) % ((MAX_QP + 1) + qpBdOffsetY) - (MAX_QP + 1) / 2 - (qpBdOffsetY / 2);
2179
4.50k
  unsigned  absDQP      = unsigned( DQp < 0 ? -DQp : DQp );
2180
4.50k
  unsigned  unaryDQP    = std::min<unsigned>( absDQP, CU_DQP_TU_CMAX );
2181
2182
4.50k
  unary_max_symbol( unaryDQP, Ctx::DeltaQP(), Ctx::DeltaQP(1), CU_DQP_TU_CMAX );
2183
4.50k
  if( absDQP >= CU_DQP_TU_CMAX )
2184
0
  {
2185
0
    exp_golomb_eqprob( absDQP - CU_DQP_TU_CMAX, CU_DQP_EG_k );
2186
0
  }
2187
4.50k
  if( absDQP > 0 )
2188
0
  {
2189
0
    m_BinEncoder.encodeBinEP( DQp < 0 );
2190
0
  }
2191
2192
4.50k
  DTRACE_COND( ( isEncoding() ), g_trace_ctx, D_DQP, "x=%d, y=%d, d=%d, pred_qp=%d, DQp=%d, qp=%d\n", cu.blocks[cu.chType].lumaPos().x, cu.blocks[cu.chType].lumaPos().y, cu.qtDepth, predQP, DQp, qp );
2193
4.50k
}
2194
2195
2196
void CABACWriter::cu_chroma_qp_offset( const CodingUnit& cu )
2197
0
{
2198
  // cu_chroma_qp_offset_flag
2199
0
  unsigned qpAdj = cu.chromaQpAdj;
2200
0
  if( qpAdj == 0 )
2201
0
  {
2202
0
    m_BinEncoder.encodeBin( 0, Ctx::ChromaQpAdjFlag() );
2203
0
  }
2204
0
  else
2205
0
  {
2206
0
    m_BinEncoder.encodeBin( 1, Ctx::ChromaQpAdjFlag() );
2207
0
    int length = cu.cs->pps->chromaQpOffsetListLen;
2208
0
    if( length > 1 )
2209
0
    {
2210
0
      unary_max_symbol( qpAdj-1, Ctx::ChromaQpAdjIdc(), Ctx::ChromaQpAdjIdc(), length-1 );
2211
0
    }
2212
0
  }
2213
0
}
2214
2215
2216
//================================================================================
2217
//  clause 7.3.8.11
2218
//--------------------------------------------------------------------------------
2219
//    void        residual_coding         ( tu, compID )
2220
//    void        transform_skip_flag     ( tu, compID )
2221
//    void        last_sig_coeff          ( coeffCtx )
2222
//    void        residual_coding_subblock( coeffCtx )
2223
//================================================================================
2224
2225
void CABACWriter::joint_cb_cr( const TransformUnit& tu, const int cbfMask )
2226
1.75M
{
2227
1.75M
  if ( !tu.cu->slice->sps->jointCbCr )
2228
0
  {
2229
0
    return;
2230
0
  }
2231
2232
1.75M
  CHECK( tu.jointCbCr && tu.jointCbCr != cbfMask, "wrong value of jointCbCr (" << (int)tu.jointCbCr << " vs " << (int)cbfMask << ")" );
2233
1.75M
  if( ( CU::isIntra( *tu.cu ) && cbfMask ) || ( cbfMask == 3 ) )
2234
819k
  {
2235
819k
    m_BinEncoder.encodeBin( tu.jointCbCr ? 1 : 0, Ctx::JointCbCrFlag( cbfMask - 1 ) );
2236
819k
  }
2237
1.75M
}
2238
2239
2240
void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID, CUCtx* cuCtx )
2241
1.66M
{
2242
1.66M
  const CodingUnit& cu = *tu.cu;
2243
1.66M
  DTRACE( g_trace_ctx, D_SYNTAX, "residual_coding() etype=%d pos=(%d,%d) size=%dx%d predMode=%d\n", tu.blocks[compID].compID, tu.blocks[compID].x, tu.blocks[compID].y, tu.blocks[compID].width, tu.blocks[compID].height, cu.predMode );
2244
2245
1.66M
  if( compID == COMP_Cr && tu.jointCbCr == 3 )
2246
478k
  {
2247
478k
    return;
2248
478k
  }
2249
2250
1.19M
  ts_flag            ( tu, compID );
2251
2252
1.19M
  if( tu.mtsIdx[compID] == MTS_SKIP && !tu.cs->slice->tsResidualCodingDisabled )
2253
82.1k
  {
2254
82.1k
    residual_codingTS( tu, compID );
2255
82.1k
    return;
2256
82.1k
  }
2257
2258
  // determine sign hiding
2259
1.10M
  bool signHiding  = cu.cs->slice->signDataHidingEnabled;
2260
2261
  // init coeff coding context
2262
1.10M
  CoeffCodingContext  cctx    ( tu, compID, signHiding, false, m_tplBuf );
2263
1.10M
  const TCoeffSig*    coeff   = tu.getCoeffs( compID ).buf;
2264
2265
  // determine and set last coeff position and sig group flags
2266
1.10M
  int                      scanPosLast = tu.lastPos[compID];
2267
1.10M
  std::bitset<MLS_GRP_NUM> sigGroupFlags;
2268
2269
2.24M
  for( int subSetId = 0; subSetId <= ( scanPosLast >> cctx.log2CGSize() ); subSetId++ )
2270
1.13M
  {
2271
1.13M
    const int scanPosStart = subSetId << cctx.log2CGSize();
2272
1.13M
    const int scanPosEnd   = scanPosStart + ( 1 << cctx.log2CGSize() ) - 1;
2273
2274
10.3M
    for( int scanPos = scanPosEnd; scanPos >= scanPosStart; scanPos-- )
2275
10.3M
    {
2276
10.3M
      unsigned blkPos = cctx.blockPos( scanPos );
2277
2278
10.3M
      if( coeff[blkPos] )
2279
1.12M
      {
2280
1.12M
        sigGroupFlags.set( subSetId );
2281
1.12M
        break;
2282
1.12M
      }
2283
10.3M
    }
2284
1.13M
  }
2285
1.10M
  CHECK( scanPosLast < 0, "Coefficient coding called for empty TU" );
2286
1.10M
  cctx.setScanPosLast(scanPosLast);
2287
2288
1.10M
  if( cuCtx && tu.mtsIdx[compID] != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
2289
976k
  {
2290
976k
    const int maxLfnstPos = ((tu.blocks[compID].height == 4 && tu.blocks[compID].width == 4) || (tu.blocks[compID].height == 8 && tu.blocks[compID].width == 8)) ? 7 : 15;
2291
976k
    cuCtx->violatesLfnstConstrained[ toChannelType(compID) ] |= cctx.scanPosLast() > maxLfnstPos;
2292
976k
  }
2293
1.10M
  if( cuCtx && tu.mtsIdx[compID] != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
2294
976k
  {
2295
976k
    const int lfnstLastScanPosTh = isLuma( compID ) ? LFNST_LAST_SIG_LUMA : LFNST_LAST_SIG_CHROMA;
2296
976k
    cuCtx->lfnstLastScanPos |= cctx.scanPosLast() >= lfnstLastScanPosTh;
2297
976k
  }
2298
1.10M
  if (cuCtx && isLuma(compID) && tu.mtsIdx[compID] != MTS_SKIP)
2299
33.4k
  {
2300
33.4k
    cuCtx->mtsLastScanPos |= cctx.scanPosLast() >= 1;
2301
33.4k
  }
2302
  
2303
  // code last coeff position
2304
1.10M
  last_sig_coeff( cctx, tu, compID );
2305
2306
  // code subblocks
2307
1.10M
  const int stateTab  = ( tu.cs->slice->depQuantEnabled ? 32040 : 0 );
2308
1.10M
  int       state     = 0;
2309
2310
1.10M
  int ctxBinSampleRatio = MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT;
2311
1.10M
  cctx.remRegBins = (tu.getTbAreaAfterCoefZeroOut(compID) * ctxBinSampleRatio) >> 4;
2312
2313
1.10M
  const bool zeroOutCheck  = isLuma( compID ) && tu.cs->sps->MTS && tu.cu->sbtInfo != 0 && tu.blocks[compID].height <= 32 && tu.blocks[compID].width <= 32;
2314
1.10M
  const bool zeroOutWidth  = tu.blocks[compID].width;
2315
1.10M
  const bool zeroOutHeight = tu.blocks[compID].height;
2316
2317
2.24M
  for( int subSetId = ( cctx.scanPosLast() >> cctx.log2CGSize() ); subSetId >= 0; subSetId--)
2318
1.13M
  {
2319
1.13M
    cctx.initSubblock( subSetId, sigGroupFlags[subSetId] );
2320
2321
1.13M
    if( zeroOutCheck )
2322
0
    {
2323
0
      if( ( zeroOutHeight && cctx.cgPosY() >= ( 16 >> cctx.log2CGHeight() ) ) || ( zeroOutWidth  && cctx.cgPosX() >= ( 16 >> cctx.log2CGWidth() ) ) )
2324
0
      {
2325
0
        continue;
2326
0
      }
2327
0
    }
2328
2329
1.13M
    residual_coding_subblock( cctx, coeff, stateTab, state );
2330
1.13M
    if ( cuCtx && isLuma(compID) && cctx.isSigGroup() && ( cctx.cgPosY() > 3 || cctx.cgPosX() > 3 ) )
2331
0
    {
2332
0
      cuCtx->violatesMtsCoeffConstraint = true;
2333
0
    }
2334
1.13M
  }
2335
1.10M
}
2336
2337
2338
void CABACWriter::ts_flag( const TransformUnit& tu, ComponentID compID )
2339
1.19M
{
2340
1.19M
  int tsFlag = tu.mtsIdx[compID] == MTS_SKIP ? 1 : 0;
2341
1.19M
  int ctxIdx = isLuma(compID) ? 0 : 1;
2342
  
2343
1.19M
  if( TU::isTSAllowed ( tu, compID ) )
2344
811k
  {
2345
811k
    m_BinEncoder.encodeBin( tsFlag, Ctx::TransformSkipFlag(ctxIdx));
2346
811k
  }
2347
1.19M
  DTRACE( g_trace_ctx, D_SYNTAX, "ts_flag() etype=%d pos=(%d,%d) mtsIdx=%d\n", COMP_Y, tu.cu->lx(), tu.cu->ly(), tsFlag );
2348
1.19M
}
2349
2350
2351
void CABACWriter::mts_idx( const CodingUnit& cu, CUCtx* cuCtx )
2352
238k
{
2353
238k
  TransformUnit &tu = *cu.firstTU;
2354
238k
  int        mtsIdx = tu.mtsIdx[COMP_Y];
2355
  
2356
238k
  if( CU::isMTSAllowed( cu, COMP_Y ) && cuCtx && !cuCtx->violatesMtsCoeffConstraint &&
2357
0
      cuCtx->mtsLastScanPos && cu.lfnstIdx == 0 && mtsIdx != MTS_SKIP)
2358
0
  {
2359
0
    int symbol = mtsIdx != MTS_DCT2_DCT2 ? 1 : 0;
2360
0
    int ctxIdx = 0;
2361
    
2362
0
    m_BinEncoder.encodeBin( symbol, Ctx::MTSIdx(ctxIdx));
2363
    
2364
0
    if( symbol )
2365
0
    {
2366
0
      ctxIdx = 1;
2367
0
      for( int i = 0; i < 3; i++, ctxIdx++ )
2368
0
      {
2369
0
        symbol = mtsIdx > i + MTS_DST7_DST7 ? 1 : 0;
2370
0
        m_BinEncoder.encodeBin( symbol, Ctx::MTSIdx(ctxIdx));
2371
        
2372
0
        if( !symbol )
2373
0
        {
2374
0
          break;
2375
0
        }
2376
0
      }
2377
0
    }
2378
0
  }
2379
238k
  DTRACE( g_trace_ctx, D_SYNTAX, "mts_idx() etype=%d pos=(%d,%d) mtsIdx=%d\n", COMP_Y, tu.cu->lx(), tu.cu->ly(), mtsIdx);
2380
238k
}
2381
2382
2383
void CABACWriter::isp_mode( const CodingUnit& cu )
2384
1.16M
{
2385
1.16M
  if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.multiRefIdx || !cu.cs->sps->ISP || cu.bdpcmM[CH_L] || !CU::canUseISP( cu, getFirstComponentOfChannel( cu.chType ) )  || cu.colorTransform)
2386
213k
  {
2387
213k
    CHECK( cu.ispMode != NOT_INTRA_SUBPARTITIONS, "cu.ispMode != 0" );
2388
213k
    return;
2389
213k
  }
2390
953k
  if ( cu.ispMode == NOT_INTRA_SUBPARTITIONS )
2391
940k
  {
2392
940k
    m_BinEncoder.encodeBin( 0, Ctx::ISPMode( 0 ) );
2393
940k
  }
2394
12.6k
  else
2395
12.6k
  {
2396
12.6k
    m_BinEncoder.encodeBin( 1, Ctx::ISPMode( 0 ) );
2397
12.6k
    m_BinEncoder.encodeBin( cu.ispMode - 1, Ctx::ISPMode( 1 ) );
2398
12.6k
  }
2399
953k
  DTRACE( g_trace_ctx, D_SYNTAX, "intra_subPartitions() etype=%d pos=(%d,%d) ispIdx=%d\n", cu.chType, cu.blocks[cu.chType].x, cu.blocks[cu.chType].y, (int)cu.ispMode );
2400
953k
}
2401
2402
2403
void CABACWriter::residual_lfnst_mode( const CodingUnit& cu, CUCtx& cuCtx )
2404
348k
{
2405
348k
  int chIdx = CS::isDualITree( *cu.cs ) && cu.chType == CH_C ? 1 : 0;
2406
348k
  if( ( cu.ispMode && !CU::canUseLfnstWithISP( cu, cu.chType ) ) ||
2407
348k
      (cu.cs->sps->LFNST && CU::isIntra(cu) && cu.mipFlag && !allowLfnstWithMip(cu.lumaSize())) ||
2408
345k
    ( CU::isSepTree(cu) && cu.chType == CH_C && std::min( cu.blocks[ 1 ].width, cu.blocks[ 1 ].height ) < 4 )
2409
342k
    || ( cu.blocks[ chIdx ].lumaSize().width > cu.cs->sps->getMaxTbSize() || cu.blocks[ chIdx ].lumaSize().height > cu.cs->sps->getMaxTbSize() )
2410
348k
    )
2411
5.77k
  {
2412
5.77k
    return;
2413
5.77k
  }
2414
2415
342k
  if( cu.cs->sps->LFNST && CU::isIntra( cu )  )
2416
342k
  {
2417
342k
    const bool lumaFlag                   = CU::isSepTree(cu) ? (   isLuma( cu.chType ) ? true : false ) : true;
2418
342k
    const bool chromaFlag                 = CU::isSepTree(cu) ? ( isChroma( cu.chType ) ? true : false ) : true;
2419
342k
          bool nonZeroCoeffNonTsCorner8x8 = ( lumaFlag && cuCtx.violatesLfnstConstrained[CH_L] ) || (chromaFlag && cuCtx.violatesLfnstConstrained[CH_C] );
2420
2421
342k
    bool isTrSkip = false;
2422
2423
342k
    for( const auto& currTU : cTUTraverser( cu.firstTU, cu.lastTU->next ) )
2424
348k
    {
2425
348k
      const uint32_t numValidComp = getNumberValidComponents(cu.chromaFormat);
2426
1.39M
      for (uint32_t compID = COMP_Y; compID < numValidComp; compID++)
2427
1.04M
      {
2428
1.04M
        if (currTU.blocks[compID].valid() && TU::getCbf(currTU, (ComponentID)compID) && currTU.mtsIdx[compID] == MTS_SKIP)
2429
67
        {
2430
67
          isTrSkip = true;
2431
67
          break;
2432
67
        }
2433
1.04M
      }
2434
348k
    }
2435
2436
342k
    if( (!cuCtx.lfnstLastScanPos && !cu.ispMode) || nonZeroCoeffNonTsCorner8x8 || isTrSkip )
2437
322k
    {
2438
322k
      return;
2439
322k
    }
2440
342k
  }
2441
161
  else
2442
161
  {
2443
161
    return;
2444
161
  }
2445
  
2446
19.4k
  unsigned cctx = 0;
2447
19.4k
  if ( CU::isSepTree(cu) ) cctx++;
2448
2449
19.4k
  const uint32_t idxLFNST = cu.lfnstIdx;
2450
19.4k
  assert( idxLFNST < 3 );
2451
19.4k
  m_BinEncoder.encodeBin( idxLFNST ? 1 : 0, Ctx::LFNSTIdx( cctx ) );
2452
2453
19.4k
  if( idxLFNST )
2454
18.9k
  {
2455
18.9k
    m_BinEncoder.encodeBin( (idxLFNST - 1) ? 1 : 0, Ctx::LFNSTIdx(2));
2456
18.9k
  }
2457
2458
19.4k
  DTRACE( g_trace_ctx, D_SYNTAX, "residual_lfnst_mode() etype=%d pos=(%d,%d) mode=%d\n", COMP_Y, cu.lx(), cu.ly(), ( int ) cu.lfnstIdx );
2459
19.4k
}
2460
2461
2462
void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx, const TransformUnit& tu, ComponentID compID )
2463
1.10M
{
2464
1.10M
  unsigned blkPos = cctx.blockPos( cctx.scanPosLast() );
2465
1.10M
  unsigned posX, posY;
2466
1.10M
  {
2467
1.10M
    posY  = blkPos / cctx.width();
2468
1.10M
    posX  = blkPos - ( posY * cctx.width() );
2469
1.10M
  }
2470
2471
1.10M
  unsigned CtxLast;
2472
1.10M
  unsigned GroupIdxX = g_uiGroupIdx[ posX ];
2473
1.10M
  unsigned GroupIdxY = g_uiGroupIdx[ posY ];
2474
2475
1.10M
  unsigned maxLastPosX = cctx.maxLastPosX();
2476
1.10M
  unsigned maxLastPosY = cctx.maxLastPosY();
2477
2478
1.10M
  if( tu.cs->sps->MTS && tu.cu->sbtInfo != 0 && tu.blocks[ compID ].width <= 32 && tu.blocks[ compID ].height <= 32 && compID == COMP_Y )
2479
0
  {
2480
0
    maxLastPosX = ( tu.blocks[compID].width  == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosX;
2481
0
    maxLastPosY = ( tu.blocks[compID].height == 32 ) ? g_uiGroupIdx[ 15 ] : maxLastPosY;
2482
0
  }
2483
2484
2.58M
  for( CtxLast = 0; CtxLast < GroupIdxX; CtxLast++ )
2485
1.48M
  {
2486
1.48M
    m_BinEncoder.encodeBin( 1, cctx.lastXCtxId( CtxLast ) );
2487
1.48M
  }
2488
1.10M
  if( GroupIdxX < maxLastPosX )
2489
1.06M
  {
2490
1.06M
    m_BinEncoder.encodeBin( 0, cctx.lastXCtxId( CtxLast ) );
2491
1.06M
  }
2492
2.66M
  for( CtxLast = 0; CtxLast < GroupIdxY; CtxLast++ )
2493
1.55M
  {
2494
1.55M
    m_BinEncoder.encodeBin( 1, cctx.lastYCtxId( CtxLast ) );
2495
1.55M
  }
2496
1.10M
  if( GroupIdxY < maxLastPosY )
2497
1.05M
  {
2498
1.05M
    m_BinEncoder.encodeBin( 0, cctx.lastYCtxId( CtxLast ) );
2499
1.05M
  }
2500
1.10M
  if( GroupIdxX > 3 )
2501
3.28k
  {
2502
3.28k
    posX -= g_uiMinInGroup[ GroupIdxX ];
2503
9.49k
    for (int i = ( ( GroupIdxX - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
2504
6.20k
    {
2505
6.20k
      m_BinEncoder.encodeBinEP( ( posX >> i ) & 1 );
2506
6.20k
    }
2507
3.28k
  }
2508
1.10M
  if( GroupIdxY > 3 )
2509
2.55k
  {
2510
2.55k
    posY -= g_uiMinInGroup[ GroupIdxY ];
2511
6.95k
    for ( int i = ( ( GroupIdxY - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
2512
4.39k
    {
2513
4.39k
      m_BinEncoder.encodeBinEP( ( posY >> i ) & 1 );
2514
4.39k
    }
2515
2.55k
  }
2516
1.10M
}
2517
2518
2519
namespace
2520
{
2521
  // Estimates the bits of bins exactly like BitEstimator (same context updates, same bits per bin; keep the two in
2522
  // sync), but sums them in its own member. As a local object whose address never escapes, its sum can stay in a
2523
  // register, while BitEstimator's sum is read and written in memory for every bin.
2524
  class LocalBitEstimate
2525
  {
2526
  public:
2527
1.13M
    explicit LocalBitEstimate( CtxStore& ctx ) : m_ctx( ctx ) {}
2528
2529
30.6M
    void encodeBin     ( unsigned bin, unsigned ctxId )        { m_ctx[ctxId].estFracBitsUpdate( bin, m_fracBits ); }
2530
1.12M
    void encodeBinsEP  ( unsigned /*bins*/, unsigned numBins ) { m_fracBits += BinProbModelBase::estFracBitsEP( numBins ); }
2531
    void encodeRemAbsEP( unsigned bins, unsigned goRicePar, unsigned cutoff, int maxLog2TrDynamicRange )
2532
5.88M
    {
2533
5.88M
      m_fracBits += BinProbModelBase::estFracBitsEP( BitEstimatorBase::numRemAbsEPBins( bins, goRicePar, cutoff, maxLog2TrDynamicRange ) );
2534
5.88M
    }
2535
2536
1.13M
    uint64_t fracBits() const { return m_fracBits; }
2537
2538
  private:
2539
    CtxStore& m_ctx;
2540
    uint64_t  m_fracBits = 0;
2541
  };
2542
2543
// CABACWriter::residual_coding_subblock with the bins coded by binCoder: the writer's BinEncIf, or a LocalBitEstimate
2544
template<class BinCoder>
2545
void residual_coding_subblock_bins( CoeffCodingContext& cctx, const TCoeffSig* coeff, const int stateTransTable, int& state, BinCoder& binCoder )
2546
1.13M
{
2547
  //===== init =====
2548
1.13M
  const int   minSubPos   = cctx.minSubPos();
2549
1.13M
  const bool  isLast      = cctx.isLast();
2550
1.13M
  int         firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() );
2551
1.13M
  int         nextSigPos  = firstSigPos;
2552
2553
  //===== encode significant_coeffgroup_flag =====
2554
1.13M
  if( !isLast && cctx.isNotFirst() )
2555
25.4k
  {
2556
25.4k
    if( cctx.isSigGroup() )
2557
15.0k
    {
2558
15.0k
      binCoder.encodeBin( 1, cctx.sigGroupCtxId() );
2559
15.0k
    }
2560
10.3k
    else
2561
10.3k
    {
2562
10.3k
      binCoder.encodeBin( 0, cctx.sigGroupCtxId() );
2563
10.3k
      return;
2564
10.3k
    }
2565
25.4k
  }
2566
2567
  //===== encode absolute values =====
2568
1.12M
  const int inferSigPos   = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
2569
1.12M
  int       firstNZPos    = nextSigPos;
2570
1.12M
  int       lastNZPos     = -1;
2571
1.12M
  int       remAbsLevel   = -1;
2572
1.12M
  int       numNonZero    =  0;
2573
1.12M
  unsigned  signPattern   =  0;
2574
1.12M
  int       remRegBins    = cctx.remRegBins;
2575
1.12M
  int       firstPosMode2 = minSubPos - 1;
2576
2577
10.1M
  for( ; nextSigPos >= minSubPos && remRegBins >= 4; nextSigPos-- )
2578
9.00M
  {
2579
9.00M
    const int blkPos     = cctx.blockPos( nextSigPos );
2580
9.00M
    TCoeff    Coeff      = coeff[ blkPos ];
2581
9.00M
    unsigned  sigFlag    = ( Coeff != 0 );
2582
9.00M
    if( numNonZero || nextSigPos != inferSigPos )
2583
7.89M
    {
2584
7.89M
      const unsigned sigCtxId = cctx.sigCtxIdAbsWithAcc( nextSigPos, state );
2585
7.89M
      binCoder.encodeBin( sigFlag, sigCtxId );
2586
7.89M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2587
7.89M
      remRegBins--;
2588
7.89M
    }
2589
1.10M
    else if( nextSigPos != cctx.scanPosLast() )
2590
56
    {
2591
56
      cctx.sigCtxIdAbsWithAcc( nextSigPos, state ); // required for setting variables that are needed for gtx/par context selection
2592
56
    }
2593
2594
9.00M
    if( sigFlag )
2595
8.30M
    {
2596
8.30M
      uint8_t ctxOff = cctx.ctxOffsetAbs();
2597
8.30M
      numNonZero++;
2598
8.30M
      firstNZPos  = nextSigPos;
2599
8.30M
      lastNZPos   = std::max<int>( lastNZPos, nextSigPos );
2600
8.30M
      int absLevel= abs( Coeff );
2601
8.30M
      remAbsLevel = absLevel - 1;
2602
2603
8.30M
      if( nextSigPos != cctx.scanPosLast() ) signPattern <<= 1;
2604
8.30M
      if( Coeff < 0 )                        signPattern++;
2605
2606
8.30M
      unsigned gt1 = !!remAbsLevel;
2607
8.30M
      binCoder.encodeBin( gt1, cctx.greater1CtxIdAbs(ctxOff) );
2608
8.30M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1, cctx.greater1CtxIdAbs(ctxOff) );
2609
8.30M
      remRegBins--;
2610
2611
8.30M
      if( gt1 )
2612
7.22M
      {
2613
7.22M
        remAbsLevel  -= 1;
2614
7.22M
        binCoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2615
7.22M
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2616
7.22M
        remAbsLevel >>= 1;
2617
2618
7.22M
        remRegBins--;
2619
7.22M
        unsigned gt2 = !!remAbsLevel;
2620
7.22M
        binCoder.encodeBin(gt2, cctx.greater2CtxIdAbs(ctxOff));
2621
7.22M
        DTRACE(g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2, cctx.greater2CtxIdAbs(ctxOff));
2622
7.22M
        remRegBins--;
2623
7.22M
      }
2624
2625
8.30M
      cctx.absVal1stPass( nextSigPos, std::min<TCoeff>( 4 + ( absLevel & 1 ), absLevel ) );
2626
8.30M
    }
2627
2628
9.00M
    state = ( stateTransTable >> ((state<<2)+((Coeff&1)<<1)) ) & 3;
2629
9.00M
  }
2630
1.12M
  firstPosMode2 = nextSigPos;
2631
1.12M
  cctx.remRegBins = remRegBins;
2632
2633
2634
  //===== 2nd PASS: Go-rice codes =====
2635
10.1M
  for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- )
2636
9.00M
  {
2637
9.00M
    unsigned absLevel = abs( coeff[cctx.blockPos( scanPos )] );
2638
2639
9.00M
    if( absLevel >= 4 )
2640
5.76M
    {
2641
5.76M
      int      sumAll   = cctx.templateAbsSum( scanPos, coeff, 4 );
2642
5.76M
      unsigned ricePar  = g_auiGoRiceParsCoeff[sumAll];
2643
5.76M
      unsigned rem      = ( absLevel - 4 ) >> 1;
2644
5.76M
      binCoder.encodeRemAbsEP( rem, ricePar, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2645
5.76M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
2646
5.76M
    }
2647
9.00M
  }
2648
2649
  //===== coeff bypass ====
2650
1.24M
  for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
2651
118k
  {
2652
118k
    TCoeff    Coeff     = coeff[ cctx.blockPos( scanPos ) ];
2653
118k
    unsigned  absLevel  = abs( Coeff );
2654
118k
    int       sumAll    = cctx.templateAbsSum(scanPos, coeff, 0);
2655
118k
    int       rice      = g_auiGoRiceParsCoeff[sumAll];
2656
118k
    int       pos0      = g_auiGoRicePosCoeff0(state, rice);
2657
118k
    unsigned  rem       = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel );
2658
118k
    binCoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2659
118k
    DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
2660
118k
    state = ( stateTransTable >> ((state<<2)+((absLevel&1)<<1)) ) & 3;
2661
118k
    if( absLevel )
2662
117k
    {
2663
117k
      numNonZero++;
2664
117k
      firstNZPos = scanPos;
2665
117k
      lastNZPos   = std::max<int>( lastNZPos, scanPos );
2666
117k
      signPattern <<= 1;
2667
117k
      if( Coeff < 0 ) signPattern++;
2668
117k
    }
2669
118k
  }
2670
2671
  //===== encode sign's =====
2672
1.12M
  unsigned numSigns = numNonZero;
2673
1.12M
  if( cctx.hideSign( firstNZPos, lastNZPos ) )
2674
0
  {
2675
0
    numSigns    --;
2676
0
    signPattern >>= 1;
2677
0
  }
2678
1.12M
  binCoder.encodeBinsEP( signPattern, numSigns );
2679
1.12M
}
CABACWriter.cpp:void vvenc::(anonymous namespace)::residual_coding_subblock_bins<vvenc::BinEncIf>(vvenc::CoeffCodingContext&, short const*, int, int&, vvenc::BinEncIf&)
Line
Count
Source
2546
3.22k
{
2547
  //===== init =====
2548
3.22k
  const int   minSubPos   = cctx.minSubPos();
2549
3.22k
  const bool  isLast      = cctx.isLast();
2550
3.22k
  int         firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() );
2551
3.22k
  int         nextSigPos  = firstSigPos;
2552
2553
  //===== encode significant_coeffgroup_flag =====
2554
3.22k
  if( !isLast && cctx.isNotFirst() )
2555
0
  {
2556
0
    if( cctx.isSigGroup() )
2557
0
    {
2558
0
      binCoder.encodeBin( 1, cctx.sigGroupCtxId() );
2559
0
    }
2560
0
    else
2561
0
    {
2562
0
      binCoder.encodeBin( 0, cctx.sigGroupCtxId() );
2563
0
      return;
2564
0
    }
2565
0
  }
2566
2567
  //===== encode absolute values =====
2568
3.22k
  const int inferSigPos   = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
2569
3.22k
  int       firstNZPos    = nextSigPos;
2570
3.22k
  int       lastNZPos     = -1;
2571
3.22k
  int       remAbsLevel   = -1;
2572
3.22k
  int       numNonZero    =  0;
2573
3.22k
  unsigned  signPattern   =  0;
2574
3.22k
  int       remRegBins    = cctx.remRegBins;
2575
3.22k
  int       firstPosMode2 = minSubPos - 1;
2576
2577
6.45k
  for( ; nextSigPos >= minSubPos && remRegBins >= 4; nextSigPos-- )
2578
3.22k
  {
2579
3.22k
    const int blkPos     = cctx.blockPos( nextSigPos );
2580
3.22k
    TCoeff    Coeff      = coeff[ blkPos ];
2581
3.22k
    unsigned  sigFlag    = ( Coeff != 0 );
2582
3.22k
    if( numNonZero || nextSigPos != inferSigPos )
2583
0
    {
2584
0
      const unsigned sigCtxId = cctx.sigCtxIdAbsWithAcc( nextSigPos, state );
2585
0
      binCoder.encodeBin( sigFlag, sigCtxId );
2586
0
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2587
0
      remRegBins--;
2588
0
    }
2589
3.22k
    else if( nextSigPos != cctx.scanPosLast() )
2590
0
    {
2591
0
      cctx.sigCtxIdAbsWithAcc( nextSigPos, state ); // required for setting variables that are needed for gtx/par context selection
2592
0
    }
2593
2594
3.22k
    if( sigFlag )
2595
3.22k
    {
2596
3.22k
      uint8_t ctxOff = cctx.ctxOffsetAbs();
2597
3.22k
      numNonZero++;
2598
3.22k
      firstNZPos  = nextSigPos;
2599
3.22k
      lastNZPos   = std::max<int>( lastNZPos, nextSigPos );
2600
3.22k
      int absLevel= abs( Coeff );
2601
3.22k
      remAbsLevel = absLevel - 1;
2602
2603
3.22k
      if( nextSigPos != cctx.scanPosLast() ) signPattern <<= 1;
2604
3.22k
      if( Coeff < 0 )                        signPattern++;
2605
2606
3.22k
      unsigned gt1 = !!remAbsLevel;
2607
3.22k
      binCoder.encodeBin( gt1, cctx.greater1CtxIdAbs(ctxOff) );
2608
3.22k
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1, cctx.greater1CtxIdAbs(ctxOff) );
2609
3.22k
      remRegBins--;
2610
2611
3.22k
      if( gt1 )
2612
2.98k
      {
2613
2.98k
        remAbsLevel  -= 1;
2614
2.98k
        binCoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2615
2.98k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2616
2.98k
        remAbsLevel >>= 1;
2617
2618
2.98k
        remRegBins--;
2619
2.98k
        unsigned gt2 = !!remAbsLevel;
2620
2.98k
        binCoder.encodeBin(gt2, cctx.greater2CtxIdAbs(ctxOff));
2621
2.98k
        DTRACE(g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2, cctx.greater2CtxIdAbs(ctxOff));
2622
2.98k
        remRegBins--;
2623
2.98k
      }
2624
2625
3.22k
      cctx.absVal1stPass( nextSigPos, std::min<TCoeff>( 4 + ( absLevel & 1 ), absLevel ) );
2626
3.22k
    }
2627
2628
3.22k
    state = ( stateTransTable >> ((state<<2)+((Coeff&1)<<1)) ) & 3;
2629
3.22k
  }
2630
3.22k
  firstPosMode2 = nextSigPos;
2631
3.22k
  cctx.remRegBins = remRegBins;
2632
2633
2634
  //===== 2nd PASS: Go-rice codes =====
2635
6.45k
  for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- )
2636
3.22k
  {
2637
3.22k
    unsigned absLevel = abs( coeff[cctx.blockPos( scanPos )] );
2638
2639
3.22k
    if( absLevel >= 4 )
2640
2.98k
    {
2641
2.98k
      int      sumAll   = cctx.templateAbsSum( scanPos, coeff, 4 );
2642
2.98k
      unsigned ricePar  = g_auiGoRiceParsCoeff[sumAll];
2643
2.98k
      unsigned rem      = ( absLevel - 4 ) >> 1;
2644
2.98k
      binCoder.encodeRemAbsEP( rem, ricePar, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2645
2.98k
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
2646
2.98k
    }
2647
3.22k
  }
2648
2649
  //===== coeff bypass ====
2650
3.22k
  for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
2651
0
  {
2652
0
    TCoeff    Coeff     = coeff[ cctx.blockPos( scanPos ) ];
2653
0
    unsigned  absLevel  = abs( Coeff );
2654
0
    int       sumAll    = cctx.templateAbsSum(scanPos, coeff, 0);
2655
0
    int       rice      = g_auiGoRiceParsCoeff[sumAll];
2656
0
    int       pos0      = g_auiGoRicePosCoeff0(state, rice);
2657
0
    unsigned  rem       = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel );
2658
0
    binCoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2659
0
    DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
2660
0
    state = ( stateTransTable >> ((state<<2)+((absLevel&1)<<1)) ) & 3;
2661
0
    if( absLevel )
2662
0
    {
2663
0
      numNonZero++;
2664
0
      firstNZPos = scanPos;
2665
0
      lastNZPos   = std::max<int>( lastNZPos, scanPos );
2666
0
      signPattern <<= 1;
2667
0
      if( Coeff < 0 ) signPattern++;
2668
0
    }
2669
0
  }
2670
2671
  //===== encode sign's =====
2672
3.22k
  unsigned numSigns = numNonZero;
2673
3.22k
  if( cctx.hideSign( firstNZPos, lastNZPos ) )
2674
0
  {
2675
0
    numSigns    --;
2676
0
    signPattern >>= 1;
2677
0
  }
2678
3.22k
  binCoder.encodeBinsEP( signPattern, numSigns );
2679
3.22k
}
CABACWriter.cpp:void vvenc::(anonymous namespace)::residual_coding_subblock_bins<vvenc::(anonymous namespace)::LocalBitEstimate>(vvenc::CoeffCodingContext&, short const*, int, int&, vvenc::(anonymous namespace)::LocalBitEstimate&)
Line
Count
Source
2546
1.13M
{
2547
  //===== init =====
2548
1.13M
  const int   minSubPos   = cctx.minSubPos();
2549
1.13M
  const bool  isLast      = cctx.isLast();
2550
1.13M
  int         firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() );
2551
1.13M
  int         nextSigPos  = firstSigPos;
2552
2553
  //===== encode significant_coeffgroup_flag =====
2554
1.13M
  if( !isLast && cctx.isNotFirst() )
2555
25.4k
  {
2556
25.4k
    if( cctx.isSigGroup() )
2557
15.0k
    {
2558
15.0k
      binCoder.encodeBin( 1, cctx.sigGroupCtxId() );
2559
15.0k
    }
2560
10.3k
    else
2561
10.3k
    {
2562
10.3k
      binCoder.encodeBin( 0, cctx.sigGroupCtxId() );
2563
10.3k
      return;
2564
10.3k
    }
2565
25.4k
  }
2566
2567
  //===== encode absolute values =====
2568
1.12M
  const int inferSigPos   = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
2569
1.12M
  int       firstNZPos    = nextSigPos;
2570
1.12M
  int       lastNZPos     = -1;
2571
1.12M
  int       remAbsLevel   = -1;
2572
1.12M
  int       numNonZero    =  0;
2573
1.12M
  unsigned  signPattern   =  0;
2574
1.12M
  int       remRegBins    = cctx.remRegBins;
2575
1.12M
  int       firstPosMode2 = minSubPos - 1;
2576
2577
10.1M
  for( ; nextSigPos >= minSubPos && remRegBins >= 4; nextSigPos-- )
2578
9.00M
  {
2579
9.00M
    const int blkPos     = cctx.blockPos( nextSigPos );
2580
9.00M
    TCoeff    Coeff      = coeff[ blkPos ];
2581
9.00M
    unsigned  sigFlag    = ( Coeff != 0 );
2582
9.00M
    if( numNonZero || nextSigPos != inferSigPos )
2583
7.89M
    {
2584
7.89M
      const unsigned sigCtxId = cctx.sigCtxIdAbsWithAcc( nextSigPos, state );
2585
7.89M
      binCoder.encodeBin( sigFlag, sigCtxId );
2586
7.89M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2587
7.89M
      remRegBins--;
2588
7.89M
    }
2589
1.10M
    else if( nextSigPos != cctx.scanPosLast() )
2590
56
    {
2591
56
      cctx.sigCtxIdAbsWithAcc( nextSigPos, state ); // required for setting variables that are needed for gtx/par context selection
2592
56
    }
2593
2594
9.00M
    if( sigFlag )
2595
8.30M
    {
2596
8.30M
      uint8_t ctxOff = cctx.ctxOffsetAbs();
2597
8.30M
      numNonZero++;
2598
8.30M
      firstNZPos  = nextSigPos;
2599
8.30M
      lastNZPos   = std::max<int>( lastNZPos, nextSigPos );
2600
8.30M
      int absLevel= abs( Coeff );
2601
8.30M
      remAbsLevel = absLevel - 1;
2602
2603
8.30M
      if( nextSigPos != cctx.scanPosLast() ) signPattern <<= 1;
2604
8.30M
      if( Coeff < 0 )                        signPattern++;
2605
2606
8.30M
      unsigned gt1 = !!remAbsLevel;
2607
8.30M
      binCoder.encodeBin( gt1, cctx.greater1CtxIdAbs(ctxOff) );
2608
8.30M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1, cctx.greater1CtxIdAbs(ctxOff) );
2609
8.30M
      remRegBins--;
2610
2611
8.30M
      if( gt1 )
2612
7.21M
      {
2613
7.21M
        remAbsLevel  -= 1;
2614
7.21M
        binCoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2615
7.21M
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2616
7.21M
        remAbsLevel >>= 1;
2617
2618
7.21M
        remRegBins--;
2619
7.21M
        unsigned gt2 = !!remAbsLevel;
2620
7.21M
        binCoder.encodeBin(gt2, cctx.greater2CtxIdAbs(ctxOff));
2621
7.21M
        DTRACE(g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2, cctx.greater2CtxIdAbs(ctxOff));
2622
7.21M
        remRegBins--;
2623
7.21M
      }
2624
2625
8.30M
      cctx.absVal1stPass( nextSigPos, std::min<TCoeff>( 4 + ( absLevel & 1 ), absLevel ) );
2626
8.30M
    }
2627
2628
9.00M
    state = ( stateTransTable >> ((state<<2)+((Coeff&1)<<1)) ) & 3;
2629
9.00M
  }
2630
1.12M
  firstPosMode2 = nextSigPos;
2631
1.12M
  cctx.remRegBins = remRegBins;
2632
2633
2634
  //===== 2nd PASS: Go-rice codes =====
2635
10.1M
  for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- )
2636
9.00M
  {
2637
9.00M
    unsigned absLevel = abs( coeff[cctx.blockPos( scanPos )] );
2638
2639
9.00M
    if( absLevel >= 4 )
2640
5.76M
    {
2641
5.76M
      int      sumAll   = cctx.templateAbsSum( scanPos, coeff, 4 );
2642
5.76M
      unsigned ricePar  = g_auiGoRiceParsCoeff[sumAll];
2643
5.76M
      unsigned rem      = ( absLevel - 4 ) >> 1;
2644
5.76M
      binCoder.encodeRemAbsEP( rem, ricePar, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2645
5.76M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
2646
5.76M
    }
2647
9.00M
  }
2648
2649
  //===== coeff bypass ====
2650
1.24M
  for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
2651
118k
  {
2652
118k
    TCoeff    Coeff     = coeff[ cctx.blockPos( scanPos ) ];
2653
118k
    unsigned  absLevel  = abs( Coeff );
2654
118k
    int       sumAll    = cctx.templateAbsSum(scanPos, coeff, 0);
2655
118k
    int       rice      = g_auiGoRiceParsCoeff[sumAll];
2656
118k
    int       pos0      = g_auiGoRicePosCoeff0(state, rice);
2657
118k
    unsigned  rem       = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel );
2658
118k
    binCoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2659
118k
    DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
2660
118k
    state = ( stateTransTable >> ((state<<2)+((absLevel&1)<<1)) ) & 3;
2661
118k
    if( absLevel )
2662
117k
    {
2663
117k
      numNonZero++;
2664
117k
      firstNZPos = scanPos;
2665
117k
      lastNZPos   = std::max<int>( lastNZPos, scanPos );
2666
117k
      signPattern <<= 1;
2667
117k
      if( Coeff < 0 ) signPattern++;
2668
117k
    }
2669
118k
  }
2670
2671
  //===== encode sign's =====
2672
1.12M
  unsigned numSigns = numNonZero;
2673
1.12M
  if( cctx.hideSign( firstNZPos, lastNZPos ) )
2674
0
  {
2675
0
    numSigns    --;
2676
0
    signPattern >>= 1;
2677
0
  }
2678
1.12M
  binCoder.encodeBinsEP( signPattern, numSigns );
2679
1.12M
}
2680
}   // namespace
2681
2682
void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoeffSig* coeff, const int stateTransTable, int& state )
2683
1.13M
{
2684
1.13M
  if( m_BinEncoder.isEncoding() )
2685
3.22k
  {
2686
3.22k
    residual_coding_subblock_bins( cctx, coeff, stateTransTable, state, m_BinEncoder );
2687
3.22k
  }
2688
1.13M
  else
2689
1.13M
  {
2690
    // only estimating bits (m_BinEncoder is a BitEstimator): sum the subblock's bits locally, add them once
2691
1.13M
    LocalBitEstimate estimate( static_cast<CtxStore&>( m_BinEncoder.getCtx() ) );
2692
1.13M
    residual_coding_subblock_bins( cctx, coeff, stateTransTable, state, estimate );
2693
1.13M
    static_cast<BitEstimatorBase&>( m_BinEncoder ).addEstFracBits( estimate.fracBits() );
2694
1.13M
  }
2695
1.13M
}
2696
2697
2698
void CABACWriter::residual_codingTS( const TransformUnit& tu, ComponentID compID )
2699
82.1k
{
2700
82.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "residual_codingTS() etype=%d pos=(%d,%d) size=%dx%d\n", tu.blocks[compID].compID, tu.blocks[compID].x, tu.blocks[compID].y, tu.blocks[compID].width, tu.blocks[compID].height );
2701
2702
  // init coeff coding context
2703
82.1k
  CoeffCodingContext  cctx    ( tu, compID, false, tu.cu->bdpcmM[toChannelType(compID)] );
2704
82.1k
  const TCoeffSig*    coeff   = tu.getCoeffs( compID ).buf;
2705
82.1k
  int maxCtxBins = (cctx.maxNumCoeff() * 7) >> 2;
2706
82.1k
  cctx.remRegBins = maxCtxBins;
2707
2708
  // determine and set last coeff position and sig group flags
2709
82.1k
  std::bitset<MLS_GRP_NUM> sigGroupFlags;
2710
7.75M
  for( int scanPos = 0; scanPos < cctx.maxNumCoeff(); scanPos++)
2711
7.67M
  {
2712
7.67M
    unsigned blkPos = cctx.blockPos( scanPos );
2713
7.67M
    if( coeff[blkPos] )
2714
814k
    {
2715
814k
      sigGroupFlags.set( scanPos >> cctx.log2CGSize() );
2716
814k
    }
2717
7.67M
  }
2718
2719
  // code subblocks
2720
561k
  for( int subSetId = 0; subSetId <= ( cctx.maxNumCoeff() - 1 ) >> cctx.log2CGSize(); subSetId++ )
2721
479k
  {
2722
479k
    cctx.initSubblock         ( subSetId, sigGroupFlags[subSetId] );
2723
479k
    residual_coding_subblockTS( cctx, coeff );
2724
479k
  }
2725
82.1k
}
2726
2727
2728
void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TCoeffSig* coeff )
2729
479k
{
2730
  //===== init =====
2731
479k
  const int   minSubPos   = cctx.maxSubPos();
2732
479k
  int         firstSigPos = cctx.minSubPos();
2733
479k
  int         nextSigPos  = firstSigPos;
2734
2735
  //===== encode significant_coeffgroup_flag =====
2736
479k
  if( !cctx.isLastSubSet() || !cctx.only1stSigGroup() )
2737
467k
  {
2738
467k
    if( cctx.isSigGroup() )
2739
179k
    {
2740
179k
        m_BinEncoder.encodeBin( 1, cctx.sigGroupCtxId( true ) );
2741
179k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 1, cctx.sigGroupCtxId() );
2742
179k
    }
2743
287k
    else
2744
287k
    {
2745
287k
        m_BinEncoder.encodeBin( 0, cctx.sigGroupCtxId( true ) );
2746
287k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 0, cctx.sigGroupCtxId() );
2747
287k
      return;
2748
287k
    }
2749
467k
  }
2750
2751
  //===== encode absolute values =====
2752
192k
  const int inferSigPos   = minSubPos;
2753
192k
  int       remAbsLevel   = -1;
2754
192k
  int       numNonZero    =  0;
2755
2756
192k
  int rightPixel, belowPixel, modAbsCoeff;
2757
2758
192k
  int lastScanPosPass1 = -1;
2759
192k
  int lastScanPosPass2 = -1;
2760
3.01M
  for (; nextSigPos <= minSubPos && cctx.remRegBins >= 4; nextSigPos++)
2761
2.82M
  {
2762
2.82M
    TCoeff    Coeff      = coeff[ cctx.blockPos( nextSigPos ) ];
2763
2.82M
    unsigned  sigFlag    = ( Coeff != 0 );
2764
2.82M
    if( numNonZero || nextSigPos != inferSigPos )
2765
2.82M
    {
2766
2.82M
      const unsigned sigCtxId = cctx.sigCtxIdAbsTS( nextSigPos, coeff );
2767
2.82M
      m_BinEncoder.encodeBin( sigFlag, sigCtxId );
2768
2.82M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2769
2.82M
      cctx.remRegBins--;
2770
2.82M
    }
2771
2772
2.82M
    if( sigFlag )
2773
756k
    {
2774
      //===== encode sign's =====
2775
756k
      int sign = Coeff < 0;
2776
756k
      const unsigned signCtxId = cctx.signCtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm());
2777
756k
      m_BinEncoder.encodeBin(sign, signCtxId);
2778
756k
      cctx.remRegBins--;
2779
756k
      numNonZero++;
2780
756k
      cctx.neighTS(rightPixel, belowPixel, nextSigPos, coeff);
2781
756k
      modAbsCoeff = cctx.deriveModCoeff(rightPixel, belowPixel, abs(Coeff), cctx.bdpcm());
2782
756k
      remAbsLevel = modAbsCoeff - 1;
2783
2784
756k
      unsigned gt1 = !!remAbsLevel;
2785
756k
      const unsigned gt1CtxId = cctx.lrg1CtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm());
2786
756k
      m_BinEncoder.encodeBin(gt1, gt1CtxId);
2787
756k
      DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_gt1_flag() bin=%d ctx=%d\n", gt1, gt1CtxId);
2788
756k
      cctx.remRegBins--;
2789
2790
756k
      if( gt1 )
2791
744k
      {
2792
744k
        remAbsLevel  -= 1;
2793
744k
        m_BinEncoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbsTS() );
2794
744k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbsTS() );
2795
744k
        cctx.remRegBins--;
2796
744k
      }
2797
756k
    }
2798
2.82M
    lastScanPosPass1 = nextSigPos;
2799
2.82M
  }
2800
2801
192k
  int cutoffVal = 2;
2802
192k
  int numGtBins = 4;
2803
2804
2.77M
  for (int scanPos = firstSigPos; scanPos <= minSubPos && cctx.remRegBins >= 4; scanPos++)
2805
2.58M
  {
2806
2.58M
    unsigned absLevel;
2807
2.58M
    cctx.neighTS(rightPixel, belowPixel, scanPos, coeff);
2808
2.58M
    absLevel = cctx.deriveModCoeff(rightPixel, belowPixel, abs(coeff[cctx.blockPos(scanPos)]), cctx.bdpcm());
2809
2.58M
    cutoffVal = 2;
2810
12.9M
    for (int i = 0; i < numGtBins; i++)
2811
10.3M
    {
2812
10.3M
      if (absLevel >= cutoffVal)
2813
1.81M
      {
2814
1.81M
        unsigned gt2 = (absLevel >= (cutoffVal + 2));
2815
1.81M
        m_BinEncoder.encodeBin(gt2, cctx.greaterXCtxIdAbsTS(cutoffVal >> 1));
2816
1.81M
        DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_gt%d_flag() bin=%d ctx=%d sp=%d coeff=%d\n", i, gt2, cctx.greaterXCtxIdAbsTS(cutoffVal >> 1), scanPos, std::min<int>(absLevel, cutoffVal + 2));
2817
1.81M
        cctx.remRegBins--;
2818
1.81M
      }
2819
10.3M
      cutoffVal += 2;
2820
10.3M
    }
2821
2.58M
    lastScanPosPass2 = scanPos;
2822
2.58M
  }
2823
2824
  //===== coeff bypass ====
2825
3.27M
  for( int scanPos = firstSigPos; scanPos <= minSubPos; scanPos++ )
2826
3.07M
  {
2827
3.07M
    unsigned absLevel;
2828
3.07M
    cctx.neighTS(rightPixel, belowPixel, scanPos, coeff);
2829
3.07M
    cutoffVal = (scanPos <= lastScanPosPass2 ? 10 : (scanPos <= lastScanPosPass1 ? 2 : 0));
2830
3.07M
    absLevel = cctx.deriveModCoeff(rightPixel, belowPixel, abs(coeff[cctx.blockPos(scanPos)]), cctx.bdpcm()||!cutoffVal);
2831
3.07M
    if( absLevel >= cutoffVal )
2832
652k
    {
2833
      //int       rice = cctx.templateAbsSumTS( scanPos, coeff );
2834
652k
      int       rice = 1;
2835
652k
      unsigned  rem = scanPos <= lastScanPosPass1 ? (absLevel - cutoffVal) >> 1 : absLevel;
2836
652k
      m_BinEncoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2837
652k
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_rem_val() bin=%d ctx=%d sp=%d\n", rem, rice, scanPos );
2838
2839
652k
      if (absLevel && scanPos > lastScanPosPass1)
2840
58.3k
      {
2841
58.3k
        int sign = coeff[cctx.blockPos(scanPos)] < 0;
2842
58.3k
        m_BinEncoder.encodeBinEP(sign);
2843
58.3k
      }
2844
652k
    }
2845
3.07M
  }
2846
192k
}
2847
2848
2849
//================================================================================
2850
//  helper functions
2851
//--------------------------------------------------------------------------------
2852
//    void  unary_max_symbol  ( symbol, ctxId0, ctxIdN, maxSymbol )
2853
//    void  unary_max_eqprob  ( symbol,                 maxSymbol )
2854
//    void  exp_golomb_eqprob ( symbol, count )
2855
//================================================================================
2856
2857
void CABACWriter::unary_max_symbol( unsigned symbol, unsigned ctxId0, unsigned ctxIdN, unsigned maxSymbol )
2858
4.50k
{
2859
4.50k
  CHECK( symbol > maxSymbol, "symbol > maxSymbol" );
2860
4.50k
  const unsigned totalBinsToWrite = std::min( symbol + 1, maxSymbol );
2861
9.00k
  for( unsigned binsWritten = 0; binsWritten < totalBinsToWrite; ++binsWritten )
2862
4.50k
  {
2863
4.50k
    const unsigned nextBin = symbol > binsWritten;
2864
4.50k
    m_BinEncoder.encodeBin( nextBin, binsWritten == 0 ? ctxId0 : ctxIdN );
2865
4.50k
  }
2866
4.50k
}
2867
2868
2869
void CABACWriter::unary_max_eqprob( unsigned symbol, unsigned maxSymbol )
2870
298k
{
2871
298k
  if( maxSymbol == 0 )
2872
0
  {
2873
0
    return;
2874
0
  }
2875
298k
  bool     codeLast = ( maxSymbol > symbol );
2876
298k
  unsigned bins     = 0;
2877
298k
  unsigned numBins  = 0;
2878
299k
  while( symbol-- )
2879
392
  {
2880
392
    bins   <<= 1;
2881
392
    bins   ++;
2882
392
    numBins++;
2883
392
  }
2884
298k
  if( codeLast )
2885
298k
  {
2886
298k
    bins  <<= 1;
2887
298k
    numBins++;
2888
298k
  }
2889
298k
  CHECK(!( numBins <= 32 ), "Unspecified error");
2890
298k
  m_BinEncoder.encodeBinsEP( bins, numBins );
2891
298k
}
2892
2893
2894
void CABACWriter::exp_golomb_eqprob( unsigned symbol, unsigned count )
2895
0
{
2896
0
  unsigned bins    = 0;
2897
0
  unsigned numBins = 0;
2898
0
  while( symbol >= (unsigned)(1<<count) )
2899
0
  {
2900
0
    bins <<= 1;
2901
0
    bins++;
2902
0
    numBins++;
2903
0
    symbol -= 1 << count;
2904
0
    count++;
2905
0
  }
2906
0
  bins <<= 1;
2907
0
  numBins++;
2908
0
  bins = (bins << count) | symbol;
2909
0
  numBins += count;
2910
0
  CHECK(!( numBins <= 32 ), "Unspecified error");
2911
0
  m_BinEncoder.encodeBinsEP( bins, numBins );
2912
0
}
2913
2914
2915
void CABACWriter::codeAlfCtuEnabled( CodingStructure& cs, ChannelType channel, AlfParam* alfParam, const int numCtus )
2916
19.0k
{
2917
19.0k
  if( isLuma( channel ) )
2918
2.98k
  {
2919
2.98k
    if (alfParam->alfEnabled[COMP_Y])
2920
2.98k
      codeAlfCtuEnabled( cs, COMP_Y, alfParam, numCtus );
2921
2.98k
  }
2922
16.0k
  else
2923
16.0k
  {
2924
16.0k
    if (alfParam->alfEnabled[COMP_Cb])
2925
16.0k
      codeAlfCtuEnabled( cs, COMP_Cb, alfParam, numCtus );
2926
16.0k
    if (alfParam->alfEnabled[COMP_Cr])
2927
16.0k
      codeAlfCtuEnabled( cs, COMP_Cr, alfParam, numCtus );
2928
16.0k
  }
2929
19.0k
}
2930
2931
2932
void CABACWriter::codeAlfCtuEnabled( CodingStructure& cs, ComponentID compID, AlfParam* alfParam, const int numCtus )
2933
35.1k
{
2934
179k
  for( int ctuIdx = 0; ctuIdx < numCtus; ctuIdx++ )
2935
144k
  {
2936
144k
    codeAlfCtuEnabledFlag( cs, ctuIdx, compID );
2937
144k
  }
2938
35.1k
}
2939
2940
2941
void CABACWriter::codeAlfCtuEnabledFlag( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx)
2942
516k
{
2943
516k
  CHECKD( !cs.sps->alfEnabled, "ALF is disabled in SPS" ); 
2944
2945
516k
  const PreCalcValues& pcv = *cs.pcv;
2946
516k
  int                 frame_width_in_ctus = pcv.widthInCtus;
2947
516k
  int                 ry = ctuRsAddr / frame_width_in_ctus;
2948
516k
  int                 rx = ctuRsAddr - ry * frame_width_in_ctus;
2949
516k
  const Position      pos( rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize );
2950
516k
  const uint32_t      curSliceIdx = cs.slice->independentSliceIdx;
2951
516k
  const uint32_t      curTileIdx  = cs.pps->getTileIdx( pos );
2952
516k
  bool                leftAvail   = cs.getCURestricted( pos.offset( -(int)pcv.maxCUSize, 0 ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2953
516k
  bool                aboveAvail  = cs.getCURestricted( pos.offset( 0, -(int)pcv.maxCUSize ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2954
2955
516k
  int leftCTUAddr = leftAvail ? ctuRsAddr - 1 : -1;
2956
516k
  int aboveCTUAddr = aboveAvail ? ctuRsAddr - frame_width_in_ctus : -1;
2957
2958
516k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compIdx ].data();
2959
516k
  int ctx = 0;
2960
516k
  ctx += leftCTUAddr > -1 ? ( ctbAlfFlag[leftCTUAddr] ? 1 : 0 ) : 0;
2961
516k
  ctx += aboveCTUAddr > -1 ? ( ctbAlfFlag[aboveCTUAddr] ? 1 : 0 ) : 0;
2962
516k
  m_BinEncoder.encodeBin( ctbAlfFlag[ctuRsAddr], Ctx::ctbAlfFlag( compIdx * 3 + ctx ) );
2963
516k
}
2964
2965
2966
void CABACWriter::codeCcAlfFilterControlIdc(uint8_t idcVal, CodingStructure &cs, const ComponentID compID,
2967
                                            const int curIdx, const uint8_t *filterControlIdc, Position lumaPos,
2968
                                            const int filterCount)
2969
0
{
2970
0
  CHECK(idcVal > filterCount, "Filter index is too large");
2971
2972
0
  const uint32_t curSliceIdx    = cs.slice->independentSliceIdx;
2973
0
  const uint32_t curTileIdx     = cs.pps->getTileIdx( lumaPos );
2974
0
  Position       leftLumaPos    = lumaPos.offset(-(int)cs.pcv->maxCUSize, 0);
2975
0
  Position       aboveLumaPos   = lumaPos.offset(0, -(int)cs.pcv->maxCUSize);
2976
0
  bool           leftAvail      = cs.getCURestricted( leftLumaPos,  lumaPos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2977
0
  bool           aboveAvail     = cs.getCURestricted( aboveLumaPos, lumaPos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2978
0
  int            ctxt           = 0;
2979
2980
0
  if (leftAvail)
2981
0
  {
2982
0
    ctxt += ( filterControlIdc[curIdx - 1]) ? 1 : 0;
2983
0
  }
2984
0
  if (aboveAvail)
2985
0
  {
2986
0
    ctxt += (filterControlIdc[curIdx - cs.pcv->widthInCtus]) ? 1 : 0;
2987
0
  }
2988
0
  ctxt += ( compID == COMP_Cr ) ? 3 : 0;
2989
2990
0
  m_BinEncoder.encodeBin( ( idcVal == 0 ) ? 0 : 1, Ctx::CcAlfFilterControlFlag( ctxt ) ); // ON/OFF flag is context coded
2991
0
  if ( idcVal > 0 )
2992
0
  {
2993
0
    int val = (idcVal - 1);
2994
0
    while ( val )
2995
0
    {
2996
0
      m_BinEncoder.encodeBinEP( 1 );
2997
0
      val--;
2998
0
    }
2999
0
    if ( idcVal < filterCount )
3000
0
    {
3001
0
      m_BinEncoder.encodeBinEP( 0 );
3002
0
    }
3003
0
  }
3004
0
  DTRACE( g_trace_ctx, D_SYNTAX, "ccAlfFilterControlIdc() compID=%d pos=(%d,%d) ctxt=%d, filterCount=%d, idcVal=%d\n", compID, lumaPos.x, lumaPos.y, ctxt, filterCount, idcVal );
3005
0
}
3006
3007
3008
void CABACWriter::mip_flag( const CodingUnit& cu )
3009
1.52M
{
3010
1.52M
  if( !cu.Y().valid() )
3011
0
  {
3012
0
    return;
3013
0
  }
3014
1.52M
  if( !cu.cs->sps->MIP )
3015
0
  {
3016
0
    return;
3017
0
  }
3018
3019
1.52M
  unsigned ctxId = DeriveCtx::CtxMipFlag( cu );
3020
1.52M
  m_BinEncoder.encodeBin( cu.mipFlag, Ctx::MipFlag( ctxId ) );
3021
1.52M
  DTRACE( g_trace_ctx, D_SYNTAX, "mip_flag() pos=(%d,%d) mode=%d\n", cu.lumaPos().x, cu.lumaPos().y, cu.mipFlag ? 1 : 0 );
3022
1.52M
}
3023
3024
3025
void CABACWriter::mip_pred_modes( const CodingUnit& cu )
3026
1.73k
{
3027
1.73k
  if( !cu.Y().valid() )
3028
0
  {
3029
0
    return;
3030
0
  }
3031
3032
1.73k
  mip_pred_mode( cu );
3033
1.73k
}
3034
3035
3036
void CABACWriter::mip_pred_mode( const CodingUnit& cu )
3037
359k
{
3038
359k
  m_BinEncoder.encodeBinEP( (cu.mipTransposedFlag ? 1 : 0) );
3039
3040
359k
  const int numModes = getNumModesMip( cu.Y() );
3041
359k
  CHECKD( cu.intraDir[CH_L] < 0 || cu.intraDir[CH_L] >= numModes, "Invalid MIP mode" );
3042
359k
  xWriteTruncBinCode( cu.intraDir[CH_L], numModes );
3043
3044
359k
  DTRACE( g_trace_ctx, D_SYNTAX, "mip_pred_mode() pos=(%d,%d) mode=%d transposed=%d\n", cu.lumaPos().x, cu.lumaPos().y, cu.intraDir[CH_L], cu.mipTransposedFlag ? 1 : 0 );
3045
359k
}
3046
3047
3048
void CABACWriter::codeAlfCtuFilterIndex(CodingStructure& cs, uint32_t ctuRsAddr)
3049
99.5k
{
3050
99.5k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ COMP_Y ].data();
3051
99.5k
  if (!ctbAlfFlag[ctuRsAddr])
3052
0
  {
3053
0
    return;
3054
0
  }
3055
3056
99.5k
  const short* alfCtbFilterIndex = cs.slice->pic->m_alfCtbFilterIndex.data();
3057
99.5k
  const unsigned filterSetIdx = alfCtbFilterIndex[ctuRsAddr];
3058
99.5k
  unsigned numAps = cs.slice->numAps;
3059
99.5k
  unsigned numAvailableFiltSets = numAps + NUM_FIXED_FILTER_SETS;
3060
99.5k
  if (numAvailableFiltSets > NUM_FIXED_FILTER_SETS)
3061
19.9k
  {
3062
19.9k
    int useTemporalFilt = (filterSetIdx >= NUM_FIXED_FILTER_SETS) ? 1 : 0;
3063
19.9k
    m_BinEncoder.encodeBin(useTemporalFilt, Ctx::AlfUseTemporalFilt());
3064
19.9k
    if (useTemporalFilt)
3065
19.9k
    {
3066
19.9k
      CHECK((filterSetIdx - NUM_FIXED_FILTER_SETS) >= (numAvailableFiltSets - NUM_FIXED_FILTER_SETS), "temporal non-latest set");
3067
19.9k
      if (numAps > 1)
3068
0
      {
3069
0
        xWriteTruncBinCode(filterSetIdx - NUM_FIXED_FILTER_SETS, numAvailableFiltSets - NUM_FIXED_FILTER_SETS);
3070
0
      }
3071
19.9k
    }
3072
0
    else
3073
0
    {
3074
0
      CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set larger than temporal");
3075
0
      xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS);
3076
0
    }
3077
19.9k
  }
3078
79.6k
  else
3079
79.6k
  {
3080
79.6k
    CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set numavail < num_fixed");
3081
79.6k
    xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS);
3082
79.6k
  }
3083
99.5k
}
3084
3085
3086
void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ChannelType channel, AlfParam* alfParam, const int numCtus )
3087
19.0k
{
3088
19.0k
  if( isChroma( channel ) )
3089
16.0k
  {
3090
16.0k
    if (alfParam->alfEnabled[COMP_Cb])
3091
16.0k
      codeAlfCtuAlternatives( cs, COMP_Cb, alfParam, numCtus );
3092
16.0k
    if (alfParam->alfEnabled[COMP_Cr])
3093
16.0k
      codeAlfCtuAlternatives( cs, COMP_Cr, alfParam, numCtus );
3094
16.0k
  }
3095
19.0k
}
3096
3097
3098
void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ComponentID compID, AlfParam* alfParam, const int numCtus)
3099
32.1k
{
3100
32.1k
  if( compID == COMP_Y )
3101
0
    return;
3102
32.1k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compID ].data();
3103
3104
166k
  for( int ctuIdx = 0; ctuIdx < numCtus; ctuIdx++ )
3105
134k
  {
3106
134k
    if( ctbAlfFlag[ctuIdx] )
3107
134k
    {
3108
134k
      codeAlfCtuAlternative( cs, ctuIdx, compID, alfParam );
3109
134k
    }
3110
134k
  }
3111
32.1k
}
3112
3113
3114
void CABACWriter::codeAlfCtuAlternative( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx, const AlfParam* alfParam)
3115
691k
{
3116
691k
  if( compIdx == COMP_Y )
3117
0
    return;
3118
3119
691k
  {
3120
691k
    const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compIdx ].data();
3121
3122
691k
    if( ctbAlfFlag[ctuRsAddr] )
3123
691k
    {
3124
691k
      const int numAlts = alfParam->numAlternativesChroma;
3125
691k
      const uint8_t* ctbAlfAlternative = cs.slice->pic->m_alfCtuAlternative[compIdx].data();
3126
691k
      unsigned numOnes = ctbAlfAlternative[ctuRsAddr];
3127
691k
      assert( ctbAlfAlternative[ctuRsAddr] < numAlts );
3128
1.99M
      for( int i = 0; i < numOnes; ++i )
3129
1.30M
        m_BinEncoder.encodeBin( 1, Ctx::ctbAlfAlternative( compIdx-1 ) );
3130
691k
      if( numOnes < numAlts-1 )
3131
524k
        m_BinEncoder.encodeBin( 0, Ctx::ctbAlfAlternative( compIdx-1 ) );
3132
691k
    }
3133
691k
  }
3134
691k
}
3135
3136
} // namespace vvenc
3137
3138
//! \}
3139