Coverage Report

Created: 2026-10-28 06:18

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