Coverage Report

Created: 2026-06-15 06:25

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