Coverage Report

Created: 2026-05-30 06:10

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
12.9k
{
65
12.9k
  int       qp                = slice.sliceQp;
66
12.9k
  SliceType sliceType         = slice.sliceType;
67
12.9k
  SliceType encCABACTableIdx  = slice.encCABACTableIdx;
68
12.9k
  if( !slice.isIntra() && (encCABACTableIdx==VVENC_B_SLICE || encCABACTableIdx==VVENC_P_SLICE) && slice.pps->cabacInitPresent )
69
0
  {
70
0
    sliceType = encCABACTableIdx;
71
0
  }
72
12.9k
  m_BinEncoder.reset( qp, (int)sliceType );
73
12.9k
}
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.29k
{
145
1.29k
  m_BinEncoder.encodeBinTrm ( 1 );
146
1.29k
  m_BinEncoder.finish       ();
147
1.29k
}
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
8.10k
{
158
8.10k
  CUCtx cuCtx( qps[CH_L] );
159
8.10k
  Partitioner *partitioner = &m_partitioner[0];
160
161
8.10k
  partitioner->initCtu( area, CH_L, *cs.slice );
162
163
8.10k
  if( !skipSao )
164
4.05k
  {
165
4.05k
    sao( *cs.slice, ctuRsAddr );
166
4.05k
  }
167
168
8.10k
  if (!skipAlf)
169
4.05k
  {
170
16.2k
    for (int compIdx = 0; compIdx < MAX_NUM_COMP; compIdx++)
171
12.1k
    {
172
12.1k
      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
12.1k
    }
185
4.05k
  }
186
187
8.10k
  if ( !skipAlf )
188
4.05k
  {
189
12.1k
    for ( int compIdx = 1; compIdx < getNumberValidComponents( cs.pcv->chrFormat ); compIdx++ )
190
8.10k
    {
191
8.10k
      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
8.10k
    }
203
4.05k
  }
204
205
8.10k
  if ( CS::isDualITree(cs) && cs.pcv->chrFormat != CHROMA_400 && cs.pcv->maxCUSize > 64 )
206
8.10k
  {
207
8.10k
    CUCtx chromaCuCtx(qps[CH_C]);
208
8.10k
    Partitioner *chromaPartitioner = &m_partitioner[1];
209
8.10k
    chromaPartitioner->initCtu(area, CH_C, *cs.slice);
210
8.10k
    coding_tree(cs, *partitioner, cuCtx, chromaPartitioner, &chromaCuCtx);
211
8.10k
    qps[CH_L] = cuCtx.qp;
212
8.10k
    qps[CH_C] = chromaCuCtx.qp;
213
8.10k
  }
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
8.10k
}
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.05k
{
239
4.05k
  const SPS& sps = *slice.sps;
240
4.05k
  if( !sps.saoEnabled )
241
0
  {
242
0
    return;
243
0
  }
244
245
4.05k
  CodingStructure&     cs                     = *slice.pic->cs;
246
4.05k
  const PreCalcValues& pcv                    = *cs.pcv;
247
4.05k
  const SAOBlkParam&  sao_ctu_pars            = cs.picture->getSAO()[ctuRsAddr];
248
4.05k
  bool                slice_sao_luma_flag     = ( slice.saoEnabled[ CH_L ] );
249
4.05k
  bool                slice_sao_chroma_flag   = ( slice.saoEnabled[ CH_C ] && sps.chromaFormatIdc != CHROMA_400 );
250
4.05k
  if( !slice_sao_luma_flag && !slice_sao_chroma_flag )
251
0
  {
252
0
    return;
253
0
  }
254
255
4.05k
  bool                sliceEnabled[3]         = { slice_sao_luma_flag, slice_sao_chroma_flag, slice_sao_chroma_flag };
256
4.05k
  int                 frame_width_in_ctus     = pcv.widthInCtus;
257
4.05k
  int                 ry                      = ctuRsAddr      / frame_width_in_ctus;
258
4.05k
  int                 rx                      = ctuRsAddr - ry * frame_width_in_ctus;
259
4.05k
  const Position      pos                     ( rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize );
260
4.05k
  const unsigned      curSliceIdx             = slice.independentSliceIdx;
261
4.05k
  const unsigned      curTileIdx              = cs.pps->getTileIdx( pos );
262
4.05k
  bool                leftMergeAvail          = cs.getCURestricted( pos.offset( -(int)pcv.maxCUSize, 0  ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
263
4.05k
  bool                aboveMergeAvail         = cs.getCURestricted( pos.offset( 0, -(int)pcv.maxCUSize ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
264
4.05k
  sao_block_pars( sao_ctu_pars, sps.bitDepths, sliceEnabled, leftMergeAvail, aboveMergeAvail, false );
265
4.05k
}
266
267
268
void CABACWriter::sao_block_pars( const SAOBlkParam& saoPars, const BitDepths& bitDepths, const bool* sliceEnabled, bool leftMergeAvail, bool aboveMergeAvail, bool onlyEstMergeInfo )
269
15.7k
{
270
15.7k
  bool isLeftMerge  = false;
271
15.7k
  bool isAboveMerge = false;
272
15.7k
  if( leftMergeAvail )
273
7.99k
  {
274
    // sao_merge_left_flag
275
7.99k
    isLeftMerge   = ( saoPars[COMP_Y].modeIdc == SAO_MODE_MERGE && saoPars[COMP_Y].typeIdc == SAO_MERGE_LEFT );
276
7.99k
    m_BinEncoder.encodeBin( (isLeftMerge), Ctx::SaoMergeFlag() );
277
7.99k
  }
278
15.7k
  if( aboveMergeAvail && !isLeftMerge )
279
6.41k
  {
280
    // sao_merge_above_flag
281
6.41k
    isAboveMerge  = ( saoPars[COMP_Y].modeIdc == SAO_MODE_MERGE && saoPars[COMP_Y].typeIdc == SAO_MERGE_ABOVE );
282
6.41k
    m_BinEncoder.encodeBin( (isAboveMerge), Ctx::SaoMergeFlag() );
283
6.41k
  }
284
15.7k
  if( onlyEstMergeInfo )
285
4.05k
  {
286
4.05k
    return; //only for RDO
287
4.05k
  }
288
11.7k
  if( !isLeftMerge && !isAboveMerge )
289
5.35k
  {
290
    // explicit parameters
291
21.4k
    for( int compIdx=0; compIdx < MAX_NUM_COMP; compIdx++ )
292
16.0k
    {
293
16.0k
      sao_offset_pars( saoPars[compIdx], ComponentID(compIdx), sliceEnabled[compIdx], bitDepths[ toChannelType(ComponentID(compIdx)) ] );
294
16.0k
    }
295
5.35k
  }
296
11.7k
}
297
298
299
void CABACWriter::sao_offset_pars( const SAOOffset& ctbPars, ComponentID compID, bool sliceEnabled, int bitDepth )
300
88.9k
{
301
88.9k
  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
88.9k
  const bool isFirstCompOfChType = ( getFirstComponentOfChannel( toChannelType(compID) ) == compID );
307
308
88.9k
  if( isFirstCompOfChType )
309
59.3k
  {
310
    // sao_type_idx_luma / sao_type_idx_chroma
311
59.3k
    if( ctbPars.modeIdc == SAO_MODE_OFF )
312
18.7k
    {
313
18.7k
      m_BinEncoder.encodeBin  ( 0, Ctx::SaoTypeIdx() );
314
18.7k
    }
315
40.5k
    else if( ctbPars.typeIdc == SAO_TYPE_BO )
316
8.14k
    {
317
8.14k
      m_BinEncoder.encodeBin  ( 1, Ctx::SaoTypeIdx() );
318
8.14k
      m_BinEncoder.encodeBinEP( 0 );
319
8.14k
    }
320
32.4k
    else
321
32.4k
    {
322
32.4k
      CHECK(!( ctbPars.typeIdc < SAO_TYPE_START_BO ), "Unspecified error");
323
32.4k
      m_BinEncoder.encodeBin  ( 1, Ctx::SaoTypeIdx() );
324
32.4k
      m_BinEncoder.encodeBinEP( 1 );
325
32.4k
    }
326
59.3k
  }
327
328
88.9k
  if( ctbPars.modeIdc == SAO_MODE_NEW )
329
60.8k
  {
330
60.8k
    const int maxOffsetQVal = SampleAdaptiveOffset::getMaxOffsetQVal( bitDepth );
331
60.8k
    int       numClasses    = ( ctbPars.typeIdc == SAO_TYPE_BO ? 4 : NUM_SAO_EO_CLASSES );
332
60.8k
    int       k             = 0;
333
60.8k
    int       offset[4];
334
352k
    for( int i = 0; i < numClasses; i++ )
335
291k
    {
336
291k
      if( ctbPars.typeIdc != SAO_TYPE_BO && i == SAO_CLASS_EO_PLAIN )
337
48.6k
      {
338
48.6k
        continue;
339
48.6k
      }
340
243k
      int classIdx = ( ctbPars.typeIdc == SAO_TYPE_BO ? ( ctbPars.typeAuxInfo + i ) % NUM_SAO_BO_CLASSES : i );
341
243k
      offset[k++]  = ctbPars.offset[classIdx];
342
243k
    }
343
344
    // sao_offset_abs
345
304k
    for( int i = 0; i < 4; i++ )
346
243k
    {
347
243k
      unsigned absOffset = ( offset[i] < 0 ? -offset[i] : offset[i] );
348
243k
      unary_max_eqprob( absOffset, maxOffsetQVal );
349
243k
    }
350
351
    // band offset mode
352
60.8k
    if( ctbPars.typeIdc == SAO_TYPE_BO )
353
12.2k
    {
354
      // sao_offset_sign
355
61.0k
      for( int i = 0; i < 4; i++ )
356
48.8k
      {
357
48.8k
        if( offset[i] )
358
322
        {
359
322
          m_BinEncoder.encodeBinEP( (offset[i] < 0) );
360
322
        }
361
48.8k
      }
362
      // sao_band_position
363
12.2k
      m_BinEncoder.encodeBinsEP( ctbPars.typeAuxInfo, NUM_SAO_BO_CLASSES_LOG2 );
364
12.2k
    }
365
    // edge offset mode
366
48.6k
    else
367
48.6k
    {
368
48.6k
      if( isFirstCompOfChType )
369
32.4k
      {
370
        // sao_eo_class_luma / sao_eo_class_chroma
371
32.4k
        CHECK( ctbPars.typeIdc - SAO_TYPE_START_EO < 0, "sao edge offset class is outside valid range" );
372
32.4k
        m_BinEncoder.encodeBinsEP( ctbPars.typeIdc - SAO_TYPE_START_EO, NUM_SAO_EO_TYPES_LOG2 );
373
32.4k
      }
374
48.6k
    }
375
60.8k
  }
376
88.9k
}
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
175k
{
389
175k
  const PPS      &pps         = *cs.pps;
390
175k
  const UnitArea& currArea    = partitioner.currArea();
391
175k
  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
175k
  if( pps.useDQP && partitioner.currQgEnable() && !isChroma( partitioner.chType ) )
396
15.5k
  {
397
15.5k
    cuCtx.qgStart    = true;
398
15.5k
    cuCtx.isDQPCoded          = false;
399
15.5k
  }
400
175k
  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
175k
  if (CS::isDualITree(cs) && pPartitionerChroma != nullptr)
406
8.10k
  {
407
8.10k
    if (pps.useDQP && pPartitionerChroma->currQgEnable())
408
8.10k
    {
409
8.10k
      pCuCtxChroma->qgStart    = true;
410
8.10k
      pCuCtxChroma->isDQPCoded = false;
411
8.10k
    }
412
8.10k
    if (cs.slice->chromaQpAdjEnabled && pPartitionerChroma->currQgChromaEnable())
413
0
    {
414
0
      pCuCtxChroma->isChromaQpAdjCoded = false;
415
0
    }
416
8.10k
  }
417
418
175k
  determineNeighborCus( cs, partitioner.currArea(), partitioner.chType, partitioner.treeType );
419
420
175k
  const PartSplit splitMode = CU::getSplitAtDepth( cu, partitioner.currDepth );
421
422
175k
  split_cu_mode( splitMode, cs, partitioner );
423
424
175k
  CHECK( !partitioner.canSplit( splitMode, cs ), "The chosen split mode is invalid!" );
425
426
175k
  if( splitMode != CU_DONT_SPLIT )
427
90.1k
  {
428
90.1k
    if (CS::isDualITree(cs) && pPartitionerChroma != nullptr && (partitioner.currArea().lwidth() >= 64 || partitioner.currArea().lheight() >= 64))
429
8.10k
    {
430
8.10k
      partitioner.splitCurrArea(CU_QUAD_SPLIT, cs);
431
8.10k
      pPartitionerChroma->splitCurrArea(CU_QUAD_SPLIT, cs);
432
8.10k
      bool beContinue = true;
433
8.10k
      bool lumaContinue = true;
434
8.10k
      bool chromaContinue = true;
435
436
40.5k
      while (beContinue)
437
32.4k
      {
438
32.4k
        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
32.4k
        else
450
32.4k
        {
451
          //dual tree coding under 64x64 block
452
32.4k
          if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos()))
453
22.0k
          {
454
22.0k
            coding_tree(cs, partitioner, cuCtx);
455
22.0k
          }
456
32.4k
          lumaContinue = partitioner.nextPart(cs);
457
32.4k
          if (cs.picture->blocks[pPartitionerChroma->chType].contains(pPartitionerChroma->currArea().blocks[pPartitionerChroma->chType].pos()))
458
22.0k
          {
459
22.0k
            coding_tree(cs, *pPartitionerChroma, *pCuCtxChroma);
460
22.0k
          }
461
32.4k
          chromaContinue = pPartitionerChroma->nextPart(cs);
462
32.4k
          CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched");
463
32.4k
          beContinue = lumaContinue;
464
32.4k
        }
465
32.4k
      }
466
8.10k
      partitioner.exitCurrSplit();
467
8.10k
      pPartitionerChroma->exitCurrSplit();
468
469
8.10k
    }
470
82.0k
    else
471
82.0k
    {
472
82.0k
      const ModeType modeTypeParent = partitioner.modeType;
473
82.0k
      const ModeType modeTypeChild = CU::getModeTypeAtDepth( cu, partitioner.currDepth );
474
82.0k
      mode_constraint( splitMode, cs, partitioner, modeTypeChild );
475
82.0k
      partitioner.modeType = modeTypeChild;
476
477
82.0k
      bool chromaNotSplit = modeTypeParent == MODE_TYPE_ALL && modeTypeChild == MODE_TYPE_INTRA ? true : false;
478
82.0k
      CHECK( chromaNotSplit && partitioner.chType != CH_L, "chType must be luma" );
479
82.0k
      if( partitioner.treeType == TREE_D )
480
82.0k
      {
481
82.0k
        partitioner.treeType = chromaNotSplit ? TREE_L : TREE_D;
482
82.0k
      }
483
82.0k
      partitioner.splitCurrArea( splitMode, cs );
484
485
82.0k
      do
486
202k
      {
487
202k
        if( cs.picture->blocks[partitioner.chType].contains( partitioner.currArea().blocks[partitioner.chType].pos() ) )
488
123k
        {
489
123k
          coding_tree( cs, partitioner, cuCtx );
490
123k
        }
491
202k
      } while( partitioner.nextPart( cs ) );
492
493
82.0k
      partitioner.exitCurrSplit();
494
82.0k
      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
82.0k
      partitioner.modeType = modeTypeParent;
512
82.0k
    }
513
90.1k
    return;
514
90.1k
  }
515
516
  // Predict QP on start of quantization group
517
85.7k
  if( cuCtx.qgStart )
518
20.8k
  {
519
20.8k
    cuCtx.qgStart = false;
520
20.8k
    cuCtx.qp = CU::predictQP( cu, cuCtx.qp );
521
20.8k
  }
522
85.7k
  CHECK( cu.treeType != partitioner.treeType, "treeType mismatch" );
523
524
525
  // coding unit
526
85.7k
  coding_unit( cu, partitioner, cuCtx );
527
528
85.7k
  if( cu.chType == CH_C )
529
34.3k
  {
530
34.3k
    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
34.3k
  }
532
51.3k
  else
533
51.3k
  {
534
51.3k
    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
51.3k
  }
536
85.7k
  DTRACE_BLOCK_REC_COND( ( !isEncoding() ), cs.picture->getRecoBuf( cu ), cu, cu.predMode );
537
85.7k
}
538
539
540
void CABACWriter::mode_constraint( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner, const ModeType modeType )
541
273k
{
542
273k
  CHECK( split == CU_DONT_SPLIT, "splitMode shall not be no split" );
543
273k
  int val = CS::signalModeCons( cs, partitioner.currArea(), split, partitioner.modeType);
544
273k
  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
273k
  else if( val == LDT_MODE_TYPE_INFER )
553
0
  {
554
0
    CHECK( modeType != MODE_TYPE_INTRA, "Wrong mode type" );
555
0
  }
556
273k
  else
557
273k
  {
558
273k
    CHECK( modeType != partitioner.modeType, "Wrong mode type" );
559
273k
  }
560
273k
}
561
562
563
void CABACWriter::split_cu_mode( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner )
564
479k
{
565
479k
  bool canNo, canQt, canBh, canBv, canTh, canTv;
566
479k
  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv );
567
568
479k
  const bool canSpl[6] = { canNo, canQt, canBh, canBv, canTh, canTv };
569
570
479k
  unsigned ctxSplit = 0, ctxQtSplit = 0, ctxBttHV = 0, ctxBttH12 = 0, ctxBttV12;
571
479k
  DeriveCtx::CtxSplit( partitioner, ctxSplit, ctxQtSplit, ctxBttHV, ctxBttH12, ctxBttV12, canSpl );
572
573
479k
  const bool canSplit = canBh || canBv || canTh || canTv || canQt;
574
479k
  const bool isNo     = split == CU_DONT_SPLIT;
575
576
479k
  if( canNo && canSplit )
577
293k
  {
578
293k
    m_BinEncoder.encodeBin( !isNo, Ctx::SplitFlag( ctxSplit ) );
579
293k
  }
580
581
479k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d split=%d\n", ctxSplit, !isNo );
582
583
479k
  if( isNo )
584
198k
  {
585
198k
    return;
586
198k
  }
587
588
281k
  const bool canBtt = canBh || canBv || canTh || canTv;
589
281k
  const bool isQt   = split == CU_QUAD_SPLIT;
590
591
281k
  if( canQt && canBtt )
592
110k
  {
593
110k
    m_BinEncoder.encodeBin( isQt, Ctx::SplitQtFlag( ctxQtSplit ) );
594
110k
  }
595
596
281k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d qt=%d\n", ctxQtSplit, isQt );
597
598
281k
  if( isQt )
599
71.2k
  {
600
71.2k
    return;
601
71.2k
  }
602
603
209k
  const bool canHor = canBh || canTh;
604
209k
  const bool canVer = canBv || canTv;
605
209k
  const bool  isVer = split == CU_VERT_SPLIT || split == CU_TRIV_SPLIT;
606
607
209k
  if( canVer && canHor )
608
108k
  {
609
108k
    m_BinEncoder.encodeBin( isVer, Ctx::SplitHvFlag( ctxBttHV ) );
610
108k
  }
611
612
209k
  const bool can14 = isVer ? canTv : canTh;
613
209k
  const bool can12 = isVer ? canBv : canBh;
614
209k
  const bool  is12 = isVer ? ( split == CU_VERT_SPLIT ) : ( split == CU_HORZ_SPLIT );
615
616
209k
  if( can12 && can14 )
617
58.2k
  {
618
58.2k
    m_BinEncoder.encodeBin( is12, Ctx::Split12Flag( isVer ? ctxBttV12 : ctxBttH12 ) );
619
58.2k
  }
620
621
209k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctxHv=%d ctx12=%d mode=%d\n", ctxBttHV, isVer ? ctxBttV12 : ctxBttH12, split );
622
209k
}
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
85.7k
{
643
85.7k
  DTRACE( g_trace_ctx, D_SYNTAX, "coding_unit() treeType=%d modeType=%d\n", cu.treeType, cu.modeType );
644
85.7k
  STAT_COUNT_CU_MODES( isEncoding() && partitioner.chType == CH_L, g_cuCounters1D[CU_CODED_FINALLY][0][!cu.slice->isIntra() + cu.slice->depth] );
645
85.7k
  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
85.7k
  CodingStructure& cs = *cu.cs;
648
649
  // skip flag
650
85.7k
  if ((!cs.slice->isIntra() || cs.slice->sps->IBC) && cu.Y().valid())
651
51.3k
  {
652
51.3k
    cu_skip_flag( cu );
653
51.3k
  }
654
  
655
  // skip data
656
85.7k
  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
85.7k
  pred_mode ( cu );
667
85.7k
  if (CU::isIntra(cu))
668
85.7k
  {
669
85.7k
    adaptive_color_transform(cu);
670
85.7k
  }
671
85.7k
  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
85.7k
  cu_pred_data( cu );
679
680
  // residual data ( coded block flags + transform coefficient levels )
681
85.7k
  cu_residual( cu, partitioner, cuCtx );
682
683
  // end of cu
684
85.7k
  end_of_ctu( cu, cuCtx );
685
85.7k
}
686
687
688
void CABACWriter::cu_skip_flag( const CodingUnit& cu )
689
102k
{
690
102k
  unsigned ctxId = DeriveCtx::CtxSkipFlag();
691
692
102k
  if ((cu.slice->isIntra() || CU::isConsIntra(cu)) && cu.cs->slice->sps->IBC)
693
102k
  {
694
102k
    if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64
695
102k
    {
696
102k
      m_BinEncoder.encodeBin((cu.skip), Ctx::SkipFlag(ctxId));
697
102k
      DTRACE(g_trace_ctx, D_SYNTAX, "cu_skip_flag() ctx=%d skip=%d\n", ctxId, cu.skip ? 1 : 0);
698
102k
    }
699
102k
    return;
700
102k
  }
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
394k
{
730
394k
  if (cu.cs->slice->sps->IBC && cu.chType != CH_C)
731
299k
  {
732
299k
    if( CU::isConsInter(cu) )
733
0
    {
734
0
      assert( CU::isInter( cu ) );
735
0
      return;
736
0
    }
737
738
299k
    if ( cu.cs->slice->isIntra() || ( cu.lwidth() == 4 && cu.lheight() == 4 ) || CU::isConsIntra(cu) )
739
299k
    {
740
299k
      if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64
741
299k
      {
742
299k
        unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
743
299k
        m_BinEncoder.encodeBin(CU::isIBC(cu), Ctx::IBCFlag(ctxidx));
744
299k
      }
745
299k
      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
299k
    }
750
18.4E
    else
751
18.4E
    {
752
18.4E
      if( CU::isConsInter(cu) )
753
0
      {
754
0
        return;
755
0
      }
756
18.4E
      m_BinEncoder.encodeBin((CU::isIntra(cu) || CU::isPLT(cu)), Ctx::PredMode(DeriveCtx::CtxPredModeFlag()));
757
18.4E
      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
18.4E
      else
765
18.4E
      {
766
18.4E
        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
18.4E
      }
772
18.4E
    }
773
299k
  }
774
95.3k
  else
775
95.3k
  {
776
95.3k
    if( CU::isConsInter(cu) )
777
0
    {
778
0
      assert( CU::isInter( cu ) );
779
0
      return;
780
0
    }
781
782
95.3k
    if ( cu.cs->slice->isIntra() || ( cu.lwidth() == 4 && cu.lheight() == 4 ) || CU::isConsIntra(cu) )
783
95.3k
    {
784
95.3k
      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
95.3k
      return;
789
95.3k
    }
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
394k
}
797
798
799
void CABACWriter::bdpcm_mode( const CodingUnit& cu, const ComponentID compID )
800
672k
{
801
672k
  if( !cu.cs->sps->BDPCM) return;
802
672k
  if( !CU::bdpcmAllowed( cu, compID ) ) return;
803
804
297k
  int bdpcmMode = cu.bdpcmM[toChannelType(compID)];
805
806
297k
  unsigned ctxId = isLuma(compID) ? 0 : 2; 
807
297k
  m_BinEncoder.encodeBin(bdpcmMode > 0 ? 1 : 0, Ctx::BDPCMMode(ctxId));
808
297k
  if (bdpcmMode)
809
53.5k
  {
810
53.5k
    m_BinEncoder.encodeBin(bdpcmMode > 1 ? 1 : 0, Ctx::BDPCMMode(ctxId+1));
811
53.5k
  }
812
297k
  if (isLuma(compID))
813
43.5k
  {
814
43.5k
    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
43.5k
  }
816
253k
  else
817
253k
  {
818
253k
    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
253k
  }
820
297k
}
821
822
823
void CABACWriter::cu_pred_data( const CodingUnit& cu )
824
198k
{
825
198k
  if( CU::isIntra( cu ) )
826
173k
  {
827
173k
    if( cu.Y().valid() )
828
78.5k
    {
829
78.5k
      bdpcm_mode( cu, COMP_Y );
830
78.5k
    }
831
173k
    intra_luma_pred_modes  ( cu );
832
173k
    if( ( !cu.Y().valid() || ( !CU::isSepTree(cu) && cu.Y().valid() ) ) && isChromaEnabled(cu.chromaFormat) )
833
95.3k
    {
834
95.3k
      bdpcm_mode( cu, ComponentID(CH_C) );
835
95.3k
    } 
836
173k
    intra_chroma_pred_modes( cu );
837
173k
    return;
838
173k
  }
839
24.3k
  if (!cu.Y().valid()) // dual tree chroma CU
840
0
  {
841
0
    return;
842
0
  }
843
844
24.3k
  prediction_unit ( cu );
845
24.3k
  imv_mode        ( cu );
846
24.3k
  affine_amvr_mode( cu );
847
24.3k
  cu_bcw_flag     ( cu );
848
24.3k
}
849
850
851
void CABACWriter::cu_bcw_flag(const CodingUnit& cu)
852
24.3k
{
853
24.3k
  if(!CU::isBcwIdxCoded(cu))
854
24.3k
  {
855
24.3k
    return;
856
24.3k
  }
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
907k
{
890
907k
  int thresh;
891
907k
  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
907k
  else
903
907k
  {
904
907k
    thresh = g_tbMax[maxSymbol];
905
907k
  }
906
907
907k
  int val = 1 << thresh;
908
907k
  assert(val <= maxSymbol);
909
907k
  assert((val << 1) > maxSymbol);
910
907k
  assert(symbol < maxSymbol);
911
907k
  int b = maxSymbol - val;
912
907k
  assert(b < val);
913
907k
  if (symbol < val - b)
914
282k
  {
915
282k
    m_BinEncoder.encodeBinsEP(symbol, thresh);
916
282k
  }
917
625k
  else
918
625k
  {
919
625k
    symbol += val - b;
920
625k
    assert(symbol < (val << 1));
921
625k
    assert((symbol >> 1) >= val - b);
922
625k
    m_BinEncoder.encodeBinsEP(symbol, thresh + 1);
923
625k
  }
924
907k
}
925
926
927
void CABACWriter::extend_ref_line(const CodingUnit& cu)
928
977k
{
929
977k
  if ( !cu.Y().valid() || cu.predMode != MODE_INTRA || !isLuma(cu.chType) || cu.bdpcmM[CH_L] )
930
0
  {
931
0
    return;
932
0
  }
933
977k
  if( !cu.cs->sps->MRL )
934
0
  {
935
0
    return;
936
0
  }
937
938
977k
  bool isFirstLineOfCtu = (((cu.block(COMP_Y).y)&((cu.cs->sps)->CTUSize - 1)) == 0);
939
977k
  if (isFirstLineOfCtu)
940
320k
  {
941
320k
    return;
942
320k
  }
943
656k
  int multiRefIdx = cu.multiRefIdx;
944
656k
  if (MRL_NUM_REF_LINES > 1)
945
656k
  {
946
656k
    m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[0], Ctx::MultiRefLineIdx(0));
947
656k
    if (MRL_NUM_REF_LINES > 2 && multiRefIdx != MULTI_REF_LINE_IDX[0])
948
179k
    {
949
179k
      m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], Ctx::MultiRefLineIdx(1));
950
179k
    }
951
656k
  }
952
656k
}
953
954
955
void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
956
173k
{
957
173k
  if( !cu.Y().valid() || cu.bdpcmM[CH_L] )
958
100k
  {
959
100k
    return;
960
100k
  }
961
962
73.0k
  mip_flag(cu);
963
73.0k
  if (cu.mipFlag)
964
1.64k
  {
965
1.64k
    mip_pred_modes(cu);
966
1.64k
    return;
967
1.64k
  }
968
71.4k
  extend_ref_line( cu );
969
970
71.4k
  isp_mode( cu );
971
972
71.4k
  const int numMPMs   = NUM_MOST_PROBABLE_MODES;
973
71.4k
  unsigned  mpm_pred   [numMPMs];
974
71.4k
  unsigned  mpm_idx;
975
71.4k
  unsigned  ipred_mode ;
976
977
  // prev_intra_luma_pred_flag
978
71.4k
  {
979
71.4k
    CU::getIntraMPMs( cu, mpm_pred );
980
981
71.4k
    ipred_mode = cu.intraDir[0];
982
71.4k
    mpm_idx    = numMPMs;
983
71.5k
    for( unsigned idx = 0; idx < numMPMs; idx++ )
984
71.5k
    {
985
71.5k
      if( ipred_mode == mpm_pred[idx] )
986
71.4k
      {
987
71.4k
        mpm_idx = idx;
988
71.4k
        break;
989
71.4k
      }
990
71.5k
    }
991
71.4k
    if ( cu.multiRefIdx )
992
0
    {
993
0
      CHECK(mpm_idx >= numMPMs, "use of non-MPM");
994
0
    }
995
71.4k
    else
996
71.4k
    {
997
71.4k
      m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
998
71.4k
    }
999
71.4k
  }
1000
1001
  // mpm_idx / rem_intra_luma_pred_mode
1002
71.4k
  {
1003
71.4k
    if( mpm_idx < numMPMs )
1004
71.4k
    {
1005
71.4k
      {
1006
71.4k
        unsigned ctx = (cu.ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
1007
71.4k
        if (cu.multiRefIdx == 0)
1008
71.4k
          m_BinEncoder.encodeBin(mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx));
1009
71.4k
        if( mpm_idx )
1010
108
        {
1011
108
          m_BinEncoder.encodeBinEP( mpm_idx > 1 );
1012
108
        }
1013
71.4k
        if (mpm_idx > 1)
1014
0
        {
1015
0
          m_BinEncoder.encodeBinEP(mpm_idx > 2);
1016
0
        }
1017
71.4k
        if (mpm_idx > 2)
1018
0
        {
1019
0
          m_BinEncoder.encodeBinEP(mpm_idx > 3);
1020
0
        }
1021
71.4k
        if (mpm_idx > 3)
1022
0
        {
1023
0
          m_BinEncoder.encodeBinEP(mpm_idx > 4);
1024
0
        }
1025
71.4k
      }
1026
71.4k
    }
1027
1
    else
1028
1
    {
1029
      // sorting of MPMs
1030
1
      std::sort( mpm_pred, mpm_pred + numMPMs );
1031
1032
1
      {
1033
1
        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
1
        CHECK(ipred_mode >= 64, "Incorrect mode");
1041
1
        xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
1042
1
      }
1043
1
    }
1044
1045
71.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
71.4k
  }
1047
71.4k
}
1048
1049
1050
void CABACWriter::intra_luma_pred_mode( const CodingUnit& cu, const unsigned *mpmLst )
1051
1.21M
{
1052
1.21M
  if( cu.bdpcmM[CH_L] ) 
1053
7.68k
  {
1054
7.68k
    return;
1055
7.68k
  }
1056
1057
1.20M
  mip_flag(cu);
1058
1.20M
  if (cu.mipFlag)
1059
298k
  {
1060
298k
    mip_pred_mode(cu);
1061
298k
    return;
1062
298k
  }
1063
906k
  extend_ref_line( cu );
1064
1065
906k
  isp_mode( cu );
1066
1067
  // prev_intra_luma_pred_flag
1068
906k
  unsigned ipred_mode = cu.intraDir[0];
1069
906k
  static constexpr int numMPMs = NUM_MOST_PROBABLE_MODES;
1070
906k
  unsigned mpm_idx = numMPMs;
1071
906k
  unsigned  mpm_pred[numMPMs];
1072
1073
906k
  if (mpmLst)
1074
765k
  {
1075
765k
    memcpy(mpm_pred, mpmLst, sizeof(unsigned) * numMPMs);
1076
765k
  }
1077
140k
  else
1078
140k
  {
1079
140k
    CU::getIntraMPMs(cu, mpm_pred);
1080
140k
  }
1081
1082
4.75M
  for (int idx = 0; idx < numMPMs; idx++)
1083
4.21M
  {
1084
4.21M
    if (ipred_mode == mpm_pred[idx])
1085
363k
    {
1086
363k
      mpm_idx = idx;
1087
363k
      break;
1088
363k
    }
1089
4.21M
  }
1090
906k
  if (cu.multiRefIdx)
1091
179k
  {
1092
179k
    CHECK(mpm_idx >= numMPMs, "use of non-MPM");
1093
179k
  }
1094
726k
  else
1095
726k
  {
1096
726k
    m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
1097
726k
  }
1098
1099
  // mpm_idx / rem_intra_luma_pred_mode
1100
906k
  if( mpm_idx < numMPMs )
1101
363k
  {
1102
363k
    unsigned ctx = (cu.ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
1103
363k
    if (cu.multiRefIdx == 0)
1104
184k
      m_BinEncoder.encodeBin( mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx) );
1105
363k
    if( mpm_idx )
1106
245k
    {
1107
245k
      m_BinEncoder.encodeBinEP( mpm_idx > 1 );
1108
245k
    }
1109
363k
    if (mpm_idx > 1)
1110
139k
    {
1111
139k
      m_BinEncoder.encodeBinEP(mpm_idx > 2);
1112
139k
    }
1113
363k
    if (mpm_idx > 2)
1114
103k
    {
1115
103k
      m_BinEncoder.encodeBinEP(mpm_idx > 3);
1116
103k
    }
1117
363k
    if (mpm_idx > 3)
1118
68.7k
    {
1119
68.7k
      m_BinEncoder.encodeBinEP(mpm_idx > 4);
1120
68.7k
    }
1121
363k
  }
1122
542k
  else
1123
542k
  {
1124
    // mpm_pred[0] is always 0, i.e. PLANAR, so its always first in the list
1125
542k
    std::sort( mpm_pred + 1, mpm_pred + numMPMs );
1126
1127
3.79M
    for (int idx = numMPMs - 1; idx >= 0; idx--)
1128
3.25M
    {
1129
3.25M
      if (ipred_mode > mpm_pred[idx])
1130
1.76M
      {
1131
1.76M
        ipred_mode--;
1132
1.76M
      }
1133
3.25M
    }
1134
1135
542k
    xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
1136
542k
  }
1137
906k
}
1138
1139
1140
void CABACWriter::intra_chroma_pred_modes( const CodingUnit& cu )
1141
173k
{
1142
173k
  if( cu.chromaFormat == CHROMA_400 || ( CU::isSepTree(cu) && cu.chType == CH_L ) || cu.bdpcmM[CH_C] )
1143
78.5k
  {
1144
78.5k
    return;
1145
78.5k
  }
1146
1147
95.3k
  intra_chroma_pred_mode( cu );
1148
95.3k
}
1149
1150
1151
void CABACWriter::intra_chroma_lmc_mode(const CodingUnit& cu)
1152
36.8k
{
1153
36.8k
  const unsigned intraDir = cu.intraDir[1];
1154
36.8k
  int lmModeList[10];
1155
36.8k
  CU::getLMSymbolList(cu, lmModeList);
1156
36.8k
  int symbol = -1;
1157
36.8k
  for (int k = 0; k < LM_SYMBOL_NUM; k++)
1158
36.8k
  {
1159
36.8k
    if (lmModeList[k] == intraDir)
1160
36.8k
    {
1161
36.8k
      symbol = k;
1162
36.8k
      break;
1163
36.8k
    }
1164
36.8k
  }
1165
36.8k
  CHECK(symbol < 0, "invalid symbol found");
1166
1167
36.8k
  m_BinEncoder.encodeBin(symbol == 0 ? 0 : 1, Ctx::CclmModeIdx(0));
1168
1169
36.8k
  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
36.8k
}
1176
1177
1178
void CABACWriter::intra_chroma_pred_mode(const CodingUnit& cu)
1179
397k
{
1180
397k
  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
397k
  const unsigned intraDir = cu.intraDir[1];
1187
397k
  if (cu.cs->sps->LMChroma && CU::checkCCLMAllowed(cu))
1188
272k
  {
1189
272k
    m_BinEncoder.encodeBin(CU::isLMCMode(intraDir) ? 1 : 0, Ctx::CclmModeFlag(0));
1190
272k
    if (CU::isLMCMode(intraDir))
1191
36.8k
    {
1192
36.8k
      intra_chroma_lmc_mode(cu);
1193
36.8k
      return;
1194
36.8k
    }
1195
272k
  }
1196
1197
360k
  const bool     isDerivedMode = intraDir == DM_CHROMA_IDX;
1198
360k
  m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0));
1199
360k
  if (isDerivedMode)
1200
81.6k
  {
1201
81.6k
    return;
1202
81.6k
  }
1203
1204
  // chroma candidate index
1205
278k
  unsigned chromaCandModes[NUM_CHROMA_MODE];
1206
278k
  CU::getIntraChromaCandModes(cu, chromaCandModes);
1207
1208
278k
  int candId = 0;
1209
661k
  for (; candId < NUM_CHROMA_MODE; candId++)
1210
661k
  {
1211
661k
    if (intraDir == chromaCandModes[candId])
1212
278k
    {
1213
278k
      break;
1214
278k
    }
1215
661k
  }
1216
1217
278k
  CHECK(candId >= NUM_CHROMA_MODE, "Chroma prediction mode index out of bounds");
1218
278k
  CHECK(chromaCandModes[candId] == DM_CHROMA_IDX, "The intra dir cannot be DM_CHROMA for this path");
1219
278k
  {
1220
278k
    m_BinEncoder.encodeBinsEP(candId, 2);
1221
278k
  }
1222
278k
}
1223
1224
1225
void CABACWriter::cu_residual( const CodingUnit& cu, Partitioner& partitioner, CUCtx& cuCtx )
1226
198k
{
1227
198k
  if (!CU::isIntra(cu))
1228
24.3k
  {
1229
24.3k
    if( !cu.mergeFlag )
1230
24.3k
    {
1231
24.3k
      rqt_root_cbf( cu );
1232
24.3k
    }
1233
24.3k
    if( cu.rootCbf )
1234
146
    {
1235
146
      sbt_mode( cu );
1236
146
    }
1237
1238
24.3k
    if( !cu.rootCbf )
1239
24.1k
    {
1240
24.1k
      CHECK(cu.colorTransform, "ACT should not be enabled for root_cbf = 0");
1241
24.1k
      return;
1242
24.1k
    }
1243
24.3k
  }
1244
1245
174k
  if( CU::isInter( cu ) || CU::isIBC( cu ) )
1246
146
  {
1247
146
    adaptive_color_transform(cu);
1248
146
  }
1249
1250
174k
  cuCtx.violatesLfnstConstrained[CH_L] = false;
1251
174k
  cuCtx.violatesLfnstConstrained[CH_C] = false;
1252
174k
  cuCtx.lfnstLastScanPos               = false;
1253
174k
  cuCtx.violatesMtsCoeffConstraint     = false;
1254
174k
  cuCtx.mtsLastScanPos                                = false;
1255
1256
174k
  if( cu.ispMode && isLuma( partitioner.chType ) )
1257
38
  {
1258
38
    transform_tree( *cu.cs, partitioner, cuCtx, CU::getISPType( cu, getFirstComponentOfChannel( partitioner.chType ) ), 0 );
1259
38
  }
1260
173k
  else
1261
173k
  {
1262
173k
    transform_tree( *cu.cs, partitioner, cuCtx );
1263
173k
  }
1264
1265
174k
  residual_lfnst_mode( cu, cuCtx );
1266
174k
  mts_idx            ( cu, &cuCtx );
1267
174k
}
1268
1269
1270
void CABACWriter::rqt_root_cbf( const CodingUnit& cu )
1271
48.6k
{
1272
48.6k
  m_BinEncoder.encodeBin( cu.rootCbf, Ctx::QtRootCbf() );
1273
1274
48.6k
  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
48.6k
}
1276
1277
1278
void CABACWriter::adaptive_color_transform(const CodingUnit& cu)
1279
85.9k
{
1280
85.9k
  if (!cu.slice->sps->useColorTrans )
1281
85.9k
  {
1282
85.9k
    return;
1283
85.9k
  }
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
146
{
1300
146
  uint8_t sbtAllowed = CU::checkAllowedSbt(cu);
1301
146
  if( !sbtAllowed )
1302
146
  {
1303
146
    return;
1304
146
  }
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
85.7k
{
1358
85.7k
  const bool    isLastSubCUOfCtu  = CU::isLastSubCUOfCtu( cu );
1359
1360
85.7k
  if ( isLastSubCUOfCtu
1361
16.2k
    && ( !CU::isSepTree(cu) || cu.chromaFormat == CHROMA_400 || isChroma( cu.chType ) )
1362
85.7k
      )
1363
8.10k
  {
1364
8.10k
    cuCtx.isDQPCoded = ( cu.cs->pps->useDQP && !cuCtx.isDQPCoded );
1365
1366
8.10k
  }
1367
85.7k
}
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
24.3k
{
1389
24.3k
  CHECK( cu.treeType == TREE_C, "cannot be chroma CU" );
1390
24.3k
  if( cu.skip )
1391
0
  {
1392
0
    CHECK( !cu.mergeFlag, "merge_flag must be true for skipped CUs" );
1393
0
  }
1394
24.3k
  else
1395
24.3k
  {
1396
24.3k
    merge_flag( cu );
1397
24.3k
  }
1398
24.3k
  if( cu.mergeFlag )
1399
0
  {
1400
0
    merge_data(cu);
1401
0
  }
1402
24.3k
  else if (CU::isIBC(cu))
1403
24.3k
  {
1404
24.3k
    ref_idx(cu, REF_PIC_LIST_0);
1405
24.3k
    Mv mvd = cu.mvd[REF_PIC_LIST_0][0];
1406
24.3k
    mvd.changeIbcPrecInternal2Amvr(cu.imv);
1407
24.3k
    mvd_coding(mvd, 0); // already changed to signaling precision
1408
24.3k
    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
24.3k
    else
1413
24.3k
    mvp_flag(cu, REF_PIC_LIST_0);
1414
24.3k
  }
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
24.3k
}
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
24.3k
{
1532
24.3k
  m_BinEncoder.encodeBin( cu.mergeFlag, Ctx::MergeFlag() );
1533
1534
24.3k
  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
24.3k
}
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
24.3k
{
1590
24.3k
  const SPS *sps = cu.cs->sps;
1591
1592
24.3k
  if( !sps->AMVR )
1593
0
  {
1594
0
    return;
1595
0
  }
1596
24.3k
  if ( cu.affine )
1597
0
  {
1598
0
    return;
1599
0
  }
1600
1601
24.3k
  bool bNonZeroMvd = CU::hasSubCUNonZeroMVd( cu );
1602
24.3k
  if( !bNonZeroMvd )
1603
0
  {
1604
0
    return;
1605
0
  }
1606
1607
24.3k
  if (CU::isIBC(cu) == false)
1608
0
    m_BinEncoder.encodeBin( (cu.imv > 0), Ctx::ImvFlag( 0 ) );
1609
24.3k
  DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 0), 0 );
1610
1611
24.3k
  if( sps->AMVR && cu.imv > 0 )
1612
24.3k
  {
1613
24.3k
    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
24.3k
    if (cu.imv < IMV_HPEL)
1619
24.3k
    {
1620
24.3k
    m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 1 ) );
1621
24.3k
    DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 1), 1 );
1622
24.3k
    }
1623
24.3k
  }
1624
1625
24.3k
  DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() IMVFlag=%d\n", cu.imv );
1626
24.3k
}
1627
1628
1629
void CABACWriter::affine_amvr_mode( const CodingUnit& cu )
1630
24.3k
{
1631
24.3k
  const SPS* sps = cu.slice->sps;
1632
1633
24.3k
  if( !sps->AffineAmvr || !cu.affine )
1634
24.3k
  {
1635
24.3k
    return;
1636
24.3k
  }
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
24.3k
{
1812
24.3k
  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
24.3k
  int numRef  = cu.cs->slice->numRefIdx[eRefList];
1819
1820
24.3k
  if (eRefList == REF_PIC_LIST_0 && cu.cs->sps->IBC)
1821
24.3k
  {
1822
24.3k
    if (CU::isIBC(cu))
1823
24.3k
      return;
1824
24.3k
  }
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
24.3k
{
1861
24.3k
  m_BinEncoder.encodeBin( cu.mvpIdx[eRefList], Ctx::MVPIdx() );
1862
24.3k
  DTRACE( g_trace_ctx, D_SYNTAX, "mvp_flag() value=%d pos=(%d,%d)\n", cu.mvpIdx[eRefList], cu.lumaPos().x, cu.lumaPos().y );
1863
24.3k
  DTRACE( g_trace_ctx, D_SYNTAX, "mvpIdx(refList:%d)=%d\n", eRefList, cu.mvpIdx[eRefList] );
1864
24.3k
}
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
174k
{
1894
174k
  const UnitArea&       area = partitioner.currArea();
1895
174k
  int             subTuCounter = subTuIdx;
1896
174k
  const TransformUnit&  tu = *cs.getTU(area.blocks[partitioner.chType].pos(), partitioner.chType, subTuIdx);
1897
174k
  const CodingUnit&     cu = *tu.cu;
1898
174k
  const unsigned        trDepth = partitioner.currTrDepth;
1899
174k
  const bool            split = (tu.depth > trDepth);
1900
174k
  if( split )
1901
38
  {
1902
38
    PartSplit partSplit;
1903
1904
38
    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
38
    else if( cu.ispMode )
1914
38
    {
1915
38
      partitioner.splitCurrArea( ispType, cs );
1916
38
    }
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
38
    do
1925
152
    {
1926
152
      transform_tree( cs, partitioner, cuCtx,                ispType, subTuCounter );
1927
152
      subTuCounter += subTuCounter != -1 ? 1 : 0;
1928
152
    } while( partitioner.nextPart( cs ) );
1929
1930
38
    partitioner.exitCurrSplit();
1931
38
  }
1932
174k
  else
1933
174k
  {
1934
    // split_transform_flag
1935
174k
    CHECK( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) || (cu.sbtInfo && partitioner.canSplit( CU::getSbtTuSplit( cu.sbtInfo ), cs)),  "transform split implied" );
1936
174k
    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
174k
    transform_unit( tu, cuCtx, partitioner, subTuCounter);
1939
174k
  }
1940
174k
}
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.29M
{
1945
3.29M
  const CtxSet&   ctxSet  = Ctx::QtCbf[ area.compID ];
1946
3.29M
  unsigned  ctxId;
1947
3.29M
  if( cu.bdpcmM[toChannelType(area.compID)] )
1948
207k
  {
1949
207k
    ctxId = (area.compID != COMP_Cr) ? 1 : 2;
1950
207k
    m_BinEncoder.encodeBin(cbf, ctxSet(ctxId));
1951
207k
  }
1952
3.08M
  else
1953
3.08M
  {
1954
3.08M
    ctxId = DeriveCtx::CtxQtCbf(area.compID, prevCbf, useISP && isLuma(area.compID));
1955
3.08M
    m_BinEncoder.encodeBin( cbf, ctxSet( ctxId ) );
1956
3.08M
  }
1957
3.29M
  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.29M
}
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
24.3k
{
1969
24.3k
  int       horMvd = rMvd.hor;
1970
24.3k
  int       verMvd = rMvd.ver;
1971
24.3k
  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
24.3k
  unsigned  horAbs  = unsigned( horMvd < 0 ? -horMvd : horMvd );
1988
24.3k
  unsigned  verAbs  = unsigned( verMvd < 0 ? -verMvd : verMvd );
1989
1990
1991
  // abs_mvd_greater0_flag[ 0 | 1 ]
1992
24.3k
  m_BinEncoder.encodeBin( (horAbs > 0), Ctx::Mvd() );
1993
24.3k
  m_BinEncoder.encodeBin( (verAbs > 0), Ctx::Mvd() );
1994
1995
  // abs_mvd_greater1_flag[ 0 | 1 ]
1996
24.3k
  if( horAbs > 0 )
1997
15.0k
  {
1998
15.0k
    m_BinEncoder.encodeBin( (horAbs > 1), Ctx::Mvd(1) );
1999
15.0k
  }
2000
24.3k
  if( verAbs > 0 )
2001
9.24k
  {
2002
9.24k
    m_BinEncoder.encodeBin( (verAbs > 1), Ctx::Mvd(1) );
2003
9.24k
  }
2004
2005
  // abs_mvd_minus2[ 0 | 1 ] and mvd_sign_flag[ 0 | 1 ]
2006
24.3k
  if( horAbs > 0 )
2007
15.0k
  {
2008
15.0k
    if( horAbs > 1 )
2009
15.0k
    {
2010
15.0k
      m_BinEncoder.encodeRemAbsEP(horAbs - 2, 1, 0, MV_BITS - 1);
2011
15.0k
    }
2012
15.0k
    m_BinEncoder.encodeBinEP( (horMvd < 0) );
2013
15.0k
  }
2014
24.3k
  if( verAbs > 0 )
2015
9.24k
  {
2016
9.24k
    if( verAbs > 1 )
2017
9.17k
    {
2018
9.17k
      m_BinEncoder.encodeRemAbsEP(verAbs - 2, 1, 0, MV_BITS - 1);
2019
9.17k
    }
2020
9.24k
    m_BinEncoder.encodeBinEP( (verMvd < 0) );
2021
9.24k
  }
2022
24.3k
}
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
174k
{
2034
174k
  const CodingUnit&       cu = *tu.cu;
2035
174k
  const UnitArea&         area = partitioner.currArea();
2036
174k
  const unsigned          trDepth = partitioner.currTrDepth;
2037
174k
  ChromaCbfs              chromaCbfs;
2038
174k
  CHECK(tu.depth != trDepth, " transform unit should be not be futher partitioned");
2039
2040
  // cbf_cb & cbf_cr
2041
174k
  if (area.chromaFormat != CHROMA_400)
2042
174k
  {
2043
174k
    const bool              chromaCbfISP = area.blocks[COMP_Cb].valid() && cu.ispMode;
2044
174k
    if (area.blocks[COMP_Cb].valid() && (!CU::isSepTree(cu) || partitioner.chType == CH_C) && (!cu.ispMode || chromaCbfISP))
2045
95.3k
    {
2046
95.3k
      unsigned cbfDepth = chromaCbfISP ? trDepth - 1 : trDepth;
2047
95.3k
      {
2048
95.3k
        chromaCbfs.Cb = TU::getCbfAtDepth(tu, COMP_Cb, trDepth);
2049
        //if (!(cu.sbtInfo && trDepth == 1))
2050
95.3k
        if (!(cu.sbtInfo && tu.noResidual))
2051
95.3k
          cbf_comp(*tu.cu, chromaCbfs.Cb, area.blocks[COMP_Cb], cbfDepth);
2052
95.3k
      }
2053
2054
95.3k
      {
2055
95.3k
        chromaCbfs.Cr = TU::getCbfAtDepth(tu, COMP_Cr, trDepth);
2056
        //if (!(cu.sbtInfo && trDepth == 1))
2057
95.3k
        if (!(cu.sbtInfo && tu.noResidual))
2058
95.3k
          cbf_comp(*tu.cu, chromaCbfs.Cr, area.blocks[COMP_Cr], cbfDepth, chromaCbfs.Cb);
2059
95.3k
      }
2060
95.3k
    }
2061
78.7k
    else if (CU::isSepTree(cu))
2062
78.7k
    {
2063
78.7k
      chromaCbfs = ChromaCbfs(false);
2064
78.7k
    }
2065
174k
  }
2066
0
  else if (CU::isSepTree(cu))
2067
0
  {
2068
0
    chromaCbfs = ChromaCbfs(false);
2069
0
  }
2070
2071
174k
  if (!isChroma(partitioner.chType))
2072
78.7k
  {
2073
78.7k
    if (!CU::isIntra(cu) && trDepth == 0 && !chromaCbfs.sigChroma(area.chromaFormat))
2074
146
    {
2075
146
      CHECK(!TU::getCbfAtDepth(tu, COMP_Y, trDepth), "Luma cbf must be true for inter units with no chroma coeffs");
2076
146
    }
2077
78.6k
    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
78.6k
    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
78.6k
    else
2087
78.6k
    {
2088
78.6k
      bool previousCbf = false;
2089
78.6k
      bool rootCbfSoFar = false;
2090
78.6k
      bool lumaCbfIsInferredACT = (cu.colorTransform && cu.predMode == MODE_INTRA && trDepth == 0 && !chromaCbfs.sigChroma(area.chromaFormat));
2091
78.6k
      CHECK(lumaCbfIsInferredACT && !TU::getCbfAtDepth(tu, COMP_Y, trDepth), "adaptive color transform cannot have all zero coefficients");
2092
78.6k
      bool lastCbfIsInferred    = lumaCbfIsInferredACT; // ISP and ACT are mutually exclusive
2093
78.6k
      if (cu.ispMode)
2094
152
      {
2095
152
        uint32_t nTus = cu.ispMode == HOR_INTRA_SUBPARTITIONS ? cu.lheight() >> Log2(tu.lheight()) : cu.lwidth() >> Log2(tu.lwidth());
2096
152
        if (subTuCounter == nTus - 1)
2097
38
        {
2098
38
          TransformUnit* tuPointer = cu.firstTU;
2099
152
          for (int tuIdx = 0; tuIdx < subTuCounter; tuIdx++)
2100
114
          {
2101
114
            rootCbfSoFar |= TU::getCbfAtDepth(*tuPointer, COMP_Y, trDepth);
2102
114
            tuPointer = tuPointer->next;
2103
114
          }
2104
38
          if (!rootCbfSoFar)
2105
0
          {
2106
0
            lastCbfIsInferred = true;
2107
0
          }
2108
38
        }
2109
152
        if (!lastCbfIsInferred)
2110
152
        {
2111
152
          previousCbf = TU::getPrevTuCbfAtDepth(tu, COMP_Y, partitioner.currTrDepth);
2112
152
        }
2113
152
      }
2114
78.6k
      if (!lastCbfIsInferred)
2115
78.6k
      {
2116
78.6k
        cbf_comp(*tu.cu, TU::getCbfAtDepth(tu, COMP_Y, trDepth), tu.Y(), trDepth, previousCbf, cu.ispMode);
2117
78.6k
      }
2118
78.6k
    }
2119
78.7k
  }
2120
174k
  bool        lumaOnly  = ( cu.chromaFormat == CHROMA_400 || !tu.blocks[COMP_Cb].valid() );
2121
174k
  bool        cbf[3]    = { TU::getCbf( tu, COMP_Y ), chromaCbfs.Cb, chromaCbfs.Cr };
2122
174k
  bool        cbfLuma   = ( cbf[ COMP_Y ] != 0 );
2123
174k
  bool        cbfChroma = false;
2124
2125
174k
  if( !lumaOnly )
2126
95.3k
  {
2127
95.3k
    if( tu.blocks[COMP_Cb].valid() )
2128
95.3k
    {
2129
95.3k
      cbf   [ COMP_Cb  ] = TU::getCbf( tu, COMP_Cb );
2130
95.3k
      cbf   [ COMP_Cr  ] = TU::getCbf( tu, COMP_Cr );
2131
95.3k
    }
2132
95.3k
    cbfChroma = ( cbf[ COMP_Cb ] || cbf[ COMP_Cr ] );
2133
95.3k
  }
2134
2135
174k
  if( ( cu.lwidth() > 64 || cu.lheight() > 64 || cbfLuma || cbfChroma ) &&
2136
29.6k
    (!CU::isSepTree(*tu.cu) || isLuma(tu.chType)) )
2137
5.32k
  {
2138
5.32k
    if( cu.cs->pps->useDQP && !cuCtx.isDQPCoded )
2139
2.61k
    {
2140
2.61k
      cu_qp_delta(cu, cuCtx.qp, cu.qp);
2141
2.61k
      cuCtx.qp = cu.qp;
2142
2.61k
      cuCtx.isDQPCoded = true;
2143
2.61k
    }
2144
5.32k
  }
2145
174k
  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
174k
  if( !lumaOnly )
2152
95.3k
  {
2153
95.3k
    joint_cb_cr( tu, ( cbf[COMP_Cb] ? 2 : 0 ) + ( cbf[COMP_Cr] ? 1 : 0 ) );
2154
95.3k
  }
2155
2156
174k
  if( cbfLuma )
2157
5.32k
  {
2158
5.32k
    residual_coding( tu, COMP_Y, &cuCtx );
2159
5.32k
  }
2160
174k
  if( !lumaOnly )
2161
95.3k
  {
2162
285k
    for( ComponentID compID = COMP_Cb; compID <= COMP_Cr; compID = ComponentID( compID + 1 ) )
2163
190k
    {
2164
190k
      if( cbf[ compID ] )
2165
48.2k
      {
2166
48.2k
        residual_coding( tu, compID, &cuCtx );
2167
48.2k
      }
2168
190k
    }
2169
95.3k
  }
2170
174k
}
2171
2172
2173
void CABACWriter::cu_qp_delta( const CodingUnit& cu, int predQP, const int8_t qp )
2174
3.91k
{
2175
3.91k
  CHECK(!( predQP != std::numeric_limits<int>::max()), "Unspecified error");
2176
3.91k
  int       DQp         = qp - predQP;
2177
3.91k
  int       qpBdOffsetY = cu.cs->sps->qpBDOffset[ CH_L ];
2178
3.91k
  DQp                   = ( DQp + (MAX_QP + 1) + (MAX_QP + 1) / 2 + qpBdOffsetY + (qpBdOffsetY / 2)) % ((MAX_QP + 1) + qpBdOffsetY) - (MAX_QP + 1) / 2 - (qpBdOffsetY / 2);
2179
3.91k
  unsigned  absDQP      = unsigned( DQp < 0 ? -DQp : DQp );
2180
3.91k
  unsigned  unaryDQP    = std::min<unsigned>( absDQP, CU_DQP_TU_CMAX );
2181
2182
3.91k
  unary_max_symbol( unaryDQP, Ctx::DeltaQP(), Ctx::DeltaQP(1), CU_DQP_TU_CMAX );
2183
3.91k
  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
3.91k
  if( absDQP > 0 )
2188
0
  {
2189
0
    m_BinEncoder.encodeBinEP( DQp < 0 );
2190
0
  }
2191
2192
3.91k
  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
3.91k
}
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.47M
{
2227
1.47M
  if ( !tu.cu->slice->sps->jointCbCr )
2228
0
  {
2229
0
    return;
2230
0
  }
2231
2232
1.47M
  CHECK( tu.jointCbCr && tu.jointCbCr != cbfMask, "wrong value of jointCbCr (" << (int)tu.jointCbCr << " vs " << (int)cbfMask << ")" );
2233
1.47M
  if( ( CU::isIntra( *tu.cu ) && cbfMask ) || ( cbfMask == 3 ) )
2234
695k
  {
2235
695k
    m_BinEncoder.encodeBin( tu.jointCbCr ? 1 : 0, Ctx::JointCbCrFlag( cbfMask - 1 ) );
2236
695k
  }
2237
1.47M
}
2238
2239
2240
void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID, CUCtx* cuCtx )
2241
1.41M
{
2242
1.41M
  const CodingUnit& cu = *tu.cu;
2243
1.41M
  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.41M
  if( compID == COMP_Cr && tu.jointCbCr == 3 )
2246
407k
  {
2247
407k
    return;
2248
407k
  }
2249
2250
1.01M
  ts_flag            ( tu, compID );
2251
2252
1.01M
  if( tu.mtsIdx[compID] == MTS_SKIP && !tu.cs->slice->tsResidualCodingDisabled )
2253
70.1k
  {
2254
70.1k
    residual_codingTS( tu, compID );
2255
70.1k
    return;
2256
70.1k
  }
2257
2258
  // determine sign hiding
2259
941k
  bool signHiding  = cu.cs->slice->signDataHidingEnabled;
2260
2261
  // init coeff coding context
2262
941k
  CoeffCodingContext  cctx    ( tu, compID, signHiding, false, m_tplBuf );
2263
941k
  const TCoeffSig*    coeff   = tu.getCoeffs( compID ).buf;
2264
2265
  // determine and set last coeff position and sig group flags
2266
941k
  int                      scanPosLast = tu.lastPos[compID];
2267
941k
  std::bitset<MLS_GRP_NUM> sigGroupFlags;
2268
2269
1.91M
  for( int subSetId = 0; subSetId <= ( scanPosLast >> cctx.log2CGSize() ); subSetId++ )
2270
969k
  {
2271
969k
    const int scanPosStart = subSetId << cctx.log2CGSize();
2272
969k
    const int scanPosEnd   = scanPosStart + ( 1 << cctx.log2CGSize() ) - 1;
2273
2274
8.77M
    for( int scanPos = scanPosEnd; scanPos >= scanPosStart; scanPos-- )
2275
8.77M
    {
2276
8.77M
      unsigned blkPos = cctx.blockPos( scanPos );
2277
2278
8.77M
      if( coeff[blkPos] )
2279
959k
      {
2280
959k
        sigGroupFlags.set( subSetId );
2281
959k
        break;
2282
959k
      }
2283
8.77M
    }
2284
969k
  }
2285
941k
  CHECK( scanPosLast < 0, "Coefficient coding called for empty TU" );
2286
941k
  cctx.setScanPosLast(scanPosLast);
2287
2288
941k
  if( cuCtx && tu.mtsIdx[compID] != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
2289
828k
  {
2290
828k
    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
828k
    cuCtx->violatesLfnstConstrained[ toChannelType(compID) ] |= cctx.scanPosLast() > maxLfnstPos;
2292
828k
  }
2293
941k
  if( cuCtx && tu.mtsIdx[compID] != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
2294
828k
  {
2295
828k
    const int lfnstLastScanPosTh = isLuma( compID ) ? LFNST_LAST_SIG_LUMA : LFNST_LAST_SIG_CHROMA;
2296
828k
    cuCtx->lfnstLastScanPos |= cctx.scanPosLast() >= lfnstLastScanPosTh;
2297
828k
  }
2298
941k
  if (cuCtx && isLuma(compID) && tu.mtsIdx[compID] != MTS_SKIP)
2299
29.6k
  {
2300
29.6k
    cuCtx->mtsLastScanPos |= cctx.scanPosLast() >= 1;
2301
29.6k
  }
2302
  
2303
  // code last coeff position
2304
941k
  last_sig_coeff( cctx, tu, compID );
2305
2306
  // code subblocks
2307
941k
  const int stateTab  = ( tu.cs->slice->depQuantEnabled ? 32040 : 0 );
2308
941k
  int       state     = 0;
2309
2310
941k
  int ctxBinSampleRatio = MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT;
2311
941k
  cctx.remRegBins = (tu.getTbAreaAfterCoefZeroOut(compID) * ctxBinSampleRatio) >> 4;
2312
2313
941k
  const bool zeroOutCheck  = isLuma( compID ) && tu.cs->sps->MTS && tu.cu->sbtInfo != 0 && tu.blocks[compID].height <= 32 && tu.blocks[compID].width <= 32;
2314
941k
  const bool zeroOutWidth  = tu.blocks[compID].width;
2315
941k
  const bool zeroOutHeight = tu.blocks[compID].height;
2316
2317
1.91M
  for( int subSetId = ( cctx.scanPosLast() >> cctx.log2CGSize() ); subSetId >= 0; subSetId--)
2318
969k
  {
2319
969k
    cctx.initSubblock( subSetId, sigGroupFlags[subSetId] );
2320
2321
969k
    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
969k
    residual_coding_subblock( cctx, coeff, stateTab, state );
2330
969k
    if ( cuCtx && isLuma(compID) && cctx.isSigGroup() && ( cctx.cgPosY() > 3 || cctx.cgPosX() > 3 ) )
2331
0
    {
2332
0
      cuCtx->violatesMtsCoeffConstraint = true;
2333
0
    }
2334
969k
  }
2335
941k
}
2336
2337
2338
void CABACWriter::ts_flag( const TransformUnit& tu, ComponentID compID )
2339
1.01M
{
2340
1.01M
  int tsFlag = tu.mtsIdx[compID] == MTS_SKIP ? 1 : 0;
2341
1.01M
  int ctxIdx = isLuma(compID) ? 0 : 1;
2342
  
2343
1.01M
  if( TU::isTSAllowed ( tu, compID ) )
2344
691k
  {
2345
691k
    m_BinEncoder.encodeBin( tsFlag, Ctx::TransformSkipFlag(ctxIdx));
2346
691k
  }
2347
1.01M
  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.01M
}
2349
2350
2351
void CABACWriter::mts_idx( const CodingUnit& cu, CUCtx* cuCtx )
2352
201k
{
2353
201k
  TransformUnit &tu = *cu.firstTU;
2354
201k
  int        mtsIdx = tu.mtsIdx[COMP_Y];
2355
  
2356
201k
  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
201k
  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
201k
}
2381
2382
2383
void CABACWriter::isp_mode( const CodingUnit& cu )
2384
977k
{
2385
977k
  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
179k
  {
2387
179k
    CHECK( cu.ispMode != NOT_INTRA_SUBPARTITIONS, "cu.ispMode != 0" );
2388
179k
    return;
2389
179k
  }
2390
798k
  if ( cu.ispMode == NOT_INTRA_SUBPARTITIONS )
2391
787k
  {
2392
787k
    m_BinEncoder.encodeBin( 0, Ctx::ISPMode( 0 ) );
2393
787k
  }
2394
10.8k
  else
2395
10.8k
  {
2396
10.8k
    m_BinEncoder.encodeBin( 1, Ctx::ISPMode( 0 ) );
2397
10.8k
    m_BinEncoder.encodeBin( cu.ispMode - 1, Ctx::ISPMode( 1 ) );
2398
10.8k
  }
2399
798k
  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
798k
}
2401
2402
2403
void CABACWriter::residual_lfnst_mode( const CodingUnit& cu, CUCtx& cuCtx )
2404
291k
{
2405
291k
  int chIdx = CS::isDualITree( *cu.cs ) && cu.chType == CH_C ? 1 : 0;
2406
291k
  if( ( cu.ispMode && !CU::canUseLfnstWithISP( cu, cu.chType ) ) ||
2407
291k
      (cu.cs->sps->LFNST && CU::isIntra(cu) && cu.mipFlag && !allowLfnstWithMip(cu.lumaSize())) ||
2408
289k
    ( CU::isSepTree(cu) && cu.chType == CH_C && std::min( cu.blocks[ 1 ].width, cu.blocks[ 1 ].height ) < 4 )
2409
286k
    || ( cu.blocks[ chIdx ].lumaSize().width > cu.cs->sps->getMaxTbSize() || cu.blocks[ chIdx ].lumaSize().height > cu.cs->sps->getMaxTbSize() )
2410
291k
    )
2411
5.02k
  {
2412
5.02k
    return;
2413
5.02k
  }
2414
2415
286k
  if( cu.cs->sps->LFNST && CU::isIntra( cu )  )
2416
286k
  {
2417
286k
    const bool lumaFlag                   = CU::isSepTree(cu) ? (   isLuma( cu.chType ) ? true : false ) : true;
2418
286k
    const bool chromaFlag                 = CU::isSepTree(cu) ? ( isChroma( cu.chType ) ? true : false ) : true;
2419
286k
          bool nonZeroCoeffNonTsCorner8x8 = ( lumaFlag && cuCtx.violatesLfnstConstrained[CH_L] ) || (chromaFlag && cuCtx.violatesLfnstConstrained[CH_C] );
2420
2421
286k
    bool isTrSkip = false;
2422
2423
286k
    for( const auto& currTU : cTUTraverser( cu.firstTU, cu.lastTU->next ) )
2424
292k
    {
2425
292k
      const uint32_t numValidComp = getNumberValidComponents(cu.chromaFormat);
2426
1.16M
      for (uint32_t compID = COMP_Y; compID < numValidComp; compID++)
2427
876k
      {
2428
876k
        if (currTU.blocks[compID].valid() && TU::getCbf(currTU, (ComponentID)compID) && currTU.mtsIdx[compID] == MTS_SKIP)
2429
59
        {
2430
59
          isTrSkip = true;
2431
59
          break;
2432
59
        }
2433
876k
      }
2434
292k
    }
2435
2436
286k
    if( (!cuCtx.lfnstLastScanPos && !cu.ispMode) || nonZeroCoeffNonTsCorner8x8 || isTrSkip )
2437
270k
    {
2438
270k
      return;
2439
270k
    }
2440
286k
  }
2441
145
  else
2442
145
  {
2443
145
    return;
2444
145
  }
2445
  
2446
16.7k
  unsigned cctx = 0;
2447
16.7k
  if ( CU::isSepTree(cu) ) cctx++;
2448
2449
16.7k
  const uint32_t idxLFNST = cu.lfnstIdx;
2450
16.7k
  assert( idxLFNST < 3 );
2451
16.7k
  m_BinEncoder.encodeBin( idxLFNST ? 1 : 0, Ctx::LFNSTIdx( cctx ) );
2452
2453
16.7k
  if( idxLFNST )
2454
16.3k
  {
2455
16.3k
    m_BinEncoder.encodeBin( (idxLFNST - 1) ? 1 : 0, Ctx::LFNSTIdx(2));
2456
16.3k
  }
2457
2458
16.7k
  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
16.7k
}
2460
2461
2462
void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx, const TransformUnit& tu, ComponentID compID )
2463
941k
{
2464
941k
  unsigned blkPos = cctx.blockPos( cctx.scanPosLast() );
2465
941k
  unsigned posX, posY;
2466
941k
  {
2467
941k
    posY  = blkPos / cctx.width();
2468
941k
    posX  = blkPos - ( posY * cctx.width() );
2469
941k
  }
2470
2471
941k
  unsigned CtxLast;
2472
941k
  unsigned GroupIdxX = g_uiGroupIdx[ posX ];
2473
941k
  unsigned GroupIdxY = g_uiGroupIdx[ posY ];
2474
2475
941k
  unsigned maxLastPosX = cctx.maxLastPosX();
2476
941k
  unsigned maxLastPosY = cctx.maxLastPosY();
2477
2478
941k
  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.19M
  for( CtxLast = 0; CtxLast < GroupIdxX; CtxLast++ )
2485
1.25M
  {
2486
1.25M
    m_BinEncoder.encodeBin( 1, cctx.lastXCtxId( CtxLast ) );
2487
1.25M
  }
2488
941k
  if( GroupIdxX < maxLastPosX )
2489
902k
  {
2490
902k
    m_BinEncoder.encodeBin( 0, cctx.lastXCtxId( CtxLast ) );
2491
902k
  }
2492
2.25M
  for( CtxLast = 0; CtxLast < GroupIdxY; CtxLast++ )
2493
1.31M
  {
2494
1.31M
    m_BinEncoder.encodeBin( 1, cctx.lastYCtxId( CtxLast ) );
2495
1.31M
  }
2496
941k
  if( GroupIdxY < maxLastPosY )
2497
894k
  {
2498
894k
    m_BinEncoder.encodeBin( 0, cctx.lastYCtxId( CtxLast ) );
2499
894k
  }
2500
941k
  if( GroupIdxX > 3 )
2501
2.98k
  {
2502
2.98k
    posX -= g_uiMinInGroup[ GroupIdxX ];
2503
8.63k
    for (int i = ( ( GroupIdxX - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
2504
5.64k
    {
2505
5.64k
      m_BinEncoder.encodeBinEP( ( posX >> i ) & 1 );
2506
5.64k
    }
2507
2.98k
  }
2508
941k
  if( GroupIdxY > 3 )
2509
2.33k
  {
2510
2.33k
    posY -= g_uiMinInGroup[ GroupIdxY ];
2511
6.32k
    for ( int i = ( ( GroupIdxY - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
2512
3.98k
    {
2513
3.98k
      m_BinEncoder.encodeBinEP( ( posY >> i ) & 1 );
2514
3.98k
    }
2515
2.33k
  }
2516
941k
}
2517
2518
2519
void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoeffSig* coeff, const int stateTransTable, int& state )
2520
969k
{
2521
  //===== init =====
2522
969k
  const int   minSubPos   = cctx.minSubPos();
2523
969k
  const bool  isLast      = cctx.isLast();
2524
969k
  int         firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() );
2525
969k
  int         nextSigPos  = firstSigPos;
2526
2527
  //===== encode significant_coeffgroup_flag =====
2528
969k
  if( !isLast && cctx.isNotFirst() )
2529
23.0k
  {
2530
23.0k
    if( cctx.isSigGroup() )
2531
13.8k
    {
2532
13.8k
      m_BinEncoder.encodeBin( 1, cctx.sigGroupCtxId() );
2533
13.8k
    }
2534
9.18k
    else
2535
9.18k
    {
2536
9.18k
      m_BinEncoder.encodeBin( 0, cctx.sigGroupCtxId() );
2537
9.18k
      return;
2538
9.18k
    }
2539
23.0k
  }
2540
2541
  //===== encode absolute values =====
2542
959k
  const int inferSigPos   = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
2543
959k
  int       firstNZPos    = nextSigPos;
2544
959k
  int       lastNZPos     = -1;
2545
959k
  int       remAbsLevel   = -1;
2546
959k
  int       numNonZero    =  0;
2547
959k
  unsigned  signPattern   =  0;
2548
959k
  int       remRegBins    = cctx.remRegBins;
2549
959k
  int       firstPosMode2 = minSubPos - 1;
2550
2551
8.61M
  for( ; nextSigPos >= minSubPos && remRegBins >= 4; nextSigPos-- )
2552
7.65M
  {
2553
7.65M
    const int blkPos     = cctx.blockPos( nextSigPos );
2554
7.65M
    TCoeff    Coeff      = coeff[ blkPos ];
2555
7.65M
    unsigned  sigFlag    = ( Coeff != 0 );
2556
7.65M
    if( numNonZero || nextSigPos != inferSigPos )
2557
6.71M
    {
2558
6.71M
      const unsigned sigCtxId = cctx.sigCtxIdAbsWithAcc( nextSigPos, state );
2559
6.71M
      m_BinEncoder.encodeBin( sigFlag, sigCtxId );
2560
6.71M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2561
6.71M
      remRegBins--;
2562
6.71M
    }
2563
941k
    else if( nextSigPos != cctx.scanPosLast() )
2564
44
    {
2565
44
      cctx.sigCtxIdAbsWithAcc( nextSigPos, state ); // required for setting variables that are needed for gtx/par context selection
2566
44
    }
2567
2568
7.65M
    if( sigFlag )
2569
7.05M
    {
2570
7.05M
      uint8_t ctxOff = cctx.ctxOffsetAbs();
2571
7.05M
      numNonZero++;
2572
7.05M
      firstNZPos  = nextSigPos;
2573
7.05M
      lastNZPos   = std::max<int>( lastNZPos, nextSigPos );
2574
7.05M
      int absLevel= abs( Coeff );
2575
7.05M
      remAbsLevel = absLevel - 1;
2576
2577
7.05M
      if( nextSigPos != cctx.scanPosLast() ) signPattern <<= 1;
2578
7.05M
      if( Coeff < 0 )                        signPattern++;
2579
2580
7.05M
      unsigned gt1 = !!remAbsLevel;
2581
7.05M
      m_BinEncoder.encodeBin( gt1, cctx.greater1CtxIdAbs(ctxOff) );
2582
7.05M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1, cctx.greater1CtxIdAbs(ctxOff) );
2583
7.05M
      remRegBins--;
2584
2585
7.05M
      if( gt1 )
2586
6.09M
      {
2587
6.09M
        remAbsLevel  -= 1;
2588
6.09M
        m_BinEncoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2589
6.09M
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2590
6.09M
        remAbsLevel >>= 1;
2591
2592
6.09M
        remRegBins--;
2593
6.09M
        unsigned gt2 = !!remAbsLevel;
2594
6.09M
        m_BinEncoder.encodeBin(gt2, cctx.greater2CtxIdAbs(ctxOff));
2595
6.09M
        DTRACE(g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2, cctx.greater2CtxIdAbs(ctxOff));
2596
6.09M
        remRegBins--;
2597
6.09M
      }
2598
2599
7.05M
      cctx.absVal1stPass( nextSigPos, std::min<TCoeff>( 4 + ( absLevel & 1 ), absLevel ) );
2600
7.05M
    }
2601
2602
7.65M
    state = ( stateTransTable >> ((state<<2)+((Coeff&1)<<1)) ) & 3;
2603
7.65M
  }
2604
959k
  firstPosMode2 = nextSigPos;
2605
959k
  cctx.remRegBins = remRegBins;
2606
2607
2608
  //===== 2nd PASS: Go-rice codes =====
2609
8.61M
  for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- )
2610
7.65M
  {
2611
7.65M
    unsigned absLevel = abs( coeff[cctx.blockPos( scanPos )] );
2612
2613
7.65M
    if( absLevel >= 4 )
2614
4.84M
    {
2615
4.84M
      int      sumAll   = cctx.templateAbsSum( scanPos, coeff, 4 );
2616
4.84M
      unsigned ricePar  = g_auiGoRiceParsCoeff[sumAll];
2617
4.84M
      unsigned rem      = ( absLevel - 4 ) >> 1;
2618
4.84M
      m_BinEncoder.encodeRemAbsEP( rem, ricePar, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2619
4.84M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
2620
4.84M
    }
2621
7.65M
  }
2622
2623
  //===== coeff bypass ====
2624
1.06M
  for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
2625
104k
  {
2626
104k
    TCoeff    Coeff     = coeff[ cctx.blockPos( scanPos ) ];
2627
104k
    unsigned  absLevel  = abs( Coeff );
2628
104k
    int       sumAll    = cctx.templateAbsSum(scanPos, coeff, 0);
2629
104k
    int       rice      = g_auiGoRiceParsCoeff[sumAll];
2630
104k
    int       pos0      = g_auiGoRicePosCoeff0(state, rice);
2631
104k
    unsigned  rem       = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel );
2632
104k
    m_BinEncoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2633
104k
    DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
2634
104k
    state = ( stateTransTable >> ((state<<2)+((absLevel&1)<<1)) ) & 3;
2635
104k
    if( absLevel )
2636
103k
    {
2637
103k
      numNonZero++;
2638
103k
      firstNZPos = scanPos;
2639
103k
      lastNZPos   = std::max<int>( lastNZPos, scanPos );
2640
103k
      signPattern <<= 1;
2641
103k
      if( Coeff < 0 ) signPattern++;
2642
103k
    }
2643
104k
  }
2644
2645
  //===== encode sign's =====
2646
959k
  unsigned numSigns = numNonZero;
2647
959k
  if( cctx.hideSign( firstNZPos, lastNZPos ) )
2648
0
  {
2649
0
    numSigns    --;
2650
0
    signPattern >>= 1;
2651
0
  }
2652
959k
  m_BinEncoder.encodeBinsEP( signPattern, numSigns );
2653
959k
}
2654
2655
2656
void CABACWriter::residual_codingTS( const TransformUnit& tu, ComponentID compID )
2657
70.1k
{
2658
70.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 );
2659
2660
  // init coeff coding context
2661
70.1k
  CoeffCodingContext  cctx    ( tu, compID, false, tu.cu->bdpcmM[toChannelType(compID)] );
2662
70.1k
  const TCoeffSig*    coeff   = tu.getCoeffs( compID ).buf;
2663
70.1k
  int maxCtxBins = (cctx.maxNumCoeff() * 7) >> 2;
2664
70.1k
  cctx.remRegBins = maxCtxBins;
2665
2666
  // determine and set last coeff position and sig group flags
2667
70.1k
  std::bitset<MLS_GRP_NUM> sigGroupFlags;
2668
6.56M
  for( int scanPos = 0; scanPos < cctx.maxNumCoeff(); scanPos++)
2669
6.49M
  {
2670
6.49M
    unsigned blkPos = cctx.blockPos( scanPos );
2671
6.49M
    if( coeff[blkPos] )
2672
692k
    {
2673
692k
      sigGroupFlags.set( scanPos >> cctx.log2CGSize() );
2674
692k
    }
2675
6.49M
  }
2676
2677
  // code subblocks
2678
475k
  for( int subSetId = 0; subSetId <= ( cctx.maxNumCoeff() - 1 ) >> cctx.log2CGSize(); subSetId++ )
2679
405k
  {
2680
405k
    cctx.initSubblock         ( subSetId, sigGroupFlags[subSetId] );
2681
405k
    residual_coding_subblockTS( cctx, coeff );
2682
405k
  }
2683
70.1k
}
2684
2685
2686
void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TCoeffSig* coeff )
2687
405k
{
2688
  //===== init =====
2689
405k
  const int   minSubPos   = cctx.maxSubPos();
2690
405k
  int         firstSigPos = cctx.minSubPos();
2691
405k
  int         nextSigPos  = firstSigPos;
2692
2693
  //===== encode significant_coeffgroup_flag =====
2694
405k
  if( !cctx.isLastSubSet() || !cctx.only1stSigGroup() )
2695
395k
  {
2696
395k
    if( cctx.isSigGroup() )
2697
152k
    {
2698
152k
        m_BinEncoder.encodeBin( 1, cctx.sigGroupCtxId( true ) );
2699
152k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 1, cctx.sigGroupCtxId() );
2700
152k
    }
2701
242k
    else
2702
242k
    {
2703
242k
        m_BinEncoder.encodeBin( 0, cctx.sigGroupCtxId( true ) );
2704
242k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 0, cctx.sigGroupCtxId() );
2705
242k
      return;
2706
242k
    }
2707
395k
  }
2708
2709
  //===== encode absolute values =====
2710
163k
  const int inferSigPos   = minSubPos;
2711
163k
  int       remAbsLevel   = -1;
2712
163k
  int       numNonZero    =  0;
2713
2714
163k
  int rightPixel, belowPixel, modAbsCoeff;
2715
2716
163k
  int lastScanPosPass1 = -1;
2717
163k
  int lastScanPosPass2 = -1;
2718
2.56M
  for (; nextSigPos <= minSubPos && cctx.remRegBins >= 4; nextSigPos++)
2719
2.39M
  {
2720
2.39M
    TCoeff    Coeff      = coeff[ cctx.blockPos( nextSigPos ) ];
2721
2.39M
    unsigned  sigFlag    = ( Coeff != 0 );
2722
2.39M
    if( numNonZero || nextSigPos != inferSigPos )
2723
2.39M
    {
2724
2.39M
      const unsigned sigCtxId = cctx.sigCtxIdAbsTS( nextSigPos, coeff );
2725
2.39M
      m_BinEncoder.encodeBin( sigFlag, sigCtxId );
2726
2.39M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2727
2.39M
      cctx.remRegBins--;
2728
2.39M
    }
2729
2730
2.39M
    if( sigFlag )
2731
641k
    {
2732
      //===== encode sign's =====
2733
641k
      int sign = Coeff < 0;
2734
641k
      const unsigned signCtxId = cctx.signCtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm());
2735
641k
      m_BinEncoder.encodeBin(sign, signCtxId);
2736
641k
      cctx.remRegBins--;
2737
641k
      numNonZero++;
2738
641k
      cctx.neighTS(rightPixel, belowPixel, nextSigPos, coeff);
2739
641k
      modAbsCoeff = cctx.deriveModCoeff(rightPixel, belowPixel, abs(Coeff), cctx.bdpcm());
2740
641k
      remAbsLevel = modAbsCoeff - 1;
2741
2742
641k
      unsigned gt1 = !!remAbsLevel;
2743
641k
      const unsigned gt1CtxId = cctx.lrg1CtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm());
2744
641k
      m_BinEncoder.encodeBin(gt1, gt1CtxId);
2745
641k
      DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_gt1_flag() bin=%d ctx=%d\n", gt1, gt1CtxId);
2746
641k
      cctx.remRegBins--;
2747
2748
641k
      if( gt1 )
2749
632k
      {
2750
632k
        remAbsLevel  -= 1;
2751
632k
        m_BinEncoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbsTS() );
2752
632k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbsTS() );
2753
632k
        cctx.remRegBins--;
2754
632k
      }
2755
641k
    }
2756
2.39M
    lastScanPosPass1 = nextSigPos;
2757
2.39M
  }
2758
2759
163k
  int cutoffVal = 2;
2760
163k
  int numGtBins = 4;
2761
2762
2.35M
  for (int scanPos = firstSigPos; scanPos <= minSubPos && cctx.remRegBins >= 4; scanPos++)
2763
2.19M
  {
2764
2.19M
    unsigned absLevel;
2765
2.19M
    cctx.neighTS(rightPixel, belowPixel, scanPos, coeff);
2766
2.19M
    absLevel = cctx.deriveModCoeff(rightPixel, belowPixel, abs(coeff[cctx.blockPos(scanPos)]), cctx.bdpcm());
2767
2.19M
    cutoffVal = 2;
2768
10.9M
    for (int i = 0; i < numGtBins; i++)
2769
8.76M
    {
2770
8.76M
      if (absLevel >= cutoffVal)
2771
1.51M
      {
2772
1.51M
        unsigned gt2 = (absLevel >= (cutoffVal + 2));
2773
1.51M
        m_BinEncoder.encodeBin(gt2, cctx.greaterXCtxIdAbsTS(cutoffVal >> 1));
2774
1.51M
        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));
2775
1.51M
        cctx.remRegBins--;
2776
1.51M
      }
2777
8.76M
      cutoffVal += 2;
2778
8.76M
    }
2779
2.19M
    lastScanPosPass2 = scanPos;
2780
2.19M
  }
2781
2782
  //===== coeff bypass ====
2783
2.77M
  for( int scanPos = firstSigPos; scanPos <= minSubPos; scanPos++ )
2784
2.61M
  {
2785
2.61M
    unsigned absLevel;
2786
2.61M
    cctx.neighTS(rightPixel, belowPixel, scanPos, coeff);
2787
2.61M
    cutoffVal = (scanPos <= lastScanPosPass2 ? 10 : (scanPos <= lastScanPosPass1 ? 2 : 0));
2788
2.61M
    absLevel = cctx.deriveModCoeff(rightPixel, belowPixel, abs(coeff[cctx.blockPos(scanPos)]), cctx.bdpcm()||!cutoffVal);
2789
2.61M
    if( absLevel >= cutoffVal )
2790
545k
    {
2791
      //int       rice = cctx.templateAbsSumTS( scanPos, coeff );
2792
545k
      int       rice = 1;
2793
545k
      unsigned  rem = scanPos <= lastScanPosPass1 ? (absLevel - cutoffVal) >> 1 : absLevel;
2794
545k
      m_BinEncoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2795
545k
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_rem_val() bin=%d ctx=%d sp=%d\n", rem, rice, scanPos );
2796
2797
545k
      if (absLevel && scanPos > lastScanPosPass1)
2798
50.8k
      {
2799
50.8k
        int sign = coeff[cctx.blockPos(scanPos)] < 0;
2800
50.8k
        m_BinEncoder.encodeBinEP(sign);
2801
50.8k
      }
2802
545k
    }
2803
2.61M
  }
2804
163k
}
2805
2806
2807
//================================================================================
2808
//  helper functions
2809
//--------------------------------------------------------------------------------
2810
//    void  unary_max_symbol  ( symbol, ctxId0, ctxIdN, maxSymbol )
2811
//    void  unary_max_eqprob  ( symbol,                 maxSymbol )
2812
//    void  exp_golomb_eqprob ( symbol, count )
2813
//================================================================================
2814
2815
void CABACWriter::unary_max_symbol( unsigned symbol, unsigned ctxId0, unsigned ctxIdN, unsigned maxSymbol )
2816
3.91k
{
2817
3.91k
  CHECK( symbol > maxSymbol, "symbol > maxSymbol" );
2818
3.91k
  const unsigned totalBinsToWrite = std::min( symbol + 1, maxSymbol );
2819
7.83k
  for( unsigned binsWritten = 0; binsWritten < totalBinsToWrite; ++binsWritten )
2820
3.91k
  {
2821
3.91k
    const unsigned nextBin = symbol > binsWritten;
2822
3.91k
    m_BinEncoder.encodeBin( nextBin, binsWritten == 0 ? ctxId0 : ctxIdN );
2823
3.91k
  }
2824
3.91k
}
2825
2826
2827
void CABACWriter::unary_max_eqprob( unsigned symbol, unsigned maxSymbol )
2828
243k
{
2829
243k
  if( maxSymbol == 0 )
2830
0
  {
2831
0
    return;
2832
0
  }
2833
243k
  bool     codeLast = ( maxSymbol > symbol );
2834
243k
  unsigned bins     = 0;
2835
243k
  unsigned numBins  = 0;
2836
243k
  while( symbol-- )
2837
375
  {
2838
375
    bins   <<= 1;
2839
375
    bins   ++;
2840
375
    numBins++;
2841
375
  }
2842
243k
  if( codeLast )
2843
243k
  {
2844
243k
    bins  <<= 1;
2845
243k
    numBins++;
2846
243k
  }
2847
243k
  CHECK(!( numBins <= 32 ), "Unspecified error");
2848
243k
  m_BinEncoder.encodeBinsEP( bins, numBins );
2849
243k
}
2850
2851
2852
void CABACWriter::exp_golomb_eqprob( unsigned symbol, unsigned count )
2853
0
{
2854
0
  unsigned bins    = 0;
2855
0
  unsigned numBins = 0;
2856
0
  while( symbol >= (unsigned)(1<<count) )
2857
0
  {
2858
0
    bins <<= 1;
2859
0
    bins++;
2860
0
    numBins++;
2861
0
    symbol -= 1 << count;
2862
0
    count++;
2863
0
  }
2864
0
  bins <<= 1;
2865
0
  numBins++;
2866
0
  bins = (bins << count) | symbol;
2867
0
  numBins += count;
2868
0
  CHECK(!( numBins <= 32 ), "Unspecified error");
2869
0
  m_BinEncoder.encodeBinsEP( bins, numBins );
2870
0
}
2871
2872
2873
void CABACWriter::codeAlfCtuEnabled( CodingStructure& cs, ChannelType channel, AlfParam* alfParam, const int numCtus )
2874
16.0k
{
2875
16.0k
  if( isLuma( channel ) )
2876
2.59k
  {
2877
2.59k
    if (alfParam->alfEnabled[COMP_Y])
2878
2.59k
      codeAlfCtuEnabled( cs, COMP_Y, alfParam, numCtus );
2879
2.59k
  }
2880
13.4k
  else
2881
13.4k
  {
2882
13.4k
    if (alfParam->alfEnabled[COMP_Cb])
2883
13.4k
      codeAlfCtuEnabled( cs, COMP_Cb, alfParam, numCtus );
2884
13.4k
    if (alfParam->alfEnabled[COMP_Cr])
2885
13.4k
      codeAlfCtuEnabled( cs, COMP_Cr, alfParam, numCtus );
2886
13.4k
  }
2887
16.0k
}
2888
2889
2890
void CABACWriter::codeAlfCtuEnabled( CodingStructure& cs, ComponentID compID, AlfParam* alfParam, const int numCtus )
2891
29.5k
{
2892
144k
  for( int ctuIdx = 0; ctuIdx < numCtus; ctuIdx++ )
2893
114k
  {
2894
114k
    codeAlfCtuEnabledFlag( cs, ctuIdx, compID );
2895
114k
  }
2896
29.5k
}
2897
2898
2899
void CABACWriter::codeAlfCtuEnabledFlag( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx)
2900
412k
{
2901
412k
  CHECKD( !cs.sps->alfEnabled, "ALF is disabled in SPS" ); 
2902
2903
412k
  const PreCalcValues& pcv = *cs.pcv;
2904
412k
  int                 frame_width_in_ctus = pcv.widthInCtus;
2905
412k
  int                 ry = ctuRsAddr / frame_width_in_ctus;
2906
412k
  int                 rx = ctuRsAddr - ry * frame_width_in_ctus;
2907
412k
  const Position      pos( rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize );
2908
412k
  const uint32_t      curSliceIdx = cs.slice->independentSliceIdx;
2909
412k
  const uint32_t      curTileIdx  = cs.pps->getTileIdx( pos );
2910
412k
  bool                leftAvail   = cs.getCURestricted( pos.offset( -(int)pcv.maxCUSize, 0 ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2911
412k
  bool                aboveAvail  = cs.getCURestricted( pos.offset( 0, -(int)pcv.maxCUSize ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2912
2913
412k
  int leftCTUAddr = leftAvail ? ctuRsAddr - 1 : -1;
2914
412k
  int aboveCTUAddr = aboveAvail ? ctuRsAddr - frame_width_in_ctus : -1;
2915
2916
412k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compIdx ].data();
2917
412k
  int ctx = 0;
2918
412k
  ctx += leftCTUAddr > -1 ? ( ctbAlfFlag[leftCTUAddr] ? 1 : 0 ) : 0;
2919
412k
  ctx += aboveCTUAddr > -1 ? ( ctbAlfFlag[aboveCTUAddr] ? 1 : 0 ) : 0;
2920
412k
  m_BinEncoder.encodeBin( ctbAlfFlag[ctuRsAddr], Ctx::ctbAlfFlag( compIdx * 3 + ctx ) );
2921
412k
}
2922
2923
2924
void CABACWriter::codeCcAlfFilterControlIdc(uint8_t idcVal, CodingStructure &cs, const ComponentID compID,
2925
                                            const int curIdx, const uint8_t *filterControlIdc, Position lumaPos,
2926
                                            const int filterCount)
2927
0
{
2928
0
  CHECK(idcVal > filterCount, "Filter index is too large");
2929
2930
0
  const uint32_t curSliceIdx    = cs.slice->independentSliceIdx;
2931
0
  const uint32_t curTileIdx     = cs.pps->getTileIdx( lumaPos );
2932
0
  Position       leftLumaPos    = lumaPos.offset(-(int)cs.pcv->maxCUSize, 0);
2933
0
  Position       aboveLumaPos   = lumaPos.offset(0, -(int)cs.pcv->maxCUSize);
2934
0
  bool           leftAvail      = cs.getCURestricted( leftLumaPos,  lumaPos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2935
0
  bool           aboveAvail     = cs.getCURestricted( aboveLumaPos, lumaPos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2936
0
  int            ctxt           = 0;
2937
2938
0
  if (leftAvail)
2939
0
  {
2940
0
    ctxt += ( filterControlIdc[curIdx - 1]) ? 1 : 0;
2941
0
  }
2942
0
  if (aboveAvail)
2943
0
  {
2944
0
    ctxt += (filterControlIdc[curIdx - cs.pcv->widthInCtus]) ? 1 : 0;
2945
0
  }
2946
0
  ctxt += ( compID == COMP_Cr ) ? 3 : 0;
2947
2948
0
  m_BinEncoder.encodeBin( ( idcVal == 0 ) ? 0 : 1, Ctx::CcAlfFilterControlFlag( ctxt ) ); // ON/OFF flag is context coded
2949
0
  if ( idcVal > 0 )
2950
0
  {
2951
0
    int val = (idcVal - 1);
2952
0
    while ( val )
2953
0
    {
2954
0
      m_BinEncoder.encodeBinEP( 1 );
2955
0
      val--;
2956
0
    }
2957
0
    if ( idcVal < filterCount )
2958
0
    {
2959
0
      m_BinEncoder.encodeBinEP( 0 );
2960
0
    }
2961
0
  }
2962
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 );
2963
0
}
2964
2965
2966
void CABACWriter::mip_flag( const CodingUnit& cu )
2967
1.27M
{
2968
1.27M
  if( !cu.Y().valid() )
2969
0
  {
2970
0
    return;
2971
0
  }
2972
1.27M
  if( !cu.cs->sps->MIP )
2973
0
  {
2974
0
    return;
2975
0
  }
2976
2977
1.27M
  unsigned ctxId = DeriveCtx::CtxMipFlag( cu );
2978
1.27M
  m_BinEncoder.encodeBin( cu.mipFlag, Ctx::MipFlag( ctxId ) );
2979
1.27M
  DTRACE( g_trace_ctx, D_SYNTAX, "mip_flag() pos=(%d,%d) mode=%d\n", cu.lumaPos().x, cu.lumaPos().y, cu.mipFlag ? 1 : 0 );
2980
1.27M
}
2981
2982
2983
void CABACWriter::mip_pred_modes( const CodingUnit& cu )
2984
1.64k
{
2985
1.64k
  if( !cu.Y().valid() )
2986
0
  {
2987
0
    return;
2988
0
  }
2989
2990
1.64k
  mip_pred_mode( cu );
2991
1.64k
}
2992
2993
2994
void CABACWriter::mip_pred_mode( const CodingUnit& cu )
2995
300k
{
2996
300k
  m_BinEncoder.encodeBinEP( (cu.mipTransposedFlag ? 1 : 0) );
2997
2998
300k
  const int numModes = getNumModesMip( cu.Y() );
2999
300k
  CHECKD( cu.intraDir[CH_L] < 0 || cu.intraDir[CH_L] >= numModes, "Invalid MIP mode" );
3000
300k
  xWriteTruncBinCode( cu.intraDir[CH_L], numModes );
3001
3002
300k
  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 );
3003
300k
}
3004
3005
3006
void CABACWriter::codeAlfCtuFilterIndex(CodingStructure& cs, uint32_t ctuRsAddr)
3007
81.0k
{
3008
81.0k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ COMP_Y ].data();
3009
81.0k
  if (!ctbAlfFlag[ctuRsAddr])
3010
0
  {
3011
0
    return;
3012
0
  }
3013
3014
81.0k
  const short* alfCtbFilterIndex = cs.slice->pic->m_alfCtbFilterIndex.data();
3015
81.0k
  const unsigned filterSetIdx = alfCtbFilterIndex[ctuRsAddr];
3016
81.0k
  unsigned numAps = cs.slice->numAps;
3017
81.0k
  unsigned numAvailableFiltSets = numAps + NUM_FIXED_FILTER_SETS;
3018
81.0k
  if (numAvailableFiltSets > NUM_FIXED_FILTER_SETS)
3019
16.2k
  {
3020
16.2k
    int useTemporalFilt = (filterSetIdx >= NUM_FIXED_FILTER_SETS) ? 1 : 0;
3021
16.2k
    m_BinEncoder.encodeBin(useTemporalFilt, Ctx::AlfUseTemporalFilt());
3022
16.2k
    if (useTemporalFilt)
3023
16.2k
    {
3024
16.2k
      CHECK((filterSetIdx - NUM_FIXED_FILTER_SETS) >= (numAvailableFiltSets - NUM_FIXED_FILTER_SETS), "temporal non-latest set");
3025
16.2k
      if (numAps > 1)
3026
0
      {
3027
0
        xWriteTruncBinCode(filterSetIdx - NUM_FIXED_FILTER_SETS, numAvailableFiltSets - NUM_FIXED_FILTER_SETS);
3028
0
      }
3029
16.2k
    }
3030
0
    else
3031
0
    {
3032
0
      CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set larger than temporal");
3033
0
      xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS);
3034
0
    }
3035
16.2k
  }
3036
64.8k
  else
3037
64.8k
  {
3038
64.8k
    CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set numavail < num_fixed");
3039
64.8k
    xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS);
3040
64.8k
  }
3041
81.0k
}
3042
3043
3044
void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ChannelType channel, AlfParam* alfParam, const int numCtus )
3045
16.0k
{
3046
16.0k
  if( isChroma( channel ) )
3047
13.4k
  {
3048
13.4k
    if (alfParam->alfEnabled[COMP_Cb])
3049
13.4k
      codeAlfCtuAlternatives( cs, COMP_Cb, alfParam, numCtus );
3050
13.4k
    if (alfParam->alfEnabled[COMP_Cr])
3051
13.4k
      codeAlfCtuAlternatives( cs, COMP_Cr, alfParam, numCtus );
3052
13.4k
  }
3053
16.0k
}
3054
3055
3056
void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ComponentID compID, AlfParam* alfParam, const int numCtus)
3057
26.9k
{
3058
26.9k
  if( compID == COMP_Y )
3059
0
    return;
3060
26.9k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compID ].data();
3061
3062
133k
  for( int ctuIdx = 0; ctuIdx < numCtus; ctuIdx++ )
3063
106k
  {
3064
106k
    if( ctbAlfFlag[ctuIdx] )
3065
106k
    {
3066
106k
      codeAlfCtuAlternative( cs, ctuIdx, compID, alfParam );
3067
106k
    }
3068
106k
  }
3069
26.9k
}
3070
3071
3072
void CABACWriter::codeAlfCtuAlternative( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx, const AlfParam* alfParam)
3073
543k
{
3074
543k
  if( compIdx == COMP_Y )
3075
0
    return;
3076
3077
543k
  {
3078
543k
    const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compIdx ].data();
3079
3080
543k
    if( ctbAlfFlag[ctuRsAddr] )
3081
543k
    {
3082
543k
      const int numAlts = alfParam->numAlternativesChroma;
3083
543k
      const uint8_t* ctbAlfAlternative = cs.slice->pic->m_alfCtuAlternative[compIdx].data();
3084
543k
      unsigned numOnes = ctbAlfAlternative[ctuRsAddr];
3085
543k
      assert( ctbAlfAlternative[ctuRsAddr] < numAlts );
3086
1.55M
      for( int i = 0; i < numOnes; ++i )
3087
1.01M
        m_BinEncoder.encodeBin( 1, Ctx::ctbAlfAlternative( compIdx-1 ) );
3088
543k
      if( numOnes < numAlts-1 )
3089
410k
        m_BinEncoder.encodeBin( 0, Ctx::ctbAlfAlternative( compIdx-1 ) );
3090
543k
    }
3091
543k
  }
3092
543k
}
3093
3094
} // namespace vvenc
3095
3096
//! \}
3097