Coverage Report

Created: 2026-10-17 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/vvenc/source/Lib/EncoderLib/CABACWriter.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
The copyright in this software is being made available under the Clear BSD
3
License, included below. No patent rights, trademark rights and/or 
4
other Intellectual Property Rights other than the copyrights concerning 
5
the Software are granted under this license.
6
7
The Clear BSD License
8
9
Copyright (c) 2019-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVenC Authors.
10
All rights reserved.
11
12
Redistribution and use in source and binary forms, with or without modification,
13
are permitted (subject to the limitations in the disclaimer below) provided that
14
the following conditions are met:
15
16
     * Redistributions of source code must retain the above copyright notice,
17
     this list of conditions and the following disclaimer.
18
19
     * Redistributions in binary form must reproduce the above copyright
20
     notice, this list of conditions and the following disclaimer in the
21
     documentation and/or other materials provided with the distribution.
22
23
     * Neither the name of the copyright holder nor the names of its
24
     contributors may be used to endorse or promote products derived from this
25
     software without specific prior written permission.
26
27
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
28
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
29
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
31
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
32
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
36
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
POSSIBILITY OF SUCH DAMAGE.
39
40
41
------------------------------------------------------------------------------------------- */
42
43
44
/** \file     CABACWriter.cpp
45
 *  \brief    Writer for low level syntax
46
 */
47
48
#include "CABACWriter.h"
49
#include "EncLib.h"
50
#include "CommonLib/Contexts.h"
51
#include "CommonLib/UnitTools.h"
52
#include "CommonLib/SampleAdaptiveOffset.h"
53
#include "CommonLib/dtrace_buffer.h"
54
55
#include <map>
56
#include <algorithm>
57
58
//! \ingroup EncoderLib
59
//! \{
60
61
namespace vvenc {
62
63
void CABACWriter::initCtxModels( const Slice& slice )
64
11.6k
{
65
11.6k
  int       qp                = slice.sliceQp;
66
11.6k
  SliceType sliceType         = slice.sliceType;
67
11.6k
  SliceType encCABACTableIdx  = slice.encCABACTableIdx;
68
11.6k
  if( !slice.isIntra() && (encCABACTableIdx==VVENC_B_SLICE || encCABACTableIdx==VVENC_P_SLICE) && slice.pps->cabacInitPresent )
69
0
  {
70
0
    sliceType = encCABACTableIdx;
71
0
  }
72
11.6k
  m_BinEncoder.reset( qp, (int)sliceType );
73
11.6k
}
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.15k
{
145
1.15k
  m_BinEncoder.encodeBinTrm ( 1 );
146
1.15k
  m_BinEncoder.finish       ();
147
1.15k
}
148
149
150
//================================================================================
151
//  clause 7.3.8.2
152
//--------------------------------------------------------------------------------
153
//    bool  coding_tree_unit( cs, area, qp, ctuRsAddr, skipSao, skipAlf )
154
//================================================================================
155
156
void CABACWriter::coding_tree_unit( CodingStructure& cs, const UnitArea& area, int (&qps)[2], unsigned ctuRsAddr, bool skipSao /* = false */, bool skipAlf /* = false */ )
157
7.00k
{
158
7.00k
  CUCtx cuCtx( qps[CH_L] );
159
7.00k
  Partitioner *partitioner = &m_partitioner[0];
160
161
7.00k
  partitioner->initCtu( area, CH_L, *cs.slice );
162
163
7.00k
  if( !skipSao )
164
3.50k
  {
165
3.50k
    sao( *cs.slice, ctuRsAddr );
166
3.50k
  }
167
168
7.00k
  if (!skipAlf)
169
3.50k
  {
170
14.0k
    for (int compIdx = 0; compIdx < MAX_NUM_COMP; compIdx++)
171
10.5k
    {
172
10.5k
      if(cs.slice->alfEnabled[compIdx])
173
0
      {
174
0
        codeAlfCtuEnabledFlag(cs, ctuRsAddr, compIdx);
175
0
        if (isLuma(ComponentID(compIdx)))
176
0
        {
177
0
          codeAlfCtuFilterIndex(cs, ctuRsAddr);
178
0
        }
179
0
        if (isChroma(ComponentID(compIdx)))
180
0
        {
181
0
          codeAlfCtuAlternative(cs, ctuRsAddr, compIdx, &cs.slice->alfAps[cs.slice->chromaApsId]->alfParam );
182
0
        }
183
0
      }
184
10.5k
    }
185
3.50k
  }
186
187
7.00k
  if ( !skipAlf )
188
3.50k
  {
189
10.5k
    for ( int compIdx = 1; compIdx < getNumberValidComponents( cs.pcv->chrFormat ); compIdx++ )
190
7.00k
    {
191
7.00k
      if (cs.slice->ccAlfFilterParam.ccAlfFilterEnabled[compIdx - 1])
192
0
      {
193
0
        const int filterCount   = cs.slice->ccAlfFilterParam.ccAlfFilterCount[compIdx - 1];
194
195
0
        const int      ry = ctuRsAddr / cs.pcv->widthInCtus;
196
0
        const int      rx = ctuRsAddr % cs.pcv->widthInCtus;
197
0
        const Position lumaPos(rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize);
198
199
0
        codeCcAlfFilterControlIdc(cs.slice->ccAlfFilterControl[compIdx - 1][ctuRsAddr], cs, ComponentID(compIdx),
200
0
                                  ctuRsAddr, cs.slice->ccAlfFilterControl[compIdx - 1], lumaPos, filterCount);
201
0
      }
202
7.00k
    }
203
3.50k
  }
204
205
7.00k
  if ( CS::isDualITree(cs) && cs.pcv->chrFormat != CHROMA_400 && cs.pcv->maxCUSize > 64 )
206
7.00k
  {
207
7.00k
    CUCtx chromaCuCtx(qps[CH_C]);
208
7.00k
    Partitioner *chromaPartitioner = &m_partitioner[1];
209
7.00k
    chromaPartitioner->initCtu(area, CH_C, *cs.slice);
210
7.00k
    coding_tree(cs, *partitioner, cuCtx, chromaPartitioner, &chromaCuCtx);
211
7.00k
    qps[CH_L] = cuCtx.qp;
212
7.00k
    qps[CH_C] = chromaCuCtx.qp;
213
7.00k
  }
214
0
  else
215
0
  {
216
0
    coding_tree( cs, *partitioner, cuCtx );
217
0
    qps[CH_L] = cuCtx.qp;
218
0
    if( CS::isDualITree( cs ) && cs.pcv->chrFormat != CHROMA_400 )
219
0
    {
220
0
      CUCtx cuCtxChroma( qps[CH_C] );
221
0
      partitioner->initCtu( area, CH_C, *cs.slice );
222
0
      coding_tree( cs, *partitioner, cuCtxChroma );
223
0
      qps[CH_C] = cuCtxChroma.qp;
224
0
    }
225
0
  }
226
7.00k
}
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.50k
{
239
3.50k
  const SPS& sps = *slice.sps;
240
3.50k
  if( !sps.saoEnabled )
241
0
  {
242
0
    return;
243
0
  }
244
245
3.50k
  CodingStructure&     cs                     = *slice.pic->cs;
246
3.50k
  const PreCalcValues& pcv                    = *cs.pcv;
247
3.50k
  const SAOBlkParam&  sao_ctu_pars            = cs.picture->getSAO()[ctuRsAddr];
248
3.50k
  bool                slice_sao_luma_flag     = ( slice.saoEnabled[ CH_L ] );
249
3.50k
  bool                slice_sao_chroma_flag   = ( slice.saoEnabled[ CH_C ] && sps.chromaFormatIdc != CHROMA_400 );
250
3.50k
  if( !slice_sao_luma_flag && !slice_sao_chroma_flag )
251
0
  {
252
0
    return;
253
0
  }
254
255
3.50k
  bool                sliceEnabled[3]         = { slice_sao_luma_flag, slice_sao_chroma_flag, slice_sao_chroma_flag };
256
3.50k
  int                 frame_width_in_ctus     = pcv.widthInCtus;
257
3.50k
  int                 ry                      = ctuRsAddr      / frame_width_in_ctus;
258
3.50k
  int                 rx                      = ctuRsAddr - ry * frame_width_in_ctus;
259
3.50k
  const Position      pos                     ( rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize );
260
3.50k
  const unsigned      curSliceIdx             = slice.independentSliceIdx;
261
3.50k
  const unsigned      curTileIdx              = cs.pps->getTileIdx( pos );
262
3.50k
  bool                leftMergeAvail          = cs.getCURestricted( pos.offset( -(int)pcv.maxCUSize, 0  ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
263
3.50k
  bool                aboveMergeAvail         = cs.getCURestricted( pos.offset( 0, -(int)pcv.maxCUSize ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
264
3.50k
  sao_block_pars( sao_ctu_pars, sps.bitDepths, sliceEnabled, leftMergeAvail, aboveMergeAvail, false );
265
3.50k
}
266
267
268
void CABACWriter::sao_block_pars( const SAOBlkParam& saoPars, const BitDepths& bitDepths, const bool* sliceEnabled, bool leftMergeAvail, bool aboveMergeAvail, bool onlyEstMergeInfo )
269
13.5k
{
270
13.5k
  bool isLeftMerge  = false;
271
13.5k
  bool isAboveMerge = false;
272
13.5k
  if( leftMergeAvail )
273
6.55k
  {
274
    // sao_merge_left_flag
275
6.55k
    isLeftMerge   = ( saoPars[COMP_Y].modeIdc == SAO_MODE_MERGE && saoPars[COMP_Y].typeIdc == SAO_MERGE_LEFT );
276
6.55k
    m_BinEncoder.encodeBin( (isLeftMerge), Ctx::SaoMergeFlag() );
277
6.55k
  }
278
13.5k
  if( aboveMergeAvail && !isLeftMerge )
279
5.63k
  {
280
    // sao_merge_above_flag
281
5.63k
    isAboveMerge  = ( saoPars[COMP_Y].modeIdc == SAO_MODE_MERGE && saoPars[COMP_Y].typeIdc == SAO_MERGE_ABOVE );
282
5.63k
    m_BinEncoder.encodeBin( (isAboveMerge), Ctx::SaoMergeFlag() );
283
5.63k
  }
284
13.5k
  if( onlyEstMergeInfo )
285
3.50k
  {
286
3.50k
    return; //only for RDO
287
3.50k
  }
288
10.0k
  if( !isLeftMerge && !isAboveMerge )
289
4.65k
  {
290
    // explicit parameters
291
18.6k
    for( int compIdx=0; compIdx < MAX_NUM_COMP; compIdx++ )
292
13.9k
    {
293
13.9k
      sao_offset_pars( saoPars[compIdx], ComponentID(compIdx), sliceEnabled[compIdx], bitDepths[ toChannelType(ComponentID(compIdx)) ] );
294
13.9k
    }
295
4.65k
  }
296
10.0k
}
297
298
299
void CABACWriter::sao_offset_pars( const SAOOffset& ctbPars, ComponentID compID, bool sliceEnabled, int bitDepth )
300
77.0k
{
301
77.0k
  if( !sliceEnabled )
302
0
  {
303
0
    CHECK( ctbPars.modeIdc != SAO_MODE_OFF, "Sao must be off, if it is disabled on slice level" );
304
0
    return;
305
0
  }
306
77.0k
  const bool isFirstCompOfChType = ( getFirstComponentOfChannel( toChannelType(compID) ) == compID );
307
308
77.0k
  if( isFirstCompOfChType )
309
51.3k
  {
310
    // sao_type_idx_luma / sao_type_idx_chroma
311
51.3k
    if( ctbPars.modeIdc == SAO_MODE_OFF )
312
16.2k
    {
313
16.2k
      m_BinEncoder.encodeBin  ( 0, Ctx::SaoTypeIdx() );
314
16.2k
    }
315
35.0k
    else if( ctbPars.typeIdc == SAO_TYPE_BO )
316
7.05k
    {
317
7.05k
      m_BinEncoder.encodeBin  ( 1, Ctx::SaoTypeIdx() );
318
7.05k
      m_BinEncoder.encodeBinEP( 0 );
319
7.05k
    }
320
28.0k
    else
321
28.0k
    {
322
28.0k
      CHECK(!( ctbPars.typeIdc < SAO_TYPE_START_BO ), "Unspecified error");
323
28.0k
      m_BinEncoder.encodeBin  ( 1, Ctx::SaoTypeIdx() );
324
28.0k
      m_BinEncoder.encodeBinEP( 1 );
325
28.0k
    }
326
51.3k
  }
327
328
77.0k
  if( ctbPars.modeIdc == SAO_MODE_NEW )
329
52.5k
  {
330
52.5k
    const int maxOffsetQVal = SampleAdaptiveOffset::getMaxOffsetQVal( bitDepth );
331
52.5k
    int       numClasses    = ( ctbPars.typeIdc == SAO_TYPE_BO ? 4 : NUM_SAO_EO_CLASSES );
332
52.5k
    int       k             = 0;
333
52.5k
    int       offset[4];
334
304k
    for( int i = 0; i < numClasses; i++ )
335
252k
    {
336
252k
      if( ctbPars.typeIdc != SAO_TYPE_BO && i == SAO_CLASS_EO_PLAIN )
337
42.0k
      {
338
42.0k
        continue;
339
42.0k
      }
340
210k
      int classIdx = ( ctbPars.typeIdc == SAO_TYPE_BO ? ( ctbPars.typeAuxInfo + i ) % NUM_SAO_BO_CLASSES : i );
341
210k
      offset[k++]  = ctbPars.offset[classIdx];
342
210k
    }
343
344
    // sao_offset_abs
345
262k
    for( int i = 0; i < 4; i++ )
346
210k
    {
347
210k
      unsigned absOffset = ( offset[i] < 0 ? -offset[i] : offset[i] );
348
210k
      unary_max_eqprob( absOffset, maxOffsetQVal );
349
210k
    }
350
351
    // band offset mode
352
52.5k
    if( ctbPars.typeIdc == SAO_TYPE_BO )
353
10.5k
    {
354
      // sao_offset_sign
355
52.7k
      for( int i = 0; i < 4; i++ )
356
42.2k
      {
357
42.2k
        if( offset[i] )
358
289
        {
359
289
          m_BinEncoder.encodeBinEP( (offset[i] < 0) );
360
289
        }
361
42.2k
      }
362
      // sao_band_position
363
10.5k
      m_BinEncoder.encodeBinsEP( ctbPars.typeAuxInfo, NUM_SAO_BO_CLASSES_LOG2 );
364
10.5k
    }
365
    // edge offset mode
366
42.0k
    else
367
42.0k
    {
368
42.0k
      if( isFirstCompOfChType )
369
28.0k
      {
370
        // sao_eo_class_luma / sao_eo_class_chroma
371
28.0k
        CHECK( ctbPars.typeIdc - SAO_TYPE_START_EO < 0, "sao edge offset class is outside valid range" );
372
28.0k
        m_BinEncoder.encodeBinsEP( ctbPars.typeIdc - SAO_TYPE_START_EO, NUM_SAO_EO_TYPES_LOG2 );
373
28.0k
      }
374
42.0k
    }
375
52.5k
  }
376
77.0k
}
377
378
379
//================================================================================
380
//  clause 7.3.8.4
381
//--------------------------------------------------------------------------------
382
//    void  coding_tree       ( cs, partitioner, cuCtx )
383
//    void  split_cu_flag     ( split, cs, partitioner )
384
//    void  split_cu_mode_mt  ( split, cs, partitioner )
385
//================================================================================
386
387
void CABACWriter::coding_tree(const CodingStructure& cs, Partitioner& partitioner, CUCtx& cuCtx, Partitioner* pPartitionerChroma, CUCtx* pCuCtxChroma)
388
153k
{
389
153k
  const PPS      &pps         = *cs.pps;
390
153k
  const UnitArea& currArea    = partitioner.currArea();
391
153k
  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
153k
  if( pps.useDQP && partitioner.currQgEnable() && !isChroma( partitioner.chType ) )
396
13.3k
  {
397
13.3k
    cuCtx.qgStart    = true;
398
13.3k
    cuCtx.isDQPCoded          = false;
399
13.3k
  }
400
153k
  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
153k
  if (CS::isDualITree(cs) && pPartitionerChroma != nullptr)
406
7.00k
  {
407
7.00k
    if (pps.useDQP && pPartitionerChroma->currQgEnable())
408
7.00k
    {
409
7.00k
      pCuCtxChroma->qgStart    = true;
410
7.00k
      pCuCtxChroma->isDQPCoded = false;
411
7.00k
    }
412
7.00k
    if (cs.slice->chromaQpAdjEnabled && pPartitionerChroma->currQgChromaEnable())
413
0
    {
414
0
      pCuCtxChroma->isChromaQpAdjCoded = false;
415
0
    }
416
7.00k
  }
417
418
153k
  determineNeighborCus( cs, partitioner.currArea(), partitioner.chType, partitioner.treeType );
419
420
153k
  const PartSplit splitMode = CU::getSplitAtDepth( cu, partitioner.currDepth );
421
422
153k
  split_cu_mode( splitMode, cs, partitioner );
423
424
153k
  CHECK( !partitioner.canSplit( splitMode, cs ), "The chosen split mode is invalid!" );
425
426
153k
  if( splitMode != CU_DONT_SPLIT )
427
79.2k
  {
428
79.2k
    if (CS::isDualITree(cs) && pPartitionerChroma != nullptr && (partitioner.currArea().lwidth() >= 64 || partitioner.currArea().lheight() >= 64))
429
7.00k
    {
430
7.00k
      partitioner.splitCurrArea(CU_QUAD_SPLIT, cs);
431
7.00k
      pPartitionerChroma->splitCurrArea(CU_QUAD_SPLIT, cs);
432
7.00k
      bool beContinue = true;
433
7.00k
      bool lumaContinue = true;
434
7.00k
      bool chromaContinue = true;
435
436
35.0k
      while (beContinue)
437
28.0k
      {
438
28.0k
        if (partitioner.currArea().lwidth() > 64 || partitioner.currArea().lheight() > 64)
439
0
        {
440
0
          if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos()))
441
0
          {
442
0
            coding_tree(cs, partitioner, cuCtx, pPartitionerChroma, pCuCtxChroma);
443
0
          }
444
0
          lumaContinue = partitioner.nextPart(cs);
445
0
          chromaContinue = pPartitionerChroma->nextPart(cs);
446
0
          CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched");
447
0
          beContinue = lumaContinue;
448
0
        }
449
28.0k
        else
450
28.0k
        {
451
          //dual tree coding under 64x64 block
452
28.0k
          if (cs.picture->blocks[partitioner.chType].contains(partitioner.currArea().blocks[partitioner.chType].pos()))
453
18.5k
          {
454
18.5k
            coding_tree(cs, partitioner, cuCtx);
455
18.5k
          }
456
28.0k
          lumaContinue = partitioner.nextPart(cs);
457
28.0k
          if (cs.picture->blocks[pPartitionerChroma->chType].contains(pPartitionerChroma->currArea().blocks[pPartitionerChroma->chType].pos()))
458
18.5k
          {
459
18.5k
            coding_tree(cs, *pPartitionerChroma, *pCuCtxChroma);
460
18.5k
          }
461
28.0k
          chromaContinue = pPartitionerChroma->nextPart(cs);
462
28.0k
          CHECK(lumaContinue != chromaContinue, "luma chroma partition should be matched");
463
28.0k
          beContinue = lumaContinue;
464
28.0k
        }
465
28.0k
      }
466
7.00k
      partitioner.exitCurrSplit();
467
7.00k
      pPartitionerChroma->exitCurrSplit();
468
469
7.00k
    }
470
72.2k
    else
471
72.2k
    {
472
72.2k
      const ModeType modeTypeParent = partitioner.modeType;
473
72.2k
      const ModeType modeTypeChild = CU::getModeTypeAtDepth( cu, partitioner.currDepth );
474
72.2k
      mode_constraint( splitMode, cs, partitioner, modeTypeChild );
475
72.2k
      partitioner.modeType = modeTypeChild;
476
477
72.2k
      bool chromaNotSplit = modeTypeParent == MODE_TYPE_ALL && modeTypeChild == MODE_TYPE_INTRA ? true : false;
478
72.2k
      CHECK( chromaNotSplit && partitioner.chType != CH_L, "chType must be luma" );
479
72.2k
      if( partitioner.treeType == TREE_D )
480
72.2k
      {
481
72.2k
        partitioner.treeType = chromaNotSplit ? TREE_L : TREE_D;
482
72.2k
      }
483
72.2k
      partitioner.splitCurrArea( splitMode, cs );
484
485
72.2k
      do
486
179k
      {
487
179k
        if( cs.picture->blocks[partitioner.chType].contains( partitioner.currArea().blocks[partitioner.chType].pos() ) )
488
109k
        {
489
109k
          coding_tree( cs, partitioner, cuCtx );
490
109k
        }
491
179k
      } while( partitioner.nextPart( cs ) );
492
493
72.2k
      partitioner.exitCurrSplit();
494
72.2k
      if( chromaNotSplit )
495
0
      {
496
0
        if (isChromaEnabled(cs.pcv->chrFormat))
497
0
        {
498
0
          CHECK( partitioner.chType != CH_L, "must be luma status" );
499
0
          partitioner.chType = CH_C;
500
0
          partitioner.treeType = TREE_C;
501
502
0
          if( cs.picture->blocks[partitioner.chType].contains( partitioner.currArea().blocks[partitioner.chType].pos() ) )
503
0
          {
504
0
            coding_tree( cs, partitioner, cuCtx );
505
0
          }
506
0
        }
507
        //recover
508
0
        partitioner.chType = CH_L;
509
0
        partitioner.treeType = TREE_D;
510
0
      }
511
72.2k
      partitioner.modeType = modeTypeParent;
512
72.2k
    }
513
79.2k
    return;
514
79.2k
  }
515
516
  // Predict QP on start of quantization group
517
74.2k
  if( cuCtx.qgStart )
518
17.9k
  {
519
17.9k
    cuCtx.qgStart = false;
520
17.9k
    cuCtx.qp = CU::predictQP( cu, cuCtx.qp );
521
17.9k
  }
522
74.2k
  CHECK( cu.treeType != partitioner.treeType, "treeType mismatch" );
523
524
525
  // coding unit
526
74.2k
  coding_unit( cu, partitioner, cuCtx );
527
528
74.2k
  if( cu.chType == CH_C )
529
29.6k
  {
530
29.6k
    DTRACE_COND( (isEncoding()), g_trace_ctx, D_QP, "[chroma CU]x=%d, y=%d, w=%d, h=%d, qp=%d\n", cu.Cb().x, cu.Cb().y, cu.Cb().width, cu.Cb().height, cu.qp );
531
29.6k
  }
532
44.6k
  else
533
44.6k
  {
534
44.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
44.6k
  }
536
74.2k
  DTRACE_BLOCK_REC_COND( ( !isEncoding() ), cs.picture->getRecoBuf( cu ), cu, cu.predMode );
537
74.2k
}
538
539
540
void CABACWriter::mode_constraint( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner, const ModeType modeType )
541
240k
{
542
240k
  CHECK( split == CU_DONT_SPLIT, "splitMode shall not be no split" );
543
240k
  int val = CS::signalModeCons( cs, partitioner.currArea(), split, partitioner.modeType);
544
240k
  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
240k
  else if( val == LDT_MODE_TYPE_INFER )
553
0
  {
554
0
    CHECK( modeType != MODE_TYPE_INTRA, "Wrong mode type" );
555
0
  }
556
240k
  else
557
240k
  {
558
240k
    CHECK( modeType != partitioner.modeType, "Wrong mode type" );
559
240k
  }
560
240k
}
561
562
563
void CABACWriter::split_cu_mode( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner )
564
421k
{
565
421k
  bool canNo, canQt, canBh, canBv, canTh, canTv;
566
421k
  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv );
567
568
421k
  const bool canSpl[6] = { canNo, canQt, canBh, canBv, canTh, canTv };
569
570
421k
  unsigned ctxSplit = 0, ctxQtSplit = 0, ctxBttHV = 0, ctxBttH12 = 0, ctxBttV12;
571
421k
  DeriveCtx::CtxSplit( partitioner, ctxSplit, ctxQtSplit, ctxBttHV, ctxBttH12, ctxBttV12, canSpl );
572
573
421k
  const bool canSplit = canBh || canBv || canTh || canTv || canQt;
574
421k
  const bool isNo     = split == CU_DONT_SPLIT;
575
576
421k
  if( canNo && canSplit )
577
256k
  {
578
256k
    m_BinEncoder.encodeBin( !isNo, Ctx::SplitFlag( ctxSplit ) );
579
256k
  }
580
581
421k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d split=%d\n", ctxSplit, !isNo );
582
583
421k
  if( isNo )
584
173k
  {
585
173k
    return;
586
173k
  }
587
588
247k
  const bool canBtt = canBh || canBv || canTh || canTv;
589
247k
  const bool isQt   = split == CU_QUAD_SPLIT;
590
591
247k
  if( canQt && canBtt )
592
97.8k
  {
593
97.8k
    m_BinEncoder.encodeBin( isQt, Ctx::SplitQtFlag( ctxQtSplit ) );
594
97.8k
  }
595
596
247k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctx=%d qt=%d\n", ctxQtSplit, isQt );
597
598
247k
  if( isQt )
599
62.8k
  {
600
62.8k
    return;
601
62.8k
  }
602
603
185k
  const bool canHor = canBh || canTh;
604
185k
  const bool canVer = canBv || canTv;
605
185k
  const bool  isVer = split == CU_VERT_SPLIT || split == CU_TRIV_SPLIT;
606
607
185k
  if( canVer && canHor )
608
95.9k
  {
609
95.9k
    m_BinEncoder.encodeBin( isVer, Ctx::SplitHvFlag( ctxBttHV ) );
610
95.9k
  }
611
612
185k
  const bool can14 = isVer ? canTv : canTh;
613
185k
  const bool can12 = isVer ? canBv : canBh;
614
185k
  const bool  is12 = isVer ? ( split == CU_VERT_SPLIT ) : ( split == CU_HORZ_SPLIT );
615
616
185k
  if( can12 && can14 )
617
51.9k
  {
618
51.9k
    m_BinEncoder.encodeBin( is12, Ctx::Split12Flag( isVer ? ctxBttV12 : ctxBttH12 ) );
619
51.9k
  }
620
621
185k
  DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() ctxHv=%d ctx12=%d mode=%d\n", ctxBttHV, isVer ? ctxBttV12 : ctxBttH12, split );
622
185k
}
623
624
625
//================================================================================
626
//  clause 7.3.8.5
627
//--------------------------------------------------------------------------------
628
//    void  coding_unit               ( cu, partitioner, cuCtx )
629
//    void  cu_skip_flag              ( cu )
630
//    void  pred_mode                 ( cu )
631
//    void  part_mode                 ( cu )
632
//    void  cu_pred_data              ( pus )
633
//    void  cu_lic_flag               ( cu )
634
//    void  intra_luma_pred_modes     ( pus )
635
//    void  intra_chroma_pred_mode    ( cu )
636
//    void  cu_residual               ( cu, partitioner, cuCtx )
637
//    void  rqt_root_cbf              ( cu )
638
//    void  end_of_ctu                ( cu, cuCtx )
639
//================================================================================
640
641
void CABACWriter::coding_unit( const CodingUnit& cu, Partitioner& partitioner, CUCtx& cuCtx )
642
74.3k
{
643
74.3k
  DTRACE( g_trace_ctx, D_SYNTAX, "coding_unit() treeType=%d modeType=%d\n", cu.treeType, cu.modeType );
644
74.3k
  STAT_COUNT_CU_MODES( isEncoding() && partitioner.chType == CH_L, g_cuCounters1D[CU_CODED_FINALLY][0][!cu.slice->isIntra() + cu.slice->depth] );
645
74.3k
  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
74.3k
  CodingStructure& cs = *cu.cs;
648
649
  // skip flag
650
74.3k
  if ((!cs.slice->isIntra() || cs.slice->sps->IBC) && cu.Y().valid())
651
44.6k
  {
652
44.6k
    cu_skip_flag( cu );
653
44.6k
  }
654
  
655
  // skip data
656
74.3k
  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
74.3k
  pred_mode ( cu );
667
74.3k
  if (CU::isIntra(cu))
668
74.3k
  {
669
74.3k
    adaptive_color_transform(cu);
670
74.3k
  }
671
74.3k
  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
74.3k
  cu_pred_data( cu );
679
680
  // residual data ( coded block flags + transform coefficient levels )
681
74.3k
  cu_residual( cu, partitioner, cuCtx );
682
683
  // end of cu
684
74.3k
  end_of_ctu( cu, cuCtx );
685
74.3k
}
686
687
688
void CABACWriter::cu_skip_flag( const CodingUnit& cu )
689
89.4k
{
690
89.4k
  unsigned ctxId = DeriveCtx::CtxSkipFlag();
691
692
89.4k
  if ((cu.slice->isIntra() || CU::isConsIntra(cu)) && cu.cs->slice->sps->IBC)
693
89.4k
  {
694
89.4k
    if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64
695
89.4k
    {
696
89.4k
      m_BinEncoder.encodeBin((cu.skip), Ctx::SkipFlag(ctxId));
697
89.4k
      DTRACE(g_trace_ctx, D_SYNTAX, "cu_skip_flag() ctx=%d skip=%d\n", ctxId, cu.skip ? 1 : 0);
698
89.4k
    }
699
89.4k
    return;
700
89.4k
  }
701
0
  if ( !cu.cs->slice->sps->IBC && cu.lwidth() == 4 && cu.lheight() == 4 )
702
0
  {
703
0
    return;
704
0
  }
705
0
  if( !cu.cs->slice->sps->IBC && CU::isConsIntra(cu) )
706
0
  {
707
0
    return;
708
0
  }
709
0
  m_BinEncoder.encodeBin( ( cu.skip ), Ctx::SkipFlag( ctxId ) );
710
711
0
  DTRACE( g_trace_ctx, D_SYNTAX, "cu_skip_flag() ctx=%d skip=%d\n", ctxId, cu.skip ? 1 : 0 );
712
0
  if (cu.skip && cu.cs->slice->sps->IBC)
713
0
  {
714
0
    if (cu.lwidth() < 128 && cu.lheight() < 128 && !CU::isConsInter(cu)) // disable IBC mode larger than 64x64 and disable IBC when only allowing inter mode
715
0
    {
716
0
      if ( cu.lwidth() == 4 && cu.lheight() == 4 )
717
0
      {
718
0
        return;
719
0
      }
720
0
      unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
721
0
      m_BinEncoder.encodeBin(CU::isIBC(cu) ? 1 : 0, Ctx::IBCFlag(ctxidx));
722
0
      DTRACE(g_trace_ctx, D_SYNTAX, "ibc() ctx=%d cu.predMode=%d\n", ctxidx, cu.predMode);
723
0
    }
724
0
  }
725
0
}
726
727
728
void CABACWriter::pred_mode( const CodingUnit& cu )
729
346k
{
730
346k
  if (cu.cs->slice->sps->IBC && cu.chType != CH_C)
731
262k
  {
732
262k
    if( CU::isConsInter(cu) )
733
0
    {
734
0
      assert( CU::isInter( cu ) );
735
0
      return;
736
0
    }
737
738
262k
    if ( cu.cs->slice->isIntra() || ( cu.lwidth() == 4 && cu.lheight() == 4 ) || CU::isConsIntra(cu) )
739
262k
    {
740
262k
      if (cu.lwidth() < 128 && cu.lheight() < 128) // disable IBC mode larger than 64x64
741
262k
      {
742
262k
        unsigned ctxidx = DeriveCtx::CtxIBCFlag(cu);
743
262k
        m_BinEncoder.encodeBin(CU::isIBC(cu), Ctx::IBCFlag(ctxidx));
744
262k
      }
745
262k
      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
262k
    }
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
262k
  }
774
83.7k
  else
775
83.7k
  {
776
83.7k
    if( CU::isConsInter(cu) )
777
0
    {
778
0
      assert( CU::isInter( cu ) );
779
0
      return;
780
0
    }
781
782
83.7k
    if ( cu.cs->slice->isIntra() || ( cu.lwidth() == 4 && cu.lheight() == 4 ) || CU::isConsIntra(cu) )
783
83.7k
    {
784
83.7k
      if (cu.cs->slice->sps->PLT && cu.lwidth() <= 64 && cu.lheight() <= 64 && ( ( (!isLuma(cu.chType)) && (cu.chromaSize().width * cu.chromaSize().height > 16) ) || ((isLuma(cu.chType)) && ((cu.lumaSize().width * cu.lumaSize().height) > 16 ) ) ) && (!CU::isLocalSepTree(cu) || isLuma(cu.chType) ) )
785
0
      {
786
0
        m_BinEncoder.encodeBin((CU::isPLT(cu)), Ctx::PLTFlag(0));
787
0
      }
788
83.7k
      return;
789
83.7k
    }
790
18.4E
    m_BinEncoder.encodeBin((CU::isIntra(cu) || CU::isPLT(cu)), Ctx::PredMode(DeriveCtx::CtxPredModeFlag()));
791
18.4E
    if ((CU::isIntra(cu) || CU::isPLT(cu)) && cu.cs->slice->sps->PLT && cu.lwidth() <= 64 && cu.lheight() <= 64&& ( ( (!isLuma(cu.chType)) && (cu.chromaSize().width * cu.chromaSize().height > 16) ) || ((isLuma(cu.chType)) && ((cu.lumaSize().width * cu.lumaSize().height) > 16 ) ) ) && (!CU::isLocalSepTree(cu) || isLuma(cu.chType)  ) )
792
0
    {
793
0
      m_BinEncoder.encodeBin((CU::isPLT(cu)), Ctx::PLTFlag(0));
794
0
    }
795
18.4E
  }
796
346k
}
797
798
799
void CABACWriter::bdpcm_mode( const CodingUnit& cu, const ComponentID compID )
800
593k
{
801
593k
  if( !cu.cs->sps->BDPCM) return;
802
593k
  if( !CU::bdpcmAllowed( cu, compID ) ) return;
803
804
271k
  int bdpcmMode = cu.bdpcmM[toChannelType(compID)];
805
806
271k
  unsigned ctxId = isLuma(compID) ? 0 : 2; 
807
271k
  m_BinEncoder.encodeBin(bdpcmMode > 0 ? 1 : 0, Ctx::BDPCMMode(ctxId));
808
271k
  if (bdpcmMode)
809
49.1k
  {
810
49.1k
    m_BinEncoder.encodeBin(bdpcmMode > 1 ? 1 : 0, Ctx::BDPCMMode(ctxId+1));
811
49.1k
  }
812
271k
  if (isLuma(compID))
813
41.3k
  {
814
41.3k
    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
41.3k
  }
816
230k
  else
817
230k
  {
818
230k
    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
230k
  }
820
271k
}
821
822
823
void CABACWriter::cu_pred_data( const CodingUnit& cu )
824
173k
{
825
173k
  if( CU::isIntra( cu ) )
826
152k
  {
827
152k
    if( cu.Y().valid() )
828
68.3k
    {
829
68.3k
      bdpcm_mode( cu, COMP_Y );
830
68.3k
    }
831
152k
    intra_luma_pred_modes  ( cu );
832
152k
    if( ( !cu.Y().valid() || ( !CU::isSepTree(cu) && cu.Y().valid() ) ) && isChromaEnabled(cu.chromaFormat) )
833
83.7k
    {
834
83.7k
      bdpcm_mode( cu, ComponentID(CH_C) );
835
83.7k
    } 
836
152k
    intra_chroma_pred_modes( cu );
837
152k
    return;
838
152k
  }
839
21.1k
  if (!cu.Y().valid()) // dual tree chroma CU
840
0
  {
841
0
    return;
842
0
  }
843
844
21.1k
  prediction_unit ( cu );
845
21.1k
  imv_mode        ( cu );
846
21.1k
  affine_amvr_mode( cu );
847
21.1k
  cu_bcw_flag     ( cu );
848
21.1k
}
849
850
851
void CABACWriter::cu_bcw_flag(const CodingUnit& cu)
852
21.1k
{
853
21.1k
  if(!CU::isBcwIdxCoded(cu))
854
21.1k
  {
855
21.1k
    return;
856
21.1k
  }
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
793k
{
890
793k
  int thresh;
891
793k
  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
793k
  else
903
793k
  {
904
793k
    thresh = g_tbMax[maxSymbol];
905
793k
  }
906
907
793k
  int val = 1 << thresh;
908
793k
  assert(val <= maxSymbol);
909
793k
  assert((val << 1) > maxSymbol);
910
793k
  assert(symbol < maxSymbol);
911
793k
  int b = maxSymbol - val;
912
793k
  assert(b < val);
913
793k
  if (symbol < val - b)
914
246k
  {
915
246k
    m_BinEncoder.encodeBinsEP(symbol, thresh);
916
246k
  }
917
546k
  else
918
546k
  {
919
546k
    symbol += val - b;
920
546k
    assert(symbol < (val << 1));
921
546k
    assert((symbol >> 1) >= val - b);
922
546k
    m_BinEncoder.encodeBinsEP(symbol, thresh + 1);
923
546k
  }
924
793k
}
925
926
927
void CABACWriter::extend_ref_line(const CodingUnit& cu)
928
853k
{
929
853k
  if ( !cu.Y().valid() || cu.predMode != MODE_INTRA || !isLuma(cu.chType) || cu.bdpcmM[CH_L] )
930
0
  {
931
0
    return;
932
0
  }
933
853k
  if( !cu.cs->sps->MRL )
934
0
  {
935
0
    return;
936
0
  }
937
938
853k
  bool isFirstLineOfCtu = (((cu.block(COMP_Y).y)&((cu.cs->sps)->CTUSize - 1)) == 0);
939
853k
  if (isFirstLineOfCtu)
940
282k
  {
941
282k
    return;
942
282k
  }
943
571k
  int multiRefIdx = cu.multiRefIdx;
944
571k
  if (MRL_NUM_REF_LINES > 1)
945
571k
  {
946
571k
    m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[0], Ctx::MultiRefLineIdx(0));
947
571k
    if (MRL_NUM_REF_LINES > 2 && multiRefIdx != MULTI_REF_LINE_IDX[0])
948
156k
    {
949
156k
      m_BinEncoder.encodeBin(multiRefIdx != MULTI_REF_LINE_IDX[1], Ctx::MultiRefLineIdx(1));
950
156k
    }
951
571k
  }
952
571k
}
953
954
955
void CABACWriter::intra_luma_pred_modes( const CodingUnit& cu )
956
152k
{
957
152k
  if( !cu.Y().valid() || cu.bdpcmM[CH_L] )
958
89.0k
  {
959
89.0k
    return;
960
89.0k
  }
961
962
63.0k
  mip_flag(cu);
963
63.0k
  if (cu.mipFlag)
964
1.60k
  {
965
1.60k
    mip_pred_modes(cu);
966
1.60k
    return;
967
1.60k
  }
968
61.4k
  extend_ref_line( cu );
969
970
61.4k
  isp_mode( cu );
971
972
61.4k
  const int numMPMs   = NUM_MOST_PROBABLE_MODES;
973
61.4k
  unsigned  mpm_pred   [numMPMs];
974
61.4k
  unsigned  mpm_idx;
975
61.4k
  unsigned  ipred_mode ;
976
977
  // prev_intra_luma_pred_flag
978
61.4k
  {
979
61.4k
    CU::getIntraMPMs( cu, mpm_pred );
980
981
61.4k
    ipred_mode = cu.intraDir[0];
982
61.4k
    mpm_idx    = numMPMs;
983
61.5k
    for( unsigned idx = 0; idx < numMPMs; idx++ )
984
61.5k
    {
985
61.5k
      if( ipred_mode == mpm_pred[idx] )
986
61.4k
      {
987
61.4k
        mpm_idx = idx;
988
61.4k
        break;
989
61.4k
      }
990
61.5k
    }
991
61.4k
    if ( cu.multiRefIdx )
992
0
    {
993
0
      CHECK(mpm_idx >= numMPMs, "use of non-MPM");
994
0
    }
995
61.4k
    else
996
61.4k
    {
997
61.4k
      m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
998
61.4k
    }
999
61.4k
  }
1000
1001
  // mpm_idx / rem_intra_luma_pred_mode
1002
61.4k
  {
1003
61.4k
    if( mpm_idx < numMPMs )
1004
61.4k
    {
1005
61.4k
      {
1006
61.4k
        unsigned ctx = (cu.ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
1007
61.4k
        if (cu.multiRefIdx == 0)
1008
61.4k
          m_BinEncoder.encodeBin(mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx));
1009
61.4k
        if( mpm_idx )
1010
111
        {
1011
111
          m_BinEncoder.encodeBinEP( mpm_idx > 1 );
1012
111
        }
1013
61.4k
        if (mpm_idx > 1)
1014
0
        {
1015
0
          m_BinEncoder.encodeBinEP(mpm_idx > 2);
1016
0
        }
1017
61.4k
        if (mpm_idx > 2)
1018
0
        {
1019
0
          m_BinEncoder.encodeBinEP(mpm_idx > 3);
1020
0
        }
1021
61.4k
        if (mpm_idx > 3)
1022
0
        {
1023
0
          m_BinEncoder.encodeBinEP(mpm_idx > 4);
1024
0
        }
1025
61.4k
      }
1026
61.4k
    }
1027
18.4E
    else
1028
18.4E
    {
1029
      // sorting of MPMs
1030
18.4E
      std::sort( mpm_pred, mpm_pred + numMPMs );
1031
1032
18.4E
      {
1033
18.4E
        for (int idx = numMPMs - 1; idx >= 0; idx--)
1034
0
        {
1035
0
          if (ipred_mode > mpm_pred[idx])
1036
0
          {
1037
0
            ipred_mode--;
1038
0
          }
1039
0
        }
1040
18.4E
        CHECK(ipred_mode >= 64, "Incorrect mode");
1041
18.4E
        xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
1042
18.4E
      }
1043
18.4E
    }
1044
1045
61.4k
    DTRACE( g_trace_ctx, D_SYNTAX, "intra_luma_pred_modes() idx=%d pos=(%d,%d) mode=%d\n", 0, cu.lumaPos().x, cu.lumaPos().y, cu.intraDir[0] );
1046
61.4k
  }
1047
61.4k
}
1048
1049
1050
void CABACWriter::intra_luma_pred_mode( const CodingUnit& cu, const unsigned *mpmLst )
1051
1.06M
{
1052
1.06M
  if( cu.bdpcmM[CH_L] ) 
1053
7.29k
  {
1054
7.29k
    return;
1055
7.29k
  }
1056
1057
1.05M
  mip_flag(cu);
1058
1.05M
  if (cu.mipFlag)
1059
261k
  {
1060
261k
    mip_pred_mode(cu);
1061
261k
    return;
1062
261k
  }
1063
792k
  extend_ref_line( cu );
1064
1065
792k
  isp_mode( cu );
1066
1067
  // prev_intra_luma_pred_flag
1068
792k
  unsigned ipred_mode = cu.intraDir[0];
1069
792k
  static constexpr int numMPMs = NUM_MOST_PROBABLE_MODES;
1070
792k
  unsigned mpm_idx = numMPMs;
1071
792k
  unsigned  mpm_pred[numMPMs];
1072
1073
792k
  if (mpmLst)
1074
792k
  {
1075
792k
    memcpy(mpm_pred, mpmLst, sizeof(unsigned) * numMPMs);
1076
792k
  }
1077
117
  else
1078
117
  {
1079
117
    CU::getIntraMPMs(cu, mpm_pred);
1080
117
  }
1081
1082
4.15M
  for (int idx = 0; idx < numMPMs; idx++)
1083
3.67M
  {
1084
3.67M
    if (ipred_mode == mpm_pred[idx])
1085
318k
    {
1086
318k
      mpm_idx = idx;
1087
318k
      break;
1088
318k
    }
1089
3.67M
  }
1090
792k
  if (cu.multiRefIdx)
1091
156k
  {
1092
156k
    CHECK(mpm_idx >= numMPMs, "use of non-MPM");
1093
156k
  }
1094
636k
  else
1095
636k
  {
1096
636k
    m_BinEncoder.encodeBin(mpm_idx < numMPMs, Ctx::IntraLumaMpmFlag());
1097
636k
  }
1098
1099
  // mpm_idx / rem_intra_luma_pred_mode
1100
792k
  if( mpm_idx < numMPMs )
1101
318k
  {
1102
318k
    unsigned ctx = (cu.ispMode == NOT_INTRA_SUBPARTITIONS ? 1 : 0);
1103
318k
    if (cu.multiRefIdx == 0)
1104
162k
      m_BinEncoder.encodeBin( mpm_idx > 0, Ctx::IntraLumaPlanarFlag(ctx) );
1105
318k
    if( mpm_idx )
1106
214k
    {
1107
214k
      m_BinEncoder.encodeBinEP( mpm_idx > 1 );
1108
214k
    }
1109
318k
    if (mpm_idx > 1)
1110
121k
    {
1111
121k
      m_BinEncoder.encodeBinEP(mpm_idx > 2);
1112
121k
    }
1113
318k
    if (mpm_idx > 2)
1114
90.3k
    {
1115
90.3k
      m_BinEncoder.encodeBinEP(mpm_idx > 3);
1116
90.3k
    }
1117
318k
    if (mpm_idx > 3)
1118
60.0k
    {
1119
60.0k
      m_BinEncoder.encodeBinEP(mpm_idx > 4);
1120
60.0k
    }
1121
318k
  }
1122
474k
  else
1123
474k
  {
1124
    // mpm_pred[0] is always 0, i.e. PLANAR, so its always first in the list
1125
474k
    std::sort( mpm_pred + 1, mpm_pred + numMPMs );
1126
1127
3.31M
    for (int idx = numMPMs - 1; idx >= 0; idx--)
1128
2.84M
    {
1129
2.84M
      if (ipred_mode > mpm_pred[idx])
1130
1.54M
      {
1131
1.54M
        ipred_mode--;
1132
1.54M
      }
1133
2.84M
    }
1134
1135
474k
    xWriteTruncBinCode(ipred_mode, NUM_LUMA_MODE - NUM_MOST_PROBABLE_MODES);  // Remaining mode is truncated binary coded
1136
474k
  }
1137
792k
}
1138
1139
1140
void CABACWriter::intra_chroma_pred_modes( const CodingUnit& cu )
1141
152k
{
1142
152k
  if( cu.chromaFormat == CHROMA_400 || ( CU::isSepTree(cu) && cu.chType == CH_L ) || cu.bdpcmM[CH_C] )
1143
68.3k
  {
1144
68.3k
    return;
1145
68.3k
  }
1146
1147
83.7k
  intra_chroma_pred_mode( cu );
1148
83.7k
}
1149
1150
1151
void CABACWriter::intra_chroma_lmc_mode(const CodingUnit& cu)
1152
31.9k
{
1153
31.9k
  const unsigned intraDir = cu.intraDir[1];
1154
31.9k
  int lmModeList[10];
1155
31.9k
  CU::getLMSymbolList(cu, lmModeList);
1156
31.9k
  int symbol = -1;
1157
31.9k
  for (int k = 0; k < LM_SYMBOL_NUM; k++)
1158
31.9k
  {
1159
31.9k
    if (lmModeList[k] == intraDir)
1160
31.9k
    {
1161
31.9k
      symbol = k;
1162
31.9k
      break;
1163
31.9k
    }
1164
31.9k
  }
1165
31.9k
  CHECK(symbol < 0, "invalid symbol found");
1166
1167
31.9k
  m_BinEncoder.encodeBin(symbol == 0 ? 0 : 1, Ctx::CclmModeIdx(0));
1168
1169
31.9k
  if (symbol > 0)
1170
0
  {
1171
0
    CHECK(symbol > 2, "invalid symbol for MMLM");
1172
0
    unsigned int symbol_minus_1 = symbol - 1;
1173
0
    m_BinEncoder.encodeBinEP(symbol_minus_1);
1174
0
  }
1175
31.9k
}
1176
1177
1178
void CABACWriter::intra_chroma_pred_mode(const CodingUnit& cu)
1179
352k
{
1180
352k
  if (cu.colorTransform)
1181
0
  {
1182
0
    CHECK(cu.intraDir[CH_C] != DM_CHROMA_IDX, "chroma should use DM for adaptive color transform");
1183
0
    return;
1184
0
  }
1185
1186
352k
  const unsigned intraDir = cu.intraDir[1];
1187
352k
  if (cu.cs->sps->LMChroma && CU::checkCCLMAllowed(cu))
1188
240k
  {
1189
240k
    m_BinEncoder.encodeBin(CU::isLMCMode(intraDir) ? 1 : 0, Ctx::CclmModeFlag(0));
1190
240k
    if (CU::isLMCMode(intraDir))
1191
31.9k
    {
1192
31.9k
      intra_chroma_lmc_mode(cu);
1193
31.9k
      return;
1194
31.9k
    }
1195
240k
  }
1196
1197
320k
  const bool     isDerivedMode = intraDir == DM_CHROMA_IDX;
1198
320k
  m_BinEncoder.encodeBin(isDerivedMode ? 0 : 1, Ctx::IntraChromaPredMode(0));
1199
320k
  if (isDerivedMode)
1200
73.0k
  {
1201
73.0k
    return;
1202
73.0k
  }
1203
1204
  // chroma candidate index
1205
247k
  unsigned chromaCandModes[NUM_CHROMA_MODE];
1206
247k
  CU::getIntraChromaCandModes(cu, chromaCandModes);
1207
1208
247k
  int candId = 0;
1209
587k
  for (; candId < NUM_CHROMA_MODE; candId++)
1210
587k
  {
1211
587k
    if (intraDir == chromaCandModes[candId])
1212
247k
    {
1213
247k
      break;
1214
247k
    }
1215
587k
  }
1216
1217
247k
  CHECK(candId >= NUM_CHROMA_MODE, "Chroma prediction mode index out of bounds");
1218
247k
  CHECK(chromaCandModes[candId] == DM_CHROMA_IDX, "The intra dir cannot be DM_CHROMA for this path");
1219
247k
  {
1220
247k
    m_BinEncoder.encodeBinsEP(candId, 2);
1221
247k
  }
1222
247k
}
1223
1224
1225
void CABACWriter::cu_residual( const CodingUnit& cu, Partitioner& partitioner, CUCtx& cuCtx )
1226
173k
{
1227
173k
  if (!CU::isIntra(cu))
1228
21.1k
  {
1229
21.1k
    if( !cu.mergeFlag )
1230
21.1k
    {
1231
21.1k
      rqt_root_cbf( cu );
1232
21.1k
    }
1233
21.1k
    if( cu.rootCbf )
1234
129
    {
1235
129
      sbt_mode( cu );
1236
129
    }
1237
1238
21.1k
    if( !cu.rootCbf )
1239
21.0k
    {
1240
21.0k
      CHECK(cu.colorTransform, "ACT should not be enabled for root_cbf = 0");
1241
21.0k
      return;
1242
21.0k
    }
1243
21.1k
  }
1244
1245
152k
  if( CU::isInter( cu ) || CU::isIBC( cu ) )
1246
129
  {
1247
129
    adaptive_color_transform(cu);
1248
129
  }
1249
1250
152k
  cuCtx.violatesLfnstConstrained[CH_L] = false;
1251
152k
  cuCtx.violatesLfnstConstrained[CH_C] = false;
1252
152k
  cuCtx.lfnstLastScanPos               = false;
1253
152k
  cuCtx.violatesMtsCoeffConstraint     = false;
1254
152k
  cuCtx.mtsLastScanPos                                = false;
1255
1256
152k
  if( cu.ispMode && isLuma( partitioner.chType ) )
1257
41
  {
1258
41
    transform_tree( *cu.cs, partitioner, cuCtx, CU::getISPType( cu, getFirstComponentOfChannel( partitioner.chType ) ), 0 );
1259
41
  }
1260
152k
  else
1261
152k
  {
1262
152k
    transform_tree( *cu.cs, partitioner, cuCtx );
1263
152k
  }
1264
1265
152k
  residual_lfnst_mode( cu, cuCtx );
1266
152k
  mts_idx            ( cu, &cuCtx );
1267
152k
}
1268
1269
1270
void CABACWriter::rqt_root_cbf( const CodingUnit& cu )
1271
42.2k
{
1272
42.2k
  m_BinEncoder.encodeBin( cu.rootCbf, Ctx::QtRootCbf() );
1273
1274
42.2k
  DTRACE( g_trace_ctx, D_SYNTAX, "rqt_root_cbf() ctx=0 root_cbf=%d pos=(%d,%d)\n", cu.rootCbf ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y );
1275
42.2k
}
1276
1277
1278
void CABACWriter::adaptive_color_transform(const CodingUnit& cu)
1279
74.4k
{
1280
74.4k
  if (!cu.slice->sps->useColorTrans )
1281
74.4k
  {
1282
74.4k
    return;
1283
74.4k
  }
1284
1285
0
  if (CU::isSepTree(cu))
1286
0
  {
1287
0
    CHECK(cu.colorTransform, "adaptive color transform should be disabled when dualtree and localtree are enabled");
1288
0
    return;
1289
0
  }
1290
1291
0
  if (CU::isInter(cu) || CU::isIBC(cu) || CU::isIntra(cu))
1292
0
  {
1293
0
    m_BinEncoder.encodeBin(cu.colorTransform, Ctx::ACTFlag());
1294
0
  }
1295
0
}
1296
1297
1298
void CABACWriter::sbt_mode( const CodingUnit& cu )
1299
129
{
1300
129
  uint8_t sbtAllowed = CU::checkAllowedSbt(cu);
1301
129
  if( !sbtAllowed )
1302
129
  {
1303
129
    return;
1304
129
  }
1305
1306
0
  SizeType cuWidth = cu.lwidth();
1307
0
  SizeType cuHeight = cu.lheight();
1308
0
  uint8_t sbtIdx = CU::getSbtIdx( cu.sbtInfo );
1309
0
  uint8_t sbtPos = CU::getSbtPos( cu.sbtInfo );
1310
1311
  //bin - flag
1312
0
  bool sbtFlag = cu.sbtInfo != 0;
1313
0
  uint8_t ctxIdx = ( cuWidth * cuHeight <= 256 ) ? 1 : 0;
1314
0
  m_BinEncoder.encodeBin( sbtFlag, Ctx::SbtFlag( ctxIdx ) );
1315
0
  if( !sbtFlag )
1316
0
  {
1317
0
    return;
1318
0
  }
1319
1320
0
  bool sbtQuadFlag = sbtIdx == SBT_HOR_QUAD || sbtIdx == SBT_VER_QUAD;
1321
0
  bool sbtHorFlag = sbtIdx == SBT_HOR_HALF || sbtIdx == SBT_HOR_QUAD;
1322
0
  bool sbtPosFlag = sbtPos == SBT_POS1;
1323
1324
0
  uint8_t sbtVerHalfAllow = CU::targetSbtAllowed( SBT_VER_HALF, sbtAllowed );
1325
0
  uint8_t sbtHorHalfAllow = CU::targetSbtAllowed( SBT_HOR_HALF, sbtAllowed );
1326
0
  uint8_t sbtVerQuadAllow = CU::targetSbtAllowed( SBT_VER_QUAD, sbtAllowed );
1327
0
  uint8_t sbtHorQuadAllow = CU::targetSbtAllowed( SBT_HOR_QUAD, sbtAllowed );
1328
  //bin - type
1329
0
  if( ( sbtHorHalfAllow || sbtVerHalfAllow ) && ( sbtHorQuadAllow || sbtVerQuadAllow ) )
1330
0
  {
1331
0
    m_BinEncoder.encodeBin( sbtQuadFlag, Ctx::SbtQuadFlag( 0 ) );
1332
0
  }
1333
0
  else
1334
0
  {
1335
0
    assert( sbtQuadFlag == 0 );
1336
0
  }
1337
1338
  //bin - dir
1339
0
  if( ( sbtQuadFlag && sbtVerQuadAllow && sbtHorQuadAllow ) || ( !sbtQuadFlag && sbtVerHalfAllow && sbtHorHalfAllow ) ) //both direction allowed
1340
0
  {
1341
0
    uint8_t ctxIdx = ( cuWidth == cuHeight ) ? 0 : ( cuWidth < cuHeight ? 1 : 2 );
1342
0
    m_BinEncoder.encodeBin( sbtHorFlag, Ctx::SbtHorFlag( ctxIdx ) );
1343
0
  }
1344
0
  else
1345
0
  {
1346
0
    assert( sbtHorFlag == ( ( sbtQuadFlag && sbtHorQuadAllow ) || ( !sbtQuadFlag && sbtHorHalfAllow ) ) );
1347
0
  }
1348
1349
  //bin - pos
1350
0
  m_BinEncoder.encodeBin( sbtPosFlag, Ctx::SbtPosFlag( 0 ) );
1351
1352
0
  DTRACE( g_trace_ctx, D_SYNTAX, "sbt_mode() pos=(%d,%d) sbtInfo=%d\n", cu.lx(), cu.ly(), (int)cu.sbtInfo );
1353
0
}
1354
1355
1356
void CABACWriter::end_of_ctu( const CodingUnit& cu, CUCtx& cuCtx )
1357
74.2k
{
1358
74.2k
  const bool    isLastSubCUOfCtu  = CU::isLastSubCUOfCtu( cu );
1359
1360
74.2k
  if ( isLastSubCUOfCtu
1361
14.0k
    && ( !CU::isSepTree(cu) || cu.chromaFormat == CHROMA_400 || isChroma( cu.chType ) )
1362
74.2k
      )
1363
7.00k
  {
1364
7.00k
    cuCtx.isDQPCoded = ( cu.cs->pps->useDQP && !cuCtx.isDQPCoded );
1365
1366
7.00k
  }
1367
74.2k
}
1368
1369
1370
void CABACWriter::cu_palette_info(const CodingUnit& cu, ComponentID compBegin, uint32_t numComp, CUCtx& cuCtx)
1371
0
{
1372
0
  THROW("no support");
1373
0
}
1374
1375
1376
//================================================================================
1377
//  clause 7.3.8.6
1378
//--------------------------------------------------------------------------------
1379
//    void  prediction_unit ( cu );
1380
//    void  merge_flag      ( cu );
1381
//    void  merge_idx       ( cu );
1382
//    void  inter_pred_idc  ( cu );
1383
//    void  ref_idx         ( cu, refList );
1384
//    void  mvp_flag        ( cu, refList );
1385
//================================================================================
1386
1387
void CABACWriter::prediction_unit( const CodingUnit& cu )
1388
21.1k
{
1389
21.1k
  CHECK( cu.treeType == TREE_C, "cannot be chroma CU" );
1390
21.1k
  if( cu.skip )
1391
0
  {
1392
0
    CHECK( !cu.mergeFlag, "merge_flag must be true for skipped CUs" );
1393
0
  }
1394
21.1k
  else
1395
21.1k
  {
1396
21.1k
    merge_flag( cu );
1397
21.1k
  }
1398
21.1k
  if( cu.mergeFlag )
1399
0
  {
1400
0
    merge_data(cu);
1401
0
  }
1402
21.1k
  else if (CU::isIBC(cu))
1403
21.1k
  {
1404
21.1k
    ref_idx(cu, REF_PIC_LIST_0);
1405
21.1k
    Mv mvd = cu.mvd[REF_PIC_LIST_0][0];
1406
21.1k
    mvd.changeIbcPrecInternal2Amvr(cu.imv);
1407
21.1k
    mvd_coding(mvd, 0); // already changed to signaling precision
1408
21.1k
    if ( cu.slice->sps->maxNumIBCMergeCand == 1 )
1409
0
    {
1410
0
      CHECK( cu.mvpIdx[REF_PIC_LIST_0], "mvpIdx for IBC mode should be 0" );
1411
0
    }
1412
21.1k
    else
1413
21.1k
    mvp_flag(cu, REF_PIC_LIST_0);
1414
21.1k
  }
1415
0
  else
1416
0
  {
1417
0
    inter_pred_idc( cu );
1418
0
    affine_flag   ( cu );
1419
0
    smvd_mode( cu );
1420
0
    if( cu.interDir != 2 /* PRED_L1 */ )
1421
0
    {
1422
0
      ref_idx     ( cu, REF_PIC_LIST_0 );
1423
0
      if ( cu.affine )
1424
0
      {
1425
0
        Mv mvd = cu.mvd[REF_PIC_LIST_0][0];
1426
0
        mvd.changeAffinePrecInternal2Amvr(cu.imv);
1427
0
        mvd_coding(mvd, 0); // already changed to signaling precision
1428
0
        mvd = cu.mvd[REF_PIC_LIST_0][1];
1429
0
        mvd.changeAffinePrecInternal2Amvr(cu.imv);
1430
0
        mvd_coding(mvd, 0); // already changed to signaling precision
1431
0
        if ( cu.affineType == AFFINEMODEL_6PARAM )
1432
0
        {
1433
0
          mvd = cu.mvd[REF_PIC_LIST_0][2];
1434
0
          mvd.changeAffinePrecInternal2Amvr(cu.imv);
1435
0
          mvd_coding(mvd, 0); // already changed to signaling precision
1436
0
        }
1437
0
      }
1438
0
      else
1439
0
      {
1440
0
        Mv mvd = cu.mvd[REF_PIC_LIST_0][0];
1441
0
        mvd.changeTransPrecInternal2Amvr(cu.imv);
1442
0
        mvd_coding(mvd, 0); // already changed to signaling precision
1443
0
      }
1444
0
      mvp_flag    ( cu, REF_PIC_LIST_0 );
1445
0
    }
1446
0
    if( cu.interDir != 1 /* PRED_L0 */ )
1447
0
    {
1448
0
      if ( cu.smvdMode != 1 )
1449
0
      {
1450
0
        ref_idx     ( cu, REF_PIC_LIST_1 );
1451
0
        if( !cu.cs->picHeader->mvdL1Zero || cu.interDir != 3 /* PRED_BI */ )
1452
0
        {
1453
0
          if ( cu.affine )
1454
0
          {
1455
0
            Mv mvd = cu.mvd[REF_PIC_LIST_1][0];
1456
0
            mvd.changeAffinePrecInternal2Amvr(cu.imv);
1457
0
            mvd_coding(mvd, 0); // already changed to signaling precision
1458
0
            mvd = cu.mvd[REF_PIC_LIST_1][1];
1459
0
            mvd.changeAffinePrecInternal2Amvr(cu.imv);
1460
0
            mvd_coding(mvd, 0); // already changed to signaling precision
1461
0
            if ( cu.affineType == AFFINEMODEL_6PARAM )
1462
0
            {
1463
0
              mvd = cu.mvd[REF_PIC_LIST_1][2];
1464
0
              mvd.changeAffinePrecInternal2Amvr(cu.imv);
1465
0
              mvd_coding(mvd, 0); // already changed to signaling precision
1466
0
            }
1467
0
          }
1468
0
          else
1469
0
          {
1470
0
            Mv mvd = cu.mvd[REF_PIC_LIST_1][0];
1471
0
            mvd.changeTransPrecInternal2Amvr(cu.imv);
1472
0
            mvd_coding(mvd, 0); // already changed to signaling precision
1473
0
          }
1474
0
        }
1475
0
      }
1476
0
      mvp_flag    ( cu, REF_PIC_LIST_1 );
1477
0
    }
1478
0
  }
1479
21.1k
}
1480
1481
1482
void CABACWriter::smvd_mode( const CodingUnit& cu )
1483
0
{
1484
0
  if ( cu.interDir != 3 || cu.affine )
1485
0
  {
1486
0
    return;
1487
0
  }
1488
1489
0
  if ( cu.cs->slice->biDirPred == false )
1490
0
  {
1491
0
    return;
1492
0
  }
1493
1494
0
  m_BinEncoder.encodeBin( cu.smvdMode ? 1 : 0, Ctx::SmvdFlag() );
1495
1496
0
  DTRACE( g_trace_ctx, D_SYNTAX, "symmvd_flag() symmvd=%d pos=(%d,%d) size=%dx%d\n", cu.smvdMode ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height );
1497
0
}
1498
1499
1500
void CABACWriter::subblock_merge_flag( const CodingUnit& cu )
1501
0
{
1502
1503
0
  if ( !cu.cs->slice->isIntra() && (cu.slice->picHeader->maxNumAffineMergeCand > 0) && cu.lumaSize().width >= 8 && cu.lumaSize().height >= 8 )
1504
0
  {
1505
0
    unsigned ctxId = DeriveCtx::CtxAffineFlag();
1506
0
    m_BinEncoder.encodeBin( cu.affine, Ctx::SubblockMergeFlag( ctxId ) );
1507
0
    DTRACE( g_trace_ctx, D_SYNTAX, "subblock_merge_flag() subblock_merge_flag=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
1508
0
  }
1509
0
}
1510
1511
1512
void CABACWriter::affine_flag( const CodingUnit& cu )
1513
0
{
1514
0
  if ( !cu.cs->slice->isIntra() && cu.cs->sps->Affine && cu.lumaSize().width > 8 && cu.lumaSize().height > 8 )
1515
0
  {
1516
0
    unsigned ctxId = DeriveCtx::CtxAffineFlag();
1517
0
    m_BinEncoder.encodeBin( cu.affine, Ctx::AffineFlag( ctxId ) );
1518
0
    DTRACE( g_trace_ctx, D_SYNTAX, "affine_flag() affine=%d ctx=%d pos=(%d,%d)\n", cu.affine ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
1519
1520
0
    if ( cu.affine && cu.cs->sps->AffineType )
1521
0
    {
1522
0
      unsigned ctxId = 0;
1523
0
      m_BinEncoder.encodeBin( cu.affineType, Ctx::AffineType( ctxId ) );
1524
0
      DTRACE( g_trace_ctx, D_SYNTAX, "affine_type() affine_type=%d ctx=%d pos=(%d,%d)\n", cu.affineType ? 1 : 0, ctxId, cu.Y().x, cu.Y().y );
1525
0
    }
1526
0
  }
1527
0
}
1528
1529
1530
void CABACWriter::merge_flag( const CodingUnit& cu )
1531
21.1k
{
1532
21.1k
  m_BinEncoder.encodeBin( cu.mergeFlag, Ctx::MergeFlag() );
1533
1534
21.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "merge_flag() merge=%d pos=(%d,%d) size=%dx%d\n", cu.mergeFlag ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height );
1535
21.1k
}
1536
1537
1538
void CABACWriter::merge_data(const CodingUnit& cu)
1539
0
{
1540
0
  if (CU::isIBC(cu))
1541
0
  {
1542
0
    merge_idx(cu);
1543
0
    return;
1544
0
  }
1545
0
  subblock_merge_flag(cu);
1546
0
  if (cu.affine)
1547
0
  {
1548
0
    merge_idx(cu);
1549
0
    return;
1550
0
  }
1551
1552
0
  const bool ciipAvailable = cu.cs->sps->CIIP && !cu.skip && cu.Y().maxDim() < MAX_CU_SIZE && cu.Y().area() >= 64;
1553
0
  const bool geoAvailable = cu.cs->slice->sps->GEO && cu.cs->slice->isInterB() && cu.cs->sps->maxNumGeoCand > 1
1554
0
                                                   && cu.Y().minDim() >= GEO_MIN_CU_SIZE && cu.Y().maxDim() <= GEO_MAX_CU_SIZE
1555
0
                                                   && cu.Y().maxDim() < 8 * cu.Y().minDim();
1556
1557
0
  if (geoAvailable || ciipAvailable)
1558
0
  {
1559
0
    m_BinEncoder.encodeBin(!cu.geo && !cu.ciip, Ctx::RegularMergeFlag(cu.skip ? 0 : 1));
1560
0
  }
1561
0
  if (!cu.geo && !cu.ciip)
1562
0
  {
1563
0
    if (cu.cs->sps->MMVD)
1564
0
    {
1565
0
      m_BinEncoder.encodeBin(cu.mmvdMergeFlag, Ctx::MmvdFlag(0));
1566
0
      DTRACE(g_trace_ctx, D_SYNTAX, "mmvd_merge_flag() mmvd_merge=%d pos=(%d,%d) size=%dx%d\n", cu.mmvdMergeFlag ? 1 : 0, cu.lumaPos().x, cu.lumaPos().y, cu.lumaSize().width, cu.lumaSize().height);
1567
0
    }
1568
0
    if (cu.mmvdMergeFlag || cu.mmvdSkip)
1569
0
    {
1570
0
      mmvd_merge_idx(cu);
1571
0
    }
1572
0
    else
1573
0
    {
1574
0
      merge_idx(cu);
1575
0
    }
1576
0
  }
1577
0
  else
1578
0
  {
1579
0
    if (geoAvailable && ciipAvailable)
1580
0
    {
1581
0
      ciip_flag(cu);
1582
0
    }
1583
0
    merge_idx(cu);
1584
0
  }
1585
0
}
1586
1587
1588
void CABACWriter::imv_mode( const CodingUnit& cu )
1589
21.1k
{
1590
21.1k
  const SPS *sps = cu.cs->sps;
1591
1592
21.1k
  if( !sps->AMVR )
1593
0
  {
1594
0
    return;
1595
0
  }
1596
21.1k
  if ( cu.affine )
1597
0
  {
1598
0
    return;
1599
0
  }
1600
1601
21.1k
  bool bNonZeroMvd = CU::hasSubCUNonZeroMVd( cu );
1602
21.1k
  if( !bNonZeroMvd )
1603
0
  {
1604
0
    return;
1605
0
  }
1606
1607
21.1k
  if (CU::isIBC(cu) == false)
1608
0
    m_BinEncoder.encodeBin( (cu.imv > 0), Ctx::ImvFlag( 0 ) );
1609
21.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 0), 0 );
1610
1611
21.1k
  if( sps->AMVR && cu.imv > 0 )
1612
21.1k
  {
1613
21.1k
    if (!CU::isIBC(cu))
1614
0
    {
1615
0
      m_BinEncoder.encodeBin(cu.imv < IMV_HPEL, Ctx::ImvFlag(4));
1616
0
      DTRACE(g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", cu.imv < 3, 4);
1617
0
    }
1618
21.1k
    if (cu.imv < IMV_HPEL)
1619
21.1k
    {
1620
21.1k
    m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 1 ) );
1621
21.1k
    DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() value=%d ctx=%d\n", (cu.imv > 1), 1 );
1622
21.1k
    }
1623
21.1k
  }
1624
1625
21.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "imv_mode() IMVFlag=%d\n", cu.imv );
1626
21.1k
}
1627
1628
1629
void CABACWriter::affine_amvr_mode( const CodingUnit& cu )
1630
21.1k
{
1631
21.1k
  const SPS* sps = cu.slice->sps;
1632
1633
21.1k
  if( !sps->AffineAmvr || !cu.affine )
1634
21.1k
  {
1635
21.1k
    return;
1636
21.1k
  }
1637
1638
0
  if ( !CU::hasSubCUNonZeroAffineMVd( cu ) )
1639
0
  {
1640
0
    return;
1641
0
  }
1642
1643
0
  m_BinEncoder.encodeBin( (cu.imv > 0), Ctx::ImvFlag( 2 ) );
1644
0
  DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", (cu.imv > 0), 2 );
1645
1646
0
  if( cu.imv > 0 )
1647
0
  {
1648
0
    m_BinEncoder.encodeBin( (cu.imv > 1), Ctx::ImvFlag( 3 ) );
1649
0
    DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() value=%d ctx=%d\n", (cu.imv > 1), 3 );
1650
0
  }
1651
0
  DTRACE( g_trace_ctx, D_SYNTAX, "affine_amvr_mode() IMVFlag=%d\n", cu.imv );
1652
0
}
1653
1654
1655
void CABACWriter::merge_idx( const CodingUnit& cu )
1656
0
{
1657
0
  if ( cu.affine )
1658
0
  {
1659
0
    int numCandminus1 = int( cu.cs->picHeader->maxNumAffineMergeCand ) - 1;
1660
0
    if ( numCandminus1 > 0 )
1661
0
    {
1662
0
      if ( cu.mergeIdx == 0 )
1663
0
      {
1664
0
        m_BinEncoder.encodeBin( 0, Ctx::AffMergeIdx() );
1665
0
        DTRACE( g_trace_ctx, D_SYNTAX, "aff_merge_idx() aff_merge_idx=%d\n", cu.mergeIdx );
1666
0
        return;
1667
0
      }
1668
0
      else
1669
0
      {
1670
0
        m_BinEncoder.encodeBin( 1, Ctx::AffMergeIdx() );
1671
0
        for ( unsigned idx = 1; idx < numCandminus1; idx++ )
1672
0
        {
1673
0
            m_BinEncoder.encodeBinEP( cu.mergeIdx == idx ? 0 : 1 );
1674
0
          if ( cu.mergeIdx == idx )
1675
0
          {
1676
0
            break;
1677
0
          }
1678
0
        }
1679
0
      }
1680
0
    }
1681
0
    DTRACE( g_trace_ctx, D_SYNTAX, "aff_merge_idx() aff_merge_idx=%d\n", cu.mergeIdx );
1682
0
  }
1683
0
  else
1684
0
  {
1685
0
    if( cu.geo )
1686
0
    {
1687
0
      uint8_t splitDir = cu.geoSplitDir;
1688
0
      uint8_t candIdx0 = cu.geoMergeIdx[0];
1689
0
      uint8_t candIdx1 = cu.geoMergeIdx[1];
1690
0
      DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_split_dir=%d\n", splitDir );
1691
0
      DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_idx0=%d\n", candIdx0 );
1692
0
      DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() geo_idx1=%d\n", candIdx1 );
1693
0
      xWriteTruncBinCode(splitDir, GEO_NUM_PARTITION_MODE);
1694
0
      candIdx1 -= candIdx1 < candIdx0 ? 0 : 1;
1695
0
      const int maxNumGeoCand = cu.cs->sps->maxNumGeoCand;
1696
0
      CHECK(maxNumGeoCand < 2, "Incorrect max number of geo candidates");
1697
0
      CHECK(candIdx0 >= maxNumGeoCand, "Incorrect candIdx0");
1698
0
      CHECK(candIdx1 >= maxNumGeoCand, "Incorrect candIdx1");
1699
0
      int numCandminus2 = maxNumGeoCand - 2;
1700
0
      m_BinEncoder.encodeBin( candIdx0 == 0 ? 0 : 1, Ctx::MergeIdx() );
1701
0
      if( candIdx0 > 0 )
1702
0
      {
1703
0
        unary_max_eqprob(candIdx0 - 1, numCandminus2);
1704
0
      }
1705
0
      if (numCandminus2 > 0)
1706
0
      {
1707
0
        m_BinEncoder.encodeBin(candIdx1 == 0 ? 0 : 1, Ctx::MergeIdx());
1708
0
        if (candIdx1 > 0)
1709
0
        {
1710
0
          unary_max_eqprob(candIdx1 - 1, numCandminus2 - 1);
1711
0
        }
1712
0
      }
1713
0
      return;
1714
0
    }
1715
0
    int numCandminus1 = (cu.predMode == MODE_IBC) ? (int(cu.cs->sps->maxNumIBCMergeCand) - 1) : (int(cu.cs->sps->maxNumMergeCand) - 1);
1716
0
    if( numCandminus1 > 0 )
1717
0
    {
1718
0
      if( cu.mergeIdx == 0 )
1719
0
      {
1720
0
        m_BinEncoder.encodeBin( 0, Ctx::MergeIdx() );
1721
0
        DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", cu.mergeIdx );
1722
0
        return;
1723
0
      }
1724
0
      else
1725
0
      {
1726
0
        m_BinEncoder.encodeBin( 1, Ctx::MergeIdx() );
1727
0
        for( unsigned idx = 1; idx < numCandminus1; idx++ )
1728
0
        {
1729
0
          m_BinEncoder.encodeBinEP( cu.mergeIdx == idx ? 0 : 1 );
1730
0
          if( cu.mergeIdx == idx )
1731
0
          {
1732
0
            break;
1733
0
          }
1734
0
        }
1735
0
      }
1736
0
    }
1737
0
    DTRACE( g_trace_ctx, D_SYNTAX, "merge_idx() merge_idx=%d\n", cu.mergeIdx );
1738
0
  }
1739
0
}
1740
1741
1742
void CABACWriter::mmvd_merge_idx( const CodingUnit &cu )
1743
0
{
1744
0
  const int mvdBaseIdx  = cu.mmvdMergeIdx.pos.baseIdx;
1745
0
  const int mvdStep     = cu.mmvdMergeIdx.pos.step;
1746
0
  const int mvdPosition = cu.mmvdMergeIdx.pos.position;
1747
1748
0
  if( cu.cs->sps->maxNumMergeCand > 1 )
1749
0
  {
1750
0
    static_assert( MMVD_BASE_MV_NUM == 2, "" );
1751
0
    CHECK( mvdBaseIdx >= 2, "Invalid mvdBaseIdx" );
1752
0
    m_BinEncoder.encodeBin( mvdBaseIdx, Ctx::MmvdMergeIdx() );
1753
0
  }
1754
0
  DTRACE( g_trace_ctx, D_SYNTAX, "base_mvp_idx() base_mvp_idx=%d\n", mvdBaseIdx );
1755
1756
0
  int numCandminus1_step = MMVD_REFINE_STEP - 1;
1757
0
  if( numCandminus1_step > 0 )
1758
0
  {
1759
0
    if( mvdStep == 0 )
1760
0
    {
1761
0
      m_BinEncoder.encodeBin( 0, Ctx::MmvdStepMvpIdx() );
1762
0
    }
1763
0
    else
1764
0
    {
1765
0
      m_BinEncoder.encodeBin( 1, Ctx::MmvdStepMvpIdx() );
1766
0
      for( unsigned idx = 1; idx < numCandminus1_step; idx++ )
1767
0
      {
1768
0
        m_BinEncoder.encodeBinEP( mvdStep == idx ? 0 : 1 );
1769
0
        if( mvdStep == idx )
1770
0
        {
1771
0
          break;
1772
0
        }
1773
0
      }
1774
0
    }
1775
0
  }
1776
0
  DTRACE( g_trace_ctx, D_SYNTAX, "MmvdStepMvpIdx() MmvdStepMvpIdx=%d\n", mvdStep );
1777
1778
0
  m_BinEncoder.encodeBinsEP( mvdPosition, 2 );
1779
1780
0
  DTRACE( g_trace_ctx, D_SYNTAX, "pos() pos=%d\n", mvdPosition );
1781
0
  DTRACE( g_trace_ctx, D_SYNTAX, "mmvd_merge_idx() mmvd_merge_idx=%d\n", cu.mmvdMergeIdx.val );
1782
0
}
1783
1784
1785
void CABACWriter::inter_pred_idc( const CodingUnit& cu )
1786
0
{
1787
0
  if( !cu.cs->slice->isInterB() )
1788
0
  {
1789
0
    return;
1790
0
  }
1791
0
  if( !(CU::isBipredRestriction(cu)) )
1792
0
  {
1793
0
    unsigned ctxId = DeriveCtx::CtxInterDir(cu);
1794
0
    if( cu.interDir == 3 )
1795
0
    {
1796
0
      m_BinEncoder.encodeBin( 1, Ctx::InterDir(ctxId) );
1797
0
      DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=%d value=%d pos=(%d,%d)\n", ctxId, cu.interDir, cu.lumaPos().x, cu.lumaPos().y );
1798
0
      return;
1799
0
    }
1800
0
    else
1801
0
    {
1802
0
      m_BinEncoder.encodeBin( 0, Ctx::InterDir(ctxId) );
1803
0
    }
1804
0
  }
1805
0
  m_BinEncoder.encodeBin( ( cu.interDir == 2 ), Ctx::InterDir( 5 ) );
1806
0
  DTRACE( g_trace_ctx, D_SYNTAX, "inter_pred_idc() ctx=5 value=%d pos=(%d,%d)\n", cu.interDir, cu.lumaPos().x, cu.lumaPos().y );
1807
0
}
1808
1809
1810
void CABACWriter::ref_idx( const CodingUnit& cu, RefPicList eRefList )
1811
21.1k
{
1812
21.1k
  if ( cu.smvdMode )
1813
0
  {
1814
0
    CHECK( cu.refIdx[eRefList] != cu.cs->slice->symRefIdx[ eRefList ], "Invalid reference index!\n" );
1815
0
    return;
1816
0
  }
1817
1818
21.1k
  int numRef  = cu.cs->slice->numRefIdx[eRefList];
1819
1820
21.1k
  if (eRefList == REF_PIC_LIST_0 && cu.cs->sps->IBC)
1821
21.1k
  {
1822
21.1k
    if (CU::isIBC(cu))
1823
21.1k
      return;
1824
21.1k
  }
1825
1826
0
  if( numRef <= 1 )
1827
0
  {
1828
0
    return;
1829
0
  }
1830
0
  int refIdx  = cu.refIdx[eRefList];
1831
0
  m_BinEncoder.encodeBin( (refIdx > 0), Ctx::RefPic() );
1832
0
  if( numRef <= 2 || refIdx == 0 )
1833
0
  {
1834
0
    DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y );
1835
0
    return;
1836
0
  }
1837
0
  m_BinEncoder.encodeBin( (refIdx > 1), Ctx::RefPic(1) );
1838
0
  if( numRef <= 3 || refIdx == 1 )
1839
0
  {
1840
0
    DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y );
1841
0
    return;
1842
0
  }
1843
0
  for( int idx = 3; idx < numRef; idx++ )
1844
0
  {
1845
0
    if( refIdx > idx - 1 )
1846
0
    {
1847
0
      m_BinEncoder.encodeBinEP( 1 );
1848
0
    }
1849
0
    else
1850
0
    {
1851
0
      m_BinEncoder.encodeBinEP( 0 );
1852
0
      break;
1853
0
    }
1854
0
  }
1855
0
  DTRACE( g_trace_ctx, D_SYNTAX, "ref_idx() value=%d pos=(%d,%d)\n", refIdx, cu.lumaPos().x, cu.lumaPos().y );
1856
0
}
1857
1858
1859
void CABACWriter::mvp_flag( const CodingUnit& cu, RefPicList eRefList )
1860
21.1k
{
1861
21.1k
  m_BinEncoder.encodeBin( cu.mvpIdx[eRefList], Ctx::MVPIdx() );
1862
21.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "mvp_flag() value=%d pos=(%d,%d)\n", cu.mvpIdx[eRefList], cu.lumaPos().x, cu.lumaPos().y );
1863
21.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "mvpIdx(refList:%d)=%d\n", eRefList, cu.mvpIdx[eRefList] );
1864
21.1k
}
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
152k
{
1894
152k
  const UnitArea&       area = partitioner.currArea();
1895
152k
  int             subTuCounter = subTuIdx;
1896
152k
  const TransformUnit&  tu = *cs.getTU(area.blocks[partitioner.chType].pos(), partitioner.chType, subTuIdx);
1897
152k
  const CodingUnit&     cu = *tu.cu;
1898
152k
  const unsigned        trDepth = partitioner.currTrDepth;
1899
152k
  const bool            split = (tu.depth > trDepth);
1900
152k
  if( split )
1901
41
  {
1902
41
    PartSplit partSplit;
1903
1904
41
    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
41
    else if( cu.ispMode )
1914
41
    {
1915
41
      partitioner.splitCurrArea( ispType, cs );
1916
41
    }
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
41
    do
1925
164
    {
1926
164
      transform_tree( cs, partitioner, cuCtx,                ispType, subTuCounter );
1927
164
      subTuCounter += subTuCounter != -1 ? 1 : 0;
1928
164
    } while( partitioner.nextPart( cs ) );
1929
1930
41
    partitioner.exitCurrSplit();
1931
41
  }
1932
152k
  else
1933
152k
  {
1934
    // split_transform_flag
1935
152k
    CHECK( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) || (cu.sbtInfo && partitioner.canSplit( CU::getSbtTuSplit( cu.sbtInfo ), cs)),  "transform split implied" );
1936
152k
    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
152k
    transform_unit( tu, cuCtx, partitioner, subTuCounter);
1939
152k
  }
1940
152k
}
1941
1942
1943
void CABACWriter::cbf_comp( const CodingUnit& cu, bool cbf, const CompArea& area, unsigned depth, const bool prevCbf, const bool useISP )
1944
2.92M
{
1945
2.92M
  const CtxSet&   ctxSet  = Ctx::QtCbf[ area.compID ];
1946
2.92M
  unsigned  ctxId;
1947
2.92M
  if( cu.bdpcmM[toChannelType(area.compID)] )
1948
188k
  {
1949
188k
    ctxId = (area.compID != COMP_Cr) ? 1 : 2;
1950
188k
    m_BinEncoder.encodeBin(cbf, ctxSet(ctxId));
1951
188k
  }
1952
2.73M
  else
1953
2.73M
  {
1954
2.73M
    ctxId = DeriveCtx::CtxQtCbf(area.compID, prevCbf, useISP && isLuma(area.compID));
1955
2.73M
    m_BinEncoder.encodeBin( cbf, ctxSet( ctxId ) );
1956
2.73M
  }
1957
2.92M
  DTRACE( g_trace_ctx, D_SYNTAX, "cbf_comp() etype=%d pos=(%d,%d) ctx=%d cbf=%d\n", area.compID, area.x, area.y, ctxId, cbf );
1958
2.92M
}
1959
1960
1961
1962
//================================================================================
1963
//  clause 7.3.8.9
1964
//--------------------------------------------------------------------------------
1965
//    void  mvd_coding( cu, refList )
1966
//================================================================================
1967
void CABACWriter::mvd_coding( const Mv &rMvd, int8_t imv )
1968
21.1k
{
1969
21.1k
  int       horMvd = rMvd.hor;
1970
21.1k
  int       verMvd = rMvd.ver;
1971
21.1k
  if ( imv > 0 )
1972
0
  {
1973
0
    int shift = 1;
1974
0
    if (imv < IMV_HPEL)
1975
0
    {
1976
0
      shift = 2;
1977
0
      if (imv == IMV_4PEL)
1978
0
      {
1979
0
        shift = 4;
1980
0
      }
1981
0
    }
1982
1983
0
    CHECK((horMvd % (1<<shift)) != 0 && (verMvd % (4<<shift)) != 0, "IMV: MVD is not a multiple of 2^N ");
1984
0
    horMvd >>= shift;
1985
0
    verMvd >>= shift;
1986
0
  }
1987
21.1k
  unsigned  horAbs  = unsigned( horMvd < 0 ? -horMvd : horMvd );
1988
21.1k
  unsigned  verAbs  = unsigned( verMvd < 0 ? -verMvd : verMvd );
1989
1990
1991
  // abs_mvd_greater0_flag[ 0 | 1 ]
1992
21.1k
  m_BinEncoder.encodeBin( (horAbs > 0), Ctx::Mvd() );
1993
21.1k
  m_BinEncoder.encodeBin( (verAbs > 0), Ctx::Mvd() );
1994
1995
  // abs_mvd_greater1_flag[ 0 | 1 ]
1996
21.1k
  if( horAbs > 0 )
1997
13.0k
  {
1998
13.0k
    m_BinEncoder.encodeBin( (horAbs > 1), Ctx::Mvd(1) );
1999
13.0k
  }
2000
21.1k
  if( verAbs > 0 )
2001
8.04k
  {
2002
8.04k
    m_BinEncoder.encodeBin( (verAbs > 1), Ctx::Mvd(1) );
2003
8.04k
  }
2004
2005
  // abs_mvd_minus2[ 0 | 1 ] and mvd_sign_flag[ 0 | 1 ]
2006
21.1k
  if( horAbs > 0 )
2007
13.0k
  {
2008
13.0k
    if( horAbs > 1 )
2009
13.0k
    {
2010
13.0k
      m_BinEncoder.encodeRemAbsEP(horAbs - 2, 1, 0, MV_BITS - 1);
2011
13.0k
    }
2012
13.0k
    m_BinEncoder.encodeBinEP( (horMvd < 0) );
2013
13.0k
  }
2014
21.1k
  if( verAbs > 0 )
2015
8.04k
  {
2016
8.04k
    if( verAbs > 1 )
2017
7.97k
    {
2018
7.97k
      m_BinEncoder.encodeRemAbsEP(verAbs - 2, 1, 0, MV_BITS - 1);
2019
7.97k
    }
2020
8.04k
    m_BinEncoder.encodeBinEP( (verMvd < 0) );
2021
8.04k
  }
2022
21.1k
}
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
152k
{
2034
152k
  const CodingUnit&       cu = *tu.cu;
2035
152k
  const UnitArea&         area = partitioner.currArea();
2036
152k
  const unsigned          trDepth = partitioner.currTrDepth;
2037
152k
  ChromaCbfs              chromaCbfs;
2038
152k
  CHECK(tu.depth != trDepth, " transform unit should be not be futher partitioned");
2039
2040
  // cbf_cb & cbf_cr
2041
152k
  if (area.chromaFormat != CHROMA_400)
2042
152k
  {
2043
152k
    const bool              chromaCbfISP = area.blocks[COMP_Cb].valid() && cu.ispMode;
2044
152k
    if (area.blocks[COMP_Cb].valid() && (!CU::isSepTree(cu) || partitioner.chType == CH_C) && (!cu.ispMode || chromaCbfISP))
2045
83.7k
    {
2046
83.7k
      unsigned cbfDepth = chromaCbfISP ? trDepth - 1 : trDepth;
2047
83.7k
      {
2048
83.7k
        chromaCbfs.Cb = TU::getCbfAtDepth(tu, COMP_Cb, trDepth);
2049
        //if (!(cu.sbtInfo && trDepth == 1))
2050
83.7k
        if (!(cu.sbtInfo && tu.noResidual))
2051
83.7k
          cbf_comp(*tu.cu, chromaCbfs.Cb, area.blocks[COMP_Cb], cbfDepth);
2052
83.7k
      }
2053
2054
83.7k
      {
2055
83.7k
        chromaCbfs.Cr = TU::getCbfAtDepth(tu, COMP_Cr, trDepth);
2056
        //if (!(cu.sbtInfo && trDepth == 1))
2057
83.7k
        if (!(cu.sbtInfo && tu.noResidual))
2058
83.7k
          cbf_comp(*tu.cu, chromaCbfs.Cr, area.blocks[COMP_Cr], cbfDepth, chromaCbfs.Cb);
2059
83.7k
      }
2060
83.7k
    }
2061
68.6k
    else if (CU::isSepTree(cu))
2062
68.6k
    {
2063
68.6k
      chromaCbfs = ChromaCbfs(false);
2064
68.6k
    }
2065
152k
  }
2066
0
  else if (CU::isSepTree(cu))
2067
0
  {
2068
0
    chromaCbfs = ChromaCbfs(false);
2069
0
  }
2070
2071
152k
  if (!isChroma(partitioner.chType))
2072
68.6k
  {
2073
68.6k
    if (!CU::isIntra(cu) && trDepth == 0 && !chromaCbfs.sigChroma(area.chromaFormat))
2074
129
    {
2075
129
      CHECK(!TU::getCbfAtDepth(tu, COMP_Y, trDepth), "Luma cbf must be true for inter units with no chroma coeffs");
2076
129
    }
2077
68.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
68.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
68.4k
    else
2087
68.4k
    {
2088
68.4k
      bool previousCbf = false;
2089
68.4k
      bool rootCbfSoFar = false;
2090
68.4k
      bool lumaCbfIsInferredACT = (cu.colorTransform && cu.predMode == MODE_INTRA && trDepth == 0 && !chromaCbfs.sigChroma(area.chromaFormat));
2091
68.4k
      CHECK(lumaCbfIsInferredACT && !TU::getCbfAtDepth(tu, COMP_Y, trDepth), "adaptive color transform cannot have all zero coefficients");
2092
68.4k
      bool lastCbfIsInferred    = lumaCbfIsInferredACT; // ISP and ACT are mutually exclusive
2093
68.4k
      if (cu.ispMode)
2094
164
      {
2095
164
        uint32_t nTus = cu.ispMode == HOR_INTRA_SUBPARTITIONS ? cu.lheight() >> Log2(tu.lheight()) : cu.lwidth() >> Log2(tu.lwidth());
2096
164
        if (subTuCounter == nTus - 1)
2097
41
        {
2098
41
          TransformUnit* tuPointer = cu.firstTU;
2099
164
          for (int tuIdx = 0; tuIdx < subTuCounter; tuIdx++)
2100
123
          {
2101
123
            rootCbfSoFar |= TU::getCbfAtDepth(*tuPointer, COMP_Y, trDepth);
2102
123
            tuPointer = tuPointer->next;
2103
123
          }
2104
41
          if (!rootCbfSoFar)
2105
0
          {
2106
0
            lastCbfIsInferred = true;
2107
0
          }
2108
41
        }
2109
164
        if (!lastCbfIsInferred)
2110
164
        {
2111
164
          previousCbf = TU::getPrevTuCbfAtDepth(tu, COMP_Y, partitioner.currTrDepth);
2112
164
        }
2113
164
      }
2114
68.4k
      if (!lastCbfIsInferred)
2115
68.4k
      {
2116
68.4k
        cbf_comp(*tu.cu, TU::getCbfAtDepth(tu, COMP_Y, trDepth), tu.Y(), trDepth, previousCbf, cu.ispMode);
2117
68.4k
      }
2118
68.4k
    }
2119
68.6k
  }
2120
152k
  bool        lumaOnly  = ( cu.chromaFormat == CHROMA_400 || !tu.blocks[COMP_Cb].valid() );
2121
152k
  bool        cbf[3]    = { TU::getCbf( tu, COMP_Y ), chromaCbfs.Cb, chromaCbfs.Cr };
2122
152k
  bool        cbfLuma   = ( cbf[ COMP_Y ] != 0 );
2123
152k
  bool        cbfChroma = false;
2124
2125
152k
  if( !lumaOnly )
2126
83.7k
  {
2127
83.7k
    if( tu.blocks[COMP_Cb].valid() )
2128
83.7k
    {
2129
83.7k
      cbf   [ COMP_Cb  ] = TU::getCbf( tu, COMP_Cb );
2130
83.7k
      cbf   [ COMP_Cr  ] = TU::getCbf( tu, COMP_Cr );
2131
83.7k
    }
2132
83.7k
    cbfChroma = ( cbf[ COMP_Cb ] || cbf[ COMP_Cr ] );
2133
83.7k
  }
2134
2135
152k
  if( ( cu.lwidth() > 64 || cu.lheight() > 64 || cbfLuma || cbfChroma ) &&
2136
26.6k
    (!CU::isSepTree(*tu.cu) || isLuma(tu.chType)) )
2137
4.79k
  {
2138
4.79k
    if( cu.cs->pps->useDQP && !cuCtx.isDQPCoded )
2139
2.32k
    {
2140
2.32k
      cu_qp_delta(cu, cuCtx.qp, cu.qp);
2141
2.32k
      cuCtx.qp = cu.qp;
2142
2.32k
      cuCtx.isDQPCoded = true;
2143
2.32k
    }
2144
4.79k
  }
2145
152k
  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
152k
  if( !lumaOnly )
2152
83.7k
  {
2153
83.7k
    joint_cb_cr( tu, ( cbf[COMP_Cb] ? 2 : 0 ) + ( cbf[COMP_Cr] ? 1 : 0 ) );
2154
83.7k
  }
2155
2156
152k
  if( cbfLuma )
2157
4.79k
  {
2158
4.79k
    residual_coding( tu, COMP_Y, &cuCtx );
2159
4.79k
  }
2160
152k
  if( !lumaOnly )
2161
83.7k
  {
2162
251k
    for( ComponentID compID = COMP_Cb; compID <= COMP_Cr; compID = ComponentID( compID + 1 ) )
2163
167k
    {
2164
167k
      if( cbf[ compID ] )
2165
43.2k
      {
2166
43.2k
        residual_coding( tu, compID, &cuCtx );
2167
43.2k
      }
2168
167k
    }
2169
83.7k
  }
2170
152k
}
2171
2172
2173
void CABACWriter::cu_qp_delta( const CodingUnit& cu, int predQP, const int8_t qp )
2174
3.48k
{
2175
3.48k
  CHECK(!( predQP != std::numeric_limits<int>::max()), "Unspecified error");
2176
3.48k
  int       DQp         = qp - predQP;
2177
3.48k
  int       qpBdOffsetY = cu.cs->sps->qpBDOffset[ CH_L ];
2178
3.48k
  DQp                   = ( DQp + (MAX_QP + 1) + (MAX_QP + 1) / 2 + qpBdOffsetY + (qpBdOffsetY / 2)) % ((MAX_QP + 1) + qpBdOffsetY) - (MAX_QP + 1) / 2 - (qpBdOffsetY / 2);
2179
3.48k
  unsigned  absDQP      = unsigned( DQp < 0 ? -DQp : DQp );
2180
3.48k
  unsigned  unaryDQP    = std::min<unsigned>( absDQP, CU_DQP_TU_CMAX );
2181
2182
3.48k
  unary_max_symbol( unaryDQP, Ctx::DeltaQP(), Ctx::DeltaQP(1), CU_DQP_TU_CMAX );
2183
3.48k
  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.48k
  if( absDQP > 0 )
2188
0
  {
2189
0
    m_BinEncoder.encodeBinEP( DQp < 0 );
2190
0
  }
2191
2192
3.48k
  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.48k
}
2194
2195
2196
void CABACWriter::cu_chroma_qp_offset( const CodingUnit& cu )
2197
0
{
2198
  // cu_chroma_qp_offset_flag
2199
0
  unsigned qpAdj = cu.chromaQpAdj;
2200
0
  if( qpAdj == 0 )
2201
0
  {
2202
0
    m_BinEncoder.encodeBin( 0, Ctx::ChromaQpAdjFlag() );
2203
0
  }
2204
0
  else
2205
0
  {
2206
0
    m_BinEncoder.encodeBin( 1, Ctx::ChromaQpAdjFlag() );
2207
0
    int length = cu.cs->pps->chromaQpOffsetListLen;
2208
0
    if( length > 1 )
2209
0
    {
2210
0
      unary_max_symbol( qpAdj-1, Ctx::ChromaQpAdjIdc(), Ctx::ChromaQpAdjIdc(), length-1 );
2211
0
    }
2212
0
  }
2213
0
}
2214
2215
2216
//================================================================================
2217
//  clause 7.3.8.11
2218
//--------------------------------------------------------------------------------
2219
//    void        residual_coding         ( tu, compID )
2220
//    void        transform_skip_flag     ( tu, compID )
2221
//    void        last_sig_coeff          ( coeffCtx )
2222
//    void        residual_coding_subblock( coeffCtx )
2223
//================================================================================
2224
2225
void CABACWriter::joint_cb_cr( const TransformUnit& tu, const int cbfMask )
2226
1.31M
{
2227
1.31M
  if ( !tu.cu->slice->sps->jointCbCr )
2228
0
  {
2229
0
    return;
2230
0
  }
2231
2232
1.31M
  CHECK( tu.jointCbCr && tu.jointCbCr != cbfMask, "wrong value of jointCbCr (" << (int)tu.jointCbCr << " vs " << (int)cbfMask << ")" );
2233
1.31M
  if( ( CU::isIntra( *tu.cu ) && cbfMask ) || ( cbfMask == 3 ) )
2234
623k
  {
2235
623k
    m_BinEncoder.encodeBin( tu.jointCbCr ? 1 : 0, Ctx::JointCbCrFlag( cbfMask - 1 ) );
2236
623k
  }
2237
1.31M
}
2238
2239
2240
void CABACWriter::residual_coding( const TransformUnit& tu, ComponentID compID, CUCtx* cuCtx )
2241
1.27M
{
2242
1.27M
  const CodingUnit& cu = *tu.cu;
2243
1.27M
  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.27M
  if( compID == COMP_Cr && tu.jointCbCr == 3 )
2246
364k
  {
2247
364k
    return;
2248
364k
  }
2249
2250
907k
  ts_flag            ( tu, compID );
2251
2252
907k
  if( tu.mtsIdx[compID] == MTS_SKIP && !tu.cs->slice->tsResidualCodingDisabled )
2253
63.9k
  {
2254
63.9k
    residual_codingTS( tu, compID );
2255
63.9k
    return;
2256
63.9k
  }
2257
2258
  // determine sign hiding
2259
844k
  bool signHiding  = cu.cs->slice->signDataHidingEnabled;
2260
2261
  // init coeff coding context
2262
844k
  CoeffCodingContext  cctx    ( tu, compID, signHiding, false, m_tplBuf );
2263
844k
  const TCoeffSig*    coeff   = tu.getCoeffs( compID ).buf;
2264
2265
  // determine and set last coeff position and sig group flags
2266
844k
  int                      scanPosLast = tu.lastPos[compID];
2267
844k
  std::bitset<MLS_GRP_NUM> sigGroupFlags;
2268
2269
1.71M
  for( int subSetId = 0; subSetId <= ( scanPosLast >> cctx.log2CGSize() ); subSetId++ )
2270
869k
  {
2271
869k
    const int scanPosStart = subSetId << cctx.log2CGSize();
2272
869k
    const int scanPosEnd   = scanPosStart + ( 1 << cctx.log2CGSize() ) - 1;
2273
2274
7.90M
    for( int scanPos = scanPosEnd; scanPos >= scanPosStart; scanPos-- )
2275
7.89M
    {
2276
7.89M
      unsigned blkPos = cctx.blockPos( scanPos );
2277
2278
7.89M
      if( coeff[blkPos] )
2279
861k
      {
2280
861k
        sigGroupFlags.set( subSetId );
2281
861k
        break;
2282
861k
      }
2283
7.89M
    }
2284
869k
  }
2285
844k
  CHECK( scanPosLast < 0, "Coefficient coding called for empty TU" );
2286
844k
  cctx.setScanPosLast(scanPosLast);
2287
2288
844k
  if( cuCtx && tu.mtsIdx[compID] != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
2289
741k
  {
2290
741k
    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
741k
    cuCtx->violatesLfnstConstrained[ toChannelType(compID) ] |= cctx.scanPosLast() > maxLfnstPos;
2292
741k
  }
2293
844k
  if( cuCtx && tu.mtsIdx[compID] != MTS_SKIP && tu.blocks[ compID ].height >= 4 && tu.blocks[ compID ].width >= 4 )
2294
741k
  {
2295
741k
    const int lfnstLastScanPosTh = isLuma( compID ) ? LFNST_LAST_SIG_LUMA : LFNST_LAST_SIG_CHROMA;
2296
741k
    cuCtx->lfnstLastScanPos |= cctx.scanPosLast() >= lfnstLastScanPosTh;
2297
741k
  }
2298
844k
  if (cuCtx && isLuma(compID) && tu.mtsIdx[compID] != MTS_SKIP)
2299
26.9k
  {
2300
26.9k
    cuCtx->mtsLastScanPos |= cctx.scanPosLast() >= 1;
2301
26.9k
  }
2302
  
2303
  // code last coeff position
2304
844k
  last_sig_coeff( cctx, tu, compID );
2305
2306
  // code subblocks
2307
844k
  const int stateTab  = ( tu.cs->slice->depQuantEnabled ? 32040 : 0 );
2308
844k
  int       state     = 0;
2309
2310
844k
  int ctxBinSampleRatio = MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT;
2311
844k
  cctx.remRegBins = (tu.getTbAreaAfterCoefZeroOut(compID) * ctxBinSampleRatio) >> 4;
2312
2313
844k
  const bool zeroOutCheck  = isLuma( compID ) && tu.cs->sps->MTS && tu.cu->sbtInfo != 0 && tu.blocks[compID].height <= 32 && tu.blocks[compID].width <= 32;
2314
844k
  const bool zeroOutWidth  = tu.blocks[compID].width;
2315
844k
  const bool zeroOutHeight = tu.blocks[compID].height;
2316
2317
1.71M
  for( int subSetId = ( cctx.scanPosLast() >> cctx.log2CGSize() ); subSetId >= 0; subSetId--)
2318
869k
  {
2319
869k
    cctx.initSubblock( subSetId, sigGroupFlags[subSetId] );
2320
2321
869k
    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
869k
    residual_coding_subblock( cctx, coeff, stateTab, state );
2330
869k
    if ( cuCtx && isLuma(compID) && cctx.isSigGroup() && ( cctx.cgPosY() > 3 || cctx.cgPosX() > 3 ) )
2331
0
    {
2332
0
      cuCtx->violatesMtsCoeffConstraint = true;
2333
0
    }
2334
869k
  }
2335
844k
}
2336
2337
2338
void CABACWriter::ts_flag( const TransformUnit& tu, ComponentID compID )
2339
907k
{
2340
907k
  int tsFlag = tu.mtsIdx[compID] == MTS_SKIP ? 1 : 0;
2341
907k
  int ctxIdx = isLuma(compID) ? 0 : 1;
2342
  
2343
907k
  if( TU::isTSAllowed ( tu, compID ) )
2344
627k
  {
2345
627k
    m_BinEncoder.encodeBin( tsFlag, Ctx::TransformSkipFlag(ctxIdx));
2346
627k
  }
2347
907k
  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
907k
}
2349
2350
2351
void CABACWriter::mts_idx( const CodingUnit& cu, CUCtx* cuCtx )
2352
177k
{
2353
177k
  TransformUnit &tu = *cu.firstTU;
2354
177k
  int        mtsIdx = tu.mtsIdx[COMP_Y];
2355
  
2356
177k
  if( CU::isMTSAllowed( cu, COMP_Y ) && cuCtx && !cuCtx->violatesMtsCoeffConstraint &&
2357
0
      cuCtx->mtsLastScanPos && cu.lfnstIdx == 0 && mtsIdx != MTS_SKIP)
2358
0
  {
2359
0
    int symbol = mtsIdx != MTS_DCT2_DCT2 ? 1 : 0;
2360
0
    int ctxIdx = 0;
2361
    
2362
0
    m_BinEncoder.encodeBin( symbol, Ctx::MTSIdx(ctxIdx));
2363
    
2364
0
    if( symbol )
2365
0
    {
2366
0
      ctxIdx = 1;
2367
0
      for( int i = 0; i < 3; i++, ctxIdx++ )
2368
0
      {
2369
0
        symbol = mtsIdx > i + MTS_DST7_DST7 ? 1 : 0;
2370
0
        m_BinEncoder.encodeBin( symbol, Ctx::MTSIdx(ctxIdx));
2371
        
2372
0
        if( !symbol )
2373
0
        {
2374
0
          break;
2375
0
        }
2376
0
      }
2377
0
    }
2378
0
  }
2379
177k
  DTRACE( g_trace_ctx, D_SYNTAX, "mts_idx() etype=%d pos=(%d,%d) mtsIdx=%d\n", COMP_Y, tu.cu->lx(), tu.cu->ly(), mtsIdx);
2380
177k
}
2381
2382
2383
void CABACWriter::isp_mode( const CodingUnit& cu )
2384
853k
{
2385
853k
  if( !CU::isIntra( cu ) || !isLuma( cu.chType ) || cu.multiRefIdx || !cu.cs->sps->ISP || cu.bdpcmM[CH_L] || !CU::canUseISP( cu, getFirstComponentOfChannel( cu.chType ) )  || cu.colorTransform)
2386
156k
  {
2387
156k
    CHECK( cu.ispMode != NOT_INTRA_SUBPARTITIONS, "cu.ispMode != 0" );
2388
156k
    return;
2389
156k
  }
2390
697k
  if ( cu.ispMode == NOT_INTRA_SUBPARTITIONS )
2391
687k
  {
2392
687k
    m_BinEncoder.encodeBin( 0, Ctx::ISPMode( 0 ) );
2393
687k
  }
2394
9.96k
  else
2395
9.96k
  {
2396
9.96k
    m_BinEncoder.encodeBin( 1, Ctx::ISPMode( 0 ) );
2397
9.96k
    m_BinEncoder.encodeBin( cu.ispMode - 1, Ctx::ISPMode( 1 ) );
2398
9.96k
  }
2399
697k
  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
697k
}
2401
2402
2403
void CABACWriter::residual_lfnst_mode( const CodingUnit& cu, CUCtx& cuCtx )
2404
256k
{
2405
256k
  int chIdx = CS::isDualITree( *cu.cs ) && cu.chType == CH_C ? 1 : 0;
2406
256k
  if( ( cu.ispMode && !CU::canUseLfnstWithISP( cu, cu.chType ) ) ||
2407
256k
      (cu.cs->sps->LFNST && CU::isIntra(cu) && cu.mipFlag && !allowLfnstWithMip(cu.lumaSize())) ||
2408
254k
    ( CU::isSepTree(cu) && cu.chType == CH_C && std::min( cu.blocks[ 1 ].width, cu.blocks[ 1 ].height ) < 4 )
2409
252k
    || ( cu.blocks[ chIdx ].lumaSize().width > cu.cs->sps->getMaxTbSize() || cu.blocks[ chIdx ].lumaSize().height > cu.cs->sps->getMaxTbSize() )
2410
256k
    )
2411
4.77k
  {
2412
4.77k
    return;
2413
4.77k
  }
2414
2415
252k
  if( cu.cs->sps->LFNST && CU::isIntra( cu )  )
2416
251k
  {
2417
251k
    const bool lumaFlag                   = CU::isSepTree(cu) ? (   isLuma( cu.chType ) ? true : false ) : true;
2418
251k
    const bool chromaFlag                 = CU::isSepTree(cu) ? ( isChroma( cu.chType ) ? true : false ) : true;
2419
251k
          bool nonZeroCoeffNonTsCorner8x8 = ( lumaFlag && cuCtx.violatesLfnstConstrained[CH_L] ) || (chromaFlag && cuCtx.violatesLfnstConstrained[CH_C] );
2420
2421
251k
    bool isTrSkip = false;
2422
2423
251k
    for( const auto& currTU : cTUTraverser( cu.firstTU, cu.lastTU->next ) )
2424
257k
    {
2425
257k
      const uint32_t numValidComp = getNumberValidComponents(cu.chromaFormat);
2426
1.02M
      for (uint32_t compID = COMP_Y; compID < numValidComp; compID++)
2427
771k
      {
2428
771k
        if (currTU.blocks[compID].valid() && TU::getCbf(currTU, (ComponentID)compID) && currTU.mtsIdx[compID] == MTS_SKIP)
2429
60
        {
2430
60
          isTrSkip = true;
2431
60
          break;
2432
60
        }
2433
771k
      }
2434
257k
    }
2435
2436
251k
    if( (!cuCtx.lfnstLastScanPos && !cu.ispMode) || nonZeroCoeffNonTsCorner8x8 || isTrSkip )
2437
236k
    {
2438
236k
      return;
2439
236k
    }
2440
251k
  }
2441
129
  else
2442
129
  {
2443
129
    return;
2444
129
  }
2445
  
2446
15.1k
  unsigned cctx = 0;
2447
15.1k
  if ( CU::isSepTree(cu) ) cctx++;
2448
2449
15.1k
  const uint32_t idxLFNST = cu.lfnstIdx;
2450
15.1k
  assert( idxLFNST < 3 );
2451
15.1k
  m_BinEncoder.encodeBin( idxLFNST ? 1 : 0, Ctx::LFNSTIdx( cctx ) );
2452
2453
15.1k
  if( idxLFNST )
2454
14.7k
  {
2455
14.7k
    m_BinEncoder.encodeBin( (idxLFNST - 1) ? 1 : 0, Ctx::LFNSTIdx(2));
2456
14.7k
  }
2457
2458
15.1k
  DTRACE( g_trace_ctx, D_SYNTAX, "residual_lfnst_mode() etype=%d pos=(%d,%d) mode=%d\n", COMP_Y, cu.lx(), cu.ly(), ( int ) cu.lfnstIdx );
2459
15.1k
}
2460
2461
2462
void CABACWriter::last_sig_coeff( CoeffCodingContext& cctx, const TransformUnit& tu, ComponentID compID )
2463
844k
{
2464
844k
  unsigned blkPos = cctx.blockPos( cctx.scanPosLast() );
2465
844k
  unsigned posX, posY;
2466
844k
  {
2467
844k
    posY  = blkPos / cctx.width();
2468
844k
    posX  = blkPos - ( posY * cctx.width() );
2469
844k
  }
2470
2471
844k
  unsigned CtxLast;
2472
844k
  unsigned GroupIdxX = g_uiGroupIdx[ posX ];
2473
844k
  unsigned GroupIdxY = g_uiGroupIdx[ posY ];
2474
2475
844k
  unsigned maxLastPosX = cctx.maxLastPosX();
2476
844k
  unsigned maxLastPosY = cctx.maxLastPosY();
2477
2478
844k
  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.96M
  for( CtxLast = 0; CtxLast < GroupIdxX; CtxLast++ )
2485
1.11M
  {
2486
1.11M
    m_BinEncoder.encodeBin( 1, cctx.lastXCtxId( CtxLast ) );
2487
1.11M
  }
2488
844k
  if( GroupIdxX < maxLastPosX )
2489
807k
  {
2490
807k
    m_BinEncoder.encodeBin( 0, cctx.lastXCtxId( CtxLast ) );
2491
807k
  }
2492
2.02M
  for( CtxLast = 0; CtxLast < GroupIdxY; CtxLast++ )
2493
1.17M
  {
2494
1.17M
    m_BinEncoder.encodeBin( 1, cctx.lastYCtxId( CtxLast ) );
2495
1.17M
  }
2496
844k
  if( GroupIdxY < maxLastPosY )
2497
800k
  {
2498
800k
    m_BinEncoder.encodeBin( 0, cctx.lastYCtxId( CtxLast ) );
2499
800k
  }
2500
844k
  if( GroupIdxX > 3 )
2501
2.86k
  {
2502
2.86k
    posX -= g_uiMinInGroup[ GroupIdxX ];
2503
8.25k
    for (int i = ( ( GroupIdxX - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
2504
5.38k
    {
2505
5.38k
      m_BinEncoder.encodeBinEP( ( posX >> i ) & 1 );
2506
5.38k
    }
2507
2.86k
  }
2508
844k
  if( GroupIdxY > 3 )
2509
2.20k
  {
2510
2.20k
    posY -= g_uiMinInGroup[ GroupIdxY ];
2511
5.91k
    for ( int i = ( ( GroupIdxY - 2 ) >> 1 ) - 1 ; i >= 0; i-- )
2512
3.71k
    {
2513
3.71k
      m_BinEncoder.encodeBinEP( ( posY >> i ) & 1 );
2514
3.71k
    }
2515
2.20k
  }
2516
844k
}
2517
2518
2519
namespace
2520
{
2521
  // Estimates the bits of bins exactly like BitEstimator (same context updates, same bits per bin; keep the two in
2522
  // sync), but sums them in its own member. As a local object whose address never escapes, its sum can stay in a
2523
  // register, while BitEstimator's sum is read and written in memory for every bin.
2524
  class LocalBitEstimate
2525
  {
2526
  public:
2527
867k
    explicit LocalBitEstimate( CtxStore& ctx ) : m_ctx( ctx ) {}
2528
2529
23.2M
    void encodeBin     ( unsigned bin, unsigned ctxId )        { m_ctx[ctxId].estFracBitsUpdate( bin, m_fracBits ); }
2530
859k
    void encodeBinsEP  ( unsigned /*bins*/, unsigned numBins ) { m_fracBits += BinProbModelBase::estFracBitsEP( numBins ); }
2531
    void encodeRemAbsEP( unsigned bins, unsigned goRicePar, unsigned cutoff, int maxLog2TrDynamicRange )
2532
4.44M
    {
2533
4.44M
      m_fracBits += BinProbModelBase::estFracBitsEP( BitEstimatorBase::numRemAbsEPBins( bins, goRicePar, cutoff, maxLog2TrDynamicRange ) );
2534
4.44M
    }
2535
2536
867k
    uint64_t fracBits() const { return m_fracBits; }
2537
2538
  private:
2539
    CtxStore& m_ctx;
2540
    uint64_t  m_fracBits = 0;
2541
  };
2542
2543
// CABACWriter::residual_coding_subblock with the bins coded by binCoder: the writer's BinEncIf, or a LocalBitEstimate
2544
template<class BinCoder>
2545
void residual_coding_subblock_bins( CoeffCodingContext& cctx, const TCoeffSig* coeff, const int stateTransTable, int& state, BinCoder& binCoder )
2546
869k
{
2547
  //===== init =====
2548
869k
  const int   minSubPos   = cctx.minSubPos();
2549
869k
  const bool  isLast      = cctx.isLast();
2550
869k
  int         firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() );
2551
869k
  int         nextSigPos  = firstSigPos;
2552
2553
  //===== encode significant_coeffgroup_flag =====
2554
869k
  if( !isLast && cctx.isNotFirst() )
2555
21.3k
  {
2556
21.3k
    if( cctx.isSigGroup() )
2557
13.2k
    {
2558
13.2k
      binCoder.encodeBin( 1, cctx.sigGroupCtxId() );
2559
13.2k
    }
2560
8.06k
    else
2561
8.06k
    {
2562
8.06k
      binCoder.encodeBin( 0, cctx.sigGroupCtxId() );
2563
8.06k
      return;
2564
8.06k
    }
2565
21.3k
  }
2566
2567
  //===== encode absolute values =====
2568
861k
  const int inferSigPos   = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
2569
861k
  int       firstNZPos    = nextSigPos;
2570
861k
  int       lastNZPos     = -1;
2571
861k
  int       remAbsLevel   = -1;
2572
861k
  int       numNonZero    =  0;
2573
861k
  unsigned  signPattern   =  0;
2574
861k
  int       remRegBins    = cctx.remRegBins;
2575
861k
  int       firstPosMode2 = minSubPos - 1;
2576
2577
7.70M
  for( ; nextSigPos >= minSubPos && remRegBins >= 4; nextSigPos-- )
2578
6.83M
  {
2579
6.83M
    const int blkPos     = cctx.blockPos( nextSigPos );
2580
6.83M
    TCoeff    Coeff      = coeff[ blkPos ];
2581
6.83M
    unsigned  sigFlag    = ( Coeff != 0 );
2582
6.83M
    if( numNonZero || nextSigPos != inferSigPos )
2583
5.99M
    {
2584
5.99M
      const unsigned sigCtxId = cctx.sigCtxIdAbsWithAcc( nextSigPos, state );
2585
5.99M
      binCoder.encodeBin( sigFlag, sigCtxId );
2586
5.99M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2587
5.99M
      remRegBins--;
2588
5.99M
    }
2589
844k
    else if( nextSigPos != cctx.scanPosLast() )
2590
40
    {
2591
40
      cctx.sigCtxIdAbsWithAcc( nextSigPos, state ); // required for setting variables that are needed for gtx/par context selection
2592
40
    }
2593
2594
6.83M
    if( sigFlag )
2595
6.31M
    {
2596
6.31M
      uint8_t ctxOff = cctx.ctxOffsetAbs();
2597
6.31M
      numNonZero++;
2598
6.31M
      firstNZPos  = nextSigPos;
2599
6.31M
      lastNZPos   = std::max<int>( lastNZPos, nextSigPos );
2600
6.31M
      int absLevel= abs( Coeff );
2601
6.31M
      remAbsLevel = absLevel - 1;
2602
2603
6.31M
      if( nextSigPos != cctx.scanPosLast() ) signPattern <<= 1;
2604
6.31M
      if( Coeff < 0 )                        signPattern++;
2605
2606
6.31M
      unsigned gt1 = !!remAbsLevel;
2607
6.31M
      binCoder.encodeBin( gt1, cctx.greater1CtxIdAbs(ctxOff) );
2608
6.31M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1, cctx.greater1CtxIdAbs(ctxOff) );
2609
6.31M
      remRegBins--;
2610
2611
6.31M
      if( gt1 )
2612
5.45M
      {
2613
5.45M
        remAbsLevel  -= 1;
2614
5.45M
        binCoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2615
5.45M
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2616
5.45M
        remAbsLevel >>= 1;
2617
2618
5.45M
        remRegBins--;
2619
5.45M
        unsigned gt2 = !!remAbsLevel;
2620
5.45M
        binCoder.encodeBin(gt2, cctx.greater2CtxIdAbs(ctxOff));
2621
5.45M
        DTRACE(g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2, cctx.greater2CtxIdAbs(ctxOff));
2622
5.45M
        remRegBins--;
2623
5.45M
      }
2624
2625
6.31M
      cctx.absVal1stPass( nextSigPos, std::min<TCoeff>( 4 + ( absLevel & 1 ), absLevel ) );
2626
6.31M
    }
2627
2628
6.83M
    state = ( stateTransTable >> ((state<<2)+((Coeff&1)<<1)) ) & 3;
2629
6.83M
  }
2630
861k
  firstPosMode2 = nextSigPos;
2631
861k
  cctx.remRegBins = remRegBins;
2632
2633
2634
  //===== 2nd PASS: Go-rice codes =====
2635
7.70M
  for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- )
2636
6.83M
  {
2637
6.83M
    unsigned absLevel = abs( coeff[cctx.blockPos( scanPos )] );
2638
2639
6.83M
    if( absLevel >= 4 )
2640
4.34M
    {
2641
4.34M
      int      sumAll   = cctx.templateAbsSum( scanPos, coeff, 4 );
2642
4.34M
      unsigned ricePar  = g_auiGoRiceParsCoeff[sumAll];
2643
4.34M
      unsigned rem      = ( absLevel - 4 ) >> 1;
2644
4.34M
      binCoder.encodeRemAbsEP( rem, ricePar, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2645
4.34M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
2646
4.34M
    }
2647
6.83M
  }
2648
2649
  //===== coeff bypass ====
2650
964k
  for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
2651
102k
  {
2652
102k
    TCoeff    Coeff     = coeff[ cctx.blockPos( scanPos ) ];
2653
102k
    unsigned  absLevel  = abs( Coeff );
2654
102k
    int       sumAll    = cctx.templateAbsSum(scanPos, coeff, 0);
2655
102k
    int       rice      = g_auiGoRiceParsCoeff[sumAll];
2656
102k
    int       pos0      = g_auiGoRicePosCoeff0(state, rice);
2657
102k
    unsigned  rem       = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel );
2658
102k
    binCoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2659
102k
    DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
2660
102k
    state = ( stateTransTable >> ((state<<2)+((absLevel&1)<<1)) ) & 3;
2661
102k
    if( absLevel )
2662
102k
    {
2663
102k
      numNonZero++;
2664
102k
      firstNZPos = scanPos;
2665
102k
      lastNZPos   = std::max<int>( lastNZPos, scanPos );
2666
102k
      signPattern <<= 1;
2667
102k
      if( Coeff < 0 ) signPattern++;
2668
102k
    }
2669
102k
  }
2670
2671
  //===== encode sign's =====
2672
861k
  unsigned numSigns = numNonZero;
2673
861k
  if( cctx.hideSign( firstNZPos, lastNZPos ) )
2674
0
  {
2675
0
    numSigns    --;
2676
0
    signPattern >>= 1;
2677
0
  }
2678
861k
  binCoder.encodeBinsEP( signPattern, numSigns );
2679
861k
}
CABACWriter.cpp:void vvenc::(anonymous namespace)::residual_coding_subblock_bins<vvenc::BinEncIf>(vvenc::CoeffCodingContext&, short const*, int, int&, vvenc::BinEncIf&)
Line
Count
Source
2546
2.52k
{
2547
  //===== init =====
2548
2.52k
  const int   minSubPos   = cctx.minSubPos();
2549
2.52k
  const bool  isLast      = cctx.isLast();
2550
2.52k
  int         firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() );
2551
2.52k
  int         nextSigPos  = firstSigPos;
2552
2553
  //===== encode significant_coeffgroup_flag =====
2554
2.52k
  if( !isLast && cctx.isNotFirst() )
2555
0
  {
2556
0
    if( cctx.isSigGroup() )
2557
0
    {
2558
0
      binCoder.encodeBin( 1, cctx.sigGroupCtxId() );
2559
0
    }
2560
0
    else
2561
0
    {
2562
0
      binCoder.encodeBin( 0, cctx.sigGroupCtxId() );
2563
0
      return;
2564
0
    }
2565
0
  }
2566
2567
  //===== encode absolute values =====
2568
2.52k
  const int inferSigPos   = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
2569
2.52k
  int       firstNZPos    = nextSigPos;
2570
2.52k
  int       lastNZPos     = -1;
2571
2.52k
  int       remAbsLevel   = -1;
2572
2.52k
  int       numNonZero    =  0;
2573
2.52k
  unsigned  signPattern   =  0;
2574
2.52k
  int       remRegBins    = cctx.remRegBins;
2575
2.52k
  int       firstPosMode2 = minSubPos - 1;
2576
2577
5.05k
  for( ; nextSigPos >= minSubPos && remRegBins >= 4; nextSigPos-- )
2578
2.52k
  {
2579
2.52k
    const int blkPos     = cctx.blockPos( nextSigPos );
2580
2.52k
    TCoeff    Coeff      = coeff[ blkPos ];
2581
2.52k
    unsigned  sigFlag    = ( Coeff != 0 );
2582
2.52k
    if( numNonZero || nextSigPos != inferSigPos )
2583
0
    {
2584
0
      const unsigned sigCtxId = cctx.sigCtxIdAbsWithAcc( nextSigPos, state );
2585
0
      binCoder.encodeBin( sigFlag, sigCtxId );
2586
0
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2587
0
      remRegBins--;
2588
0
    }
2589
2.52k
    else if( nextSigPos != cctx.scanPosLast() )
2590
0
    {
2591
0
      cctx.sigCtxIdAbsWithAcc( nextSigPos, state ); // required for setting variables that are needed for gtx/par context selection
2592
0
    }
2593
2594
2.52k
    if( sigFlag )
2595
2.52k
    {
2596
2.52k
      uint8_t ctxOff = cctx.ctxOffsetAbs();
2597
2.52k
      numNonZero++;
2598
2.52k
      firstNZPos  = nextSigPos;
2599
2.52k
      lastNZPos   = std::max<int>( lastNZPos, nextSigPos );
2600
2.52k
      int absLevel= abs( Coeff );
2601
2.52k
      remAbsLevel = absLevel - 1;
2602
2603
2.52k
      if( nextSigPos != cctx.scanPosLast() ) signPattern <<= 1;
2604
2.52k
      if( Coeff < 0 )                        signPattern++;
2605
2606
2.52k
      unsigned gt1 = !!remAbsLevel;
2607
2.52k
      binCoder.encodeBin( gt1, cctx.greater1CtxIdAbs(ctxOff) );
2608
2.52k
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1, cctx.greater1CtxIdAbs(ctxOff) );
2609
2.52k
      remRegBins--;
2610
2611
2.52k
      if( gt1 )
2612
2.31k
      {
2613
2.31k
        remAbsLevel  -= 1;
2614
2.31k
        binCoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2615
2.31k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2616
2.31k
        remAbsLevel >>= 1;
2617
2618
2.31k
        remRegBins--;
2619
2.31k
        unsigned gt2 = !!remAbsLevel;
2620
2.31k
        binCoder.encodeBin(gt2, cctx.greater2CtxIdAbs(ctxOff));
2621
2.31k
        DTRACE(g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2, cctx.greater2CtxIdAbs(ctxOff));
2622
2.31k
        remRegBins--;
2623
2.31k
      }
2624
2625
2.52k
      cctx.absVal1stPass( nextSigPos, std::min<TCoeff>( 4 + ( absLevel & 1 ), absLevel ) );
2626
2.52k
    }
2627
2628
2.52k
    state = ( stateTransTable >> ((state<<2)+((Coeff&1)<<1)) ) & 3;
2629
2.52k
  }
2630
2.52k
  firstPosMode2 = nextSigPos;
2631
2.52k
  cctx.remRegBins = remRegBins;
2632
2633
2634
  //===== 2nd PASS: Go-rice codes =====
2635
5.05k
  for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- )
2636
2.52k
  {
2637
2.52k
    unsigned absLevel = abs( coeff[cctx.blockPos( scanPos )] );
2638
2639
2.52k
    if( absLevel >= 4 )
2640
2.31k
    {
2641
2.31k
      int      sumAll   = cctx.templateAbsSum( scanPos, coeff, 4 );
2642
2.31k
      unsigned ricePar  = g_auiGoRiceParsCoeff[sumAll];
2643
2.31k
      unsigned rem      = ( absLevel - 4 ) >> 1;
2644
2.31k
      binCoder.encodeRemAbsEP( rem, ricePar, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2645
2.31k
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
2646
2.31k
    }
2647
2.52k
  }
2648
2649
  //===== coeff bypass ====
2650
2.52k
  for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
2651
0
  {
2652
0
    TCoeff    Coeff     = coeff[ cctx.blockPos( scanPos ) ];
2653
0
    unsigned  absLevel  = abs( Coeff );
2654
0
    int       sumAll    = cctx.templateAbsSum(scanPos, coeff, 0);
2655
0
    int       rice      = g_auiGoRiceParsCoeff[sumAll];
2656
0
    int       pos0      = g_auiGoRicePosCoeff0(state, rice);
2657
0
    unsigned  rem       = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel );
2658
0
    binCoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2659
0
    DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
2660
0
    state = ( stateTransTable >> ((state<<2)+((absLevel&1)<<1)) ) & 3;
2661
0
    if( absLevel )
2662
0
    {
2663
0
      numNonZero++;
2664
0
      firstNZPos = scanPos;
2665
0
      lastNZPos   = std::max<int>( lastNZPos, scanPos );
2666
0
      signPattern <<= 1;
2667
0
      if( Coeff < 0 ) signPattern++;
2668
0
    }
2669
0
  }
2670
2671
  //===== encode sign's =====
2672
2.52k
  unsigned numSigns = numNonZero;
2673
2.52k
  if( cctx.hideSign( firstNZPos, lastNZPos ) )
2674
0
  {
2675
0
    numSigns    --;
2676
0
    signPattern >>= 1;
2677
0
  }
2678
2.52k
  binCoder.encodeBinsEP( signPattern, numSigns );
2679
2.52k
}
CABACWriter.cpp:void vvenc::(anonymous namespace)::residual_coding_subblock_bins<vvenc::(anonymous namespace)::LocalBitEstimate>(vvenc::CoeffCodingContext&, short const*, int, int&, vvenc::(anonymous namespace)::LocalBitEstimate&)
Line
Count
Source
2546
867k
{
2547
  //===== init =====
2548
867k
  const int   minSubPos   = cctx.minSubPos();
2549
867k
  const bool  isLast      = cctx.isLast();
2550
867k
  int         firstSigPos = ( isLast ? cctx.scanPosLast() : cctx.maxSubPos() );
2551
867k
  int         nextSigPos  = firstSigPos;
2552
2553
  //===== encode significant_coeffgroup_flag =====
2554
867k
  if( !isLast && cctx.isNotFirst() )
2555
21.3k
  {
2556
21.3k
    if( cctx.isSigGroup() )
2557
13.2k
    {
2558
13.2k
      binCoder.encodeBin( 1, cctx.sigGroupCtxId() );
2559
13.2k
    }
2560
8.06k
    else
2561
8.06k
    {
2562
8.06k
      binCoder.encodeBin( 0, cctx.sigGroupCtxId() );
2563
8.06k
      return;
2564
8.06k
    }
2565
21.3k
  }
2566
2567
  //===== encode absolute values =====
2568
859k
  const int inferSigPos   = nextSigPos != cctx.scanPosLast() ? ( cctx.isNotFirst() ? minSubPos : -1 ) : nextSigPos;
2569
859k
  int       firstNZPos    = nextSigPos;
2570
859k
  int       lastNZPos     = -1;
2571
859k
  int       remAbsLevel   = -1;
2572
859k
  int       numNonZero    =  0;
2573
859k
  unsigned  signPattern   =  0;
2574
859k
  int       remRegBins    = cctx.remRegBins;
2575
859k
  int       firstPosMode2 = minSubPos - 1;
2576
2577
7.69M
  for( ; nextSigPos >= minSubPos && remRegBins >= 4; nextSigPos-- )
2578
6.83M
  {
2579
6.83M
    const int blkPos     = cctx.blockPos( nextSigPos );
2580
6.83M
    TCoeff    Coeff      = coeff[ blkPos ];
2581
6.83M
    unsigned  sigFlag    = ( Coeff != 0 );
2582
6.83M
    if( numNonZero || nextSigPos != inferSigPos )
2583
5.99M
    {
2584
5.99M
      const unsigned sigCtxId = cctx.sigCtxIdAbsWithAcc( nextSigPos, state );
2585
5.99M
      binCoder.encodeBin( sigFlag, sigCtxId );
2586
5.99M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2587
5.99M
      remRegBins--;
2588
5.99M
    }
2589
841k
    else if( nextSigPos != cctx.scanPosLast() )
2590
40
    {
2591
40
      cctx.sigCtxIdAbsWithAcc( nextSigPos, state ); // required for setting variables that are needed for gtx/par context selection
2592
40
    }
2593
2594
6.83M
    if( sigFlag )
2595
6.30M
    {
2596
6.30M
      uint8_t ctxOff = cctx.ctxOffsetAbs();
2597
6.30M
      numNonZero++;
2598
6.30M
      firstNZPos  = nextSigPos;
2599
6.30M
      lastNZPos   = std::max<int>( lastNZPos, nextSigPos );
2600
6.30M
      int absLevel= abs( Coeff );
2601
6.30M
      remAbsLevel = absLevel - 1;
2602
2603
6.30M
      if( nextSigPos != cctx.scanPosLast() ) signPattern <<= 1;
2604
6.30M
      if( Coeff < 0 )                        signPattern++;
2605
2606
6.30M
      unsigned gt1 = !!remAbsLevel;
2607
6.30M
      binCoder.encodeBin( gt1, cctx.greater1CtxIdAbs(ctxOff) );
2608
6.30M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "gt1_flag() bin=%d ctx=%d\n", gt1, cctx.greater1CtxIdAbs(ctxOff) );
2609
6.30M
      remRegBins--;
2610
2611
6.30M
      if( gt1 )
2612
5.45M
      {
2613
5.45M
        remAbsLevel  -= 1;
2614
5.45M
        binCoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2615
5.45M
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbs( ctxOff ) );
2616
5.45M
        remAbsLevel >>= 1;
2617
2618
5.45M
        remRegBins--;
2619
5.45M
        unsigned gt2 = !!remAbsLevel;
2620
5.45M
        binCoder.encodeBin(gt2, cctx.greater2CtxIdAbs(ctxOff));
2621
5.45M
        DTRACE(g_trace_ctx, D_SYNTAX_RESI, "gt2_flag() bin=%d ctx=%d\n", gt2, cctx.greater2CtxIdAbs(ctxOff));
2622
5.45M
        remRegBins--;
2623
5.45M
      }
2624
2625
6.30M
      cctx.absVal1stPass( nextSigPos, std::min<TCoeff>( 4 + ( absLevel & 1 ), absLevel ) );
2626
6.30M
    }
2627
2628
6.83M
    state = ( stateTransTable >> ((state<<2)+((Coeff&1)<<1)) ) & 3;
2629
6.83M
  }
2630
859k
  firstPosMode2 = nextSigPos;
2631
859k
  cctx.remRegBins = remRegBins;
2632
2633
2634
  //===== 2nd PASS: Go-rice codes =====
2635
7.69M
  for( int scanPos = firstSigPos; scanPos > firstPosMode2; scanPos-- )
2636
6.83M
  {
2637
6.83M
    unsigned absLevel = abs( coeff[cctx.blockPos( scanPos )] );
2638
2639
6.83M
    if( absLevel >= 4 )
2640
4.34M
    {
2641
4.34M
      int      sumAll   = cctx.templateAbsSum( scanPos, coeff, 4 );
2642
4.34M
      unsigned ricePar  = g_auiGoRiceParsCoeff[sumAll];
2643
4.34M
      unsigned rem      = ( absLevel - 4 ) >> 1;
2644
4.34M
      binCoder.encodeRemAbsEP( rem, ricePar, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2645
4.34M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, ricePar );
2646
4.34M
    }
2647
6.83M
  }
2648
2649
  //===== coeff bypass ====
2650
962k
  for( int scanPos = firstPosMode2; scanPos >= minSubPos; scanPos-- )
2651
102k
  {
2652
102k
    TCoeff    Coeff     = coeff[ cctx.blockPos( scanPos ) ];
2653
102k
    unsigned  absLevel  = abs( Coeff );
2654
102k
    int       sumAll    = cctx.templateAbsSum(scanPos, coeff, 0);
2655
102k
    int       rice      = g_auiGoRiceParsCoeff[sumAll];
2656
102k
    int       pos0      = g_auiGoRicePosCoeff0(state, rice);
2657
102k
    unsigned  rem       = ( absLevel == 0 ? pos0 : absLevel <= pos0 ? absLevel-1 : absLevel );
2658
102k
    binCoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2659
102k
    DTRACE( g_trace_ctx, D_SYNTAX_RESI, "rem_val() bin=%d ctx=%d\n", rem, rice );
2660
102k
    state = ( stateTransTable >> ((state<<2)+((absLevel&1)<<1)) ) & 3;
2661
102k
    if( absLevel )
2662
102k
    {
2663
102k
      numNonZero++;
2664
102k
      firstNZPos = scanPos;
2665
102k
      lastNZPos   = std::max<int>( lastNZPos, scanPos );
2666
102k
      signPattern <<= 1;
2667
102k
      if( Coeff < 0 ) signPattern++;
2668
102k
    }
2669
102k
  }
2670
2671
  //===== encode sign's =====
2672
859k
  unsigned numSigns = numNonZero;
2673
859k
  if( cctx.hideSign( firstNZPos, lastNZPos ) )
2674
0
  {
2675
0
    numSigns    --;
2676
0
    signPattern >>= 1;
2677
0
  }
2678
859k
  binCoder.encodeBinsEP( signPattern, numSigns );
2679
859k
}
2680
}   // namespace
2681
2682
void CABACWriter::residual_coding_subblock( CoeffCodingContext& cctx, const TCoeffSig* coeff, const int stateTransTable, int& state )
2683
869k
{
2684
869k
  if( m_BinEncoder.isEncoding() )
2685
2.52k
  {
2686
2.52k
    residual_coding_subblock_bins( cctx, coeff, stateTransTable, state, m_BinEncoder );
2687
2.52k
  }
2688
867k
  else
2689
867k
  {
2690
    // only estimating bits (m_BinEncoder is a BitEstimator): sum the subblock's bits locally, add them once
2691
867k
    LocalBitEstimate estimate( static_cast<CtxStore&>( m_BinEncoder.getCtx() ) );
2692
867k
    residual_coding_subblock_bins( cctx, coeff, stateTransTable, state, estimate );
2693
867k
    static_cast<BitEstimatorBase&>( m_BinEncoder ).addEstFracBits( estimate.fracBits() );
2694
867k
  }
2695
869k
}
2696
2697
2698
void CABACWriter::residual_codingTS( const TransformUnit& tu, ComponentID compID )
2699
63.9k
{
2700
63.9k
  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 );
2701
2702
  // init coeff coding context
2703
63.9k
  CoeffCodingContext  cctx    ( tu, compID, false, tu.cu->bdpcmM[toChannelType(compID)] );
2704
63.9k
  const TCoeffSig*    coeff   = tu.getCoeffs( compID ).buf;
2705
63.9k
  int maxCtxBins = (cctx.maxNumCoeff() * 7) >> 2;
2706
63.9k
  cctx.remRegBins = maxCtxBins;
2707
2708
  // determine and set last coeff position and sig group flags
2709
63.9k
  std::bitset<MLS_GRP_NUM> sigGroupFlags;
2710
5.85M
  for( int scanPos = 0; scanPos < cctx.maxNumCoeff(); scanPos++)
2711
5.79M
  {
2712
5.79M
    unsigned blkPos = cctx.blockPos( scanPos );
2713
5.79M
    if( coeff[blkPos] )
2714
627k
    {
2715
627k
      sigGroupFlags.set( scanPos >> cctx.log2CGSize() );
2716
627k
    }
2717
5.79M
  }
2718
2719
  // code subblocks
2720
426k
  for( int subSetId = 0; subSetId <= ( cctx.maxNumCoeff() - 1 ) >> cctx.log2CGSize(); subSetId++ )
2721
362k
  {
2722
362k
    cctx.initSubblock         ( subSetId, sigGroupFlags[subSetId] );
2723
362k
    residual_coding_subblockTS( cctx, coeff );
2724
362k
  }
2725
63.9k
}
2726
2727
2728
void CABACWriter::residual_coding_subblockTS( CoeffCodingContext& cctx, const TCoeffSig* coeff )
2729
362k
{
2730
  //===== init =====
2731
362k
  const int   minSubPos   = cctx.maxSubPos();
2732
362k
  int         firstSigPos = cctx.minSubPos();
2733
362k
  int         nextSigPos  = firstSigPos;
2734
2735
  //===== encode significant_coeffgroup_flag =====
2736
362k
  if( !cctx.isLastSubSet() || !cctx.only1stSigGroup() )
2737
352k
  {
2738
352k
    if( cctx.isSigGroup() )
2739
137k
    {
2740
137k
        m_BinEncoder.encodeBin( 1, cctx.sigGroupCtxId( true ) );
2741
137k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 1, cctx.sigGroupCtxId() );
2742
137k
    }
2743
214k
    else
2744
214k
    {
2745
214k
        m_BinEncoder.encodeBin( 0, cctx.sigGroupCtxId( true ) );
2746
214k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sigGroup() bin=%d ctx=%d\n", 0, cctx.sigGroupCtxId() );
2747
214k
      return;
2748
214k
    }
2749
352k
  }
2750
2751
  //===== encode absolute values =====
2752
147k
  const int inferSigPos   = minSubPos;
2753
147k
  int       remAbsLevel   = -1;
2754
147k
  int       numNonZero    =  0;
2755
2756
147k
  int rightPixel, belowPixel, modAbsCoeff;
2757
2758
147k
  int lastScanPosPass1 = -1;
2759
147k
  int lastScanPosPass2 = -1;
2760
2.30M
  for (; nextSigPos <= minSubPos && cctx.remRegBins >= 4; nextSigPos++)
2761
2.15M
  {
2762
2.15M
    TCoeff    Coeff      = coeff[ cctx.blockPos( nextSigPos ) ];
2763
2.15M
    unsigned  sigFlag    = ( Coeff != 0 );
2764
2.15M
    if( numNonZero || nextSigPos != inferSigPos )
2765
2.15M
    {
2766
2.15M
      const unsigned sigCtxId = cctx.sigCtxIdAbsTS( nextSigPos, coeff );
2767
2.15M
      m_BinEncoder.encodeBin( sigFlag, sigCtxId );
2768
2.15M
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_sig_bin() bin=%d ctx=%d\n", sigFlag, sigCtxId );
2769
2.15M
      cctx.remRegBins--;
2770
2.15M
    }
2771
2772
2.15M
    if( sigFlag )
2773
580k
    {
2774
      //===== encode sign's =====
2775
580k
      int sign = Coeff < 0;
2776
580k
      const unsigned signCtxId = cctx.signCtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm());
2777
580k
      m_BinEncoder.encodeBin(sign, signCtxId);
2778
580k
      cctx.remRegBins--;
2779
580k
      numNonZero++;
2780
580k
      cctx.neighTS(rightPixel, belowPixel, nextSigPos, coeff);
2781
580k
      modAbsCoeff = cctx.deriveModCoeff(rightPixel, belowPixel, abs(Coeff), cctx.bdpcm());
2782
580k
      remAbsLevel = modAbsCoeff - 1;
2783
2784
580k
      unsigned gt1 = !!remAbsLevel;
2785
580k
      const unsigned gt1CtxId = cctx.lrg1CtxIdAbsTS(nextSigPos, coeff, cctx.bdpcm());
2786
580k
      m_BinEncoder.encodeBin(gt1, gt1CtxId);
2787
580k
      DTRACE(g_trace_ctx, D_SYNTAX_RESI, "ts_gt1_flag() bin=%d ctx=%d\n", gt1, gt1CtxId);
2788
580k
      cctx.remRegBins--;
2789
2790
580k
      if( gt1 )
2791
569k
      {
2792
569k
        remAbsLevel  -= 1;
2793
569k
        m_BinEncoder.encodeBin( remAbsLevel&1, cctx.parityCtxIdAbsTS() );
2794
569k
        DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_par_flag() bin=%d ctx=%d\n", remAbsLevel&1, cctx.parityCtxIdAbsTS() );
2795
569k
        cctx.remRegBins--;
2796
569k
      }
2797
580k
    }
2798
2.15M
    lastScanPosPass1 = nextSigPos;
2799
2.15M
  }
2800
2801
147k
  int cutoffVal = 2;
2802
147k
  int numGtBins = 4;
2803
2804
2.11M
  for (int scanPos = firstSigPos; scanPos <= minSubPos && cctx.remRegBins >= 4; scanPos++)
2805
1.96M
  {
2806
1.96M
    unsigned absLevel;
2807
1.96M
    cctx.neighTS(rightPixel, belowPixel, scanPos, coeff);
2808
1.96M
    absLevel = cctx.deriveModCoeff(rightPixel, belowPixel, abs(coeff[cctx.blockPos(scanPos)]), cctx.bdpcm());
2809
1.96M
    cutoffVal = 2;
2810
9.82M
    for (int i = 0; i < numGtBins; i++)
2811
7.86M
    {
2812
7.86M
      if (absLevel >= cutoffVal)
2813
1.37M
      {
2814
1.37M
        unsigned gt2 = (absLevel >= (cutoffVal + 2));
2815
1.37M
        m_BinEncoder.encodeBin(gt2, cctx.greaterXCtxIdAbsTS(cutoffVal >> 1));
2816
1.37M
        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));
2817
1.37M
        cctx.remRegBins--;
2818
1.37M
      }
2819
7.86M
      cutoffVal += 2;
2820
7.86M
    }
2821
1.96M
    lastScanPosPass2 = scanPos;
2822
1.96M
  }
2823
2824
  //===== coeff bypass ====
2825
2.50M
  for( int scanPos = firstSigPos; scanPos <= minSubPos; scanPos++ )
2826
2.35M
  {
2827
2.35M
    unsigned absLevel;
2828
2.35M
    cctx.neighTS(rightPixel, belowPixel, scanPos, coeff);
2829
2.35M
    cutoffVal = (scanPos <= lastScanPosPass2 ? 10 : (scanPos <= lastScanPosPass1 ? 2 : 0));
2830
2.35M
    absLevel = cctx.deriveModCoeff(rightPixel, belowPixel, abs(coeff[cctx.blockPos(scanPos)]), cctx.bdpcm()||!cutoffVal);
2831
2.35M
    if( absLevel >= cutoffVal )
2832
507k
    {
2833
      //int       rice = cctx.templateAbsSumTS( scanPos, coeff );
2834
507k
      int       rice = 1;
2835
507k
      unsigned  rem = scanPos <= lastScanPosPass1 ? (absLevel - cutoffVal) >> 1 : absLevel;
2836
507k
      m_BinEncoder.encodeRemAbsEP( rem, rice, COEF_REMAIN_BIN_REDUCTION, cctx.maxLog2TrDRange() );
2837
507k
      DTRACE( g_trace_ctx, D_SYNTAX_RESI, "ts_rem_val() bin=%d ctx=%d sp=%d\n", rem, rice, scanPos );
2838
2839
507k
      if (absLevel && scanPos > lastScanPosPass1)
2840
46.6k
      {
2841
46.6k
        int sign = coeff[cctx.blockPos(scanPos)] < 0;
2842
46.6k
        m_BinEncoder.encodeBinEP(sign);
2843
46.6k
      }
2844
507k
    }
2845
2.35M
  }
2846
147k
}
2847
2848
2849
//================================================================================
2850
//  helper functions
2851
//--------------------------------------------------------------------------------
2852
//    void  unary_max_symbol  ( symbol, ctxId0, ctxIdN, maxSymbol )
2853
//    void  unary_max_eqprob  ( symbol,                 maxSymbol )
2854
//    void  exp_golomb_eqprob ( symbol, count )
2855
//================================================================================
2856
2857
void CABACWriter::unary_max_symbol( unsigned symbol, unsigned ctxId0, unsigned ctxIdN, unsigned maxSymbol )
2858
3.48k
{
2859
3.48k
  CHECK( symbol > maxSymbol, "symbol > maxSymbol" );
2860
3.48k
  const unsigned totalBinsToWrite = std::min( symbol + 1, maxSymbol );
2861
6.97k
  for( unsigned binsWritten = 0; binsWritten < totalBinsToWrite; ++binsWritten )
2862
3.48k
  {
2863
3.48k
    const unsigned nextBin = symbol > binsWritten;
2864
3.48k
    m_BinEncoder.encodeBin( nextBin, binsWritten == 0 ? ctxId0 : ctxIdN );
2865
3.48k
  }
2866
3.48k
}
2867
2868
2869
void CABACWriter::unary_max_eqprob( unsigned symbol, unsigned maxSymbol )
2870
210k
{
2871
210k
  if( maxSymbol == 0 )
2872
0
  {
2873
0
    return;
2874
0
  }
2875
210k
  bool     codeLast = ( maxSymbol > symbol );
2876
210k
  unsigned bins     = 0;
2877
210k
  unsigned numBins  = 0;
2878
210k
  while( symbol-- )
2879
339
  {
2880
339
    bins   <<= 1;
2881
339
    bins   ++;
2882
339
    numBins++;
2883
339
  }
2884
210k
  if( codeLast )
2885
210k
  {
2886
210k
    bins  <<= 1;
2887
210k
    numBins++;
2888
210k
  }
2889
210k
  CHECK(!( numBins <= 32 ), "Unspecified error");
2890
210k
  m_BinEncoder.encodeBinsEP( bins, numBins );
2891
210k
}
2892
2893
2894
void CABACWriter::exp_golomb_eqprob( unsigned symbol, unsigned count )
2895
0
{
2896
0
  unsigned bins    = 0;
2897
0
  unsigned numBins = 0;
2898
0
  while( symbol >= (unsigned)(1<<count) )
2899
0
  {
2900
0
    bins <<= 1;
2901
0
    bins++;
2902
0
    numBins++;
2903
0
    symbol -= 1 << count;
2904
0
    count++;
2905
0
  }
2906
0
  bins <<= 1;
2907
0
  numBins++;
2908
0
  bins = (bins << count) | symbol;
2909
0
  numBins += count;
2910
0
  CHECK(!( numBins <= 32 ), "Unspecified error");
2911
0
  m_BinEncoder.encodeBinsEP( bins, numBins );
2912
0
}
2913
2914
2915
void CABACWriter::codeAlfCtuEnabled( CodingStructure& cs, ChannelType channel, AlfParam* alfParam, const int numCtus )
2916
14.0k
{
2917
14.0k
  if( isLuma( channel ) )
2918
2.31k
  {
2919
2.31k
    if (alfParam->alfEnabled[COMP_Y])
2920
2.31k
      codeAlfCtuEnabled( cs, COMP_Y, alfParam, numCtus );
2921
2.31k
  }
2922
11.7k
  else
2923
11.7k
  {
2924
11.7k
    if (alfParam->alfEnabled[COMP_Cb])
2925
11.7k
      codeAlfCtuEnabled( cs, COMP_Cb, alfParam, numCtus );
2926
11.7k
    if (alfParam->alfEnabled[COMP_Cr])
2927
11.7k
      codeAlfCtuEnabled( cs, COMP_Cr, alfParam, numCtus );
2928
11.7k
  }
2929
14.0k
}
2930
2931
2932
void CABACWriter::codeAlfCtuEnabled( CodingStructure& cs, ComponentID compID, AlfParam* alfParam, const int numCtus )
2933
25.7k
{
2934
123k
  for( int ctuIdx = 0; ctuIdx < numCtus; ctuIdx++ )
2935
97.4k
  {
2936
97.4k
    codeAlfCtuEnabledFlag( cs, ctuIdx, compID );
2937
97.4k
  }
2938
25.7k
}
2939
2940
2941
void CABACWriter::codeAlfCtuEnabledFlag( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx)
2942
352k
{
2943
352k
  CHECKD( !cs.sps->alfEnabled, "ALF is disabled in SPS" ); 
2944
2945
352k
  const PreCalcValues& pcv = *cs.pcv;
2946
352k
  int                 frame_width_in_ctus = pcv.widthInCtus;
2947
352k
  int                 ry = ctuRsAddr / frame_width_in_ctus;
2948
352k
  int                 rx = ctuRsAddr - ry * frame_width_in_ctus;
2949
352k
  const Position      pos( rx * cs.pcv->maxCUSize, ry * cs.pcv->maxCUSize );
2950
352k
  const uint32_t      curSliceIdx = cs.slice->independentSliceIdx;
2951
352k
  const uint32_t      curTileIdx  = cs.pps->getTileIdx( pos );
2952
352k
  bool                leftAvail   = cs.getCURestricted( pos.offset( -(int)pcv.maxCUSize, 0 ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2953
352k
  bool                aboveAvail  = cs.getCURestricted( pos.offset( 0, -(int)pcv.maxCUSize ), pos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2954
2955
352k
  int leftCTUAddr = leftAvail ? ctuRsAddr - 1 : -1;
2956
352k
  int aboveCTUAddr = aboveAvail ? ctuRsAddr - frame_width_in_ctus : -1;
2957
2958
352k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compIdx ].data();
2959
352k
  int ctx = 0;
2960
352k
  ctx += leftCTUAddr > -1 ? ( ctbAlfFlag[leftCTUAddr] ? 1 : 0 ) : 0;
2961
352k
  ctx += aboveCTUAddr > -1 ? ( ctbAlfFlag[aboveCTUAddr] ? 1 : 0 ) : 0;
2962
352k
  m_BinEncoder.encodeBin( ctbAlfFlag[ctuRsAddr], Ctx::ctbAlfFlag( compIdx * 3 + ctx ) );
2963
352k
}
2964
2965
2966
void CABACWriter::codeCcAlfFilterControlIdc(uint8_t idcVal, CodingStructure &cs, const ComponentID compID,
2967
                                            const int curIdx, const uint8_t *filterControlIdc, Position lumaPos,
2968
                                            const int filterCount)
2969
0
{
2970
0
  CHECK(idcVal > filterCount, "Filter index is too large");
2971
2972
0
  const uint32_t curSliceIdx    = cs.slice->independentSliceIdx;
2973
0
  const uint32_t curTileIdx     = cs.pps->getTileIdx( lumaPos );
2974
0
  Position       leftLumaPos    = lumaPos.offset(-(int)cs.pcv->maxCUSize, 0);
2975
0
  Position       aboveLumaPos   = lumaPos.offset(0, -(int)cs.pcv->maxCUSize);
2976
0
  bool           leftAvail      = cs.getCURestricted( leftLumaPos,  lumaPos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2977
0
  bool           aboveAvail     = cs.getCURestricted( aboveLumaPos, lumaPos, curSliceIdx, curTileIdx, CH_L, TREE_D ) ? true : false;
2978
0
  int            ctxt           = 0;
2979
2980
0
  if (leftAvail)
2981
0
  {
2982
0
    ctxt += ( filterControlIdc[curIdx - 1]) ? 1 : 0;
2983
0
  }
2984
0
  if (aboveAvail)
2985
0
  {
2986
0
    ctxt += (filterControlIdc[curIdx - cs.pcv->widthInCtus]) ? 1 : 0;
2987
0
  }
2988
0
  ctxt += ( compID == COMP_Cr ) ? 3 : 0;
2989
2990
0
  m_BinEncoder.encodeBin( ( idcVal == 0 ) ? 0 : 1, Ctx::CcAlfFilterControlFlag( ctxt ) ); // ON/OFF flag is context coded
2991
0
  if ( idcVal > 0 )
2992
0
  {
2993
0
    int val = (idcVal - 1);
2994
0
    while ( val )
2995
0
    {
2996
0
      m_BinEncoder.encodeBinEP( 1 );
2997
0
      val--;
2998
0
    }
2999
0
    if ( idcVal < filterCount )
3000
0
    {
3001
0
      m_BinEncoder.encodeBinEP( 0 );
3002
0
    }
3003
0
  }
3004
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 );
3005
0
}
3006
3007
3008
void CABACWriter::mip_flag( const CodingUnit& cu )
3009
1.11M
{
3010
1.11M
  if( !cu.Y().valid() )
3011
0
  {
3012
0
    return;
3013
0
  }
3014
1.11M
  if( !cu.cs->sps->MIP )
3015
0
  {
3016
0
    return;
3017
0
  }
3018
3019
1.11M
  unsigned ctxId = DeriveCtx::CtxMipFlag( cu );
3020
1.11M
  m_BinEncoder.encodeBin( cu.mipFlag, Ctx::MipFlag( ctxId ) );
3021
1.11M
  DTRACE( g_trace_ctx, D_SYNTAX, "mip_flag() pos=(%d,%d) mode=%d\n", cu.lumaPos().x, cu.lumaPos().y, cu.mipFlag ? 1 : 0 );
3022
1.11M
}
3023
3024
3025
void CABACWriter::mip_pred_modes( const CodingUnit& cu )
3026
1.60k
{
3027
1.60k
  if( !cu.Y().valid() )
3028
0
  {
3029
0
    return;
3030
0
  }
3031
3032
1.60k
  mip_pred_mode( cu );
3033
1.60k
}
3034
3035
3036
void CABACWriter::mip_pred_mode( const CodingUnit& cu )
3037
263k
{
3038
263k
  m_BinEncoder.encodeBinEP( (cu.mipTransposedFlag ? 1 : 0) );
3039
3040
263k
  const int numModes = getNumModesMip( cu.Y() );
3041
263k
  CHECKD( cu.intraDir[CH_L] < 0 || cu.intraDir[CH_L] >= numModes, "Invalid MIP mode" );
3042
263k
  xWriteTruncBinCode( cu.intraDir[CH_L], numModes );
3043
3044
263k
  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 );
3045
263k
}
3046
3047
3048
void CABACWriter::codeAlfCtuFilterIndex(CodingStructure& cs, uint32_t ctuRsAddr)
3049
70.0k
{
3050
70.0k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ COMP_Y ].data();
3051
70.0k
  if (!ctbAlfFlag[ctuRsAddr])
3052
0
  {
3053
0
    return;
3054
0
  }
3055
3056
70.0k
  const short* alfCtbFilterIndex = cs.slice->pic->m_alfCtbFilterIndex.data();
3057
70.0k
  const unsigned filterSetIdx = alfCtbFilterIndex[ctuRsAddr];
3058
70.0k
  unsigned numAps = cs.slice->numAps;
3059
70.0k
  unsigned numAvailableFiltSets = numAps + NUM_FIXED_FILTER_SETS;
3060
70.0k
  if (numAvailableFiltSets > NUM_FIXED_FILTER_SETS)
3061
14.0k
  {
3062
14.0k
    int useTemporalFilt = (filterSetIdx >= NUM_FIXED_FILTER_SETS) ? 1 : 0;
3063
14.0k
    m_BinEncoder.encodeBin(useTemporalFilt, Ctx::AlfUseTemporalFilt());
3064
14.0k
    if (useTemporalFilt)
3065
14.0k
    {
3066
14.0k
      CHECK((filterSetIdx - NUM_FIXED_FILTER_SETS) >= (numAvailableFiltSets - NUM_FIXED_FILTER_SETS), "temporal non-latest set");
3067
14.0k
      if (numAps > 1)
3068
0
      {
3069
0
        xWriteTruncBinCode(filterSetIdx - NUM_FIXED_FILTER_SETS, numAvailableFiltSets - NUM_FIXED_FILTER_SETS);
3070
0
      }
3071
14.0k
    }
3072
0
    else
3073
0
    {
3074
0
      CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set larger than temporal");
3075
0
      xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS);
3076
0
    }
3077
14.0k
  }
3078
56.0k
  else
3079
56.0k
  {
3080
56.0k
    CHECK(filterSetIdx >= NUM_FIXED_FILTER_SETS, "fixed set numavail < num_fixed");
3081
56.0k
    xWriteTruncBinCode(filterSetIdx, NUM_FIXED_FILTER_SETS);
3082
56.0k
  }
3083
70.0k
}
3084
3085
3086
void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ChannelType channel, AlfParam* alfParam, const int numCtus )
3087
14.0k
{
3088
14.0k
  if( isChroma( channel ) )
3089
11.7k
  {
3090
11.7k
    if (alfParam->alfEnabled[COMP_Cb])
3091
11.7k
      codeAlfCtuAlternatives( cs, COMP_Cb, alfParam, numCtus );
3092
11.7k
    if (alfParam->alfEnabled[COMP_Cr])
3093
11.7k
      codeAlfCtuAlternatives( cs, COMP_Cr, alfParam, numCtus );
3094
11.7k
  }
3095
14.0k
}
3096
3097
3098
void CABACWriter::codeAlfCtuAlternatives( CodingStructure& cs, ComponentID compID, AlfParam* alfParam, const int numCtus)
3099
23.4k
{
3100
23.4k
  if( compID == COMP_Y )
3101
0
    return;
3102
23.4k
  const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compID ].data();
3103
3104
113k
  for( int ctuIdx = 0; ctuIdx < numCtus; ctuIdx++ )
3105
90.4k
  {
3106
90.4k
    if( ctbAlfFlag[ctuIdx] )
3107
90.4k
    {
3108
90.4k
      codeAlfCtuAlternative( cs, ctuIdx, compID, alfParam );
3109
90.4k
    }
3110
90.4k
  }
3111
23.4k
}
3112
3113
3114
void CABACWriter::codeAlfCtuAlternative( CodingStructure& cs, uint32_t ctuRsAddr, const int compIdx, const AlfParam* alfParam)
3115
458k
{
3116
458k
  if( compIdx == COMP_Y )
3117
0
    return;
3118
3119
458k
  {
3120
458k
    const uint8_t* ctbAlfFlag = cs.slice->pic->m_alfCtuEnabled[ compIdx ].data();
3121
3122
458k
    if( ctbAlfFlag[ctuRsAddr] )
3123
458k
    {
3124
458k
      const int numAlts = alfParam->numAlternativesChroma;
3125
458k
      const uint8_t* ctbAlfAlternative = cs.slice->pic->m_alfCtuAlternative[compIdx].data();
3126
458k
      unsigned numOnes = ctbAlfAlternative[ctuRsAddr];
3127
458k
      assert( ctbAlfAlternative[ctuRsAddr] < numAlts );
3128
1.30M
      for( int i = 0; i < numOnes; ++i )
3129
845k
        m_BinEncoder.encodeBin( 1, Ctx::ctbAlfAlternative( compIdx-1 ) );
3130
458k
      if( numOnes < numAlts-1 )
3131
345k
        m_BinEncoder.encodeBin( 0, Ctx::ctbAlfAlternative( compIdx-1 ) );
3132
458k
    }
3133
458k
  }
3134
458k
}
3135
3136
} // namespace vvenc
3137
3138
//! \}
3139