Coverage Report

Created: 2026-09-02 06:43

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
11.5k
{
65
11.5k
  int       qp                = slice.sliceQp;
66
11.5k
  SliceType sliceType         = slice.sliceType;
67
11.5k
  SliceType encCABACTableIdx  = slice.encCABACTableIdx;
68
11.5k
  if( !slice.isIntra() && (encCABACTableIdx==VVENC_B_SLICE || encCABACTableIdx==VVENC_P_SLICE) && slice.pps->cabacInitPresent )
69
0
  {
70
0
    sliceType = encCABACTableIdx;
71
0
  }
72
11.5k
  m_BinEncoder.reset( qp, (int)sliceType );
73
11.5k
}
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.14k
{
145
1.14k
  m_BinEncoder.encodeBinTrm ( 1 );
146
1.14k
  m_BinEncoder.finish       ();
147
1.14k
}
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.18k
{
158
7.18k
  CUCtx cuCtx( qps[CH_L] );
159
7.18k
  Partitioner *partitioner = &m_partitioner[0];
160
161
7.18k
  partitioner->initCtu( area, CH_L, *cs.slice );
162
163
7.18k
  if( !skipSao )
164
3.59k
  {
165
3.59k
    sao( *cs.slice, ctuRsAddr );
166
3.59k
  }
167
168
7.18k
  if (!skipAlf)
169
3.59k
  {
170
14.3k
    for (int compIdx = 0; compIdx < MAX_NUM_COMP; compIdx++)
171
10.7k
    {
172
10.7k
      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
10.7k
    }
185
3.59k
  }
186
187
7.18k
  if ( !skipAlf )
188
3.59k
  {
189
10.7k
    for ( int compIdx = 1; compIdx < getNumberValidComponents( cs.pcv->chrFormat ); compIdx++ )
190
7.18k
    {
191
7.18k
      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.18k
    }
203
3.59k
  }
204
205
7.18k
  if ( CS::isDualITree(cs) && cs.pcv->chrFormat != CHROMA_400 && cs.pcv->maxCUSize > 64 )
206
7.18k
  {
207
7.18k
    CUCtx chromaCuCtx(qps[CH_C]);
208
7.18k
    Partitioner *chromaPartitioner = &m_partitioner[1];
209
7.18k
    chromaPartitioner->initCtu(area, CH_C, *cs.slice);
210
7.18k
    coding_tree(cs, *partitioner, cuCtx, chromaPartitioner, &chromaCuCtx);
211
7.18k
    qps[CH_L] = cuCtx.qp;
212
7.18k
    qps[CH_C] = chromaCuCtx.qp;
213
7.18k
  }
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.18k
}
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.59k
{
239
3.59k
  const SPS& sps = *slice.sps;
240
3.59k
  if( !sps.saoEnabled )
241
0
  {
242
0
    return;
243
0
  }
244
245
3.59k
  CodingStructure&     cs                     = *slice.pic->cs;
246
3.59k
  const PreCalcValues& pcv                    = *cs.pcv;
247
3.59k
  const SAOBlkParam&  sao_ctu_pars            = cs.picture->getSAO()[ctuRsAddr];
248
3.59k
  bool                slice_sao_luma_flag     = ( slice.saoEnabled[ CH_L ] );
249
3.59k
  bool                slice_sao_chroma_flag   = ( slice.saoEnabled[ CH_C ] && sps.chromaFormatIdc != CHROMA_400 );
250
3.59k
  if( !slice_sao_luma_flag && !slice_sao_chroma_flag )
251
0
  {
252
0
    return;
253
0
  }
254
255
3.59k
  bool                sliceEnabled[3]         = { slice_sao_luma_flag, slice_sao_chroma_flag, slice_sao_chroma_flag };
256
3.59k
  int                 frame_width_in_ctus     = pcv.widthInCtus;
257
3.59k
  int                 ry                      = ctuRsAddr      / frame_width_in_ctus;
258
3.59k
  int                 rx                      = ctuRsAddr - ry * frame_width_in_ctus;
259
3.59k
  const Position      pos                     ( rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize );
260
3.59k
  const unsigned      curSliceIdx             = slice.independentSliceIdx;
261
3.59k
  const unsigned      curTileIdx              = cs.pps->getTileIdx( pos );
262
3.59k
  bool                leftMergeAvail          = cs.getCURestricted( pos.offset( -(int)pcv.maxCUSize, 0  ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
263
3.59k
  bool                aboveMergeAvail         = cs.getCURestricted( pos.offset( 0, -(int)pcv.maxCUSize ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
264
3.59k
  sao_block_pars( sao_ctu_pars, sps.bitDepths, sliceEnabled, leftMergeAvail, aboveMergeAvail, false );
265
3.59k
}
266
267
268
void CABACWriter::sao_block_pars( const SAOBlkParam& saoPars, const BitDepths& bitDepths, const bool* sliceEnabled, bool leftMergeAvail, bool aboveMergeAvail, bool onlyEstMergeInfo )
269
13.9k
{
270
13.9k
  bool isLeftMerge  = false;
271
13.9k
  bool isAboveMerge = false;
272
13.9k
  if( leftMergeAvail )
273
6.99k
  {
274
    // sao_merge_left_flag
275
6.99k
    isLeftMerge   = ( saoPars[COMP_Y].modeIdc == SAO_MODE_MERGE && saoPars[COMP_Y].typeIdc == SAO_MERGE_LEFT );
276
6.99k
    m_BinEncoder.encodeBin( (isLeftMerge), Ctx::SaoMergeFlag() );
277
6.99k
  }
278
13.9k
  if( aboveMergeAvail && !isLeftMerge )
279
5.79k
  {
280
    // sao_merge_above_flag
281
5.79k
    isAboveMerge  = ( saoPars[COMP_Y].modeIdc == SAO_MODE_MERGE && saoPars[COMP_Y].typeIdc == SAO_MERGE_ABOVE );
282
5.79k
    m_BinEncoder.encodeBin( (isAboveMerge), Ctx::SaoMergeFlag() );
283
5.79k
  }
284
13.9k
  if( onlyEstMergeInfo )
285
3.59k
  {
286
3.59k
    return; //only for RDO
287
3.59k
  }
288
10.3k
  if( !isLeftMerge && !isAboveMerge )
289
4.73k
  {
290
    // explicit parameters
291
18.9k
    for( int compIdx=0; compIdx < MAX_NUM_COMP; compIdx++ )
292
14.2k
    {
293
14.2k
      sao_offset_pars( saoPars[compIdx], ComponentID(compIdx), sliceEnabled[compIdx], bitDepths[ toChannelType(ComponentID(compIdx)) ] );
294
14.2k
    }
295
4.73k
  }
296
10.3k
}
297
298
299
void CABACWriter::sao_offset_pars( const SAOOffset& ctbPars, ComponentID compID, bool sliceEnabled, int bitDepth )
300
78.8k
{
301
78.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
78.8k
  const bool isFirstCompOfChType = ( getFirstComponentOfChannel( toChannelType(compID) ) == compID );
307
308
78.8k
  if( isFirstCompOfChType )
309
52.5k
  {
310
    // sao_type_idx_luma / sao_type_idx_chroma
311
52.5k
    if( ctbPars.modeIdc == SAO_MODE_OFF )
312
16.6k
    {
313
16.6k
      m_BinEncoder.encodeBin  ( 0, Ctx::SaoTypeIdx() );
314
16.6k
    }
315
35.9k
    else if( ctbPars.typeIdc == SAO_TYPE_BO )
316
7.23k
    {
317
7.23k
      m_BinEncoder.encodeBin  ( 1, Ctx::SaoTypeIdx() );
318
7.23k
      m_BinEncoder.encodeBinEP( 0 );
319
7.23k
    }
320
28.7k
    else
321
28.7k
    {
322
28.7k
      CHECK(!( ctbPars.typeIdc < SAO_TYPE_START_BO ), "Unspecified error");
323
28.7k
      m_BinEncoder.encodeBin  ( 1, Ctx::SaoTypeIdx() );
324
28.7k
      m_BinEncoder.encodeBinEP( 1 );
325
28.7k
    }
326
52.5k
  }
327
328
78.8k
  if( ctbPars.modeIdc == SAO_MODE_NEW )
329
53.8k
  {
330
53.8k
    const int maxOffsetQVal = SampleAdaptiveOffset::getMaxOffsetQVal( bitDepth );
331
53.8k
    int       numClasses    = ( ctbPars.typeIdc == SAO_TYPE_BO ? 4 : NUM_SAO_EO_CLASSES );
332
53.8k
    int       k             = 0;
333
53.8k
    int       offset[4];
334
312k
    for( int i = 0; i < numClasses; i++ )
335
258k
    {
336
258k
      if( ctbPars.typeIdc != SAO_TYPE_BO && i == SAO_CLASS_EO_PLAIN )
337
43.0k
      {
338
43.0k
        continue;
339
43.0k
      }
340
215k
      int classIdx = ( ctbPars.typeIdc == SAO_TYPE_BO ? ( ctbPars.typeAuxInfo + i ) % NUM_SAO_BO_CLASSES : i );
341
215k
      offset[k++]  = ctbPars.offset[classIdx];
342
215k
    }
343
344
    // sao_offset_abs
345
269k
    for( int i = 0; i < 4; i++ )
346
215k
    {
347
215k
      unsigned absOffset = ( offset[i] < 0 ? -offset[i] : offset[i] );
348
215k
      unary_max_eqprob( absOffset, maxOffsetQVal );
349
215k
    }
350
351
    // band offset mode
352
53.8k
    if( ctbPars.typeIdc == SAO_TYPE_BO )
353
10.8k
    {
354
      // sao_offset_sign
355
54.1k
      for( int i = 0; i < 4; i++ )
356
43.2k
      {
357
43.2k
        if( offset[i] )
358
309
        {
359
309
          m_BinEncoder.encodeBinEP( (offset[i] < 0) );
360
309
        }
361
43.2k
      }
362
      // sao_band_position
363
10.8k
      m_BinEncoder.encodeBinsEP( ctbPars.typeAuxInfo, NUM_SAO_BO_CLASSES_LOG2 );
364
10.8k
    }
365
    // edge offset mode
366
43.0k
    else
367
43.0k
    {
368
43.0k
      if( isFirstCompOfChType )
369
28.7k
      {
370
        // sao_eo_class_luma / sao_eo_class_chroma
371
28.7k
        CHECK( ctbPars.typeIdc - SAO_TYPE_START_EO < 0, "sao edge offset class is outside valid range" );
372
28.7k
        m_BinEncoder.encodeBinsEP( ctbPars.typeIdc - SAO_TYPE_START_EO, NUM_SAO_EO_TYPES_LOG2 );
373
28.7k
      }
374
43.0k
    }
375
53.8k
  }
376
78.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
155k
{
389
155k
  const PPS      &pps         = *cs.pps;
390
155k
  const UnitArea& currArea    = partitioner.currArea();
391
155k
  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
155k
  if( pps.useDQP && partitioner.currQgEnable() && !isChroma( partitioner.chType ) )
396
13.4k
  {
397
13.4k
    cuCtx.qgStart    = true;
398
13.4k
    cuCtx.isDQPCoded          = false;
399
13.4k
  }
400
155k
  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
155k
  if (CS::isDualITree(cs) && pPartitionerChroma != nullptr)
406
7.18k
  {
407
7.18k
    if (pps.useDQP && pPartitionerChroma->currQgEnable())
408
7.18k
    {
409
7.18k
      pCuCtxChroma->qgStart    = true;
410
7.18k
      pCuCtxChroma->isDQPCoded = false;
411
7.18k
    }
412
7.18k
    if (cs.slice->chromaQpAdjEnabled && pPartitionerChroma->currQgChromaEnable())
413
0
    {
414
0
      pCuCtxChroma->isChromaQpAdjCoded = false;
415
0
    }
416
7.18k
  }
417
418
155k
  determineNeighborCus( cs, partitioner.currArea(), partitioner.chType, partitioner.treeType );
419
420
155k
  const PartSplit splitMode = CU::getSplitAtDepth( cu, partitioner.currDepth );
421
422
155k
  split_cu_mode( splitMode, cs, partitioner );
423
424
155k
  CHECK( !partitioner.canSplit( splitMode, cs ), "The chosen split mode is invalid!" );
425
426
155k
  if( splitMode != CU_DONT_SPLIT )
427
79.8k
  {
428
79.8k
    if (CS::isDualITree(cs) && pPartitionerChroma != nullptr && (partitioner.currArea().lwidth() >= 64 || partitioner.currArea().lheight() >= 64))
429
7.18k
    {
430
7.18k
      partitioner.splitCurrArea(CU_QUAD_SPLIT, cs);
431
7.18k
      pPartitionerChroma->splitCurrArea(CU_QUAD_SPLIT, cs);
432
7.18k
      bool beContinue = true;
433
7.18k
      bool lumaContinue = true;
434
7.18k
      bool chromaContinue = true;
435
436
35.9k
      while (beContinue)
437
28.7k
      {
438
28.7k
        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
28.7k
        else
450
28.7k
        {
451
          //dual tree coding under 64x64 block
452
28.7k
          if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos()))
453
19.0k
          {
454
19.0k
            coding_tree(cs, partitioner, cuCtx);
455
19.0k
          }
456
28.7k
          lumaContinue = partitioner.nextPart(cs);
457
28.7k
          if (cs.picture->blocks[pPartitionerChroma->chType].contains(pPartitionerChroma->currArea().blocks[pPartitionerChroma->chType].pos()))
458
19.0k
          {
459
19.0k
            coding_tree(cs, *pPartitionerChroma, *pCuCtxChroma);
460
19.0k
          }
461
28.7k
          chromaContinue = pPartitionerChroma->nextPart(cs);
462
28.7k
          CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched");
463
28.7k
          beContinue = lumaContinue;
464
28.7k
        }
465
28.7k
      }
466
7.18k
      partitioner.exitCurrSplit();
467
7.18k
      pPartitionerChroma->exitCurrSplit();
468
469
7.18k
    }
470
72.7k
    else
471
72.7k
    {
472
72.7k
      const ModeType modeTypeParent = partitioner.modeType;
473
72.7k
      const ModeType modeTypeChild = CU::getModeTypeAtDepth( cu, partitioner.currDepth );
474
72.7k
      mode_constraint( splitMode, cs, partitioner, modeTypeChild );
475
72.7k
      partitioner.modeType = modeTypeChild;
476
477
72.7k
      bool chromaNotSplit = modeTypeParent == MODE_TYPE_ALL && modeTypeChild == MODE_TYPE_INTRA ? true : false;
478
72.7k
      CHECK( chromaNotSplit && partitioner.chType != CH_L, "chType must be luma" );
479
72.7k
      if( partitioner.treeType == TREE_D )
480
72.7k
      {
481
72.7k
        partitioner.treeType = chromaNotSplit ? TREE_L : TREE_D;
482
72.7k
      }
483
72.7k
      partitioner.splitCurrArea( splitMode, cs );
484
485
72.7k
      do
486
180k
      {
487
180k
        if( cs.picture->blocks[partitioner.chType].contains( partitioner.currArea().blocks[partitioner.chType].pos() ) )
488
109k
        {
489
109k
          coding_tree( cs, partitioner, cuCtx );
490
109k
        }
491
180k
      } while( partitioner.nextPart( cs ) );
492
493
72.7k
      partitioner.exitCurrSplit();
494
72.7k
      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
72.7k
      partitioner.modeType = modeTypeParent;
512
72.7k
    }
513
79.8k
    return;
514
79.8k
  }
515
516
  // Predict QP on start of quantization group
517
75.2k
  if( cuCtx.qgStart )
518
18.1k
  {
519
18.1k
    cuCtx.qgStart = false;
520
18.1k
    cuCtx.qp = CU::predictQP( cu, cuCtx.qp );
521
18.1k
  }
522
75.2k
  CHECK( cu.treeType != partitioner.treeType, "treeType mismatch" );
523
524
525
  // coding unit
526
75.2k
  coding_unit( cu, partitioner, cuCtx );
527
528
75.2k
  if( cu.chType == CH_C )
529
30.1k
  {
530
30.1k
    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
30.1k
  }
532
45.1k
  else
533
45.1k
  {
534
45.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
45.1k
  }
536
75.2k
  DTRACE_BLOCK_REC_COND( ( !isEncoding() ), cs.picture->getRecoBuf( cu ), cu, cu.predMode );
537
75.2k
}
538
539
540
void CABACWriter::mode_constraint( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner, const ModeType modeType )
541
241k
{
542
241k
  CHECK( split == CU_DONT_SPLIT, "splitMode shall not be no split" );
543
241k
  int val = CS::signalModeCons( cs, partitioner.currArea(), split, partitioner.modeType);
544
241k
  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
241k
  else if( val == LDT_MODE_TYPE_INFER )
553
0
  {
554
0
    CHECK( modeType != MODE_TYPE_INTRA, "Wrong mode type" );
555
0
  }
556
241k
  else
557
241k
  {
558
241k
    CHECK( modeType != partitioner.modeType, "Wrong mode type" );
559
241k
  }
560
241k
}
561
562
563
void CABACWriter::split_cu_mode( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner )
564
423k
{
565
423k
  bool canNo, canQt, canBh, canBv, canTh, canTv;
566
423k
  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv );
567
568
423k
  const bool canSpl[6] = { canNo, canQt, canBh, canBv, canTh, canTv };
569
570
423k
  unsigned ctxSplit = 0, ctxQtSplit = 0, ctxBttHV = 0, ctxBttH12 = 0, ctxBttV12;
571
423k
  DeriveCtx::CtxSplit( partitioner, ctxSplit, ctxQtSplit, ctxBttHV, ctxBttH12, ctxBttV12, canSpl );
572
573
423k
  const bool canSplit = canBh || canBv || canTh || canTv || canQt;
574
423k
  const bool isNo     = split == CU_DONT_SPLIT;
575
576
423k
  if( canNo && canSplit )
577
258k
  {
578
258k
    m_BinEncoder.encodeBin( !isNo, Ctx::SplitFlag( ctxSplit ) );
579
258k
  }
580
581
423k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d split=%d\n", ctxSplit, !isNo );
582
583
423k
  if( isNo )
584
174k
  {
585
174k
    return;
586
174k
  }
587
588
249k
  const bool canBtt = canBh || canBv || canTh || canTv;
589
249k
  const bool isQt   = split == CU_QUAD_SPLIT;
590
591
249k
  if( canQt && canBtt )
592
98.0k
  {
593
98.0k
    m_BinEncoder.encodeBin( isQt, Ctx::SplitQtFlag( ctxQtSplit ) );
594
98.0k
  }
595
596
249k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d qt=%d\n", ctxQtSplit, isQt );
597
598
249k
  if( isQt )
599
63.1k
  {
600
63.1k
    return;
601
63.1k
  }
602
603
185k
  const bool canHor = canBh || canTh;
604
185k
  const bool canVer = canBv || canTv;
605
185k
  const bool  isVer = split == CU_VERT_SPLIT || split == CU_TRIV_SPLIT;
606
607
185k
  if( canVer && canHor )
608
96.3k
  {
609
96.3k
    m_BinEncoder.encodeBin( isVer, Ctx::SplitHvFlag( ctxBttHV ) );
610
96.3k
  }
611
612
185k
  const bool can14 = isVer ? canTv : canTh;
613
185k
  const bool can12 = isVer ? canBv : canBh;
614
185k
  const bool  is12 = isVer ? ( split == CU_VERT_SPLIT ) : ( split == CU_HORZ_SPLIT );
615
616
185k
  if( can12 && can14 )
617
51.8k
  {
618
51.8k
    m_BinEncoder.encodeBin( is12, Ctx::Split12Flag( isVer ? ctxBttV12 : ctxBttH12 ) );
619
51.8k
  }
620
621
185k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctxHv=%d ctx12=%d mode=%d\n", ctxBttHV, isVer ? ctxBttV12 : ctxBttH12, split );
622
185k
}
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
75.2k
{
643
75.2k
  DTRACE( g_trace_ctx, D_SYNTAX, "coding_unit() treeType=%d modeType=%d\n", cu.treeType, cu.modeType );
644
75.2k
  STAT_COUNT_CU_MODES( isEncoding() && partitioner.chType == CH_L, g_cuCounters1D[CU_CODED_FINALLY][0][!cu.slice->isIntra() + cu.slice->depth] );
645
75.2k
  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
75.2k
  CodingStructure& cs = *cu.cs;
648
649
  // skip flag
650
75.2k
  if ((!cs.slice->isIntra() || cs.slice->sps->IBC) && cu.Y().valid())
651
45.1k
  {
652
45.1k
    cu_skip_flag( cu );
653
45.1k
  }
654
  
655
  // skip data
656
75.2k
  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
75.2k
  pred_mode ( cu );
667
75.2k
  if (CU::isIntra(cu))
668
75.2k
  {
669
75.2k
    adaptive_color_transform(cu);
670
75.2k
  }
671
75.2k
  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
75.2k
  cu_pred_data( cu );
679
680
  // residual data ( coded block flags + transform coefficient levels )
681
75.2k
  cu_residual( cu, partitioner, cuCtx );
682
683
  // end of cu
684
75.2k
  end_of_ctu( cu, cuCtx );
685
75.2k
}
686
687
688
void CABACWriter::cu_skip_flag( const CodingUnit& cu )
689
90.4k
{
690
90.4k
  unsigned ctxId = DeriveCtx::CtxSkipFlag();
691
692
90.4k
  if ((cu.slice->isIntra() || CU::isConsIntra(cu)) && cu.cs->slice->sps->IBC)
693
90.4k
  {
694
90.4k
    if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64
695
90.4k
    {
696
90.4k
      m_BinEncoder.encodeBin((cu.skip), Ctx::SkipFlag(ctxId));
697
90.4k
      DTRACE(g_trace_ctx, D_SYNTAX, "cu_skip_flag() ctx=%d skip=%d\n", ctxId, cu.skip ? 1 : 0);
698
90.4k
    }
699
90.4k
    return;
700
90.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
348k
{
730
348k
  if (cu.cs->slice->sps->IBC && cu.chType != CH_C)
731
264k
  {
732
264k
    if( CU::isConsInter(cu) )
733
0
    {
734
0
      assert( CU::isInter( cu ) );
735
0
      return;
736
0
    }
737
738
264k
    if ( cu.cs->slice->isIntra() || ( cu.lwidth() == 4 && cu.lheight() == 4 ) || CU::isConsIntra(cu) )
739
264k
    {
740
264k
      if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64
741
264k
      {
742
264k
        unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
743
264k
        m_BinEncoder.encodeBin(CU::isIBC(cu), Ctx::IBCFlag(ctxidx));
744
264k
      }
745
264k
      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
264k
    }
750
0
    else
751
0
    {
752
0
      if( CU::isConsInter(cu) )
753
0
      {
754
0
        return;
755
0
      }
756
0
      m_BinEncoder.encodeBin((CU::isIntra(cu) || CU::isPLT(cu)), Ctx::PredMode(DeriveCtx::CtxPredModeFlag()));
757
0
      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
0
      else
765
0
      {
766
0
        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
0
      }
772
0
    }
773
264k
  }
774
84.1k
  else
775
84.1k
  {
776
84.1k
    if( CU::isConsInter(cu) )
777
0
    {
778
0
      assert( CU::isInter( cu ) );
779
0
      return;
780
0
    }
781
782
84.1k
    if ( cu.cs->slice->isIntra() || ( cu.lwidth() == 4 && cu.lheight() == 4 ) || CU::isConsIntra(cu) )
783
84.1k
    {
784
84.1k
      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
84.1k
      return;
789
84.1k
    }
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
348k
}
797
798
799
void CABACWriter::bdpcm_mode( const CodingUnit& cu, const ComponentID compID )
800
594k
{
801
594k
  if( !cu.cs->sps->BDPCM) return;
802
594k
  if( !CU::bdpcmAllowed( cu, compID ) ) return;
803
804
267k
  int bdpcmMode = cu.bdpcmM[toChannelType(compID)];
805
806
267k
  unsigned ctxId = isLuma(compID) ? 0 : 2; 
807
267k
  m_BinEncoder.encodeBin(bdpcmMode > 0 ? 1 : 0, Ctx::BDPCMMode(ctxId));
808
267k
  if (bdpcmMode)
809
48.0k
  {
810
48.0k
    m_BinEncoder.encodeBin(bdpcmMode > 1 ? 1 : 0, Ctx::BDPCMMode(ctxId+1));
811
48.0k
  }
812
267k
  if (isLuma(compID))
813
39.0k
  {
814
39.0k
    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
39.0k
  }
816
227k
  else
817
227k
  {
818
227k
    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
227k
  }
820
267k
}
821
822
823
void CABACWriter::cu_pred_data( const CodingUnit& cu )
824
174k
{
825
174k
  if( CU::isIntra( cu ) )
826
153k
  {
827
153k
    if( cu.Y().valid() )
828
69.0k
    {
829
69.0k
      bdpcm_mode( cu, COMP_Y );
830
69.0k
    }
831
153k
    intra_luma_pred_modes  ( cu );
832
153k
    if( ( !cu.Y().valid() || ( !CU::isSepTree(cu) && cu.Y().valid() ) ) && isChromaEnabled(cu.chromaFormat) )
833
84.1k
    {
834
84.1k
      bdpcm_mode( cu, ComponentID(CH_C) );
835
84.1k
    } 
836
153k
    intra_chroma_pred_modes( cu );
837
153k
    return;
838
153k
  }
839
21.3k
  if (!cu.Y().valid()) // dual tree chroma CU
840
0
  {
841
0
    return;
842
0
  }
843
844
21.3k
  prediction_unit ( cu );
845
21.3k
  imv_mode        ( cu );
846
21.3k
  affine_amvr_mode( cu );
847
21.3k
  cu_bcw_flag     ( cu );
848
21.3k
}
849
850
851
void CABACWriter::cu_bcw_flag(const CodingUnit& cu)
852
21.3k
{
853
21.3k
  if(!CU::isBcwIdxCoded(cu))
854
21.3k
  {
855
21.3k
    return;
856
21.3k
  }
857
858
0
  CHECK(!(BCW_NUM > 1 && (BCW_NUM == 2 || (BCW_NUM & 0x01) == 1)), " !( BCW_NUM > 1 && ( BCW_NUM == 2 || ( BCW_NUM & 0x01 ) == 1 ) ) ");
859
0
  const uint8_t bcwCodingIdx = (uint8_t)g_BcwCodingOrder[CU::getValidBcwIdx(cu)];
860
861
0
  const int32_t numBcw = (cu.slice->checkLDC) ? 5 : 3;
862
0
  m_BinEncoder.encodeBin((bcwCodingIdx == 0 ? 0 : 1), Ctx::BcwIdx(0));
863
0
  if(numBcw > 2 && bcwCodingIdx != 0)
864
0
  {
865
0
    const uint32_t prefixNumBits = numBcw - 2;
866
0
    const uint32_t step = 1;
867
868
0
    uint8_t idx = 1;
869
0
    for(int ui = 0; ui < prefixNumBits; ++ui)
870
0
    {
871
0
      if (bcwCodingIdx == idx)
872
0
      {
873
0
        m_BinEncoder.encodeBinEP(0);
874
0
        break;
875
0
      }
876
0
      else
877
0
      {
878
0
        m_BinEncoder.encodeBinEP(1);
879
0
        idx += step;
880
0
      }
881
0
    }
882
0
  }
883
884
0
  DTRACE(g_trace_ctx, D_SYNTAX, "cu_bcw_flag() bcw_idx=%d\n", cu.BcwIdx ? 1 : 0);
885
0
}
886
887
888
void CABACWriter::xWriteTruncBinCode(uint32_t symbol, uint32_t maxSymbol)
889
799k
{
890
799k
  int thresh;
891
799k
  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
799k
  else
903
799k
  {
904
799k
    thresh = g_tbMax[maxSymbol];
905
799k
  }
906
907
799k
  int val = 1 << thresh;
908
799k
  assert(val <= maxSymbol);
909
799k
  assert((val << 1) > maxSymbol);
910
799k
  assert(symbol < maxSymbol);
911
799k
  int b = maxSymbol - val;
912
799k
  assert(b < val);
913
799k
  if (symbol < val - b)
914
249k
  {
915
249k
    m_BinEncoder.encodeBinsEP(symbol, thresh);
916
249k
  }
917
550k
  else
918
550k
  {
919
550k
    symbol += val - b;
920
550k
    assert(symbol < (val << 1));
921
550k
    assert((symbol >> 1) >= val - b);
922
550k
    m_BinEncoder.encodeBinsEP(symbol, thresh + 1);
923
550k
  }
924
799k
}
925
926
927
void CABACWriter::extend_ref_line(const CodingUnit& cu)
928
859k
{
929
859k
  if ( !cu.Y().valid() || cu.predMode != MODE_INTRA || !isLuma(cu.chType) || cu.bdpcmM[CH_L] )
930
0
  {
931
0
    return;
932
0
  }
933
859k
  if( !cu.cs->sps->MRL )
934
0
  {
935
0
    return;
936
0
  }
937
938
859k
  bool isFirstLineOfCtu = (((cu.block(COMP_Y).y)&((cu.cs->sps)->CTUSize - 1)) == 0);
939
859k
  if (isFirstLineOfCtu)
940
285k
  {
941
285k
    return;
942
285k
  }
943
574k
  int multiRefIdx = cu.multiRefIdx;
944
574k
  if (MRL_NUM_REF_LINES > 1)
945
574k
  {
946
574k
    m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[0], Ctx::MultiRefLineIdx(0));
947
574k
    if (MRL_NUM_REF_LINES > 2 && multiRefIdx != MULTI_REF_LINE_IDX[0])
948
156k
    {
949
156k
      m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], Ctx::MultiRefLineIdx(1));
950
156k
    }
951
574k
  }
952
574k
}
953
954
955
void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
956
153k
{
957
153k
  if( !cu.Y().valid() || cu.bdpcmM[CH_L] )
958
89.0k
  {
959
89.0k
    return;
960
89.0k
  }
961
962
64.1k
  mip_flag(cu);
963
64.1k
  if (cu.mipFlag)
964
1.53k
  {
965
1.53k
    mip_pred_modes(cu);
966
1.53k
    return;
967
1.53k
  }
968
62.6k
  extend_ref_line( cu );
969
970
62.6k
  isp_mode( cu );
971
972
62.6k
  const int numMPMs   = NUM_MOST_PROBABLE_MODES;
973
62.6k
  unsigned  mpm_pred   [numMPMs];
974
62.6k
  unsigned  mpm_idx;
975
62.6k
  unsigned  ipred_mode ;
976
977
  // prev_intra_luma_pred_flag
978
62.6k
  {
979
62.6k
    CU::getIntraMPMs( cu, mpm_pred );
980
981
62.6k
    ipred_mode = cu.intraDir[0];
982
62.6k
    mpm_idx    = numMPMs;
983
62.7k
    for( unsigned idx = 0; idx < numMPMs; idx++ )
984
62.7k
    {
985
62.7k
      if( ipred_mode == mpm_pred[idx] )
986
62.6k
      {
987
62.6k
        mpm_idx = idx;
988
62.6k
        break;
989
62.6k
      }
990
62.7k
    }
991
62.6k
    if ( cu.multiRefIdx )
992
0
    {
993
0
      CHECK(mpm_idx >= numMPMs, "use of non-MPM");
994
0
    }
995
62.6k
    else
996
62.6k
    {
997
62.6k
      m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
998
62.6k
    }
999
62.6k
  }
1000
1001
  // mpm_idx / rem_intra_luma_pred_mode
1002
62.6k
  {
1003
62.6k
    if( mpm_idx < numMPMs )
1004
62.6k
    {
1005
62.6k
      {
1006
62.6k
        unsigned ctx = (cu.ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
1007
62.6k
        if (cu.multiRefIdx == 0)
1008
62.6k
          m_BinEncoder.encodeBin(mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx));
1009
62.6k
        if( mpm_idx )
1010
111
        {
1011
111
          m_BinEncoder.encodeBinEP( mpm_idx > 1 );
1012
111
        }
1013
62.6k
        if (mpm_idx > 1)
1014
0
        {
1015
0
          m_BinEncoder.encodeBinEP(mpm_idx > 2);
1016
0
        }
1017
62.6k
        if (mpm_idx > 2)
1018
0
        {
1019
0
          m_BinEncoder.encodeBinEP(mpm_idx > 3);
1020
0
        }
1021
62.6k
        if (mpm_idx > 3)
1022
0
        {
1023
0
          m_BinEncoder.encodeBinEP(mpm_idx > 4);
1024
0
        }
1025
62.6k
      }
1026
62.6k
    }
1027
18.4E
    else
1028
18.4E
    {
1029
      // sorting of MPMs
1030
18.4E
      std::sort( mpm_pred, mpm_pred + numMPMs );
1031
1032
18.4E
      {
1033
18.4E
        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
18.4E
        CHECK(ipred_mode >= 64, "Incorrect mode");
1041
18.4E
        xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
1042
18.4E
      }
1043
18.4E
    }
1044
1045
62.6k
    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
62.6k
  }
1047
62.6k
}
1048
1049
1050
void CABACWriter::intra_luma_pred_mode( const CodingUnit& cu, const unsigned *mpmLst )
1051
1.06M
{
1052
1.06M
  if( cu.bdpcmM[CH_L] ) 
1053
6.90k
  {
1054
6.90k
    return;
1055
6.90k
  }
1056
1057
1.06M
  mip_flag(cu);
1058
1.06M
  if (cu.mipFlag)
1059
263k
  {
1060
263k
    mip_pred_mode(cu);
1061
263k
    return;
1062
263k
  }
1063
797k
  extend_ref_line( cu );
1064
1065
797k
  isp_mode( cu );
1066
1067
  // prev_intra_luma_pred_flag
1068
797k
  unsigned ipred_mode = cu.intraDir[0];
1069
797k
  static constexpr int numMPMs = NUM_MOST_PROBABLE_MODES;
1070
797k
  unsigned mpm_idx = numMPMs;
1071
797k
  unsigned  mpm_pred[numMPMs];
1072
1073
797k
  if (mpmLst)
1074
672k
  {
1075
672k
    memcpy(mpm_pred, mpmLst, sizeof(unsigned) * numMPMs);
1076
672k
  }
1077
124k
  else
1078
124k
  {
1079
124k
    CU::getIntraMPMs(cu, mpm_pred);
1080
124k
  }
1081
1082
4.18M
  for (int idx = 0; idx < numMPMs; idx++)
1083
3.70M
  {
1084
3.70M
    if (ipred_mode == mpm_pred[idx])
1085
319k
    {
1086
319k
      mpm_idx = idx;
1087
319k
      break;
1088
319k
    }
1089
3.70M
  }
1090
797k
  if (cu.multiRefIdx)
1091
156k
  {
1092
156k
    CHECK(mpm_idx >= numMPMs, "use of non-MPM");
1093
156k
  }
1094
640k
  else
1095
640k
  {
1096
640k
    m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
1097
640k
  }
1098
1099
  // mpm_idx / rem_intra_luma_pred_mode
1100
797k
  if( mpm_idx < numMPMs )
1101
319k
  {
1102
319k
    unsigned ctx = (cu.ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
1103
319k
    if (cu.multiRefIdx == 0)
1104
162k
      m_BinEncoder.encodeBin( mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx) );
1105
319k
    if( mpm_idx )
1106
214k
    {
1107
214k
      m_BinEncoder.encodeBinEP( mpm_idx > 1 );
1108
214k
    }
1109
319k
    if (mpm_idx > 1)
1110
121k
    {
1111
121k
      m_BinEncoder.encodeBinEP(mpm_idx > 2);
1112
121k
    }
1113
319k
    if (mpm_idx > 2)
1114
90.4k
    {
1115
90.4k
      m_BinEncoder.encodeBinEP(mpm_idx > 3);
1116
90.4k
    }
1117
319k
    if (mpm_idx > 3)
1118
60.1k
    {
1119
60.1k
      m_BinEncoder.encodeBinEP(mpm_idx > 4);
1120
60.1k
    }
1121
319k
  }
1122
477k
  else
1123
477k
  {
1124
    // mpm_pred[0] is always 0, i.e. PLANAR, so its always first in the list
1125
477k
    std::sort( mpm_pred + 1, mpm_pred + numMPMs );
1126
1127
3.34M
    for (int idx = numMPMs - 1; idx >= 0; idx--)
1128
2.86M
    {
1129
2.86M
      if (ipred_mode > mpm_pred[idx])
1130
1.55M
      {
1131
1.55M
        ipred_mode--;
1132
1.55M
      }
1133
2.86M
    }
1134
1135
477k
    xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
1136
477k
  }
1137
797k
}
1138
1139
1140
void CABACWriter::intra_chroma_pred_modes( const CodingUnit& cu )
1141
153k
{
1142
153k
  if( cu.chromaFormat == CHROMA_400 || ( CU::isSepTree(cu) && cu.chType == CH_L ) || cu.bdpcmM[CH_C] )
1143
69.0k
  {
1144
69.0k
    return;
1145
69.0k
  }
1146
1147
84.1k
  intra_chroma_pred_mode( cu );
1148
84.1k
}
1149
1150
1151
void CABACWriter::intra_chroma_lmc_mode(const CodingUnit& cu)
1152
32.8k
{
1153
32.8k
  const unsigned intraDir = cu.intraDir[1];
1154
32.8k
  int lmModeList[10];
1155
32.8k
  CU::getLMSymbolList(cu, lmModeList);
1156
32.8k
  int symbol = -1;
1157
32.8k
  for (int k = 0; k < LM_SYMBOL_NUM; k++)
1158
32.8k
  {
1159
32.8k
    if (lmModeList[k] == intraDir)
1160
32.8k
    {
1161
32.8k
      symbol = k;
1162
32.8k
      break;
1163
32.8k
    }
1164
32.8k
  }
1165
32.8k
  CHECK(symbol < 0, "invalid symbol found");
1166
1167
32.8k
  m_BinEncoder.encodeBin(symbol == 0 ? 0 : 1, Ctx::CclmModeIdx(0));
1168
1169
32.8k
  if (symbol > 0)
1170
0
  {
1171
0
    CHECK(symbol > 2, "invalid symbol for MMLM");
1172
0
    unsigned int symbol_minus_1 = symbol - 1;
1173
0
    m_BinEncoder.encodeBinEP(symbol_minus_1);
1174
0
  }
1175
32.8k
}
1176
1177
1178
void CABACWriter::intra_chroma_pred_mode(const CodingUnit& cu)
1179
352k
{
1180
352k
  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
352k
  const unsigned intraDir = cu.intraDir[1];
1187
352k
  if (cu.cs->sps->LMChroma && CU::checkCCLMAllowed(cu))
1188
240k
  {
1189
240k
    m_BinEncoder.encodeBin(CU::isLMCMode(intraDir) ? 1 : 0, Ctx::CclmModeFlag(0));
1190
240k
    if (CU::isLMCMode(intraDir))
1191
32.8k
    {
1192
32.8k
      intra_chroma_lmc_mode(cu);
1193
32.8k
      return;
1194
32.8k
    }
1195
240k
  }
1196
1197
319k
  const bool     isDerivedMode = intraDir == DM_CHROMA_IDX;
1198
319k
  m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0));
1199
319k
  if (isDerivedMode)
1200
72.7k
  {
1201
72.7k
    return;
1202
72.7k
  }
1203
1204
  // chroma candidate index
1205
246k
  unsigned chromaCandModes[NUM_CHROMA_MODE];
1206
246k
  CU::getIntraChromaCandModes(cu, chromaCandModes);
1207
1208
246k
  int candId = 0;
1209
587k
  for (; candId < NUM_CHROMA_MODE; candId++)
1210
587k
  {
1211
587k
    if (intraDir == chromaCandModes[candId])
1212
246k
    {
1213
246k
      break;
1214
246k
    }
1215
587k
  }
1216
1217
246k
  CHECK(candId >= NUM_CHROMA_MODE, "Chroma prediction mode index out of bounds");
1218
246k
  CHECK(chromaCandModes[candId] == DM_CHROMA_IDX, "The intra dir cannot be DM_CHROMA for this path");
1219
246k
  {
1220
246k
    m_BinEncoder.encodeBinsEP(candId, 2);
1221
246k
  }
1222
246k
}
1223
1224
1225
void CABACWriter::cu_residual( const CodingUnit& cu, Partitioner& partitioner, CUCtx& cuCtx )
1226
174k
{
1227
174k
  if (!CU::isIntra(cu))
1228
21.3k
  {
1229
21.3k
    if( !cu.mergeFlag )
1230
21.3k
    {
1231
21.3k
      rqt_root_cbf( cu );
1232
21.3k
    }
1233
21.3k
    if( cu.rootCbf )
1234
138
    {
1235
138
      sbt_mode( cu );
1236
138
    }
1237
1238
21.3k
    if( !cu.rootCbf )
1239
21.2k
    {
1240
21.2k
      CHECK(cu.colorTransform, "ACT should not be enabled for root_cbf = 0");
1241
21.2k
      return;
1242
21.2k
    }
1243
21.3k
  }
1244
1245
153k
  if( CU::isInter( cu ) || CU::isIBC( cu ) )
1246
138
  {
1247
138
    adaptive_color_transform(cu);
1248
138
  }
1249
1250
153k
  cuCtx.violatesLfnstConstrained[CH_L] = false;
1251
153k
  cuCtx.violatesLfnstConstrained[CH_C] = false;
1252
153k
  cuCtx.lfnstLastScanPos               = false;
1253
153k
  cuCtx.violatesMtsCoeffConstraint     = false;
1254
153k
  cuCtx.mtsLastScanPos                                = false;
1255
1256
153k
  if( cu.ispMode && isLuma( partitioner.chType ) )
1257
34
  {
1258
34
    transform_tree( *cu.cs, partitioner, cuCtx, CU::getISPType( cu, getFirstComponentOfChannel( partitioner.chType ) ), 0 );
1259
34
  }
1260
153k
  else
1261
153k
  {
1262
153k
    transform_tree( *cu.cs, partitioner, cuCtx );
1263
153k
  }
1264
1265
153k
  residual_lfnst_mode( cu, cuCtx );
1266
153k
  mts_idx            ( cu, &cuCtx );
1267
153k
}
1268
1269
1270
void CABACWriter::rqt_root_cbf( const CodingUnit& cu )
1271
42.7k
{
1272
42.7k
  m_BinEncoder.encodeBin( cu.rootCbf, Ctx::QtRootCbf() );
1273
1274
42.7k
  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
42.7k
}
1276
1277
1278
void CABACWriter::adaptive_color_transform(const CodingUnit& cu)
1279
75.4k
{
1280
75.4k
  if (!cu.slice->sps->useColorTrans )
1281
75.4k
  {
1282
75.4k
    return;
1283
75.4k
  }
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
75.2k
{
1358
75.2k
  const bool    isLastSubCUOfCtu  = CU::isLastSubCUOfCtu( cu );
1359
1360
75.2k
  if ( isLastSubCUOfCtu
1361
14.3k
    && ( !CU::isSepTree(cu) || cu.chromaFormat == CHROMA_400 || isChroma( cu.chType ) )
1362
75.2k
      )
1363
7.18k
  {
1364
7.18k
    cuCtx.isDQPCoded = ( cu.cs->pps->useDQP && !cuCtx.isDQPCoded );
1365
1366
7.18k
  }
1367
75.2k
}
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
21.3k
{
1389
21.3k
  CHECK( cu.treeType == TREE_C, "cannot be chroma CU" );
1390
21.3k
  if( cu.skip )
1391
0
  {
1392
0
    CHECK( !cu.mergeFlag, "merge_flag must be true for skipped CUs" );
1393
0
  }
1394
21.3k
  else
1395
21.3k
  {
1396
21.3k
    merge_flag( cu );
1397
21.3k
  }
1398
21.3k
  if( cu.mergeFlag )
1399
0
  {
1400
0
    merge_data(cu);
1401
0
  }
1402
21.3k
  else if (CU::isIBC(cu))
1403
21.3k
  {
1404
21.3k
    ref_idx(cu, REF_PIC_LIST_0);
1405
21.3k
    Mv mvd = cu.mvd[REF_PIC_LIST_0][0];
1406
21.3k
    mvd.changeIbcPrecInternal2Amvr(cu.imv);
1407
21.3k
    mvd_coding(mvd, 0); // already changed to signaling precision
1408
21.3k
    if ( cu.slice->sps->maxNumIBCMergeCand == 1 )
1409
0
    {
1410
0
      CHECK( cu.mvpIdx[REF_PIC_LIST_0], "mvpIdx for IBC mode should be 0" );
1411
0
    }
1412
21.3k
    else
1413
21.3k
    mvp_flag(cu, REF_PIC_LIST_0);
1414
21.3k
  }
1415
0
  else
1416
0
  {
1417
0
    inter_pred_idc( cu );
1418
0
    affine_flag   ( cu );
1419
0
    smvd_mode( cu );
1420
0
    if( cu.interDir != 2 /* PRED_L1 */ )
1421
0
    {
1422
0
      ref_idx     ( cu, REF_PIC_LIST_0 );
1423
0
      if ( cu.affine )
1424
0
      {
1425
0
        Mv mvd = cu.mvd[REF_PIC_LIST_0][0];
1426
0
        mvd.changeAffinePrecInternal2Amvr(cu.imv);
1427
0
        mvd_coding(mvd, 0); // already changed to signaling precision
1428
0
        mvd = cu.mvd[REF_PIC_LIST_0][1];
1429
0
        mvd.changeAffinePrecInternal2Amvr(cu.imv);
1430
0
        mvd_coding(mvd, 0); // already changed to signaling precision
1431
0
        if ( cu.affineType == AFFINEMODEL_6PARAM )
1432
0
        {
1433
0
          mvd = cu.mvd[REF_PIC_LIST_0][2];
1434
0
          mvd.changeAffinePrecInternal2Amvr(cu.imv);
1435
0
          mvd_coding(mvd, 0); // already changed to signaling precision
1436
0
        }
1437
0
      }
1438
0
      else
1439
0
      {
1440
0
        Mv mvd = cu.mvd[REF_PIC_LIST_0][0];
1441
0
        mvd.changeTransPrecInternal2Amvr(cu.imv);
1442
0
        mvd_coding(mvd, 0); // already changed to signaling precision
1443
0
      }
1444
0
      mvp_flag    ( cu, REF_PIC_LIST_0 );
1445
0
    }
1446
0
    if( cu.interDir != 1 /* PRED_L0 */ )
1447
0
    {
1448
0
      if ( cu.smvdMode != 1 )
1449
0
      {
1450
0
        ref_idx     ( cu, REF_PIC_LIST_1 );
1451
0
        if( !cu.cs->picHeader->mvdL1Zero || cu.interDir != 3 /* PRED_BI */ )
1452
0
        {
1453
0
          if ( cu.affine )
1454
0
          {
1455
0
            Mv mvd = cu.mvd[REF_PIC_LIST_1][0];
1456
0
            mvd.changeAffinePrecInternal2Amvr(cu.imv);
1457
0
            mvd_coding(mvd, 0); // already changed to signaling precision
1458
0
            mvd = cu.mvd[REF_PIC_LIST_1][1];
1459
0
            mvd.changeAffinePrecInternal2Amvr(cu.imv);
1460
0
            mvd_coding(mvd, 0); // already changed to signaling precision
1461
0
            if ( cu.affineType == AFFINEMODEL_6PARAM )
1462
0
            {
1463
0
              mvd = cu.mvd[REF_PIC_LIST_1][2];
1464
0
              mvd.changeAffinePrecInternal2Amvr(cu.imv);
1465
0
              mvd_coding(mvd, 0); // already changed to signaling precision
1466
0
            }
1467
0
          }
1468
0
          else
1469
0
          {
1470
0
            Mv mvd = cu.mvd[REF_PIC_LIST_1][0];
1471
0
            mvd.changeTransPrecInternal2Amvr(cu.imv);
1472
0
            mvd_coding(mvd, 0); // already changed to signaling precision
1473
0
          }
1474
0
        }
1475
0
      }
1476
0
      mvp_flag    ( cu, REF_PIC_LIST_1 );
1477
0
    }
1478
0
  }
1479
21.3k
}
1480
1481
1482
void CABACWriter::smvd_mode( const CodingUnit& cu )
1483
0
{
1484
0
  if ( cu.interDir != 3 || cu.affine )
1485
0
  {
1486
0
    return;
1487
0
  }
1488
1489
0
  if ( cu.cs->slice->biDirPred == false )
1490
0
  {
1491
0
    return;
1492
0
  }
1493
1494
0
  m_BinEncoder.encodeBin( cu.smvdMode ? 1 : 0, Ctx::SmvdFlag() );
1495
1496
0
  DTRACE( g_trace_ctx, D_SYNTAX, "symmvd_flag() symmvd=%d pos=(%d,%d) size=%dx%d\n", cu.smvdMode ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height );
1497
0
}
1498
1499
1500
void CABACWriter::subblock_merge_flag( const CodingUnit& cu )
1501
0
{
1502
1503
0
  if ( !cu.cs->slice->isIntra() && (cu.slice->picHeader->maxNumAffineMergeCand > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
1504
0
  {
1505
0
    unsigned ctxId = DeriveCtx::CtxAffineFlag();
1506
0
    m_BinEncoder.encodeBin( cu.affine, Ctx::SubblockMergeFlag( ctxId ) );
1507
0
    DTRACE( g_trace_ctx, D_SYNTAX, "subblock_merge_flag() subblock_merge_flag=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
1508
0
  }
1509
0
}
1510
1511
1512
void CABACWriter::affine_flag( const CodingUnit& cu )
1513
0
{
1514
0
  if ( !cu.cs->slice->isIntra() && cu.cs->sps->Affine && cu.lumaSize().width > 8 && cu.lumaSize().height > 8 )
1515
0
  {
1516
0
    unsigned ctxId = DeriveCtx::CtxAffineFlag();
1517
0
    m_BinEncoder.encodeBin( cu.affine, Ctx::AffineFlag( ctxId ) );
1518
0
    DTRACE( g_trace_ctx, D_SYNTAX, "affine_flag() affine=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
1519
1520
0
    if ( cu.affine && cu.cs->sps->AffineType )
1521
0
    {
1522
0
      unsigned ctxId = 0;
1523
0
      m_BinEncoder.encodeBin( cu.affineType, Ctx::AffineType( ctxId ) );
1524
0
      DTRACE( g_trace_ctx, D_SYNTAX, "affine_type() affine_type=%d ctx=%d pos=(%d,%d)\n", cu.affineType ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
1525
0
    }
1526
0
  }
1527
0
}
1528
1529
1530
void CABACWriter::merge_flag( const CodingUnit& cu )
1531
21.3k
{
1532
21.3k
  m_BinEncoder.encodeBin( cu.mergeFlag, Ctx::MergeFlag() );
1533
1534
21.3k
  DTRACE( g_trace_ctx, D_SYNTAX, "merge_flag() merge=%d pos=(%d,%d) size=%dx%d\n", cu.mergeFlag ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height );
1535
21.3k
}
1536
1537
1538
void CABACWriter::merge_data(const CodingUnit& cu)
1539
0
{
1540
0
  if (CU::isIBC(cu))
1541
0
  {
1542
0
    merge_idx(cu);
1543
0
    return;
1544
0
  }
1545
0
  subblock_merge_flag(cu);
1546
0
  if (cu.affine)
1547
0
  {
1548
0
    merge_idx(cu);
1549
0
    return;
1550
0
  }
1551
1552
0
  const bool ciipAvailable = cu.cs->sps->CIIP && !cu.skip && cu.Y().maxDim() < MAX_CU_SIZE && cu.Y().area() >= 64;
1553
0
  const bool geoAvailable = cu.cs->slice->sps->GEO && cu.cs->slice->isInterB() && cu.cs->sps->maxNumGeoCand > 1
1554
0
                                                   && cu.Y().minDim() >= GEO_MIN_CU_SIZE && cu.Y().maxDim() <= GEO_MAX_CU_SIZE
1555
0
                                                   && cu.Y().maxDim() < 8 * cu.Y().minDim();
1556
1557
0
  if (geoAvailable || ciipAvailable)
1558
0
  {
1559
0
    m_BinEncoder.encodeBin(!cu.geo && !cu.ciip, Ctx::RegularMergeFlag(cu.skip ? 0 : 1));
1560
0
  }
1561
0
  if (!cu.geo && !cu.ciip)
1562
0
  {
1563
0
    if (cu.cs->sps->MMVD)
1564
0
    {
1565
0
      m_BinEncoder.encodeBin(cu.mmvdMergeFlag, Ctx::MmvdFlag(0));
1566
0
      DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_flag() mmvd_merge=%d pos=(%d,%d) size=%dx%d\n", cu.mmvdMergeFlag ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height);
1567
0
    }
1568
0
    if (cu.mmvdMergeFlag || cu.mmvdSkip)
1569
0
    {
1570
0
      mmvd_merge_idx(cu);
1571
0
    }
1572
0
    else
1573
0
    {
1574
0
      merge_idx(cu);
1575
0
    }
1576
0
  }
1577
0
  else
1578
0
  {
1579
0
    if (geoAvailable && ciipAvailable)
1580
0
    {
1581
0
      ciip_flag(cu);
1582
0
    }
1583
0
    merge_idx(cu);
1584
0
  }
1585
0
}
1586
1587
1588
void CABACWriter::imv_mode( const CodingUnit& cu )
1589
21.3k
{
1590
21.3k
  const SPS *sps = cu.cs->sps;
1591
1592
21.3k
  if( !sps->AMVR )
1593
0
  {
1594
0
    return;
1595
0
  }
1596
21.3k
  if ( cu.affine )
1597
0
  {
1598
0
    return;
1599
0
  }
1600
1601
21.3k
  bool bNonZeroMvd = CU::hasSubCUNonZeroMVd( cu );
1602
21.3k
  if( !bNonZeroMvd )
1603
0
  {
1604
0
    return;
1605
0
  }
1606
1607
21.3k
  if (CU::isIBC(cu) == false)
1608
0
    m_BinEncoder.encodeBin( (cu.imv > 0), Ctx::ImvFlag( 0 ) );
1609
21.3k
  DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 0), 0 );
1610
1611
21.3k
  if( sps->AMVR && cu.imv > 0 )
1612
21.3k
  {
1613
21.3k
    if (!CU::isIBC(cu))
1614
0
    {
1615
0
      m_BinEncoder.encodeBin(cu.imv < IMV_HPEL, Ctx::ImvFlag(4));
1616
0
      DTRACE(g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", cu.imv < 3, 4);
1617
0
    }
1618
21.3k
    if (cu.imv < IMV_HPEL)
1619
21.3k
    {
1620
21.3k
    m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 1 ) );
1621
21.3k
    DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 1), 1 );
1622
21.3k
    }
1623
21.3k
  }
1624
1625
21.3k
  DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() IMVFlag=%d\n", cu.imv );
1626
21.3k
}
1627
1628
1629
void CABACWriter::affine_amvr_mode( const CodingUnit& cu )
1630
21.3k
{
1631
21.3k
  const SPS* sps = cu.slice->sps;
1632
1633
21.3k
  if( !sps->AffineAmvr || !cu.affine )
1634
21.3k
  {
1635
21.3k
    return;
1636
21.3k
  }
1637
1638
0
  if ( !CU::hasSubCUNonZeroAffineMVd( cu ) )
1639
0
  {
1640
0
    return;
1641
0
  }
1642
1643
0
  m_BinEncoder.encodeBin( (cu.imv > 0), Ctx::ImvFlag( 2 ) );
1644
0
  DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", (cu.imv > 0), 2 );
1645
1646
0
  if( cu.imv > 0 )
1647
0
  {
1648
0
    m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 3 ) );
1649
0
    DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", (cu.imv > 1), 3 );
1650
0
  }
1651
0
  DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() IMVFlag=%d\n", cu.imv );
1652
0
}
1653
1654
1655
void CABACWriter::merge_idx( const CodingUnit& cu )
1656
0
{
1657
0
  if ( cu.affine )
1658
0
  {
1659
0
    int numCandminus1 = int( cu.cs->picHeader->maxNumAffineMergeCand ) - 1;
1660
0
    if ( numCandminus1 > 0 )
1661
0
    {
1662
0
      if ( cu.mergeIdx == 0 )
1663
0
      {
1664
0
        m_BinEncoder.encodeBin( 0, Ctx::AffMergeIdx() );
1665
0
        DTRACE( g_trace_ctx, D_SYNTAX, "aff_merge_idx() aff_merge_idx=%d\n", cu.mergeIdx );
1666
0
        return;
1667
0
      }
1668
0
      else
1669
0
      {
1670
0
        m_BinEncoder.encodeBin( 1, Ctx::AffMergeIdx() );
1671
0
        for ( unsigned idx = 1; idx < numCandminus1; idx++ )
1672
0
        {
1673
0
            m_BinEncoder.encodeBinEP( cu.mergeIdx == idx ? 0 : 1 );
1674
0
          if ( cu.mergeIdx == idx )
1675
0
          {
1676
0
            break;
1677
0
          }
1678
0
        }
1679
0
      }
1680
0
    }
1681
0
    DTRACE( g_trace_ctx, D_SYNTAX, "aff_merge_idx() aff_merge_idx=%d\n", cu.mergeIdx );
1682
0
  }
1683
0
  else
1684
0
  {
1685
0
    if( cu.geo )
1686
0
    {
1687
0
      uint8_t splitDir = cu.geoSplitDir;
1688
0
      uint8_t candIdx0 = cu.geoMergeIdx[0];
1689
0
      uint8_t candIdx1 = cu.geoMergeIdx[1];
1690
0
      DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_split_dir=%d\n", splitDir );
1691
0
      DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_idx0=%d\n", candIdx0 );
1692
0
      DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_idx1=%d\n", candIdx1 );
1693
0
      xWriteTruncBinCode(splitDir, GEO_NUM_PARTITION_MODE);
1694
0
      candIdx1 -= candIdx1 < candIdx0 ? 0 : 1;
1695
0
      const int maxNumGeoCand = cu.cs->sps->maxNumGeoCand;
1696
0
      CHECK(maxNumGeoCand < 2, "Incorrect max number of geo candidates");
1697
0
      CHECK(candIdx0 >= maxNumGeoCand, "Incorrect candIdx0");
1698
0
      CHECK(candIdx1 >= maxNumGeoCand, "Incorrect candIdx1");
1699
0
      int numCandminus2 = maxNumGeoCand - 2;
1700
0
      m_BinEncoder.encodeBin( candIdx0 == 0 ? 0 : 1, Ctx::MergeIdx() );
1701
0
      if( candIdx0 > 0 )
1702
0
      {
1703
0
        unary_max_eqprob(candIdx0 - 1, numCandminus2);
1704
0
      }
1705
0
      if (numCandminus2 > 0)
1706
0
      {
1707
0
        m_BinEncoder.encodeBin(candIdx1 == 0 ? 0 : 1, Ctx::MergeIdx());
1708
0
        if (candIdx1 > 0)
1709
0
        {
1710
0
          unary_max_eqprob(candIdx1 - 1, numCandminus2 - 1);
1711
0
        }
1712
0
      }
1713
0
      return;
1714
0
    }
1715
0
    int numCandminus1 = (cu.predMode == MODE_IBC) ? (int(cu.cs->sps->maxNumIBCMergeCand) - 1) : (int(cu.cs->sps->maxNumMergeCand) - 1);
1716
0
    if( numCandminus1 > 0 )
1717
0
    {
1718
0
      if( cu.mergeIdx == 0 )
1719
0
      {
1720
0
        m_BinEncoder.encodeBin( 0, Ctx::MergeIdx() );
1721
0
        DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", cu.mergeIdx );
1722
0
        return;
1723
0
      }
1724
0
      else
1725
0
      {
1726
0
        m_BinEncoder.encodeBin( 1, Ctx::MergeIdx() );
1727
0
        for( unsigned idx = 1; idx < numCandminus1; idx++ )
1728
0
        {
1729
0
          m_BinEncoder.encodeBinEP( cu.mergeIdx == idx ? 0 : 1 );
1730
0
          if( cu.mergeIdx == idx )
1731
0
          {
1732
0
            break;
1733
0
          }
1734
0
        }
1735
0
      }
1736
0
    }
1737
0
    DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", cu.mergeIdx );
1738
0
  }
1739
0
}
1740
1741
1742
void CABACWriter::mmvd_merge_idx( const CodingUnit &cu )
1743
0
{
1744
0
  const int mvdBaseIdx  = cu.mmvdMergeIdx.pos.baseIdx;
1745
0
  const int mvdStep     = cu.mmvdMergeIdx.pos.step;
1746
0
  const int mvdPosition = cu.mmvdMergeIdx.pos.position;
1747
1748
0
  if( cu.cs->sps->maxNumMergeCand > 1 )
1749
0
  {
1750
0
    static_assert( MMVD_BASE_MV_NUM == 2, "" );
1751
0
    CHECK( mvdBaseIdx >= 2, "Invalid mvdBaseIdx" );
1752
0
    m_BinEncoder.encodeBin( mvdBaseIdx, Ctx::MmvdMergeIdx() );
1753
0
  }
1754
0
  DTRACE( g_trace_ctx, D_SYNTAX, "base_mvp_idx() base_mvp_idx=%d\n", mvdBaseIdx );
1755
1756
0
  int numCandminus1_step = MMVD_REFINE_STEP - 1;
1757
0
  if( numCandminus1_step > 0 )
1758
0
  {
1759
0
    if( mvdStep == 0 )
1760
0
    {
1761
0
      m_BinEncoder.encodeBin( 0, Ctx::MmvdStepMvpIdx() );
1762
0
    }
1763
0
    else
1764
0
    {
1765
0
      m_BinEncoder.encodeBin( 1, Ctx::MmvdStepMvpIdx() );
1766
0
      for( unsigned idx = 1; idx < numCandminus1_step; idx++ )
1767
0
      {
1768
0
        m_BinEncoder.encodeBinEP( mvdStep == idx ? 0 : 1 );
1769
0
        if( mvdStep == idx )
1770
0
        {
1771
0
          break;
1772
0
        }
1773
0
      }
1774
0
    }
1775
0
  }
1776
0
  DTRACE( g_trace_ctx, D_SYNTAX, "MmvdStepMvpIdx() MmvdStepMvpIdx=%d\n", mvdStep );
1777
1778
0
  m_BinEncoder.encodeBinsEP( mvdPosition, 2 );
1779
1780
0
  DTRACE( g_trace_ctx, D_SYNTAX, "pos() pos=%d\n", mvdPosition );
1781
0
  DTRACE( g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", cu.mmvdMergeIdx.val );
1782
0
}
1783
1784
1785
void CABACWriter::inter_pred_idc( const CodingUnit& cu )
1786
0
{
1787
0
  if( !cu.cs->slice->isInterB() )
1788
0
  {
1789
0
    return;
1790
0
  }
1791
0
  if( !(CU::isBipredRestriction(cu)) )
1792
0
  {
1793
0
    unsigned ctxId = DeriveCtx::CtxInterDir(cu);
1794
0
    if( cu.interDir == 3 )
1795
0
    {
1796
0
      m_BinEncoder.encodeBin( 1, Ctx::InterDir(ctxId) );
1797
0
      DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=%d value=%d pos=(%d,%d)\n", ctxId, cu.interDir, cu.lumaPos().x, cu.lumaPos().y );
1798
0
      return;
1799
0
    }
1800
0
    else
1801
0
    {
1802
0
      m_BinEncoder.encodeBin( 0, Ctx::InterDir(ctxId) );
1803
0
    }
1804
0
  }
1805
0
  m_BinEncoder.encodeBin( ( cu.interDir == 2 ), Ctx::InterDir( 5 ) );
1806
0
  DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=5 value=%d pos=(%d,%d)\n", cu.interDir, cu.lumaPos().x, cu.lumaPos().y );
1807
0
}
1808
1809
1810
void CABACWriter::ref_idx( const CodingUnit& cu, RefPicList eRefList )
1811
21.3k
{
1812
21.3k
  if ( cu.smvdMode )
1813
0
  {
1814
0
    CHECK( cu.refIdx[eRefList] != cu.cs->slice->symRefIdx[ eRefList ], "Invalid reference index!\n" );
1815
0
    return;
1816
0
  }
1817
1818
21.3k
  int numRef  = cu.cs->slice->numRefIdx[eRefList];
1819
1820
21.3k
  if (eRefList == REF_PIC_LIST_0 && cu.cs->sps->IBC)
1821
21.3k
  {
1822
21.3k
    if (CU::isIBC(cu))
1823
21.3k
      return;
1824
21.3k
  }
1825
1826
0
  if( numRef <= 1 )
1827
0
  {
1828
0
    return;
1829
0
  }
1830
0
  int refIdx  = cu.refIdx[eRefList];
1831
0
  m_BinEncoder.encodeBin( (refIdx > 0), Ctx::RefPic() );
1832
0
  if( numRef <= 2 || refIdx == 0 )
1833
0
  {
1834
0
    DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y );
1835
0
    return;
1836
0
  }
1837
0
  m_BinEncoder.encodeBin( (refIdx > 1), Ctx::RefPic(1) );
1838
0
  if( numRef <= 3 || refIdx == 1 )
1839
0
  {
1840
0
    DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y );
1841
0
    return;
1842
0
  }
1843
0
  for( int idx = 3; idx < numRef; idx++ )
1844
0
  {
1845
0
    if( refIdx > idx - 1 )
1846
0
    {
1847
0
      m_BinEncoder.encodeBinEP( 1 );
1848
0
    }
1849
0
    else
1850
0
    {
1851
0
      m_BinEncoder.encodeBinEP( 0 );
1852
0
      break;
1853
0
    }
1854
0
  }
1855
0
  DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y );
1856
0
}
1857
1858
1859
void CABACWriter::mvp_flag( const CodingUnit& cu, RefPicList eRefList )
1860
21.3k
{
1861
21.3k
  m_BinEncoder.encodeBin( cu.mvpIdx[eRefList], Ctx::MVPIdx() );
1862
21.3k
  DTRACE( g_trace_ctx, D_SYNTAX, "mvp_flag() value=%d pos=(%d,%d)\n", cu.mvpIdx[eRefList], cu.lumaPos().x, cu.lumaPos().y );
1863
21.3k
  DTRACE( g_trace_ctx, D_SYNTAX, "mvpIdx(refList:%d)=%d\n", eRefList, cu.mvpIdx[eRefList] );
1864
21.3k
}
1865
1866
1867
void CABACWriter::ciip_flag(const CodingUnit& cu)
1868
0
{
1869
0
  if (!cu.cs->sps->CIIP)
1870
0
  {
1871
0
    CHECK(cu.ciip == true, "invalid Ciip SPS");
1872
0
    return;
1873
0
  }
1874
0
  if (cu.skip)
1875
0
  {
1876
0
    CHECK(cu.ciip == true, "invalid Ciip and skip");
1877
0
    return;
1878
0
  }
1879
0
  m_BinEncoder.encodeBin(cu.ciip, Ctx::CiipFlag());
1880
0
  DTRACE(g_trace_ctx, D_SYNTAX, "Ciip_flag() Ciip=%d pos=(%d,%d) size=%dx%d\n", cu.ciip ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height);
1881
0
}
1882
1883
1884
//================================================================================
1885
//  clause 7.3.8.8
1886
//--------------------------------------------------------------------------------
1887
//    void  transform_tree      ( cs, area, cuCtx, chromaCbfs )
1888
//    bool  split_transform_flag( split, depth )
1889
//    bool  cbf_comp            ( cbf, area, depth )
1890
//================================================================================
1891
1892
void CABACWriter::transform_tree( const CodingStructure& cs, Partitioner& partitioner, CUCtx& cuCtx, const PartSplit ispType, const int subTuIdx )
1893
153k
{
1894
153k
  const UnitArea&       area = partitioner.currArea();
1895
153k
  int             subTuCounter = subTuIdx;
1896
153k
  const TransformUnit&  tu = *cs.getTU(area.blocks[partitioner.chType].pos(), partitioner.chType, subTuIdx);
1897
153k
  const CodingUnit&     cu = *tu.cu;
1898
153k
  const unsigned        trDepth = partitioner.currTrDepth;
1899
153k
  const bool            split = (tu.depth > trDepth);
1900
153k
  if( split )
1901
34
  {
1902
34
    PartSplit partSplit;
1903
1904
34
    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
34
    else if( cu.ispMode )
1914
34
    {
1915
34
      partitioner.splitCurrArea( ispType, cs );
1916
34
    }
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
34
    do
1925
136
    {
1926
136
      transform_tree( cs, partitioner, cuCtx,                ispType, subTuCounter );
1927
136
      subTuCounter += subTuCounter != -1 ? 1 : 0;
1928
136
    } while( partitioner.nextPart( cs ) );
1929
1930
34
    partitioner.exitCurrSplit();
1931
34
  }
1932
153k
  else
1933
153k
  {
1934
    // split_transform_flag
1935
153k
    CHECK( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) || (cu.sbtInfo && partitioner.canSplit( CU::getSbtTuSplit( cu.sbtInfo ), cs)),  "transform split implied" );
1936
153k
    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
153k
    transform_unit( tu, cuCtx, partitioner, subTuCounter);
1939
153k
  }
1940
153k
}
1941
1942
1943
void CABACWriter::cbf_comp( const CodingUnit& cu, bool cbf, const CompArea& area, unsigned depth, const bool prevCbf, const bool useISP )
1944
2.92M
{
1945
2.92M
  const CtxSet&   ctxSet  = Ctx::QtCbf[ area.compID ];
1946
2.92M
  unsigned  ctxId;
1947
2.92M
  if( cu.bdpcmM[toChannelType(area.compID)] )
1948
186k
  {
1949
186k
    ctxId = (area.compID != COMP_Cr) ? 1 : 2;
1950
186k
    m_BinEncoder.encodeBin(cbf, ctxSet(ctxId));
1951
186k
  }
1952
2.73M
  else
1953
2.73M
  {
1954
2.73M
    ctxId = DeriveCtx::CtxQtCbf(area.compID, prevCbf, useISP && isLuma(area.compID));
1955
2.73M
    m_BinEncoder.encodeBin( cbf, ctxSet( ctxId ) );
1956
2.73M
  }
1957
2.92M
  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
2.92M
}
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
21.3k
{
1969
21.3k
  int       horMvd = rMvd.hor;
1970
21.3k
  int       verMvd = rMvd.ver;
1971
21.3k
  if ( imv > 0 )
1972
0
  {
1973
0
    int shift = 1;
1974
0
    if (imv < IMV_HPEL)
1975
0
    {
1976
0
      shift = 2;
1977
0
      if (imv == IMV_4PEL)
1978
0
      {
1979
0
        shift = 4;
1980
0
      }
1981
0
    }
1982
1983
0
    CHECK((horMvd % (1<<shift)) != 0 && (verMvd % (4<<shift)) != 0, "IMV: MVD is not a multiple of 2^N ");
1984
0
    horMvd >>= shift;
1985
0
    verMvd >>= shift;
1986
0
  }
1987
21.3k
  unsigned  horAbs  = unsigned( horMvd < 0 ? -horMvd : horMvd );
1988
21.3k
  unsigned  verAbs  = unsigned( verMvd < 0 ? -verMvd : verMvd );
1989
1990
1991
  // abs_mvd_greater0_flag[ 0 | 1 ]
1992
21.3k
  m_BinEncoder.encodeBin( (horAbs > 0), Ctx::Mvd() );
1993
21.3k
  m_BinEncoder.encodeBin( (verAbs > 0), Ctx::Mvd() );
1994
1995
  // abs_mvd_greater1_flag[ 0 | 1 ]
1996
21.3k
  if( horAbs > 0 )
1997
13.3k
  {
1998
13.3k
    m_BinEncoder.encodeBin( (horAbs > 1), Ctx::Mvd(1) );
1999
13.3k
  }
2000
21.3k
  if( verAbs > 0 )
2001
8.03k
  {
2002
8.03k
    m_BinEncoder.encodeBin( (verAbs > 1), Ctx::Mvd(1) );
2003
8.03k
  }
2004
2005
  // abs_mvd_minus2[ 0 | 1 ] and mvd_sign_flag[ 0 | 1 ]
2006
21.3k
  if( horAbs > 0 )
2007
13.3k
  {
2008
13.3k
    if( horAbs > 1 )
2009
13.3k
    {
2010
13.3k
      m_BinEncoder.encodeRemAbsEP(horAbs - 2, 1, 0, MV_BITS - 1);
2011
13.3k
    }
2012
13.3k
    m_BinEncoder.encodeBinEP( (horMvd < 0) );
2013
13.3k
  }
2014
21.3k
  if( verAbs > 0 )
2015
8.03k
  {
2016
8.03k
    if( verAbs > 1 )
2017
7.97k
    {
2018
7.97k
      m_BinEncoder.encodeRemAbsEP(verAbs - 2, 1, 0, MV_BITS - 1);
2019
7.97k
    }
2020
8.03k
    m_BinEncoder.encodeBinEP( (verMvd < 0) );
2021
8.03k
  }
2022
21.3k
}
2023
2024
2025
//================================================================================
2026
//  clause 7.3.8.10
2027
//--------------------------------------------------------------------------------
2028
//    void  transform_unit      ( tu, cuCtx, chromaCbfs )
2029
//    void  cu_qp_delta         ( cu )
2030
//    void  cu_chroma_qp_offset ( cu )
2031
//================================================================================
2032
void CABACWriter::transform_unit( const TransformUnit& tu, CUCtx& cuCtx, Partitioner& partitioner, const int subTuCounter)
2033
153k
{
2034
153k
  const CodingUnit&       cu = *tu.cu;
2035
153k
  const UnitArea&         area = partitioner.currArea();
2036
153k
  const unsigned          trDepth = partitioner.currTrDepth;
2037
153k
  ChromaCbfs              chromaCbfs;
2038
153k
  CHECK(tu.depth != trDepth, " transform unit should be not be futher partitioned");
2039
2040
  // cbf_cb & cbf_cr
2041
153k
  if (area.chromaFormat != CHROMA_400)
2042
153k
  {
2043
153k
    const bool              chromaCbfISP = area.blocks[COMP_Cb].valid() && cu.ispMode;
2044
153k
    if (area.blocks[COMP_Cb].valid() && (!CU::isSepTree(cu) || partitioner.chType == CH_C) && (!cu.ispMode || chromaCbfISP))
2045
84.1k
    {
2046
84.1k
      unsigned cbfDepth = chromaCbfISP ? trDepth - 1 : trDepth;
2047
84.1k
      {
2048
84.1k
        chromaCbfs.Cb = TU::getCbfAtDepth(tu, COMP_Cb, trDepth);
2049
        //if (!(cu.sbtInfo && trDepth == 1))
2050
84.1k
        if (!(cu.sbtInfo && tu.noResidual))
2051
84.1k
          cbf_comp(*tu.cu, chromaCbfs.Cb, area.blocks[COMP_Cb], cbfDepth);
2052
84.1k
      }
2053
2054
84.1k
      {
2055
84.1k
        chromaCbfs.Cr = TU::getCbfAtDepth(tu, COMP_Cr, trDepth);
2056
        //if (!(cu.sbtInfo && trDepth == 1))
2057
84.1k
        if (!(cu.sbtInfo && tu.noResidual))
2058
84.1k
          cbf_comp(*tu.cu, chromaCbfs.Cr, area.blocks[COMP_Cr], cbfDepth, chromaCbfs.Cb);
2059
84.1k
      }
2060
84.1k
    }
2061
69.3k
    else if (CU::isSepTree(cu))
2062
69.3k
    {
2063
69.3k
      chromaCbfs = ChromaCbfs(false);
2064
69.3k
    }
2065
153k
  }
2066
0
  else if (CU::isSepTree(cu))
2067
0
  {
2068
0
    chromaCbfs = ChromaCbfs(false);
2069
0
  }
2070
2071
153k
  if (!isChroma(partitioner.chType))
2072
69.3k
  {
2073
69.3k
    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
69.1k
    else if (cu.sbtInfo && tu.noResidual)
2078
0
    {
2079
0
      CHECK(TU::getCbfAtDepth(tu, COMP_Y, trDepth), "Luma cbf must be false for inter sbt no-residual tu");
2080
0
    }
2081
69.1k
    else if (cu.sbtInfo && !chromaCbfs.sigChroma(area.chromaFormat))
2082
0
    {
2083
0
      assert(!tu.noResidual);
2084
0
      CHECK(!TU::getCbfAtDepth(tu, COMP_Y, trDepth), "Luma cbf must be true for inter sbt residual tu");
2085
0
    }
2086
69.1k
    else
2087
69.1k
    {
2088
69.1k
      bool previousCbf = false;
2089
69.1k
      bool rootCbfSoFar = false;
2090
69.1k
      bool lumaCbfIsInferredACT = (cu.colorTransform && cu.predMode == MODE_INTRA && trDepth == 0 && !chromaCbfs.sigChroma(area.chromaFormat));
2091
69.1k
      CHECK(lumaCbfIsInferredACT && !TU::getCbfAtDepth(tu, COMP_Y, trDepth), "adaptive color transform cannot have all zero coefficients");
2092
69.1k
      bool lastCbfIsInferred    = lumaCbfIsInferredACT; // ISP and ACT are mutually exclusive
2093
69.1k
      if (cu.ispMode)
2094
136
      {
2095
136
        uint32_t nTus = cu.ispMode == HOR_INTRA_SUBPARTITIONS ? cu.lheight() >> Log2(tu.lheight()) : cu.lwidth() >> Log2(tu.lwidth());
2096
136
        if (subTuCounter == nTus - 1)
2097
34
        {
2098
34
          TransformUnit* tuPointer = cu.firstTU;
2099
136
          for (int tuIdx = 0; tuIdx < subTuCounter; tuIdx++)
2100
102
          {
2101
102
            rootCbfSoFar |= TU::getCbfAtDepth(*tuPointer, COMP_Y, trDepth);
2102
102
            tuPointer = tuPointer->next;
2103
102
          }
2104
34
          if (!rootCbfSoFar)
2105
0
          {
2106
0
            lastCbfIsInferred = true;
2107
0
          }
2108
34
        }
2109
136
        if (!lastCbfIsInferred)
2110
136
        {
2111
136
          previousCbf = TU::getPrevTuCbfAtDepth(tu, COMP_Y, partitioner.currTrDepth);
2112
136
        }
2113
136
      }
2114
69.1k
      if (!lastCbfIsInferred)
2115
69.1k
      {
2116
69.1k
        cbf_comp(*tu.cu, TU::getCbfAtDepth(tu, COMP_Y, trDepth), tu.Y(), trDepth, previousCbf, cu.ispMode);
2117
69.1k
      }
2118
69.1k
    }
2119
69.3k
  }
2120
153k
  bool        lumaOnly  = ( cu.chromaFormat == CHROMA_400 || !tu.blocks[COMP_Cb].valid() );
2121
153k
  bool        cbf[3]    = { TU::getCbf( tu, COMP_Y ), chromaCbfs.Cb, chromaCbfs.Cr };
2122
153k
  bool        cbfLuma   = ( cbf[ COMP_Y ] != 0 );
2123
153k
  bool        cbfChroma = false;
2124
2125
153k
  if( !lumaOnly )
2126
84.1k
  {
2127
84.1k
    if( tu.blocks[COMP_Cb].valid() )
2128
84.1k
    {
2129
84.1k
      cbf   [ COMP_Cb  ] = TU::getCbf( tu, COMP_Cb );
2130
84.1k
      cbf   [ COMP_Cr  ] = TU::getCbf( tu, COMP_Cr );
2131
84.1k
    }
2132
84.1k
    cbfChroma = ( cbf[ COMP_Cb ] || cbf[ COMP_Cr ] );
2133
84.1k
  }
2134
2135
153k
  if( ( cu.lwidth() > 64 || cu.lheight() > 64 || cbfLuma || cbfChroma ) &&
2136
26.4k
    (!CU::isSepTree(*tu.cu) || isLuma(tu.chType)) )
2137
4.74k
  {
2138
4.74k
    if( cu.cs->pps->useDQP && !cuCtx.isDQPCoded )
2139
2.30k
    {
2140
2.30k
      cu_qp_delta(cu, cuCtx.qp, cu.qp);
2141
2.30k
      cuCtx.qp = cu.qp;
2142
2.30k
      cuCtx.isDQPCoded = true;
2143
2.30k
    }
2144
4.74k
  }
2145
153k
  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
153k
  if( !lumaOnly )
2152
84.1k
  {
2153
84.1k
    joint_cb_cr( tu, ( cbf[COMP_Cb] ? 2 : 0 ) + ( cbf[COMP_Cr] ? 1 : 0 ) );
2154
84.1k
  }
2155
2156
153k
  if( cbfLuma )
2157
4.74k
  {
2158
4.74k
    residual_coding( tu, COMP_Y, &cuCtx );
2159
4.74k
  }
2160
153k
  if( !lumaOnly )
2161
84.1k
  {
2162
252k
    for( ComponentID compID = COMP_Cb; compID <= COMP_Cr; compID = ComponentID( compID + 1 ) )
2163
168k
    {
2164
168k
      if( cbf[ compID ] )
2165
42.9k
      {
2166
42.9k
        residual_coding( tu, compID, &cuCtx );
2167
42.9k
      }
2168
168k
    }
2169
84.1k
  }
2170
153k
}
2171
2172
2173
void CABACWriter::cu_qp_delta( const CodingUnit& cu, int predQP, const int8_t qp )
2174
3.46k
{
2175
3.46k
  CHECK(!( predQP != std::numeric_limits<int>::max()), "Unspecified error");
2176
3.46k
  int       DQp         = qp - predQP;
2177
3.46k
  int       qpBdOffsetY = cu.cs->sps->qpBDOffset[ CH_L ];
2178
3.46k
  DQp                   = ( DQp + (MAX_QP + 1) + (MAX_QP + 1) / 2 + qpBdOffsetY + (qpBdOffsetY / 2)) % ((MAX_QP + 1) + qpBdOffsetY) - (MAX_QP + 1) / 2 - (qpBdOffsetY / 2);
2179
3.46k
  unsigned  absDQP      = unsigned( DQp < 0 ? -DQp : DQp );
2180
3.46k
  unsigned  unaryDQP    = std::min<unsigned>( absDQP, CU_DQP_TU_CMAX );
2181
2182
3.46k
  unary_max_symbol( unaryDQP, Ctx::DeltaQP(), Ctx::DeltaQP(1), CU_DQP_TU_CMAX );
2183
3.46k
  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.46k
  if( absDQP > 0 )
2188
0
  {
2189
0
    m_BinEncoder.encodeBinEP( DQp < 0 );
2190
0
  }
2191
2192
3.46k
  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.46k
}
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.31M
{
2227
1.31M
  if ( !tu.cu->slice->sps->jointCbCr )
2228
0
  {
2229
0
    return;
2230
0
  }
2231
2232
1.31M
  CHECK( tu.jointCbCr && tu.jointCbCr != cbfMask, "wrong value of jointCbCr (" << (int)tu.jointCbCr << " vs " << (int)cbfMask << ")" );
2233
1.31M
  if( ( CU::isIntra( *tu.cu ) && cbfMask ) || ( cbfMask == 3 ) )
2234
619k
  {
2235
619k
    m_BinEncoder.encodeBin( tu.jointCbCr ? 1 : 0, Ctx::JointCbCrFlag( cbfMask - 1 ) );
2236
619k
  }
2237
1.31M
}
2238
2239
2240
void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID, CUCtx* cuCtx )
2241
1.26M
{
2242
1.26M
  const CodingUnit& cu = *tu.cu;
2243
1.26M
  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.26M
  if( compID == COMP_Cr && tu.jointCbCr == 3 )
2246
362k
  {
2247
362k
    return;
2248
362k
  }
2249
2250
901k
  ts_flag            ( tu, compID );
2251
2252
901k
  if( tu.mtsIdx[compID] == MTS_SKIP && !tu.cs->slice->tsResidualCodingDisabled )
2253
63.0k
  {
2254
63.0k
    residual_codingTS( tu, compID );
2255
63.0k
    return;
2256
63.0k
  }
2257
2258
  // determine sign hiding
2259
838k
  bool signHiding  = cu.cs->slice->signDataHidingEnabled;
2260
2261
  // init coeff coding context
2262
838k
  CoeffCodingContext  cctx    ( tu, compID, signHiding, false, m_tplBuf );
2263
838k
  const TCoeffSig*    coeff   = tu.getCoeffs( compID ).buf;
2264
2265
  // determine and set last coeff position and sig group flags
2266
838k
  int                      scanPosLast = tu.lastPos[compID];
2267
838k
  std::bitset<MLS_GRP_NUM> sigGroupFlags;
2268
2269
1.70M
  for( int subSetId = 0; subSetId <= ( scanPosLast >> cctx.log2CGSize() ); subSetId++ )
2270
863k
  {
2271
863k
    const int scanPosStart = subSetId << cctx.log2CGSize();
2272
863k
    const int scanPosEnd   = scanPosStart + ( 1 << cctx.log2CGSize() ) - 1;
2273
2274
7.84M
    for( int scanPos = scanPosEnd; scanPos >= scanPosStart; scanPos-- )
2275
7.83M
    {
2276
7.83M
      unsigned blkPos = cctx.blockPos( scanPos );
2277
2278
7.83M
      if( coeff[blkPos] )
2279
855k
      {
2280
855k
        sigGroupFlags.set( subSetId );
2281
855k
        break;
2282
855k
      }
2283
7.83M
    }
2284
863k
  }
2285
838k
  CHECK( scanPosLast < 0, "Coefficient coding called for empty TU" );
2286
838k
  cctx.setScanPosLast(scanPosLast);
2287
2288
838k
  if( cuCtx && tu.mtsIdx[compID] != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
2289
737k
  {
2290
737k
    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
737k
    cuCtx->violatesLfnstConstrained[ toChannelType(compID) ] |= cctx.scanPosLast() > maxLfnstPos;
2292
737k
  }
2293
838k
  if( cuCtx && tu.mtsIdx[compID] != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
2294
737k
  {
2295
737k
    const int lfnstLastScanPosTh = isLuma( compID ) ? LFNST_LAST_SIG_LUMA : LFNST_LAST_SIG_CHROMA;
2296
737k
    cuCtx->lfnstLastScanPos |= cctx.scanPosLast() >= lfnstLastScanPosTh;
2297
737k
  }
2298
838k
  if (cuCtx && isLuma(compID) && tu.mtsIdx[compID] != MTS_SKIP)
2299
26.5k
  {
2300
26.5k
    cuCtx->mtsLastScanPos |= cctx.scanPosLast() >= 1;
2301
26.5k
  }
2302
  
2303
  // code last coeff position
2304
838k
  last_sig_coeff( cctx, tu, compID );
2305
2306
  // code subblocks
2307
838k
  const int stateTab  = ( tu.cs->slice->depQuantEnabled ? 32040 : 0 );
2308
838k
  int       state     = 0;
2309
2310
838k
  int ctxBinSampleRatio = MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT;
2311
838k
  cctx.remRegBins = (tu.getTbAreaAfterCoefZeroOut(compID) * ctxBinSampleRatio) >> 4;
2312
2313
838k
  const bool zeroOutCheck  = isLuma( compID ) && tu.cs->sps->MTS && tu.cu->sbtInfo != 0 && tu.blocks[compID].height <= 32 && tu.blocks[compID].width <= 32;
2314
838k
  const bool zeroOutWidth  = tu.blocks[compID].width;
2315
838k
  const bool zeroOutHeight = tu.blocks[compID].height;
2316
2317
1.70M
  for( int subSetId = ( cctx.scanPosLast() >> cctx.log2CGSize() ); subSetId >= 0; subSetId--)
2318
863k
  {
2319
863k
    cctx.initSubblock( subSetId, sigGroupFlags[subSetId] );
2320
2321
863k
    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
863k
    residual_coding_subblock( cctx, coeff, stateTab, state );
2330
863k
    if ( cuCtx && isLuma(compID) && cctx.isSigGroup() && ( cctx.cgPosY() > 3 || cctx.cgPosX() > 3 ) )
2331
0
    {
2332
0
      cuCtx->violatesMtsCoeffConstraint = true;
2333
0
    }
2334
863k
  }
2335
838k
}
2336
2337
2338
void CABACWriter::ts_flag( const TransformUnit& tu, ComponentID compID )
2339
901k
{
2340
901k
  int tsFlag = tu.mtsIdx[compID] == MTS_SKIP ? 1 : 0;
2341
901k
  int ctxIdx = isLuma(compID) ? 0 : 1;
2342
  
2343
901k
  if( TU::isTSAllowed ( tu, compID ) )
2344
620k
  {
2345
620k
    m_BinEncoder.encodeBin( tsFlag, Ctx::TransformSkipFlag(ctxIdx));
2346
620k
  }
2347
901k
  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
901k
}
2349
2350
2351
void CABACWriter::mts_idx( const CodingUnit& cu, CUCtx* cuCtx )
2352
177k
{
2353
177k
  TransformUnit &tu = *cu.firstTU;
2354
177k
  int        mtsIdx = tu.mtsIdx[COMP_Y];
2355
  
2356
177k
  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
177k
  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
177k
}
2381
2382
2383
void CABACWriter::isp_mode( const CodingUnit& cu )
2384
859k
{
2385
859k
  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
156k
  {
2387
156k
    CHECK( cu.ispMode != NOT_INTRA_SUBPARTITIONS, "cu.ispMode != 0" );
2388
156k
    return;
2389
156k
  }
2390
702k
  if ( cu.ispMode == NOT_INTRA_SUBPARTITIONS )
2391
693k
  {
2392
693k
    m_BinEncoder.encodeBin( 0, Ctx::ISPMode( 0 ) );
2393
693k
  }
2394
9.77k
  else
2395
9.77k
  {
2396
9.77k
    m_BinEncoder.encodeBin( 1, Ctx::ISPMode( 0 ) );
2397
9.77k
    m_BinEncoder.encodeBin( cu.ispMode - 1, Ctx::ISPMode( 1 ) );
2398
9.77k
  }
2399
702k
  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
702k
}
2401
2402
2403
void CABACWriter::residual_lfnst_mode( const CodingUnit& cu, CUCtx& cuCtx )
2404
257k
{
2405
257k
  int chIdx = CS::isDualITree( *cu.cs ) && cu.chType == CH_C ? 1 : 0;
2406
257k
  if( ( cu.ispMode && !CU::canUseLfnstWithISP( cu, cu.chType ) ) ||
2407
257k
      (cu.cs->sps->LFNST && CU::isIntra(cu) && cu.mipFlag && !allowLfnstWithMip(cu.lumaSize())) ||
2408
255k
    ( CU::isSepTree(cu) && cu.chType == CH_C && std::min( cu.blocks[ 1 ].width, cu.blocks[ 1 ].height ) < 4 )
2409
253k
    || ( cu.blocks[ chIdx ].lumaSize().width > cu.cs->sps->getMaxTbSize() || cu.blocks[ chIdx ].lumaSize().height > cu.cs->sps->getMaxTbSize() )
2410
257k
    )
2411
4.54k
  {
2412
4.54k
    return;
2413
4.54k
  }
2414
2415
253k
  if( cu.cs->sps->LFNST && CU::isIntra( cu )  )
2416
253k
  {
2417
253k
    const bool lumaFlag                   = CU::isSepTree(cu) ? (   isLuma( cu.chType ) ? true : false ) : true;
2418
253k
    const bool chromaFlag                 = CU::isSepTree(cu) ? ( isChroma( cu.chType ) ? true : false ) : true;
2419
253k
          bool nonZeroCoeffNonTsCorner8x8 = ( lumaFlag && cuCtx.violatesLfnstConstrained[CH_L] ) || (chromaFlag && cuCtx.violatesLfnstConstrained[CH_C] );
2420
2421
253k
    bool isTrSkip = false;
2422
2423
253k
    for( const auto& currTU : cTUTraverser( cu.firstTU, cu.lastTU->next ) )
2424
258k
    {
2425
258k
      const uint32_t numValidComp = getNumberValidComponents(cu.chromaFormat);
2426
1.03M
      for (uint32_t compID = COMP_Y; compID < numValidComp; compID++)
2427
775k
      {
2428
775k
        if (currTU.blocks[compID].valid() && TU::getCbf(currTU, (ComponentID)compID) && currTU.mtsIdx[compID] == MTS_SKIP)
2429
53
        {
2430
53
          isTrSkip = true;
2431
53
          break;
2432
53
        }
2433
775k
      }
2434
258k
    }
2435
2436
253k
    if( (!cuCtx.lfnstLastScanPos && !cu.ispMode) || nonZeroCoeffNonTsCorner8x8 || isTrSkip )
2437
238k
    {
2438
238k
      return;
2439
238k
    }
2440
253k
  }
2441
139
  else
2442
139
  {
2443
139
    return;
2444
139
  }
2445
  
2446
15.0k
  unsigned cctx = 0;
2447
15.0k
  if ( CU::isSepTree(cu) ) cctx++;
2448
2449
15.0k
  const uint32_t idxLFNST = cu.lfnstIdx;
2450
15.0k
  assert( idxLFNST < 3 );
2451
15.0k
  m_BinEncoder.encodeBin( idxLFNST ? 1 : 0, Ctx::LFNSTIdx( cctx ) );
2452
2453
15.0k
  if( idxLFNST )
2454
14.6k
  {
2455
14.6k
    m_BinEncoder.encodeBin( (idxLFNST - 1) ? 1 : 0, Ctx::LFNSTIdx(2));
2456
14.6k
  }
2457
2458
15.0k
  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.0k
}
2460
2461
2462
void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx, const TransformUnit& tu, ComponentID compID )
2463
838k
{
2464
838k
  unsigned blkPos = cctx.blockPos( cctx.scanPosLast() );
2465
838k
  unsigned posX, posY;
2466
838k
  {
2467
838k
    posY  = blkPos / cctx.width();
2468
838k
    posX  = blkPos - ( posY * cctx.width() );
2469
838k
  }
2470
2471
838k
  unsigned CtxLast;
2472
838k
  unsigned GroupIdxX = g_uiGroupIdx[ posX ];
2473
838k
  unsigned GroupIdxY = g_uiGroupIdx[ posY ];
2474
2475
838k
  unsigned maxLastPosX = cctx.maxLastPosX();
2476
838k
  unsigned maxLastPosY = cctx.maxLastPosY();
2477
2478
838k
  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
1.95M
  for( CtxLast = 0; CtxLast < GroupIdxX; CtxLast++ )
2485
1.11M
  {
2486
1.11M
    m_BinEncoder.encodeBin( 1, cctx.lastXCtxId( CtxLast ) );
2487
1.11M
  }
2488
838k
  if( GroupIdxX < maxLastPosX )
2489
802k
  {
2490
802k
    m_BinEncoder.encodeBin( 0, cctx.lastXCtxId( CtxLast ) );
2491
802k
  }
2492
2.00M
  for( CtxLast = 0; CtxLast < GroupIdxY; CtxLast++ )
2493
1.16M
  {
2494
1.16M
    m_BinEncoder.encodeBin( 1, cctx.lastYCtxId( CtxLast ) );
2495
1.16M
  }
2496
838k
  if( GroupIdxY < maxLastPosY )
2497
795k
  {
2498
795k
    m_BinEncoder.encodeBin( 0, cctx.lastYCtxId( CtxLast ) );
2499
795k
  }
2500
838k
  if( GroupIdxX > 3 )
2501
2.73k
  {
2502
2.73k
    posX -= g_uiMinInGroup[ GroupIdxX ];
2503
7.89k
    for (int i = ( ( GroupIdxX - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
2504
5.16k
    {
2505
5.16k
      m_BinEncoder.encodeBinEP( ( posX >> i ) & 1 );
2506
5.16k
    }
2507
2.73k
  }
2508
838k
  if( GroupIdxY > 3 )
2509
2.11k
  {
2510
2.11k
    posY -= g_uiMinInGroup[ GroupIdxY ];
2511
5.71k
    for ( int i = ( ( GroupIdxY - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
2512
3.59k
    {
2513
3.59k
      m_BinEncoder.encodeBinEP( ( posY >> i ) & 1 );
2514
3.59k
    }
2515
2.11k
  }
2516
838k
}
2517
2518
2519
void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoeffSig* coeff, const int stateTransTable, int& state )
2520
863k
{
2521
  //===== init =====
2522
863k
  const int   minSubPos   = cctx.minSubPos();
2523
863k
  const bool  isLast      = cctx.isLast();
2524
863k
  int         firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() );
2525
863k
  int         nextSigPos  = firstSigPos;
2526
2527
  //===== encode significant_coeffgroup_flag =====
2528
863k
  if( !isLast && cctx.isNotFirst() )
2529
20.8k
  {
2530
20.8k
    if( cctx.isSigGroup() )
2531
12.7k
    {
2532
12.7k
      m_BinEncoder.encodeBin( 1, cctx.sigGroupCtxId() );
2533
12.7k
    }
2534
8.10k
    else
2535
8.10k
    {
2536
8.10k
      m_BinEncoder.encodeBin( 0, cctx.sigGroupCtxId() );
2537
8.10k
      return;
2538
8.10k
    }
2539
20.8k
  }
2540
2541
  //===== encode absolute values =====
2542
855k
  const int inferSigPos   = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
2543
855k
  int       firstNZPos    = nextSigPos;
2544
855k
  int       lastNZPos     = -1;
2545
855k
  int       remAbsLevel   = -1;
2546
855k
  int       numNonZero    =  0;
2547
855k
  unsigned  signPattern   =  0;
2548
855k
  int       remRegBins    = cctx.remRegBins;
2549
855k
  int       firstPosMode2 = minSubPos - 1;
2550
2551
7.65M
  for( ; nextSigPos >= minSubPos && remRegBins >= 4; nextSigPos-- )
2552
6.80M
  {
2553
6.80M
    const int blkPos     = cctx.blockPos( nextSigPos );
2554
6.80M
    TCoeff    Coeff      = coeff[ blkPos ];
2555
6.80M
    unsigned  sigFlag    = ( Coeff != 0 );
2556
6.80M
    if( numNonZero || nextSigPos != inferSigPos )
2557
5.96M
    {
2558
5.96M
      const unsigned sigCtxId = cctx.sigCtxIdAbsWithAcc( nextSigPos, state );
2559
5.96M
      m_BinEncoder.encodeBin( sigFlag, sigCtxId );
2560
5.96M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2561
5.96M
      remRegBins--;
2562
5.96M
    }
2563
838k
    else if( nextSigPos != cctx.scanPosLast() )
2564
42
    {
2565
42
      cctx.sigCtxIdAbsWithAcc( nextSigPos, state ); // required for setting variables that are needed for gtx/par context selection
2566
42
    }
2567
2568
6.80M
    if( sigFlag )
2569
6.27M
    {
2570
6.27M
      uint8_t ctxOff = cctx.ctxOffsetAbs();
2571
6.27M
      numNonZero++;
2572
6.27M
      firstNZPos  = nextSigPos;
2573
6.27M
      lastNZPos   = std::max<int>( lastNZPos, nextSigPos );
2574
6.27M
      int absLevel= abs( Coeff );
2575
6.27M
      remAbsLevel = absLevel - 1;
2576
2577
6.27M
      if( nextSigPos != cctx.scanPosLast() ) signPattern <<= 1;
2578
6.27M
      if( Coeff < 0 )                        signPattern++;
2579
2580
6.27M
      unsigned gt1 = !!remAbsLevel;
2581
6.27M
      m_BinEncoder.encodeBin( gt1, cctx.greater1CtxIdAbs(ctxOff) );
2582
6.27M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1, cctx.greater1CtxIdAbs(ctxOff) );
2583
6.27M
      remRegBins--;
2584
2585
6.27M
      if( gt1 )
2586
5.41M
      {
2587
5.41M
        remAbsLevel  -= 1;
2588
5.41M
        m_BinEncoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2589
5.41M
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2590
5.41M
        remAbsLevel >>= 1;
2591
2592
5.41M
        remRegBins--;
2593
5.41M
        unsigned gt2 = !!remAbsLevel;
2594
5.41M
        m_BinEncoder.encodeBin(gt2, cctx.greater2CtxIdAbs(ctxOff));
2595
5.41M
        DTRACE(g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2, cctx.greater2CtxIdAbs(ctxOff));
2596
5.41M
        remRegBins--;
2597
5.41M
      }
2598
2599
6.27M
      cctx.absVal1stPass( nextSigPos, std::min<TCoeff>( 4 + ( absLevel & 1 ), absLevel ) );
2600
6.27M
    }
2601
2602
6.80M
    state = ( stateTransTable >> ((state<<2)+((Coeff&1)<<1)) ) & 3;
2603
6.80M
  }
2604
855k
  firstPosMode2 = nextSigPos;
2605
855k
  cctx.remRegBins = remRegBins;
2606
2607
2608
  //===== 2nd PASS: Go-rice codes =====
2609
7.65M
  for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- )
2610
6.80M
  {
2611
6.80M
    unsigned absLevel = abs( coeff[cctx.blockPos( scanPos )] );
2612
2613
6.80M
    if( absLevel >= 4 )
2614
4.29M
    {
2615
4.29M
      int      sumAll   = cctx.templateAbsSum( scanPos, coeff, 4 );
2616
4.29M
      unsigned ricePar  = g_auiGoRiceParsCoeff[sumAll];
2617
4.29M
      unsigned rem      = ( absLevel - 4 ) >> 1;
2618
4.29M
      m_BinEncoder.encodeRemAbsEP( rem, ricePar, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2619
4.29M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
2620
4.29M
    }
2621
6.80M
  }
2622
2623
  //===== coeff bypass ====
2624
950k
  for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
2625
95.2k
  {
2626
95.2k
    TCoeff    Coeff     = coeff[ cctx.blockPos( scanPos ) ];
2627
95.2k
    unsigned  absLevel  = abs( Coeff );
2628
95.2k
    int       sumAll    = cctx.templateAbsSum(scanPos, coeff, 0);
2629
95.2k
    int       rice      = g_auiGoRiceParsCoeff[sumAll];
2630
95.2k
    int       pos0      = g_auiGoRicePosCoeff0(state, rice);
2631
95.2k
    unsigned  rem       = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel );
2632
95.2k
    m_BinEncoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2633
95.2k
    DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
2634
95.2k
    state = ( stateTransTable >> ((state<<2)+((absLevel&1)<<1)) ) & 3;
2635
95.2k
    if( absLevel )
2636
94.9k
    {
2637
94.9k
      numNonZero++;
2638
94.9k
      firstNZPos = scanPos;
2639
94.9k
      lastNZPos   = std::max<int>( lastNZPos, scanPos );
2640
94.9k
      signPattern <<= 1;
2641
94.9k
      if( Coeff < 0 ) signPattern++;
2642
94.9k
    }
2643
95.2k
  }
2644
2645
  //===== encode sign's =====
2646
855k
  unsigned numSigns = numNonZero;
2647
855k
  if( cctx.hideSign( firstNZPos, lastNZPos ) )
2648
0
  {
2649
0
    numSigns    --;
2650
0
    signPattern >>= 1;
2651
0
  }
2652
855k
  m_BinEncoder.encodeBinsEP( signPattern, numSigns );
2653
855k
}
2654
2655
2656
void CABACWriter::residual_codingTS( const TransformUnit& tu, ComponentID compID )
2657
63.0k
{
2658
63.0k
  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
63.0k
  CoeffCodingContext  cctx    ( tu, compID, false, tu.cu->bdpcmM[toChannelType(compID)] );
2662
63.0k
  const TCoeffSig*    coeff   = tu.getCoeffs( compID ).buf;
2663
63.0k
  int maxCtxBins = (cctx.maxNumCoeff() * 7) >> 2;
2664
63.0k
  cctx.remRegBins = maxCtxBins;
2665
2666
  // determine and set last coeff position and sig group flags
2667
63.0k
  std::bitset<MLS_GRP_NUM> sigGroupFlags;
2668
5.80M
  for( int scanPos = 0; scanPos < cctx.maxNumCoeff(); scanPos++)
2669
5.74M
  {
2670
5.74M
    unsigned blkPos = cctx.blockPos( scanPos );
2671
5.74M
    if( coeff[blkPos] )
2672
618k
    {
2673
618k
      sigGroupFlags.set( scanPos >> cctx.log2CGSize() );
2674
618k
    }
2675
5.74M
  }
2676
2677
  // code subblocks
2678
422k
  for( int subSetId = 0; subSetId <= ( cctx.maxNumCoeff() - 1 ) >> cctx.log2CGSize(); subSetId++ )
2679
359k
  {
2680
359k
    cctx.initSubblock         ( subSetId, sigGroupFlags[subSetId] );
2681
359k
    residual_coding_subblockTS( cctx, coeff );
2682
359k
  }
2683
63.0k
}
2684
2685
2686
void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TCoeffSig* coeff )
2687
359k
{
2688
  //===== init =====
2689
359k
  const int   minSubPos   = cctx.maxSubPos();
2690
359k
  int         firstSigPos = cctx.minSubPos();
2691
359k
  int         nextSigPos  = firstSigPos;
2692
2693
  //===== encode significant_coeffgroup_flag =====
2694
359k
  if( !cctx.isLastSubSet() || !cctx.only1stSigGroup() )
2695
349k
  {
2696
349k
    if( cctx.isSigGroup() )
2697
136k
    {
2698
136k
        m_BinEncoder.encodeBin( 1, cctx.sigGroupCtxId( true ) );
2699
136k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 1, cctx.sigGroupCtxId() );
2700
136k
    }
2701
213k
    else
2702
213k
    {
2703
213k
        m_BinEncoder.encodeBin( 0, cctx.sigGroupCtxId( true ) );
2704
213k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 0, cctx.sigGroupCtxId() );
2705
213k
      return;
2706
213k
    }
2707
349k
  }
2708
2709
  //===== encode absolute values =====
2710
145k
  const int inferSigPos   = minSubPos;
2711
145k
  int       remAbsLevel   = -1;
2712
145k
  int       numNonZero    =  0;
2713
2714
145k
  int rightPixel, belowPixel, modAbsCoeff;
2715
2716
145k
  int lastScanPosPass1 = -1;
2717
145k
  int lastScanPosPass2 = -1;
2718
2.28M
  for (; nextSigPos <= minSubPos && cctx.remRegBins >= 4; nextSigPos++)
2719
2.13M
  {
2720
2.13M
    TCoeff    Coeff      = coeff[ cctx.blockPos( nextSigPos ) ];
2721
2.13M
    unsigned  sigFlag    = ( Coeff != 0 );
2722
2.13M
    if( numNonZero || nextSigPos != inferSigPos )
2723
2.13M
    {
2724
2.13M
      const unsigned sigCtxId = cctx.sigCtxIdAbsTS( nextSigPos, coeff );
2725
2.13M
      m_BinEncoder.encodeBin( sigFlag, sigCtxId );
2726
2.13M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2727
2.13M
      cctx.remRegBins--;
2728
2.13M
    }
2729
2730
2.13M
    if( sigFlag )
2731
572k
    {
2732
      //===== encode sign's =====
2733
572k
      int sign = Coeff < 0;
2734
572k
      const unsigned signCtxId = cctx.signCtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm());
2735
572k
      m_BinEncoder.encodeBin(sign, signCtxId);
2736
572k
      cctx.remRegBins--;
2737
572k
      numNonZero++;
2738
572k
      cctx.neighTS(rightPixel, belowPixel, nextSigPos, coeff);
2739
572k
      modAbsCoeff = cctx.deriveModCoeff(rightPixel, belowPixel, abs(Coeff), cctx.bdpcm());
2740
572k
      remAbsLevel = modAbsCoeff - 1;
2741
2742
572k
      unsigned gt1 = !!remAbsLevel;
2743
572k
      const unsigned gt1CtxId = cctx.lrg1CtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm());
2744
572k
      m_BinEncoder.encodeBin(gt1, gt1CtxId);
2745
572k
      DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_gt1_flag() bin=%d ctx=%d\n", gt1, gt1CtxId);
2746
572k
      cctx.remRegBins--;
2747
2748
572k
      if( gt1 )
2749
563k
      {
2750
563k
        remAbsLevel  -= 1;
2751
563k
        m_BinEncoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbsTS() );
2752
563k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbsTS() );
2753
563k
        cctx.remRegBins--;
2754
563k
      }
2755
572k
    }
2756
2.13M
    lastScanPosPass1 = nextSigPos;
2757
2.13M
  }
2758
2759
145k
  int cutoffVal = 2;
2760
145k
  int numGtBins = 4;
2761
2762
2.09M
  for (int scanPos = firstSigPos; scanPos <= minSubPos && cctx.remRegBins >= 4; scanPos++)
2763
1.94M
  {
2764
1.94M
    unsigned absLevel;
2765
1.94M
    cctx.neighTS(rightPixel, belowPixel, scanPos, coeff);
2766
1.94M
    absLevel = cctx.deriveModCoeff(rightPixel, belowPixel, abs(coeff[cctx.blockPos(scanPos)]), cctx.bdpcm());
2767
1.94M
    cutoffVal = 2;
2768
9.73M
    for (int i = 0; i < numGtBins; i++)
2769
7.79M
    {
2770
7.79M
      if (absLevel >= cutoffVal)
2771
1.35M
      {
2772
1.35M
        unsigned gt2 = (absLevel >= (cutoffVal + 2));
2773
1.35M
        m_BinEncoder.encodeBin(gt2, cctx.greaterXCtxIdAbsTS(cutoffVal >> 1));
2774
1.35M
        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.35M
        cctx.remRegBins--;
2776
1.35M
      }
2777
7.79M
      cutoffVal += 2;
2778
7.79M
    }
2779
1.94M
    lastScanPosPass2 = scanPos;
2780
1.94M
  }
2781
2782
  //===== coeff bypass ====
2783
2.47M
  for( int scanPos = firstSigPos; scanPos <= minSubPos; scanPos++ )
2784
2.33M
  {
2785
2.33M
    unsigned absLevel;
2786
2.33M
    cctx.neighTS(rightPixel, belowPixel, scanPos, coeff);
2787
2.33M
    cutoffVal = (scanPos <= lastScanPosPass2 ? 10 : (scanPos <= lastScanPosPass1 ? 2 : 0));
2788
2.33M
    absLevel = cctx.deriveModCoeff(rightPixel, belowPixel, abs(coeff[cctx.blockPos(scanPos)]), cctx.bdpcm()||!cutoffVal);
2789
2.33M
    if( absLevel >= cutoffVal )
2790
490k
    {
2791
      //int       rice = cctx.templateAbsSumTS( scanPos, coeff );
2792
490k
      int       rice = 1;
2793
490k
      unsigned  rem = scanPos <= lastScanPosPass1 ? (absLevel - cutoffVal) >> 1 : absLevel;
2794
490k
      m_BinEncoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2795
490k
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_rem_val() bin=%d ctx=%d sp=%d\n", rem, rice, scanPos );
2796
2797
490k
      if (absLevel && scanPos > lastScanPosPass1)
2798
45.5k
      {
2799
45.5k
        int sign = coeff[cctx.blockPos(scanPos)] < 0;
2800
45.5k
        m_BinEncoder.encodeBinEP(sign);
2801
45.5k
      }
2802
490k
    }
2803
2.33M
  }
2804
145k
}
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.46k
{
2817
3.46k
  CHECK( symbol > maxSymbol, "symbol > maxSymbol" );
2818
3.46k
  const unsigned totalBinsToWrite = std::min( symbol + 1, maxSymbol );
2819
6.92k
  for( unsigned binsWritten = 0; binsWritten < totalBinsToWrite; ++binsWritten )
2820
3.46k
  {
2821
3.46k
    const unsigned nextBin = symbol > binsWritten;
2822
3.46k
    m_BinEncoder.encodeBin( nextBin, binsWritten == 0 ? ctxId0 : ctxIdN );
2823
3.46k
  }
2824
3.46k
}
2825
2826
2827
void CABACWriter::unary_max_eqprob( unsigned symbol, unsigned maxSymbol )
2828
215k
{
2829
215k
  if( maxSymbol == 0 )
2830
0
  {
2831
0
    return;
2832
0
  }
2833
215k
  bool     codeLast = ( maxSymbol > symbol );
2834
215k
  unsigned bins     = 0;
2835
215k
  unsigned numBins  = 0;
2836
215k
  while( symbol-- )
2837
357
  {
2838
357
    bins   <<= 1;
2839
357
    bins   ++;
2840
357
    numBins++;
2841
357
  }
2842
215k
  if( codeLast )
2843
215k
  {
2844
215k
    bins  <<= 1;
2845
215k
    numBins++;
2846
215k
  }
2847
215k
  CHECK(!( numBins <= 32 ), "Unspecified error");
2848
215k
  m_BinEncoder.encodeBinsEP( bins, numBins );
2849
215k
}
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.1k
{
2875
14.1k
  if( isLuma( channel ) )
2876
2.29k
  {
2877
2.29k
    if (alfParam->alfEnabled[COMP_Y])
2878
2.29k
      codeAlfCtuEnabled( cs, COMP_Y, alfParam, numCtus );
2879
2.29k
  }
2880
11.8k
  else
2881
11.8k
  {
2882
11.8k
    if (alfParam->alfEnabled[COMP_Cb])
2883
11.8k
      codeAlfCtuEnabled( cs, COMP_Cb, alfParam, numCtus );
2884
11.8k
    if (alfParam->alfEnabled[COMP_Cr])
2885
11.8k
      codeAlfCtuEnabled( cs, COMP_Cr, alfParam, numCtus );
2886
11.8k
  }
2887
14.1k
}
2888
2889
2890
void CABACWriter::codeAlfCtuEnabled( CodingStructure& cs, ComponentID compID, AlfParam* alfParam, const int numCtus )
2891
25.9k
{
2892
127k
  for( int ctuIdx = 0; ctuIdx < numCtus; ctuIdx++ )
2893
101k
  {
2894
101k
    codeAlfCtuEnabledFlag( cs, ctuIdx, compID );
2895
101k
  }
2896
25.9k
}
2897
2898
2899
void CABACWriter::codeAlfCtuEnabledFlag( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx)
2900
364k
{
2901
364k
  CHECKD( !cs.sps->alfEnabled, "ALF is disabled in SPS" ); 
2902
2903
364k
  const PreCalcValues& pcv = *cs.pcv;
2904
364k
  int                 frame_width_in_ctus = pcv.widthInCtus;
2905
364k
  int                 ry = ctuRsAddr / frame_width_in_ctus;
2906
364k
  int                 rx = ctuRsAddr - ry * frame_width_in_ctus;
2907
364k
  const Position      pos( rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize );
2908
364k
  const uint32_t      curSliceIdx = cs.slice->independentSliceIdx;
2909
364k
  const uint32_t      curTileIdx  = cs.pps->getTileIdx( pos );
2910
364k
  bool                leftAvail   = cs.getCURestricted( pos.offset( -(int)pcv.maxCUSize, 0 ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2911
364k
  bool                aboveAvail  = cs.getCURestricted( pos.offset( 0, -(int)pcv.maxCUSize ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2912
2913
364k
  int leftCTUAddr = leftAvail ? ctuRsAddr - 1 : -1;
2914
364k
  int aboveCTUAddr = aboveAvail ? ctuRsAddr - frame_width_in_ctus : -1;
2915
2916
364k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compIdx ].data();
2917
364k
  int ctx = 0;
2918
364k
  ctx += leftCTUAddr > -1 ? ( ctbAlfFlag[leftCTUAddr] ? 1 : 0 ) : 0;
2919
364k
  ctx += aboveCTUAddr > -1 ? ( ctbAlfFlag[aboveCTUAddr] ? 1 : 0 ) : 0;
2920
364k
  m_BinEncoder.encodeBin( ctbAlfFlag[ctuRsAddr], Ctx::ctbAlfFlag( compIdx * 3 + ctx ) );
2921
364k
}
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.12M
{
2968
1.12M
  if( !cu.Y().valid() )
2969
0
  {
2970
0
    return;
2971
0
  }
2972
1.12M
  if( !cu.cs->sps->MIP )
2973
0
  {
2974
0
    return;
2975
0
  }
2976
2977
1.12M
  unsigned ctxId = DeriveCtx::CtxMipFlag( cu );
2978
1.12M
  m_BinEncoder.encodeBin( cu.mipFlag, Ctx::MipFlag( ctxId ) );
2979
1.12M
  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.12M
}
2981
2982
2983
void CABACWriter::mip_pred_modes( const CodingUnit& cu )
2984
1.53k
{
2985
1.53k
  if( !cu.Y().valid() )
2986
0
  {
2987
0
    return;
2988
0
  }
2989
2990
1.53k
  mip_pred_mode( cu );
2991
1.53k
}
2992
2993
2994
void CABACWriter::mip_pred_mode( const CodingUnit& cu )
2995
264k
{
2996
264k
  m_BinEncoder.encodeBinEP( (cu.mipTransposedFlag ? 1 : 0) );
2997
2998
264k
  const int numModes = getNumModesMip( cu.Y() );
2999
264k
  CHECKD( cu.intraDir[CH_L] < 0 || cu.intraDir[CH_L] >= numModes, "Invalid MIP mode" );
3000
264k
  xWriteTruncBinCode( cu.intraDir[CH_L], numModes );
3001
3002
264k
  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
264k
}
3004
3005
3006
void CABACWriter::codeAlfCtuFilterIndex(CodingStructure& cs, uint32_t ctuRsAddr)
3007
71.8k
{
3008
71.8k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ COMP_Y ].data();
3009
71.8k
  if (!ctbAlfFlag[ctuRsAddr])
3010
0
  {
3011
0
    return;
3012
0
  }
3013
3014
71.8k
  const short* alfCtbFilterIndex = cs.slice->pic->m_alfCtbFilterIndex.data();
3015
71.8k
  const unsigned filterSetIdx = alfCtbFilterIndex[ctuRsAddr];
3016
71.8k
  unsigned numAps = cs.slice->numAps;
3017
71.8k
  unsigned numAvailableFiltSets = numAps + NUM_FIXED_FILTER_SETS;
3018
71.8k
  if (numAvailableFiltSets > NUM_FIXED_FILTER_SETS)
3019
14.3k
  {
3020
14.3k
    int useTemporalFilt = (filterSetIdx >= NUM_FIXED_FILTER_SETS) ? 1 : 0;
3021
14.3k
    m_BinEncoder.encodeBin(useTemporalFilt, Ctx::AlfUseTemporalFilt());
3022
14.3k
    if (useTemporalFilt)
3023
14.3k
    {
3024
14.3k
      CHECK((filterSetIdx - NUM_FIXED_FILTER_SETS) >= (numAvailableFiltSets - NUM_FIXED_FILTER_SETS), "temporal non-latest set");
3025
14.3k
      if (numAps > 1)
3026
0
      {
3027
0
        xWriteTruncBinCode(filterSetIdx - NUM_FIXED_FILTER_SETS, numAvailableFiltSets - NUM_FIXED_FILTER_SETS);
3028
0
      }
3029
14.3k
    }
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
14.3k
  }
3036
57.4k
  else
3037
57.4k
  {
3038
57.4k
    CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set numavail < num_fixed");
3039
57.4k
    xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS);
3040
57.4k
  }
3041
71.8k
}
3042
3043
3044
void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ChannelType channel, AlfParam* alfParam, const int numCtus )
3045
14.1k
{
3046
14.1k
  if( isChroma( channel ) )
3047
11.8k
  {
3048
11.8k
    if (alfParam->alfEnabled[COMP_Cb])
3049
11.8k
      codeAlfCtuAlternatives( cs, COMP_Cb, alfParam, numCtus );
3050
11.8k
    if (alfParam->alfEnabled[COMP_Cr])
3051
11.8k
      codeAlfCtuAlternatives( cs, COMP_Cr, alfParam, numCtus );
3052
11.8k
  }
3053
14.1k
}
3054
3055
3056
void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ComponentID compID, AlfParam* alfParam, const int numCtus)
3057
23.6k
{
3058
23.6k
  if( compID == COMP_Y )
3059
0
    return;
3060
23.6k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compID ].data();
3061
3062
117k
  for( int ctuIdx = 0; ctuIdx < numCtus; ctuIdx++ )
3063
94.1k
  {
3064
94.1k
    if( ctbAlfFlag[ctuIdx] )
3065
94.1k
    {
3066
94.1k
      codeAlfCtuAlternative( cs, ctuIdx, compID, alfParam );
3067
94.1k
    }
3068
94.1k
  }
3069
23.6k
}
3070
3071
3072
void CABACWriter::codeAlfCtuAlternative( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx, const AlfParam* alfParam)
3073
479k
{
3074
479k
  if( compIdx == COMP_Y )
3075
0
    return;
3076
3077
479k
  {
3078
479k
    const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compIdx ].data();
3079
3080
479k
    if( ctbAlfFlag[ctuRsAddr] )
3081
479k
    {
3082
479k
      const int numAlts = alfParam->numAlternativesChroma;
3083
479k
      const uint8_t* ctbAlfAlternative = cs.slice->pic->m_alfCtuAlternative[compIdx].data();
3084
479k
      unsigned numOnes = ctbAlfAlternative[ctuRsAddr];
3085
479k
      assert( ctbAlfAlternative[ctuRsAddr] < numAlts );
3086
1.37M
      for( int i = 0; i < numOnes; ++i )
3087
891k
        m_BinEncoder.encodeBin( 1, Ctx::ctbAlfAlternative( compIdx-1 ) );
3088
479k
      if( numOnes < numAlts-1 )
3089
361k
        m_BinEncoder.encodeBin( 0, Ctx::ctbAlfAlternative( compIdx-1 ) );
3090
479k
    }
3091
479k
  }
3092
479k
}
3093
3094
} // namespace vvenc
3095
3096
//! \}
3097