Coverage Report

Created: 2026-06-10 07:00

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