Coverage Report

Created: 2026-06-15 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/vvenc/source/Lib/CommonLib/Slice.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     Slice.cpp
45
    \brief    slice header and SPS class
46
*/
47
48
#include "CommonDef.h"
49
#include "Unit.h"
50
#include "Slice.h"
51
#include "Picture.h"
52
#include "UnitTools.h"
53
#include "dtrace_next.h"
54
55
//! \ingroup CommonLib
56
//! \{
57
58
namespace vvenc {
59
60
Slice::Slice()
61
1.08k
  : ppsId                               ( -1 )
62
//  , picOutputFlag                       ( true )
63
1.08k
  , poc                                 ( 0 )
64
1.08k
  , lastIDR                             ( 0 )
65
1.08k
  , prevGDRInSameLayerPOC               ( 0 )
66
1.08k
  , associatedIRAP                      ( 0 )
67
1.08k
  , associatedIRAPType                  ( VVENC_NAL_UNIT_INVALID )
68
1.08k
  , enableDRAPSEI                       ( false )
69
1.08k
  , useLTforDRAP                        ( false )
70
1.08k
  , isDRAP                              ( false )
71
1.08k
  , latestDRAPPOC                       ( 0 )
72
1.08k
  , colourPlaneId                       ( 0 )
73
1.08k
  , pictureHeaderInSliceHeader          ( true )
74
1.08k
  , nuhLayerId                          ( 0 )
75
1.08k
  , nalUnitType                         ( VVENC_NAL_UNIT_CODED_SLICE_IDR_W_RADL )
76
1.08k
  , sliceType                           ( VVENC_I_SLICE )
77
1.08k
  , sliceQp                             ( 0 )
78
1.08k
  , chromaQpAdjEnabled                  ( false )
79
1.08k
  , lmcsEnabled                         ( 0 )
80
1.08k
  , explicitScalingListUsed             ( 0 )
81
1.08k
  , deblockingFilterDisable             ( false )
82
1.08k
  , deblockingFilterOverride            ( false )
83
1.08k
  , deblockingFilterBetaOffsetDiv2      { 0 }
84
1.08k
  , deblockingFilterTcOffsetDiv2        { 0 }
85
1.08k
  , depQuantEnabled                     ( false )
86
1.08k
  , signDataHidingEnabled               ( false )
87
1.08k
  , tsResidualCodingDisabled            ( false )
88
1.08k
  , pendingRasInit                      ( false )
89
1.08k
  , checkLDC                            ( false )
90
1.08k
  , biDirPred                           ( false )
91
1.08k
  , lmChromaCheckDisable                { false }
92
1.08k
  , symRefIdx                           { -1, -1 }
93
1.08k
  , vps                                 ( nullptr )
94
1.08k
  , dci                                 ( nullptr )
95
1.08k
  , sps                                 ( nullptr )
96
1.08k
  , pps                                 ( nullptr )
97
1.08k
  , pic                                 ( nullptr )
98
1.08k
  , picHeader                           ( nullptr )
99
1.08k
  , colFromL0Flag                       ( true )
100
1.08k
  , colRefIdx                           ( 0 )
101
1.08k
  , TLayer                              ( 0 )
102
1.08k
  , TLayerSwitchingFlag                 ( false )
103
1.08k
  , independentSliceIdx                 ( 0 )
104
1.08k
  , cabacInitFlag                       ( false )
105
1.08k
  , sliceSubPicId                       ( 0 )
106
1.08k
  , encCABACTableIdx                    ( VVENC_I_SLICE )
107
1.08k
  , numAps                     ( 0 )
108
1.08k
  , chromaApsId                ( -1 )
109
1.08k
  , ccAlfCbEnabled             ( false )
110
1.08k
  , ccAlfCrEnabled             ( false )
111
1.08k
  , ccAlfCbApsId               ( -1 )
112
1.08k
  , ccAlfCrApsId               ( -1 )
113
1.08k
  , isLossless                          ( false )
114
1.08k
{
115
1.08k
  ::memset( saoEnabled,              0, sizeof( saoEnabled ) );
116
1.08k
  ::memset( numRefIdx,               0, sizeof( numRefIdx ) );
117
1.08k
  ::memset( sliceChromaQpDelta,      0, sizeof( sliceChromaQpDelta ) );
118
1.08k
  ::memset( lambdas,                 0, sizeof( lambdas ) );
119
1.08k
  ::memset( alfEnabled,              0, sizeof( alfEnabled ) );
120
1.08k
  ::memset( alfAps,                  0, sizeof( alfAps ) );
121
1.08k
  ::memset( refPicList,              0, sizeof( refPicList ) );
122
1.08k
  ::memset( refPOCList,              0, sizeof( refPOCList ) );
123
1.08k
  ::memset( isUsedAsLongTerm,        0, sizeof( isUsedAsLongTerm ) );
124
1.08k
  ::memset( ccAlfFilterControl,      0, sizeof( ccAlfFilterControl ) );
125
126
18.4k
  for ( int idx = 0; idx < MAX_NUM_REF; idx++ )
127
17.3k
  {
128
17.3k
    list1IdxToList0Idx[idx] = -1;
129
17.3k
  }
130
131
3.25k
  for ( int idx = 0; idx < NUM_REF_PIC_LIST_01; idx++ )
132
2.17k
  {
133
2.17k
    rpl[idx]                = nullptr;
134
2.17k
    rplIdx[idx]             = -1;
135
2.17k
  }
136
  
137
1.08k
  resetWpScaling();
138
1.08k
}
139
140
Slice::~Slice()
141
1.08k
{
142
1.08k
}
143
144
145
void Slice::resetSlicePart()
146
0
{
147
0
  colFromL0Flag        = true;
148
0
  colRefIdx            = 0;
149
0
  checkLDC             = false;
150
0
  biDirPred            = false;
151
0
  symRefIdx[0]         = -1;
152
0
  symRefIdx[1]         = -1;
153
0
  cabacInitFlag        = false;
154
155
0
  substreamSizes.clear();
156
157
0
  ::memset( numRefIdx,           0, sizeof( numRefIdx ) );
158
0
  ::memset( sliceChromaQpDelta,  0, sizeof( sliceChromaQpDelta ) );
159
0
  ::memset( lambdas,             0, sizeof( lambdas ) );
160
0
  ::memset( alfEnabled,          0, sizeof( alfEnabled ) );
161
162
0
  ccAlfFilterParam.reset();
163
0
  ccAlfCbEnabled = false;
164
0
  ccAlfCrEnabled = false;
165
166
0
  sliceMap = SliceMap();
167
0
}
168
169
void Slice::setDefaultClpRng( const SPS& sps )
170
1.08k
{
171
1.08k
  CHECK( sps.bitDepths[CH_L] != sps.bitDepths[CH_C], "Different luma/chroma bitdepths not supported!" );
172
173
1.08k
  clpRngs.bd = sps.bitDepths[CH_L];
174
1.08k
}
175
176
177
bool Slice::getRapPicFlag() const
178
0
{
179
0
  return nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_W_RADL
180
0
      || nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_N_LP
181
0
      || nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_CRA;
182
0
}
183
184
185
void  Slice::sortPicList        (PicList& rcListPic)
186
0
{
187
0
  Picture*    picExtract;
188
0
  Picture*    picInsert;
189
190
0
  PicList::iterator    iterPicExtract;
191
0
  PicList::iterator    iterPicExtract_1;
192
0
  PicList::iterator    iterPicInsert;
193
194
0
  for (int i = 1; i < (int)(rcListPic.size()); i++)
195
0
  {
196
0
    iterPicExtract = rcListPic.begin();
197
0
    for (int j = 0; j < i; j++)
198
0
    {
199
0
      iterPicExtract++;
200
0
    }
201
0
    picExtract = *(iterPicExtract);
202
203
0
    iterPicInsert = rcListPic.begin();
204
0
    while (iterPicInsert != iterPicExtract)
205
0
    {
206
0
      picInsert = *(iterPicInsert);
207
0
      if (picInsert->getPOC() >= picExtract->getPOC())
208
0
      {
209
0
        break;
210
0
      }
211
212
0
      iterPicInsert++;
213
0
    }
214
215
0
    iterPicExtract_1 = iterPicExtract;    iterPicExtract_1++;
216
217
    //  swap iterPicExtract and iterPicInsert, iterPicExtract = curr. / iterPicInsert = insertion position
218
0
    rcListPic.insert( iterPicInsert, iterPicExtract, iterPicExtract_1 );
219
0
    rcListPic.erase( iterPicExtract );
220
0
  }
221
0
}
222
223
224
Picture* Slice::xGetLongTermRefPic( const PicList& rcListPic, int poc, bool pocHasMsb)
225
0
{
226
0
  PicList::const_iterator  iterPic = rcListPic.begin();
227
0
  Picture*           picCand = *(iterPic);
228
0
  Picture*           pcStPic = picCand;
229
230
0
  int pocCycle = 1 << sps->bitsForPOC;
231
0
  if (!pocHasMsb)
232
0
  {
233
0
    poc = poc & (pocCycle - 1);
234
0
  }
235
236
0
  while ( iterPic != rcListPic.end() )
237
0
  {
238
0
    picCand = *(iterPic);
239
0
    if (picCand && picCand->poc != this->poc && picCand->isReferenced)
240
0
    {
241
0
      int picPoc = picCand->poc;
242
0
      if (!pocHasMsb)
243
0
      {
244
0
        picPoc = picPoc & (pocCycle - 1);
245
0
      }
246
247
0
      if (poc == picPoc)
248
0
      {
249
0
        if(picCand->isLongTerm)
250
0
        {
251
0
          return picCand;
252
0
        }
253
254
0
        pcStPic = picCand;
255
0
        break;
256
0
      }
257
0
    }
258
259
0
    iterPic++;
260
0
  }
261
262
0
  return pcStPic;
263
0
}
264
265
void Slice::setRefPOCList       ()
266
1.08k
{
267
3.25k
  for (int iDir = 0; iDir < NUM_REF_PIC_LIST_01; iDir++)
268
2.17k
  {
269
2.17k
    for (int iNumRefIdx = 0; iNumRefIdx < numRefIdx[iDir]; iNumRefIdx++)
270
0
    {
271
0
      refPOCList[iDir][iNumRefIdx] = refPicList[iDir][iNumRefIdx]->getPOC();
272
0
    }
273
2.17k
  }
274
275
1.08k
}
276
277
void Slice::setSMVDParam()
278
1.08k
{
279
1.08k
  if ( sps->SMVD && checkLDC == false && picHeader->mvdL1Zero == false )
280
1.08k
  {
281
1.08k
    int currPOC  = poc;
282
1.08k
    int forwardPOC = poc;
283
1.08k
    int backwardPOC = poc;
284
1.08k
    int ref = 0;
285
1.08k
    int refIdx0 = -1;
286
1.08k
    int refIdx1 = -1;
287
288
    // search nearest forward POC in List 0
289
1.08k
    for (ref = 0; ref < numRefIdx[REF_PIC_LIST_0]; ref++)
290
0
    {
291
0
      const int refPoc = getRefPic(REF_PIC_LIST_0, ref)->getPOC();
292
0
      const bool isRefLongTerm = getRefPic(REF_PIC_LIST_0, ref)->isLongTerm;
293
0
      if (refPoc < currPOC && (refPoc > forwardPOC || refIdx0 == -1) && !isRefLongTerm)
294
0
      {
295
0
        forwardPOC = refPoc;
296
0
        refIdx0 = ref;
297
0
      }
298
0
    }
299
300
    // search nearest backward POC in List 1
301
1.08k
    for (ref = 0; ref < numRefIdx[REF_PIC_LIST_1]; ref++)
302
0
    {
303
0
      const int refPoc = getRefPic(REF_PIC_LIST_1, ref)->getPOC();
304
0
      const bool isRefLongTerm = getRefPic(REF_PIC_LIST_1, ref)->isLongTerm;
305
0
      if (refPoc > currPOC && (refPoc < backwardPOC || refIdx1 == -1) && !isRefLongTerm)
306
0
      {
307
0
        backwardPOC = refPoc;
308
0
        refIdx1 = ref;
309
0
      }
310
0
    }
311
312
1.08k
    if (!(forwardPOC < currPOC && backwardPOC > currPOC))
313
1.08k
    {
314
1.08k
      forwardPOC = currPOC;
315
1.08k
      backwardPOC = currPOC;
316
1.08k
      refIdx0 = -1;
317
1.08k
      refIdx1 = -1;
318
319
      // search nearest backward POC in List 0
320
1.08k
      for (ref = 0; ref < numRefIdx[REF_PIC_LIST_0]; ref++)
321
0
      {
322
0
        const int refPoc = getRefPic(REF_PIC_LIST_0, ref)->getPOC();
323
0
        const bool isRefLongTerm = getRefPic(REF_PIC_LIST_0, ref)->isLongTerm;
324
0
        if (refPoc > currPOC && (refPoc < backwardPOC || refIdx0 == -1) && !isRefLongTerm)
325
0
        {
326
0
          backwardPOC = refPoc;
327
0
          refIdx0 = ref;
328
0
        }
329
0
      }
330
331
      // search nearest forward POC in List 1
332
1.08k
      for (ref = 0; ref < numRefIdx[REF_PIC_LIST_1]; ref++)
333
0
      {
334
0
        const int refPoc = getRefPic(REF_PIC_LIST_1, ref)->getPOC();
335
0
        const bool isRefLongTerm = getRefPic(REF_PIC_LIST_1, ref)->isLongTerm;
336
0
        if (refPoc < currPOC && (refPoc > forwardPOC || refIdx1 == -1) && !isRefLongTerm)
337
0
        {
338
0
          forwardPOC = refPoc;
339
0
          refIdx1 = ref;
340
0
        }
341
0
      }
342
1.08k
    }
343
344
1.08k
    if (forwardPOC < currPOC && backwardPOC > currPOC)
345
0
    {
346
0
      biDirPred    = true;
347
0
      symRefIdx[0] = refIdx0;
348
0
      symRefIdx[1] = refIdx1;
349
0
      return;
350
0
    }
351
1.08k
  }
352
353
1.08k
  biDirPred    = false;
354
1.08k
  symRefIdx[0] = -1;
355
1.08k
  symRefIdx[1] = -1;
356
1.08k
}
357
358
void Slice::setList1IdxToList0Idx()
359
1.08k
{
360
1.08k
  int idxL0, idxL1;
361
1.08k
  for ( idxL1 = 0; idxL1 < numRefIdx[ REF_PIC_LIST_1 ]; idxL1++ )
362
0
  {
363
0
    list1IdxToList0Idx[idxL1] = -1;
364
0
    for ( idxL0 = 0; idxL0 < numRefIdx[ REF_PIC_LIST_0 ]; idxL0++ )
365
0
    {
366
0
      if ( refPicList[REF_PIC_LIST_0][idxL0]->getPOC() == refPicList[REF_PIC_LIST_1][idxL1]->getPOC() )
367
0
      {
368
0
        list1IdxToList0Idx[idxL1] = idxL0;
369
0
        break;
370
0
      }
371
0
    }
372
0
  }
373
1.08k
}
374
375
void Slice::constructRefPicList(const PicList& rcListPic, bool extBorder, const bool usingLongTerm)
376
1.08k
{
377
1.08k
  ::memset(isUsedAsLongTerm, 0, sizeof(isUsedAsLongTerm));
378
1.08k
  if (sliceType == VVENC_I_SLICE)
379
1.08k
  {
380
1.08k
    ::memset(refPicList, 0, sizeof(refPicList));
381
1.08k
    ::memset(numRefIdx, 0, sizeof(numRefIdx));
382
1.08k
    return;
383
1.08k
  }
384
385
0
  Picture*  pcRefPic = NULL;
386
0
  uint32_t numOfActiveRef = 0;
387
  //construct L0
388
0
  for (int refList = 0; refList < NUM_REF_PIC_LIST_01; refList++)
389
0
  {
390
0
    RefPicList eRefList = RefPicList(refList);
391
0
    numOfActiveRef = numRefIdx[ eRefList ];
392
0
    for (int ii = 0; ii < numOfActiveRef; ii++)
393
0
    {
394
0
      if (!rpl[eRefList]->isLongtermRefPic[ii])
395
0
      {
396
0
        int poc_ = poc + rpl[eRefList]->refPicIdentifier[ii];
397
398
0
        PicList::const_iterator  iterPic = rcListPic.begin();
399
0
        pcRefPic   = *(iterPic);
400
401
0
        while ( iterPic != rcListPic.end() )
402
0
        {
403
0
          if(pcRefPic->getPOC() == poc_)
404
0
          {
405
0
            break;
406
0
          }
407
0
          iterPic++;
408
0
          pcRefPic = *(iterPic);
409
0
        }
410
411
0
        if(usingLongTerm)
412
0
          pcRefPic->isLongTerm = false;
413
0
      }
414
0
      else
415
0
      {
416
0
        CHECK(!usingLongTerm, "Wrong state: using long term when it's not supported by the encoder configuration");
417
0
        int pocBits = sps->bitsForPOC;
418
0
        int pocMask = (1 << pocBits) - 1;
419
0
        int ltrpPoc = rpl[eRefList]->refPicIdentifier[ii] & pocMask;
420
0
        ltrpPoc += rpl[eRefList]->deltaPocMSBPresent[ii] ? (pocMask + 1) * rpl[eRefList]->deltaPocMSBCycleLT[ii] : 0;
421
0
        pcRefPic = xGetLongTermRefPic(rcListPic, ltrpPoc, rpl[eRefList]->deltaPocMSBPresent[ii]);
422
0
        pcRefPic->isLongTerm = true;
423
0
      }
424
0
      if ( extBorder )
425
0
      {
426
0
        pcRefPic->extendPicBorder();
427
0
      }
428
0
      refPicList[eRefList][ii] = pcRefPic;
429
0
      isUsedAsLongTerm[eRefList][ii] = usingLongTerm ? pcRefPic->isLongTerm: false;
430
0
    }
431
0
  }
432
0
}
433
434
void Slice::updateRefPicCounter( int step )
435
2.17k
{
436
6.51k
  for ( int refList = 0; refList < NUM_REF_PIC_LIST_01; refList++ )
437
4.34k
  {
438
4.34k
    int numOfActiveRef = numRefIdx[ refList ];
439
4.34k
    for ( int i = 0; i < numOfActiveRef; i++ )
440
0
    {
441
0
      refPicList[ refList ][ i ]->refCounter += step;
442
0
    }
443
4.34k
  }
444
2.17k
}
445
446
bool Slice::checkAllRefPicsReconstructed() const
447
1.08k
{
448
3.25k
  for ( int refList = 0; refList < NUM_REF_PIC_LIST_01; refList++ )
449
2.17k
  {
450
2.17k
    int numOfActiveRef = numRefIdx[ refList ];
451
2.17k
    for ( int i = 0; i < numOfActiveRef; i++ )
452
0
    {
453
0
      if ( ! refPicList[ refList ][ i ]->isReconstructed )
454
0
      {
455
0
        return false;
456
0
      }
457
0
    }
458
2.17k
  }
459
460
1.08k
  return true;
461
1.08k
}
462
463
bool Slice::checkAllRefPicsAccessible() const
464
0
{
465
0
  for ( int refList = 0; refList < NUM_REF_PIC_LIST_01; refList++ )
466
0
  {
467
0
    int numOfActiveRef = numRefIdx[ refList ];
468
0
    for ( int i = 0; i < numOfActiveRef; i++ )
469
0
    {
470
0
      if ( ! refPicList[ refList ][ i ]->isInProcessList )
471
0
      {
472
0
        return false;
473
0
      }
474
0
    }
475
0
  }
476
477
0
  return true;
478
0
}
479
480
void Slice::checkColRefIdx(uint32_t curSliceSegmentIdx, const Picture* pic) const
481
0
{
482
0
  Slice* curSlice   = pic->slices[ curSliceSegmentIdx ];
483
0
  int currColRefPOC =  curSlice->getRefPOC( RefPicList( 1 - curSlice->colFromL0Flag ), curSlice->colRefIdx );
484
485
0
  for( int i = curSliceSegmentIdx - 1; i >= 0; i-- )
486
0
  {
487
0
    const Slice* preSlice = pic->slices[i];
488
0
    if( preSlice->sliceType != VVENC_I_SLICE )
489
0
    {
490
0
      const int preColRefPOC  = preSlice->getRefPOC( RefPicList( 1 - preSlice->colFromL0Flag ), preSlice->colRefIdx );
491
0
      if( currColRefPOC != preColRefPOC )
492
0
      {
493
0
        THROW( "Collocated_ref_idx shall always be the same for all slices of a coded picture!" );
494
0
      }
495
0
      else
496
0
      {
497
0
        break;
498
0
      }
499
0
    }
500
0
  }
501
0
}
502
503
void Slice::checkCRA(const ReferencePictureList* pRPL0, const ReferencePictureList* pRPL1, int& pocCRA, vvencNalUnitType& associatedIRAPType, PicList& rcListPic)
504
0
{
505
0
  if (pocCRA < MAX_UINT && poc > pocCRA)
506
0
  {
507
0
    uint32_t numRefPic = pRPL0->numberOfShorttermPictures + pRPL0->numberOfLongtermPictures;
508
0
    for (int i = 0; i < numRefPic; i++)
509
0
    {
510
0
      if (!pRPL0->isLongtermRefPic[i])
511
0
      {
512
0
        CHECK(poc + pRPL0->refPicIdentifier[i] < pocCRA, "Invalid state");
513
0
      }
514
0
      else
515
0
      {
516
0
        CHECK(xGetLongTermRefPic(rcListPic, pRPL0->refPicIdentifier[i], pRPL0->deltaPocMSBPresent[i])->getPOC() < pocCRA, "Invalid state");
517
0
      }
518
0
    }
519
0
    numRefPic = pRPL1->numberOfShorttermPictures + pRPL1->numberOfLongtermPictures;
520
0
    for (int i = 0; i < numRefPic; i++)
521
0
    {
522
0
      if (!pRPL1->isLongtermRefPic[i])
523
0
      {
524
0
        CHECK(poc + pRPL1->refPicIdentifier[i] < pocCRA, "Invalid state");
525
0
      }
526
0
      else
527
0
      {
528
0
        CHECK(xGetLongTermRefPic(rcListPic, pRPL1->refPicIdentifier[i], pRPL1->deltaPocMSBPresent[i])->getPOC() < pocCRA, "Invalid state");
529
0
      }
530
0
    }
531
0
  }
532
0
  if (nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_W_RADL || nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_N_LP) // IDR picture found
533
0
  {
534
0
    pocCRA = poc;
535
0
    associatedIRAPType = nalUnitType;
536
0
  }
537
0
  else if (nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_CRA) // CRA picture found
538
0
  {
539
0
    pocCRA = poc;
540
0
    associatedIRAPType = nalUnitType;
541
0
  }
542
0
}
543
544
/** Function for marking the reference pictures when an IDR/CRA/CRANT/BLA/BLANT is encountered.
545
 * \param pocCRA POC of the CRA/CRANT/BLA/BLANT picture
546
 * \param bRefreshPending flag indicating if a deferred decoding refresh is pending
547
 * \param rcListPic reference to the reference picture list
548
 * This function marks the reference pictures as "unused for reference" in the following conditions.
549
 * If the nal_unit_type is IDR/BLA/BLANT, all pictures in the reference picture list
550
 * are marked as "unused for reference"
551
 *    If the nal_unit_type is BLA/BLANT, set the pocCRA to the temporal reference of the current picture.
552
 * Otherwise
553
 *    If the bRefreshPending flag is true (a deferred decoding refresh is pending) and the current
554
 *    temporal reference is greater than the temporal reference of the latest CRA/CRANT/BLA/BLANT picture (pocCRA),
555
 *    mark all reference pictures except the latest CRA/CRANT/BLA/BLANT picture as "unused for reference" and set
556
 *    the bRefreshPending flag to false.
557
 *    If the nal_unit_type is CRA/CRANT, set the bRefreshPending flag to true and pocCRA to the temporal
558
 *    reference of the current picture.
559
 * Note that the current picture is already placed in the reference list and its marking is not changed.
560
 * If the current picture has a nal_ref_idc that is not 0, it will remain marked as "used for reference".
561
 */
562
void Slice::setDecodingRefreshMarking( int& pocCRA, bool& bRefreshPending, const PicList& rcListPic )
563
1.08k
{
564
1.08k
  const bool bEfficientFieldIRAPEnabled = true;
565
1.08k
  Picture* rpcPic;
566
1.08k
  int      pocCurr = poc;
567
568
1.08k
  if ( nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_W_RADL
569
0
    || nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_N_LP)  // IDR picture
570
1.08k
  {
571
    // mark all pictures as not used for reference
572
1.08k
    PicList::const_iterator iterPic = rcListPic.begin();
573
2.17k
    while (iterPic != rcListPic.end())
574
1.08k
    {
575
1.08k
      rpcPic = *(iterPic);
576
1.08k
      if (rpcPic->getPOC() != pocCurr)
577
0
      {
578
0
        rpcPic->isReferenced = false;
579
0
      }
580
1.08k
      iterPic++;
581
1.08k
    }
582
1.08k
    if (bEfficientFieldIRAPEnabled)
583
1.08k
    {
584
1.08k
      bRefreshPending = true;
585
1.08k
    }
586
1.08k
  }
587
0
  else // CRA or No DR
588
0
  {
589
0
    if(bEfficientFieldIRAPEnabled && (associatedIRAPType == VVENC_NAL_UNIT_CODED_SLICE_IDR_N_LP || associatedIRAPType == VVENC_NAL_UNIT_CODED_SLICE_IDR_W_RADL))
590
0
    {
591
0
      if (bRefreshPending==true && pocCurr > lastIDR) // IDR reference marking pending
592
0
      {
593
0
        PicList::const_iterator iterPic = rcListPic.begin();
594
0
        while (iterPic != rcListPic.end())
595
0
        {
596
0
          rpcPic = *(iterPic);
597
0
          if (rpcPic->getPOC() != pocCurr && rpcPic->getPOC() != lastIDR)
598
0
          {
599
0
            rpcPic->isReferenced = false;
600
0
          }
601
0
          iterPic++;
602
0
        }
603
0
        bRefreshPending = false;
604
0
      }
605
0
    }
606
0
    else
607
0
    {
608
0
      if (bRefreshPending==true && pocCurr > pocCRA) // CRA reference marking pending
609
0
      {
610
0
        PicList::const_iterator iterPic = rcListPic.begin();
611
0
        while (iterPic != rcListPic.end())
612
0
        {
613
0
          rpcPic = *(iterPic);
614
0
          if (rpcPic->getPOC() != pocCurr && rpcPic->getPOC() != pocCRA)
615
0
          {
616
0
            rpcPic->isReferenced = false;
617
0
          }
618
0
          iterPic++;
619
0
        }
620
0
        bRefreshPending = false;
621
0
      }
622
0
    }
623
0
    if ( nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_CRA ) // CRA picture found
624
0
    {
625
0
      bRefreshPending = true;
626
0
      pocCRA = pocCurr;
627
0
    }
628
0
  }
629
1.08k
}
630
631
void Slice::copySliceInfo( const Slice* slice, bool cpyAlmostAll)
632
0
{
633
0
  CHECK(!slice, "Source is NULL");
634
635
0
  int i, j;
636
637
0
  poc                             = slice->poc;
638
0
  nalUnitType                     = slice->nalUnitType;
639
0
  sliceType                       = slice->sliceType;
640
0
  sliceQp                         = slice->sliceQp;
641
0
  chromaQpAdjEnabled              = slice->chromaQpAdjEnabled;
642
0
  deblockingFilterDisable         = slice->deblockingFilterDisable;
643
0
  deblockingFilterOverride        = slice->deblockingFilterOverride;
644
0
  for( int comp = 0; comp < MAX_NUM_COMP; comp++ )
645
0
  {
646
0
    deblockingFilterBetaOffsetDiv2[comp]  = slice->deblockingFilterBetaOffsetDiv2[comp];
647
0
    deblockingFilterTcOffsetDiv2[comp]    = slice->deblockingFilterTcOffsetDiv2[comp];
648
0
  }
649
650
0
  for (i = 0; i < NUM_REF_PIC_LIST_01; i++)
651
0
  {
652
0
    numRefIdx[i] = slice->numRefIdx[i];
653
0
  }
654
655
0
  for (i = 0; i < MAX_NUM_REF; i++)
656
0
  {
657
0
    list1IdxToList0Idx[i] = slice->list1IdxToList0Idx[i];
658
0
  }
659
660
0
  checkLDC      = slice->checkLDC;
661
662
0
  biDirPred     = slice->biDirPred;
663
0
  symRefIdx[0]  = slice->symRefIdx[0];
664
0
  symRefIdx[1]  = slice->symRefIdx[1];
665
666
0
  for (uint32_t component = 0; component < MAX_NUM_COMP; component++)
667
0
  {
668
0
    sliceChromaQpDelta[component] = slice->sliceChromaQpDelta[component];
669
0
  }
670
0
  sliceChromaQpDelta[COMP_JOINT_CbCr] = slice->sliceChromaQpDelta[COMP_JOINT_CbCr];
671
0
  if( cpyAlmostAll )
672
0
  {
673
0
    for( i = 0; i < NUM_REF_PIC_LIST_01; i++ )
674
0
    {
675
0
      for( j = 0; j < MAX_NUM_REF; j++ )
676
0
      {
677
0
        refPicList[i][j] = slice->refPicList[i][j];
678
0
        refPOCList[i][j] = slice->refPOCList[i][j];
679
0
        isUsedAsLongTerm[i][j] = slice->isUsedAsLongTerm[i][j];
680
0
      }
681
0
      isUsedAsLongTerm[i][MAX_NUM_REF] = slice->isUsedAsLongTerm[i][MAX_NUM_REF];
682
0
    }
683
0
  }
684
685
  // access channel
686
0
  if (cpyAlmostAll) rpl[0] = slice->rpl[0];
687
0
  if (cpyAlmostAll) rpl[1] = slice->rpl[1];
688
0
  lastIDR             = slice->lastIDR;
689
690
0
  if( cpyAlmostAll ) pic  = slice->pic;
691
692
0
  colFromL0Flag        = slice->colFromL0Flag;
693
0
  colRefIdx            = slice->colRefIdx;
694
695
0
  if( cpyAlmostAll ) setLambdas(slice->getLambdas());
696
697
0
  TLayer                        = slice->TLayer;
698
0
  TLayerSwitchingFlag           = slice->TLayerSwitchingFlag;
699
0
  independentSliceIdx           = slice->independentSliceIdx;
700
0
  clpRngs                       = slice->clpRngs;
701
0
  lmcsEnabled                   = slice->lmcsEnabled;
702
0
  explicitScalingListUsed       = slice->explicitScalingListUsed;
703
0
  pendingRasInit                = slice->pendingRasInit;
704
705
0
  for( uint32_t ch = 0 ; ch < MAX_NUM_CH; ch++)
706
0
  {
707
0
    saoEnabled[ch] = slice->saoEnabled[ch];
708
0
  }
709
710
0
  cabacInitFlag                 = slice->cabacInitFlag;
711
0
  memcpy( alfAps, slice->alfAps, sizeof(alfAps)); // this might be quite unsafe
712
0
  memcpy( alfEnabled, slice->alfEnabled, sizeof(alfEnabled));
713
0
  numAps               = slice->numAps;
714
0
  lumaApsId            = slice->lumaApsId;
715
0
  chromaApsId          = slice->chromaApsId;
716
0
  isLossless                    = slice->isLossless;
717
718
0
  sliceMap                      = slice->sliceMap;
719
720
0
  ccAlfFilterParam              = slice->ccAlfFilterParam;
721
0
  ccAlfFilterControl[0]         = slice->ccAlfFilterControl[0];
722
0
  ccAlfFilterControl[1]         = slice->ccAlfFilterControl[1];
723
0
  ccAlfCbEnabled       = slice->ccAlfCbEnabled;
724
0
  ccAlfCrEnabled       = slice->ccAlfCrEnabled;
725
0
  ccAlfCbApsId         = slice->ccAlfCbApsId;
726
0
  ccAlfCrApsId         = slice->ccAlfCrApsId;
727
728
0
  if( cpyAlmostAll ) encCABACTableIdx  = slice->encCABACTableIdx;
729
0
}
730
731
/** Function for checking if this is a STSA candidate
732
 */
733
bool Slice::isStepwiseTemporalLayerSwitchingPointCandidate(const PicList& rcListPic) const
734
0
{
735
0
  PicList::const_iterator iterPic = rcListPic.begin();
736
0
  while ( iterPic != rcListPic.end())
737
0
  {
738
0
    const Picture* pic = *(iterPic++);
739
0
    if( pic->isInitDone && pic->isReferenced && pic->poc != poc)
740
0
    {
741
0
      if( pic->TLayer >= TLayer)
742
0
      {
743
0
        return false;
744
0
      }
745
0
    }
746
0
  }
747
0
  return true;
748
0
}
749
750
751
void Slice::checkLeadingPictureRestrictions(const PicList& rcListPic) const
752
1.08k
{
753
  // When a picture is a leading picture, it shall be a RADL or RASL picture.
754
1.08k
  if(associatedIRAP > poc && !pps->mixedNaluTypesInPic)
755
0
  {
756
    // Do not check IRAP pictures since they may get a POC lower than their associated IRAP
757
0
    if (nalUnitType < VVENC_NAL_UNIT_CODED_SLICE_IDR_W_RADL ||
758
0
        nalUnitType > VVENC_NAL_UNIT_CODED_SLICE_CRA)
759
0
    {
760
0
      CHECK(nalUnitType != VVENC_NAL_UNIT_CODED_SLICE_RASL &&
761
0
            nalUnitType != VVENC_NAL_UNIT_CODED_SLICE_RADL, "Invalid NAL unit type");
762
0
    }
763
0
  }
764
765
  // When a picture is a trailing picture, it shall not be a RADL or RASL picture.
766
1.08k
  if(associatedIRAP < poc && !pps->mixedNaluTypesInPic)
767
0
  {
768
0
    CHECK(nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_RASL ||
769
0
          nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_RADL, "Invalid NAL unit type");
770
0
  }
771
772
773
  // No RASL pictures shall be present in the bitstream that are associated with
774
  // an IDR picture.
775
1.08k
  if (nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_RASL)
776
0
  {
777
0
    CHECK( associatedIRAPType == VVENC_NAL_UNIT_CODED_SLICE_IDR_N_LP   ||
778
0
           associatedIRAPType == VVENC_NAL_UNIT_CODED_SLICE_IDR_W_RADL, "Invalid NAL unit type");
779
0
  }
780
781
  // No RADL pictures shall be present in the bitstream that are associated with
782
  // a BLA picture having nal_unit_type equal to BLA_N_LP or that are associated
783
  // with an IDR picture having nal_unit_type equal to IDR_N_LP.
784
1.08k
  if (nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_RADL)
785
0
  {
786
0
    CHECK (associatedIRAPType == VVENC_NAL_UNIT_CODED_SLICE_IDR_N_LP, "Invalid NAL unit type");
787
0
  }
788
789
  // loop through all pictures in the reference picture buffer
790
1.08k
  PicList::const_iterator iterPic = rcListPic.begin();
791
2.17k
  while ( iterPic != rcListPic.end())
792
1.08k
  {
793
1.08k
    Picture* pic = *(iterPic++);
794
1.08k
    if( ! pic->isReconstructed )
795
1.08k
    {
796
1.08k
      continue;
797
1.08k
    }
798
0
    if( pic->poc == poc)
799
0
    {
800
0
      continue;
801
0
    }
802
0
    const Slice* slice = pic->slices[0];
803
804
0
    if (slice->picHeader->picOutputFlag == 1 && !picHeader->noOutputOfPriorPics && pic->layerId == nuhLayerId)
805
0
    {
806
0
      if (nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_CRA || nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_N_LP || nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_W_RADL)
807
0
      {
808
0
        CHECK(pic->poc >= poc, "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes an IRAP picture with nuh_layer_id "
809
0
              "equal to layerId in decoding order shall precede the IRAP picture in output order.");
810
0
      }
811
0
    }
812
813
0
    if (slice->picHeader->picOutputFlag == 1 && !picHeader->noOutputBeforeRecovery && pic->layerId == nuhLayerId)
814
0
    {
815
0
      if (poc == picHeader->recoveryPocCnt + prevGDRInSameLayerPOC)
816
0
      {
817
0
        CHECK(pic->poc >= poc, "Any picture, with nuh_layer_id equal to a particular value layerId, that precedes a recovery point picture with "
818
0
              "nuh_layer_id equal to layerId in decoding order shall precede the recovery point picture in output order.");
819
0
      }
820
0
    }
821
822
0
    if (nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_RASL)
823
0
    {
824
0
      if ((associatedIRAPType == VVENC_NAL_UNIT_CODED_SLICE_CRA) &&
825
0
          associatedIRAP == slice->associatedIRAP)
826
0
      {
827
0
        if (slice->nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_RADL)
828
0
        {
829
0
          CHECK(pic->poc <= poc, "Any RASL picture associated with a CRA picture shall precede any RADL picture associated with the CRA picture in output order.");
830
0
        }
831
0
      }
832
0
    }
833
834
0
    if (nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_RASL)
835
0
    {
836
0
      if(associatedIRAPType == VVENC_NAL_UNIT_CODED_SLICE_CRA)
837
0
      {
838
0
        if(slice->poc < associatedIRAP &&
839
0
          (
840
0
            slice->nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_N_LP   ||
841
0
            slice->nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_W_RADL ||
842
0
            slice->nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_CRA ||
843
0
            slice->nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_GDR) &&
844
0
            pic->layerId == nuhLayerId)
845
0
        {
846
0
          CHECK(poc <= slice->poc, "Any RASL picture, with nuh_layer_id equal to a particular value layerId, associated with a CRA picture shall follow, "
847
0
               "in output order, any IRAP or GDR picture with nuh_layer_id equal to layerId that precedes the CRA picture in decoding order.");
848
0
        }
849
0
      }
850
0
    }
851
0
  }
852
1.08k
}
853
854
855
//Function for applying picture marking based on the Reference Picture List
856
void Slice::applyReferencePictureListBasedMarking(const PicList& rcListPic, const ReferencePictureList* pRPL0, const ReferencePictureList* pRPL1, const int layerId, const PPS& pps, const bool usingLongTerm ) const
857
1.08k
{
858
1.08k
  int i, isReference;
859
1.08k
  checkLeadingPictureRestrictions(rcListPic);
860
861
1.08k
  bool isNeedToCheck = ( nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_N_LP || nalUnitType == VVENC_NAL_UNIT_CODED_SLICE_IDR_W_RADL ) ? false : true;
862
863
  // loop through all pictures in the reference picture buffer
864
1.08k
  PicList::const_iterator iterPic = rcListPic.begin();
865
2.17k
  while( iterPic != rcListPic.end() )
866
1.08k
  {
867
1.08k
    Picture* pic = *( iterPic++ );
868
869
1.08k
    if( !pic->isReferenced )
870
0
      continue;
871
872
1.08k
    isReference = 0;
873
    // loop through all pictures in the Reference Picture Set
874
    // to see if the picture should be kept as reference picture
875
1.08k
    for( i = 0; isNeedToCheck && !isReference && i < pRPL0->numberOfShorttermPictures + pRPL0->numberOfLongtermPictures + pRPL0->numberOfInterLayerPictures; i++ )
876
0
    {
877
0
      if( pRPL0->isInterLayerRefPic[ i ] )
878
0
      {
879
        // Diagonal inter-layer prediction is not allowed
880
0
        CHECK( pRPL0->refPicIdentifier[i], "ILRP identifier should be 0" );
881
882
0
        if( pic->poc == poc )
883
0
        {
884
0
          isReference = 1;
885
0
          if( usingLongTerm && !pic->isLongTerm ) pic->isLongTerm = true;
886
0
        }
887
0
      }
888
0
      else if( pic->layerId == layerId )
889
0
      {
890
0
        if( !pRPL0->isLongtermRefPic[i] )
891
0
        {
892
0
          if( pic->poc == poc + pRPL0->refPicIdentifier[i] )
893
0
          {
894
0
            isReference = 1;
895
0
            if( usingLongTerm && pic->isLongTerm ) pic->isLongTerm = false;
896
0
          }
897
0
        }
898
0
        else
899
0
        {
900
0
          int pocCycle = 1 << (pic->cs->sps->bitsForPOC);
901
0
          int curPoc = pic->poc & (pocCycle - 1);
902
0
          if( usingLongTerm && pic->isLongTerm && curPoc == pRPL0->refPicIdentifier[i] )
903
0
          {
904
0
            isReference = 1;
905
0
          }
906
0
        }
907
0
      }
908
0
    }
909
1.08k
    for( i = 0; isNeedToCheck && !isReference && i < pRPL1->numberOfShorttermPictures + pRPL1->numberOfLongtermPictures + pRPL1->numberOfInterLayerPictures; i++ )
910
0
    {
911
0
      if( pRPL1->isInterLayerRefPic[i] )
912
0
      {
913
        // Diagonal inter-layer prediction is not allowed
914
0
        CHECK( pRPL1->refPicIdentifier[i], "ILRP identifier should be 0" );
915
916
0
        if( pic->poc == poc )
917
0
        {
918
0
          isReference = 1;
919
0
          if( usingLongTerm && !pic->isLongTerm ) pic->isLongTerm = true;
920
0
        }
921
0
      }
922
0
      else if( pic->layerId == layerId )
923
0
      {
924
0
        if( !pRPL1->isLongtermRefPic[i] )
925
0
        {
926
0
          if( pic->poc == poc + pRPL1->refPicIdentifier[i] )
927
0
          {
928
0
            isReference = 1;
929
0
            if( usingLongTerm && pic->isLongTerm ) pic->isLongTerm = false;
930
0
          }
931
0
        }
932
0
        else
933
0
        {
934
0
          int pocCycle = 1 << ( pic->cs->sps->bitsForPOC );
935
0
          int curPoc = pic->poc & ( pocCycle - 1 );
936
0
          if( usingLongTerm && pic->isLongTerm && curPoc == pRPL1->refPicIdentifier[i] )
937
0
          {
938
0
            isReference = 1;
939
0
          }
940
0
        }
941
0
      }
942
0
    }
943
    // mark the picture as "unused for reference" if it is not in
944
    // the Reference Picture List
945
1.08k
    if ( pic->layerId == layerId && pic->isInitDone && pic->poc != poc && isReference == 0 )
946
0
    {
947
0
      pic->isReferenced = false;
948
0
      if( usingLongTerm )
949
0
        pic->isLongTerm   = false;
950
0
    }
951
1.08k
  }
952
1.08k
}
953
954
// int Slice::checkThatAllRefPicsAreAvailable( const PicList& rcListPic, const ReferencePictureList *pRPL, int rplIdx ) const
955
bool Slice::isRplPicMissing( const PicList& rcListPic, const RefPicList refList, int& missingPoc, int ip ) const
956
2.17k
{
957
2.17k
  if( isIDRorBLA() ) return false; // assume that all pic in the DPB will be flushed anyway so no need to check.
958
959
0
  const ReferencePictureList* pRPL = rpl[ refList ];
960
0
  int numberOfPictures             = pRPL->numberOfLongtermPictures + pRPL->numberOfShorttermPictures + pRPL->numberOfInterLayerPictures;
961
962
  // check long term ref pics
963
0
  if( pRPL->numberOfLongtermPictures > 0 )
964
0
  {
965
0
    for( int ii = 0; ii < numberOfPictures; ii++ )
966
0
    {
967
0
      if( ! pRPL->isLongtermRefPic[ii] || pRPL->isInterLayerRefPic[ii] )
968
0
        continue;
969
970
0
      bool isAvailable = false;
971
0
      int  checkPoc    = pRPL->refPicIdentifier[ii];
972
973
0
      for( auto& pic : rcListPic )
974
0
      {
975
0
        int pocCycle = 1 << (pic->cs->sps->bitsForPOC);
976
0
        int curPoc   = pic->getPOC() & (pocCycle - 1);
977
0
        int refPoc   = pRPL->refPicIdentifier[ii] & (pocCycle - 1);
978
0
        if( pRPL->deltaPocMSBPresent[ii] )
979
0
        {
980
0
          refPoc += poc - pRPL->deltaPocMSBCycleLT[ii] * pocCycle - (poc & (pocCycle - 1));
981
0
        }
982
0
        else
983
0
        {
984
0
          curPoc = curPoc & (pocCycle - 1);
985
0
        }
986
0
        if( pic->isLongTerm && curPoc == refPoc && pic->isReferenced )
987
0
        {
988
0
          isAvailable = true;
989
0
          break;
990
0
        }
991
0
      }
992
993
      // if there was no such long-term check the short terms
994
0
      if( ! isAvailable )
995
0
      {
996
0
        for( auto& pic : rcListPic )
997
0
        {
998
0
          int pocCycle = 1 << (pic->cs->sps->bitsForPOC);
999
0
          int curPoc   = pic->getPOC() & (pocCycle - 1);
1000
0
          int refPoc   = pRPL->refPicIdentifier[ii] & (pocCycle - 1);
1001
0
          if( pRPL->deltaPocMSBPresent[ii] )
1002
0
          {
1003
0
            refPoc += poc - pRPL->deltaPocMSBCycleLT[ii] * pocCycle - (poc & (pocCycle - 1));
1004
0
          }
1005
0
          else
1006
0
          {
1007
0
            curPoc = curPoc & (pocCycle - 1);
1008
0
          }
1009
0
          if( ! pic->isLongTerm && curPoc == refPoc && pic->isReferenced )
1010
0
          {
1011
0
            isAvailable     = true;
1012
0
            pic->isLongTerm = true;
1013
0
            break;
1014
0
          }
1015
0
        }
1016
0
      }
1017
1018
0
      if( ! isAvailable )
1019
0
      {
1020
0
        missingPoc = checkPoc;
1021
0
        return true;
1022
0
      }
1023
0
    }
1024
0
  }
1025
1026
  // check short term ref pics
1027
0
  for( int ii = 0; ii < numberOfPictures; ii++ )
1028
0
  {
1029
0
    if( pRPL->isLongtermRefPic[ii] )
1030
0
      continue;
1031
1032
0
    bool isAvailable = false;
1033
0
    int  checkPoc    = poc + pRPL->refPicIdentifier[ii];
1034
1035
0
    for( auto& pic : rcListPic )
1036
0
    {
1037
0
      if( ! pic->isLongTerm && pic->getPOC() == poc + pRPL->refPicIdentifier[ii] && pic->isReferenced && !refPicIsFutureIDRnoLP( pic->getPOC(), ip ) )
1038
0
      {
1039
0
        isAvailable = true;
1040
0
        break;
1041
0
      }
1042
0
    }
1043
0
    if( ! isAvailable && pRPL->numberOfShorttermPictures > 0 )
1044
0
    {
1045
0
      missingPoc = checkPoc;
1046
0
      return true;
1047
0
    }
1048
0
  }
1049
1050
0
  return false;
1051
0
}
1052
1053
void Slice::createExplicitReferencePictureSetFromReference(const PicList& rcListPic, const ReferencePictureList* pRPL0, const ReferencePictureList* pRPL1, int ip)
1054
0
{
1055
0
  Picture* picCand;;
1056
0
  int pocCycle = 0;
1057
1058
0
  if ( isIDRorBLA() ) return; //Assume that all pic in the DPB will be flushed anyway so no need to check.
1059
1060
0
  ReferencePictureList rplSrc0 = *pRPL0;
1061
0
  ReferencePictureList rplSrc1 = *pRPL1;
1062
1063
0
  ReferencePictureList* pLocalRPL0 = &rplLocal[0];
1064
0
  (*pLocalRPL0) = ReferencePictureList();
1065
1066
0
  uint32_t numOfSTRPL0 = 0;
1067
0
  uint32_t numOfLTRPL0 = 0;
1068
0
  uint32_t numOfILRPL0 = 0;
1069
0
  uint32_t numOfRefPic = rplSrc0.numberOfShorttermPictures + rplSrc0.numberOfLongtermPictures;
1070
0
  uint32_t refPicIdxL0 = 0;
1071
0
  for (int ii = 0; ii < numOfRefPic; ii++)
1072
0
  {
1073
    // loop through all pictures in the reference picture buffer
1074
0
    PicList::const_iterator iterPic = rcListPic.begin();
1075
0
    bool isAvailable = false;
1076
1077
0
    pocCycle = 1 << (sps->bitsForPOC);
1078
0
    while (iterPic != rcListPic.end())
1079
0
    {
1080
0
      picCand = *(iterPic++);
1081
0
      if( pic->layerId == picCand->layerId && picCand->isReferenced)
1082
0
      {
1083
0
        if (!rplSrc0.isLongtermRefPic[ii] && picCand->poc == poc + rplSrc0.refPicIdentifier[ii] && !isPocRestrictedByDRAP(picCand->poc, picCand->precedingDRAP) && !refPicIsFutureIDRnoLP(picCand->poc, ip))
1084
0
        {
1085
0
          isAvailable = true;
1086
0
          break;
1087
0
        }
1088
0
        else if (rplSrc0.isLongtermRefPic[ii] && (picCand->poc & (pocCycle - 1)) == rplSrc0.refPicIdentifier[ii] && !isPocRestrictedByDRAP(picCand->poc, picCand->precedingDRAP))
1089
0
        {
1090
0
          isAvailable = true;
1091
0
          break;
1092
0
        }
1093
0
      }
1094
0
    }
1095
0
    if (isAvailable)
1096
0
    {
1097
0
      pLocalRPL0->setRefPicIdentifier(refPicIdxL0, rplSrc0.refPicIdentifier[ii], rplSrc0.isLongtermRefPic[ii], rplSrc0.isInterLayerRefPic[ii], rplSrc0.interLayerRefPicIdx[ii]);
1098
0
      refPicIdxL0++;
1099
0
      numOfSTRPL0 = numOfSTRPL0 + ((rplSrc0.isLongtermRefPic[ii]) ? 0 : 1);
1100
0
      numOfLTRPL0 = numOfLTRPL0 + ((rplSrc0.isLongtermRefPic[ii]) ? 1 : 0);
1101
0
      isAvailable = false;
1102
0
    }
1103
0
  }
1104
1105
0
  if( enableDRAPSEI)
1106
0
  {
1107
0
    pLocalRPL0->numberOfShorttermPictures = (numOfSTRPL0);
1108
0
    pLocalRPL0->numberOfLongtermPictures = (numOfLTRPL0);
1109
0
    if( !isIRAP() && !pLocalRPL0->isPOCInRefPicList(associatedIRAP, poc))
1110
0
    {
1111
0
      if (useLTforDRAP && !rplSrc1.isPOCInRefPicList(associatedIRAP, poc))
1112
0
      {
1113
        // Adding associated IRAP as longterm picture
1114
0
        pLocalRPL0->setRefPicIdentifier(refPicIdxL0, associatedIRAP, true, false, 0);
1115
0
        refPicIdxL0++;
1116
0
        numOfLTRPL0++;
1117
0
      }
1118
0
      else
1119
0
      {
1120
        // Adding associated IRAP as shortterm picture
1121
0
        pLocalRPL0->setRefPicIdentifier(refPicIdxL0, associatedIRAP - poc, false, false, 0);
1122
0
        refPicIdxL0++;
1123
0
        numOfSTRPL0++;
1124
0
      }
1125
0
    }
1126
0
  }
1127
1128
0
  ReferencePictureList* pLocalRPL1 = &rplLocal[1];
1129
0
  (*pLocalRPL1) = ReferencePictureList();
1130
1131
0
  uint32_t numOfSTRPL1 = 0;
1132
0
  uint32_t numOfLTRPL1 = 0;
1133
0
  uint32_t numOfILRPL1 = 0;
1134
0
  numOfRefPic = rplSrc1.numberOfShorttermPictures + rplSrc1.numberOfLongtermPictures;
1135
0
  uint32_t refPicIdxL1 = 0;
1136
0
  for (int ii = 0; ii < numOfRefPic; ii++)
1137
0
  {
1138
    // loop through all pictures in the reference picture buffer
1139
0
    PicList::const_iterator iterPic = rcListPic.begin();
1140
0
    bool isAvailable = false;
1141
0
    pocCycle = 1 << sps->bitsForPOC;
1142
0
    while (iterPic != rcListPic.end())
1143
0
    {
1144
0
      picCand = *(iterPic++);
1145
0
      if( pic->layerId == picCand->layerId && picCand->isReferenced )
1146
0
      {
1147
0
        if (!rplSrc1.isLongtermRefPic[ii] && picCand->poc == poc + rplSrc1.refPicIdentifier[ii] && !isPocRestrictedByDRAP(picCand->poc, picCand->precedingDRAP) && !refPicIsFutureIDRnoLP(picCand->poc, ip))
1148
0
        {
1149
0
          isAvailable = true;
1150
0
          break;
1151
0
        }
1152
0
        else if (rplSrc1.isLongtermRefPic[ii] && (picCand->poc & (pocCycle - 1)) == rplSrc1.refPicIdentifier[ii] && !isPocRestrictedByDRAP(picCand->poc, picCand->precedingDRAP))
1153
0
        {
1154
0
          isAvailable = true;
1155
0
          break;
1156
0
        }
1157
0
      }
1158
0
    }
1159
0
    if (isAvailable)
1160
0
    {
1161
0
      pLocalRPL1->setRefPicIdentifier(refPicIdxL1, rplSrc1.refPicIdentifier[ii], rplSrc1.isLongtermRefPic[ii], rplSrc1.isInterLayerRefPic[ii], rplSrc1.interLayerRefPicIdx[ii]);
1162
0
      refPicIdxL1++;
1163
0
      numOfSTRPL1 = numOfSTRPL1 + ((rplSrc1.isLongtermRefPic[ii]) ? 0 : 1);
1164
0
      numOfLTRPL1 = numOfLTRPL1 + ((rplSrc1.isLongtermRefPic[ii]) ? 1 : 0);
1165
0
      isAvailable = false;
1166
0
    }
1167
0
  }
1168
1169
  //Copy from L1 if we have less than active ref pic
1170
0
  int numOfNeedToFill = rplSrc0.numberOfActivePictures - (numOfLTRPL0 + numOfSTRPL0);
1171
0
  bool isDisallowMixedRefPic = sps->allRplEntriesHasSameSign;
1172
0
  int originalL0StrpNum = numOfSTRPL0;
1173
0
  int originalL0LtrpNum = numOfLTRPL0;
1174
0
  int originalL0IlrpNum = numOfILRPL0;
1175
1176
0
  for (int ii = 0; numOfNeedToFill > 0 && ii < (numOfLTRPL1 + numOfSTRPL1 + numOfILRPL1); ii++)
1177
0
  {
1178
0
    if (ii <= (numOfLTRPL1 + numOfSTRPL1 + numOfILRPL1 - 1))
1179
0
    {
1180
      //Make sure this copy is not already in L0
1181
0
      bool canIncludeThis = true;
1182
0
      for (int jj = 0; jj < refPicIdxL0; jj++)
1183
0
      {
1184
0
        if ((pLocalRPL1->refPicIdentifier[ii] == pLocalRPL0->refPicIdentifier[jj])
1185
0
         && (pLocalRPL1->isLongtermRefPic[ii] == pLocalRPL0->isLongtermRefPic[jj])
1186
0
         && (pLocalRPL1->isInterLayerRefPic[ii] == pLocalRPL0->isInterLayerRefPic[jj]) )
1187
0
        {
1188
0
          canIncludeThis = false;
1189
0
        }
1190
0
        bool sameSign = (pLocalRPL1->refPicIdentifier[ii] > 0) == (pLocalRPL0->refPicIdentifier[0] > 0);
1191
0
        if (isDisallowMixedRefPic && canIncludeThis && !pLocalRPL1->isLongtermRefPic[ii] && !sameSign)
1192
0
        {
1193
0
          canIncludeThis = false;
1194
0
        }
1195
0
      }
1196
0
      if (canIncludeThis)
1197
0
      {
1198
0
        pLocalRPL0->setRefPicIdentifier(refPicIdxL0, pLocalRPL1->refPicIdentifier[ii], pLocalRPL1->isLongtermRefPic[ii], pLocalRPL1->isInterLayerRefPic[ii], pLocalRPL1->interLayerRefPicIdx[ii]);
1199
0
        refPicIdxL0++;
1200
0
        numOfSTRPL0 +=  rplSrc1.isLongtermRefPic[ii] ? 0 : 1;
1201
0
        numOfLTRPL0 += (rplSrc1.isLongtermRefPic[ii] && !rplSrc1.isInterLayerRefPic[ii]) ? 1 : 0;
1202
0
        numOfILRPL0 +=  rplSrc1.isInterLayerRefPic[ ii] ? 1 : 0;
1203
1204
0
        numOfNeedToFill--;
1205
0
      }
1206
0
    }
1207
0
  }
1208
0
  pLocalRPL0->numberOfLongtermPictures  = numOfLTRPL0;
1209
0
  pLocalRPL0->numberOfShorttermPictures = numOfSTRPL0;
1210
0
  pLocalRPL0->numberOfInterLayerPictures = numOfILRPL0;
1211
1212
0
  int numPics = numOfLTRPL0 + numOfSTRPL0;
1213
0
  pLocalRPL0->numberOfActivePictures  = ( numPics < rpl[0]->numberOfActivePictures ? numPics : rpl[0]->numberOfActivePictures ) + numOfILRPL0;
1214
0
  pLocalRPL0->ltrpInSliceHeader = rpl[0]->ltrpInSliceHeader;
1215
1216
0
  pLocalRPL0->numberOfActivePictures    = (numOfLTRPL0 + numOfSTRPL0 < rplSrc0.numberOfActivePictures) ? numOfLTRPL0 + numOfSTRPL0 : rplSrc0.numberOfActivePictures;
1217
0
  pLocalRPL0->ltrpInSliceHeader = rplSrc0.ltrpInSliceHeader;
1218
0
  rplIdx[0] = -1;
1219
0
  rpl[0]    = pLocalRPL0;
1220
1221
  //Copy from L0 if we have less than active ref pic
1222
0
  numOfNeedToFill = pLocalRPL0->numberOfActivePictures - (numOfLTRPL1 + numOfSTRPL1);
1223
0
  for (int ii = 0; numOfNeedToFill > 0 && ii < (pLocalRPL0->numberOfLongtermPictures + pLocalRPL0->numberOfShorttermPictures + pLocalRPL0->numberOfInterLayerPictures ); ii++)
1224
0
  {
1225
0
    if (ii <= (originalL0StrpNum + originalL0LtrpNum + originalL0IlrpNum - 1))
1226
0
    {
1227
      //Make sure this copy is not already in L0
1228
0
      bool canIncludeThis = true;
1229
0
      for (int jj = 0; jj < refPicIdxL1; jj++)
1230
0
      {
1231
0
        if ((pLocalRPL0->refPicIdentifier[ii] == pLocalRPL1->refPicIdentifier[jj])
1232
0
          && (pLocalRPL0->isLongtermRefPic[ii] == pLocalRPL1->isLongtermRefPic[jj])
1233
0
          && (pLocalRPL0->isInterLayerRefPic[ii] == pLocalRPL1->isInterLayerRefPic[jj]))
1234
0
        {
1235
0
          canIncludeThis = false;
1236
0
        }
1237
0
        bool sameSign = (pLocalRPL0->refPicIdentifier[ii] > 0) == (pLocalRPL1->refPicIdentifier[0] > 0);
1238
0
        if (isDisallowMixedRefPic && canIncludeThis && !pLocalRPL0->isLongtermRefPic[ii] && !sameSign)
1239
0
        {
1240
0
          canIncludeThis = false;
1241
0
        }
1242
0
      }
1243
0
      if (canIncludeThis)
1244
0
      {
1245
0
        pLocalRPL1->setRefPicIdentifier(refPicIdxL1, pLocalRPL0->refPicIdentifier[ii], pLocalRPL0->isLongtermRefPic[ii], pLocalRPL0->isInterLayerRefPic[ii], pLocalRPL0->interLayerRefPicIdx[ii]);
1246
0
        refPicIdxL1++;
1247
0
        numOfSTRPL1 += pLocalRPL0->isLongtermRefPic[ii] ? 0 : 1;
1248
0
        numOfLTRPL1 += (pLocalRPL0->isLongtermRefPic[ii] && !pLocalRPL0->isInterLayerRefPic[ii]) ? 1 : 0;
1249
0
        numOfLTRPL1 += pLocalRPL0->isInterLayerRefPic[ii] ? 1 : 0;
1250
1251
0
        numOfNeedToFill--;
1252
0
      }
1253
0
    }
1254
0
  }
1255
0
  pLocalRPL1->numberOfLongtermPictures  = numOfLTRPL1;
1256
0
  pLocalRPL1->numberOfShorttermPictures = numOfSTRPL1;
1257
0
  pLocalRPL1->numberOfInterLayerPictures = numOfILRPL1;
1258
0
  numPics = numOfLTRPL1 + numOfSTRPL1;
1259
1260
0
  pLocalRPL1->numberOfActivePictures    = (isDisallowMixedRefPic) ? numPics : ((numPics < rplSrc1.numberOfActivePictures) ? numPics : rplSrc1.numberOfActivePictures);
1261
0
  pLocalRPL1->ltrpInSliceHeader         = rplSrc1.ltrpInSliceHeader;
1262
0
  rplIdx[1] = -1;
1263
0
  rpl[1]    = pLocalRPL1;
1264
0
}
1265
1266
//! get tables for weighted prediction
1267
void  Slice::getWpScaling( RefPicList e, int iRefIdx, WPScalingParam *&wp ) const
1268
0
{
1269
0
 CHECK(e>=NUM_REF_PIC_LIST_01, "Invalid picture reference list");
1270
0
  wp = (WPScalingParam*) weightPredTable[e][iRefIdx];
1271
0
}
1272
1273
void PicHeader::getWpScaling(RefPicList e, int iRefIdx, WPScalingParam *&wp) const
1274
0
{
1275
0
  CHECK(e >= NUM_REF_PIC_LIST_01, "Invalid picture reference list");
1276
0
  wp = (WPScalingParam *) weightPredTable[e][iRefIdx];
1277
0
}
1278
1279
//! reset Default WP tables settings : no weight.
1280
void  Slice::resetWpScaling()
1281
1.08k
{
1282
3.25k
  for ( int e=0 ; e<NUM_REF_PIC_LIST_01 ; e++ )
1283
2.17k
  {
1284
36.9k
    for ( int i=0 ; i<MAX_NUM_REF ; i++ )
1285
34.7k
    {
1286
139k
      for ( int yuv=0 ; yuv<MAX_NUM_COMP ; yuv++ )
1287
104k
      {
1288
104k
        WPScalingParam  *pwp = &(weightPredTable[e][i][yuv]);
1289
104k
        pwp->presentFlag     = false;
1290
104k
        pwp->log2WeightDenom = 0;
1291
104k
        pwp->iWeight         = 1;
1292
104k
        pwp->iOffset         = 0;
1293
104k
      }
1294
34.7k
    }
1295
2.17k
  }
1296
1.08k
}
1297
1298
unsigned Slice::getMinPictureDistance() const
1299
3.33k
{
1300
3.33k
  int minPicDist = MAX_INT;
1301
3.33k
  if (sps->IBC)
1302
3.33k
  {
1303
3.33k
    minPicDist = 0;
1304
3.33k
  }
1305
0
  else
1306
0
  if( ! isIntra() )
1307
0
  {
1308
0
    const int currPOC  = poc;
1309
0
    for (int refIdx = 0; refIdx < numRefIdx[ REF_PIC_LIST_0 ]; refIdx++)
1310
0
    {
1311
0
      minPicDist = std::min( minPicDist, std::abs(currPOC - getRefPic(REF_PIC_LIST_0, refIdx)->getPOC()));
1312
0
    }
1313
0
    if( sliceType == VVENC_B_SLICE )
1314
0
    {
1315
0
      for (int refIdx = 0; refIdx < numRefIdx[ REF_PIC_LIST_1 ]; refIdx++)
1316
0
      {
1317
0
        minPicDist = std::min(minPicDist, std::abs(currPOC - getRefPic(REF_PIC_LIST_1, refIdx)->getPOC()));
1318
0
      }
1319
0
    }
1320
0
  }
1321
3.33k
  return (unsigned) minPicDist;
1322
3.33k
}
1323
1324
bool Slice::isPocRestrictedByDRAP( int poc, bool precedingDRAPInDecodingOrder ) const
1325
0
{
1326
0
  if (!enableDRAPSEI)
1327
0
  {
1328
0
    return false;
1329
0
  }
1330
0
  return ( isDRAP && poc != associatedIRAP ) || ( latestDRAPPOC != MAX_INT && poc > latestDRAPPOC && (precedingDRAPInDecodingOrder || poc < latestDRAPPOC) );
1331
0
}
1332
1333
bool Slice::refPicIsFutureIDRnoLP( int candPoc, int ipc ) const
1334
0
{
1335
  //check if we are not trying to reference a future IDR picture
1336
0
  if( ipc != 0 && associatedIRAP + ipc == candPoc )
1337
0
  {
1338
0
    return true;
1339
0
  }
1340
0
  return false;
1341
0
}
1342
1343
void Slice::setAlfApsIds( const std::vector<int>& ApsIDs)
1344
0
{
1345
0
  lumaApsId.resize(numAps);
1346
0
  for (int i = 0; i < numAps; i++)
1347
0
  {
1348
0
    lumaApsId[i] = ApsIDs[i];
1349
0
  }
1350
0
}
1351
1352
1353
void PicHeader::copyPicInfo( const PicHeader* other, bool cpyAll)
1354
0
{
1355
0
  pocLsb                                  = other->pocLsb;                                
1356
0
  nonRefPic                               = other->nonRefPic;                             
1357
0
  gdrOrIrapPic                            = other->gdrOrIrapPic;                          
1358
0
  gdrPic                                  = other->gdrPic;                                
1359
0
  noOutputOfPriorPics                     = other->noOutputOfPriorPics;                   
1360
0
  recoveryPocCnt                          = other->recoveryPocCnt;                        
1361
0
  noOutputBeforeRecovery                  = other->noOutputBeforeRecovery;                
1362
0
  handleCraAsCvsStart                     = other->handleCraAsCvsStart;                   
1363
0
  handleGdrAsCvsStart                     = other->handleGdrAsCvsStart;                   
1364
0
  spsId                                   = other->spsId;                                 
1365
0
  ppsId                                   = other->ppsId;                                 
1366
0
  pocMsbPresent                           = other->pocMsbPresent;                         
1367
0
  pocMsbVal                               = other->pocMsbVal;                             
1368
0
  virtualBoundariesEnabled                = other->virtualBoundariesEnabled;              
1369
0
  virtualBoundariesPresent                = other->virtualBoundariesPresent;              
1370
0
  numVerVirtualBoundaries                 = other->numVerVirtualBoundaries;               
1371
0
  numHorVirtualBoundaries                 = other->numHorVirtualBoundaries;               
1372
//  virtualBoundariesPosX[3];               = other->virtualBoundariesPosX[3];              
1373
//  virtualBoundariesPosY[3];               = other->virtualBoundariesPosY[3];              
1374
0
  picOutputFlag                           = other->picOutputFlag;                         
1375
//pic                                     = other->pic;                                   
1376
//  pRPL[NUM_REF_PIC_LIST_01]              = other->pRPL[NUM_REF_PIC_LIST_01];             
1377
0
  localRPL[L0]                            = other->localRPL[L0];         
1378
0
  localRPL[L1]                            = other->localRPL[L1];         
1379
0
  rplIdx[L0]                              = other->rplIdx[L0];           
1380
0
  rplIdx[L1]                              = other->rplIdx[L1];           
1381
0
  picInterSliceAllowed                    = other->picInterSliceAllowed;                  
1382
0
  picIntraSliceAllowed                    = other->picIntraSliceAllowed;                  
1383
0
  splitConsOverride                       = other->splitConsOverride;                     
1384
0
  cuQpDeltaSubdivIntra                    = other->cuQpDeltaSubdivIntra;                  
1385
0
  cuQpDeltaSubdivInter                    = other->cuQpDeltaSubdivInter;                  
1386
0
  cuChromaQpOffsetSubdivIntra             = other->cuChromaQpOffsetSubdivIntra;           
1387
0
  cuChromaQpOffsetSubdivInter             = other->cuChromaQpOffsetSubdivInter;           
1388
0
  enableTMVP                              = other->enableTMVP;                            
1389
0
  picColFromL0                            = other->picColFromL0;                          
1390
0
  colRefIdx                               = other->colRefIdx;
1391
0
  mvdL1Zero                               = other->mvdL1Zero;                             
1392
0
  maxNumAffineMergeCand                   = other->maxNumAffineMergeCand;                 
1393
0
  disFracMMVD                             = other->disFracMMVD;                           
1394
0
  disBdofFlag                             = other->disBdofFlag;                           
1395
0
  disDmvrFlag                             = other->disDmvrFlag;                           
1396
0
  disProfFlag                             = other->disProfFlag;                           
1397
0
  jointCbCrSign                           = other->jointCbCrSign;                         
1398
0
  qpDelta                                 = other->qpDelta;                               
1399
0
  memcpy(saoEnabled, other->saoEnabled, sizeof(saoEnabled));                
1400
0
  memcpy(alfEnabled, other->alfEnabled, sizeof(alfEnabled));              
1401
0
  numAlfAps                               = other->numAlfAps;                             
1402
0
  alfApsId                                = other->alfApsId;                              
1403
0
  alfChromaApsId                          = other->alfChromaApsId;                        
1404
0
  memcpy(ccalfEnabled, other->ccalfEnabled, sizeof(ccalfEnabled));                
1405
0
  ccalfCbApsId                            = other->ccalfCbApsId;
1406
0
  ccalfCrApsId                            = other->ccalfCrApsId;
1407
0
  deblockingFilterOverride                = other->deblockingFilterOverride;                
1408
0
  deblockingFilterDisable                 = other->deblockingFilterDisable;                
1409
0
  memcpy(deblockingFilterBetaOffsetDiv2,  other->deblockingFilterBetaOffsetDiv2,  sizeof(deblockingFilterBetaOffsetDiv2));                
1410
0
  memcpy(deblockingFilterTcOffsetDiv2,    other->deblockingFilterTcOffsetDiv2,    sizeof(deblockingFilterTcOffsetDiv2));                
1411
0
  lmcsEnabled                             = other->lmcsEnabled;                           
1412
0
  lmcsApsId                               = other->lmcsApsId;                             
1413
//lmcsAps;                                = other->lmcsAps;                               
1414
0
  lmcsChromaResidualScale                 = other->lmcsChromaResidualScale;               
1415
0
  explicitScalingListEnabled              = other->explicitScalingListEnabled;            
1416
0
  scalingListApsId                        = other->scalingListApsId;                      
1417
//scalingListAps;                         = other->scalingListAps;                        
1418
0
  memcpy(minQTSize,   other->minQTSize, sizeof(minQTSize));                
1419
0
  memcpy(maxMTTDepth, other->maxMTTDepth, sizeof(maxMTTDepth));                
1420
0
  memcpy(maxBTSize,   other->maxBTSize, sizeof(maxBTSize));                
1421
0
  memcpy(maxTTSize,   other->maxTTSize, sizeof(maxTTSize));                
1422
1423
//  memcpy(weightPredTable,   other->weightPredTable, sizeof(weightPredTable));                
1424
0
  numL0Weights                            = other->numL0Weights;                          
1425
0
  numL1Weights                            = other->numL1Weights;                          
1426
1427
0
}
1428
1429
// ------------------------------------------------------------------------------------------------
1430
// Sequence parameter set (SPS)
1431
// ------------------------------------------------------------------------------------------------
1432
1433
SPS::SPS()
1434
1.08k
: spsId                           (  0 )
1435
1.08k
, dciId                           (  0 )
1436
1.08k
, vpsId                           (  0 )
1437
1.08k
, layerId                         ( 0 )
1438
1.08k
, AffineAmvr                      ( false )
1439
1.08k
, DMVR                            ( false )
1440
1.08k
, MMVD                            ( false )
1441
1.08k
, SBT                             ( false )
1442
1.08k
, ISP                             ( false )
1443
1.08k
, chromaFormatIdc                 ( CHROMA_420 )
1444
1.08k
, separateColourPlane             ( false )
1445
1.08k
, maxTLayers                      ( 1 )
1446
1.08k
, ptlDpbHrdParamsPresent          ( true )
1447
1.08k
, subLayerDpbParams               ( false )
1448
1.08k
, maxPicWidthInLumaSamples        ( 352 )
1449
1.08k
, maxPicHeightInLumaSamples       ( 288 )
1450
1.08k
, subPicInfoPresent               ( false )
1451
1.08k
, numSubPics                      ( 0 )
1452
1.08k
, independentSubPicsFlag          ( false )
1453
1.08k
, subPicIdMappingExplicitlySignalled ( false )
1454
1.08k
, log2MinCodingBlockSize          ( 0 )
1455
1.08k
, CTUSize                         ( 0 )
1456
1.08k
, partitionOverrideEnabled        ( 1 )
1457
1.08k
, minQTSize                       { 0, 0, 0 }
1458
1.08k
, maxMTTDepth                     { MAX_BT_DEPTH, MAX_BT_DEPTH_INTER, 0 }
1459
1.08k
, maxBTSize                       { 0,  0,  0 }
1460
1.08k
, maxTTSize                       { 0,  0,  0 }
1461
1.08k
, idrRefParamList                 ( false )
1462
1.08k
, dualITree                       ( 0 )
1463
1.08k
, rpl1CopyFromRpl0                ( false )
1464
1.08k
, rpl1IdxPresent                  ( false )
1465
1.08k
, allRplEntriesHasSameSign        ( true )
1466
1.08k
, longTermRefsPresent             ( false )
1467
1.08k
, temporalMVPEnabled              ( 0 )
1468
1.08k
, transformSkip                   ( false )
1469
1.08k
, log2MaxTransformSkipBlockSize   ( 0 )
1470
1.08k
, BDPCM                           ( false )
1471
1.08k
, jointCbCr                       ( false )
1472
1.08k
, entropyCodingSyncEnabled        ( false )
1473
1.08k
, entryPointsPresent              ( false )
1474
1.08k
, qpBDOffset                      { 0,0 }
1475
1.08k
, internalMinusInputBitDepth      { 0,0 }
1476
1.08k
, SbtMvp                          ( false)
1477
1.08k
, BDOF                            ( false)
1478
1.08k
, fpelMmvd                        ( false )
1479
1.08k
, BdofPresent                     ( false )
1480
1.08k
, DmvrPresent                     ( false )
1481
1.08k
, ProfPresent                     ( false )
1482
1.08k
, bitsForPOC                      ( 8 )
1483
1.08k
, pocMsbFlag                      ( false )
1484
1.08k
, pocMsbLen                       ( 0 )
1485
1.08k
, numExtraPHBitsBytes             ( 0 )
1486
1.08k
, numExtraSHBitsBytes             ( 0 )
1487
1.08k
, numLongTermRefPicSPS            ( 0 )
1488
1.08k
, log2MaxTbSize                   ( 6 )
1489
1.08k
, weightPred                      ( false )
1490
1.08k
, weightedBiPred                  ( false )
1491
1.08k
, saoEnabled                      ( false )
1492
1.08k
, temporalIdNesting               ( false )
1493
1.08k
, scalingListEnabled              ( false )
1494
1.08k
, depQuantEnabled                 ( false )
1495
1.08k
, signDataHidingEnabled           ( false )
1496
1.08k
, virtualBoundariesEnabled        ( false )
1497
1.08k
, virtualBoundariesPresent        ( false )
1498
1.08k
, numVerVirtualBoundaries         ( 0 )
1499
1.08k
, numHorVirtualBoundaries         ( 0 )
1500
1.08k
, virtualBoundariesPosX           { 0,  0,  0 }
1501
1.08k
, virtualBoundariesPosY           { 0,  0,  0 }
1502
1.08k
, hrdParametersPresent            ( false )
1503
1.08k
, subLayerParametersPresent       ( false )
1504
1.08k
, fieldSeqFlag                    ( false )
1505
1.08k
, vuiParametersPresent            ( false )
1506
1.08k
, vuiPayloadSize                  ( 0 )
1507
1.08k
, vuiParameters                   ()
1508
1.08k
, alfEnabled                      ( false )
1509
1.08k
, ccalfEnabled                    ( false )
1510
1.08k
, wrapAroundEnabled               ( false )
1511
1.08k
, IBC                             ( false )
1512
1.08k
, useColorTrans                   ( false )
1513
1.08k
, PLT                             ( false )
1514
1.08k
, lumaReshapeEnable               ( false )
1515
1.08k
, AMVR                            ( false )
1516
1.08k
, LMChroma                        ( false )
1517
1.08k
, horCollocatedChroma             ( false )
1518
1.08k
, verCollocatedChroma             ( false )
1519
1.08k
, MTS                             ( false )
1520
1.08k
, MTSIntra                        ( false )
1521
1.08k
, MTSInter                        ( false )
1522
1.08k
, LFNST                           ( false )
1523
1.08k
, SMVD                            ( false )
1524
1.08k
, Affine                          ( false )
1525
1.08k
, AffineType                      ( false )
1526
1.08k
, PROF                            ( false )
1527
1.08k
, BCW                             ( false )
1528
1.08k
, CIIP                            ( false )
1529
1.08k
, GEO                             ( false )
1530
1.08k
, LADF                            ( false )
1531
1.08k
, MRL                             ( false )
1532
1.08k
, MIP                             ( false )
1533
1.08k
, GDR                             ( true )
1534
1.08k
, subLayerCbpParametersPresent    ( true)
1535
1.08k
, rprEnabled                      ( false )
1536
1.08k
, resChangeInClvsEnabled          ( false )
1537
1.08k
, interLayerPresent               ( false )
1538
1.08k
, log2ParallelMergeLevelMinus2    ( 0 )
1539
1.08k
, maxNumMergeCand                 ( 0 )
1540
1.08k
, maxNumAffineMergeCand           ( 0 )
1541
1.08k
, maxNumIBCMergeCand              ( 0 )
1542
1.08k
, maxNumGeoCand                   ( 0 )
1543
1.08k
, scalingMatrixAlternativeColourSpaceDisabled ( false )
1544
1.08k
, scalingMatrixDesignatedColourSpace          ( false )
1545
1.08k
, disableScalingMatrixForLfnstBlks            ( false )
1546
1547
1.08k
{
1548
3.25k
  for(int ch=0; ch<MAX_NUM_CH; ch++)
1549
2.17k
  {
1550
2.17k
    bitDepths.recon[ch] = 8;
1551
2.17k
    qpBDOffset   [ch] = 0;
1552
2.17k
  }
1553
1554
8.68k
  for ( int i = 0; i < VVENC_MAX_TLAYER; i++ )
1555
7.60k
  {
1556
7.60k
    maxLatencyIncreasePlus1[i] = 0;
1557
7.60k
    maxDecPicBuffering[i] = 1;
1558
7.60k
    numReorderPics[i]       = 0;
1559
7.60k
  }
1560
1561
1.08k
  ::memset(ltRefPicPocLsbSps, 0, sizeof(ltRefPicPocLsbSps));
1562
1.08k
  ::memset(usedByCurrPicLtSPS, 0, sizeof(usedByCurrPicLtSPS));
1563
1564
71.1M
  for( int i = 0; i < MAX_NUM_SUB_PICS; i++ )
1565
71.1M
  {
1566
71.1M
    subPicCtuTopLeftX[i] = 0;
1567
71.1M
    subPicCtuTopLeftY[i] = 0;
1568
71.1M
    subPicWidth[i] = 0;
1569
71.1M
    subPicHeight[i] = 0;
1570
71.1M
    subPicTreatedAsPic[i] = false;
1571
71.1M
    loopFilterAcrossSubpicEnabled[i] = false;
1572
71.1M
    subPicId[i] = 0;
1573
71.1M
  }
1574
1.08k
}
1575
1576
void ChromaQpMappingTable::setParams(const vvencChromaQpMappingTableParams &params, const int qpBdOffset)
1577
1.08k
{
1578
1.08k
  m_qpBdOffset = qpBdOffset;
1579
1.08k
  m_sameCQPTableForAllChromaFlag = params.m_sameCQPTableForAllChromaFlag;
1580
1581
4.34k
  for (int i = 0; i < VVENC_MAX_NUM_CQP_MAPPING_TABLES; i++)
1582
3.25k
  {
1583
3.25k
    m_qpTableStartMinus26[i] = params.m_qpTableStartMinus26[i];
1584
3.25k
    m_numPtsInCQPTableMinus1[i] = params.m_numPtsInCQPTableMinus1[i];
1585
3.25k
    memcpy(m_deltaQpInValMinus1[i], params.m_deltaQpInValMinus1[i], sizeof m_deltaQpInValMinus1[i]);
1586
3.25k
    memcpy(m_deltaQpOutVal[i], params.m_deltaQpOutVal[i], sizeof m_deltaQpOutVal[i]);
1587
3.25k
    m_chromaQpMappingTables[i].resize( MAX_QP + qpBdOffset + 1 );
1588
3.25k
  }
1589
1.08k
}
1590
1591
void ChromaQpMappingTable::derivedChromaQPMappingTables()
1592
1.08k
{
1593
2.17k
  for (int i = 0; i < m_numQpTables; i++)
1594
1.08k
  {
1595
1.08k
    const int qpBdOffsetC = m_qpBdOffset;
1596
1.08k
    const int numPtsInCQPTableMinus1 = m_numPtsInCQPTableMinus1[i];
1597
1.08k
    std::vector<int> qpInVal(numPtsInCQPTableMinus1 + 2), qpOutVal(numPtsInCQPTableMinus1 + 2);
1598
1599
1.08k
    qpInVal[0] = m_qpTableStartMinus26[i] + 26;
1600
1.08k
    qpOutVal[0] = qpInVal[0];
1601
4.34k
    for (int j = 0; j <= m_numPtsInCQPTableMinus1[i]; j++)
1602
3.25k
    {
1603
3.25k
      qpInVal[j+1] = qpInVal[j] + m_deltaQpInValMinus1[i][j] + 1;
1604
3.25k
      qpOutVal[j+1] = qpOutVal[j] + m_deltaQpOutVal[i][j];
1605
3.25k
    }
1606
1607
4.34k
    for (int j = 0; j <= m_numPtsInCQPTableMinus1[i]; j++)
1608
3.25k
    {
1609
3.25k
      CHECK(qpInVal[j]  < -qpBdOffsetC || qpInVal[j]  > MAX_QP, "qpInVal out of range");
1610
3.25k
      CHECK(qpOutVal[j] < -qpBdOffsetC || qpOutVal[j] > MAX_QP, "qpOutVal out of range");
1611
3.25k
    }
1612
1613
1.08k
    m_chromaQpMappingTables[i][qpInVal[0] + qpBdOffsetC] = qpOutVal[0];
1614
19.5k
    for (int k = qpInVal[0] - 1; k >= -qpBdOffsetC; k--)
1615
18.4k
    {
1616
18.4k
      m_chromaQpMappingTables[i][k + qpBdOffsetC] = Clip3(-qpBdOffsetC, MAX_QP, m_chromaQpMappingTables[i][k + 1 + qpBdOffsetC] - 1);
1617
18.4k
    }
1618
4.34k
    for (int j = 0; j <= numPtsInCQPTableMinus1; j++)
1619
3.25k
    {
1620
3.25k
      int sh = (m_deltaQpInValMinus1[i][j] + 1) >> 1;
1621
30.4k
      for (int k = qpInVal[j] + 1, m = 1; k <= qpInVal[j + 1]; k++, m++)
1622
27.1k
      {
1623
27.1k
        m_chromaQpMappingTables[i][k + qpBdOffsetC] = m_chromaQpMappingTables[i][qpInVal[j] + qpBdOffsetC]
1624
27.1k
          + ((qpOutVal[j + 1] - qpOutVal[j]) * m + sh) / (m_deltaQpInValMinus1[i][j]+ 1);
1625
27.1k
      }
1626
3.25k
    }
1627
23.8k
    for (int k = qpInVal[numPtsInCQPTableMinus1+1]+1; k <= MAX_QP; k++)
1628
22.8k
    {
1629
22.8k
      m_chromaQpMappingTables[i][k + qpBdOffsetC] = Clip3(-qpBdOffsetC, MAX_QP, m_chromaQpMappingTables[i][k - 1 + qpBdOffsetC] + 1);
1630
22.8k
    }
1631
1.08k
  }
1632
1.08k
}
1633
1634
1635
PPS::PPS()
1636
1.08k
: ppsId                              (0)
1637
1.08k
, spsId                              (0)
1638
1.08k
, picInitQPMinus26                   (0)
1639
1.08k
, useDQP                             (false)
1640
1.08k
, usePPSChromaTool                   (false)
1641
1.08k
, sliceChromaQpFlag                  (false)
1642
1.08k
, layerId                            (0)
1643
1.08k
, temporalId                         (0)
1644
1.08k
, chromaQpOffset                     { 0 }
1645
1.08k
, jointCbCrQpOffsetPresent           (false)
1646
1.08k
, chromaQpOffsetListLen              (0)
1647
1.08k
, numRefIdxL0DefaultActive           (1)
1648
1.08k
, numRefIdxL1DefaultActive           (1)
1649
1.08k
, rpl1IdxPresent                     (false)
1650
1.08k
, weightPred                         (false)
1651
1.08k
, weightedBiPred                     (0)
1652
1.08k
, outputFlagPresent                  (false)
1653
1.08k
, numSubPics                         (0)
1654
1.08k
, subPicIdMappingInPps               (false)
1655
1.08k
, subPicIdLen                        (0)
1656
//,   subPicId[MAX_NUM_SUB_PICS];        //!< sub-picture ID for each sub-picture in the sequence
1657
1.08k
, noPicPartition                     (false)
1658
1.08k
, log2CtuSize                        (0)
1659
1.08k
, ctuSize                            (0)
1660
1.08k
, picWidthInCtu                      (0)
1661
1.08k
, picHeightInCtu                     (0)
1662
1.08k
, numExpTileCols                     (1)
1663
1.08k
, numExpTileRows                     (1)
1664
1.08k
, numTileCols                        (1)
1665
1.08k
, numTileRows                        (1)
1666
1.08k
, rectSlice                          (true)
1667
1.08k
, singleSlicePerSubPic               (false)
1668
1.08k
, numSlicesInPic                     (1)
1669
1.08k
, tileIdxDeltaPresent                (false)
1670
1.08k
, loopFilterAcrossTilesEnabled       (false)
1671
1.08k
, loopFilterAcrossSlicesEnabled      (false)
1672
1.08k
, cabacInitPresent                   (false)
1673
1.08k
, pictureHeaderExtensionPresent      (false)
1674
1.08k
, sliceHeaderExtensionPresent        (false)
1675
1.08k
, deblockingFilterControlPresent     (true)
1676
1.08k
, deblockingFilterOverrideEnabled    (0)
1677
1.08k
, deblockingFilterDisabled           (true)
1678
1.08k
, deblockingFilterBetaOffsetDiv2     {0}
1679
1.08k
, deblockingFilterTcOffsetDiv2       {0}
1680
1.08k
, listsModificationPresent           (false)
1681
1.08k
, rplInfoInPh                        (false)
1682
1.08k
, dbfInfoInPh                        (false)
1683
1.08k
, saoInfoInPh                        (false)
1684
1.08k
, alfInfoInPh                        (false)
1685
1.08k
, wpInfoInPh                         (false)
1686
1.08k
, qpDeltaInfoInPh                    (false)
1687
1.08k
, mixedNaluTypesInPic                (false)
1688
1.08k
, picWidthInLumaSamples              (0)
1689
1.08k
, picHeightInLumaSamples             (0)
1690
1.08k
, wrapAroundEnabled                  (false)
1691
1.08k
, picWidthMinusWrapAroundOffset      (0)
1692
1.08k
, wrapAroundOffset                   (0)
1693
1.08k
, pcv                                (NULL)
1694
1.08k
{
1695
1.08k
  chromaQpAdjTableIncludingNullEntry[0].u.comp.CbOffset = 0; // Array includes entry [0] for the null offset used when cu_chroma_qp_offset_flag=0. This is initialised here and never subsequently changed.
1696
1.08k
  chromaQpAdjTableIncludingNullEntry[0].u.comp.CrOffset = 0;
1697
1.08k
  chromaQpAdjTableIncludingNullEntry[0].u.comp.JointCbCrOffset = 0;
1698
1.08k
}
1699
1700
PPS::~PPS()
1701
1.08k
{
1702
1.08k
  delete pcv;
1703
1.08k
}
1704
1705
/**
1706
 - initialize tile row/column sizes and boundaries
1707
 */
1708
void PPS::initTiles()
1709
1.08k
{
1710
1.08k
  int colIdx, rowIdx;
1711
1.08k
  int ctuX, ctuY;
1712
1713
  // check explicit tile column sizes
1714
1.08k
  uint32_t  remainingWidthInCtu  = picWidthInCtu;
1715
2.17k
  for( colIdx = 0; colIdx < numExpTileCols; colIdx++ )
1716
1.08k
  {
1717
1.08k
    CHECK(tileColWidth[colIdx] > remainingWidthInCtu,    "Tile column width exceeds picture width");
1718
1.08k
    remainingWidthInCtu -= tileColWidth[colIdx];
1719
1.08k
  }
1720
1721
  // divide remaining picture width into uniform tile columns
1722
1.08k
  uint32_t  uniformTileColWidth = tileColWidth[colIdx-1];
1723
1.08k
  while( remainingWidthInCtu > 0 )
1724
0
  {
1725
0
    CHECK(colIdx >= MAX_TILE_COLS, "Number of tile columns exceeds valid range");
1726
0
    uniformTileColWidth = std::min(remainingWidthInCtu, uniformTileColWidth);
1727
0
    tileColWidth.push_back( uniformTileColWidth );
1728
0
    remainingWidthInCtu -= uniformTileColWidth;
1729
0
    colIdx++;
1730
0
  }
1731
1.08k
  numTileCols = colIdx;
1732
1733
  // check explicit tile row sizes
1734
1.08k
  uint32_t  remainingHeightInCtu  = picHeightInCtu;
1735
2.17k
  for( rowIdx = 0; rowIdx < numExpTileRows; rowIdx++ )
1736
1.08k
  {
1737
1.08k
    CHECK(tileRowHeight[rowIdx] > remainingHeightInCtu,     "Tile row height exceeds picture height");
1738
1.08k
    remainingHeightInCtu -= tileRowHeight[rowIdx];
1739
1.08k
  }
1740
1741
  // divide remaining picture height into uniform tile rows
1742
1.08k
  uint32_t  uniformTileRowHeight = tileRowHeight[rowIdx - 1];
1743
1.08k
  while( remainingHeightInCtu > 0 )
1744
0
  {
1745
0
    uniformTileRowHeight = std::min(remainingHeightInCtu, uniformTileRowHeight);
1746
0
    tileRowHeight.push_back( uniformTileRowHeight );
1747
0
    remainingHeightInCtu -= uniformTileRowHeight;
1748
0
    rowIdx++;
1749
0
  }
1750
1.08k
  numTileRows = rowIdx;
1751
1752
  // set left column bounaries
1753
1.08k
  tileColBd.push_back( 0 );
1754
2.17k
  for( colIdx = 0; colIdx < numTileCols; colIdx++ )
1755
1.08k
  {
1756
1.08k
    tileColBd.push_back( tileColBd[ colIdx ] + tileColWidth[ colIdx ] );
1757
1.08k
  }
1758
1759
  // set top row bounaries
1760
1.08k
  tileRowBd.push_back( 0 );
1761
2.17k
  for( rowIdx = 0; rowIdx < numTileRows; rowIdx++ )
1762
1.08k
  {
1763
1.08k
    tileRowBd.push_back( tileRowBd[ rowIdx ] + tileRowHeight[ rowIdx ] );
1764
1.08k
  }
1765
1766
  // set right column bounaries
1767
2.17k
  for( colIdx = 0; colIdx < numTileCols; colIdx++ )
1768
1.08k
  {
1769
1.08k
    tileColBdRgt.push_back( std::min( ( tileColBd[ colIdx ] + tileColWidth[ colIdx ] ) << log2CtuSize, picWidthInLumaSamples ) );
1770
1.08k
  }
1771
1772
  // set bottom row bounaries
1773
2.17k
  for( rowIdx = 0; rowIdx < numTileRows; rowIdx++ )
1774
1.08k
  {
1775
1.08k
    tileRowBdBot.push_back( std::min( ( tileRowBd[ rowIdx ] + tileRowHeight[ rowIdx ] ) << log2CtuSize, picHeightInLumaSamples ) );
1776
1.08k
  }
1777
1778
  // set mapping between horizontal CTU address and tile column index
1779
1.08k
  colIdx = 0;
1780
3.99k
  for( ctuX = 0; ctuX <= picWidthInCtu; ctuX++ )
1781
2.91k
  {
1782
2.91k
    if( ctuX == tileColBd[ colIdx + 1 ] )
1783
1.08k
    {
1784
1.08k
      colIdx++;
1785
1.08k
    }
1786
2.91k
    ctuToTileCol.push_back( colIdx );
1787
2.91k
  }
1788
1789
  // set mapping between vertical CTU address and tile row index
1790
1.08k
  rowIdx = 0;
1791
4.07k
  for( ctuY = 0; ctuY <= picHeightInCtu; ctuY++ )
1792
2.98k
  {
1793
2.98k
    if( ctuY == tileRowBd[ rowIdx + 1 ] )
1794
1.08k
    {
1795
1.08k
      rowIdx++;
1796
1.08k
    }
1797
2.98k
    ctuToTileRow.push_back( rowIdx );
1798
2.98k
  }
1799
1.08k
}
1800
1801
/**
1802
 - initialize memory for rectangular slice parameters
1803
 */
1804
void PPS::initRectSliceMap( const SPS* sps )
1805
0
{
1806
  //currently only one slice is allowed
1807
0
  if( sps )
1808
0
  {
1809
0
    CHECK( sps->numSubPics > 1, "SubPic encoding not yet supported" );
1810
0
  }
1811
  
1812
0
  CHECK( numSlicesInPic > MAX_SLICES, "Number of slices in picture exceeds valid range" );
1813
0
  sliceMap.resize( numSlicesInPic );
1814
1815
0
  sliceMap[0].initSliceMap();
1816
  
1817
0
  uint32_t tileX = 0, tileY = 0;  
1818
0
  for( uint32_t j = 0; j < numTileRows; j++ )
1819
0
  {
1820
0
    for( uint32_t k = 0; k < numTileCols; k++ )
1821
0
    {
1822
0
      sliceMap[0].addCtusToSlice( tileColBd[tileX + k], tileColBd[tileX + k +1],
1823
0
                                  tileRowBd[tileY + j], tileRowBd[tileY + j +1], picWidthInCtu );
1824
0
    }
1825
0
  }
1826
1827
0
  checkSliceMap();
1828
0
}
1829
1830
void PPS::checkSliceMap()
1831
0
{
1832
0
  uint32_t i;
1833
0
  std::vector<int>  ctuList, sliceList;
1834
0
  uint32_t picSizeInCtu = picWidthInCtu * picHeightInCtu;
1835
0
  for( i = 0; i < numSlicesInPic; i++ )
1836
0
  {
1837
0
    sliceList = sliceMap[ i ].ctuAddrInSlice;
1838
0
    ctuList.insert( ctuList.end(), sliceList.begin(), sliceList.end() );
1839
0
  }
1840
0
  CHECK( ctuList.size() < picSizeInCtu, "Slice map contains too few CTUs");
1841
0
  CHECK( ctuList.size() > picSizeInCtu, "Slice map contains too many CTUs");
1842
0
  std::sort( ctuList.begin(), ctuList.end() );
1843
0
  for( i = 1; i < ctuList.size(); i++ )
1844
0
  {
1845
0
    CHECK( ctuList[i] > ctuList[i-1]+1, "CTU missing in slice map");
1846
0
    CHECK( ctuList[i] == ctuList[i-1],  "CTU duplicated in slice map");
1847
0
  }
1848
0
}
1849
1850
int Slice::getNumEntryPoints( const SPS& sps, const PPS& pps ) const
1851
1.08k
{
1852
1.08k
  if (!sps.entryPointsPresent )
1853
0
  {
1854
0
    return 0;
1855
0
  }
1856
1857
1.08k
  uint32_t ctuAddr, ctuX, ctuY, prevCtuX = 0, prevCtuY = 0;
1858
1.08k
  int numEntryPoints = 0;
1859
1860
  // count the number of CTUs that align with either the start of a tile, or with an entropy coding sync point
1861
  // ignore the first CTU since it doesn't count as an entry point
1862
4.41k
  for( uint32_t i = 0; i < sliceMap.numCtuInSlice; i++ )
1863
3.33k
  {
1864
3.33k
    ctuAddr = sliceMap.ctuAddrInSlice[i];
1865
3.33k
    ctuX = ( ctuAddr % pps.picWidthInCtu );
1866
3.33k
    ctuY = ( ctuAddr / pps.picWidthInCtu );
1867
1868
3.33k
    if( i != 0 && ( pps.tileRowBd[pps.ctuToTileRow[ctuY]] != pps.tileRowBd[pps.ctuToTileRow[prevCtuY]] || pps.tileColBd[pps.ctuToTileCol[ctuX]] != pps.tileColBd[pps.ctuToTileCol[prevCtuX]] || ( ctuY != prevCtuY && sps.entropyCodingSyncEnabled ) ) )
1869
0
    {
1870
0
      numEntryPoints++;
1871
0
    }
1872
    
1873
3.33k
    prevCtuX    = ctuX;
1874
3.33k
    prevCtuY    = ctuY;
1875
3.33k
  }
1876
1.08k
  return numEntryPoints;
1877
1.08k
}
1878
1879
1880
uint32_t PPS::getSubPicIdxFromSubPicId( uint32_t subPicId ) const
1881
1.08k
{
1882
1.08k
  for (int i = 0; i < numSubPics; i++)
1883
0
  {
1884
0
    if(subPics[i].subPicID == subPicId)
1885
0
    {
1886
0
      return i;
1887
0
    }
1888
0
  }
1889
1.08k
  return 0;
1890
1.08k
}
1891
1892
1893
const SubPic& PPS::getSubPicFromPos(const Position& pos)  const
1894
48.7k
{
1895
48.7k
  for (int i = 0; i< numSubPics; i++)
1896
0
  {
1897
0
    if (subPics[i].isContainingPos(pos))
1898
0
    {
1899
0
      return subPics[i];
1900
0
    }
1901
0
  }
1902
48.7k
  return subPics[0];
1903
48.7k
}
1904
1905
1906
const SubPic& PPS::getSubPicFromCU(const CodingUnit& cu) const
1907
3.35k
{
1908
3.35k
  const Position lumaPos = cu.Y().valid() ? cu.Y().pos() : recalcPosition(cu.chromaFormat, cu.chType, CH_L, cu.blocks[cu.chType].pos());
1909
3.35k
  return getSubPicFromPos(lumaPos);
1910
3.35k
}
1911
1912
1913
ReferencePictureList::ReferencePictureList()
1914
110k
  : numberOfShorttermPictures (0)
1915
110k
  , numberOfLongtermPictures  (0)
1916
110k
  , numberOfActivePictures    (0)
1917
110k
  , ltrpInSliceHeader         (0)
1918
110k
  , interLayerPresent     (false)
1919
110k
  , numberOfInterLayerPictures(0)
1920
1921
110k
{
1922
110k
  ::memset(isLongtermRefPic,    0, sizeof(isLongtermRefPic));
1923
110k
  ::memset(refPicIdentifier,    0, sizeof(refPicIdentifier));
1924
110k
  ::memset(deltaPocMSBCycleLT,  0, sizeof(deltaPocMSBCycleLT));
1925
110k
  ::memset(deltaPocMSBPresent,  0, sizeof(deltaPocMSBPresent));
1926
110k
  ::memset(POC,                 0, sizeof(POC));
1927
110k
  ::memset(isInterLayerRefPic,  0, sizeof(isInterLayerRefPic));
1928
110k
  ::memset(interLayerRefPicIdx, 0, sizeof(interLayerRefPicIdx));
1929
110k
}
1930
1931
void ReferencePictureList::initFromGopEntry( const GOPEntry& gopEntry, int l )
1932
52.1k
{
1933
52.1k
  *this = ReferencePictureList();
1934
52.1k
  numberOfShorttermPictures = gopEntry.m_numRefPics[ l ];
1935
52.1k
  numberOfLongtermPictures  = 0;
1936
52.1k
  numberOfActivePictures    = gopEntry.m_numRefPicsActive[ l ];
1937
179k
  for( int j = 0; j < gopEntry.m_numRefPics[ l ]; j++ )
1938
127k
  {
1939
127k
    setRefPicIdentifier( j, -gopEntry.m_deltaRefPics[ l ][ j ], 0, false, 0 );
1940
127k
  }
1941
52.1k
}
1942
1943
void ReferencePictureList::setRefPicIdentifier(int idx, int identifier, bool isLongterm, bool _isInterLayerRefPic, int interLayerIdx)
1944
127k
{
1945
127k
  refPicIdentifier[idx] = identifier;
1946
127k
  isLongtermRefPic[idx] = isLongterm;
1947
1948
127k
  deltaPocMSBPresent[idx] = false;
1949
127k
  deltaPocMSBCycleLT[idx] = 0;
1950
1951
127k
  isInterLayerRefPic[idx] = _isInterLayerRefPic;
1952
127k
  interLayerRefPicIdx[idx] = interLayerIdx;
1953
127k
}
1954
1955
bool ReferencePictureList::isPOCInRefPicList( const int poc, const int currPoc ) const
1956
0
{
1957
0
  for (int i = 0; i < numberOfLongtermPictures + numberOfShorttermPictures; i++)
1958
0
  {
1959
0
    if (isLongtermRefPic[i] ? (poc == refPicIdentifier[i]) : (poc == currPoc - refPicIdentifier[i]) )
1960
0
    {
1961
0
      return true;
1962
0
    }
1963
0
  }
1964
0
  return false;
1965
0
}
1966
1967
1968
ParameterSetManager::ParameterSetManager()
1969
0
: m_spsMap      (MAX_NUM_SPS)
1970
0
, m_ppsMap      (MAX_NUM_PPS)
1971
0
, m_apsMap      (MAX_NUM_APS * MAX_NUM_APS_TYPE)
1972
0
, m_dciMap      (MAX_NUM_DCI)
1973
0
, m_vpsMap      (MAX_NUM_VPS)
1974
0
, m_activeDCIId (-1)
1975
0
, m_activeSPSId (-1)
1976
0
, m_activeVPSId (-1)
1977
0
{
1978
0
}
1979
1980
1981
ParameterSetManager::~ParameterSetManager()
1982
0
{
1983
0
}
1984
1985
1986
//! activate a PPS and depending on isIDR parameter also SPS
1987
//! \returns true, if activation is successful
1988
ParameterSetManager::PPSErrCodes ParameterSetManager::activatePPS(int ppsId, bool isIRAP)
1989
0
{
1990
0
  PPSErrCodes ret=PPS_OK;
1991
1992
0
  PPS *pps = m_ppsMap.getPS(ppsId);
1993
0
  if (pps)
1994
0
  {
1995
0
    int spsId = pps->spsId;
1996
0
    if (!isIRAP && (spsId != m_activeSPSId ))
1997
0
    {
1998
0
      ret=PPS_ERR_INACTIVE_SPS;
1999
0
    }
2000
0
    else
2001
0
    {
2002
0
      SPS *sps = m_spsMap.getPS(spsId);
2003
0
      if (sps)
2004
0
      {
2005
0
        int dciId = sps->dciId;
2006
0
        if ((m_activeDCIId!=-1) && (dciId != m_activeDCIId ))
2007
0
        {
2008
0
          ret=PPS_WARN_DCI_ID;
2009
0
        }
2010
0
        else
2011
0
        {
2012
0
          if (dciId != 0)
2013
0
          {
2014
0
            DCI *dci =m_dciMap.getPS(dciId);
2015
0
            if (dci)
2016
0
            {
2017
0
              m_activeDCIId = dciId;
2018
0
              m_dciMap.setActive(dciId);
2019
0
            }
2020
0
            else
2021
0
            {
2022
0
              ret=PPS_WARN_NO_DCI;
2023
0
            }
2024
0
          }
2025
0
          else
2026
0
          {
2027
            // set zero as active DCI ID (special reserved value, no actual DCI)
2028
0
            m_activeDCIId = dciId;
2029
0
            m_dciMap.setActive(dciId);
2030
0
          }
2031
0
        }
2032
2033
0
        m_spsMap.clearActive();
2034
0
        m_spsMap.setActive(spsId);
2035
0
        m_activeSPSId = spsId;
2036
0
        m_ppsMap.clearActive();
2037
0
        m_ppsMap.setActive(ppsId);
2038
0
        return ret;
2039
0
      }
2040
0
      else
2041
0
      {
2042
0
        ret=PPS_ERR_NO_SPS;
2043
0
      }
2044
0
    }
2045
0
  }
2046
0
  else
2047
0
  {
2048
0
    ret=PPS_ERR_NO_PPS;
2049
0
  }
2050
2051
  // Failed to activate if reach here.
2052
0
  m_activeSPSId=-1;
2053
0
  m_activeDCIId=-1;
2054
0
  return ret;
2055
0
}
2056
2057
bool ParameterSetManager::activateAPS(int apsId, int apsType)
2058
0
{
2059
0
  APS *aps = m_apsMap.getPS((apsId << NUM_APS_TYPE_LEN) + apsType);
2060
0
  if (aps)
2061
0
  {
2062
0
    m_apsMap.setActive((apsId << NUM_APS_TYPE_LEN) + apsType);
2063
0
    return true;
2064
0
  }
2065
2066
0
  return false;
2067
0
}
2068
2069
template <>
2070
void ParameterSetMap<APS>::setID(APS* parameterSet, const int psId)
2071
0
{
2072
0
  parameterSet->apsId = psId;
2073
0
}
2074
template <>
2075
void ParameterSetMap<PPS>::setID(PPS* parameterSet, const int psId)
2076
1.08k
{
2077
1.08k
  parameterSet->ppsId = psId;
2078
1.08k
}
2079
2080
template <>
2081
void ParameterSetMap<SPS>::setID(SPS* parameterSet, const int psId)
2082
1.08k
{
2083
1.08k
  parameterSet->spsId = psId;
2084
1.08k
}
2085
2086
void calculateParameterSetChangedFlag(bool& bChanged, const std::vector<uint8_t>* pOldData, const std::vector<uint8_t>* pNewData)
2087
0
{
2088
0
  if (!bChanged)
2089
0
  {
2090
0
    if ((pOldData==0 && pNewData!=0) || (pOldData!=0 && pNewData==0))
2091
0
    {
2092
0
      bChanged=true;
2093
0
    }
2094
0
    else if (pOldData!=0 && pNewData!=0)
2095
0
    {
2096
      // compare the two
2097
0
      if (pOldData->size() != pNewData->size())
2098
0
      {
2099
0
        bChanged=true;
2100
0
      }
2101
0
      else
2102
0
      {
2103
0
        const uint8_t *pNewDataArray=&(*pNewData)[0];
2104
0
        const uint8_t *pOldDataArray=&(*pOldData)[0];
2105
0
        if (memcmp(pOldDataArray, pNewDataArray, pOldData->size()))
2106
0
        {
2107
0
          bChanged=true;
2108
0
        }
2109
0
      }
2110
0
    }
2111
0
  }
2112
0
}
2113
2114
//! \}
2115
2116
uint32_t PreCalcValues::getValIdx( const Slice &slice, const ChannelType chType ) const
2117
565k
{
2118
565k
  return slice.isIntra() ? ( ISingleTree ? 0 : ( chType << 1 ) ) : 1;
2119
565k
}
2120
2121
uint32_t PreCalcValues::getMaxMTTDepth( const Slice &slice, const ChannelType chType ) const
2122
466k
{
2123
466k
  if ( slice.picHeader->splitConsOverride )
2124
0
    { return slice.sliceType == VVENC_I_SLICE ? ((ISingleTree || CH_L == chType) ? slice.picHeader->maxMTTDepth[0] : slice.picHeader->maxMTTDepth[2]) : slice.picHeader->maxMTTDepth[1]; }
2125
466k
  else
2126
466k
    return maxMTTDepth[getValIdx( slice, chType )];
2127
466k
}
2128
2129
uint32_t PreCalcValues::getMinTSize( const Slice &slice, const ChannelType chType ) const
2130
19.9k
{
2131
19.9k
  return minTSize[getValIdx( slice, chType )];
2132
19.9k
}
2133
2134
uint32_t PreCalcValues::getMaxBtSize( const Slice &slice, const ChannelType chType ) const
2135
19.9k
{
2136
19.9k
  if (slice.picHeader->splitConsOverride)
2137
0
    return slice.picHeader->maxBTSize[getValIdx(slice, ISingleTree ? CH_L : chType)];
2138
19.9k
  else
2139
19.9k
    return maxBtSize[getValIdx(slice, chType)];
2140
19.9k
}
2141
2142
uint32_t PreCalcValues::getMaxTtSize( const Slice &slice, const ChannelType chType ) const
2143
19.9k
{
2144
19.9k
  if ( slice.picHeader->splitConsOverride )
2145
0
    return slice.picHeader->maxTTSize[getValIdx(slice, ISingleTree ? CH_L : chType)];
2146
19.9k
  else
2147
19.9k
    return maxTtSize[getValIdx( slice, chType )];
2148
19.9k
}
2149
2150
uint32_t PreCalcValues::getMinQtSize( const Slice &slice, const ChannelType chType ) const
2151
38.5k
{
2152
38.5k
  if ( slice.picHeader->splitConsOverride )
2153
0
    return slice.picHeader->minQTSize[getValIdx(slice, ISingleTree ? CH_L : chType)];
2154
38.5k
  else
2155
38.5k
    return minQtSize[getValIdx( slice, chType )];
2156
38.5k
}
2157
2158
Area PreCalcValues::getCtuArea( const int ctuPosX, const int ctuPosY ) const
2159
9.99k
{
2160
9.99k
  CHECKD( ctuPosX >= widthInCtus || ctuPosY >= heightInCtus, "CTU idx overflow" );
2161
9.99k
  const int x = ctuPosX << maxCUSizeLog2;
2162
9.99k
  const int y = ctuPosY << maxCUSizeLog2;
2163
9.99k
  const int width = std::min( maxCUSize, lumaWidth - x );
2164
9.99k
  const int height = std::min( maxCUSize, lumaHeight - y );
2165
9.99k
  return Area( x, y, width, height );
2166
9.99k
}
2167
2168
2169
void VPS::deriveOutputLayerSets()
2170
0
{
2171
0
  if( maxLayers == 1 )
2172
0
  {
2173
0
    totalNumOLSs = 1;
2174
0
  }
2175
0
  else if( eachLayerIsAnOls || olsModeIdc < 2 )
2176
0
  {
2177
0
    totalNumOLSs = maxLayers;
2178
0
  }
2179
0
  else if( olsModeIdc == 2 )
2180
0
  {
2181
0
    totalNumOLSs = numOutputLayerSets;
2182
0
  }
2183
2184
0
  olsDpbParamsIdx.resize( totalNumOLSs );
2185
0
  olsDpbPicSize.resize( totalNumOLSs, Size(0, 0) );
2186
0
  numOutputLayersInOls.resize( totalNumOLSs );
2187
0
  numLayersInOls.resize( totalNumOLSs );
2188
0
  outputLayerIdInOls.resize( totalNumOLSs, std::vector<int>( maxLayers, NOT_VALID ) );
2189
0
  layerIdInOls.resize( totalNumOLSs, std::vector<int>( maxLayers, NOT_VALID ) );
2190
2191
0
  std::vector<int> numRefLayers( maxLayers );
2192
0
  std::vector<std::vector<int>> outputLayerIdx( totalNumOLSs, std::vector<int>( maxLayers, NOT_VALID ) );
2193
0
  std::vector<std::vector<int>> layerIncludedInOlsFlag( totalNumOLSs, std::vector<int>( maxLayers, 0 ) );
2194
0
  std::vector<std::vector<int>> dependencyFlag( maxLayers, std::vector<int>( maxLayers, NOT_VALID ) );
2195
0
  std::vector<std::vector<int>> refLayerIdx( maxLayers, std::vector<int>( maxLayers, NOT_VALID ) );
2196
2197
0
  for( int i = 0; i < maxLayers; i++ )
2198
0
  {
2199
0
    int r = 0;
2200
2201
0
    for( int j = 0; j < maxLayers; j++ )
2202
0
    {
2203
0
      dependencyFlag[i][j] = directRefLayer[i][j];
2204
2205
0
      for( int k = 0; k < i; k++ )
2206
0
      {
2207
0
        if( directRefLayer[i][k] && dependencyFlag[k][j] )
2208
0
        {
2209
0
          dependencyFlag[i][j] = 1;
2210
0
        }
2211
0
      }
2212
2213
0
      if( dependencyFlag[i][j] )
2214
0
      {
2215
0
        refLayerIdx[i][r++] = j;
2216
0
      }
2217
0
    }
2218
2219
0
    numRefLayers[i] = r;
2220
0
  }
2221
2222
0
  numOutputLayersInOls[0] = 1;
2223
0
  outputLayerIdInOls[0][0] = layerId[0];
2224
2225
0
  for( int i = 1; i < totalNumOLSs; i++ )
2226
0
  {
2227
0
    if( eachLayerIsAnOls || olsModeIdc == 0 )
2228
0
    {
2229
0
      numOutputLayersInOls[i] = 1;
2230
0
      outputLayerIdInOls[i][0] = layerId[i];
2231
0
    }
2232
0
    else if( olsModeIdc == 1 )
2233
0
    {
2234
0
      numOutputLayersInOls[i] = i + 1;
2235
2236
0
      for( int j = 0; j < numOutputLayersInOls[i]; j++ )
2237
0
      {
2238
0
        outputLayerIdInOls[i][j] = layerId[j];
2239
0
      }
2240
0
    }
2241
0
    else if( olsModeIdc == 2 )
2242
0
    {
2243
0
      int j = 0;
2244
0
      for( int k = 0; k < maxLayers; k++ )
2245
0
      {
2246
0
        if( olsOutputLayer[i][k] )
2247
0
        {
2248
0
          layerIncludedInOlsFlag[i][k] = 1;
2249
0
          outputLayerIdx[i][j] = k;
2250
0
          outputLayerIdInOls[i][j++] = layerId[k];
2251
0
        }
2252
0
      }
2253
0
      numOutputLayersInOls[i] = j;
2254
2255
0
      for( j = 0; j < numOutputLayersInOls[i]; j++ )
2256
0
      {
2257
0
        int idx = outputLayerIdx[i][j];
2258
0
        for( int k = 0; k < numRefLayers[idx]; k++ )
2259
0
        {
2260
0
          layerIncludedInOlsFlag[i][refLayerIdx[idx][k]] = 1;
2261
0
        }
2262
0
      }
2263
0
    }
2264
0
  }
2265
2266
0
  numLayersInOls[0] = 1;
2267
0
  layerIdInOls[0][0] = layerId[0];
2268
2269
0
  for( int i = 1; i < totalNumOLSs; i++ )
2270
0
  {
2271
0
    if( eachLayerIsAnOls )
2272
0
    {
2273
0
      numLayersInOls[i] = 1;
2274
0
      layerIdInOls[i][0] = layerId[i];
2275
0
    }
2276
0
    else if( olsModeIdc == 0 || olsModeIdc == 1 )
2277
0
    {
2278
0
      numLayersInOls[i] = i + 1;
2279
0
      for( int j = 0; j < numLayersInOls[i]; j++ )
2280
0
      {
2281
0
        layerIdInOls[i][j] = layerId[j];
2282
0
      }
2283
0
    }
2284
0
    else if( olsModeIdc == 2 )
2285
0
    {
2286
0
      int j = 0;
2287
0
      for( int k = 0; k < maxLayers; k++ )
2288
0
      {
2289
0
        if( layerIncludedInOlsFlag[i][k] )
2290
0
        {
2291
0
          layerIdInOls[i][j++] = layerId[k];
2292
0
        }
2293
0
      }
2294
2295
0
      numLayersInOls[i] = j;
2296
0
    }
2297
0
  }
2298
0
}
2299
2300
} // namespace vvenc
2301
2302
//! \}
2303