Coverage Report

Created: 2026-09-02 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/vvenc/source/Lib/CommonLib/DepQuant.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
#include "DepQuant.h"
44
#include "TrQuant.h"
45
#include "CodingStructure.h"
46
#include "UnitTools.h"
47
48
#include <bitset>
49
50
//! \ingroup CommonLib
51
//! \{
52
53
namespace vvenc {
54
55
56
namespace DQIntern
57
{
58
  static void findFirstPos( int& firstTestPos, const TCoeff* tCoeff, const DQIntern::TUParameters& tuPars, int defaultTh,
59
                            bool zeroOutForThres, int zeroOutWidth, int zeroOutHeight )
60
1.78M
  {
61
200M
    for( ; firstTestPos >= 0; firstTestPos-- )
62
199M
    {
63
199M
      if( zeroOutForThres && ( tuPars.m_scanId2BlkPos[firstTestPos].x >= zeroOutWidth ||
64
24.8M
                              tuPars.m_scanId2BlkPos[firstTestPos].y >= zeroOutHeight ) )
65
0
      {
66
0
        continue;
67
0
      }
68
199M
      if( abs( tCoeff[tuPars.m_scanId2BlkPos[firstTestPos].idx] ) > defaultTh )
69
745k
      {
70
745k
        break;
71
745k
      }
72
199M
    }
73
1.78M
  }
74
75
  void Rom::xInitScanArrays()
76
18.3k
  {
77
18.3k
    if( m_scansInitialized )
78
0
    {
79
0
      return;
80
0
    }
81
18.3k
    ::memset( m_scanId2NbInfoSbbArray, 0, sizeof(m_scanId2NbInfoSbbArray) );
82
18.3k
    ::memset( m_scanId2NbInfoOutArray, 0, sizeof(m_scanId2NbInfoOutArray) );
83
18.3k
    ::memset( m_tuParameters,          0, sizeof(m_tuParameters) );
84
85
18.3k
    uint32_t raster2id[ MAX_CU_SIZE * MAX_CU_SIZE ];
86
18.3k
    ::memset(raster2id, 0, sizeof(raster2id));
87
88
146k
    for( int hd = 0; hd < MAX_TU_SIZE_IDX; hd++ )
89
128k
    {
90
1.02M
      for( int vd = 0; vd < MAX_TU_SIZE_IDX; vd++ )
91
899k
      {
92
899k
        if( (hd == 0 && vd <= 1) || (hd <= 1 && vd == 0) )
93
55.0k
        {
94
55.0k
          continue;
95
55.0k
        }
96
844k
        const uint32_t      blockWidth    = (1 << hd);
97
844k
        const uint32_t      blockHeight   = (1 << vd);
98
844k
        const uint32_t      log2CGWidth   = g_log2SbbSize[hd][vd][0];
99
844k
        const uint32_t      log2CGHeight  = g_log2SbbSize[hd][vd][1];
100
844k
        const uint32_t      groupWidth    = 1 << log2CGWidth;
101
844k
        const uint32_t      groupHeight   = 1 << log2CGHeight;
102
844k
        const uint32_t      groupSize     = groupWidth * groupHeight;
103
844k
        const SizeType      blkWidthIdx   = Log2( blockWidth );
104
844k
        const SizeType      blkHeightIdx  = Log2( blockHeight );
105
844k
        const ScanElement * scanId2RP     = getScanOrder( SCAN_GROUPED_4x4, blkWidthIdx, blkHeightIdx );
106
844k
        NbInfoSbb*&         sId2NbSbb     = m_scanId2NbInfoSbbArray[hd][vd];
107
844k
        NbInfoOut*&         sId2NbOut     = m_scanId2NbInfoOutArray[hd][vd];
108
        // consider only non-zero-out region
109
844k
        const uint32_t      blkWidthNZOut = std::min<unsigned>( JVET_C0024_ZERO_OUT_TH, blockWidth  );
110
844k
        const uint32_t      blkHeightNZOut= std::min<unsigned>( JVET_C0024_ZERO_OUT_TH, blockHeight );
111
844k
        const uint32_t      totalValues   = blkWidthNZOut * blkHeightNZOut;
112
113
844k
        sId2NbSbb = new NbInfoSbb[ totalValues ];
114
844k
        sId2NbOut = new NbInfoOut[ totalValues ];
115
116
166M
        for( uint32_t scanId = 0; scanId < totalValues; scanId++ )
117
165M
        {
118
165M
          raster2id[scanId2RP[scanId].idx] = scanId;
119
165M
          sId2NbSbb[scanId].numInv = 0;
120
165M
        }
121
122
166M
        for( unsigned scanId = 0; scanId < totalValues; scanId++ )
123
165M
        {
124
165M
          const int posX = scanId2RP[scanId].x;
125
165M
          const int posY = scanId2RP[scanId].y;
126
165M
          const int rpos = scanId2RP[scanId].idx;
127
165M
          {
128
            //===== inside subband neighbours =====
129
165M
            const int      begSbb = scanId - ( scanId & (groupSize-1) ); // first pos in current subblock
130
165M
            int            cpos[5];
131
132
165M
            cpos[0] = ( posX + 1 < blkWidthNZOut                              ? ( raster2id[rpos+1           ] < groupSize + begSbb ? raster2id[rpos+1           ] - begSbb : 0 ) : 0 );
133
165M
            cpos[1] = ( posX + 2 < blkWidthNZOut                              ? ( raster2id[rpos+2           ] < groupSize + begSbb ? raster2id[rpos+2           ] - begSbb : 0 ) : 0 );
134
165M
            cpos[2] = ( posX + 1 < blkWidthNZOut && posY + 1 < blkHeightNZOut ? ( raster2id[rpos+1+blockWidth] < groupSize + begSbb ? raster2id[rpos+1+blockWidth] - begSbb : 0 ) : 0 );
135
165M
            cpos[3] = ( posY + 1 < blkHeightNZOut                             ? ( raster2id[rpos+  blockWidth] < groupSize + begSbb ? raster2id[rpos+  blockWidth] - begSbb : 0 ) : 0 );
136
165M
            cpos[4] = ( posY + 2 < blkHeightNZOut                             ? ( raster2id[rpos+2*blockWidth] < groupSize + begSbb ? raster2id[rpos+2*blockWidth] - begSbb : 0 ) : 0 );
137
138
165M
            int num = 0;
139
165M
            int inPos[5] = { 0, };
140
141
664M
            while( true )
142
664M
            {
143
664M
              int nk = -1;
144
3.98G
              for( int k = 0; k < 5; k++ )
145
3.32G
              {
146
3.32G
                if( cpos[k] != 0 && ( nk < 0 || cpos[k] < cpos[nk] ) )
147
746M
                {
148
746M
                  nk = k;
149
746M
                }
150
3.32G
              }
151
664M
              if( nk < 0 )
152
165M
              {
153
165M
                break;
154
165M
              }
155
498M
              inPos[ num++ ] = uint8_t( cpos[nk] );
156
498M
              cpos[nk] = 0;
157
498M
            }
158
494M
            for( int k = num; k < 5; k++ )
159
328M
            {
160
328M
              inPos[k] = 0;
161
328M
            }
162
664M
            for( int k = 0; k < num; k++ )
163
498M
            {
164
498M
              CHECK( sId2NbSbb[begSbb + inPos[k]].numInv >= 5, "" );
165
498M
              sId2NbSbb[begSbb + inPos[k]].invInPos[sId2NbSbb[begSbb + inPos[k]].numInv++] = scanId & ( groupSize - 1 );
166
498M
            }
167
165M
          }
168
165M
          {
169
            //===== outside subband neighbours =====
170
165M
            NbInfoOut&     nbOut  = sId2NbOut[ scanId ];
171
165M
            const int      begSbb = scanId - ( scanId & (groupSize-1) ); // first pos in current subblock
172
165M
            int            cpos[5];
173
174
165M
            cpos[0] = ( posX + 1 < blkWidthNZOut                              ? ( raster2id[rpos+1           ] >= groupSize + begSbb ? raster2id[rpos+1           ] : 0 ) : 0 );
175
165M
            cpos[1] = ( posX + 2 < blkWidthNZOut                              ? ( raster2id[rpos+2           ] >= groupSize + begSbb ? raster2id[rpos+2           ] : 0 ) : 0 );
176
165M
            cpos[2] = ( posX + 1 < blkWidthNZOut && posY + 1 < blkHeightNZOut ? ( raster2id[rpos+1+blockWidth] >= groupSize + begSbb ? raster2id[rpos+1+blockWidth] : 0 ) : 0 );
177
165M
            cpos[3] = ( posY + 1 < blkHeightNZOut                             ? ( raster2id[rpos+  blockWidth] >= groupSize + begSbb ? raster2id[rpos+  blockWidth] : 0 ) : 0 );
178
165M
            cpos[4] = ( posY + 2 < blkHeightNZOut                             ? ( raster2id[rpos+2*blockWidth] >= groupSize + begSbb ? raster2id[rpos+2*blockWidth] : 0 ) : 0 );
179
180
401M
            for( nbOut.num = 0; true; )
181
401M
            {
182
401M
              int nk = -1;
183
2.41G
              for( int k = 0; k < 5; k++ )
184
2.00G
              {
185
2.00G
                if( cpos[k] != 0 && ( nk < 0 || cpos[k] < cpos[nk] ) )
186
346M
                {
187
346M
                  nk = k;
188
346M
                }
189
2.00G
              }
190
401M
              if( nk < 0 )
191
165M
              {
192
165M
                break;
193
165M
              }
194
236M
              nbOut.outPos[ nbOut.num++ ] = uint16_t( cpos[nk] );
195
236M
              cpos[nk] = 0;
196
236M
            }
197
757M
            for( int k = nbOut.num; k < 5; k++ )
198
591M
            {
199
591M
              nbOut.outPos[k] = 0;
200
591M
            }
201
165M
            nbOut.maxDist = ( scanId == 0 ? 0 : sId2NbOut[scanId-1].maxDist );
202
401M
            for( int k = 0; k < nbOut.num; k++ )
203
236M
            {
204
236M
              if( nbOut.outPos[k] > nbOut.maxDist )
205
25.5M
              {
206
25.5M
                nbOut.maxDist = nbOut.outPos[k];
207
25.5M
              }
208
236M
            }
209
165M
          }
210
165M
        }
211
212
        // make it relative
213
166M
        for( unsigned scanId = 0; scanId < totalValues; scanId++ )
214
165M
        {
215
165M
          NbInfoOut& nbOut  = sId2NbOut[scanId];
216
165M
          const int  begSbb = scanId - ( scanId & (groupSize-1) ); // first pos in current subblock
217
401M
          for( int k = 0; k < nbOut.num; k++ )
218
236M
          {
219
236M
            CHECK(begSbb > nbOut.outPos[k], "Position must be past sub block begin");
220
236M
            nbOut.outPos[k] -= begSbb;
221
236M
          }
222
165M
          nbOut.maxDist -= scanId;
223
165M
        }
224
225
2.53M
        for( int chId = 0; chId < MAX_NUM_CH; chId++ )
226
1.68M
        {
227
1.68M
          m_tuParameters[hd][vd][chId] = new TUParameters( *this, blockWidth, blockHeight, ChannelType(chId) );
228
1.68M
        }
229
844k
      }
230
128k
    }
231
18.3k
    m_scansInitialized = true;
232
18.3k
  }
233
234
  void Rom::xUninitScanArrays()
235
18.3k
  {
236
18.3k
    if( !m_scansInitialized )
237
0
    {
238
0
      return;
239
0
    }
240
146k
    for( int hd = 0; hd < MAX_TU_SIZE_IDX; hd++ )
241
128k
    {
242
1.02M
      for( int vd = 0; vd < MAX_TU_SIZE_IDX; vd++ )
243
899k
      {
244
899k
        NbInfoSbb*& sId2NbSbb = m_scanId2NbInfoSbbArray[hd][vd];
245
899k
        NbInfoOut*& sId2NbOut = m_scanId2NbInfoOutArray[hd][vd];
246
899k
        if( sId2NbSbb )
247
844k
        {
248
844k
          delete [] sId2NbSbb;
249
844k
        }
250
899k
        if( sId2NbOut )
251
844k
        {
252
844k
          delete [] sId2NbOut;
253
844k
        }
254
2.69M
        for( int chId = 0; chId < MAX_NUM_CH; chId++ )
255
1.79M
        {
256
1.79M
          TUParameters*& tuPars = m_tuParameters[hd][vd][chId];
257
1.79M
          if( tuPars )
258
1.68M
          {
259
1.68M
            delete tuPars;
260
1.68M
          }
261
1.79M
        }
262
899k
      }
263
128k
    }
264
18.3k
    m_scansInitialized = false;
265
18.3k
  }
266
267
268
  TUParameters::TUParameters( const Rom& rom, const unsigned width, const unsigned height, const ChannelType chType )
269
1.68M
  {
270
1.68M
    m_chType              = chType;
271
1.68M
    m_width               = width;
272
1.68M
    m_height              = height;
273
1.68M
    const uint32_t nonzeroWidth  = std::min<uint32_t>(JVET_C0024_ZERO_OUT_TH, m_width);
274
1.68M
    const uint32_t nonzeroHeight = std::min<uint32_t>(JVET_C0024_ZERO_OUT_TH, m_height);
275
1.68M
    m_numCoeff                   = nonzeroWidth * nonzeroHeight;
276
1.68M
    m_log2SbbWidth        = g_log2SbbSize[ Log2(m_width) ][ Log2(m_height) ][0];
277
1.68M
    m_log2SbbHeight       = g_log2SbbSize[ Log2(m_width) ][ Log2(m_height) ][1];
278
1.68M
    m_log2SbbSize         = m_log2SbbWidth + m_log2SbbHeight;
279
1.68M
    m_sbbSize             = ( 1 << m_log2SbbSize );
280
1.68M
    m_sbbMask             = m_sbbSize - 1;
281
1.68M
    m_widthInSbb  = nonzeroWidth >> m_log2SbbWidth;
282
1.68M
    m_heightInSbb = nonzeroHeight >> m_log2SbbHeight;
283
1.68M
    m_numSbb              = m_widthInSbb * m_heightInSbb;
284
1.68M
    SizeType        hsbb  = Log2( m_widthInSbb  );
285
1.68M
    SizeType        vsbb  = Log2( m_heightInSbb );
286
1.68M
    SizeType        hsId  = Log2( m_width  );
287
1.68M
    SizeType        vsId  = Log2( m_height );
288
1.68M
    m_scanSbbId2SbbPos    = getScanOrder( SCAN_UNGROUPED   , hsbb , vsbb );
289
1.68M
    m_scanId2BlkPos       = getScanOrder( SCAN_GROUPED_4x4 , hsId , vsId );
290
1.68M
    int log2W             = Log2( m_width  );
291
1.68M
    int log2H             = Log2( m_height );
292
1.68M
    m_scanId2NbInfoSbb    = rom.getNbInfoSbb( log2W, log2H );
293
1.68M
    m_scanId2NbInfoOut    = rom.getNbInfoOut( log2W, log2H );
294
1.68M
    m_scanInfo            = new ScanInfo[ m_numCoeff ];
295
332M
    for( int scanIdx = 0; scanIdx < m_numCoeff; scanIdx++ )
296
331M
    {
297
331M
      xSetScanInfo( m_scanInfo[scanIdx], scanIdx );
298
331M
    }
299
1.68M
  }
300
301
302
  void TUParameters::xSetScanInfo( ScanInfo& scanInfo, int scanIdx )
303
331M
  {
304
331M
    scanInfo.sbbSize    = m_sbbSize;
305
331M
    scanInfo.numSbb     = m_numSbb;
306
331M
    scanInfo.scanIdx    = scanIdx;
307
331M
    scanInfo.rasterPos  = m_scanId2BlkPos[scanIdx].idx;
308
331M
    scanInfo.sbbPos     = m_scanSbbId2SbbPos[scanIdx >> m_log2SbbSize].idx;
309
331M
    scanInfo.insidePos  = scanIdx & m_sbbMask;
310
331M
    scanInfo.spt        = SCAN_ISCSBB;
311
331M
    if(  scanInfo.insidePos == m_sbbMask && scanIdx > scanInfo.sbbSize && scanIdx < m_numCoeff - 1 )
312
17.9M
      scanInfo.spt      = SCAN_SOCSBB;
313
313M
    else if( scanInfo.insidePos == 0 && scanIdx > 0 && scanIdx < m_numCoeff - m_sbbSize )
314
17.9M
      scanInfo.spt      = SCAN_EOCSBB;
315
331M
    scanInfo.posX = m_scanId2BlkPos[scanIdx].x;
316
331M
    scanInfo.posY = m_scanId2BlkPos[scanIdx].y;
317
331M
    if( scanIdx )
318
329M
    {
319
329M
      const int nextScanIdx = scanIdx - 1;
320
329M
      const int diag        = m_scanId2BlkPos[nextScanIdx].x + m_scanId2BlkPos[nextScanIdx].y;
321
329M
      if( m_chType == CH_L )
322
164M
      {
323
164M
        scanInfo.sigCtxOffsetNext = ( diag < 2 ? 8 : diag < 5 ?  4 : 0 );
324
164M
        scanInfo.gtxCtxOffsetNext = ( diag < 1 ? 16 : diag < 3 ? 11 : diag < 10 ? 6 : 1 );
325
164M
      }
326
164M
      else
327
164M
      {
328
164M
        scanInfo.sigCtxOffsetNext = ( diag < 2 ? 4 : 0 );
329
164M
        scanInfo.gtxCtxOffsetNext = ( diag < 1 ? 6 : 1 );
330
164M
      }
331
329M
      scanInfo.nextInsidePos      = nextScanIdx & m_sbbMask;
332
329M
      scanInfo.currNbInfoSbb      = m_scanId2NbInfoSbb[ scanIdx ];
333
329M
      if( scanInfo.insidePos == 0 )
334
19.2M
      {
335
19.2M
        const int nextSbbPos  = m_scanSbbId2SbbPos[nextScanIdx >> m_log2SbbSize].idx;
336
19.2M
        const int nextSbbPosY = nextSbbPos               / m_widthInSbb;
337
19.2M
        const int nextSbbPosX = nextSbbPos - nextSbbPosY * m_widthInSbb;
338
19.2M
        scanInfo.nextSbbRight = ( nextSbbPosX < m_widthInSbb  - 1 ? nextSbbPos + 1            : 0 );
339
19.2M
        scanInfo.nextSbbBelow = ( nextSbbPosY < m_heightInSbb - 1 ? nextSbbPos + m_widthInSbb : 0 );
340
19.2M
      }
341
329M
    }
342
331M
  }
343
344
  void RateEstimator::initCtx( const TUParameters& tuPars, const TransformUnit& tu, const ComponentID compID, const FracBitsAccess& fracBitsAccess )
345
745k
  {
346
745k
    m_scanId2Pos = tuPars.m_scanId2BlkPos;
347
745k
    xSetSigSbbFracBits  ( fracBitsAccess, tuPars.m_chType );
348
745k
    xSetSigFlagBits     ( fracBitsAccess, tuPars.m_chType );
349
745k
    xSetGtxFlagBits     ( fracBitsAccess, tuPars.m_chType );
350
745k
    xSetLastCoeffOffset ( fracBitsAccess, tuPars, tu, compID );
351
745k
  }
352
353
  void RateEstimator::xSetLastCoeffOffset( const FracBitsAccess& fracBitsAccess, const TUParameters& tuPars, const TransformUnit& tu, const ComponentID compID )
354
745k
  {
355
745k
    const ChannelType chType = ( compID == COMP_Y ? CH_L : CH_C );
356
745k
    int32_t cbfDeltaBits = 0;
357
745k
    if( compID == COMP_Y && !CU::isIntra(*tu.cu) && !tu.depth )
358
263
    {
359
263
      const BinFracBits bits  = fracBitsAccess.getFracBitsArray( Ctx::QtRootCbf() );
360
263
      cbfDeltaBits            = int32_t( bits.intBits[1] ) - int32_t( bits.intBits[0] );
361
263
    }
362
745k
    else
363
745k
    {
364
745k
      BinFracBits bits;
365
745k
      bool prevLumaCbf           = false;
366
745k
      bool lastCbfIsInferred     = false;
367
745k
      bool useIntraSubPartitions = tu.cu->ispMode && isLuma(chType);
368
745k
      if( useIntraSubPartitions )
369
10.6k
      {
370
10.6k
        bool rootCbfSoFar = false;
371
10.6k
        bool isLastSubPartition = CU::isISPLast(*tu.cu, tu.Y(), compID);
372
10.6k
        uint32_t nTus = tu.cu->ispMode == HOR_INTRA_SUBPARTITIONS ? tu.cu->lheight() >> Log2(tu.lheight()) : tu.cu->lwidth() >> Log2(tu.lwidth());
373
10.6k
        if( isLastSubPartition )
374
191
        {
375
191
          TransformUnit* tuPointer = tu.cu->firstTU;
376
764
          for( int tuIdx = 0; tuIdx < nTus - 1; tuIdx++ )
377
573
          {
378
573
            rootCbfSoFar |= TU::getCbfAtDepth(*tuPointer, COMP_Y, tu.depth);
379
573
            tuPointer     = tuPointer->next;
380
573
          }
381
191
          if( !rootCbfSoFar )
382
0
          {
383
0
            lastCbfIsInferred = true;
384
0
          }
385
191
        }
386
10.6k
        if( !lastCbfIsInferred )
387
10.6k
        {
388
10.6k
          prevLumaCbf = TU::getPrevTuCbfAtDepth(tu, compID, tu.depth);
389
10.6k
        }
390
10.6k
        bits = fracBitsAccess.getFracBitsArray(Ctx::QtCbf[compID](DeriveCtx::CtxQtCbf(compID, prevLumaCbf, true)));
391
10.6k
      }
392
734k
      else
393
734k
      {
394
734k
        bits = fracBitsAccess.getFracBitsArray(Ctx::QtCbf[compID](DeriveCtx::CtxQtCbf(compID, tu.cbf[COMP_Cb])));
395
734k
      }
396
745k
      cbfDeltaBits = lastCbfIsInferred ? 0 : int32_t(bits.intBits[1]) - int32_t(bits.intBits[0]);
397
745k
    }
398
399
745k
    static const unsigned prefixCtx[] = { 0, 0, 0, 3, 6, 10, 15, 21 };
400
745k
    uint32_t              ctxBits  [ LAST_SIGNIFICANT_GROUPS ];
401
2.23M
    for( unsigned xy = 0; xy < 2; xy++ )
402
1.49M
    {
403
1.49M
      int32_t             bitOffset   = ( xy ? cbfDeltaBits : 0 );
404
1.49M
      int32_t*            lastBits    = ( xy ? m_lastBitsY : m_lastBitsX );
405
1.49M
      const unsigned      size        = ( xy ? tuPars.m_height : tuPars.m_width );
406
1.49M
      const unsigned      log2Size    = Log2( size );
407
1.49M
      const bool          useYCtx     = ( xy != 0 );
408
1.49M
      const CtxSet&       ctxSetLast  = ( useYCtx ? Ctx::LastY : Ctx::LastX )[ chType ];
409
1.49M
      const unsigned      lastShift   = ( compID == COMP_Y ? (log2Size+1)>>2 : Clip3<unsigned>(0,2,size>>3) );
410
1.49M
      const unsigned      lastOffset  = ( compID == COMP_Y ? ( prefixCtx[log2Size] ) : 0 );
411
1.49M
      uint32_t            sumFBits    = 0;
412
1.49M
      unsigned            maxCtxId    = g_uiGroupIdx[std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, size) - 1];
413
9.99M
      for( unsigned ctxId = 0; ctxId < maxCtxId; ctxId++ )
414
8.50M
      {
415
8.50M
        const BinFracBits bits  = fracBitsAccess.getFracBitsArray( ctxSetLast( lastOffset + ( ctxId >> lastShift ) ) );
416
8.50M
        ctxBits[ ctxId ]        = sumFBits + bits.intBits[0] + ( ctxId>3 ? ((ctxId-2)>>1)<<SCALE_BITS : 0 ) + bitOffset;
417
8.50M
        sumFBits               +=            bits.intBits[1];
418
8.50M
      }
419
1.49M
      ctxBits  [ maxCtxId ]     = sumFBits + ( maxCtxId>3 ? ((maxCtxId-2)>>1)<<SCALE_BITS : 0 ) + bitOffset;
420
20.8M
      for (unsigned pos = 0; pos < std::min<unsigned>(JVET_C0024_ZERO_OUT_TH, size); pos++)
421
19.3M
      {
422
19.3M
        lastBits[ pos ]         = ctxBits[ g_uiGroupIdx[ pos ] ];
423
19.3M
      }
424
1.49M
    }
425
745k
  }
426
427
  void RateEstimator::xSetSigSbbFracBits( const FracBitsAccess& fracBitsAccess, ChannelType chType )
428
745k
  {
429
745k
    const CtxSet& ctxSet = Ctx::SigCoeffGroup[ chType ];
430
2.23M
    for( unsigned ctxId = 0; ctxId < sm_maxNumSigSbbCtx; ctxId++ )
431
1.49M
    {
432
1.49M
      m_sigSbbFracBits[ ctxId ] = fracBitsAccess.getFracBitsArray( ctxSet( ctxId ) );
433
1.49M
    }
434
745k
  }
435
436
  void RateEstimator::xSetSigFlagBits( const FracBitsAccess& fracBitsAccess, ChannelType chType )
437
745k
  {
438
2.98M
    for( unsigned ctxSetId = 0; ctxSetId < sm_numCtxSetsSig; ctxSetId++ )
439
2.23M
    {
440
2.23M
      BinFracBits*    bits    = m_sigFracBits [ ctxSetId ];
441
2.23M
      const CtxSet&   ctxSet  = Ctx::SigFlag  [ chType + 2*ctxSetId ];
442
2.23M
      const unsigned  numCtx  = ( chType == CH_L ? 12 : 8 );
443
20.4M
      for( unsigned ctxId = 0; ctxId < numCtx; ctxId++ )
444
18.2M
      {
445
18.2M
        bits[ ctxId ] = fracBitsAccess.getFracBitsArray( ctxSet( ctxId ) );
446
18.2M
      }
447
2.23M
    }
448
745k
  }
449
450
  void RateEstimator::xSetGtxFlagBits( const FracBitsAccess& fracBitsAccess, ChannelType chType )
451
745k
  {
452
745k
    const CtxSet&   ctxSetPar   = Ctx::ParFlag [     chType ];
453
745k
    const CtxSet&   ctxSetGt1   = Ctx::GtxFlag [ 2 + chType ];
454
745k
    const CtxSet&   ctxSetGt2   = Ctx::GtxFlag [     chType ];
455
745k
    const unsigned  numCtx      = ( chType == CH_L ? 21 : 11 );
456
9.23M
    for( unsigned ctxId = 0; ctxId < numCtx; ctxId++ )
457
8.48M
    {
458
8.48M
      BinFracBits     fbPar = fracBitsAccess.getFracBitsArray( ctxSetPar( ctxId ) );
459
8.48M
      BinFracBits     fbGt1 = fracBitsAccess.getFracBitsArray( ctxSetGt1( ctxId ) );
460
8.48M
      BinFracBits     fbGt2 = fracBitsAccess.getFracBitsArray( ctxSetGt2( ctxId ) );
461
8.48M
      CoeffFracBits&  cb    = m_gtxFracBits[ ctxId ];
462
8.48M
      int32_t         par0  = (1<<SCALE_BITS) + int32_t(fbPar.intBits[0]);
463
8.48M
      int32_t         par1  = (1<<SCALE_BITS) + int32_t(fbPar.intBits[1]);
464
8.48M
      cb.bits[0] = 0;
465
8.48M
      cb.bits[1] = fbGt1.intBits[0] + (1 << SCALE_BITS);
466
8.48M
      cb.bits[2] = fbGt1.intBits[1] + par0 + fbGt2.intBits[0];
467
8.48M
      cb.bits[3] = fbGt1.intBits[1] + par1 + fbGt2.intBits[0];
468
8.48M
      cb.bits[4] = fbGt1.intBits[1] + par0 + fbGt2.intBits[1];
469
8.48M
      cb.bits[5] = fbGt1.intBits[1] + par1 + fbGt2.intBits[1];
470
8.48M
    }
471
745k
  }
472
473
  void CommonCtx::update( const ScanInfo& scanInfo, const int prevId, int stateId, StateMem& curr )
474
113k
  {
475
113k
    uint8_t*    sbbFlags  = m_currSbbCtx[stateId].sbbFlags;
476
113k
    uint8_t*    levels    = m_currSbbCtx[stateId].levels;
477
113k
    uint16_t    maxDist   = m_nbInfo[scanInfo.scanIdx - 1].maxDist;
478
113k
    uint16_t    sbbSize   = scanInfo.sbbSize;
479
113k
    std::size_t setCpSize = ( maxDist > sbbSize ? maxDist - sbbSize : 0 ) * sizeof( uint8_t );
480
113k
    if( prevId >= 0 )
481
93.8k
    {
482
93.8k
      ::memcpy( sbbFlags, m_prevSbbCtx[prevId].sbbFlags, scanInfo.numSbb * sizeof( uint8_t ) );
483
93.8k
      ::memcpy( levels + scanInfo.scanIdx + sbbSize, m_prevSbbCtx[prevId].levels + scanInfo.scanIdx + sbbSize, setCpSize );
484
93.8k
    }
485
19.5k
    else
486
19.5k
    {
487
19.5k
      ::memset( sbbFlags, 0, scanInfo.numSbb * sizeof( uint8_t ) );
488
19.5k
      ::memset( levels + scanInfo.scanIdx + sbbSize, 0, setCpSize );
489
19.5k
    }
490
113k
    sbbFlags[scanInfo.sbbPos] = !!curr.numSig[stateId];
491
492
113k
    const int       sigNSbb = ( ( scanInfo.nextSbbRight ? sbbFlags[scanInfo.nextSbbRight] : false ) || ( scanInfo.nextSbbBelow ? sbbFlags[scanInfo.nextSbbBelow] : false ) ? 1 : 0 );
493
113k
    curr.refSbbCtxId[stateId] = stateId;
494
113k
    const BinFracBits sbbBits = m_sbbFlagBits[sigNSbb];
495
496
113k
    curr.sbbBits0[stateId] = sbbBits.intBits[0];
497
113k
    curr.sbbBits1[stateId] = sbbBits.intBits[1];
498
499
113k
    if( sigNSbb || ( ( scanInfo.nextSbbRight && scanInfo.nextSbbBelow ) ? sbbFlags[scanInfo.nextSbbBelow + 1] : false ) )
500
69.7k
    {
501
69.7k
      const int         scanBeg = scanInfo.scanIdx - scanInfo.sbbSize;
502
69.7k
      const NbInfoOut* nbOut = m_nbInfo + scanBeg;
503
69.7k
      const uint8_t* absLevels = levels + scanBeg;
504
505
1.18M
      for( int id = 0; id < scanInfo.sbbSize; id++, nbOut++ )
506
1.11M
      {
507
1.11M
        if( nbOut->num )
508
753k
        {
509
753k
          TCoeff sumAbs = 0, sumAbs1 = 0, sumNum = 0;
510
1.83M
#define UPDATE(k) {TCoeff t=absLevels[nbOut->outPos[k]]; sumAbs+=t; sumAbs1+=std::min<TCoeff>(4+(t&1),t); sumNum+=!!t; }
511
753k
          switch( nbOut->num )
512
753k
          {
513
0
          default:
514
49.1k
          case 5:
515
49.1k
            UPDATE( 4 );
516
147k
          case 4:
517
147k
            UPDATE( 3 );
518
405k
          case 3:
519
405k
            UPDATE( 2 );
520
475k
          case 2:
521
475k
            UPDATE( 1 );
522
753k
          case 1:
523
753k
            UPDATE( 0 );
524
753k
          }
525
753k
#undef UPDATE
526
753k
          curr.tplAcc[id][stateId] = ( sumNum << 5 ) | sumAbs1;
527
753k
          curr.sum1st[id][stateId] = ( uint8_t ) std::min( 255, sumAbs );
528
753k
        }
529
1.11M
      }
530
69.7k
    }
531
113k
  }
532
533
  void Quantizer::initQuantBlock(const TransformUnit& tu, const ComponentID compID, const QpParam& cQP, const double lambda, int gValue)
534
1.78M
  {
535
1.78M
    CHECKD( lambda <= 0.0, "Lambda must be greater than 0" );
536
537
1.78M
    const int         qpDQ                  = cQP.Qp(tu.mtsIdx[compID]==MTS_SKIP) + 1;
538
1.78M
    const int         qpPer                 = qpDQ / 6;
539
1.78M
    const int         qpRem                 = qpDQ - 6 * qpPer;
540
1.78M
    const SPS&        sps                   = *tu.cs->sps;
541
1.78M
    const CompArea&   area                  = tu.blocks[ compID ];
542
1.78M
    const ChannelType chType                = toChannelType( compID );
543
1.78M
    const int         channelBitDepth       = sps.bitDepths[ chType ];
544
1.78M
    const int         maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange();
545
1.78M
    const int         nomTransformShift     = getTransformShift( channelBitDepth, area.size(), maxLog2TrDynamicRange );
546
1.78M
    const bool    needsSqrt2ScaleAdjustment = TU::needsSqrt2Scale(tu, compID);
547
1.78M
    const int         transformShift        = nomTransformShift + (needsSqrt2ScaleAdjustment?-1:0);
548
    // quant parameters
549
1.78M
    m_QShift                    = QUANT_SHIFT  - 1 + qpPer + transformShift;
550
1.78M
    m_QAdd                      = -( ( 3 << m_QShift ) >> 1 );
551
1.78M
    Intermediate_Int  invShift  = IQUANT_SHIFT + 1 - qpPer - transformShift;
552
1.78M
    m_QScale                    = g_quantScales[needsSqrt2ScaleAdjustment?1:0][ qpRem ];
553
1.78M
    const unsigned    qIdxBD    = std::min<unsigned>( maxLog2TrDynamicRange + 1, 8*sizeof(Intermediate_Int) + invShift - IQUANT_SHIFT - 1 );
554
1.78M
    m_maxQIdx                   = ( 1 << (qIdxBD-1) ) - 4;
555
1.78M
    if( m_QShift )
556
1.78M
      m_thresLast               = TCoeff((int64_t(m_DqThrVal) << (m_QShift-1)));
557
25
    else
558
25
      m_thresLast               = TCoeff((int64_t(m_DqThrVal>>1) << m_QShift));
559
1.78M
    m_thresSSbb                 = TCoeff((int64_t(3) << m_QShift));
560
    // distortion calculation parameters
561
1.78M
    const int64_t qScale        = (gValue==-1) ? m_QScale : gValue;
562
1.78M
    const int nomDShift =
563
1.78M
      SCALE_BITS - 2 * (nomTransformShift + DISTORTION_PRECISION_ADJUSTMENT(channelBitDepth)) + m_QShift + (needsSqrt2ScaleAdjustment ? 1 : 0);
564
1.78M
    const double  qScale2       = double( qScale * qScale );
565
1.78M
    const double  nomDistFactor = ( nomDShift < 0 ? 1.0/(double(int64_t(1)<<(-nomDShift))*qScale2*lambda) : double(int64_t(1)<<nomDShift)/(qScale2*lambda) );
566
1.78M
    const uint32_t pow2dfShift   = (uint32_t)( nomDistFactor * qScale2 ) + 1;
567
1.78M
    const int     dfShift       = ceilLog2( pow2dfShift );
568
1.78M
    m_DistShift                 = 62 + m_QShift - 2*maxLog2TrDynamicRange - dfShift;
569
1.78M
    m_DistAdd                   = (int64_t(1) << m_DistShift) >> 1;
570
1.78M
    m_DistStepAdd               = ((m_DistShift+m_QShift)>=64 ? (int64_t)( nomDistFactor * pow(2,m_DistShift+m_QShift) + .5 ) : (int64_t)( nomDistFactor * double(int64_t(1)<<(m_DistShift+m_QShift)) + .5 ));
571
1.78M
    m_DistOrgFact               = (int64_t)( nomDistFactor * double(int64_t(1)<<(m_DistShift+1       )) + .5 );
572
1.78M
  }
573
574
  void Quantizer::dequantBlock( const TransformUnit& tu, const ComponentID compID, const QpParam& cQP, CoeffBuf& recCoeff, bool enableScalingLists, int* piDequantCoef) const
575
734k
  {
576
577
    //----- set basic parameters -----
578
734k
    const CompArea&     area      = tu.blocks[ compID ];
579
734k
    const int           numCoeff  = area.area();
580
734k
    const SizeType      hsId      = Log2( area.width );
581
734k
    const SizeType      vsId      = Log2( area.height );
582
734k
    const ScanElement  *scan      = getScanOrder( SCAN_GROUPED_4x4, hsId, vsId );
583
734k
    const TCoeffSig*    qCoeff    = tu.getCoeffs( compID ).buf;
584
734k
          TCoeff*       tCoeff    = recCoeff.buf;
585
586
    //----- reset coefficients and get last scan index -----
587
734k
    ::memset( tCoeff, 0, numCoeff * sizeof( TCoeff ) );
588
734k
    int lastScanIdx = tu.lastPos[compID];
589
734k
    if( lastScanIdx < 0 )
590
0
    {
591
0
      return;
592
0
    }
593
594
    //----- set dequant parameters -----
595
734k
    const int         qpDQ                  = cQP.Qp(tu.mtsIdx[compID]==MTS_SKIP) + 1;
596
734k
    const int         qpPer                 = qpDQ / 6;
597
734k
    const int         qpRem                 = qpDQ - 6 * qpPer;
598
734k
    const SPS&        sps                   = *tu.cs->sps;
599
734k
    const ChannelType chType                = toChannelType( compID );
600
734k
    const int         channelBitDepth       = sps.bitDepths[ chType ];
601
734k
    const int         maxLog2TrDynamicRange = sps.getMaxLog2TrDynamicRange();
602
734k
    const TCoeff      minTCoeff             = -( 1 << maxLog2TrDynamicRange );
603
734k
    const TCoeff      maxTCoeff             =  ( 1 << maxLog2TrDynamicRange ) - 1;
604
734k
    const int         nomTransformShift     = getTransformShift( channelBitDepth, area.size(), maxLog2TrDynamicRange );
605
734k
    const bool    needsSqrt2ScaleAdjustment = TU::needsSqrt2Scale(tu, compID);
606
734k
    const int         transformShift        = nomTransformShift + (needsSqrt2ScaleAdjustment?-1:0);
607
734k
    Intermediate_Int  shift                 = IQUANT_SHIFT + 1 - qpPer - transformShift + (enableScalingLists ? LOG2_SCALING_LIST_NEUTRAL_VALUE : 0);
608
734k
    Intermediate_Int  invQScale             = g_invQuantScales[needsSqrt2ScaleAdjustment?1:0][ qpRem ];
609
734k
    Intermediate_Int  add                   = (shift < 0) ? 0 : ((1 << shift) >> 1);
610
    //----- dequant coefficients -----
611
7.77M
    for( int state = 0, scanIdx = lastScanIdx; scanIdx >= 0; scanIdx-- )
612
7.03M
    {
613
7.03M
      const unsigned   rasterPos = scan[scanIdx].idx;
614
7.03M
      const TCoeffSig& level     = qCoeff[ rasterPos ];
615
7.03M
      if( level )
616
6.33M
      {
617
6.33M
        if (enableScalingLists)
618
0
          invQScale = piDequantCoef[rasterPos];//scalingfactor*levelScale
619
6.33M
        if (shift < 0 && (enableScalingLists || scanIdx == lastScanIdx))
620
401k
        {
621
401k
          invQScale <<= -shift;
622
401k
        }
623
6.33M
        Intermediate_Int qIdx = 2 * level + (level > 0 ? -(state>>1) : (state>>1));
624
6.33M
        int64_t  nomTCoeff          = ((int64_t)qIdx * (int64_t)invQScale + add) >> ((shift < 0) ? 0 : shift);
625
6.33M
        tCoeff[rasterPos]           = (TCoeff)Clip3<int64_t>(minTCoeff, maxTCoeff, nomTCoeff);
626
6.33M
      }
627
7.03M
      state = ( 32040 >> ((state<<2)+((level&1)<<1)) ) & 3;   // the 16-bit value "32040" represent the state transition table
628
7.03M
    }
629
734k
  }
630
631
  bool Quantizer::preQuantCoeff( const TCoeff absCoeff, PQData* pqData, int quanCoeff ) const
632
0
  {
633
0
    int64_t scaledOrg = int64_t( absCoeff ) * quanCoeff;
634
0
    TCoeff  qIdx      = TCoeff( ( scaledOrg + m_QAdd ) >> m_QShift );
635
636
0
    if( qIdx < 0 )
637
0
    {
638
0
      int64_t scaledAdd = m_DistStepAdd - scaledOrg * m_DistOrgFact;
639
0
      PQData& pq_a      = pqData[1];
640
0
      PQData& pq_b      = pqData[2];
641
642
0
      pq_a.deltaDist    = ( ( scaledAdd + 0 * m_DistStepAdd ) * 1 + m_DistAdd ) >> m_DistShift;
643
0
      pq_a.absLevel     = 1;
644
645
0
      pq_b.deltaDist    = ( ( scaledAdd + 1 * m_DistStepAdd ) * 2 + m_DistAdd ) >> m_DistShift;
646
0
      pq_b.absLevel     = 1;
647
      
648
0
      return true;
649
0
    }
650
     
651
0
    qIdx              = std::max<TCoeff>( 1, std::min<TCoeff>( m_maxQIdx, qIdx ) );
652
0
    int64_t scaledAdd = qIdx * m_DistStepAdd - scaledOrg * m_DistOrgFact;
653
654
0
    PQData& pq_a      = pqData[( qIdx + 0 ) & 3];
655
0
    PQData& pq_b      = pqData[( qIdx + 1 ) & 3];
656
0
    PQData& pq_c      = pqData[( qIdx + 2 ) & 3];
657
0
    PQData& pq_d      = pqData[( qIdx + 3 ) & 3];
658
659
0
    pq_a.deltaDist    = ( ( scaledAdd + 0 * m_DistStepAdd ) * ( qIdx + 0 ) + m_DistAdd ) >> m_DistShift;
660
0
    pq_a.absLevel     = ( qIdx + 1 ) >> 1;
661
662
0
    pq_b.deltaDist    = ( ( scaledAdd + 1 * m_DistStepAdd ) * ( qIdx + 1 ) + m_DistAdd ) >> m_DistShift;
663
0
    pq_b.absLevel     = ( qIdx + 2 ) >> 1;
664
665
0
    pq_c.deltaDist    = ( ( scaledAdd + 2 * m_DistStepAdd ) * ( qIdx + 2 ) + m_DistAdd ) >> m_DistShift;
666
0
    pq_c.absLevel     = ( qIdx + 3 ) >> 1;
667
668
0
    pq_d.deltaDist    = ( ( scaledAdd + 3 * m_DistStepAdd ) * ( qIdx + 3 ) + m_DistAdd ) >> m_DistShift;
669
0
    pq_d.absLevel     = ( qIdx + 4 ) >> 1;
670
671
0
    return false;
672
0
  }
673
674
  const int32_t g_goRiceBits[4][RICEMAX] =
675
  {
676
    { 32768,  65536,  98304, 131072, 163840, 196608, 262144, 262144, 327680, 327680, 327680, 327680, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 393216, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752, 458752},
677
    { 65536,  65536,  98304,  98304, 131072, 131072, 163840, 163840, 196608, 196608, 229376, 229376, 294912, 294912, 294912, 294912, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 360448, 425984, 425984, 425984, 425984, 425984, 425984, 425984, 425984},
678
    { 98304,  98304,  98304,  98304, 131072, 131072, 131072, 131072, 163840, 163840, 163840, 163840, 196608, 196608, 196608, 196608, 229376, 229376, 229376, 229376, 262144, 262144, 262144, 262144, 327680, 327680, 327680, 327680, 327680, 327680, 327680, 327680},
679
    {131072, 131072, 131072, 131072, 131072, 131072, 131072, 131072, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 163840, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 196608, 229376, 229376, 229376, 229376, 229376, 229376, 229376, 229376}
680
  };
681
682
  static inline void initStates( const int stateId, DQIntern::StateMem& state )
683
5.96M
  {
684
5.96M
    state.rdCost[stateId]         = DQIntern::rdCostInit;
685
5.96M
    state.ctx.cff[stateId]        =  0;
686
5.96M
    state.ctx.sig[stateId]        =  0;
687
5.96M
    state.numSig[stateId]         =  0;
688
5.96M
    state.refSbbCtxId[stateId]    = -1;
689
5.96M
    state.remRegBins[stateId]     =  4;
690
5.96M
    state.cffBitsCtxOffset        =  0;
691
5.96M
    state.m_goRicePar[stateId]    =  0;
692
5.96M
    state.m_goRiceZero[stateId]   =  0;
693
5.96M
    state.sbbBits0[stateId]       =  0;
694
5.96M
    state.sbbBits1[stateId]       =  0;
695
5.96M
  }
696
697
  template<bool rrgEnsured = false>
698
  static inline void checkRdCosts( const int stateId, const DQIntern::ScanPosType spt, const DQIntern::PQData& pqDataA, const DQIntern::PQData& pqDataB, DQIntern::Decisions& decisions, int idxAZ, int idxB, const DQIntern::StateMem& state )
699
23.7M
  {
700
23.7M
    const int32_t* goRiceTab = DQIntern::g_goRiceBits[state.m_goRicePar[stateId]];
701
23.7M
    int64_t         rdCostA = state.rdCost[stateId] + pqDataA.deltaDist;
702
23.7M
    int64_t         rdCostB = state.rdCost[stateId] + pqDataB.deltaDist;
703
23.7M
    int64_t         rdCostZ = state.rdCost[stateId];
704
705
23.7M
    if( rrgEnsured || state.remRegBins[stateId] >= 4 )
706
23.3M
    {
707
23.3M
      const CoeffFracBits& cffBits = state.m_gtxFracBitsArray[state.ctx.cff[stateId]];
708
23.3M
      const BinFracBits    sigBits = state.m_sigFracBitsArray[stateId][state.ctx.sig[stateId]];
709
710
23.3M
      if( pqDataA.absLevel < 4 )
711
5.75M
        rdCostA += cffBits.bits[pqDataA.absLevel];
712
17.6M
      else
713
17.6M
      {
714
17.6M
        const unsigned value = ( pqDataA.absLevel - 4 ) >> 1;
715
17.6M
        rdCostA += cffBits.bits[pqDataA.absLevel - ( value << 1 )] + goRiceTab[std::min<unsigned>( value, RICEMAX - 1 )];
716
17.6M
      }
717
718
23.3M
      if( pqDataB.absLevel < 4 )
719
7.18M
        rdCostB += cffBits.bits[pqDataB.absLevel];
720
16.1M
      else
721
16.1M
      {
722
16.1M
        const unsigned value = ( pqDataB.absLevel - 4 ) >> 1;
723
16.1M
        rdCostB += cffBits.bits[pqDataB.absLevel - ( value << 1 )] + goRiceTab[std::min<unsigned>( value, RICEMAX - 1 )];
724
16.1M
      }
725
726
23.3M
      if( spt == SCAN_ISCSBB )
727
23.2M
      {
728
23.2M
        rdCostA += sigBits.intBits[1];
729
23.2M
        rdCostB += sigBits.intBits[1];
730
23.2M
        rdCostZ += sigBits.intBits[0];
731
23.2M
      }
732
67.8k
      else if( spt == SCAN_SOCSBB )
733
11.3k
      {
734
11.3k
        rdCostA += state.sbbBits1[stateId] + sigBits.intBits[1];
735
11.3k
        rdCostB += state.sbbBits1[stateId] + sigBits.intBits[1];
736
11.3k
        rdCostZ += state.sbbBits1[stateId] + sigBits.intBits[0];
737
11.3k
      }
738
56.5k
      else if( state.numSig[stateId] )
739
55.2k
      {
740
55.2k
        rdCostA += sigBits.intBits[1];
741
55.2k
        rdCostB += sigBits.intBits[1];
742
55.2k
        rdCostZ += sigBits.intBits[0];
743
55.2k
      }
744
1.24k
      else
745
1.24k
      {
746
1.24k
        rdCostZ = rdCostInit;
747
1.24k
      }
748
23.3M
    }
749
390k
    else
750
390k
    {
751
390k
      rdCostA += ( 1 << SCALE_BITS ) + goRiceTab[pqDataA.absLevel <= state.m_goRiceZero[stateId] ? pqDataA.absLevel - 1 : std::min<int>( pqDataA.absLevel, RICEMAX - 1 )];
752
390k
      rdCostB += ( 1 << SCALE_BITS ) + goRiceTab[pqDataB.absLevel <= state.m_goRiceZero[stateId] ? pqDataB.absLevel - 1 : std::min<int>( pqDataB.absLevel, RICEMAX - 1 )];
753
390k
      rdCostZ += goRiceTab[state.m_goRiceZero[stateId]];
754
390k
    }
755
756
23.7M
    if( rdCostA < rdCostZ && rdCostA < decisions.rdCost[idxAZ] )
757
14.8M
    {
758
14.8M
      decisions.rdCost[idxAZ] = rdCostA;
759
14.8M
      decisions.absLevel[idxAZ] = pqDataA.absLevel;
760
14.8M
      decisions.prevId[idxAZ] = stateId;
761
14.8M
    }
762
8.88M
    else if( rdCostZ < decisions.rdCost[idxAZ] )
763
314k
    {
764
314k
      decisions.rdCost[idxAZ] = rdCostZ;
765
314k
      decisions.absLevel[idxAZ] = 0;
766
314k
      decisions.prevId[idxAZ] = stateId;
767
314k
    }
768
769
23.7M
    if( rdCostB < decisions.rdCost[idxB] )
770
15.2M
    {
771
15.2M
      decisions.rdCost[idxB] = rdCostB;
772
15.2M
      decisions.absLevel[idxB] = pqDataB.absLevel;
773
15.2M
      decisions.prevId[idxB] = stateId;
774
15.2M
    }
775
23.7M
  }
DepQuant.cpp:void vvenc::DQIntern::checkRdCosts<true>(int, vvenc::DQIntern::ScanPosType, vvenc::DQIntern::PQData const&, vvenc::DQIntern::PQData const&, vvenc::DQIntern::Decisions&, int, int, vvenc::DQIntern::StateMem const&)
Line
Count
Source
699
4.34M
  {
700
4.34M
    const int32_t* goRiceTab = DQIntern::g_goRiceBits[state.m_goRicePar[stateId]];
701
4.34M
    int64_t         rdCostA = state.rdCost[stateId] + pqDataA.deltaDist;
702
4.34M
    int64_t         rdCostB = state.rdCost[stateId] + pqDataB.deltaDist;
703
4.34M
    int64_t         rdCostZ = state.rdCost[stateId];
704
705
4.34M
    if( rrgEnsured || state.remRegBins[stateId] >= 4 )
706
4.34M
    {
707
4.34M
      const CoeffFracBits& cffBits = state.m_gtxFracBitsArray[state.ctx.cff[stateId]];
708
4.34M
      const BinFracBits    sigBits = state.m_sigFracBitsArray[stateId][state.ctx.sig[stateId]];
709
710
4.34M
      if( pqDataA.absLevel < 4 )
711
4.34M
        rdCostA += cffBits.bits[pqDataA.absLevel];
712
0
      else
713
0
      {
714
0
        const unsigned value = ( pqDataA.absLevel - 4 ) >> 1;
715
0
        rdCostA += cffBits.bits[pqDataA.absLevel - ( value << 1 )] + goRiceTab[std::min<unsigned>( value, RICEMAX - 1 )];
716
0
      }
717
718
4.34M
      if( pqDataB.absLevel < 4 )
719
4.34M
        rdCostB += cffBits.bits[pqDataB.absLevel];
720
0
      else
721
0
      {
722
0
        const unsigned value = ( pqDataB.absLevel - 4 ) >> 1;
723
0
        rdCostB += cffBits.bits[pqDataB.absLevel - ( value << 1 )] + goRiceTab[std::min<unsigned>( value, RICEMAX - 1 )];
724
0
      }
725
726
4.34M
      if( spt == SCAN_ISCSBB )
727
4.31M
      {
728
4.31M
        rdCostA += sigBits.intBits[1];
729
4.31M
        rdCostB += sigBits.intBits[1];
730
4.31M
        rdCostZ += sigBits.intBits[0];
731
4.31M
      }
732
26.8k
      else if( spt == SCAN_SOCSBB )
733
9.48k
      {
734
9.48k
        rdCostA += state.sbbBits1[stateId] + sigBits.intBits[1];
735
9.48k
        rdCostB += state.sbbBits1[stateId] + sigBits.intBits[1];
736
9.48k
        rdCostZ += state.sbbBits1[stateId] + sigBits.intBits[0];
737
9.48k
      }
738
17.3k
      else if( state.numSig[stateId] )
739
16.5k
      {
740
16.5k
        rdCostA += sigBits.intBits[1];
741
16.5k
        rdCostB += sigBits.intBits[1];
742
16.5k
        rdCostZ += sigBits.intBits[0];
743
16.5k
      }
744
851
      else
745
851
      {
746
851
        rdCostZ = rdCostInit;
747
851
      }
748
4.34M
    }
749
0
    else
750
0
    {
751
0
      rdCostA += ( 1 << SCALE_BITS ) + goRiceTab[pqDataA.absLevel <= state.m_goRiceZero[stateId] ? pqDataA.absLevel - 1 : std::min<int>( pqDataA.absLevel, RICEMAX - 1 )];
752
0
      rdCostB += ( 1 << SCALE_BITS ) + goRiceTab[pqDataB.absLevel <= state.m_goRiceZero[stateId] ? pqDataB.absLevel - 1 : std::min<int>( pqDataB.absLevel, RICEMAX - 1 )];
753
0
      rdCostZ += goRiceTab[state.m_goRiceZero[stateId]];
754
0
    }
755
756
4.34M
    if( rdCostA < rdCostZ && rdCostA < decisions.rdCost[idxAZ] )
757
2.84M
    {
758
2.84M
      decisions.rdCost[idxAZ] = rdCostA;
759
2.84M
      decisions.absLevel[idxAZ] = pqDataA.absLevel;
760
2.84M
      decisions.prevId[idxAZ] = stateId;
761
2.84M
    }
762
1.49M
    else if( rdCostZ < decisions.rdCost[idxAZ] )
763
313k
    {
764
313k
      decisions.rdCost[idxAZ] = rdCostZ;
765
313k
      decisions.absLevel[idxAZ] = 0;
766
313k
      decisions.prevId[idxAZ] = stateId;
767
313k
    }
768
769
4.34M
    if( rdCostB < decisions.rdCost[idxB] )
770
3.16M
    {
771
3.16M
      decisions.rdCost[idxB] = rdCostB;
772
3.16M
      decisions.absLevel[idxB] = pqDataB.absLevel;
773
3.16M
      decisions.prevId[idxB] = stateId;
774
3.16M
    }
775
4.34M
  }
DepQuant.cpp:void vvenc::DQIntern::checkRdCosts<false>(int, vvenc::DQIntern::ScanPosType, vvenc::DQIntern::PQData const&, vvenc::DQIntern::PQData const&, vvenc::DQIntern::Decisions&, int, int, vvenc::DQIntern::StateMem const&)
Line
Count
Source
699
19.4M
  {
700
19.4M
    const int32_t* goRiceTab = DQIntern::g_goRiceBits[state.m_goRicePar[stateId]];
701
19.4M
    int64_t         rdCostA = state.rdCost[stateId] + pqDataA.deltaDist;
702
19.4M
    int64_t         rdCostB = state.rdCost[stateId] + pqDataB.deltaDist;
703
19.4M
    int64_t         rdCostZ = state.rdCost[stateId];
704
705
19.4M
    if( rrgEnsured || state.remRegBins[stateId] >= 4 )
706
19.0M
    {
707
19.0M
      const CoeffFracBits& cffBits = state.m_gtxFracBitsArray[state.ctx.cff[stateId]];
708
19.0M
      const BinFracBits    sigBits = state.m_sigFracBitsArray[stateId][state.ctx.sig[stateId]];
709
710
19.0M
      if( pqDataA.absLevel < 4 )
711
1.41M
        rdCostA += cffBits.bits[pqDataA.absLevel];
712
17.6M
      else
713
17.6M
      {
714
17.6M
        const unsigned value = ( pqDataA.absLevel - 4 ) >> 1;
715
17.6M
        rdCostA += cffBits.bits[pqDataA.absLevel - ( value << 1 )] + goRiceTab[std::min<unsigned>( value, RICEMAX - 1 )];
716
17.6M
      }
717
718
19.0M
      if( pqDataB.absLevel < 4 )
719
2.84M
        rdCostB += cffBits.bits[pqDataB.absLevel];
720
16.1M
      else
721
16.1M
      {
722
16.1M
        const unsigned value = ( pqDataB.absLevel - 4 ) >> 1;
723
16.1M
        rdCostB += cffBits.bits[pqDataB.absLevel - ( value << 1 )] + goRiceTab[std::min<unsigned>( value, RICEMAX - 1 )];
724
16.1M
      }
725
726
19.0M
      if( spt == SCAN_ISCSBB )
727
18.9M
      {
728
18.9M
        rdCostA += sigBits.intBits[1];
729
18.9M
        rdCostB += sigBits.intBits[1];
730
18.9M
        rdCostZ += sigBits.intBits[0];
731
18.9M
      }
732
40.9k
      else if( spt == SCAN_SOCSBB )
733
1.84k
      {
734
1.84k
        rdCostA += state.sbbBits1[stateId] + sigBits.intBits[1];
735
1.84k
        rdCostB += state.sbbBits1[stateId] + sigBits.intBits[1];
736
1.84k
        rdCostZ += state.sbbBits1[stateId] + sigBits.intBits[0];
737
1.84k
      }
738
39.1k
      else if( state.numSig[stateId] )
739
38.7k
      {
740
38.7k
        rdCostA += sigBits.intBits[1];
741
38.7k
        rdCostB += sigBits.intBits[1];
742
38.7k
        rdCostZ += sigBits.intBits[0];
743
38.7k
      }
744
392
      else
745
392
      {
746
392
        rdCostZ = rdCostInit;
747
392
      }
748
19.0M
    }
749
390k
    else
750
390k
    {
751
390k
      rdCostA += ( 1 << SCALE_BITS ) + goRiceTab[pqDataA.absLevel <= state.m_goRiceZero[stateId] ? pqDataA.absLevel - 1 : std::min<int>( pqDataA.absLevel, RICEMAX - 1 )];
752
390k
      rdCostB += ( 1 << SCALE_BITS ) + goRiceTab[pqDataB.absLevel <= state.m_goRiceZero[stateId] ? pqDataB.absLevel - 1 : std::min<int>( pqDataB.absLevel, RICEMAX - 1 )];
753
390k
      rdCostZ += goRiceTab[state.m_goRiceZero[stateId]];
754
390k
    }
755
756
19.4M
    if( rdCostA < rdCostZ && rdCostA < decisions.rdCost[idxAZ] )
757
12.0M
    {
758
12.0M
      decisions.rdCost[idxAZ] = rdCostA;
759
12.0M
      decisions.absLevel[idxAZ] = pqDataA.absLevel;
760
12.0M
      decisions.prevId[idxAZ] = stateId;
761
12.0M
    }
762
7.39M
    else if( rdCostZ < decisions.rdCost[idxAZ] )
763
516
    {
764
516
      decisions.rdCost[idxAZ] = rdCostZ;
765
516
      decisions.absLevel[idxAZ] = 0;
766
516
      decisions.prevId[idxAZ] = stateId;
767
516
    }
768
769
19.4M
    if( rdCostB < decisions.rdCost[idxB] )
770
12.0M
    {
771
12.0M
      decisions.rdCost[idxB] = rdCostB;
772
12.0M
      decisions.absLevel[idxB] = pqDataB.absLevel;
773
12.0M
      decisions.prevId[idxB] = stateId;
774
12.0M
    }
775
19.4M
  }
776
777
  void checkAllRdCosts( const DQIntern::ScanPosType spt, const DQIntern::PQData* pqData, DQIntern::Decisions& decisions, const DQIntern::StateMem& state )
778
1.08M
  {
779
1.08M
    checkRdCosts<true>( 0, spt, pqData[0], pqData[2], decisions, 0, 2, state );
780
1.08M
    checkRdCosts<true>( 1, spt, pqData[0], pqData[2], decisions, 2, 0, state );
781
1.08M
    checkRdCosts<true>( 2, spt, pqData[3], pqData[1], decisions, 1, 3, state );
782
1.08M
    checkRdCosts<true>( 3, spt, pqData[3], pqData[1], decisions, 3, 1, state );
783
1.08M
  }
784
785
  template<bool rrgEnsured = false>
786
  static void checkRdCostsOdd1( const int stateId, const ScanPosType spt, const int64_t deltaDist, Decisions& decisions, int idxA, int idxZ, const StateMem& state )
787
4.76M
  {
788
4.76M
    int64_t         rdCostA = state.rdCost[stateId] + deltaDist;
789
4.76M
    int64_t         rdCostZ = state.rdCost[stateId];
790
791
4.76M
    if( rrgEnsured || state.remRegBins[stateId] >= 4 )
792
4.75M
    {
793
4.75M
      const BinFracBits sigBits = state.m_sigFracBitsArray[stateId][state.ctx.sig[stateId]];
794
795
4.75M
      rdCostA += state.cffBits1[state.ctx.cff[stateId]];
796
797
4.75M
      if( spt == SCAN_ISCSBB )
798
4.64M
      {
799
4.64M
        rdCostA += sigBits.intBits[1];
800
4.64M
        rdCostZ += sigBits.intBits[0];
801
4.64M
      }
802
117k
      else if( spt == SCAN_SOCSBB )
803
76.9k
      {
804
76.9k
        rdCostA += state.sbbBits1[stateId] + sigBits.intBits[1];
805
76.9k
        rdCostZ += state.sbbBits1[stateId] + sigBits.intBits[0];
806
76.9k
      }
807
40.8k
      else if( state.numSig[stateId] )
808
8.08k
      {
809
8.08k
        rdCostA += sigBits.intBits[1];
810
8.08k
        rdCostZ += sigBits.intBits[0];
811
8.08k
      }
812
32.7k
      else
813
32.7k
      {
814
32.7k
        rdCostZ = rdCostInit;
815
32.7k
      }
816
4.75M
    }
817
1.49k
    else
818
1.49k
    {
819
1.49k
      const int32_t* goRiceTab = g_goRiceBits[state.m_goRicePar[stateId]];
820
821
1.49k
      rdCostA += ( 1 << SCALE_BITS ) + goRiceTab[0];
822
1.49k
      rdCostZ += goRiceTab[state.m_goRiceZero[stateId]];
823
1.49k
    }
824
825
4.76M
    if( rdCostA < decisions.rdCost[idxA] )
826
2.83M
    {
827
2.83M
      decisions.rdCost[idxA] = rdCostA;
828
2.83M
      decisions.absLevel[idxA] = 1;
829
2.83M
      decisions.prevId[idxA] = stateId;
830
2.83M
    }
831
832
4.76M
    if( rdCostZ < decisions.rdCost[idxZ] )
833
3.36M
    {
834
3.36M
      decisions.rdCost[idxZ] = rdCostZ;
835
3.36M
      decisions.absLevel[idxZ] = 0;
836
3.36M
      decisions.prevId[idxZ] = stateId;
837
3.36M
    }
838
4.76M
  }
DepQuant.cpp:void vvenc::DQIntern::checkRdCostsOdd1<true>(int, vvenc::DQIntern::ScanPosType, long, vvenc::DQIntern::Decisions&, int, int, vvenc::DQIntern::StateMem const&)
Line
Count
Source
787
4.43M
  {
788
4.43M
    int64_t         rdCostA = state.rdCost[stateId] + deltaDist;
789
4.43M
    int64_t         rdCostZ = state.rdCost[stateId];
790
791
4.43M
    if( rrgEnsured || state.remRegBins[stateId] >= 4 )
792
4.43M
    {
793
4.43M
      const BinFracBits sigBits = state.m_sigFracBitsArray[stateId][state.ctx.sig[stateId]];
794
795
4.43M
      rdCostA += state.cffBits1[state.ctx.cff[stateId]];
796
797
4.43M
      if( spt == SCAN_ISCSBB )
798
4.31M
      {
799
4.31M
        rdCostA += sigBits.intBits[1];
800
4.31M
        rdCostZ += sigBits.intBits[0];
801
4.31M
      }
802
117k
      else if( spt == SCAN_SOCSBB )
803
76.7k
      {
804
76.7k
        rdCostA += state.sbbBits1[stateId] + sigBits.intBits[1];
805
76.7k
        rdCostZ += state.sbbBits1[stateId] + sigBits.intBits[0];
806
76.7k
      }
807
40.3k
      else if( state.numSig[stateId] )
808
8.08k
      {
809
8.08k
        rdCostA += sigBits.intBits[1];
810
8.08k
        rdCostZ += sigBits.intBits[0];
811
8.08k
      }
812
32.3k
      else
813
32.3k
      {
814
32.3k
        rdCostZ = rdCostInit;
815
32.3k
      }
816
4.43M
    }
817
0
    else
818
0
    {
819
0
      const int32_t* goRiceTab = g_goRiceBits[state.m_goRicePar[stateId]];
820
821
0
      rdCostA += ( 1 << SCALE_BITS ) + goRiceTab[0];
822
0
      rdCostZ += goRiceTab[state.m_goRiceZero[stateId]];
823
0
    }
824
825
4.43M
    if( rdCostA < decisions.rdCost[idxA] )
826
2.83M
    {
827
2.83M
      decisions.rdCost[idxA] = rdCostA;
828
2.83M
      decisions.absLevel[idxA] = 1;
829
2.83M
      decisions.prevId[idxA] = stateId;
830
2.83M
    }
831
832
4.43M
    if( rdCostZ < decisions.rdCost[idxZ] )
833
3.36M
    {
834
3.36M
      decisions.rdCost[idxZ] = rdCostZ;
835
3.36M
      decisions.absLevel[idxZ] = 0;
836
3.36M
      decisions.prevId[idxZ] = stateId;
837
3.36M
    }
838
4.43M
  }
DepQuant.cpp:void vvenc::DQIntern::checkRdCostsOdd1<false>(int, vvenc::DQIntern::ScanPosType, long, vvenc::DQIntern::Decisions&, int, int, vvenc::DQIntern::StateMem const&)
Line
Count
Source
787
329k
  {
788
329k
    int64_t         rdCostA = state.rdCost[stateId] + deltaDist;
789
329k
    int64_t         rdCostZ = state.rdCost[stateId];
790
791
329k
    if( rrgEnsured || state.remRegBins[stateId] >= 4 )
792
328k
    {
793
328k
      const BinFracBits sigBits = state.m_sigFracBitsArray[stateId][state.ctx.sig[stateId]];
794
795
328k
      rdCostA += state.cffBits1[state.ctx.cff[stateId]];
796
797
328k
      if( spt == SCAN_ISCSBB )
798
327k
      {
799
327k
        rdCostA += sigBits.intBits[1];
800
327k
        rdCostZ += sigBits.intBits[0];
801
327k
      }
802
574
      else if( spt == SCAN_SOCSBB )
803
162
      {
804
162
        rdCostA += state.sbbBits1[stateId] + sigBits.intBits[1];
805
162
        rdCostZ += state.sbbBits1[stateId] + sigBits.intBits[0];
806
162
      }
807
412
      else if( state.numSig[stateId] )
808
0
      {
809
0
        rdCostA += sigBits.intBits[1];
810
0
        rdCostZ += sigBits.intBits[0];
811
0
      }
812
412
      else
813
412
      {
814
412
        rdCostZ = rdCostInit;
815
412
      }
816
328k
    }
817
1.49k
    else
818
1.49k
    {
819
1.49k
      const int32_t* goRiceTab = g_goRiceBits[state.m_goRicePar[stateId]];
820
821
1.49k
      rdCostA += ( 1 << SCALE_BITS ) + goRiceTab[0];
822
1.49k
      rdCostZ += goRiceTab[state.m_goRiceZero[stateId]];
823
1.49k
    }
824
825
329k
    if( rdCostA < decisions.rdCost[idxA] )
826
1.14k
    {
827
1.14k
      decisions.rdCost[idxA] = rdCostA;
828
1.14k
      decisions.absLevel[idxA] = 1;
829
1.14k
      decisions.prevId[idxA] = stateId;
830
1.14k
    }
831
832
329k
    if( rdCostZ < decisions.rdCost[idxZ] )
833
1.73k
    {
834
1.73k
      decisions.rdCost[idxZ] = rdCostZ;
835
1.73k
      decisions.absLevel[idxZ] = 0;
836
1.73k
      decisions.prevId[idxZ] = stateId;
837
1.73k
    }
838
329k
  }
839
840
  static void checkAllRdCostsOdd1( const DQIntern::ScanPosType spt, const int64_t pq_a_dist, const int64_t pq_b_dist, DQIntern::Decisions& decisions, const DQIntern::StateMem& state )
841
1.10M
  {
842
1.10M
    checkRdCostsOdd1<true>( 0, spt, pq_b_dist, decisions, 2, 0, state );
843
1.10M
    checkRdCostsOdd1<true>( 1, spt, pq_b_dist, decisions, 0, 2, state );
844
1.10M
    checkRdCostsOdd1<true>( 2, spt, pq_a_dist, decisions, 3, 1, state );
845
1.10M
    checkRdCostsOdd1<true>( 3, spt, pq_a_dist, decisions, 1, 3, state );
846
1.10M
  }
847
848
  static inline void checkRdCostStart( int32_t lastOffset, const PQData& pqData, Decisions& decisions, int idx, const StateMem& state )
849
13.0M
  {
850
13.0M
    const CoeffFracBits& cffBits = state.m_gtxFracBitsArray[0];
851
852
13.0M
    int64_t rdCost = pqData.deltaDist + lastOffset;
853
13.0M
    if( pqData.absLevel < 4 )
854
4.63M
    {
855
4.63M
      rdCost += cffBits.bits[pqData.absLevel];
856
4.63M
    }
857
8.43M
    else
858
8.43M
    {
859
8.43M
      const unsigned value = ( pqData.absLevel - 4 ) >> 1;
860
8.43M
      rdCost += cffBits.bits[pqData.absLevel - ( value << 1 )] + g_goRiceBits[0][value < RICEMAX ? value : RICEMAX - 1];
861
8.43M
    }
862
863
13.0M
    if( rdCost < decisions.rdCost[idx] )
864
1.73M
    {
865
1.73M
      decisions.rdCost[idx]   = rdCost;
866
1.73M
      decisions.absLevel[idx] = pqData.absLevel;
867
1.73M
      decisions.prevId[idx]   = -1;
868
1.73M
    }
869
13.0M
  }
870
871
  static inline void checkRdCostSkipSbb( const int stateId, Decisions& decisions, int idx, const StateMem& state )
872
108k
  {
873
108k
    int64_t rdCost = state.rdCost[stateId] + state.sbbBits0[stateId];
874
108k
    if( rdCost < decisions.rdCost[idx] )
875
38.0k
    {
876
38.0k
      decisions.rdCost[idx]   = rdCost;
877
38.0k
      decisions.absLevel[idx] = 0;
878
38.0k
      decisions.prevId[idx]   = 4 | stateId;
879
38.0k
    }
880
108k
  }
881
882
  static inline void checkRdCostSkipSbbZeroOut( const int stateId, Decisions& decisions, int idx, const StateMem& state )
883
0
  {
884
0
    int64_t rdCost          = state.rdCost[stateId] + state.sbbBits0[stateId];
885
0
    decisions.rdCost[idx]   = rdCost;
886
0
    decisions.absLevel[idx] = 0;
887
0
    decisions.prevId[idx]   = 4 | stateId;
888
0
  }
889
890
  static inline void setRiceParam( const int stateId, const ScanInfo& scanInfo, StateMem& state, bool ge4 )
891
19.2M
  {
892
19.2M
    if( state.remRegBins[stateId] < 4 || ge4 )
893
17.9M
    {
894
17.9M
      TCoeff  sumAbs = state.sum1st[scanInfo.insidePos][stateId];
895
17.9M
      int sumSub     = state.remRegBins[stateId] < 4 ? 0 : 4 * 5;
896
17.9M
      int sumAll     = std::max( std::min( 31, ( int ) sumAbs - sumSub ), 0 );
897
17.9M
      state.m_goRicePar[stateId]
898
17.9M
                     = g_auiGoRiceParsCoeff[sumAll];
899
900
17.9M
      if( state.remRegBins[stateId] < 4 )
901
391k
      {
902
391k
        state.m_goRiceZero[stateId] = g_auiGoRicePosCoeff0( stateId, state.m_goRicePar[stateId] );
903
391k
      }
904
17.9M
    }
905
19.2M
  }
906
907
  static void update1State( int stateId, const DQIntern::ScanInfo& scanInfo, const DQIntern::Decisions& decisions, DQIntern::StateMem& curr, DQIntern::StateMem& prev )
908
25.4M
  {
909
25.4M
    curr.rdCost[stateId] = decisions.rdCost[stateId];
910
25.4M
    if( decisions.prevId[stateId] > -2 )
911
24.3M
    {
912
24.3M
      if( decisions.prevId[stateId] >= 0 )
913
23.1M
      {
914
23.1M
        const int prevId          = decisions.prevId[stateId];
915
23.1M
        curr.numSig[stateId]      = prev.numSig[prevId] + !!decisions.absLevel[stateId];
916
23.1M
        curr.refSbbCtxId[stateId] = prev.refSbbCtxId[prevId];
917
23.1M
        curr.sbbBits0[stateId]    = prev.sbbBits0[prevId];
918
23.1M
        curr.sbbBits1[stateId]    = prev.sbbBits1[prevId];
919
23.1M
        curr.remRegBins[stateId]  = prev.remRegBins[prevId] - 1;
920
921
23.1M
        if( curr.remRegBins[stateId] >= 4 )
922
22.9M
        {
923
22.9M
          curr.remRegBins[stateId] -= ( decisions.absLevel[stateId] < 2 ? decisions.absLevel[stateId] : 3 );
924
22.9M
        }
925
926
393M
        for( int i = 0; i < 16; i++ )
927
370M
        {
928
370M
          curr.tplAcc[i][stateId] = prev.tplAcc[i][prevId];
929
370M
          curr.sum1st[i][stateId] = prev.sum1st[i][prevId];
930
370M
          curr.absVal[i][stateId] = prev.absVal[i][prevId];
931
370M
        }
932
23.1M
      }
933
1.21M
      else
934
1.21M
      {
935
1.21M
        curr.numSig[stateId]      =  1;
936
1.21M
        curr.refSbbCtxId[stateId] = -1;
937
1.21M
        curr.remRegBins[stateId]  = prev.initRemRegBins;
938
1.21M
        curr.remRegBins[stateId] -= ( decisions.absLevel[stateId] < 2 ? decisions.absLevel[stateId] : 3 );
939
940
20.6M
        for( int i = 0; i < 16; i++ )
941
19.4M
        {
942
19.4M
          curr.tplAcc[i][stateId] = 0;
943
19.4M
          curr.sum1st[i][stateId] = 0;
944
19.4M
          curr.absVal[i][stateId] = 0;
945
19.4M
        }
946
1.21M
      }
947
948
24.3M
      if( decisions.absLevel[stateId] )
949
21.5M
      {
950
21.5M
        curr.absVal[scanInfo.insidePos][stateId] = ( uint8_t ) std::min<TCoeff>( 126 + ( decisions.absLevel[stateId] & 1 ), decisions.absLevel[stateId] );
951
952
21.5M
        if( scanInfo.currNbInfoSbb.numInv )
953
21.5M
        {
954
21.5M
          int min4_or_5 = std::min<TCoeff>( 4 + ( decisions.absLevel[stateId] & 1 ), decisions.absLevel[stateId] );
955
956
21.5M
          auto adds8 = []( uint8_t a, uint8_t b )
957
62.9M
          {
958
62.9M
            uint8_t c = a + b;
959
62.9M
            if( c < a ) c = -1;
960
62.9M
            return c;
961
62.9M
          };
962
963
21.5M
          auto update_deps = [&]( int k )
964
62.9M
          {
965
62.9M
            curr.tplAcc[scanInfo.currNbInfoSbb.invInPos[k]][stateId] += 32 + min4_or_5;
966
62.9M
            curr.sum1st[scanInfo.currNbInfoSbb.invInPos[k]][stateId] = adds8( curr.sum1st[scanInfo.currNbInfoSbb.invInPos[k]][stateId], decisions.absLevel[stateId] );
967
62.9M
          };
968
969
21.5M
          switch( scanInfo.currNbInfoSbb.numInv )
970
21.5M
          {
971
0
          default:
972
3.54M
          case 5:
973
3.54M
            update_deps( 4 );
974
8.96M
          case 4:
975
8.96M
            update_deps( 3 );
976
10.8M
          case 3:
977
10.8M
            update_deps( 2 );
978
17.9M
          case 2:
979
17.9M
            update_deps( 1 );
980
21.5M
          case 1:
981
21.5M
            update_deps( 0 );
982
21.5M
          }
983
21.5M
        }
984
21.5M
      }
985
986
24.3M
      if( curr.remRegBins[stateId] >= 4 )
987
23.9M
      {
988
23.9M
        TCoeff  sumAbs1 = curr.tplAcc[scanInfo.nextInsidePos][stateId] & 31;
989
23.9M
        TCoeff  sumNum  = curr.tplAcc[scanInfo.nextInsidePos][stateId] >> 5u;
990
23.9M
        int sumGt1 = sumAbs1 - sumNum;
991
992
23.9M
        curr.ctx.sig[stateId] = scanInfo.sigCtxOffsetNext + std::min( ( sumAbs1 + 1 ) >> 1, 3 );
993
23.9M
        curr.ctx.cff[stateId] = scanInfo.gtxCtxOffsetNext + std::min( sumGt1, 4 );
994
23.9M
      }
995
379k
      else
996
379k
      {
997
379k
        curr.anyRemRegBinsLt4 = true;
998
379k
      }
999
24.3M
    }
1000
25.4M
  }
1001
1002
  static void update1StateEOS( const int stateId, const DQIntern::ScanInfo& scanInfo, const DQIntern::Decisions& decisions, const DQIntern::StateMem& skip, DQIntern::StateMem& curr, DQIntern::StateMem& prev, DQIntern::CommonCtx& commonCtx )
1003
114k
  {
1004
114k
    curr.rdCost[stateId] = decisions.rdCost[stateId];
1005
1006
114k
    if( decisions.prevId[stateId] > -2 )
1007
113k
    {
1008
113k
      if( decisions.prevId[stateId] >= 4 )
1009
38.0k
      {
1010
38.0k
        CHECK( decisions.absLevel[stateId] != 0, "cannot happen" );
1011
1012
38.0k
        const int prevId          = decisions.prevId[stateId] - 4;
1013
38.0k
        curr.numSig    [stateId]  = 0;
1014
38.0k
        curr.remRegBins[stateId]  = skip.remRegBins[prevId];
1015
38.0k
        curr.refSbbCtxId[stateId] = prevId;
1016
1017
646k
        for( int i = 0; i < 16; i++ )
1018
608k
        {
1019
608k
          curr.absVal[i][stateId] = 0;
1020
608k
        }
1021
38.0k
      }
1022
75.3k
      else if( decisions.prevId[stateId] >= 0 )
1023
73.5k
      {
1024
73.5k
        const int prevId          = decisions.prevId[stateId];
1025
73.5k
        curr.numSig[stateId]      = prev.numSig[prevId] + !!decisions.absLevel[stateId];
1026
73.5k
        curr.refSbbCtxId[stateId] = prev.refSbbCtxId[prevId];
1027
73.5k
        curr.remRegBins[stateId]  = prev.remRegBins[prevId] - 1;
1028
1029
73.5k
        if( curr.remRegBins[stateId] >= 4 )
1030
61.6k
        {
1031
61.6k
          curr.remRegBins[stateId] -= ( decisions.absLevel[stateId] < 2 ? decisions.absLevel[stateId] : 3 );
1032
61.6k
        }
1033
1034
1.25M
        for( int i = 0; i < 16; i++ )
1035
1.17M
        {
1036
1.17M
          curr.absVal[i][stateId] = prev.absVal[i][prevId];
1037
1.17M
        }
1038
73.5k
      }
1039
1.77k
      else
1040
1.77k
      {
1041
1.77k
        curr.numSig[stateId]      =  1;
1042
1.77k
        curr.refSbbCtxId[stateId] = -1;
1043
1.77k
        curr.remRegBins[stateId]  = prev.initRemRegBins;
1044
1.77k
        curr.remRegBins[stateId] -= ( decisions.absLevel[stateId] < 2 ? decisions.absLevel[stateId] : 3 );
1045
1046
30.2k
        for( int i = 0; i < 16; i++ )
1047
28.4k
        {
1048
28.4k
          curr.absVal[i][stateId] = 0;
1049
28.4k
        }
1050
1.77k
      }
1051
1052
113k
      curr.absVal[scanInfo.insidePos][stateId] = ( uint8_t ) std::min<TCoeff>( 126 + ( decisions.absLevel[stateId] & 1 ), decisions.absLevel[stateId] );
1053
1054
113k
      uint8_t* levels[4];
1055
113k
      commonCtx.getLevelPtrs( scanInfo, levels[0], levels[1], levels[2], levels[3] );
1056
1.92M
      for( int i = 0; i < 16; i++ )
1057
1.81M
      {
1058
        // save abs levels to commonCtx
1059
1.81M
        levels[stateId][i] = curr.absVal[i][stateId];
1060
        // clean the SBB ctx
1061
1.81M
        curr.tplAcc[i][stateId] = 0;
1062
1.81M
        curr.sum1st[i][stateId] = 0;
1063
1.81M
        curr.absVal[i][stateId] = 0;
1064
1.81M
      }
1065
1066
113k
      commonCtx.update( scanInfo, curr.refSbbCtxId[stateId], stateId, curr );
1067
1068
113k
      curr.numSig[stateId] = 0;
1069
1070
113k
      if( curr.remRegBins[stateId] >= 4 )
1071
101k
      {
1072
101k
        TCoeff  sumAbs1 = curr.tplAcc[scanInfo.nextInsidePos][stateId] & 31;
1073
101k
        TCoeff  sumNum  = curr.tplAcc[scanInfo.nextInsidePos][stateId] >> 5u;
1074
101k
        int sumGt1 = sumAbs1 - sumNum;
1075
1076
101k
        curr.ctx.sig[stateId] = scanInfo.sigCtxOffsetNext + std::min( ( sumAbs1 + 1 ) >> 1, 3 );
1077
101k
        curr.ctx.cff[stateId] = scanInfo.gtxCtxOffsetNext + std::min( sumGt1, 4 );
1078
101k
      }
1079
12.0k
      else
1080
12.0k
      {
1081
12.0k
        curr.anyRemRegBinsLt4 = true;
1082
12.0k
      }
1083
113k
    }
1084
114k
  }
1085
1086
  static void updateStates( const DQIntern::ScanInfo& scanInfo, const DQIntern::Decisions& decisions, DQIntern::StateMem& curr )
1087
6.35M
  {
1088
6.35M
    DQIntern::StateMem prev = curr;
1089
6.35M
    curr.anyRemRegBinsLt4   = false;
1090
1091
6.35M
    update1State( 0, scanInfo, decisions, curr, prev );
1092
6.35M
    update1State( 1, scanInfo, decisions, curr, prev );
1093
6.35M
    update1State( 2, scanInfo, decisions, curr, prev );
1094
6.35M
    update1State( 3, scanInfo, decisions, curr, prev );
1095
1096
6.35M
    curr.cffBitsCtxOffset = scanInfo.gtxCtxOffsetNext;
1097
6.35M
  }
1098
1099
  static void updateStatesEOS( const DQIntern::ScanInfo& scanInfo, const DQIntern::Decisions& decisions, const DQIntern::StateMem& skip, DQIntern::StateMem& curr, DQIntern::CommonCtx& commonCtx )
1100
28.6k
  {
1101
28.6k
    DQIntern::StateMem prev = curr;
1102
28.6k
    curr.anyRemRegBinsLt4   = false;
1103
1104
28.6k
    update1StateEOS( 0, scanInfo, decisions, skip, curr, prev, commonCtx );
1105
28.6k
    update1StateEOS( 1, scanInfo, decisions, skip, curr, prev, commonCtx );
1106
28.6k
    update1StateEOS( 2, scanInfo, decisions, skip, curr, prev, commonCtx );
1107
28.6k
    update1StateEOS( 3, scanInfo, decisions, skip, curr, prev, commonCtx );
1108
1109
28.6k
    curr.cffBitsCtxOffset = scanInfo.gtxCtxOffsetNext;
1110
28.6k
  }
1111
}; // namespace DQIntern
1112
1113
static const DQIntern::Decisions startDec[2] =
1114
{
1115
  DQIntern::Decisions
1116
  {
1117
    { DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2 },
1118
    { -1, -1, -1, -1 },
1119
    { -2, -2, -2, -2 },
1120
  },
1121
  DQIntern::Decisions
1122
  {
1123
    { DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2, DQIntern::rdCostInit >> 2 },
1124
    { 0, 0, 0, 0 },
1125
    { 4, 5, 6, 7 },
1126
  }
1127
};
1128
1129
void DepQuant::xQuantDQ( TransformUnit& tu, const CCoeffBuf& srcCoeff, const ComponentID compID, const QpParam& cQP, const double lambda, const Ctx& ctx, TCoeff& absSum, bool enableScalingLists, int* quantCoeff )
1130
1.78M
{
1131
1.78M
  using namespace DQIntern;
1132
  
1133
  //===== reset / pre-init =====
1134
1.78M
  const TUParameters& tuPars  = *m_scansRom->getTUPars( tu.blocks[compID], compID );
1135
1.78M
  m_quant.initQuantBlock    ( tu, compID, cQP, lambda );
1136
1.78M
  TCoeffSig*    qCoeff      = tu.getCoeffs( compID ).buf;
1137
1.78M
  const TCoeff* tCoeff      = srcCoeff.buf;
1138
1.78M
  const int     numCoeff    = tu.blocks[compID].area();
1139
1.78M
  ::memset( qCoeff, 0x00, numCoeff * sizeof( TCoeffSig ) );
1140
1.78M
  absSum                    = 0;
1141
1142
1.78M
  const CompArea& area      = tu.blocks[ compID ];
1143
1.78M
  const uint32_t  width     = area.width;
1144
1.78M
  const uint32_t  height    = area.height;
1145
1.78M
  const uint32_t  lfnstIdx  = tu.cu->lfnstIdx;
1146
  //===== scaling matrix ====
1147
  //const int         qpDQ = cQP.Qp + 1;
1148
  //const int         qpPer = qpDQ / 6;
1149
  //const int         qpRem = qpDQ - 6 * qpPer;
1150
1151
  //TCoeff thresTmp = thres;
1152
1.78M
  bool zeroOut = false;
1153
1.78M
  bool zeroOutforThres = false;
1154
1.78M
  int effWidth = tuPars.m_width, effHeight = tuPars.m_height;
1155
1.78M
  if( ( tu.mtsIdx[compID] > MTS_SKIP || ( tu.cs->sps->MTS && tu.cu->sbtInfo != 0 && tuPars.m_height <= 32 && tuPars.m_width <= 32 ) ) && compID == COMP_Y )
1156
0
  {
1157
0
    effHeight = ( tuPars.m_height == 32 ) ? 16 : tuPars.m_height;
1158
0
    effWidth  = ( tuPars.m_width  == 32 ) ? 16 : tuPars.m_width;
1159
0
    zeroOut   = ( effHeight < tuPars.m_height || effWidth < tuPars.m_width );
1160
0
  }
1161
1.78M
  zeroOutforThres = zeroOut || ( 32 < tuPars.m_height || 32 < tuPars.m_width );
1162
  //===== find first test position =====
1163
1.78M
  int firstTestPos = std::min<int>( tuPars.m_width, JVET_C0024_ZERO_OUT_TH ) * std::min<int>( tuPars.m_height, JVET_C0024_ZERO_OUT_TH ) - 1;
1164
1.78M
  if( lfnstIdx > 0 && tu.mtsIdx[compID] != MTS_SKIP && width >= 4 && height >= 4 )
1165
1.11M
  {
1166
1.11M
    firstTestPos = ( ( width == 4 && height == 4 ) || ( width == 8 && height == 8 ) )  ? 7 : 15 ;
1167
1.11M
  }
1168
1169
1.78M
  const TCoeff defaultQuantisationCoefficient = (TCoeff)m_quant.getQScale();
1170
1.78M
  const TCoeff thres = m_quant.getLastThreshold();
1171
1.78M
  const int zeroOutWidth  = ( tuPars.m_width  == 32 && zeroOut ) ? 16 : 32;
1172
1.78M
  const int zeroOutHeight = ( tuPars.m_height == 32 && zeroOut ) ? 16 : 32;
1173
1174
1.78M
  if( enableScalingLists )
1175
0
  {
1176
0
    for( ; firstTestPos >= 0; firstTestPos-- )
1177
0
    {
1178
0
      if( zeroOutforThres && ( tuPars.m_scanId2BlkPos[firstTestPos].x >= zeroOutWidth || tuPars.m_scanId2BlkPos[firstTestPos].y >= zeroOutHeight ) ) continue;
1179
1180
0
      const TCoeff thresTmp = TCoeff( thres / ( 4 * quantCoeff[tuPars.m_scanId2BlkPos[firstTestPos].idx] ) );
1181
1182
0
      if( abs( tCoeff[tuPars.m_scanId2BlkPos[firstTestPos].idx] ) > thresTmp ) break;
1183
0
    }
1184
0
  }
1185
1.78M
  else
1186
1.78M
  {
1187
1.78M
    const TCoeff defaultTh = TCoeff( thres / ( defaultQuantisationCoefficient << 2 ) );
1188
1189
1.78M
    m_findFirstPos( firstTestPos, tCoeff, tuPars, defaultTh, zeroOutforThres, zeroOutWidth, zeroOutHeight );
1190
1.78M
  }
1191
1192
1.78M
  if( firstTestPos < 0 )
1193
1.04M
  {
1194
1.04M
    tu.lastPos[compID] = -1;
1195
1.04M
    return;
1196
1.04M
  }
1197
1198
  //===== real init =====
1199
745k
  RateEstimator::initCtx( tuPars, tu, compID, ctx.getFracBitsAcess() );
1200
745k
  m_commonCtx.reset( tuPars, *this );
1201
3.72M
  for( int k = 0; k < 4; k++ )
1202
2.98M
  {
1203
2.98M
    DQIntern::initStates( k, m_state_curr );
1204
2.98M
    DQIntern::initStates( k, m_state_skip );
1205
2.98M
    m_state_curr.m_sigFracBitsArray[k] = RateEstimator::sigFlagBits(k);
1206
2.98M
  }
1207
1208
745k
  m_state_curr.m_gtxFracBitsArray = RateEstimator::gtxFracBits();
1209
  //memset( m_state_curr.tplAcc, 0, sizeof( m_state_curr.tplAcc ) ); // will be set in updateStates{,EOS} before first access
1210
745k
  memset( m_state_curr.sum1st, 0, sizeof( m_state_curr.sum1st ) );   // will be accessed in setRiceParam before updateState{,EOS}
1211
  //memset( m_state_curr.absVal, 0, sizeof( m_state_curr.absVal ) ); // will be set in updateStates{,EOS} before first access
1212
1213
745k
  const int numCtx = isLuma( compID ) ? 21 : 11;
1214
745k
  const CoeffFracBits* const cffBits = gtxFracBits();
1215
9.23M
  for( int i = 0; i < numCtx; i++ )
1216
8.48M
  {
1217
8.48M
    m_state_curr.cffBits1[i] = cffBits[i].bits[1];
1218
8.48M
  }
1219
1220
745k
  int effectWidth  = std::min( 32, effWidth );
1221
745k
  int effectHeight = std::min( 32, effHeight );
1222
745k
  m_state_curr.initRemRegBins   = ( effectWidth * effectHeight * MAX_TU_LEVEL_CTX_CODED_BIN_CONSTRAINT ) / 16;
1223
745k
  m_state_curr.anyRemRegBinsLt4 = true; // for the first coeff use scalar impl., because it check against the init state, which
1224
                                        // prohibits some paths
1225
1226
  //===== populate trellis =====
1227
7.87M
  for( int scanIdx = firstTestPos; scanIdx >= 0; scanIdx-- )
1228
7.12M
  {
1229
7.12M
    const ScanInfo& scanInfo = tuPars.m_scanInfo[ scanIdx ];
1230
7.12M
    if( enableScalingLists )
1231
0
    {
1232
0
      m_quant.initQuantBlock( tu, compID, cQP, lambda, quantCoeff[scanInfo.rasterPos] );
1233
0
      xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos] ), scanInfo, zeroOut && ( scanInfo.posX >= effWidth || scanInfo.posY >= effHeight ), quantCoeff[scanInfo.rasterPos] );
1234
0
    }
1235
7.12M
    else
1236
7.12M
      xDecideAndUpdate( abs( tCoeff[scanInfo.rasterPos] ), scanInfo, zeroOut && ( scanInfo.posX >= effWidth || scanInfo.posY >= effHeight ), defaultQuantisationCoefficient );
1237
7.12M
  }
1238
1239
  //===== find best path =====
1240
745k
  int       prevId      = -1;
1241
745k
  int64_t   minPathCost =  0;
1242
3.72M
  for( int8_t stateId = 0; stateId < 4; stateId++ )
1243
2.98M
  {
1244
2.98M
    int64_t pathCost = m_trellis[0][0].rdCost[stateId];
1245
2.98M
    if( pathCost < minPathCost )
1246
1.27M
    {
1247
1.27M
      prevId      = stateId;
1248
1.27M
      minPathCost = pathCost;
1249
1.27M
    }
1250
2.98M
  }
1251
1252
  //===== backward scanning =====
1253
745k
  int scanIdx = 0;
1254
7.78M
  for( ; prevId >= 0; scanIdx++ )
1255
7.03M
  {
1256
7.03M
    TCoeffSig absLevel = m_trellis[scanIdx][prevId >> 2].absLevel[prevId & 3];
1257
7.03M
    int32_t blkpos     = tuPars.m_scanId2BlkPos[scanIdx].idx;
1258
7.03M
    qCoeff[ blkpos ]   = TCoeffSig( tCoeff[blkpos] < 0 ? -absLevel : absLevel );
1259
7.03M
    absSum            += absLevel;
1260
7.03M
    prevId             = m_trellis[scanIdx][prevId >> 2].prevId[prevId & 3];
1261
7.03M
  }
1262
1263
745k
  tu.lastPos[compID] = scanIdx - 1;
1264
745k
}
1265
1266
void DepQuant::xDecide( const DQIntern::ScanInfo& scanInfo, const TCoeff absCoeff, const int lastOffset, DQIntern::Decisions& decisions, bool zeroOut, int quantCoeff )
1267
7.12M
{
1268
7.12M
  using namespace DQIntern;
1269
1270
7.12M
  ::memcpy( &decisions, startDec, sizeof( Decisions ) );
1271
1272
7.12M
  StateMem& skip = m_state_skip;
1273
1274
7.12M
  if( zeroOut )
1275
0
  {
1276
0
    if( scanInfo.spt == SCAN_EOCSBB )
1277
0
    {
1278
0
      checkRdCostSkipSbbZeroOut( 0, decisions, 0, skip );
1279
0
      checkRdCostSkipSbbZeroOut( 1, decisions, 1, skip );
1280
0
      checkRdCostSkipSbbZeroOut( 2, decisions, 2, skip );
1281
0
      checkRdCostSkipSbbZeroOut( 3, decisions, 3, skip );
1282
0
    }
1283
0
    return;
1284
0
  }
1285
1286
7.12M
  StateMem& prev = m_state_curr;
1287
1288
  /// start inline prequant
1289
7.12M
  int64_t scaledOrg = int64_t( absCoeff ) * quantCoeff;
1290
7.12M
  TCoeff  qIdx      = TCoeff( ( scaledOrg + m_quant.m_QAdd ) >> m_quant.m_QShift );
1291
1292
7.12M
  if( qIdx < 0 )
1293
1.19M
  {
1294
1.19M
    int64_t scaledAdd = m_quant.m_DistStepAdd - scaledOrg * m_quant.m_DistOrgFact;
1295
1.19M
    int64_t pq_a_dist = ( ( scaledAdd + 0 * m_quant.m_DistStepAdd ) * 1 + m_quant.m_DistAdd ) >> m_quant.m_DistShift;
1296
1.19M
    int64_t pq_b_dist = ( ( scaledAdd + 1 * m_quant.m_DistStepAdd ) * 2 + m_quant.m_DistAdd ) >> m_quant.m_DistShift;
1297
    /// stop inline prequant
1298
1299
1.19M
    if( prev.anyRemRegBinsLt4 )
1300
82.4k
    {
1301
82.4k
      setRiceParam( 0, scanInfo, prev, false );
1302
82.4k
      checkRdCostsOdd1( 0, scanInfo.spt, pq_b_dist, decisions, 2, 0, prev );
1303
1304
82.4k
      setRiceParam( 1, scanInfo, prev, false );
1305
82.4k
      checkRdCostsOdd1( 1, scanInfo.spt, pq_b_dist, decisions, 0, 2, prev );
1306
1307
82.4k
      setRiceParam( 2, scanInfo, prev, false );
1308
82.4k
      checkRdCostsOdd1( 2, scanInfo.spt, pq_a_dist, decisions, 3, 1, prev );
1309
1310
82.4k
      setRiceParam( 3, scanInfo, prev, false );
1311
82.4k
      checkRdCostsOdd1( 3, scanInfo.spt, pq_a_dist, decisions, 1, 3, prev );
1312
82.4k
    }
1313
1.10M
    else
1314
1.10M
    {
1315
      // has to be called as a first check, assumes no decision has been made yet
1316
1.10M
      m_checkAllRdCostsOdd1( scanInfo.spt, pq_a_dist, pq_b_dist, decisions, prev );
1317
1.10M
    }
1318
1319
1.19M
    checkRdCostStart( lastOffset, PQData{ 1, pq_b_dist }, decisions, 2, prev );
1320
1.19M
  }
1321
5.93M
  else
1322
5.93M
  {
1323
    /// start inline prequant
1324
5.93M
    qIdx = std::max<TCoeff>( 1, std::min<TCoeff>( m_quant.m_maxQIdx, qIdx ) );
1325
5.93M
    int64_t scaledAdd = qIdx * m_quant.m_DistStepAdd - scaledOrg * m_quant.m_DistOrgFact;
1326
1327
5.93M
    PQData  pqData[4];
1328
1329
5.93M
    PQData& pq_a = pqData[( qIdx + 0 ) & 3];
1330
5.93M
    PQData& pq_b = pqData[( qIdx + 1 ) & 3];
1331
5.93M
    PQData& pq_c = pqData[( qIdx + 2 ) & 3];
1332
5.93M
    PQData& pq_d = pqData[( qIdx + 3 ) & 3];
1333
1334
5.93M
    pq_a.deltaDist = ( ( scaledAdd + 0 * m_quant.m_DistStepAdd ) * ( qIdx + 0 ) + m_quant.m_DistAdd ) >> m_quant.m_DistShift;
1335
5.93M
    pq_a.absLevel = ( qIdx + 1 ) >> 1;
1336
1337
5.93M
    pq_b.deltaDist = ( ( scaledAdd + 1 * m_quant.m_DistStepAdd ) * ( qIdx + 1 ) + m_quant.m_DistAdd ) >> m_quant.m_DistShift;
1338
5.93M
    pq_b.absLevel = ( qIdx + 2 ) >> 1;
1339
1340
5.93M
    pq_c.deltaDist = ( ( scaledAdd + 2 * m_quant.m_DistStepAdd ) * ( qIdx + 2 ) + m_quant.m_DistAdd ) >> m_quant.m_DistShift;
1341
5.93M
    pq_c.absLevel = ( qIdx + 3 ) >> 1;
1342
1343
5.93M
    pq_d.deltaDist = ( ( scaledAdd + 3 * m_quant.m_DistStepAdd ) * ( qIdx + 3 ) + m_quant.m_DistAdd ) >> m_quant.m_DistShift;
1344
5.93M
    pq_d.absLevel = ( qIdx + 4 ) >> 1;
1345
    /// stop inline prequant
1346
1347
5.93M
    bool cff02ge4 = pqData[0].absLevel >= 4/* || pqData[2].absLevel >= 4 */;
1348
5.93M
    bool cff13ge4 = /* pqData[1].absLevel >= 4 || */ pqData[3].absLevel >= 4;
1349
1350
5.93M
    if( cff02ge4 || cff13ge4 || prev.anyRemRegBinsLt4 )
1351
4.85M
    {
1352
4.85M
      if( prev.anyRemRegBinsLt4 || cff02ge4 )
1353
4.62M
      {
1354
4.62M
        setRiceParam( 0, scanInfo, prev, cff02ge4 );
1355
4.62M
        setRiceParam( 1, scanInfo, prev, cff02ge4 );
1356
4.62M
      }
1357
1358
4.85M
      if( prev.anyRemRegBinsLt4 || cff13ge4 )
1359
4.85M
      {
1360
4.85M
        setRiceParam( 2, scanInfo, prev, cff13ge4 );
1361
4.85M
        setRiceParam( 3, scanInfo, prev, cff13ge4 );
1362
4.85M
      }
1363
1364
4.85M
      checkRdCosts( 0, scanInfo.spt, pqData[0], pqData[2], decisions, 0, 2, prev );
1365
4.85M
      checkRdCosts( 1, scanInfo.spt, pqData[0], pqData[2], decisions, 2, 0, prev );
1366
4.85M
      checkRdCosts( 2, scanInfo.spt, pqData[3], pqData[1], decisions, 1, 3, prev );
1367
4.85M
      checkRdCosts( 3, scanInfo.spt, pqData[3], pqData[1], decisions, 3, 1, prev );
1368
4.85M
    }
1369
1.08M
    else
1370
1.08M
    {
1371
      // has to be called as a first check, assumes no decision has been made yet
1372
1.08M
      m_checkAllRdCosts( scanInfo.spt, pqData, decisions, prev );
1373
1.08M
    }
1374
1375
5.93M
    checkRdCostStart( lastOffset, pqData[0], decisions, 0, prev );
1376
5.93M
    checkRdCostStart( lastOffset, pqData[2], decisions, 2, prev );
1377
5.93M
  }
1378
1379
7.12M
  if( scanInfo.spt == SCAN_EOCSBB )
1380
27.2k
  {
1381
27.2k
    checkRdCostSkipSbb( 0, decisions, 0, skip );
1382
27.2k
    checkRdCostSkipSbb( 1, decisions, 1, skip );
1383
27.2k
    checkRdCostSkipSbb( 2, decisions, 2, skip );
1384
27.2k
    checkRdCostSkipSbb( 3, decisions, 3, skip );
1385
27.2k
  }
1386
7.12M
}
1387
1388
void DepQuant::xDecideAndUpdate( const TCoeff absCoeff, const DQIntern::ScanInfo& scanInfo, bool zeroOut, int quantCoeff )
1389
7.12M
{
1390
7.12M
  using namespace DQIntern;
1391
1392
7.12M
  Decisions* decisions = &m_trellis[scanInfo.scanIdx][0];
1393
1394
7.12M
  xDecide( scanInfo, absCoeff, lastOffset( scanInfo.scanIdx ), *decisions, zeroOut, quantCoeff );
1395
1396
7.12M
  if( scanInfo.scanIdx )
1397
6.38M
  {
1398
6.38M
    if( scanInfo.spt == SCAN_SOCSBB )
1399
23.9k
    {
1400
23.9k
      memcpy( &m_state_skip, &m_state_curr, DQIntern::StateMemSkipCpySize );
1401
23.9k
    }
1402
1403
6.38M
    if( scanInfo.insidePos == 0 )
1404
28.6k
    {
1405
28.6k
      m_commonCtx.swap();
1406
28.6k
      m_updateStatesEOS( scanInfo, *decisions, m_state_skip, m_state_curr, m_commonCtx );
1407
28.6k
      ::memcpy( decisions + 1, decisions, sizeof( Decisions ) );
1408
28.6k
    }
1409
6.35M
    else if( !zeroOut )
1410
6.35M
    {
1411
6.35M
      m_updateStates( scanInfo, *decisions, m_state_curr );
1412
6.35M
    }
1413
6.38M
  }
1414
7.12M
}
1415
1416
void DepQuant::xDequantDQ( const TransformUnit& tu,  CoeffBuf& recCoeff, const ComponentID compID, const QpParam& cQP, bool enableScalingLists, int* piDequantCoef )
1417
734k
{
1418
734k
  m_quant.dequantBlock( tu, compID, cQP, recCoeff, enableScalingLists, piDequantCoef );
1419
734k
}
1420
1421
18.3k
DepQuant::DepQuant( const Quant* other, bool enc, bool useScalingLists, bool enableOpt ) : QuantRDOQ2( other, useScalingLists ), RateEstimator(), m_commonCtx()
1422
18.3k
{
1423
18.3k
  const DepQuant* dq = dynamic_cast<const DepQuant*>( other );
1424
18.3k
  CHECK( other && !dq, "The DepQuant cast must be successfull!" );
1425
1426
18.3k
  if( !dq )
1427
18.3k
  {
1428
18.3k
    m_scansRom = std::make_shared<DQIntern::Rom>();
1429
18.3k
    m_scansRom->init();
1430
18.3k
  }
1431
0
  else
1432
0
  {
1433
0
    m_scansRom = dq->m_scansRom;
1434
0
  }
1435
1436
75.1M
  for( int t = 0; t < ( MAX_TB_SIZEY * MAX_TB_SIZEY ); t++ )
1437
75.1M
  {
1438
75.1M
    memcpy( m_trellis[t], startDec, sizeof( startDec ) );
1439
75.1M
  }
1440
1441
18.3k
  m_checkAllRdCosts     = DQIntern::checkAllRdCosts;
1442
18.3k
  m_checkAllRdCostsOdd1 = DQIntern::checkAllRdCostsOdd1;
1443
18.3k
  m_updateStatesEOS     = DQIntern::updateStatesEOS;
1444
18.3k
  m_updateStates        = DQIntern::updateStates;
1445
18.3k
  m_findFirstPos        = DQIntern::findFirstPos;
1446
1447
18.3k
  if( enableOpt )
1448
18.3k
  {
1449
#if defined( TARGET_SIMD_X86 ) && ENABLE_SIMD_OPT_QUANT
1450
    initDepQuantX86();
1451
#endif
1452
#if defined( TARGET_SIMD_ARM ) && ENABLE_SIMD_OPT_QUANT
1453
    initDepQuantARM();
1454
#endif
1455
18.3k
  }
1456
18.3k
}
1457
1458
DepQuant::~DepQuant()
1459
18.3k
{
1460
18.3k
}
1461
1462
void DepQuant::quant( TransformUnit& tu, const ComponentID compID, const CCoeffBuf& pSrc, TCoeff& uiAbsSum, const QpParam& cQP, const Ctx& ctx )
1463
1.88M
{
1464
1.88M
  if( tu.cs->picture->useSelectiveRdoq && !xNeedRDOQ( tu, compID, pSrc, cQP ) )
1465
0
  {
1466
0
    tu.lastPos[compID] = -1;
1467
0
    uiAbsSum           =  0;
1468
0
  }
1469
1.88M
  else if( tu.cs->slice->depQuantEnabled && tu.mtsIdx[compID] != MTS_SKIP )
1470
1.78M
  {
1471
    //===== scaling matrix ====
1472
1.78M
    const int         qpDQ            = cQP.Qp(tu.mtsIdx[compID]==MTS_SKIP) + 1;
1473
1.78M
    const int         qpPer           = qpDQ / 6;
1474
1.78M
    const int         qpRem           = qpDQ - 6 * qpPer;
1475
1.78M
    const CompArea    &rect           = tu.blocks[compID];
1476
1.78M
    const int         width           = rect.width;
1477
1.78M
    const int         height          = rect.height;
1478
1.78M
    uint32_t          scalingListType = getScalingListType(tu.cu->predMode, compID);
1479
1.78M
    CHECK(scalingListType >= SCALING_LIST_NUM, "Invalid scaling list");
1480
1.78M
    const uint32_t    log2TrWidth     = Log2(width);
1481
1.78M
    const uint32_t    log2TrHeight    = Log2(height);
1482
1.78M
    const bool isLfnstApplied         = tu.cu->lfnstIdx > 0 && (CU::isSepTree(*tu.cu) ? true : isLuma(compID));
1483
1.78M
    const bool enableScalingLists     = getUseScalingList(width, height, (tu.mtsIdx[compID] == MTS_SKIP), isLfnstApplied);
1484
1.78M
    xQuantDQ( tu, pSrc, compID, cQP, Quant::m_dLambda, ctx, uiAbsSum, enableScalingLists, Quant::getQuantCoeff(scalingListType, qpRem, log2TrWidth, log2TrHeight) );
1485
1.78M
  }
1486
96.9k
  else
1487
96.9k
  {
1488
96.9k
    QuantRDOQ2::quant( tu, compID, pSrc, uiAbsSum, cQP, ctx );
1489
96.9k
  }
1490
1.88M
}
1491
1492
void DepQuant::dequant( const TransformUnit& tu, CoeffBuf& dstCoeff, const ComponentID compID, const QpParam& cQP )
1493
780k
{
1494
780k
  if( tu.cs->slice->depQuantEnabled && (tu.mtsIdx[compID] != MTS_SKIP) )
1495
734k
  {
1496
734k
    const int         qpDQ            = cQP.Qp(tu.mtsIdx[compID]==MTS_SKIP) + 1;
1497
734k
    const int         qpPer           = qpDQ / 6;
1498
734k
    const int         qpRem           = qpDQ - 6 * qpPer;
1499
734k
    const CompArea    &rect           = tu.blocks[compID];
1500
734k
    const int         width           = rect.width;
1501
734k
    const int         height          = rect.height;
1502
734k
    uint32_t          scalingListType = getScalingListType(tu.cu->predMode, compID);
1503
734k
    CHECK(scalingListType >= SCALING_LIST_NUM, "Invalid scaling list");
1504
734k
    const uint32_t    log2TrWidth    = Log2(width);
1505
734k
    const uint32_t    log2TrHeight   = Log2(height);
1506
734k
    const bool isLfnstApplied        = tu.cu->lfnstIdx > 0 && (CU::isSepTree(*tu.cu) ? true : isLuma(compID));
1507
734k
    const bool enableScalingLists    = getUseScalingList(width, height, (tu.mtsIdx[compID] == MTS_SKIP), isLfnstApplied);
1508
734k
    xDequantDQ( tu, dstCoeff, compID, cQP, enableScalingLists, Quant::getDequantCoeff(scalingListType, qpRem, log2TrWidth, log2TrHeight) );
1509
734k
  }
1510
45.8k
  else
1511
45.8k
  {
1512
45.8k
    QuantRDOQ::dequant( tu, dstCoeff, compID, cQP );
1513
45.8k
  }
1514
780k
}
1515
1516
void DepQuant::init( int rdoq, bool useRDOQTS, int thrVal )
1517
18.3k
{
1518
18.3k
  QuantRDOQ2::init( rdoq, useRDOQTS, thrVal );
1519
18.3k
  m_quant.init( thrVal );
1520
18.3k
}
1521
1522
} // namespace vvenc
1523
1524
//! \}
1525