Coverage Report

Created: 2026-04-01 07:49

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