Coverage Report

Created: 2026-05-30 06:10

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.29k
  : ppsId                               ( -1 )
62
//  , picOutputFlag                       ( true )
63
1.29k
  , poc                                 ( 0 )
64
1.29k
  , lastIDR                             ( 0 )
65
1.29k
  , prevGDRInSameLayerPOC               ( 0 )
66
1.29k
  , associatedIRAP                      ( 0 )
67
1.29k
  , associatedIRAPType                  ( VVENC_NAL_UNIT_INVALID )
68
1.29k
  , enableDRAPSEI                       ( false )
69
1.29k
  , useLTforDRAP                        ( false )
70
1.29k
  , isDRAP                              ( false )
71
1.29k
  , latestDRAPPOC                       ( 0 )
72
1.29k
  , colourPlaneId                       ( 0 )
73
1.29k
  , pictureHeaderInSliceHeader          ( true )
74
1.29k
  , nuhLayerId                          ( 0 )
75
1.29k
  , nalUnitType                         ( VVENC_NAL_UNIT_CODED_SLICE_IDR_W_RADL )
76
1.29k
  , sliceType                           ( VVENC_I_SLICE )
77
1.29k
  , sliceQp                             ( 0 )
78
1.29k
  , chromaQpAdjEnabled                  ( false )
79
1.29k
  , lmcsEnabled                         ( 0 )
80
1.29k
  , explicitScalingListUsed             ( 0 )
81
1.29k
  , deblockingFilterDisable             ( false )
82
1.29k
  , deblockingFilterOverride            ( false )
83
1.29k
  , deblockingFilterBetaOffsetDiv2      { 0 }
84
1.29k
  , deblockingFilterTcOffsetDiv2        { 0 }
85
1.29k
  , depQuantEnabled                     ( false )
86
1.29k
  , signDataHidingEnabled               ( false )
87
1.29k
  , tsResidualCodingDisabled            ( false )
88
1.29k
  , pendingRasInit                      ( false )
89
1.29k
  , checkLDC                            ( false )
90
1.29k
  , biDirPred                           ( false )
91
1.29k
  , lmChromaCheckDisable                { false }
92
1.29k
  , symRefIdx                           { -1, -1 }
93
1.29k
  , vps                                 ( nullptr )
94
1.29k
  , dci                                 ( nullptr )
95
1.29k
  , sps                                 ( nullptr )
96
1.29k
  , pps                                 ( nullptr )
97
1.29k
  , pic                                 ( nullptr )
98
1.29k
  , picHeader                           ( nullptr )
99
1.29k
  , colFromL0Flag                       ( true )
100
1.29k
  , colRefIdx                           ( 0 )
101
1.29k
  , TLayer                              ( 0 )
102
1.29k
  , TLayerSwitchingFlag                 ( false )
103
1.29k
  , independentSliceIdx                 ( 0 )
104
1.29k
  , cabacInitFlag                       ( false )
105
1.29k
  , sliceSubPicId                       ( 0 )
106
1.29k
  , encCABACTableIdx                    ( VVENC_I_SLICE )
107
1.29k
  , numAps                     ( 0 )
108
1.29k
  , chromaApsId                ( -1 )
109
1.29k
  , ccAlfCbEnabled             ( false )
110
1.29k
  , ccAlfCrEnabled             ( false )
111
1.29k
  , ccAlfCbApsId               ( -1 )
112
1.29k
  , ccAlfCrApsId               ( -1 )
113
1.29k
  , isLossless                          ( false )
114
1.29k
{
115
1.29k
  ::memset( saoEnabled,              0, sizeof( saoEnabled ) );
116
1.29k
  ::memset( numRefIdx,               0, sizeof( numRefIdx ) );
117
1.29k
  ::memset( sliceChromaQpDelta,      0, sizeof( sliceChromaQpDelta ) );
118
1.29k
  ::memset( lambdas,                 0, sizeof( lambdas ) );
119
1.29k
  ::memset( alfEnabled,              0, sizeof( alfEnabled ) );
120
1.29k
  ::memset( alfAps,                  0, sizeof( alfAps ) );
121
1.29k
  ::memset( refPicList,              0, sizeof( refPicList ) );
122
1.29k
  ::memset( refPOCList,              0, sizeof( refPOCList ) );
123
1.29k
  ::memset( isUsedAsLongTerm,        0, sizeof( isUsedAsLongTerm ) );
124
1.29k
  ::memset( ccAlfFilterControl,      0, sizeof( ccAlfFilterControl ) );
125
126
22.0k
  for ( int idx = 0; idx < MAX_NUM_REF; idx++ )
127
20.7k
  {
128
20.7k
    list1IdxToList0Idx[idx] = -1;
129
20.7k
  }
130
131
3.89k
  for ( int idx = 0; idx < NUM_REF_PIC_LIST_01; idx++ )
132
2.59k
  {
133
2.59k
    rpl[idx]                = nullptr;
134
2.59k
    rplIdx[idx]             = -1;
135
2.59k
  }
136
  
137
1.29k
  resetWpScaling();
138
1.29k
}
139
140
Slice::~Slice()
141
1.29k
{
142
1.29k
}
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.29k
{
171
1.29k
  CHECK( sps.bitDepths[CH_L] != sps.bitDepths[CH_C], "Different luma/chroma bitdepths not supported!" );
172
173
1.29k
  clpRngs.bd = sps.bitDepths[CH_L];
174
1.29k
}
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.29k
{
267
3.89k
  for (int iDir = 0; iDir < NUM_REF_PIC_LIST_01; iDir++)
268
2.59k
  {
269
2.59k
    for (int iNumRefIdx = 0; iNumRefIdx < numRefIdx[iDir]; iNumRefIdx++)
270
0
    {
271
0
      refPOCList[iDir][iNumRefIdx] = refPicList[iDir][iNumRefIdx]->getPOC();
272
0
    }
273
2.59k
  }
274
275
1.29k
}
276
277
void Slice::setSMVDParam()
278
1.29k
{
279
1.29k
  if ( sps->SMVD && checkLDC == false && picHeader->mvdL1Zero == false )
280
1.29k
  {
281
1.29k
    int currPOC  = poc;
282
1.29k
    int forwardPOC = poc;
283
1.29k
    int backwardPOC = poc;
284
1.29k
    int ref = 0;
285
1.29k
    int refIdx0 = -1;
286
1.29k
    int refIdx1 = -1;
287
288
    // search nearest forward POC in List 0
289
1.29k
    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.29k
    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.29k
    if (!(forwardPOC < currPOC && backwardPOC > currPOC))
313
1.29k
    {
314
1.29k
      forwardPOC = currPOC;
315
1.29k
      backwardPOC = currPOC;
316
1.29k
      refIdx0 = -1;
317
1.29k
      refIdx1 = -1;
318
319
      // search nearest backward POC in List 0
320
1.29k
      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.29k
      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.29k
    }
343
344
1.29k
    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.29k
  }
352
353
1.29k
  biDirPred    = false;
354
1.29k
  symRefIdx[0] = -1;
355
1.29k
  symRefIdx[1] = -1;
356
1.29k
}
357
358
void Slice::setList1IdxToList0Idx()
359
1.29k
{
360
1.29k
  int idxL0, idxL1;
361
1.29k
  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.29k
}
374
375
void Slice::constructRefPicList(const PicList& rcListPic, bool extBorder, const bool usingLongTerm)
376
1.29k
{
377
1.29k
  ::memset(isUsedAsLongTerm, 0, sizeof(isUsedAsLongTerm));
378
1.29k
  if (sliceType == VVENC_I_SLICE)
379
1.29k
  {
380
1.29k
    ::memset(refPicList, 0, sizeof(refPicList));
381
1.29k
    ::memset(numRefIdx, 0, sizeof(numRefIdx));
382
1.29k
    return;
383
1.29k
  }
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.59k
{
436
7.78k
  for ( int refList = 0; refList < NUM_REF_PIC_LIST_01; refList++ )
437
5.19k
  {
438
5.19k
    int numOfActiveRef = numRefIdx[ refList ];
439
5.19k
    for ( int i = 0; i < numOfActiveRef; i++ )
440
0
    {
441
0
      refPicList[ refList ][ i ]->refCounter += step;
442
0
    }
443
5.19k
  }
444
2.59k
}
445
446
bool Slice::checkAllRefPicsReconstructed() const
447
1.29k
{
448
3.89k
  for ( int refList = 0; refList < NUM_REF_PIC_LIST_01; refList++ )
449
2.59k
  {
450
2.59k
    int numOfActiveRef = numRefIdx[ refList ];
451
2.59k
    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.59k
  }
459
460
1.29k
  return true;
461
1.29k
}
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.29k
{
564
1.29k
  const bool bEfficientFieldIRAPEnabled = true;
565
1.29k
  Picture* rpcPic;
566
1.29k
  int      pocCurr = poc;
567
568
1.29k
  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.29k
  {
571
    // mark all pictures as not used for reference
572
1.29k
    PicList::const_iterator iterPic = rcListPic.begin();
573
2.59k
    while (iterPic != rcListPic.end())
574
1.29k
    {
575
1.29k
      rpcPic = *(iterPic);
576
1.29k
      if (rpcPic->getPOC() != pocCurr)
577
0
      {
578
0
        rpcPic->isReferenced = false;
579
0
      }
580
1.29k
      iterPic++;
581
1.29k
    }
582
1.29k
    if (bEfficientFieldIRAPEnabled)
583
1.29k
    {
584
1.29k
      bRefreshPending = true;
585
1.29k
    }
586
1.29k
  }
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.29k
}
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.29k
{
753
  // When a picture is a leading picture, it shall be a RADL or RASL picture.
754
1.29k
  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.29k
  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.29k
  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.29k
  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.29k
  PicList::const_iterator iterPic = rcListPic.begin();
791
2.59k
  while ( iterPic != rcListPic.end())
792
1.29k
  {
793
1.29k
    Picture* pic = *(iterPic++);
794
1.29k
    if( ! pic->isReconstructed )
795
1.29k
    {
796
1.29k
      continue;
797
1.29k
    }
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.29k
}
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.29k
{
858
1.29k
  int i, isReference;
859
1.29k
  checkLeadingPictureRestrictions(rcListPic);
860
861
1.29k
  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.29k
  PicList::const_iterator iterPic = rcListPic.begin();
865
2.59k
  while( iterPic != rcListPic.end() )
866
1.29k
  {
867
1.29k
    Picture* pic = *( iterPic++ );
868
869
1.29k
    if( !pic->isReferenced )
870
0
      continue;
871
872
1.29k
    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.29k
    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.29k
    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.29k
    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.29k
  }
952
1.29k
}
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.59k
{
957
2.59k
  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.29k
{
1282
3.89k
  for ( int e=0 ; e<NUM_REF_PIC_LIST_01 ; e++ )
1283
2.59k
  {
1284
44.1k
    for ( int i=0 ; i<MAX_NUM_REF ; i++ )
1285
41.5k
    {
1286
166k
      for ( int yuv=0 ; yuv<MAX_NUM_COMP ; yuv++ )
1287
124k
      {
1288
124k
        WPScalingParam  *pwp = &(weightPredTable[e][i][yuv]);
1289
124k
        pwp->presentFlag     = false;
1290
124k
        pwp->log2WeightDenom = 0;
1291
124k
        pwp->iWeight         = 1;
1292
124k
        pwp->iOffset         = 0;
1293
124k
      }
1294
41.5k
    }
1295
2.59k
  }
1296
1.29k
}
1297
1298
unsigned Slice::getMinPictureDistance() const
1299
4.05k
{
1300
4.05k
  int minPicDist = MAX_INT;
1301
4.05k
  if (sps->IBC)
1302
4.05k
  {
1303
4.05k
    minPicDist = 0;
1304
4.05k
  }
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
4.05k
  return (unsigned) minPicDist;
1322
4.05k
}
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.29k
: spsId                           (  0 )
1435
1.29k
, dciId                           (  0 )
1436
1.29k
, vpsId                           (  0 )
1437
1.29k
, layerId                         ( 0 )
1438
1.29k
, AffineAmvr                      ( false )
1439
1.29k
, DMVR                            ( false )
1440
1.29k
, MMVD                            ( false )
1441
1.29k
, SBT                             ( false )
1442
1.29k
, ISP                             ( false )
1443
1.29k
, chromaFormatIdc                 ( CHROMA_420 )
1444
1.29k
, separateColourPlane             ( false )
1445
1.29k
, maxTLayers                      ( 1 )
1446
1.29k
, ptlDpbHrdParamsPresent          ( true )
1447
1.29k
, subLayerDpbParams               ( false )
1448
1.29k
, maxPicWidthInLumaSamples        ( 352 )
1449
1.29k
, maxPicHeightInLumaSamples       ( 288 )
1450
1.29k
, subPicInfoPresent               ( false )
1451
1.29k
, numSubPics                      ( 0 )
1452
1.29k
, independentSubPicsFlag          ( false )
1453
1.29k
, subPicIdMappingExplicitlySignalled ( false )
1454
1.29k
, log2MinCodingBlockSize          ( 0 )
1455
1.29k
, CTUSize                         ( 0 )
1456
1.29k
, partitionOverrideEnabled        ( 1 )
1457
1.29k
, minQTSize                       { 0, 0, 0 }
1458
1.29k
, maxMTTDepth                     { MAX_BT_DEPTH, MAX_BT_DEPTH_INTER, 0 }
1459
1.29k
, maxBTSize                       { 0,  0,  0 }
1460
1.29k
, maxTTSize                       { 0,  0,  0 }
1461
1.29k
, idrRefParamList                 ( false )
1462
1.29k
, dualITree                       ( 0 )
1463
1.29k
, rpl1CopyFromRpl0                ( false )
1464
1.29k
, rpl1IdxPresent                  ( false )
1465
1.29k
, allRplEntriesHasSameSign        ( true )
1466
1.29k
, longTermRefsPresent             ( false )
1467
1.29k
, temporalMVPEnabled              ( 0 )
1468
1.29k
, transformSkip                   ( false )
1469
1.29k
, log2MaxTransformSkipBlockSize   ( 0 )
1470
1.29k
, BDPCM                           ( false )
1471
1.29k
, jointCbCr                       ( false )
1472
1.29k
, entropyCodingSyncEnabled        ( false )
1473
1.29k
, entryPointsPresent              ( false )
1474
1.29k
, qpBDOffset                      { 0,0 }
1475
1.29k
, internalMinusInputBitDepth      { 0,0 }
1476
1.29k
, SbtMvp                          ( false)
1477
1.29k
, BDOF                            ( false)
1478
1.29k
, fpelMmvd                        ( false )
1479
1.29k
, BdofPresent                     ( false )
1480
1.29k
, DmvrPresent                     ( false )
1481
1.29k
, ProfPresent                     ( false )
1482
1.29k
, bitsForPOC                      ( 8 )
1483
1.29k
, pocMsbFlag                      ( false )
1484
1.29k
, pocMsbLen                       ( 0 )
1485
1.29k
, numExtraPHBitsBytes             ( 0 )
1486
1.29k
, numExtraSHBitsBytes             ( 0 )
1487
1.29k
, numLongTermRefPicSPS            ( 0 )
1488
1.29k
, log2MaxTbSize                   ( 6 )
1489
1.29k
, weightPred                      ( false )
1490
1.29k
, weightedBiPred                  ( false )
1491
1.29k
, saoEnabled                      ( false )
1492
1.29k
, temporalIdNesting               ( false )
1493
1.29k
, scalingListEnabled              ( false )
1494
1.29k
, depQuantEnabled                 ( false )
1495
1.29k
, signDataHidingEnabled           ( false )
1496
1.29k
, virtualBoundariesEnabled        ( false )
1497
1.29k
, virtualBoundariesPresent        ( false )
1498
1.29k
, numVerVirtualBoundaries         ( 0 )
1499
1.29k
, numHorVirtualBoundaries         ( 0 )
1500
1.29k
, virtualBoundariesPosX           { 0,  0,  0 }
1501
1.29k
, virtualBoundariesPosY           { 0,  0,  0 }
1502
1.29k
, hrdParametersPresent            ( false )
1503
1.29k
, subLayerParametersPresent       ( false )
1504
1.29k
, fieldSeqFlag                    ( false )
1505
1.29k
, vuiParametersPresent            ( false )
1506
1.29k
, vuiPayloadSize                  ( 0 )
1507
1.29k
, vuiParameters                   ()
1508
1.29k
, alfEnabled                      ( false )
1509
1.29k
, ccalfEnabled                    ( false )
1510
1.29k
, wrapAroundEnabled               ( false )
1511
1.29k
, IBC                             ( false )
1512
1.29k
, useColorTrans                   ( false )
1513
1.29k
, PLT                             ( false )
1514
1.29k
, lumaReshapeEnable               ( false )
1515
1.29k
, AMVR                            ( false )
1516
1.29k
, LMChroma                        ( false )
1517
1.29k
, horCollocatedChroma             ( false )
1518
1.29k
, verCollocatedChroma             ( false )
1519
1.29k
, MTS                             ( false )
1520
1.29k
, MTSIntra                        ( false )
1521
1.29k
, MTSInter                        ( false )
1522
1.29k
, LFNST                           ( false )
1523
1.29k
, SMVD                            ( false )
1524
1.29k
, Affine                          ( false )
1525
1.29k
, AffineType                      ( false )
1526
1.29k
, PROF                            ( false )
1527
1.29k
, BCW                             ( false )
1528
1.29k
, CIIP                            ( false )
1529
1.29k
, GEO                             ( false )
1530
1.29k
, LADF                            ( false )
1531
1.29k
, MRL                             ( false )
1532
1.29k
, MIP                             ( false )
1533
1.29k
, GDR                             ( true )
1534
1.29k
, subLayerCbpParametersPresent    ( true)
1535
1.29k
, rprEnabled                      ( false )
1536
1.29k
, resChangeInClvsEnabled          ( false )
1537
1.29k
, interLayerPresent               ( false )
1538
1.29k
, log2ParallelMergeLevelMinus2    ( 0 )
1539
1.29k
, maxNumMergeCand                 ( 0 )
1540
1.29k
, maxNumAffineMergeCand           ( 0 )
1541
1.29k
, maxNumIBCMergeCand              ( 0 )
1542
1.29k
, maxNumGeoCand                   ( 0 )
1543
1.29k
, scalingMatrixAlternativeColourSpaceDisabled ( false )
1544
1.29k
, scalingMatrixDesignatedColourSpace          ( false )
1545
1.29k
, disableScalingMatrixForLfnstBlks            ( false )
1546
1547
1.29k
{
1548
3.89k
  for(int ch=0; ch<MAX_NUM_CH; ch++)
1549
2.59k
  {
1550
2.59k
    bitDepths.recon[ch] = 8;
1551
2.59k
    qpBDOffset   [ch] = 0;
1552
2.59k
  }
1553
1554
10.3k
  for ( int i = 0; i < VVENC_MAX_TLAYER; i++ )
1555
9.08k
  {
1556
9.08k
    maxLatencyIncreasePlus1[i] = 0;
1557
9.08k
    maxDecPicBuffering[i] = 1;
1558
9.08k
    numReorderPics[i]       = 0;
1559
9.08k
  }
1560
1561
1.29k
  ::memset(ltRefPicPocLsbSps, 0, sizeof(ltRefPicPocLsbSps));
1562
1.29k
  ::memset(usedByCurrPicLtSPS, 0, sizeof(usedByCurrPicLtSPS));
1563
1564
85.0M
  for( int i = 0; i < MAX_NUM_SUB_PICS; i++ )
1565
85.0M
  {
1566
85.0M
    subPicCtuTopLeftX[i] = 0;
1567
85.0M
    subPicCtuTopLeftY[i] = 0;
1568
85.0M
    subPicWidth[i] = 0;
1569
85.0M
    subPicHeight[i] = 0;
1570
85.0M
    subPicTreatedAsPic[i] = false;
1571
85.0M
    loopFilterAcrossSubpicEnabled[i] = false;
1572
85.0M
    subPicId[i] = 0;
1573
85.0M
  }
1574
1.29k
}
1575
1576
void ChromaQpMappingTable::setParams(const vvencChromaQpMappingTableParams &params, const int qpBdOffset)
1577
1.29k
{
1578
1.29k
  m_qpBdOffset = qpBdOffset;
1579
1.29k
  m_sameCQPTableForAllChromaFlag = params.m_sameCQPTableForAllChromaFlag;
1580
1581
5.19k
  for (int i = 0; i < VVENC_MAX_NUM_CQP_MAPPING_TABLES; i++)
1582
3.89k
  {
1583
3.89k
    m_qpTableStartMinus26[i] = params.m_qpTableStartMinus26[i];
1584
3.89k
    m_numPtsInCQPTableMinus1[i] = params.m_numPtsInCQPTableMinus1[i];
1585
3.89k
    memcpy(m_deltaQpInValMinus1[i], params.m_deltaQpInValMinus1[i], sizeof m_deltaQpInValMinus1[i]);
1586
3.89k
    memcpy(m_deltaQpOutVal[i], params.m_deltaQpOutVal[i], sizeof m_deltaQpOutVal[i]);
1587
3.89k
    m_chromaQpMappingTables[i].resize( MAX_QP + qpBdOffset + 1 );
1588
3.89k
  }
1589
1.29k
}
1590
1591
void ChromaQpMappingTable::derivedChromaQPMappingTables()
1592
1.29k
{
1593
2.59k
  for (int i = 0; i < m_numQpTables; i++)
1594
1.29k
  {
1595
1.29k
    const int qpBdOffsetC = m_qpBdOffset;
1596
1.29k
    const int numPtsInCQPTableMinus1 = m_numPtsInCQPTableMinus1[i];
1597
1.29k
    std::vector<int> qpInVal(numPtsInCQPTableMinus1 + 2), qpOutVal(numPtsInCQPTableMinus1 + 2);
1598
1599
1.29k
    qpInVal[0] = m_qpTableStartMinus26[i] + 26;
1600
1.29k
    qpOutVal[0] = qpInVal[0];
1601
5.19k
    for (int j = 0; j <= m_numPtsInCQPTableMinus1[i]; j++)
1602
3.89k
    {
1603
3.89k
      qpInVal[j+1] = qpInVal[j] + m_deltaQpInValMinus1[i][j] + 1;
1604
3.89k
      qpOutVal[j+1] = qpOutVal[j] + m_deltaQpOutVal[i][j];
1605
3.89k
    }
1606
1607
5.19k
    for (int j = 0; j <= m_numPtsInCQPTableMinus1[i]; j++)
1608
3.89k
    {
1609
3.89k
      CHECK(qpInVal[j]  < -qpBdOffsetC || qpInVal[j]  > MAX_QP, "qpInVal out of range");
1610
3.89k
      CHECK(qpOutVal[j] < -qpBdOffsetC || qpOutVal[j] > MAX_QP, "qpOutVal out of range");
1611
3.89k
    }
1612
1613
1.29k
    m_chromaQpMappingTables[i][qpInVal[0] + qpBdOffsetC] = qpOutVal[0];
1614
23.3k
    for (int k = qpInVal[0] - 1; k >= -qpBdOffsetC; k--)
1615
22.0k
    {
1616
22.0k
      m_chromaQpMappingTables[i][k + qpBdOffsetC] = Clip3(-qpBdOffsetC, MAX_QP, m_chromaQpMappingTables[i][k + 1 + qpBdOffsetC] - 1);
1617
22.0k
    }
1618
5.19k
    for (int j = 0; j <= numPtsInCQPTableMinus1; j++)
1619
3.89k
    {
1620
3.89k
      int sh = (m_deltaQpInValMinus1[i][j] + 1) >> 1;
1621
36.3k
      for (int k = qpInVal[j] + 1, m = 1; k <= qpInVal[j + 1]; k++, m++)
1622
32.4k
      {
1623
32.4k
        m_chromaQpMappingTables[i][k + qpBdOffsetC] = m_chromaQpMappingTables[i][qpInVal[j] + qpBdOffsetC]
1624
32.4k
          + ((qpOutVal[j + 1] - qpOutVal[j]) * m + sh) / (m_deltaQpInValMinus1[i][j]+ 1);
1625
32.4k
      }
1626
3.89k
    }
1627
28.5k
    for (int k = qpInVal[numPtsInCQPTableMinus1+1]+1; k <= MAX_QP; k++)
1628
27.2k
    {
1629
27.2k
      m_chromaQpMappingTables[i][k + qpBdOffsetC] = Clip3(-qpBdOffsetC, MAX_QP, m_chromaQpMappingTables[i][k - 1 + qpBdOffsetC] + 1);
1630
27.2k
    }
1631
1.29k
  }
1632
1.29k
}
1633
1634
1635
PPS::PPS()
1636
1.29k
: ppsId                              (0)
1637
1.29k
, spsId                              (0)
1638
1.29k
, picInitQPMinus26                   (0)
1639
1.29k
, useDQP                             (false)
1640
1.29k
, usePPSChromaTool                   (false)
1641
1.29k
, sliceChromaQpFlag                  (false)
1642
1.29k
, layerId                            (0)
1643
1.29k
, temporalId                         (0)
1644
1.29k
, chromaQpOffset                     { 0 }
1645
1.29k
, jointCbCrQpOffsetPresent           (false)
1646
1.29k
, chromaQpOffsetListLen              (0)
1647
1.29k
, numRefIdxL0DefaultActive           (1)
1648
1.29k
, numRefIdxL1DefaultActive           (1)
1649
1.29k
, rpl1IdxPresent                     (false)
1650
1.29k
, weightPred                         (false)
1651
1.29k
, weightedBiPred                     (0)
1652
1.29k
, outputFlagPresent                  (false)
1653
1.29k
, numSubPics                         (0)
1654
1.29k
, subPicIdMappingInPps               (false)
1655
1.29k
, subPicIdLen                        (0)
1656
//,   subPicId[MAX_NUM_SUB_PICS];        //!< sub-picture ID for each sub-picture in the sequence
1657
1.29k
, noPicPartition                     (false)
1658
1.29k
, log2CtuSize                        (0)
1659
1.29k
, ctuSize                            (0)
1660
1.29k
, picWidthInCtu                      (0)
1661
1.29k
, picHeightInCtu                     (0)
1662
1.29k
, numExpTileCols                     (1)
1663
1.29k
, numExpTileRows                     (1)
1664
1.29k
, numTileCols                        (1)
1665
1.29k
, numTileRows                        (1)
1666
1.29k
, rectSlice                          (true)
1667
1.29k
, singleSlicePerSubPic               (false)
1668
1.29k
, numSlicesInPic                     (1)
1669
1.29k
, tileIdxDeltaPresent                (false)
1670
1.29k
, loopFilterAcrossTilesEnabled       (false)
1671
1.29k
, loopFilterAcrossSlicesEnabled      (false)
1672
1.29k
, cabacInitPresent                   (false)
1673
1.29k
, pictureHeaderExtensionPresent      (false)
1674
1.29k
, sliceHeaderExtensionPresent        (false)
1675
1.29k
, deblockingFilterControlPresent     (true)
1676
1.29k
, deblockingFilterOverrideEnabled    (0)
1677
1.29k
, deblockingFilterDisabled           (true)
1678
1.29k
, deblockingFilterBetaOffsetDiv2     {0}
1679
1.29k
, deblockingFilterTcOffsetDiv2       {0}
1680
1.29k
, listsModificationPresent           (false)
1681
1.29k
, rplInfoInPh                        (false)
1682
1.29k
, dbfInfoInPh                        (false)
1683
1.29k
, saoInfoInPh                        (false)
1684
1.29k
, alfInfoInPh                        (false)
1685
1.29k
, wpInfoInPh                         (false)
1686
1.29k
, qpDeltaInfoInPh                    (false)
1687
1.29k
, mixedNaluTypesInPic                (false)
1688
1.29k
, picWidthInLumaSamples              (0)
1689
1.29k
, picHeightInLumaSamples             (0)
1690
1.29k
, wrapAroundEnabled                  (false)
1691
1.29k
, picWidthMinusWrapAroundOffset      (0)
1692
1.29k
, wrapAroundOffset                   (0)
1693
1.29k
, pcv                                (NULL)
1694
1.29k
{
1695
1.29k
  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.29k
  chromaQpAdjTableIncludingNullEntry[0].u.comp.CrOffset = 0;
1697
1.29k
  chromaQpAdjTableIncludingNullEntry[0].u.comp.JointCbCrOffset = 0;
1698
1.29k
}
1699
1700
PPS::~PPS()
1701
1.29k
{
1702
1.29k
  delete pcv;
1703
1.29k
}
1704
1705
/**
1706
 - initialize tile row/column sizes and boundaries
1707
 */
1708
void PPS::initTiles()
1709
1.29k
{
1710
1.29k
  int colIdx, rowIdx;
1711
1.29k
  int ctuX, ctuY;
1712
1713
  // check explicit tile column sizes
1714
1.29k
  uint32_t  remainingWidthInCtu  = picWidthInCtu;
1715
2.59k
  for( colIdx = 0; colIdx < numExpTileCols; colIdx++ )
1716
1.29k
  {
1717
1.29k
    CHECK(tileColWidth[colIdx] > remainingWidthInCtu,    "Tile column width exceeds picture width");
1718
1.29k
    remainingWidthInCtu -= tileColWidth[colIdx];
1719
1.29k
  }
1720
1721
  // divide remaining picture width into uniform tile columns
1722
1.29k
  uint32_t  uniformTileColWidth = tileColWidth[colIdx-1];
1723
1.29k
  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.29k
  numTileCols = colIdx;
1732
1733
  // check explicit tile row sizes
1734
1.29k
  uint32_t  remainingHeightInCtu  = picHeightInCtu;
1735
2.59k
  for( rowIdx = 0; rowIdx < numExpTileRows; rowIdx++ )
1736
1.29k
  {
1737
1.29k
    CHECK(tileRowHeight[rowIdx] > remainingHeightInCtu,     "Tile row height exceeds picture height");
1738
1.29k
    remainingHeightInCtu -= tileRowHeight[rowIdx];
1739
1.29k
  }
1740
1741
  // divide remaining picture height into uniform tile rows
1742
1.29k
  uint32_t  uniformTileRowHeight = tileRowHeight[rowIdx - 1];
1743
1.29k
  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.29k
  numTileRows = rowIdx;
1751
1752
  // set left column bounaries
1753
1.29k
  tileColBd.push_back( 0 );
1754
2.59k
  for( colIdx = 0; colIdx < numTileCols; colIdx++ )
1755
1.29k
  {
1756
1.29k
    tileColBd.push_back( tileColBd[ colIdx ] + tileColWidth[ colIdx ] );
1757
1.29k
  }
1758
1759
  // set top row bounaries
1760
1.29k
  tileRowBd.push_back( 0 );
1761
2.59k
  for( rowIdx = 0; rowIdx < numTileRows; rowIdx++ )
1762
1.29k
  {
1763
1.29k
    tileRowBd.push_back( tileRowBd[ rowIdx ] + tileRowHeight[ rowIdx ] );
1764
1.29k
  }
1765
1766
  // set right column bounaries
1767
2.59k
  for( colIdx = 0; colIdx < numTileCols; colIdx++ )
1768
1.29k
  {
1769
1.29k
    tileColBdRgt.push_back( std::min( ( tileColBd[ colIdx ] + tileColWidth[ colIdx ] ) << log2CtuSize, picWidthInLumaSamples ) );
1770
1.29k
  }
1771
1772
  // set bottom row bounaries
1773
2.59k
  for( rowIdx = 0; rowIdx < numTileRows; rowIdx++ )
1774
1.29k
  {
1775
1.29k
    tileRowBdBot.push_back( std::min( ( tileRowBd[ rowIdx ] + tileRowHeight[ rowIdx ] ) << log2CtuSize, picHeightInLumaSamples ) );
1776
1.29k
  }
1777
1778
  // set mapping between horizontal CTU address and tile column index
1779
1.29k
  colIdx = 0;
1780
4.83k
  for( ctuX = 0; ctuX <= picWidthInCtu; ctuX++ )
1781
3.53k
  {
1782
3.53k
    if( ctuX == tileColBd[ colIdx + 1 ] )
1783
1.29k
    {
1784
1.29k
      colIdx++;
1785
1.29k
    }
1786
3.53k
    ctuToTileCol.push_back( colIdx );
1787
3.53k
  }
1788
1789
  // set mapping between vertical CTU address and tile row index
1790
1.29k
  rowIdx = 0;
1791
4.86k
  for( ctuY = 0; ctuY <= picHeightInCtu; ctuY++ )
1792
3.56k
  {
1793
3.56k
    if( ctuY == tileRowBd[ rowIdx + 1 ] )
1794
1.29k
    {
1795
1.29k
      rowIdx++;
1796
1.29k
    }
1797
3.56k
    ctuToTileRow.push_back( rowIdx );
1798
3.56k
  }
1799
1.29k
}
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.29k
{
1852
1.29k
  if (!sps.entryPointsPresent )
1853
0
  {
1854
0
    return 0;
1855
0
  }
1856
1857
1.29k
  uint32_t ctuAddr, ctuX, ctuY, prevCtuX = 0, prevCtuY = 0;
1858
1.29k
  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
5.34k
  for( uint32_t i = 0; i < sliceMap.numCtuInSlice; i++ )
1863
4.05k
  {
1864
4.05k
    ctuAddr = sliceMap.ctuAddrInSlice[i];
1865
4.05k
    ctuX = ( ctuAddr % pps.picWidthInCtu );
1866
4.05k
    ctuY = ( ctuAddr / pps.picWidthInCtu );
1867
1868
4.05k
    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
4.05k
    prevCtuX    = ctuX;
1874
4.05k
    prevCtuY    = ctuY;
1875
4.05k
  }
1876
1.29k
  return numEntryPoints;
1877
1.29k
}
1878
1879
1880
uint32_t PPS::getSubPicIdxFromSubPicId( uint32_t subPicId ) const
1881
1.29k
{
1882
1.29k
  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.29k
  return 0;
1890
1.29k
}
1891
1892
1893
const SubPic& PPS::getSubPicFromPos(const Position& pos)  const
1894
58.3k
{
1895
58.3k
  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
58.3k
  return subPics[0];
1903
58.3k
}
1904
1905
1906
const SubPic& PPS::getSubPicFromCU(const CodingUnit& cu) const
1907
4.08k
{
1908
4.08k
  const Position lumaPos = cu.Y().valid() ? cu.Y().pos() : recalcPosition(cu.chromaFormat, cu.chType, CH_L, cu.blocks[cu.chType].pos());
1909
4.08k
  return getSubPicFromPos(lumaPos);
1910
4.08k
}
1911
1912
1913
ReferencePictureList::ReferencePictureList()
1914
132k
  : numberOfShorttermPictures (0)
1915
132k
  , numberOfLongtermPictures  (0)
1916
132k
  , numberOfActivePictures    (0)
1917
132k
  , ltrpInSliceHeader         (0)
1918
132k
  , interLayerPresent     (false)
1919
132k
  , numberOfInterLayerPictures(0)
1920
1921
132k
{
1922
132k
  ::memset(isLongtermRefPic,    0, sizeof(isLongtermRefPic));
1923
132k
  ::memset(refPicIdentifier,    0, sizeof(refPicIdentifier));
1924
132k
  ::memset(deltaPocMSBCycleLT,  0, sizeof(deltaPocMSBCycleLT));
1925
132k
  ::memset(deltaPocMSBPresent,  0, sizeof(deltaPocMSBPresent));
1926
132k
  ::memset(POC,                 0, sizeof(POC));
1927
132k
  ::memset(isInterLayerRefPic,  0, sizeof(isInterLayerRefPic));
1928
132k
  ::memset(interLayerRefPicIdx, 0, sizeof(interLayerRefPicIdx));
1929
132k
}
1930
1931
void ReferencePictureList::initFromGopEntry( const GOPEntry& gopEntry, int l )
1932
62.3k
{
1933
62.3k
  *this = ReferencePictureList();
1934
62.3k
  numberOfShorttermPictures = gopEntry.m_numRefPics[ l ];
1935
62.3k
  numberOfLongtermPictures  = 0;
1936
62.3k
  numberOfActivePictures    = gopEntry.m_numRefPicsActive[ l ];
1937
214k
  for( int j = 0; j < gopEntry.m_numRefPics[ l ]; j++ )
1938
151k
  {
1939
151k
    setRefPicIdentifier( j, -gopEntry.m_deltaRefPics[ l ][ j ], 0, false, 0 );
1940
151k
  }
1941
62.3k
}
1942
1943
void ReferencePictureList::setRefPicIdentifier(int idx, int identifier, bool isLongterm, bool _isInterLayerRefPic, int interLayerIdx)
1944
151k
{
1945
151k
  refPicIdentifier[idx] = identifier;
1946
151k
  isLongtermRefPic[idx] = isLongterm;
1947
1948
151k
  deltaPocMSBPresent[idx] = false;
1949
151k
  deltaPocMSBCycleLT[idx] = 0;
1950
1951
151k
  isInterLayerRefPic[idx] = _isInterLayerRefPic;
1952
151k
  interLayerRefPicIdx[idx] = interLayerIdx;
1953
151k
}
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.29k
{
2077
1.29k
  parameterSet->ppsId = psId;
2078
1.29k
}
2079
2080
template <>
2081
void ParameterSetMap<SPS>::setID(SPS* parameterSet, const int psId)
2082
1.29k
{
2083
1.29k
  parameterSet->spsId = psId;
2084
1.29k
}
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
676k
{
2118
676k
  return slice.isIntra() ? ( ISingleTree ? 0 : ( chType << 1 ) ) : 1;
2119
676k
}
2120
2121
uint32_t PreCalcValues::getMaxMTTDepth( const Slice &slice, const ChannelType chType ) const
2122
556k
{
2123
556k
  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
556k
  else
2126
556k
    return maxMTTDepth[getValIdx( slice, chType )];
2127
556k
}
2128
2129
uint32_t PreCalcValues::getMinTSize( const Slice &slice, const ChannelType chType ) const
2130
24.3k
{
2131
24.3k
  return minTSize[getValIdx( slice, chType )];
2132
24.3k
}
2133
2134
uint32_t PreCalcValues::getMaxBtSize( const Slice &slice, const ChannelType chType ) const
2135
24.3k
{
2136
24.3k
  if (slice.picHeader->splitConsOverride)
2137
0
    return slice.picHeader->maxBTSize[getValIdx(slice, ISingleTree ? CH_L : chType)];
2138
24.3k
  else
2139
24.3k
    return maxBtSize[getValIdx(slice, chType)];
2140
24.3k
}
2141
2142
uint32_t PreCalcValues::getMaxTtSize( const Slice &slice, const ChannelType chType ) const
2143
24.3k
{
2144
24.3k
  if ( slice.picHeader->splitConsOverride )
2145
0
    return slice.picHeader->maxTTSize[getValIdx(slice, ISingleTree ? CH_L : chType)];
2146
24.3k
  else
2147
24.3k
    return maxTtSize[getValIdx( slice, chType )];
2148
24.3k
}
2149
2150
uint32_t PreCalcValues::getMinQtSize( const Slice &slice, const ChannelType chType ) const
2151
46.5k
{
2152
46.5k
  if ( slice.picHeader->splitConsOverride )
2153
0
    return slice.picHeader->minQTSize[getValIdx(slice, ISingleTree ? CH_L : chType)];
2154
46.5k
  else
2155
46.5k
    return minQtSize[getValIdx( slice, chType )];
2156
46.5k
}
2157
2158
Area PreCalcValues::getCtuArea( const int ctuPosX, const int ctuPosY ) const
2159
12.1k
{
2160
12.1k
  CHECKD( ctuPosX >= widthInCtus || ctuPosY >= heightInCtus, "CTU idx overflow" );
2161
12.1k
  const int x = ctuPosX << maxCUSizeLog2;
2162
12.1k
  const int y = ctuPosY << maxCUSizeLog2;
2163
12.1k
  const int width = std::min( maxCUSize, lumaWidth - x );
2164
12.1k
  const int height = std::min( maxCUSize, lumaHeight - y );
2165
12.1k
  return Area( x, y, width, height );
2166
12.1k
}
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