Coverage Report

Created: 2026-04-01 07:49

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