Coverage Report

Created: 2026-10-17 06:56

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/vvdec/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) 2018-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVdeC 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
/** \file     Slice.cpp
44
    \brief    slice header and SPS class
45
*/
46
47
#include "CommonDef.h"
48
#include "Unit.h"
49
#include "Slice.h"
50
#include "Picture.h"
51
#include "dtrace_next.h"
52
53
#include "UnitTools.h"
54
#include "vvdec/sei.h"
55
56
namespace vvdec
57
{
58
59
void VPS::deriveOutputLayerSets()
60
0
{
61
0
  if( m_uiMaxLayers == 1 )
62
0
  {
63
0
    m_totalNumOLSs = 1;
64
0
  }
65
0
  else if( m_vpsEachLayerIsAnOlsFlag || m_vpsOlsModeIdc < 2 )
66
0
  {
67
0
    m_totalNumOLSs = m_uiMaxLayers;
68
0
  }
69
0
  else if( m_vpsOlsModeIdc == 2 )
70
0
  {
71
0
    m_totalNumOLSs = m_vpsNumOutputLayerSets;
72
0
  }
73
74
0
  m_olsDpbParamsIdx.resize( m_totalNumOLSs );
75
0
  m_olsDpbPicSize.resize( m_totalNumOLSs, Size(0, 0) );
76
0
  m_numOutputLayersInOls.resize( m_totalNumOLSs );
77
0
  m_numLayersInOls.resize( m_totalNumOLSs );
78
0
  m_outputLayerIdInOls.resize( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
79
0
  m_layerIdInOls.resize( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
80
81
0
  std::vector<int> numRefLayers( m_uiMaxLayers );
82
0
  std::vector<std::vector<int>> outputLayerIdx( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
83
0
  std::vector<std::vector<int>> layerIncludedInOlsFlag( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, 0 ) );
84
0
  std::vector<std::vector<int>> dependencyFlag( m_uiMaxLayers, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
85
0
  std::vector<std::vector<int>> refLayerIdx( m_uiMaxLayers, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
86
0
  std::vector<int> layerUsedAsRefLayerFlag( m_uiMaxLayers, 0 );
87
0
  std::vector<int> layerUsedAsOutputLayerFlag( m_uiMaxLayers, NOT_VALID );
88
0
  for( int i = 0; i < m_uiMaxLayers; i++ )
89
0
  {
90
0
    int r = 0;
91
92
0
    for( int j = 0; j < m_uiMaxLayers; j++ )
93
0
    {
94
0
      dependencyFlag[i][j] = m_vpsDirectRefLayerFlag[i][j];
95
96
0
      for( int k = 0; k < i; k++ )
97
0
      {
98
0
        if( m_vpsDirectRefLayerFlag[i][k] && dependencyFlag[k][j] )
99
0
        {
100
0
          dependencyFlag[i][j] = 1;
101
0
        }
102
0
      }
103
0
      if (m_vpsDirectRefLayerFlag[i][j])
104
0
      {
105
0
        layerUsedAsRefLayerFlag[j] = 1;
106
0
      }
107
0
      if( dependencyFlag[i][j] )
108
0
      {
109
0
        refLayerIdx[i][r++] = j;
110
0
      }
111
0
    }
112
113
0
    numRefLayers[i] = r;
114
0
  }
115
116
0
  m_numOutputLayersInOls[0] = 1;
117
0
  m_outputLayerIdInOls[0][0] = m_vpsLayerId[0];
118
0
  layerUsedAsOutputLayerFlag[0] = 1;
119
0
  for (int i = 1; i < m_uiMaxLayers; i++)
120
0
  {
121
0
    if (m_vpsEachLayerIsAnOlsFlag || m_vpsOlsModeIdc < 2)
122
0
    {
123
0
      layerUsedAsOutputLayerFlag[i] = 1;
124
0
    }
125
0
    else
126
0
    {
127
0
      layerUsedAsOutputLayerFlag[i] = 0;
128
0
    }
129
0
  }
130
0
  for( int i = 1; i < m_totalNumOLSs; i++ )
131
0
  {
132
0
    if( m_vpsEachLayerIsAnOlsFlag || m_vpsOlsModeIdc == 0 )
133
0
    {
134
0
      m_numOutputLayersInOls[i] = 1;
135
0
      m_outputLayerIdInOls[i][0] = m_vpsLayerId[i];
136
0
    }
137
0
    else if( m_vpsOlsModeIdc == 1 )
138
0
    {
139
0
      m_numOutputLayersInOls[i] = i + 1;
140
141
0
      for( int j = 0; j < m_numOutputLayersInOls[i]; j++ )
142
0
      {
143
0
        m_outputLayerIdInOls[i][j] = m_vpsLayerId[j];
144
0
      }
145
0
    }
146
0
    else if( m_vpsOlsModeIdc == 2 )
147
0
    {
148
0
      int j = 0;
149
0
      for( int k = 0; k < m_uiMaxLayers; k++ )
150
0
      {
151
0
        if( m_vpsOlsOutputLayerFlag[i][k] )
152
0
        {
153
0
          layerIncludedInOlsFlag[i][k] = 1;
154
0
          layerUsedAsOutputLayerFlag[k] = 1;
155
0
          outputLayerIdx[i][j] = k;
156
0
          m_outputLayerIdInOls[i][j++] = m_vpsLayerId[k];
157
0
        }
158
0
      }
159
0
      m_numOutputLayersInOls[i] = j;
160
161
0
      for( j = 0; j < m_numOutputLayersInOls[i]; j++ )
162
0
      {
163
0
        int idx = outputLayerIdx[i][j];
164
0
        for( int k = 0; k < numRefLayers[idx]; k++ )
165
0
        {
166
0
          layerIncludedInOlsFlag[i][refLayerIdx[idx][k]] = 1;
167
0
        }
168
0
      }
169
0
    }
170
0
  }
171
0
  for (int i = 0; i < m_uiMaxLayers; i++)
172
0
  {
173
0
    CHECK(layerUsedAsRefLayerFlag[i] == 0 && layerUsedAsOutputLayerFlag[i] == 0, "There shall be no layer that is neither an output layer nor a direct reference layer");
174
0
  }
175
176
0
  m_numLayersInOls[0]   = 1;
177
0
  m_layerIdInOls[0][0]  = m_vpsLayerId[0];
178
0
  m_numMultiLayeredOlss = 0;
179
180
0
  for( int i = 1; i < m_totalNumOLSs; i++ )
181
0
  {
182
0
    if( m_vpsEachLayerIsAnOlsFlag )
183
0
    {
184
0
      m_numLayersInOls[i] = 1;
185
0
      m_layerIdInOls[i][0] = m_vpsLayerId[i];
186
0
    }
187
0
    else if( m_vpsOlsModeIdc == 0 || m_vpsOlsModeIdc == 1 )
188
0
    {
189
0
      m_numLayersInOls[i] = i + 1;
190
0
      for( int j = 0; j < m_numLayersInOls[i]; j++ )
191
0
      {
192
0
        m_layerIdInOls[i][j] = m_vpsLayerId[j];
193
0
      }
194
0
    }
195
0
    else if( m_vpsOlsModeIdc == 2 )
196
0
    {
197
0
      int j = 0;
198
0
      for( int k = 0; k < m_uiMaxLayers; k++ )
199
0
      {
200
0
        if( layerIncludedInOlsFlag[i][k] )
201
0
        {
202
0
          m_layerIdInOls[i][j++] = m_vpsLayerId[k];
203
0
        }
204
0
      }
205
206
0
      m_numLayersInOls[i] = j;
207
0
    }
208
0
    if( m_numLayersInOls[i] > 1 )
209
0
    {
210
0
      m_multiLayerOlsIdx[i] = m_numMultiLayeredOlss;
211
0
      m_numMultiLayeredOlss++;
212
0
    }
213
0
  }
214
0
  m_multiLayerOlsIdxToOlsIdx.resize(m_numMultiLayeredOlss);
215
216
0
  for (int i=0, j=0; i<m_totalNumOLSs; i++)
217
0
  {
218
0
    if (m_numLayersInOls[i] > 1)
219
0
    {
220
0
      m_multiLayerOlsIdxToOlsIdx[j] = i;
221
0
    }
222
0
  }
223
0
}
224
225
void VPS::checkVPS()
226
0
{
227
0
  for (int multiLayerOlsIdx=0; multiLayerOlsIdx < m_numMultiLayeredOlss; multiLayerOlsIdx++)
228
0
  {
229
0
    const int olsIdx = m_multiLayerOlsIdxToOlsIdx[multiLayerOlsIdx];
230
0
    const int olsHrdIdx = getOlsHrdIdx(multiLayerOlsIdx);
231
0
    const int olsPtlIdx = getOlsPtlIdx(olsIdx);
232
0
    CHECK( getHrdMaxTid(olsHrdIdx) < getPtlMaxTemporalId(olsPtlIdx),
233
0
           "The value of vps_hrd_max_tid[vps_ols_timing_hrd_idx[m]] shall be greater than or equal to "
234
0
           "vps_ptl_max_tid[ vps_ols_ptl_idx[n]] for each m-th multi-layer OLS for m from 0 to "
235
0
           "NumMultiLayerOlss - 1, inclusive, and n being the OLS index of the m-th multi-layer OLS among all OLSs." );
236
0
    const int olsDpbParamsIdx = getOlsDpbParamsIdx(multiLayerOlsIdx);
237
0
    CHECK( m_dpbMaxTemporalId[olsDpbParamsIdx] < getPtlMaxTemporalId(olsPtlIdx),
238
0
           "The value of vps_dpb_max_tid[vps_ols_dpb_params_idx[m]] shall be greater than or equal to "
239
0
           "vps_ptl_max_tid[ vps_ols_ptl_idx[n]] for each m-th multi-layer OLS for m from 0 to "
240
0
           "NumMultiLayerOlss - 1, inclusive, and n being the OLS index of the m-th multi-layer OLS among all OLSs." );
241
0
  }
242
0
}
243
244
void VPS::deriveTargetOutputLayerSet( int targetOlsIdx )
245
0
{
246
0
  m_iTargetLayer = targetOlsIdx < 0 ? m_uiMaxLayers - 1 : targetOlsIdx;
247
0
  m_targetOutputLayerIdSet.clear();
248
0
  m_targetLayerIdSet.clear();
249
250
0
  for( int i = 0; i < m_numOutputLayersInOls[m_iTargetLayer]; i++ )
251
0
  {
252
0
    m_targetOutputLayerIdSet.push_back( m_outputLayerIdInOls[m_iTargetLayer][i] );
253
0
  }
254
255
0
  for( int i = 0; i < m_numLayersInOls[m_iTargetLayer]; i++ )
256
0
  {
257
0
    m_targetLayerIdSet.push_back( m_layerIdInOls[m_iTargetLayer][i] );
258
0
  }
259
0
}
260
261
Slice::Slice()
262
189
{
263
567
  for( uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++ )
264
378
  {
265
6.42k
    for(int iNumCount = 0; iNumCount < MAX_NUM_REF; iNumCount++)
266
6.04k
    {
267
6.04k
      m_apcRefPicList [i][iNumCount] = nullptr;
268
6.04k
      m_aiRefPOCList  [i][iNumCount] = 0;
269
6.04k
    }
270
271
378
    m_apcRefPicList[i][MAX_NUM_REF] = nullptr;
272
378
    m_aiRefPOCList [i][MAX_NUM_REF] = 0;
273
378
  }
274
275
189
  resetWpScaling();
276
189
  initWpAcDcParam();
277
278
189
  clearAlfAPSs();
279
189
}
280
281
282
void Slice::initSlice()
283
6
{
284
18
  for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
285
12
  {
286
12
    m_aiNumRefIdx[i]      = 0;
287
12
  }
288
6
  m_colFromL0Flag = true;
289
6
  m_colRefIdx = 0;
290
291
6
  m_bCheckLDC = false;
292
293
6
  m_biDirPred = false;
294
6
  m_symRefIdx[0] = -1;
295
6
  m_symRefIdx[1] = -1;
296
297
24
  for (uint32_t component = 0; component < MAX_NUM_COMPONENT; component++)
298
18
  {
299
18
    m_iSliceChromaQpDelta[component] = 0;
300
18
  }
301
6
  m_iSliceChromaQpDelta[JOINT_CbCr] = 0;
302
303
304
6
  m_substreamSizes.clear();
305
6
  m_cabacInitFlag        = false;
306
6
  resetAlfEnabledFlag();
307
6
  resetCcAlfEnabledFlags();
308
6
  m_sliceMap.resetSliceMap();
309
6
}
310
311
void Slice::inheritFromPicHeader( const PicHeader* picHeader, const PPS* pps, const SPS* sps )
312
0
{
313
0
  if( pps->getRplInfoInPhFlag() )
314
0
  {
315
0
    for( auto l: { REF_PIC_LIST_0, REF_PIC_LIST_1 } )
316
0
    {
317
#if 0
318
      // this is how it's implemented in VTM, but overridden later in parseSliceHeader()
319
      const int rplIdx = picHeader->getRPLIdx( l );
320
      m_RPLIdx[l]      = rplIdx;
321
      m_RPL[l]         = rplIdx == -1 ? *picHeader->getRPL( l ) : sps->getRPLList( l )[m_RPLIdx[l]];
322
#else
323
      // this is how it's overridden later
324
0
      setRPLIdx( l, picHeader->getRPLIdx( l ) );
325
0
      setRPL( l, *picHeader->getRPL( l ) );
326
0
#endif
327
0
    }
328
0
  }
329
0
  setColFromL0Flag( isInterB() ? picHeader->getPicColFromL0Flag() : true );
330
0
  setColRefIdx( pps->getRplInfoInPhFlag() ? picHeader->getColRefIdx() : 0 );
331
332
0
  if( pps->getQpDeltaInfoInPhFlag() )
333
0
  {
334
0
    setSliceQp( 26 + pps->getPicInitQPMinus26() + picHeader->getQpDelta() );
335
0
  }
336
337
0
  setDeblockingFilterDisable( picHeader->getDeblockingFilterDisable() );
338
0
  setDeblockingFilterBetaOffsetDiv2( picHeader->getDeblockingFilterBetaOffsetDiv2() );
339
0
  setDeblockingFilterTcOffsetDiv2  ( picHeader->getDeblockingFilterTcOffsetDiv2()   );
340
0
  if( pps->getPPSChromaToolFlag() )
341
0
  {
342
0
    setDeblockingFilterCbBetaOffsetDiv2( picHeader->getDeblockingFilterCbBetaOffsetDiv2() );
343
0
    setDeblockingFilterCbTcOffsetDiv2  ( picHeader->getDeblockingFilterCbTcOffsetDiv2()   );
344
0
    setDeblockingFilterCrBetaOffsetDiv2( picHeader->getDeblockingFilterCrBetaOffsetDiv2() );
345
0
    setDeblockingFilterCrTcOffsetDiv2  ( picHeader->getDeblockingFilterCrTcOffsetDiv2()   );
346
0
  }
347
0
  else
348
0
  {
349
0
    setDeblockingFilterCbBetaOffsetDiv2( getDeblockingFilterBetaOffsetDiv2() );
350
0
    setDeblockingFilterCbTcOffsetDiv2  ( getDeblockingFilterTcOffsetDiv2()   );
351
0
    setDeblockingFilterCrBetaOffsetDiv2( getDeblockingFilterBetaOffsetDiv2() );
352
0
    setDeblockingFilterCrTcOffsetDiv2  ( getDeblockingFilterTcOffsetDiv2()   );
353
0
  }
354
355
0
  setSaoEnabledFlag( CHANNEL_TYPE_LUMA,   picHeader->getSaoEnabledFlag( CHANNEL_TYPE_LUMA ) );
356
0
  setSaoEnabledFlag( CHANNEL_TYPE_CHROMA, picHeader->getSaoEnabledFlag( CHANNEL_TYPE_CHROMA ) );
357
358
0
  setAlfEnabledFlag( COMPONENT_Y,  picHeader->getAlfEnabledFlag( COMPONENT_Y ) );
359
0
  setAlfEnabledFlag( COMPONENT_Cb, picHeader->getAlfEnabledFlag( COMPONENT_Cb ) );
360
0
  setAlfEnabledFlag( COMPONENT_Cr, picHeader->getAlfEnabledFlag( COMPONENT_Cr ) );
361
362
0
  setNumAlfAps( picHeader->getNumAlfAps() );
363
0
  setAlfApsIdsLuma( picHeader->getAlfAPSIds() );
364
0
  setAlfApsIdChroma( picHeader->getAlfApsIdChroma() );
365
0
  setCcAlfCbEnabledFlag( picHeader->getCcAlfEnabledFlag( COMPONENT_Cb ) );
366
0
  setCcAlfCrEnabledFlag( picHeader->getCcAlfEnabledFlag( COMPONENT_Cr ) );
367
0
  setCcAlfCbApsId( picHeader->getCcAlfCbApsId() );
368
0
  setCcAlfCrApsId( picHeader->getCcAlfCrApsId() );
369
370
0
  setLmcsEnabledFlag        ( getPictureHeaderInSliceHeader() ? picHeader->getLmcsEnabledFlag()                : false );
371
0
  setExplicitScalingListUsed( getPictureHeaderInSliceHeader() ? picHeader->getExplicitScalingListEnabledFlag() : false );
372
0
}
373
374
void  Slice::setNumEntryPoints( const SPS *sps, const PPS *pps )
375
0
{
376
0
  m_numEntryPoints = 0;
377
378
0
  if( !sps->getEntryPointsPresentFlag() )
379
0
  {
380
0
    return;
381
0
  }
382
383
0
  uint32_t prevCtuX = m_sliceMap.getCtuAddrInSlice( 0 ) % pps->getPicWidthInCtu();
384
0
  uint32_t prevCtuY = m_sliceMap.getCtuAddrInSlice( 0 ) / pps->getPicWidthInCtu();
385
  // count the number of CTUs that align with either the start of a tile, or with an entropy coding sync point
386
  // ignore the first CTU since it doesn't count as an entry point
387
0
  for( uint32_t i = 1; i < m_sliceMap.getNumCtuInSlice(); i++ )
388
0
  {
389
0
    const uint32_t ctuAddr = m_sliceMap.getCtuAddrInSlice( i );
390
0
    const uint32_t ctuX    = ctuAddr % pps->getPicWidthInCtu();
391
0
    const uint32_t ctuY    = ctuAddr / pps->getPicWidthInCtu();
392
393
0
    if( pps->ctuToTileRowBd( ctuY ) != pps->ctuToTileRowBd( prevCtuY )
394
0
        || pps->ctuToTileColBd( ctuX ) != pps->ctuToTileColBd( prevCtuX )
395
0
        || ( ctuY != prevCtuY && sps->getEntropyCodingSyncEnabledFlag() ) )
396
0
    {
397
0
      m_numEntryPoints++;
398
0
    }
399
400
0
    prevCtuX = ctuX;
401
0
    prevCtuY = ctuY;
402
0
  }
403
0
}
404
405
void Slice::setDefaultClpRng( const SPS& sps )
406
0
{
407
0
  m_clpRngs.bd = sps.getBitDepth();
408
0
}
409
410
411
bool Slice::getRapPicFlag() const
412
0
{
413
0
  return getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
414
0
      || getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
415
0
      || getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA;
416
0
}
417
418
Picture* Slice::xGetRefPic( const PicList& rcListPic, int poc, const int layerId )
419
0
{
420
  // return a nullptr, if picture is not found
421
0
  for( auto& pcPic: rcListPic )
422
0
  {
423
0
    if( pcPic && pcPic->getPOC() == poc && pcPic->dpbReferenceMark && pcPic->layerId == layerId )
424
0
    {
425
0
      pcPic->stillReferenced = true;
426
0
      return pcPic;
427
0
    }
428
0
  }
429
430
0
  return nullptr;
431
0
}
432
433
Picture* Slice::xGetLongTermRefPic( const PicList& rcListPic, int poc, bool pocHasMsb, const int layerId, bool getCandidate )
434
0
{
435
0
  for( auto& pcPic: rcListPic )
436
0
  {
437
0
    if( pcPic && pcPic->getPOC() != this->getPOC() && pcPic->dpbReferenceMark && pcPic->layerId == layerId )
438
0
    {
439
0
      if( isLTPocEqual( poc, pcPic->getPOC(), getSPS()->getBitsForPOC(), pocHasMsb ) )
440
0
      {
441
0
        if( getCandidate || pcPic->dpbReferenceMark == Picture::LongTerm )
442
0
        {
443
0
          pcPic->stillReferenced = true;
444
0
          return pcPic;
445
0
        }
446
447
0
        return nullptr;
448
0
      }
449
0
    }
450
0
  }
451
452
0
  return nullptr;
453
0
}
454
455
void Slice::constructRefPicLists( const PicList& rcPicList )
456
0
{
457
0
  ::memset(m_bIsUsedAsLongTerm, 0, sizeof(m_bIsUsedAsLongTerm));
458
0
  if (m_eSliceType == I_SLICE)
459
0
  {
460
0
    ::memset(m_apcRefPicList, 0, sizeof(m_apcRefPicList));
461
0
    ::memset(m_aiRefPOCList, 0, sizeof(m_aiRefPOCList));
462
0
    ::memset(m_aiNumRefIdx, 0, sizeof(m_aiNumRefIdx));
463
0
    return;
464
0
  }
465
466
0
  constructSingleRefPicList( rcPicList, REF_PIC_LIST_0 );
467
0
  constructSingleRefPicList( rcPicList, REF_PIC_LIST_1 );
468
0
}
469
470
void Slice::constructSingleRefPicList( const PicList& rcPicList, RefPicList listId )
471
0
{
472
0
  ReferencePictureList& rRPL = m_RPL[listId];
473
474
0
  uint32_t numOfActiveRef = getNumRefIdx( listId );
475
0
  CHECK( rRPL.getNumRefEntries() < numOfActiveRef,
476
0
         "For each i equal to 0 or 1, num_ref_entries[ i ][ RplsIdx[ i ] ] shall not be less than NumRefIdxActive[ i ]." );
477
0
  for( int ii = 0; ii < rRPL.getNumRefEntries(); ii++ )
478
0
  {
479
0
    Picture* pcRefPic = nullptr;
480
0
    int      refPOC   = 0;
481
482
0
    if( !rRPL.isRefPicLongterm( ii ) )
483
0
    {
484
0
      refPOC   = getPOC() + rRPL.getRefPicIdentifier( ii );
485
      // A same-layer STRP entry must not resolve to the current POC: that is either the current
486
      // picture or a stale POC-colliding picture, neither valid for inter prediction (only the
487
      // separate inter-layer path may reference the current POC, in a different layer).
488
0
      CHECK( refPOC == getPOC(), "An STRP entry must not refer to a picture with the current POC" );
489
0
      pcRefPic = xGetRefPic( rcPicList, refPOC, m_pcPic->layerId );
490
0
      CHECK( !pcRefPic, "Picture pointer missing from ref pic list" );
491
492
0
      pcRefPic->dpbReferenceMark = Picture::ShortTerm;
493
0
    }
494
0
    else
495
0
    {
496
0
      refPOC   = rRPL.calcLTRefPOC( getPOC(), getSPS()->getBitsForPOC(), ii );
497
0
      pcRefPic = xGetLongTermRefPic( rcPicList, refPOC, rRPL.getDeltaPocMSBPresentFlag( ii ), m_pcPic->layerId, true );
498
0
      CHECK( !pcRefPic, "Picture pointer missing from ref pic list" );
499
0
      if( !rRPL.getDeltaPocMSBPresentFlag( ii ) )
500
0
        refPOC = pcRefPic->getPOC();
501
502
0
      CHECK( getPOC() - refPOC >= ( 1 << 24 ),
503
0
             "There shall be no LTRP entry in RefPicList[ 0 ] or RefPicList[ 1 ] for which the difference between the PicOrderCntVal of the"
504
0
             " current picture and the PicOrderCntVal of the picture referred to by the entry is greater than or equal to 2^24." );
505
506
0
      pcRefPic->dpbReferenceMark = Picture::LongTerm;
507
0
    }
508
509
0
    CHECK( pcRefPic->getPOC() != refPOC, "reference picture as wrong POC" );
510
0
    CHECK_FATAL(pcRefPic->chromaFormat != getPic()->chromaFormat,"reference picture has wrong chroma format");
511
    // buffers of a reference decoded under a different SPS may lack the margin or wrap-around buffer prediction relies on
512
0
    CHECK( pcRefPic->margin != getPic()->margin, "reference picture has wrong margin" );
513
0
    CHECK( getSPS()->getUseWrapAround() && !pcRefPic->cs->sps->getUseWrapAround(), "reference picture has no wrap-around buffer" );
514
515
0
    if( ii < numOfActiveRef )
516
0
    {
517
0
      m_apcRefPicList    [listId][ii] = pcRefPic;
518
0
      m_aiRefPOCList     [listId][ii] = refPOC;
519
0
      m_bIsUsedAsLongTerm[listId][ii] = pcRefPic->dpbReferenceMark == Picture::LongTerm;
520
521
0
      CHECK( !m_apcRefPicList[listId][ii] || m_apcRefPicList[listId][ii]->getTLayer() > getTLayer(),
522
0
             "The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall be present in the DPB and shall"
523
0
             " have TemporalId less than or equal to that of the current picture." );
524
0
      CHECK( !m_pcPic, "m_pcPic not set yet" );
525
0
      CHECK( m_apcRefPicList[listId][ii] == m_pcPic || m_apcRefPicList[listId][ii]->cs->picHeader->getNonReferencePictureFlag(),
526
0
             "The picture referred to by each entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall not be the current picture"
527
0
             " and shall have ph_non_ref_pic_flag equal to 0." );
528
0
      CHECK( getNalUnitType() == NAL_UNIT_CODED_SLICE_STSA && m_apcRefPicList[listId][ii]->getTLayer() == getTLayer(),
529
0
             "When the current slice has nal_unit_type equal to STSA_NUT, there shall be no active entry in RefPicList[ 0 ] or RefPicList[ 1 ]"
530
0
             " that has TemporalId equal to that of the current picture and nuh_layer_id equal to that of the current picture." );
531
532
0
      for( int j = 0; j < ii; ++j )
533
0
      {
534
0
        CHECK( m_apcRefPicList[listId][j] == m_apcRefPicList[listId][ii] && m_bIsUsedAsLongTerm[listId][j] != m_bIsUsedAsLongTerm[listId][ii],
535
0
               "An STRP entry in RefPicList[ 0 ] or RefPicList[ 1 ] of a slice of a picture and an LTRP entry in RefPicList[ 0 ] or RefPicList[ 1 ]"
536
0
               " of the same slice or a different slice of the same picture shall not refer to the same picture." )
537
0
      }
538
0
    }
539
0
  }
540
0
}
541
542
void Slice::checkColRefIdx(uint32_t curSliceSegmentIdx, const Picture* pic)
543
0
{
544
0
  int i;
545
0
  Slice* curSlice = pic->slices[curSliceSegmentIdx];
546
0
  int currColRefPOC =  curSlice->getRefPOC( RefPicList(1 - curSlice->getColFromL0Flag()), curSlice->getColRefIdx());
547
548
0
  for(i=curSliceSegmentIdx-1; i>=0; i--)
549
0
  {
550
0
    const Slice* preSlice = pic->slices[i];
551
0
    if(preSlice->getSliceType() != I_SLICE)
552
0
    {
553
0
      const int preColRefPOC  = preSlice->getRefPOC( RefPicList(1 - preSlice->getColFromL0Flag()), preSlice->getColRefIdx());
554
0
      if(currColRefPOC != preColRefPOC)
555
0
      {
556
0
        THROW_RECOVERABLE( "Collocated_ref_idx shall always be the same for all slices of a coded picture!" );
557
0
      }
558
0
      else
559
0
      {
560
0
        break;
561
0
      }
562
0
    }
563
0
  }
564
0
}
565
566
void Slice::checkCRA( int& pocCRA, NalUnitType& associatedIRAPType, const PicList& rcListPic )
567
0
{
568
0
  if( pocCRA < MAX_UINT && getPOC() > pocCRA )
569
0
  {
570
0
    for( int l = 0; l < NUM_REF_PIC_LIST_01; ++l )
571
0
    {
572
0
      const uint32_t numRefPic = m_RPL[l].getNumberOfShorttermPictures() + m_RPL[l].getNumberOfLongtermPictures();
573
0
      for( int i = 0; i < numRefPic; i++ )
574
0
      {
575
0
        if( !m_RPL[l].isRefPicLongterm( i ) )
576
0
        {
577
0
          CHECK( getPOC() + m_RPL[l].getRefPicIdentifier( i ) < pocCRA, "Invalid state" );
578
0
        }
579
0
        else
580
0
        {
581
0
          CHECK( xGetLongTermRefPic( rcListPic, m_RPL[l].getRefPicIdentifier( i ), m_RPL[l].getDeltaPocMSBPresentFlag( i ), m_pcPic->layerId )->getPOC() < pocCRA, "Invalid state" );
582
0
        }
583
0
      }
584
0
    }
585
0
  }
586
0
  if (getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP) // IDR picture found
587
0
  {
588
0
    pocCRA = getPOC();
589
0
    associatedIRAPType = getNalUnitType();
590
0
  }
591
0
  else if (getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA) // CRA picture found
592
0
  {
593
0
    pocCRA = getPOC();
594
0
    associatedIRAPType = getNalUnitType();
595
0
  }
596
0
}
597
598
void Slice::checkSTSA( const PicList& rcListPic )
599
0
{
600
0
  int ii;
601
0
  Picture* pcRefPic = NULL;
602
0
  int numOfActiveRef = getNumRefIdx(REF_PIC_LIST_0);
603
604
0
  for (ii = 0; ii < numOfActiveRef; ii++)
605
0
  {
606
0
    pcRefPic = m_apcRefPicList[REF_PIC_LIST_0][ii];
607
608
0
    if( m_eNalUnitType == NAL_UNIT_CODED_SLICE_STSA && pcRefPic->layerId == m_pcPic->layerId )
609
0
    {
610
0
      CHECK( pcRefPic->tempLayer == m_uiTLayer, "When the current picture is an STSA picture and nuh_layer_id equal to that of the current picture, there shall be no active entry in the RPL that has TemporalId equal to that of the current picture" );
611
0
    }
612
    
613
    // Checking this: "When the current picture is a picture that follows, in decoding order, an STSA picture that has TemporalId equal to that of the current picture, there shall be no
614
    // picture that has TemporalId equal to that of the current picture included as an active entry in RefPicList[ 0 ] or RefPicList[ 1 ] that precedes the STSA picture in decoding order."
615
0
    CHECK(pcRefPic->subLayerNonReferencePictureDueToSTSA, "The RPL of the current picture contains a picture that is not allowed in this temporal layer due to an earlier STSA picture");
616
0
  }
617
618
0
  numOfActiveRef = getNumRefIdx(REF_PIC_LIST_1);
619
0
  for (ii = 0; ii < numOfActiveRef; ii++)
620
0
  {
621
0
    pcRefPic = m_apcRefPicList[REF_PIC_LIST_1][ii];
622
623
0
    if( m_eNalUnitType == NAL_UNIT_CODED_SLICE_STSA && pcRefPic->layerId == m_pcPic->layerId )
624
0
    {
625
0
      CHECK( pcRefPic->tempLayer == m_uiTLayer, "When the current picture is an STSA picture and nuh_layer_id equal to that of the current picture, there shall be no active entry in the RPL that has TemporalId equal to that of the current picture" );
626
0
    }
627
    
628
    // Checking this: "When the current picture is a picture that follows, in decoding order, an STSA picture that has TemporalId equal to that of the current picture, there shall be no
629
    // picture that has TemporalId equal to that of the current picture included as an active entry in RefPicList[ 0 ] or RefPicList[ 1 ] that precedes the STSA picture in decoding order."
630
0
    CHECK(pcRefPic->subLayerNonReferencePictureDueToSTSA, "The active RPL part of the current picture contains a picture that is not allowed in this temporal layer due to an earlier STSA picture");
631
0
  }
632
633
  // If the current picture is an STSA picture, make all reference pictures in the DPB with temporal
634
  // id equal to the temproal id of the current picture sub-layer non-reference pictures. The flag
635
  // subLayerNonReferencePictureDueToSTSA equal to true means that the picture may not be used for
636
  // reference by a picture that follows the current STSA picture in decoding order
637
0
  if (getNalUnitType() == NAL_UNIT_CODED_SLICE_STSA)
638
0
  {
639
0
    for( auto & pcPic: rcListPic )
640
0
    {
641
0
      if( !pcPic->dpbReferenceMark || pcPic->getPOC() == m_iPOC )
642
0
      {
643
0
        continue;
644
0
      }
645
646
0
      if( pcPic->tempLayer == m_uiTLayer )
647
0
      {
648
0
        pcPic->subLayerNonReferencePictureDueToSTSA = true;
649
0
      }
650
0
    }
651
0
  }
652
0
}
653
654
void Slice::checkRPL(const ReferencePictureList* pRPL0, const ReferencePictureList* pRPL1, const int associatedIRAPDecodingOrderNumber, const PicList& rcListPic)
655
0
{
656
0
  Picture* pcRefPic;
657
0
  int refPicPOC;
658
0
  int refPicDecodingOrderNumber;
659
660
0
  int irapPOC = getAssociatedIRAPPOC();
661
  
662
0
  const int                   numEntries[]       = { pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures() + pRPL0->getNumberOfInterLayerPictures(),
663
0
                                                     pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures() + pRPL1->getNumberOfInterLayerPictures() };
664
0
  const int numActiveEntries[] = { getNumRefIdx( REF_PIC_LIST_0 ), getNumRefIdx( REF_PIC_LIST_1 ) };
665
0
  const ReferencePictureList* rpl[] = { pRPL0, pRPL1 };
666
0
  const bool fieldSeqFlag = getSPS()->getFieldSeqFlag();
667
0
  const int layerIdx = m_pcPic->cs->vps == nullptr ? 0 : m_pcPic->cs->vps->getGeneralLayerIdx( m_pcPic->layerId );
668
669
0
  for( int refPicList = 0; refPicList < 2; refPicList++ )
670
0
  {
671
0
    for( int i = 0; i < numEntries[refPicList]; i++ )
672
0
    {
673
0
      if( rpl[refPicList]->isInterLayerRefPic( i ) )
674
0
      {
675
0
        int refLayerId = m_pcPic->cs->vps->getLayerId( m_pcPic->cs->vps->getDirectRefLayerIdx( layerIdx, rpl[refPicList]->getInterLayerRefPicIdx( i ) ) );
676
0
        pcRefPic = xGetRefPic( rcListPic, getPOC(), refLayerId );
677
0
        refPicPOC = pcRefPic->getPOC();
678
0
      }
679
0
      else if( !rpl[refPicList]->isRefPicLongterm( i ) )
680
0
      {
681
0
        refPicPOC = getPOC() + rpl[refPicList]->getRefPicIdentifier(i);
682
0
        pcRefPic = xGetRefPic( rcListPic, refPicPOC, m_pcPic->layerId );
683
0
      }
684
0
      else
685
0
      {
686
0
        int ltrpPoc = rpl[refPicList]->calcLTRefPOC( getPOC(), getSPS()->getBitsForPOC(), i );
687
688
0
        pcRefPic = xGetLongTermRefPic( rcListPic, ltrpPoc, rpl[refPicList]->getDeltaPocMSBPresentFlag( i ), m_pcPic->layerId );
689
0
        refPicPOC = pcRefPic->getPOC();
690
0
      }
691
0
      if( !pcRefPic )
692
0
      {
693
        // can't check decoding order for unavailable reference pictures
694
0
        continue;
695
0
      }
696
0
      refPicDecodingOrderNumber = pcRefPic->getDecodingOrderNumber();
697
698
0
      if( m_eNalUnitType == NAL_UNIT_CODED_SLICE_CRA || m_eNalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL || m_eNalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP )
699
0
      {
700
0
        CHECK( refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "When the current picture, with nuh_layer_id equal to a particular value layerId, "
701
0
          "is an IRAP picture, there shall be no picture referred to by an entry in RefPicList[ 0 ] that precedes, in output order or decoding order, any preceding IRAP picture "
702
0
          "with nuh_layer_id equal to layerId in decoding order (when present)." );
703
0
      }
704
705
0
      if( irapPOC < getPOC() && !fieldSeqFlag )
706
0
      {
707
0
        CHECK( refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "When the current picture follows an IRAP picture having the same value "
708
0
          "of nuh_layer_id and the leading pictures, if any, associated with that IRAP picture, in both decoding order and output order, there shall be no picture referred "
709
0
          "to by an entry in RefPicList[ 0 ] or RefPicList[ 1 ] that precedes that IRAP picture in output order or decoding order." );
710
0
      }
711
712
      // Generated reference picture does not have picture header
713
0
      const bool nonReferencePictureFlag = pcRefPic->slices[0]->getPicHeader() ? pcRefPic->slices[0]->getPicHeader()->getNonReferencePictureFlag()
714
0
                                                                               : pcRefPic->nonReferencePictureFlag;
715
0
      CHECK( pcRefPic == m_pcPic || nonReferencePictureFlag, "The picture referred to by each entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall not be the current picture and shall have ph_non_ref_pic_flag equal to 0" );
716
717
0
      if( i < numActiveEntries[refPicList] )
718
0
      {
719
0
        if( irapPOC < getPOC() )
720
0
        {
721
0
          CHECK( refPicPOC < irapPOC || refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "When the current picture follows an IRAP picture having the same value "
722
0
            "of nuh_layer_id in both decoding order and output order, there shall be no picture referred to by an active entry in RefPicList[ 0 ] or RefPicList[ 1 ] that "
723
0
            "precedes that IRAP picture in output order or decoding order." );
724
0
        }
725
726
        // Checking this: "When the current picture is a RADL picture, there shall be no active entry in RefPicList[ 0 ] or
727
        // RefPicList[ 1 ] that is any of the following: A picture that precedes the associated IRAP picture in decoding order"
728
0
        if( m_eNalUnitType == NAL_UNIT_CODED_SLICE_RADL )
729
0
        {
730
0
          CHECK( refPicDecodingOrderNumber < associatedIRAPDecodingOrderNumber, "RADL picture detected that violate the rule that no active entry in RefPicList[] shall precede the associated IRAP picture in decoding order" );
731
0
        }
732
733
0
        CHECK( pcRefPic->tempLayer > m_pcPic->tempLayer, "The picture referred to by each active entry in RefPicList[ 0 ] or RefPicList[ 1 ] shall be present in the DPB and shall have TemporalId less than or equal to that of the current picture." );
734
0
      }
735
0
    }
736
0
  }
737
0
}
738
739
void Slice::copySliceInfo( Slice* pSrc, bool cpyAlmostAll )
740
0
{
741
0
  CHECK_FATAL( !pSrc, "Source is NULL" );
742
743
0
  m_iPOC         = pSrc->m_iPOC;
744
0
  m_eNalUnitType = pSrc->m_eNalUnitType;
745
0
  m_eSliceType   = pSrc->m_eSliceType;
746
0
  m_uiTLayer     = pSrc->m_uiTLayer;
747
748
0
  m_clpRngs      = pSrc->m_clpRngs;
749
0
  m_iSliceQp     = pSrc->m_iSliceQp;
750
751
0
  m_bCheckLDC    = pSrc->m_bCheckLDC;
752
0
  m_iLastIDR     = pSrc->m_iLastIDR;
753
754
0
  m_pcPicHeader  = pSrc->m_pcPicHeader;
755
0
  if( cpyAlmostAll )
756
0
  {
757
0
    m_pcPic      = pSrc->m_pcPic;
758
0
  }
759
760
  // TODO: check remaining fields if it really makes sense to copy (GH)
761
762
0
  m_sliceMap     = pSrc->m_sliceMap;
763
764
0
  m_biDirPred    = pSrc->m_biDirPred;
765
0
  m_symRefIdx[0] = pSrc->m_symRefIdx[0];
766
0
  m_symRefIdx[1] = pSrc->m_symRefIdx[1];
767
768
0
  memcpy( m_apcRefPicList,     pSrc->m_apcRefPicList,     sizeof( m_apcRefPicList ) );
769
0
  memcpy( m_aiRefPOCList,      pSrc->m_aiRefPOCList,      sizeof( m_aiRefPOCList ) );
770
0
  memcpy( m_bIsUsedAsLongTerm, pSrc->m_bIsUsedAsLongTerm, sizeof( m_bIsUsedAsLongTerm ) );
771
0
  if( cpyAlmostAll )
772
0
  {
773
0
    memcpy( m_RPL,             pSrc->m_RPL,               sizeof( m_RPL ) );
774
0
  }
775
0
  memcpy( m_weightPredTable,   pSrc->m_weightPredTable,   sizeof( m_weightPredTable ) );
776
0
}
777
778
void Slice::checkLeadingPictureRestrictions( const PicList & rcListPic ) const
779
0
{
780
0
  int nalUnitType = this->getNalUnitType();
781
782
  // When a picture is a leading picture, it shall be a RADL or RASL picture.
783
0
  if(this->getAssociatedIRAPPOC() > this->getPOC())
784
0
  {
785
    // Do not check IRAP pictures since they may get a POC lower than their associated IRAP
786
0
    if (nalUnitType < NAL_UNIT_CODED_SLICE_IDR_W_RADL ||
787
0
        nalUnitType > NAL_UNIT_CODED_SLICE_CRA)
788
0
    {
789
0
      CHECK(nalUnitType != NAL_UNIT_CODED_SLICE_RASL &&
790
0
            nalUnitType != NAL_UNIT_CODED_SLICE_RADL, "Invalid NAL unit type");
791
0
    }
792
0
  }
793
794
  // When a picture is a trailing picture, it shall not be a RADL or RASL picture.
795
0
  if(this->getAssociatedIRAPPOC() < this->getPOC())
796
0
  {
797
0
    CHECK(nalUnitType == NAL_UNIT_CODED_SLICE_RASL ||
798
0
          nalUnitType == NAL_UNIT_CODED_SLICE_RADL, "Invalid NAL unit type");
799
0
  }
800
801
802
  // No RASL pictures shall be present in the bitstream that are associated with
803
  // an IDR picture.
804
0
  if (nalUnitType == NAL_UNIT_CODED_SLICE_RASL)
805
0
  {
806
0
    CHECK( this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_IDR_N_LP   ||
807
0
           this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL, "Invalid NAL unit type");
808
0
  }
809
810
  // No RADL pictures shall be present in the bitstream that are associated with
811
  // a BLA picture having nal_unit_type equal to BLA_N_LP or that are associated
812
  // with an IDR picture having nal_unit_type equal to IDR_N_LP.
813
0
  if (nalUnitType == NAL_UNIT_CODED_SLICE_RADL)
814
0
  {
815
0
    CHECK (this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_IDR_N_LP, "Invalid NAL unit type");
816
0
  }
817
818
  // loop through all pictures in the reference picture buffer
819
0
  for( auto & pcPic: rcListPic )
820
0
  {
821
0
    if( pcPic->progress < Picture::reconstructed || pcPic->wasLost || pcPic->error )
822
0
    {
823
0
      continue;
824
0
    }
825
0
    if( pcPic->poc == this->getPOC())
826
0
    {
827
0
      continue;
828
0
    }
829
0
    const Slice* pcSlice = pcPic->slices[0];
830
831
    // Any picture that has PicOutputFlag equal to 1 that precedes an IRAP picture
832
    // in decoding order shall precede the IRAP picture in output order.
833
    // (Note that any picture following in output order would be present in the DPB)
834
//    if(pcSlice->getPicHeader()->getPicOutputFlag() == 1 && !this->getPicHeader()->getNoOutputOfPriorPicsFlag())
835
0
    if(pcSlice->getPicHeader()->getPicOutputFlag() == 1 && !this->getNoOutputOfPriorPicsFlag()) 
836
0
    {
837
0
      if (nalUnitType == NAL_UNIT_CODED_SLICE_CRA ||
838
0
          nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP ||
839
0
          nalUnitType == NAL_UNIT_CODED_SLICE_IDR_W_RADL)
840
0
      {
841
0
        CHECK(pcPic->poc >= this->getPOC(), "Invalid POC");
842
0
      }
843
0
    }
844
845
    // Any picture that has PicOutputFlag equal to 1 that precedes an IRAP picture
846
    // in decoding order shall precede any RADL picture associated with the IRAP
847
    // picture in output order.
848
0
    if(pcSlice->getPicHeader()->getPicOutputFlag() == 1)
849
0
    {
850
0
      if (nalUnitType == NAL_UNIT_CODED_SLICE_RADL)
851
0
      {
852
        // rpcPic precedes the IRAP in decoding order
853
0
        if(this->getAssociatedIRAPPOC() > pcSlice->getAssociatedIRAPPOC())
854
0
        {
855
          // rpcPic must not be the IRAP picture
856
0
          if(this->getAssociatedIRAPPOC() != pcPic->poc)
857
0
          {
858
0
            CHECK( pcPic->poc >= this->getPOC(), "Invalid POC");
859
0
          }
860
0
        }
861
0
      }
862
0
    }
863
864
    // When a picture is a leading picture, it shall precede, in decoding order,
865
    // all trailing pictures that are associated with the same IRAP picture.
866
0
    if (nalUnitType == NAL_UNIT_CODED_SLICE_RASL ||
867
0
        nalUnitType == NAL_UNIT_CODED_SLICE_RADL )
868
0
      {
869
0
        if(pcSlice->getAssociatedIRAPPOC() == this->getAssociatedIRAPPOC())
870
0
        {
871
          // rpcPic is a picture that preceded the leading in decoding order since it exist in the DPB
872
          // rpcPic would violate the constraint if it was a trailing picture
873
0
          CHECK( pcPic->poc > this->getAssociatedIRAPPOC(), "Invalid POC");
874
0
        }
875
0
      }
876
877
    // Any RASL picture associated with a CRA or BLA picture shall precede any
878
    // RADL picture associated with the CRA or BLA picture in output order
879
0
    if (nalUnitType == NAL_UNIT_CODED_SLICE_RASL)
880
0
    {
881
0
      if ((this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_CRA) &&
882
0
          this->getAssociatedIRAPPOC() == pcSlice->getAssociatedIRAPPOC())
883
0
      {
884
0
        if (pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_RADL)
885
0
        {
886
0
          CHECK( pcPic->poc <= this->getPOC(), "Invalid POC");
887
0
        }
888
0
      }
889
0
    }
890
891
    // Any RASL picture associated with a CRA picture shall follow, in output
892
    // order, any IRAP picture that precedes the CRA picture in decoding order.
893
0
    if (nalUnitType == NAL_UNIT_CODED_SLICE_RASL)
894
0
    {
895
0
      if(this->getAssociatedIRAPType() == NAL_UNIT_CODED_SLICE_CRA)
896
0
      {
897
0
        if(pcSlice->getPOC() < this->getAssociatedIRAPPOC() &&
898
0
          (
899
0
            pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP   ||
900
0
            pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL ||
901
0
            pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA))
902
0
        {
903
0
          CHECK(this->getPOC() <= pcSlice->getPOC(), "Invalid POC");
904
0
        }
905
0
      }
906
0
    }
907
0
  }
908
0
}
909
910
bool Slice::checkThatAllRefPicsAreAvailable( const PicList&              rcListPic,
911
                                             const ReferencePictureList* pRPL,
912
                                             int                         numActiveRefPics,
913
                                             int*                        missingPOC,
914
                                             int*                        missingRefPicIndex ) const
915
0
{
916
0
  if( this->isIDR() )
917
0
    return true;   // Assume that all pic in the DPB will be flushed anyway so no need to check.
918
919
0
  *missingPOC         = 0;
920
0
  *missingRefPicIndex = 0;
921
922
  // Check long term ref pics
923
0
  for( int ii = 0; pRPL->getNumberOfLongtermPictures() > 0 && ii < numActiveRefPics; ii++ )
924
0
  {
925
0
    if( !pRPL->isRefPicLongterm( ii ) )
926
0
      continue;
927
928
0
    const int checkPoc    = pRPL->getRefPicIdentifier( ii );
929
0
    bool      isAvailable = 0;
930
0
    for( auto& rpcPic: rcListPic )
931
0
    {
932
0
      const int bitsForPoc = rpcPic->cs->sps->getBitsForPOC();
933
0
      const int poc        = rpcPic->getPOC();
934
0
      const int refPoc     = pRPL->calcLTRefPOC( this->getPOC(), bitsForPoc, ii );
935
936
0
      if( rpcPic->dpbReferenceMark == Picture::LongTerm && isLTPocEqual( poc, refPoc, bitsForPoc, pRPL->getDeltaPocMSBPresentFlag( ii ) )  )
937
0
      {
938
0
        isAvailable = 1;
939
0
        break;
940
0
      }
941
0
    }
942
0
    if( isAvailable )
943
0
      continue;
944
945
    // if there was no such long-term check the short terms
946
0
    for( auto& rpcPic: rcListPic )
947
0
    {
948
0
      const int bitsForPoc = rpcPic->cs->sps->getBitsForPOC();
949
0
      const int poc        = rpcPic->getPOC();
950
0
      const int refPoc     = pRPL->calcLTRefPOC( this->getPOC(), bitsForPoc, ii );
951
952
0
      if( rpcPic->dpbReferenceMark == Picture::ShortTerm && isLTPocEqual( poc, refPoc, bitsForPoc, pRPL->getDeltaPocMSBPresentFlag( ii ) )  )
953
0
      {
954
0
        isAvailable      = 1;
955
0
        rpcPic->dpbReferenceMark  = Picture::LongTerm;
956
0
        break;
957
0
      }
958
0
    }
959
960
0
    if( !isAvailable )
961
0
    {
962
0
      msg( ERROR, "Current picture: %d Long-term reference picture with POC = %3d seems to have been removed or not correctly decoded.\n", this->getPOC(), checkPoc );
963
964
0
      *missingPOC         = checkPoc;
965
0
      *missingRefPicIndex = ii;
966
0
      return false;
967
0
    }
968
0
  }
969
970
  // Check short term ref pics
971
0
  for( int ii = 0; ii < numActiveRefPics; ii++ )
972
0
  {
973
0
    if( pRPL->isRefPicLongterm( ii ) )
974
0
      continue;
975
976
0
    const int checkPoc    = this->getPOC() + pRPL->getRefPicIdentifier( ii );
977
0
    bool      isAvailable = false;
978
0
    for( auto& rpcPic: rcListPic )
979
0
    {
980
0
      if( rpcPic->getPOC() == checkPoc && rpcPic->dpbReferenceMark )
981
0
      {
982
0
        isAvailable = true;
983
0
        break;
984
0
      }
985
0
    }
986
987
    // report that a picture is lost if it is in the Reference Picture List but not in the DPB
988
0
    if( !isAvailable && pRPL->getNumberOfShorttermPictures() > 0 )
989
0
    {
990
0
      msg( ERROR, "Current picture: %d Short-term reference picture with POC = %3d seems to have been removed or not correctly decoded.\n", this->getPOC(), checkPoc );
991
992
0
      *missingPOC         = checkPoc;
993
0
      *missingRefPicIndex = ii;
994
0
      return false;
995
0
    }
996
0
  }
997
998
0
  return true;
999
0
}
1000
1001
//! get AC and DC values for weighted pred
1002
void  Slice::getWpAcDcParam(const WPACDCParam *&wp) const
1003
0
{
1004
0
  wp = m_weightACDCParam;
1005
0
}
1006
1007
//! init AC and DC values for weighted pred
1008
void  Slice::initWpAcDcParam()
1009
189
{
1010
756
  for(int iComp = 0; iComp < MAX_NUM_COMPONENT; iComp++ )
1011
567
  {
1012
567
    m_weightACDCParam[iComp].iAC = 0;
1013
567
    m_weightACDCParam[iComp].iDC = 0;
1014
567
  }
1015
189
}
1016
1017
//! get tables for weighted prediction
1018
void Slice::getWpScaling( RefPicList e, int iRefIdx, const WPScalingParam*& wp ) const
1019
0
{
1020
0
  CHECK( e >= NUM_REF_PIC_LIST_01, "Invalid picture reference list" );
1021
0
  wp = m_weightPredTable[e][iRefIdx >= 0 ? iRefIdx : 0];   // iRefIdx can be -1
1022
0
}
1023
1024
void Slice::getWpScaling( RefPicList e, int iRefIdx, WPScalingParam*& wp )
1025
0
{
1026
0
  CHECK( e >= NUM_REF_PIC_LIST_01, "Invalid picture reference list" );
1027
0
  wp = m_weightPredTable[e][iRefIdx >= 0 ? iRefIdx : 0];   // iRefIdx can be -1
1028
0
}
1029
1030
//! reset Default WP tables settings : no weight.
1031
void  Slice::resetWpScaling()
1032
189
{
1033
567
  for ( int e=0 ; e<NUM_REF_PIC_LIST_01 ; e++ )
1034
378
  {
1035
6.42k
    for ( int i=0 ; i<MAX_NUM_REF ; i++ )
1036
6.04k
    {
1037
24.1k
      for ( int yuv=0 ; yuv<MAX_NUM_COMPONENT ; yuv++ )
1038
18.1k
      {
1039
18.1k
        WPScalingParam  *pwp = &(m_weightPredTable[e][i][yuv]);
1040
18.1k
        pwp->bPresentFlag      = false;
1041
18.1k
        pwp->uiLog2WeightDenom = 0;
1042
18.1k
        pwp->uiLog2WeightDenom = 0;
1043
18.1k
        pwp->iWeight           = 1;
1044
18.1k
        pwp->iOffset           = 0;
1045
18.1k
      }
1046
6.04k
    }
1047
378
  }
1048
189
}
1049
1050
//! init WP table
1051
void  Slice::initWpScaling(const SPS *sps)
1052
0
{
1053
0
  const bool bUseHighPrecisionPredictionWeighting = false;// sps->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag();
1054
0
  for ( int e=0 ; e<NUM_REF_PIC_LIST_01 ; e++ )
1055
0
  {
1056
0
    for ( int i=0 ; i<MAX_NUM_REF ; i++ )
1057
0
    {
1058
0
      for ( int yuv=0 ; yuv<MAX_NUM_COMPONENT ; yuv++ )
1059
0
      {
1060
0
        WPScalingParam  *pwp = &(m_weightPredTable[e][i][yuv]);
1061
0
        if ( !pwp->bPresentFlag )
1062
0
        {
1063
          // Inferring values not present :
1064
0
          pwp->iWeight = (1 << pwp->uiLog2WeightDenom);
1065
0
          pwp->iOffset = 0;
1066
0
        }
1067
1068
0
        const int offsetScalingFactor = bUseHighPrecisionPredictionWeighting ? 1 : ( 1 << ( sps->getBitDepth() - 8 ) );
1069
1070
0
        pwp->w      = pwp->iWeight;
1071
0
        pwp->o      = pwp->iOffset * offsetScalingFactor; //NOTE: This value of the ".o" variable is never used - .o is set immediately before it gets used
1072
0
        pwp->shift  = pwp->uiLog2WeightDenom;
1073
0
        pwp->round  = (pwp->uiLog2WeightDenom>=1) ? (1 << (pwp->uiLog2WeightDenom-1)) : (0);
1074
0
      }
1075
0
    }
1076
0
  }
1077
0
}
1078
1079
void PicHeader::getWpScaling(RefPicList e, int iRefIdx, WPScalingParam *&wp) const
1080
0
{
1081
0
  CHECK(e >= NUM_REF_PIC_LIST_01, "Invalid picture reference list");
1082
0
  wp = (WPScalingParam *) m_weightPredTable[e][iRefIdx];
1083
0
}
1084
1085
// ------------------------------------------------------------------------------------------------
1086
// Sequence parameter set (SPS)
1087
// ------------------------------------------------------------------------------------------------
1088
1089
1090
1091
RPLList& SPS::createRPLList( int l, int numRPL )
1092
0
{
1093
0
  m_RPLList[l].resize( numRPL );
1094
0
  m_numRPL[l] = numRPL;
1095
0
  m_rpl1IdxPresentFlag = ( m_RPLList[0].size() != m_RPLList[1].size() );
1096
0
  return m_RPLList[l];
1097
0
}
1098
1099
1100
const int SPS::m_winUnitX[] = { 1,2,2,1 };
1101
const int SPS::m_winUnitY[] = { 1,2,1,1 };
1102
1103
1104
void ChromaQpMappingTable::deriveChromaQPMappingTables()
1105
0
{
1106
0
  for (int i = 0; i < getNumQpTables(); i++)
1107
0
  {
1108
0
    const int qpBdOffsetC = m_qpBdOffset;
1109
0
    const int numPtsInCQPTableMinus1 = getNumPtsInCQPTableMinus1(i);
1110
0
    std::vector<int> qpInVal( numPtsInCQPTableMinus1 + 2 );
1111
0
    std::vector<int> qpOutVal( numPtsInCQPTableMinus1 + 2 );
1112
1113
0
    qpInVal[0] = getQpTableStartMinus26(i) + 26;
1114
0
    qpOutVal[0] = qpInVal[0];
1115
0
    for (int j = 0; j <= numPtsInCQPTableMinus1; j++)
1116
0
    {
1117
0
      qpInVal[j + 1] = qpInVal[j] + getDeltaQpInValMinus1(i, j) + 1;
1118
0
      qpOutVal[j + 1] = qpOutVal[j] + getDeltaQpOutVal(i, j);
1119
0
    }
1120
1121
0
    for( int j = 0; j <= numPtsInCQPTableMinus1 + 1; j++ )
1122
0
    {
1123
0
      CHECK(qpInVal[j]  < -qpBdOffsetC || qpInVal[j]  > MAX_QP, "qpInVal out of range");
1124
0
      CHECK(qpOutVal[j] < -qpBdOffsetC || qpOutVal[j] > MAX_QP, "qpOutVal out of range");
1125
0
    }
1126
1127
0
    m_chromaQpMappingTables[i].resize( MAX_QP + qpBdOffsetC + 1 );
1128
0
    m_chromaQpMappingTables[i][qpInVal[0] + qpBdOffsetC] = qpOutVal[0];   // +qpBdOffsetC, because we use a vector here, instead of a map as in VTM
1129
0
    for( int k = qpInVal[0] - 1; k >= -qpBdOffsetC; k-- )
1130
0
    {
1131
0
      m_chromaQpMappingTables[i][k + qpBdOffsetC] = Clip3( -qpBdOffsetC, MAX_QP, m_chromaQpMappingTables[i][k + 1 + qpBdOffsetC] - 1 );
1132
0
    }
1133
0
    for( int j = 0; j <= numPtsInCQPTableMinus1; j++ )
1134
0
    {
1135
0
      int sh = ( getDeltaQpInValMinus1( i, j ) + 1 ) >> 1;
1136
0
      for( int k = qpInVal[j] + 1, m = 1; k <= qpInVal[j + 1]; k++, m++ )
1137
0
      {
1138
0
        m_chromaQpMappingTables[i][k + qpBdOffsetC] =
1139
0
          m_chromaQpMappingTables[i][qpInVal[j] + qpBdOffsetC] + ( ( qpOutVal[j + 1] - qpOutVal[j] ) * m + sh ) / ( getDeltaQpInValMinus1( i, j ) + 1 );
1140
0
      }
1141
0
    }
1142
0
    for( int k = qpInVal[numPtsInCQPTableMinus1 + 1] + 1; k <= MAX_QP; k++ )
1143
0
    {
1144
0
      m_chromaQpMappingTables[i][k + qpBdOffsetC] = Clip3( -qpBdOffsetC, MAX_QP, m_chromaQpMappingTables[i][k - 1 + qpBdOffsetC] + 1 );
1145
0
    }
1146
0
  }
1147
0
}
1148
1149
1150
void PPS::resetTileSliceInfo()
1151
0
{
1152
0
  m_numExpTileCols = 0;
1153
0
  m_numExpTileRows = 0;
1154
0
  m_numTileCols    = 0;
1155
0
  m_numTileRows    = 0;
1156
0
  m_numSlicesInPic = 0;
1157
0
  m_tileColumnWidth.clear();
1158
0
  m_tileRowHeight.clear();
1159
0
  m_tileColBd.clear();
1160
0
  m_tileRowBd.clear();
1161
0
  m_ctuToTileCol.clear();
1162
0
  m_ctuToTileRow.clear();
1163
0
  m_rectSlices.clear();
1164
0
  m_sliceMap.clear();
1165
0
}
1166
1167
/**
1168
 - initialize tile row/column sizes and boundaries
1169
 */
1170
void PPS::initTiles()
1171
0
{
1172
0
  int       colIdx, rowIdx;
1173
0
  int       ctuX, ctuY;
1174
  
1175
  // check explicit tile column sizes
1176
0
  uint32_t  remainingWidthInCtu  = m_picWidthInCtu;
1177
0
  for( colIdx = 0; colIdx < m_numExpTileCols; colIdx++ )
1178
0
  {
1179
0
    CHECK(m_tileColumnWidth[colIdx] > remainingWidthInCtu,    "Tile column width exceeds picture width");
1180
0
    remainingWidthInCtu -= m_tileColumnWidth[colIdx];
1181
0
  }
1182
1183
  // divide remaining picture width into uniform tile columns
1184
0
  uint32_t  uniformTileColWidth = m_tileColumnWidth[colIdx-1];
1185
0
  while( remainingWidthInCtu > 0 )
1186
0
  {
1187
0
    CHECK(colIdx >= MAX_TILE_COLS, "Number of tile columns exceeds valid range");
1188
0
    uniformTileColWidth = std::min(remainingWidthInCtu, uniformTileColWidth);
1189
0
    m_tileColumnWidth.push_back( uniformTileColWidth );
1190
0
    remainingWidthInCtu -= uniformTileColWidth;
1191
0
    colIdx++;
1192
0
  }
1193
0
  m_numTileCols = colIdx;
1194
    
1195
  // check explicit tile row sizes
1196
0
  uint32_t  remainingHeightInCtu  = m_picHeightInCtu;
1197
0
  for( rowIdx = 0; rowIdx < m_numExpTileRows; rowIdx++ )
1198
0
  {
1199
0
    CHECK(m_tileRowHeight[rowIdx] > remainingHeightInCtu,     "Tile row height exceeds picture height");
1200
0
    remainingHeightInCtu -= m_tileRowHeight[rowIdx];
1201
0
  }
1202
    
1203
  // divide remaining picture height into uniform tile rows
1204
0
  uint32_t  uniformTileRowHeight = m_tileRowHeight[rowIdx - 1];
1205
0
  while( remainingHeightInCtu > 0 )
1206
0
  {
1207
0
    uniformTileRowHeight = std::min(remainingHeightInCtu, uniformTileRowHeight);
1208
0
    m_tileRowHeight.push_back( uniformTileRowHeight );
1209
0
    remainingHeightInCtu -= uniformTileRowHeight;
1210
0
    rowIdx++;
1211
0
  }
1212
0
  m_numTileRows = rowIdx;
1213
1214
  // set left column bounaries
1215
0
  m_tileColBd.push_back( 0 );
1216
0
  for( colIdx = 0; colIdx < m_numTileCols; colIdx++ )
1217
0
  {
1218
0
    m_tileColBd.push_back( m_tileColBd[ colIdx ] + m_tileColumnWidth[ colIdx ] );
1219
0
  }
1220
  
1221
  // set top row bounaries
1222
0
  m_tileRowBd.push_back( 0 );
1223
0
  for( rowIdx = 0; rowIdx < m_numTileRows; rowIdx++ )
1224
0
  {
1225
0
    m_tileRowBd.push_back( m_tileRowBd[ rowIdx ] + m_tileRowHeight[ rowIdx ] );
1226
0
  }
1227
1228
  // set mapping between horizontal CTU address and tile column index
1229
0
  colIdx = 0;
1230
0
  for( ctuX = 0; ctuX <= m_picWidthInCtu; ctuX++ )
1231
0
  {
1232
0
    if( ctuX == m_tileColBd[ colIdx + 1 ] )
1233
0
    {
1234
0
      colIdx++;
1235
0
    }
1236
0
    m_ctuToTileCol.push_back( colIdx );
1237
0
  }
1238
  
1239
  // set mapping between vertical CTU address and tile row index
1240
0
  rowIdx = 0;
1241
0
  for( ctuY = 0; ctuY <= m_picHeightInCtu; ctuY++ )
1242
0
  {
1243
0
    if( ctuY == m_tileRowBd[ rowIdx + 1 ] )
1244
0
    {
1245
0
      rowIdx++;
1246
0
    }
1247
0
    m_ctuToTileRow.push_back( rowIdx );
1248
0
  }
1249
0
}
1250
1251
void PPS::initRectSlices()
1252
0
{
1253
0
  CHECK(m_numSlicesInPic > MAX_SLICES, "Number of slices in picture exceeds valid range");
1254
0
  m_rectSlices.resize(m_numSlicesInPic);
1255
0
}
1256
1257
/**
1258
 - initialize mapping between rectangular slices and CTUs
1259
 */
1260
void PPS::initRectSliceMap(const SPS  *sps)
1261
0
{
1262
0
  if( getSingleSlicePerSubPicFlag() )
1263
0
  {
1264
0
    CHECK (sps==nullptr, "RectSliceMap can only be initialized for slice_per_sub_pic_flag with a valid SPS");
1265
0
    m_numSlicesInPic = sps->getNumSubPics();
1266
1267
    // allocate new memory for slice list
1268
0
    CHECK(m_numSlicesInPic > MAX_SLICES, "Number of slices in picture exceeds valid range");
1269
0
    m_sliceMap.resize( m_numSlicesInPic );
1270
1271
0
    if (sps->getNumSubPics() > 1)
1272
0
    {
1273
      // Q2001 v15 equation 29
1274
0
      std::vector<uint32_t> subpicWidthInTiles;
1275
0
      std::vector<uint32_t> subpicHeightInTiles;
1276
0
      std::vector<uint32_t> subpicHeightLessThanOneTileFlag;
1277
0
      subpicWidthInTiles.resize(sps->getNumSubPics());
1278
0
      subpicHeightInTiles.resize(sps->getNumSubPics());
1279
0
      subpicHeightLessThanOneTileFlag.resize(sps->getNumSubPics());
1280
0
      for (uint32_t i = 0; i <sps->getNumSubPics(); i++)
1281
0
      {
1282
0
        uint32_t leftX = sps->getSubPicCtuTopLeftX(i);
1283
0
        uint32_t rightX = leftX + sps->getSubPicWidth(i) - 1;
1284
0
        subpicWidthInTiles[i] = m_ctuToTileCol[rightX] + 1 - m_ctuToTileCol[leftX];
1285
1286
0
        uint32_t topY = sps->getSubPicCtuTopLeftY(i);
1287
0
        uint32_t bottomY = topY + sps->getSubPicHeight(i) - 1;
1288
0
        subpicHeightInTiles[i] = m_ctuToTileRow[bottomY] + 1 - m_ctuToTileRow[topY];
1289
1290
0
        if (subpicHeightInTiles[i] == 1 && sps->getSubPicHeight(i) < m_tileRowHeight[m_ctuToTileRow[topY]] )
1291
0
        {
1292
0
          subpicHeightLessThanOneTileFlag[i] = 1;
1293
0
        }
1294
0
        else
1295
0
        {
1296
0
          subpicHeightLessThanOneTileFlag[i] = 0;
1297
0
        }
1298
0
      }
1299
1300
0
      for( int i = 0; i < m_numSlicesInPic; i++ )
1301
0
      {
1302
0
        CHECK(m_numSlicesInPic != sps->getNumSubPics(), "in single slice per subpic mode, number of slice and subpic shall be equal");
1303
0
        m_sliceMap[ i ].resetSliceMap();
1304
0
        if (subpicHeightLessThanOneTileFlag[i])
1305
0
        {
1306
0
          m_sliceMap[i].addCtusToSlice(sps->getSubPicCtuTopLeftX(i), sps->getSubPicCtuTopLeftX(i) + sps->getSubPicWidth(i),
1307
0
                                       sps->getSubPicCtuTopLeftY(i), sps->getSubPicCtuTopLeftY(i) + sps->getSubPicHeight(i), m_picWidthInCtu);
1308
0
        }
1309
0
        else
1310
0
        {
1311
0
          uint32_t tileX = m_ctuToTileCol[sps->getSubPicCtuTopLeftX(i)];
1312
0
          uint32_t tileY = m_ctuToTileRow[sps->getSubPicCtuTopLeftY(i)];
1313
0
          for (uint32_t j = 0; j< subpicHeightInTiles[i]; j++)
1314
0
          {
1315
0
            for (uint32_t k = 0; k < subpicWidthInTiles[i]; k++)
1316
0
            {
1317
0
              m_sliceMap[i].addCtusToSlice(getTileColumnBd(tileX + k), getTileColumnBd(tileX + k + 1), getTileRowBd(tileY + j), getTileRowBd(tileY + j + 1), m_picWidthInCtu);
1318
0
            }
1319
0
          }
1320
0
        }
1321
0
      }
1322
0
      subpicWidthInTiles.clear();
1323
0
      subpicHeightInTiles.clear();
1324
0
      subpicHeightLessThanOneTileFlag.clear();
1325
0
    }
1326
0
    else
1327
0
    {
1328
0
      m_sliceMap[0].resetSliceMap();
1329
0
      for (int tileY=0; tileY<m_numTileRows; tileY++)
1330
0
      {
1331
0
        for (int tileX=0; tileX<m_numTileCols; tileX++)
1332
0
        {
1333
0
          m_sliceMap[0].addCtusToSlice(getTileColumnBd(tileX), getTileColumnBd(tileX + 1),
1334
0
                                       getTileRowBd(tileY), getTileRowBd(tileY + 1), m_picWidthInCtu);
1335
0
        }
1336
0
      }
1337
0
      m_sliceMap[0].setSliceID(0);
1338
0
    }
1339
0
  }
1340
0
  else
1341
0
  {
1342
    // allocate new memory for slice list
1343
0
    CHECK(m_numSlicesInPic > MAX_SLICES, "Number of slices in picture exceeds valid range");
1344
0
    m_sliceMap.resize( m_numSlicesInPic );
1345
    // generate CTU maps for all rectangular slices in picture
1346
0
    for( uint32_t i = 0; i < m_numSlicesInPic; i++ )
1347
0
    {
1348
0
      m_sliceMap[ i ].resetSliceMap();
1349
1350
      // get position of first tile in slice
1351
0
      uint32_t tileX =  m_rectSlices[ i ].getTileIdx() % m_numTileCols;
1352
0
      uint32_t tileY =  m_rectSlices[ i ].getTileIdx() / m_numTileCols;
1353
1354
      // infer slice size for last slice in picture
1355
0
      if( i == m_numSlicesInPic-1 )
1356
0
      {
1357
0
        m_rectSlices[ i ].setSliceWidthInTiles ( m_numTileCols - tileX );
1358
0
        m_rectSlices[ i ].setSliceHeightInTiles( m_numTileRows - tileY );
1359
0
        m_rectSlices[ i ].setNumSlicesInTile( 1 );
1360
0
      }
1361
1362
      // set slice index
1363
0
      m_sliceMap[ i ].setSliceID(i);
1364
1365
      // complete tiles within a single slice case
1366
0
      if( m_rectSlices[ i ].getSliceWidthInTiles( ) > 1 || m_rectSlices[ i ].getSliceHeightInTiles( ) > 1)
1367
0
      {
1368
0
        for( uint32_t j = 0; j < m_rectSlices[ i ].getSliceHeightInTiles( ); j++ )
1369
0
        {
1370
0
          for( uint32_t k = 0; k < m_rectSlices[ i ].getSliceWidthInTiles( ); k++ )
1371
0
          {
1372
0
            m_sliceMap[ i ].addCtusToSlice( getTileColumnBd(tileX + k), getTileColumnBd(tileX + k +1),
1373
0
                                            getTileRowBd(tileY + j), getTileRowBd(tileY + j +1), m_picWidthInCtu);
1374
0
          }
1375
0
        }
1376
0
      }
1377
      // multiple slices within a single tile case
1378
0
      else
1379
0
      {
1380
0
        uint32_t  numSlicesInTile = m_rectSlices[ i ].getNumSlicesInTile( );
1381
1382
0
        uint32_t ctuY = getTileRowBd( tileY );
1383
0
        for( uint32_t j = 0; j < numSlicesInTile-1; j++ )
1384
0
        {
1385
0
          m_sliceMap[ i ].addCtusToSlice( getTileColumnBd(tileX), getTileColumnBd(tileX+1),
1386
0
                                          ctuY, ctuY + m_rectSlices[ i ].getSliceHeightInCtu(), m_picWidthInCtu);
1387
0
          ctuY += m_rectSlices[ i ].getSliceHeightInCtu();
1388
0
          i++;
1389
0
          m_sliceMap[ i ].resetSliceMap();
1390
0
          m_sliceMap[ i ].setSliceID(i);
1391
0
        }
1392
1393
        // infer slice height for last slice in tile
1394
0
        CHECK( ctuY >= getTileRowBd( tileY + 1 ), "Invalid rectangular slice signalling");
1395
0
        m_rectSlices[ i ].setSliceHeightInCtu( getTileRowBd( tileY + 1 ) - ctuY );
1396
0
        m_sliceMap[ i ].addCtusToSlice( getTileColumnBd(tileX), getTileColumnBd(tileX+1),
1397
0
                                        ctuY, getTileRowBd( tileY + 1 ), m_picWidthInCtu);
1398
0
      }
1399
0
    }
1400
0
  }
1401
  // check for valid rectangular slice map
1402
0
  checkSliceMap();
1403
0
}
1404
1405
/**
1406
- initialize mapping between subpicture and CTUs
1407
*/
1408
void PPS::initSubPic( const SPS &sps )
1409
0
{
1410
0
  if( getSubPicIdMappingPresentFlag() )
1411
0
  {
1412
    // When signalled, the number of subpictures has to match in PPS and SPS
1413
0
    CHECK( getNumSubPics() != sps.getNumSubPics(), "pps_num_subpics_minus1 shall be equal to sps_num_subpics_minus1" );
1414
0
  }
1415
0
  else
1416
0
  {
1417
    // When not signalled  set the numer equal for convenient access
1418
0
    setNumSubPics( sps.getNumSubPics() );
1419
0
  }
1420
1421
0
  CHECK( getNumSubPics() > MAX_NUM_SUB_PICS, "Number of sub-pictures in picture exceeds valid range" );
1422
0
  m_subPics.resize(getNumSubPics());
1423
1424
  // Check that no subpicture is specified outside of the conformance cropping window
1425
0
  for(int i = 0; i < sps.getNumSubPics(); i++)
1426
0
  {
1427
0
    CHECK( (sps.getSubPicCtuTopLeftX(i) * sps.getCTUSize()) >=
1428
0
          (sps.getMaxPicWidthInLumaSamples() - sps.getConformanceWindow().getWindowRightOffset() * SPS::getWinUnitX(sps.getChromaFormatIdc())),
1429
0
          "No subpicture can be located completely outside of the conformance cropping window");
1430
0
    CHECK( ((sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) * sps.getCTUSize()) <= (sps.getConformanceWindow().getWindowLeftOffset() * SPS::getWinUnitX(sps.getChromaFormatIdc())),
1431
0
          "No subpicture can be located completely outside of the conformance cropping window" );
1432
0
    CHECK( (sps.getSubPicCtuTopLeftY(i) * sps.getCTUSize()) >=
1433
0
          (sps.getMaxPicHeightInLumaSamples()  - sps.getConformanceWindow().getWindowBottomOffset() * SPS::getWinUnitY(sps.getChromaFormatIdc())),
1434
0
          "No subpicture can be located completely outside of the conformance cropping window");
1435
0
    CHECK( ((sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)) * sps.getCTUSize()) <= (sps.getConformanceWindow().getWindowTopOffset() * SPS::getWinUnitY(sps.getChromaFormatIdc())),
1436
0
          "No subpicture can be located completely outside of the conformance cropping window");
1437
0
  }
1438
1439
  // m_ctuSize,  m_picWidthInCtu, and m_picHeightInCtu might not be initialized yet.
1440
0
  if( m_ctuSize == 0 || m_picWidthInCtu == 0 || m_picHeightInCtu == 0 )
1441
0
  {
1442
0
    m_ctuSize = sps.getCTUSize();
1443
0
    m_picWidthInCtu = (m_picWidthInLumaSamples + m_ctuSize - 1) / m_ctuSize;
1444
0
    m_picHeightInCtu = (m_picHeightInLumaSamples + m_ctuSize - 1) / m_ctuSize;
1445
0
  }
1446
0
  for( int i=0; i< getNumSubPics(); i++ )
1447
0
  {
1448
0
    m_subPics[i].setSubPicIdx(i);
1449
0
    if( sps.getSubPicIdMappingExplicitlySignalledFlag() )
1450
0
    {
1451
0
      if( m_subPicIdMappingPresentFlag )
1452
0
      {
1453
0
        m_subPics[i].setSubPicID( m_subPicId[i] );
1454
0
      }
1455
0
      else
1456
0
      {
1457
0
        m_subPics[i].setSubPicID( sps.getSubPicId(i) );
1458
0
      }
1459
0
    }
1460
0
    else
1461
0
    {
1462
0
      m_subPics[i].setSubPicID(i);
1463
0
    }
1464
0
    m_subPics[i].setSubPicCtuTopLeftX(sps.getSubPicCtuTopLeftX(i));
1465
0
    m_subPics[i].setSubPicCtuTopLeftY(sps.getSubPicCtuTopLeftY(i));
1466
0
    m_subPics[i].setSubPicWidthInCTUs(sps.getSubPicWidth(i));
1467
0
    m_subPics[i].setSubPicHeightInCTUs(sps.getSubPicHeight(i));
1468
1469
0
    uint32_t firstCTU = sps.getSubPicCtuTopLeftY(i) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i);
1470
0
    m_subPics[i].setFirstCTUInSubPic(firstCTU);
1471
0
    uint32_t lastCTU = (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i) - 1) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i) - 1;
1472
0
    m_subPics[i].setLastCTUInSubPic(lastCTU);
1473
1474
0
    uint32_t left = sps.getSubPicCtuTopLeftX(i) * m_ctuSize;
1475
0
    m_subPics[i].setSubPicLeft(left);
1476
1477
0
    uint32_t right = std::min(m_picWidthInLumaSamples - 1, (sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) * m_ctuSize - 1);
1478
0
    m_subPics[i].setSubPicRight(right);
1479
1480
0
    m_subPics[i].setSubPicWidthInLumaSample(right - left + 1);
1481
1482
0
    uint32_t top = sps.getSubPicCtuTopLeftY(i) * m_ctuSize;
1483
0
    m_subPics[i].setSubPicTop(top);
1484
1485
0
    uint32_t bottom = std::min(m_picHeightInLumaSamples - 1, (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)) * m_ctuSize - 1);
1486
1487
0
    m_subPics[i].setSubPicHeightInLumaSample(bottom - top + 1);
1488
1489
0
    m_subPics[i].setSubPicBottom(bottom);
1490
1491
0
    m_subPics[i].clearCTUAddrList();
1492
1493
0
    if( m_numSlicesInPic == 1 )
1494
0
    {
1495
0
      CHECK( getNumSubPics() != 1, "only one slice in picture, but number of subpic is not one" );
1496
0
      m_subPics[i].addAllCtusInPicToSubPic(0, getPicWidthInCtu(), 0, getPicHeightInCtu(), getPicWidthInCtu());
1497
0
      m_subPics[i].setNumSlicesInSubPic(1);
1498
0
    }
1499
0
    else
1500
0
    {
1501
0
      int numSlicesInSubPic = 0;
1502
0
      int idxLastSliceInSubpic = -1;
1503
0
      int idxFirstSliceAfterSubpic = m_numSlicesInPic;
1504
0
      for( int j = 0; j < m_numSlicesInPic; j++ )
1505
0
      {
1506
0
        uint32_t ctu = m_sliceMap[j].getCtuAddrInSlice(0);
1507
0
        uint32_t ctu_x = ctu % m_picWidthInCtu;
1508
0
        uint32_t ctu_y = ctu / m_picWidthInCtu;
1509
0
        if (ctu_x >= sps.getSubPicCtuTopLeftX(i) &&
1510
0
          ctu_x < (sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) &&
1511
0
          ctu_y >= sps.getSubPicCtuTopLeftY(i) &&
1512
0
          ctu_y < (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)))
1513
0
        {
1514
          // add ctus in a slice to the subpicture it belongs to
1515
0
          m_subPics[i].addCTUsToSubPic(m_sliceMap[j].getCtuAddrList());
1516
0
          numSlicesInSubPic++;
1517
0
          idxLastSliceInSubpic = j;
1518
0
        }
1519
0
        else if (idxFirstSliceAfterSubpic == m_numSlicesInPic && idxLastSliceInSubpic != -1)
1520
0
        {
1521
0
          idxFirstSliceAfterSubpic = j;
1522
0
        }
1523
0
      }
1524
0
      CHECK( idxFirstSliceAfterSubpic < idxLastSliceInSubpic, "The signalling order of slices shall follow the coding order" );
1525
0
      m_subPics[i].setNumSlicesInSubPic(numSlicesInSubPic);
1526
0
    }
1527
0
    m_subPics[i].setTreatedAsPicFlag(sps.getSubPicTreatedAsPicFlag(i));
1528
0
    m_subPics[i].setloopFilterAcrossSubPicEnabledFlag(sps.getLoopFilterAcrossSubpicEnabledFlag(i));
1529
0
  }
1530
0
}
1531
1532
const SubPic& PPS::getSubPicFromPos(const Position& pos)  const
1533
0
{
1534
0
  for (int i = 0; i< m_numSubPics; i++)
1535
0
  {
1536
0
    if (m_subPics[i].isContainingPos(pos))
1537
0
    {
1538
0
      return m_subPics[i];
1539
0
    }
1540
0
  }
1541
0
  return m_subPics[0];
1542
0
}
1543
1544
const SubPic& PPS::getSubPicFromCU(const CodingUnit& cu) const
1545
0
{
1546
0
  const Position lumaPos = cu.Y().valid() ? cu.Y().pos() : recalcPosition(cu.chromaFormat, cu.chType(), CHANNEL_TYPE_LUMA, cu.blocks[cu.chType()].pos());
1547
0
  return getSubPicFromPos(lumaPos);
1548
0
}
1549
1550
uint32_t PPS::getSubPicIdxFromSubPicId( uint32_t subPicId ) const
1551
0
{
1552
0
  for (int i = 0; i < m_numSubPics; i++)
1553
0
  {
1554
0
    if(m_subPics[i].getSubPicID() == subPicId)
1555
0
    {
1556
0
      return i;
1557
0
    }
1558
0
  }
1559
0
  return 0;
1560
0
}
1561
1562
void PPS::checkSliceMap()
1563
0
{
1564
0
  uint32_t i;
1565
0
  std::vector<uint32_t>  ctuList, sliceList;
1566
0
  uint32_t picSizeInCtu = getPicWidthInCtu() * getPicHeightInCtu();
1567
0
  for( i = 0; i < m_numSlicesInPic; i++ )
1568
0
  {
1569
0
    sliceList = m_sliceMap[ i ].getCtuAddrList();
1570
0
    ctuList.insert( ctuList.end(), sliceList.begin(), sliceList.end() );
1571
0
  }
1572
0
  CHECK( ctuList.size() < picSizeInCtu, "Slice map contains too few CTUs");
1573
0
  CHECK( ctuList.size() > picSizeInCtu, "Slice map contains too many CTUs");
1574
0
  std::sort( ctuList.begin(), ctuList.end() );
1575
0
  for( i = 1; i < ctuList.size(); i++ )
1576
0
  {
1577
0
    CHECK( ctuList[i] > ctuList[i-1]+1, "CTU missing in slice map");
1578
0
    CHECK( ctuList[i] == ctuList[i-1],  "CTU duplicated in slice map");
1579
0
  }
1580
0
}
1581
1582
void PPS::finalizePPSPartitioning( const SPS* pcSPS )
1583
0
{
1584
  // initialize tile/slice info for no partitioning case
1585
0
  if( getNoPicPartitionFlag() )
1586
0
  {
1587
0
    resetTileSliceInfo();
1588
0
    setLog2CtuSize( ( int ) ceil( log2( pcSPS->getCTUSize() ) ) );
1589
0
    setNumExpTileColumns( 1 );
1590
0
    setNumExpTileRows( 1 );
1591
0
    addTileColumnWidth( getPicWidthInCtu()  );
1592
0
    addTileRowHeight  ( getPicHeightInCtu() );
1593
0
    initTiles();
1594
0
    setRectSliceFlag( 1 );
1595
0
    setNumSlicesInPic( 1 );
1596
0
    initRectSlices();
1597
0
    setTileIdxDeltaPresentFlag( 0 );
1598
0
    setSliceTileIdx( 0, 0 );
1599
0
    initRectSliceMap( pcSPS );
1600
    // when no Pic partition, number of sub picture shall be less than 2
1601
0
    CHECK( getNumSubPics() >= 2, "error, no picture partitions, but have equal to or more than 2 sub pictures" );
1602
0
  }
1603
0
  else
1604
0
  {
1605
0
    CHECK( getCtuSize() != pcSPS->getCTUSize(), "PPS CTU size does not match CTU size in SPS" );
1606
0
    if( getRectSliceFlag() )
1607
0
    {
1608
0
      initRectSliceMap( pcSPS );
1609
0
    }
1610
0
  }
1611
1612
0
  initSubPic( *pcSPS );
1613
0
}
1614
1615
1616
SliceMap::SliceMap()
1617
189
{
1618
189
  m_ctuAddrInSlice.clear();
1619
189
}
1620
1621
SliceMap::~SliceMap()
1622
189
{
1623
189
  m_numCtuInSlice = 0;
1624
189
  m_ctuAddrInSlice.clear();
1625
189
}
1626
1627
/** Sorts the deltaPOC and Used by current values in the RPS based on the deltaPOC values.
1628
 *  deltaPOC values are sorted with -ve values before the +ve values.  -ve values are in decreasing order.
1629
 *  +ve values are in increasing order.
1630
 * \returns void
1631
 */
1632
1633
ReferencePictureList::ReferencePictureList()
1634
386
{
1635
386
  ::memset( this, 0, sizeof( *this ) );
1636
386
}
1637
1638
void ReferencePictureList::clear()
1639
0
{
1640
0
  ::memset( this, 0, sizeof( *this ) );
1641
0
}
1642
1643
void ReferencePictureList::setRefPicIdentifier( int idx, int identifier, bool isLongterm, bool isInterLayerRefPic, int interLayerIdx )
1644
0
{
1645
0
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setRefPicIdentifier out of range (0-15)" );
1646
0
  m_refPicIdentifier[idx] = identifier;
1647
0
  m_isLongtermRefPic[idx] = isLongterm;
1648
1649
0
  m_deltaPocMSBPresentFlag[idx] = false;
1650
0
  m_deltaPOCMSBCycleLT[idx] = 0;
1651
  
1652
0
  m_isInterLayerRefPic[idx] = isInterLayerRefPic;
1653
0
  m_interLayerRefPicIdx[idx] = interLayerIdx;
1654
0
}
1655
1656
int ReferencePictureList::getRefPicIdentifier(int idx) const
1657
0
{
1658
0
  return m_refPicIdentifier[idx];
1659
0
}
1660
1661
1662
bool ReferencePictureList::isRefPicLongterm(int idx) const
1663
0
{
1664
0
  return m_isLongtermRefPic[idx];
1665
0
}
1666
1667
void ReferencePictureList::setRefPicLongterm(int idx,bool isLongterm)
1668
0
{
1669
0
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setRefPicLongterm out of range (0-15)" );
1670
0
  m_isLongtermRefPic[idx] = isLongterm;
1671
0
}
1672
1673
void ReferencePictureList::setNumberOfShorttermPictures(int numberOfStrp)
1674
0
{
1675
0
  m_numberOfShorttermPictures = numberOfStrp;
1676
0
}
1677
1678
int ReferencePictureList::getNumberOfShorttermPictures() const
1679
0
{
1680
0
  return m_numberOfShorttermPictures;
1681
0
}
1682
1683
void ReferencePictureList::setNumberOfLongtermPictures(int numberOfLtrp)
1684
0
{
1685
0
  m_numberOfLongtermPictures = numberOfLtrp;
1686
0
}
1687
1688
int ReferencePictureList::getNumberOfLongtermPictures() const
1689
0
{
1690
0
  return m_numberOfLongtermPictures;
1691
0
}
1692
1693
void ReferencePictureList::setPOC(int idx, int POC)
1694
0
{
1695
0
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setPOC out of range (0-15)" );
1696
0
  m_POC[idx] = POC;
1697
0
}
1698
1699
int ReferencePictureList::getPOC(int idx) const
1700
0
{
1701
0
  return m_POC[idx];
1702
0
}
1703
1704
void ReferencePictureList::setDeltaPocMSBCycleLT(int idx, int x)
1705
0
{
1706
0
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setDeltaPocMSBCycleLT out of range (0-15)" );
1707
0
  m_deltaPOCMSBCycleLT[idx] = x;
1708
0
}
1709
1710
void ReferencePictureList::setDeltaPocMSBPresentFlag(int idx, bool x)
1711
0
{
1712
0
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setDeltaPocMSBPresentFlag out of range (0-15)" );
1713
0
  m_deltaPocMSBPresentFlag[idx] = x;
1714
0
}
1715
1716
void ReferencePictureList::setInterLayerRefPicIdx( int idx, int layerIdc )
1717
0
{
1718
0
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setInterLayerRefPicIdx out of range (0-15)" );
1719
0
  m_interLayerRefPicIdx[idx] = layerIdc;
1720
0
}
1721
1722
void ReferencePictureList::printRefPicInfo() const
1723
0
{
1724
0
  DTRACE(g_trace_ctx, D_RPSINFO, "RefPics = { ");
1725
0
  int numRefPic = getNumberOfShorttermPictures() + getNumberOfLongtermPictures();
1726
0
  for (int ii = 0; ii < numRefPic; ii++)
1727
0
  {
1728
0
    DTRACE(g_trace_ctx, D_RPSINFO, "%d%s ", m_refPicIdentifier[ii], (m_isLongtermRefPic[ii] == 1) ? "[LT]" : "[ST]");
1729
0
  }
1730
0
  DTRACE(g_trace_ctx, D_RPSINFO, "}\n");
1731
0
}
1732
1733
bool ReferencePictureList::findInRefPicList( const Picture* checkRefPic, int currPicPoc, int layerId ) const
1734
0
{
1735
  // loop through all pictures in the Reference Picture Set
1736
  // to see if the picture should be kept as reference picture
1737
0
  for( int i = 0; i < getNumRefEntries(); i++ )
1738
0
  {
1739
0
    if( isInterLayerRefPic( i ) )
1740
0
    {
1741
      // Diagonal inter-layer prediction is not allowed
1742
0
      CHECK( getRefPicIdentifier( i ), "ILRP identifier should be 0" );
1743
1744
0
      if( checkRefPic->poc == currPicPoc )
1745
0
      {
1746
0
        CHECK( checkRefPic->dpbReferenceMark != Picture::LongTerm, "LTRP needs long term mark" );
1747
0
        return true;
1748
0
      }
1749
0
    }
1750
0
    else if( checkRefPic->layerId == layerId )
1751
0
    {
1752
0
      if( isRefPicLongterm( i ) )
1753
0
      {
1754
0
        const int bitsForPoc = checkRefPic->cs->sps->getBitsForPOC();
1755
0
        const int curPoc     = checkRefPic->getPOC();
1756
0
        const int ltRefPoc   = calcLTRefPOC( currPicPoc, bitsForPoc, i );
1757
0
        if( checkRefPic->dpbReferenceMark == Picture::LongTerm && isLTPocEqual( curPoc, ltRefPoc, bitsForPoc, getDeltaPocMSBPresentFlag( i ) ) )
1758
0
        {
1759
0
          return true;
1760
0
        }
1761
0
      }
1762
0
      else
1763
0
      {
1764
0
        if( checkRefPic->poc == currPicPoc + getRefPicIdentifier( i ) )
1765
0
        {
1766
0
          return true;
1767
0
        }
1768
0
      }
1769
0
    }
1770
0
  }
1771
0
  return false;
1772
0
}
1773
1774
int ReferencePictureList::calcLTRefPOC( int currPoc, int bitsForPoc, int refPicIdentifier, bool pocMSBPresent, int deltaPocMSBCycle )
1775
0
{
1776
0
  const int pocCycle = 1 << bitsForPoc;
1777
0
  int       ltrpPoc  = refPicIdentifier & ( pocCycle - 1 );
1778
0
  if( pocMSBPresent )
1779
0
  {
1780
0
    ltrpPoc += currPoc - deltaPocMSBCycle * pocCycle - ( currPoc & ( pocCycle - 1 ) );
1781
0
  }
1782
0
  return ltrpPoc;
1783
0
}
1784
1785
int ReferencePictureList::calcLTRefPOC( int currPoc, int bitsForPoc, int refPicIdx ) const
1786
0
{
1787
0
  return calcLTRefPOC( currPoc,
1788
0
                       bitsForPoc,
1789
0
                       this->getRefPicIdentifier( refPicIdx ),
1790
0
                       this->getDeltaPocMSBPresentFlag( refPicIdx ),
1791
0
                       this->getDeltaPocMSBCycleLT( refPicIdx ) );
1792
0
}
1793
1794
bool isLTPocEqual( int poc1, int poc2, int bitsForPoc, bool msbPresent )
1795
0
{
1796
0
  if( msbPresent )
1797
0
  {
1798
0
    return poc1 == poc2;
1799
0
  }
1800
1801
0
  const int pocCycle = 1 << bitsForPoc;
1802
0
  return ( poc1 & ( pocCycle - 1 ) ) == ( poc2 & ( pocCycle - 1 ) );
1803
0
}
1804
1805
1806
ScalingList::ScalingList()
1807
126
{
1808
126
  reset();
1809
126
}
1810
1811
void ScalingList::reset()
1812
126
{
1813
126
  memset( m_scalingListDC, 0, sizeof( m_scalingListDC ) );
1814
1815
3.65k
  for (uint32_t id = 0; id < 28; id++)
1816
3.52k
  {
1817
3.52k
    const int matrixSize = ScalingList::matrixSize( id );
1818
3.52k
    m_scalingListCoef[id].assign( matrixSize * matrixSize, 0 );
1819
3.52k
  }
1820
126
}
1821
1822
void Slice::scaleRefPicList()
1823
0
{
1824
0
  const SPS* sps = getSPS();
1825
0
  const PPS* pps = getPPS();
1826
1827
0
  if( m_eSliceType == I_SLICE )
1828
0
  {
1829
0
    return;
1830
0
  }
1831
  
1832
0
  for( int refList = 0; refList < NUM_REF_PIC_LIST_01; refList++ )
1833
0
  {
1834
0
    if( refList == 1 && m_eSliceType != B_SLICE )
1835
0
    {
1836
0
      continue;
1837
0
    }
1838
1839
0
    for( int rIdx = 0; rIdx < m_aiNumRefIdx[refList]; rIdx++ )
1840
0
    {
1841
      // if rescaling is needed, otherwise just reuse the original picture pointer; it is needed for motion field, otherwise motion field
1842
      // requires a copy as well reference resampling for the whole picture is not applied at decoder
1843
1844
0
      CHECK( !m_apcRefPicList[refList][rIdx], "scaleRefPicList missing ref pic" );
1845
1846
0
      int xScale, yScale;
1847
0
      CU::getRprScaling( sps, pps, m_apcRefPicList[refList][rIdx]->slices[0]->getPPS(), xScale, yScale );
1848
0
      m_scalingRatio[refList][rIdx] = std::pair<int, int>( xScale, yScale );
1849
0
    }
1850
0
  }
1851
1852
  // the collocated motion field is indexed with the current picture's layout (7.4.8)
1853
0
  if( getPicHeader()->getEnableTMVPFlag() )
1854
0
  {
1855
0
    const RefPicList colList = RefPicList( isInterB() ? 1 - getColFromL0Flag() : 0 );
1856
0
    CHECK( getColRefIdx() >= getNumRefIdx( colList ), "collocated_ref_idx shall be less than NumRefIdxActive" );
1857
1858
0
    const Picture* colPic = getRefPic( colList, getColRefIdx() );
1859
0
    CHECK( colPic->isRefScaled( pps ), "the collocated picture shall have the same size and scaling window as the current picture" );
1860
0
  }
1861
0
}
1862
1863
bool             operator == (const ConstraintInfo& op1, const ConstraintInfo& op2)
1864
0
{
1865
0
  if( op1.m_intraOnlyConstraintFlag                      != op2.m_intraOnlyConstraintFlag                        ) return false;
1866
0
  if( op1.m_maxBitDepthConstraintIdc                     != op2.m_maxBitDepthConstraintIdc                       ) return false;
1867
0
  if( op1.m_maxChromaFormatConstraintIdc                 != op2.m_maxChromaFormatConstraintIdc                   ) return false;
1868
0
  if( op1.m_onePictureOnlyConstraintFlag                 != op2.m_onePictureOnlyConstraintFlag                   ) return false;
1869
0
  if( op1.m_lowerBitRateConstraintFlag                   != op2.m_lowerBitRateConstraintFlag                     ) return false;
1870
0
  if (op1.m_allLayersIndependentConstraintFlag           != op2.m_allLayersIndependentConstraintFlag             ) return false;
1871
0
  if (op1.m_noMrlConstraintFlag                          != op2.m_noMrlConstraintFlag                            ) return false;
1872
0
  if (op1.m_noIspConstraintFlag                          != op2.m_noIspConstraintFlag                            ) return false;
1873
0
  if (op1.m_noMipConstraintFlag                          != op2.m_noMipConstraintFlag                            ) return false;
1874
0
  if (op1.m_noLfnstConstraintFlag                        != op2.m_noLfnstConstraintFlag                          ) return false;
1875
0
  if (op1.m_noMmvdConstraintFlag                         != op2.m_noMmvdConstraintFlag                           ) return false;
1876
0
  if (op1.m_noSmvdConstraintFlag                         != op2.m_noSmvdConstraintFlag                           ) return false;
1877
0
  if (op1.m_noProfConstraintFlag                         != op2.m_noProfConstraintFlag                           ) return false;
1878
0
  if (op1.m_noPaletteConstraintFlag                      != op2.m_noPaletteConstraintFlag                        ) return false;
1879
0
  if (op1.m_noActConstraintFlag                          != op2.m_noActConstraintFlag                            ) return false;
1880
0
  if (op1.m_noLmcsConstraintFlag                         != op2.m_noLmcsConstraintFlag                           ) return false;
1881
0
  if (op1.m_noExplicitScaleListConstraintFlag            != op2.m_noExplicitScaleListConstraintFlag              ) return false;
1882
0
  if (op1.m_noVirtualBoundaryConstraintFlag              != op2.m_noVirtualBoundaryConstraintFlag                ) return false;
1883
0
  if (op1.m_noChromaQpOffsetConstraintFlag               != op2.m_noChromaQpOffsetConstraintFlag                 ) return false;
1884
0
  if (op1.m_noRprConstraintFlag                          != op2.m_noRprConstraintFlag                            ) return false;
1885
0
  if (op1.m_noResChangeInClvsConstraintFlag              != op2.m_noResChangeInClvsConstraintFlag                ) return false;
1886
0
  if (op1.m_noMttConstraintFlag                          != op2.m_noMttConstraintFlag                            ) return false;
1887
0
  if( op1.m_noQtbttDualTreeIntraConstraintFlag           != op2.m_noQtbttDualTreeIntraConstraintFlag             ) return false;
1888
0
  if( op1.m_noPartitionConstraintsOverrideConstraintFlag != op2.m_noPartitionConstraintsOverrideConstraintFlag   ) return false;
1889
0
  if( op1.m_noSaoConstraintFlag                          != op2.m_noSaoConstraintFlag                            ) return false;
1890
0
  if( op1.m_noAlfConstraintFlag                          != op2.m_noAlfConstraintFlag                            ) return false;
1891
0
  if( op1.m_noCCAlfConstraintFlag                        != op2.m_noCCAlfConstraintFlag                          ) return false;
1892
0
  if (op1.m_noWeightedPredictionConstraintFlag           != op2.m_noWeightedPredictionConstraintFlag             ) return false;
1893
0
  if( op1.m_noRefWraparoundConstraintFlag                != op2.m_noRefWraparoundConstraintFlag                  ) return false;
1894
0
  if( op1.m_noTemporalMvpConstraintFlag                  != op2.m_noTemporalMvpConstraintFlag                    ) return false;
1895
0
  if( op1.m_noSbtmvpConstraintFlag                       != op2.m_noSbtmvpConstraintFlag                         ) return false;
1896
0
  if( op1.m_noAmvrConstraintFlag                         != op2.m_noAmvrConstraintFlag                           ) return false;
1897
0
  if( op1.m_noBdofConstraintFlag                         != op2.m_noBdofConstraintFlag                           ) return false;
1898
0
  if( op1.m_noDmvrConstraintFlag                         != op2.m_noDmvrConstraintFlag                           ) return false;
1899
0
  if( op1.m_noCclmConstraintFlag                         != op2.m_noCclmConstraintFlag                           ) return false;
1900
0
  if( op1.m_noMtsConstraintFlag                          != op2.m_noMtsConstraintFlag                            ) return false;
1901
0
  if( op1.m_noSbtConstraintFlag                          != op2.m_noSbtConstraintFlag                            ) return false;
1902
0
  if( op1.m_noAffineMotionConstraintFlag                 != op2.m_noAffineMotionConstraintFlag                   ) return false;
1903
0
  if( op1.m_noBcwConstraintFlag                          != op2.m_noBcwConstraintFlag                            ) return false;
1904
0
  if( op1.m_noIbcConstraintFlag                          != op2.m_noIbcConstraintFlag                            ) return false;
1905
0
  if( op1.m_noCiipConstraintFlag                         != op2.m_noCiipConstraintFlag                           ) return false;
1906
0
  if( op1.m_noLadfConstraintFlag                         != op2.m_noLadfConstraintFlag                           ) return false;
1907
0
  if( op1.m_noTransformSkipConstraintFlag                != op2.m_noTransformSkipConstraintFlag                  ) return false;
1908
0
  if( op1.m_noBDPCMConstraintFlag                        != op2.m_noBDPCMConstraintFlag                          ) return false;
1909
0
  if( op1.m_noJointCbCrConstraintFlag                    != op2.m_noJointCbCrConstraintFlag                      ) return false;
1910
0
  if( op1.m_noQpDeltaConstraintFlag                      != op2.m_noQpDeltaConstraintFlag                        ) return false;
1911
0
  if( op1.m_noDepQuantConstraintFlag                     != op2.m_noDepQuantConstraintFlag                       ) return false;
1912
0
  if( op1.m_noSignDataHidingConstraintFlag               != op2.m_noSignDataHidingConstraintFlag                 ) return false;
1913
0
  if( op1.m_noTrailConstraintFlag                        != op2.m_noTrailConstraintFlag                          ) return false;
1914
0
  if( op1.m_noStsaConstraintFlag                         != op2.m_noStsaConstraintFlag                           ) return false;
1915
0
  if( op1.m_noRaslConstraintFlag                         != op2.m_noRaslConstraintFlag                           ) return false;
1916
0
  if( op1.m_noRadlConstraintFlag                         != op2.m_noRadlConstraintFlag                           ) return false;
1917
0
  if( op1.m_noIdrConstraintFlag                          != op2.m_noIdrConstraintFlag                            ) return false;
1918
0
  if( op1.m_noCraConstraintFlag                          != op2.m_noCraConstraintFlag                            ) return false;
1919
0
  if( op1.m_noGdrConstraintFlag                          != op2.m_noGdrConstraintFlag                            ) return false;
1920
0
  if( op1.m_noApsConstraintFlag                          != op2.m_noApsConstraintFlag                            ) return false;
1921
0
  return true;
1922
0
}
1923
bool             operator != (const ConstraintInfo& op1, const ConstraintInfo& op2)
1924
0
{
1925
0
  return !(op1 == op2);
1926
0
}
1927
1928
bool             operator == (const ProfileTierLevel& op1, const ProfileTierLevel& op2)
1929
0
{
1930
0
  if (op1.m_tierFlag        != op2.m_tierFlag) return false;
1931
0
  if (op1.m_profileIdc      != op2.m_profileIdc) return false;
1932
0
  if (op1.m_numSubProfile   != op2.m_numSubProfile) return false;
1933
0
  if (op1.m_levelIdc        != op2.m_levelIdc) return false;
1934
0
  if (op1.m_frameOnlyConstraintFlag != op2.m_frameOnlyConstraintFlag) return false;
1935
0
  if (op1.m_multiLayerEnabledFlag   != op2.m_multiLayerEnabledFlag) return false;
1936
0
  if (op1.m_constraintInfo  != op2.m_constraintInfo) return false;
1937
0
  if (op1.m_subProfileIdc   != op2.m_subProfileIdc) return false;
1938
1939
0
  for (int i = 0; i < MAX_TLAYER - 1; i++)
1940
0
  {
1941
0
    if (op1.m_subLayerLevelPresentFlag[i] != op2.m_subLayerLevelPresentFlag[i])
1942
0
    {
1943
0
      return false;
1944
0
    }
1945
0
  }
1946
0
  for (int i = 0; i < MAX_TLAYER; i++)
1947
0
  {
1948
0
    if (op1.m_subLayerLevelIdc[i] != op2.m_subLayerLevelIdc[i])
1949
0
    {
1950
0
      return false;
1951
0
    }
1952
0
  }
1953
0
  return true;
1954
0
}
1955
bool             operator != (const ProfileTierLevel& op1, const ProfileTierLevel& op2)
1956
0
{
1957
0
  return !(op1 == op2);
1958
0
}
1959
1960
uint32_t
1961
LevelTierFeatures::getMaxPicWidthInLumaSamples()  const
1962
0
{
1963
0
  return uint32_t(sqrt(maxLumaPs*8.0));
1964
0
}
1965
1966
uint32_t
1967
LevelTierFeatures::getMaxPicHeightInLumaSamples() const
1968
0
{
1969
0
  return uint32_t(sqrt(maxLumaPs*8.0));
1970
0
}
1971
1972
static const uint64_t MAX_CNFUINT64 = std::numeric_limits<uint64_t>::max();
1973
1974
static const LevelTierFeatures mainLevelTierInfo[] =
1975
{
1976
      //  level,       maxlumaps,      maxcpb[tier],,  maxSlicesPerAu,maxTilesPerAu,cols, maxLumaSr,       maxBr[tier],,    minCr[tier],,
1977
    { vvdecLevel::VVDEC_LEVEL1  ,    36864, {      350,        0 },       16,        1,        1,     552960ULL, {     128,        0 }, { 2, 2} },
1978
    { vvdecLevel::VVDEC_LEVEL2  ,   122880, {     1500,        0 },       16,        1,        1,    3686400ULL, {    1500,        0 }, { 2, 2} },
1979
    { vvdecLevel::VVDEC_LEVEL2_1,   245760, {     3000,        0 },       20,        1,        1,    7372800ULL, {    3000,        0 }, { 2, 2} },
1980
    { vvdecLevel::VVDEC_LEVEL3  ,   552960, {     6000,        0 },       30,        4,        2,   16588800ULL, {    6000,        0 }, { 2, 2} },
1981
    { vvdecLevel::VVDEC_LEVEL3_1,   983040, {    10000,        0 },       40,        9,        3,   33177600ULL, {   10000,        0 }, { 2, 2} },
1982
    { vvdecLevel::VVDEC_LEVEL4  ,  2228224, {    12000,    30000 },       75,       25,        5,   66846720ULL, {   12000,    30000 }, { 4, 4} },
1983
    { vvdecLevel::VVDEC_LEVEL4_1,  2228224, {    20000,    50000 },       75,       25,        5,  133693440ULL, {   20000,    50000 }, { 4, 4} },
1984
    { vvdecLevel::VVDEC_LEVEL5  ,  8912896, {    25000,   100000 },      200,      110,       10,  267386880ULL, {   25000,   100000 }, { 6, 4} },
1985
    { vvdecLevel::VVDEC_LEVEL5_1,  8912896, {    40000,   160000 },      200,      110,       10,  534773760ULL, {   40000,   160000 }, { 8, 4} },
1986
    { vvdecLevel::VVDEC_LEVEL5_2,  8912896, {    60000,   240000 },      200,      110,       10, 1069547520ULL, {   60000,   240000 }, { 8, 4} },
1987
    { vvdecLevel::VVDEC_LEVEL6  , 35651584, {    80000,   240000 },      600,      440,       20, 1069547520ULL, {   60000,   240000 }, { 8, 4} },
1988
    { vvdecLevel::VVDEC_LEVEL6_1, 35651584, {   120000,   480000 },      600,      440,       20, 2139095040ULL, {  120000,   480000 }, { 8, 4} },
1989
    { vvdecLevel::VVDEC_LEVEL6_2, 35651584, {   180000,   800000 },      600,      440,       20, 4278190080ULL, {  240000,   800000 }, { 8, 4} },
1990
    { vvdecLevel::VVDEC_LEVEL15_5, MAX_UINT,{ MAX_UINT, MAX_UINT }, MAX_UINT, MAX_UINT, MAX_UINT, MAX_CNFUINT64, {MAX_UINT, MAX_UINT }, { 0, 0} },
1991
    { vvdecLevel::VVDEC_LEVEL_NONE    }
1992
};
1993
1994
static const ProfileFeatures validProfiles[] = {
1995
// profile, pNameString, maxBitDepth, maxChrFmt, lvl15.5, cpbvcl, cpbnal, fcf*1000, mincr*100, levelInfo
1996
// most constrained profiles must appear first.
1997
  { Profile::MAIN_10_STILL_PICTURE, "Main_10_Still_Picture", 10, CHROMA_420, true, 1000, 1100, 1875, 100,
1998
    mainLevelTierInfo, true },
1999
  { Profile::MULTILAYER_MAIN_10_STILL_PICTURE, "Multilayer_Main_10_Still_Picture", 10, CHROMA_420, true, 1000, 1100,
2000
    1875, 100, mainLevelTierInfo, true },
2001
  { Profile::MAIN_10_444_STILL_PICTURE, "Main_444_10_Still_Picture", 10, CHROMA_444, true, 2500, 2750, 3750, 75,
2002
    mainLevelTierInfo, true },
2003
  { Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE, "Multilayer_Main_444_10_Still_Picture", 10, CHROMA_444, true, 2500,
2004
    2750, 3750, 75, mainLevelTierInfo, true },
2005
  { Profile::MAIN_10, "Main_10", 10, CHROMA_420, false, 1000, 1100, 1875, 100, mainLevelTierInfo, false },
2006
  { Profile::MULTILAYER_MAIN_10, "Multilayer_Main_10", 10, CHROMA_420, false, 1000, 1100, 1875, 100, mainLevelTierInfo,
2007
    false },
2008
  { Profile::MAIN_10_444, "Main_444_10", 10, CHROMA_444, false, 2500, 2750, 3750, 75, mainLevelTierInfo, false },
2009
  { Profile::MULTILAYER_MAIN_10_444, "Multilayer_Main_444_10", 10, CHROMA_444, false, 2500, 2750, 3750, 75,
2010
    mainLevelTierInfo, false },
2011
  { Profile::NONE, 0 },
2012
};
2013
2014
const ProfileFeatures *ProfileFeatures::getProfileFeatures(const Profile::Name p)
2015
0
{
2016
0
  int i;
2017
0
  for (i = 0; validProfiles[i].profile != Profile::NONE; i++)
2018
0
  {
2019
0
    if (validProfiles[i].profile == p)
2020
0
    {
2021
0
      return &validProfiles[i];
2022
0
    }
2023
0
  }
2024
2025
0
  return &validProfiles[i];
2026
0
}
2027
2028
void
2029
ProfileLevelTierFeatures::extractPTLInformation(const SPS &sps)
2030
0
{
2031
0
  const ProfileTierLevel &spsPtl =*(sps.getProfileTierLevel());
2032
2033
0
  m_tier = spsPtl.getTierFlag();
2034
2035
  // Identify the profile from the profile Idc, and possibly other constraints.
2036
0
  for(int32_t i=0; validProfiles[i].profile != Profile::NONE; i++)
2037
0
  {
2038
0
    if (spsPtl.getProfileIdc() == validProfiles[i].profile)
2039
0
    {
2040
0
      m_pProfile = &(validProfiles[i]);
2041
0
      break;
2042
0
    }
2043
0
  }
2044
2045
0
  if (m_pProfile != 0)
2046
0
  {
2047
    // Now identify the level:
2048
0
    const LevelTierFeatures *pLTF  = m_pProfile->pLevelTiersListInfo;
2049
0
    const vvdecLevel spsLevelName  = spsPtl.getLevelIdc();
2050
0
    if (spsLevelName!=vvdecLevel::VVDEC_LEVEL15_5 || m_pProfile->canUseLevel15p5)
2051
0
    {
2052
0
      for(int i=0; pLTF[i].level!=vvdecLevel::VVDEC_LEVEL_NONE; i++)
2053
0
      {
2054
0
        if (pLTF[i].level == spsLevelName)
2055
0
        {
2056
0
          m_pLevelTier = &(pLTF[i]);
2057
0
        }
2058
0
      }
2059
0
    }
2060
0
  }
2061
0
}
2062
2063
uint64_t ProfileLevelTierFeatures::getCpbSizeInBits() const
2064
0
{
2065
0
  return (m_pLevelTier!=0 && m_pProfile!=0) ? uint64_t(m_pProfile->cpbVclFactor) * m_pLevelTier->maxCpb[m_tier?1:0] : uint64_t(0);
2066
0
}
2067
2068
uint32_t ProfileLevelTierFeatures::getMaxDpbSize( uint32_t picSizeMaxInSamplesY ) const
2069
0
{
2070
0
  const uint32_t maxDpbPicBuf = 8;
2071
0
  uint32_t       maxDpbSize;
2072
2073
0
  if (m_pLevelTier->level == vvdecLevel::VVDEC_LEVEL15_5)
2074
0
  {
2075
    // maxDpbSize is unconstrained in this case
2076
0
    maxDpbSize = std::numeric_limits<uint32_t>::max();
2077
0
  }
2078
0
  else if (2 * picSizeMaxInSamplesY <= m_pLevelTier->maxLumaPs)
2079
0
  {
2080
0
    maxDpbSize = 2 * maxDpbPicBuf;
2081
0
  }
2082
0
  else if (3 * picSizeMaxInSamplesY <= 2 * m_pLevelTier->maxLumaPs)
2083
0
  {
2084
0
    maxDpbSize = 3 * maxDpbPicBuf / 2;
2085
0
  }
2086
0
  else
2087
0
  {
2088
0
    maxDpbSize = maxDpbPicBuf;
2089
0
  }
2090
2091
0
  return maxDpbSize;
2092
0
}
2093
2094
#if ENABLE_TRACING
2095
void xTraceVPSHeader()
2096
{
2097
  DTRACE( g_trace_ctx, D_HEADER, "=========== Video Parameter Set     ===========\n" );
2098
}
2099
void xTraceDCIHeader()
2100
{
2101
  DTRACE( g_trace_ctx, D_HEADER, "=========== DCI     ===========\n" );
2102
}
2103
void xTraceSPSHeader()
2104
{
2105
  DTRACE( g_trace_ctx, D_HEADER, "=========== Sequence Parameter Set  ===========\n" );
2106
}
2107
2108
void xTracePPSHeader()
2109
{
2110
  DTRACE( g_trace_ctx, D_HEADER, "=========== Picture Parameter Set  ===========\n" );
2111
}
2112
2113
void xTraceAPSHeader()
2114
{
2115
  DTRACE(g_trace_ctx, D_HEADER, "=========== Adaptation Parameter Set  ===========\n");
2116
}
2117
2118
void xTracePictureHeader()
2119
{
2120
  DTRACE( g_trace_ctx, D_HEADER, "=========== Picture Header ===========\n" );
2121
}
2122
2123
void xTraceSliceHeader()
2124
{
2125
  DTRACE( g_trace_ctx, D_HEADER, "=========== Slice ===========\n" );
2126
}
2127
2128
void xTraceAccessUnitDelimiter()
2129
{
2130
  DTRACE( g_trace_ctx, D_HEADER, "=========== Access Unit Delimiter ===========\n" );
2131
}
2132
#endif
2133
2134
}