Coverage Report

Created: 2026-08-13 07:23

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