Coverage Report

Created: 2026-07-30 06:27

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