Coverage Report

Created: 2026-10-28 06:18

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
478
{
263
1.43k
  for( uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++ )
264
956
  {
265
16.2k
    for(int iNumCount = 0; iNumCount < MAX_NUM_REF; iNumCount++)
266
15.2k
    {
267
15.2k
      m_apcRefPicList [i][iNumCount] = nullptr;
268
15.2k
      m_aiRefPOCList  [i][iNumCount] = 0;
269
15.2k
    }
270
271
956
    m_apcRefPicList[i][MAX_NUM_REF] = nullptr;
272
956
    m_aiRefPOCList [i][MAX_NUM_REF] = 0;
273
956
  }
274
275
478
  resetWpScaling();
276
478
  initWpAcDcParam();
277
278
478
  clearAlfAPSs();
279
478
}
280
281
282
void Slice::initSlice()
283
14
{
284
42
  for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
285
28
  {
286
28
    m_aiNumRefIdx[i]      = 0;
287
28
  }
288
14
  m_colFromL0Flag = true;
289
14
  m_colRefIdx = 0;
290
291
14
  m_bCheckLDC = false;
292
293
14
  m_biDirPred = false;
294
14
  m_symRefIdx[0] = -1;
295
14
  m_symRefIdx[1] = -1;
296
297
56
  for (uint32_t component = 0; component < MAX_NUM_COMPONENT; component++)
298
42
  {
299
42
    m_iSliceChromaQpDelta[component] = 0;
300
42
  }
301
14
  m_iSliceChromaQpDelta[JOINT_CbCr] = 0;
302
303
304
14
  m_substreamSizes.clear();
305
14
  m_cabacInitFlag        = false;
306
14
  resetAlfEnabledFlag();
307
14
  resetCcAlfEnabledFlags();
308
14
  m_sliceMap.resetSliceMap();
309
14
}
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                         currPicBitsForPoc,
914
                                             int*                        missingPOC,
915
                                             int*                        missingRefPicIndex ) const
916
0
{
917
0
  if( this->isIDR() )
918
0
    return true;   // Assume that all pic in the DPB will be flushed anyway so no need to check.
919
920
0
  *missingPOC         = 0;
921
0
  *missingRefPicIndex = 0;
922
923
  // Check long term ref pics
924
0
  for( int ii = 0; pRPL->getNumberOfLongtermPictures() > 0 && ii < numActiveRefPics; ii++ )
925
0
  {
926
0
    if( !pRPL->isRefPicLongterm( ii ) )
927
0
      continue;
928
929
    // RefPicLtPocList (8.3.2): the full POC when the MSB is signalled, so the picture generated for it (8.3.4.1) matches
930
0
    const int checkPoc    = pRPL->calcLTRefPOC( this->getPOC(), currPicBitsForPoc, ii );
931
0
    bool      isAvailable = 0;
932
0
    for( auto& rpcPic: rcListPic )
933
0
    {
934
0
      const int bitsForPoc = rpcPic->cs->sps->getBitsForPOC();
935
0
      const int poc        = rpcPic->getPOC();
936
0
      const int refPoc     = pRPL->calcLTRefPOC( this->getPOC(), bitsForPoc, ii );
937
938
0
      if( rpcPic->dpbReferenceMark == Picture::LongTerm && isLTPocEqual( poc, refPoc, bitsForPoc, pRPL->getDeltaPocMSBPresentFlag( ii ) )  )
939
0
      {
940
0
        isAvailable = 1;
941
0
        break;
942
0
      }
943
0
    }
944
0
    if( isAvailable )
945
0
      continue;
946
947
    // if there was no such long-term check the short terms
948
0
    for( auto& rpcPic: rcListPic )
949
0
    {
950
0
      const int bitsForPoc = rpcPic->cs->sps->getBitsForPOC();
951
0
      const int poc        = rpcPic->getPOC();
952
0
      const int refPoc     = pRPL->calcLTRefPOC( this->getPOC(), bitsForPoc, ii );
953
954
0
      if( rpcPic->dpbReferenceMark == Picture::ShortTerm && isLTPocEqual( poc, refPoc, bitsForPoc, pRPL->getDeltaPocMSBPresentFlag( ii ) )  )
955
0
      {
956
0
        isAvailable      = 1;
957
0
        rpcPic->dpbReferenceMark  = Picture::LongTerm;
958
0
        break;
959
0
      }
960
0
    }
961
962
0
    if( !isAvailable )
963
0
    {
964
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 );
965
966
0
      *missingPOC         = checkPoc;
967
0
      *missingRefPicIndex = ii;
968
0
      return false;
969
0
    }
970
0
  }
971
972
  // Check short term ref pics
973
0
  for( int ii = 0; ii < numActiveRefPics; ii++ )
974
0
  {
975
0
    if( pRPL->isRefPicLongterm( ii ) )
976
0
      continue;
977
978
0
    const int checkPoc    = this->getPOC() + pRPL->getRefPicIdentifier( ii );
979
0
    bool      isAvailable = false;
980
0
    for( auto& rpcPic: rcListPic )
981
0
    {
982
0
      if( rpcPic->getPOC() == checkPoc && rpcPic->dpbReferenceMark )
983
0
      {
984
0
        isAvailable = true;
985
0
        break;
986
0
      }
987
0
    }
988
989
    // report that a picture is lost if it is in the Reference Picture List but not in the DPB
990
0
    if( !isAvailable && pRPL->getNumberOfShorttermPictures() > 0 )
991
0
    {
992
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 );
993
994
0
      *missingPOC         = checkPoc;
995
0
      *missingRefPicIndex = ii;
996
0
      return false;
997
0
    }
998
0
  }
999
1000
0
  return true;
1001
0
}
1002
1003
//! get AC and DC values for weighted pred
1004
void  Slice::getWpAcDcParam(const WPACDCParam *&wp) const
1005
0
{
1006
0
  wp = m_weightACDCParam;
1007
0
}
1008
1009
//! init AC and DC values for weighted pred
1010
void  Slice::initWpAcDcParam()
1011
478
{
1012
1.91k
  for(int iComp = 0; iComp < MAX_NUM_COMPONENT; iComp++ )
1013
1.43k
  {
1014
1.43k
    m_weightACDCParam[iComp].iAC = 0;
1015
1.43k
    m_weightACDCParam[iComp].iDC = 0;
1016
1.43k
  }
1017
478
}
1018
1019
//! get tables for weighted prediction
1020
void Slice::getWpScaling( RefPicList e, int iRefIdx, const WPScalingParam*& wp ) const
1021
0
{
1022
0
  CHECK( e >= NUM_REF_PIC_LIST_01, "Invalid picture reference list" );
1023
0
  wp = m_weightPredTable[e][iRefIdx >= 0 ? iRefIdx : 0];   // iRefIdx can be -1
1024
0
}
1025
1026
void Slice::getWpScaling( RefPicList e, int iRefIdx, WPScalingParam*& wp )
1027
0
{
1028
0
  CHECK( e >= NUM_REF_PIC_LIST_01, "Invalid picture reference list" );
1029
0
  wp = m_weightPredTable[e][iRefIdx >= 0 ? iRefIdx : 0];   // iRefIdx can be -1
1030
0
}
1031
1032
//! reset Default WP tables settings : no weight.
1033
void  Slice::resetWpScaling()
1034
478
{
1035
1.43k
  for ( int e=0 ; e<NUM_REF_PIC_LIST_01 ; e++ )
1036
956
  {
1037
16.2k
    for ( int i=0 ; i<MAX_NUM_REF ; i++ )
1038
15.2k
    {
1039
61.1k
      for ( int yuv=0 ; yuv<MAX_NUM_COMPONENT ; yuv++ )
1040
45.8k
      {
1041
45.8k
        WPScalingParam  *pwp = &(m_weightPredTable[e][i][yuv]);
1042
45.8k
        pwp->bPresentFlag      = false;
1043
45.8k
        pwp->uiLog2WeightDenom = 0;
1044
45.8k
        pwp->uiLog2WeightDenom = 0;
1045
45.8k
        pwp->iWeight           = 1;
1046
45.8k
        pwp->iOffset           = 0;
1047
45.8k
      }
1048
15.2k
    }
1049
956
  }
1050
478
}
1051
1052
//! init WP table
1053
void  Slice::initWpScaling(const SPS *sps)
1054
0
{
1055
0
  const bool bUseHighPrecisionPredictionWeighting = false;// sps->getSpsRangeExtension().getHighPrecisionOffsetsEnabledFlag();
1056
0
  for ( int e=0 ; e<NUM_REF_PIC_LIST_01 ; e++ )
1057
0
  {
1058
0
    for ( int i=0 ; i<MAX_NUM_REF ; i++ )
1059
0
    {
1060
0
      for ( int yuv=0 ; yuv<MAX_NUM_COMPONENT ; yuv++ )
1061
0
      {
1062
0
        WPScalingParam  *pwp = &(m_weightPredTable[e][i][yuv]);
1063
0
        if ( !pwp->bPresentFlag )
1064
0
        {
1065
          // Inferring values not present :
1066
0
          pwp->iWeight = (1 << pwp->uiLog2WeightDenom);
1067
0
          pwp->iOffset = 0;
1068
0
        }
1069
1070
0
        const int offsetScalingFactor = bUseHighPrecisionPredictionWeighting ? 1 : ( 1 << ( sps->getBitDepth() - 8 ) );
1071
1072
0
        pwp->w      = pwp->iWeight;
1073
0
        pwp->o      = pwp->iOffset * offsetScalingFactor; //NOTE: This value of the ".o" variable is never used - .o is set immediately before it gets used
1074
0
        pwp->shift  = pwp->uiLog2WeightDenom;
1075
0
        pwp->round  = (pwp->uiLog2WeightDenom>=1) ? (1 << (pwp->uiLog2WeightDenom-1)) : (0);
1076
0
      }
1077
0
    }
1078
0
  }
1079
0
}
1080
1081
void PicHeader::getWpScaling(RefPicList e, int iRefIdx, WPScalingParam *&wp) const
1082
0
{
1083
0
  CHECK(e >= NUM_REF_PIC_LIST_01, "Invalid picture reference list");
1084
0
  wp = (WPScalingParam *) m_weightPredTable[e][iRefIdx];
1085
0
}
1086
1087
// ------------------------------------------------------------------------------------------------
1088
// Sequence parameter set (SPS)
1089
// ------------------------------------------------------------------------------------------------
1090
1091
1092
1093
RPLList& SPS::createRPLList( int l, int numRPL )
1094
264
{
1095
264
  m_RPLList[l].resize( numRPL );
1096
264
  m_numRPL[l] = numRPL;
1097
264
  m_rpl1IdxPresentFlag = ( m_RPLList[0].size() != m_RPLList[1].size() );
1098
264
  return m_RPLList[l];
1099
264
}
1100
1101
1102
const int SPS::m_winUnitX[] = { 1,2,2,1 };
1103
const int SPS::m_winUnitY[] = { 1,2,1,1 };
1104
1105
1106
void ChromaQpMappingTable::deriveChromaQPMappingTables()
1107
144
{
1108
424
  for (int i = 0; i < getNumQpTables(); i++)
1109
285
  {
1110
285
    const int qpBdOffsetC = m_qpBdOffset;
1111
285
    const int numPtsInCQPTableMinus1 = getNumPtsInCQPTableMinus1(i);
1112
285
    std::vector<int> qpInVal( numPtsInCQPTableMinus1 + 2 );
1113
285
    std::vector<int> qpOutVal( numPtsInCQPTableMinus1 + 2 );
1114
1115
285
    qpInVal[0] = getQpTableStartMinus26(i) + 26;
1116
285
    qpOutVal[0] = qpInVal[0];
1117
922
    for (int j = 0; j <= numPtsInCQPTableMinus1; j++)
1118
637
    {
1119
637
      qpInVal[j + 1] = qpInVal[j] + getDeltaQpInValMinus1(i, j) + 1;
1120
637
      qpOutVal[j + 1] = qpOutVal[j] + getDeltaQpOutVal(i, j);
1121
637
    }
1122
1123
1.19k
    for( int j = 0; j <= numPtsInCQPTableMinus1 + 1; j++ )
1124
911
    {
1125
911
      CHECK(qpInVal[j]  < -qpBdOffsetC || qpInVal[j]  > MAX_QP, "qpInVal out of range");
1126
910
      CHECK(qpOutVal[j] < -qpBdOffsetC || qpOutVal[j] > MAX_QP, "qpOutVal out of range");
1127
906
    }
1128
1129
280
    m_chromaQpMappingTables[i].resize( MAX_QP + qpBdOffsetC + 1 );
1130
280
    m_chromaQpMappingTables[i][qpInVal[0] + qpBdOffsetC] = qpOutVal[0];   // +qpBdOffsetC, because we use a vector here, instead of a map as in VTM
1131
8.81k
    for( int k = qpInVal[0] - 1; k >= -qpBdOffsetC; k-- )
1132
8.53k
    {
1133
8.53k
      m_chromaQpMappingTables[i][k + qpBdOffsetC] = Clip3( -qpBdOffsetC, MAX_QP, m_chromaQpMappingTables[i][k + 1 + qpBdOffsetC] - 1 );
1134
8.53k
    }
1135
884
    for( int j = 0; j <= numPtsInCQPTableMinus1; j++ )
1136
604
    {
1137
604
      int sh = ( getDeltaQpInValMinus1( i, j ) + 1 ) >> 1;
1138
1.95k
      for( int k = qpInVal[j] + 1, m = 1; k <= qpInVal[j + 1]; k++, m++ )
1139
1.34k
      {
1140
1.34k
        m_chromaQpMappingTables[i][k + qpBdOffsetC] =
1141
1.34k
          m_chromaQpMappingTables[i][qpInVal[j] + qpBdOffsetC] + ( ( qpOutVal[j + 1] - qpOutVal[j] ) * m + sh ) / ( getDeltaQpInValMinus1( i, j ) + 1 );
1142
1.34k
      }
1143
604
    }
1144
9.78k
    for( int k = qpInVal[numPtsInCQPTableMinus1 + 1] + 1; k <= MAX_QP; k++ )
1145
9.50k
    {
1146
9.50k
      m_chromaQpMappingTables[i][k + qpBdOffsetC] = Clip3( -qpBdOffsetC, MAX_QP, m_chromaQpMappingTables[i][k - 1 + qpBdOffsetC] + 1 );
1147
9.50k
    }
1148
280
  }
1149
144
}
1150
1151
1152
void PPS::resetTileSliceInfo()
1153
0
{
1154
0
  m_numExpTileCols = 0;
1155
0
  m_numExpTileRows = 0;
1156
0
  m_numTileCols    = 0;
1157
0
  m_numTileRows    = 0;
1158
0
  m_numSlicesInPic = 0;
1159
0
  m_tileColumnWidth.clear();
1160
0
  m_tileRowHeight.clear();
1161
0
  m_tileColBd.clear();
1162
0
  m_tileRowBd.clear();
1163
0
  m_ctuToTileCol.clear();
1164
0
  m_ctuToTileRow.clear();
1165
0
  m_rectSlices.clear();
1166
0
  m_sliceMap.clear();
1167
0
}
1168
1169
/**
1170
 - initialize tile row/column sizes and boundaries
1171
 */
1172
void PPS::initTiles()
1173
0
{
1174
0
  int       colIdx, rowIdx;
1175
0
  int       ctuX, ctuY;
1176
  
1177
  // check explicit tile column sizes
1178
0
  uint32_t  remainingWidthInCtu  = m_picWidthInCtu;
1179
0
  for( colIdx = 0; colIdx < m_numExpTileCols; colIdx++ )
1180
0
  {
1181
0
    CHECK(m_tileColumnWidth[colIdx] > remainingWidthInCtu,    "Tile column width exceeds picture width");
1182
0
    remainingWidthInCtu -= m_tileColumnWidth[colIdx];
1183
0
  }
1184
1185
  // divide remaining picture width into uniform tile columns
1186
0
  uint32_t  uniformTileColWidth = m_tileColumnWidth[colIdx-1];
1187
0
  while( remainingWidthInCtu > 0 )
1188
0
  {
1189
0
    CHECK(colIdx >= MAX_TILE_COLS, "Number of tile columns exceeds valid range");
1190
0
    uniformTileColWidth = std::min(remainingWidthInCtu, uniformTileColWidth);
1191
0
    m_tileColumnWidth.push_back( uniformTileColWidth );
1192
0
    remainingWidthInCtu -= uniformTileColWidth;
1193
0
    colIdx++;
1194
0
  }
1195
0
  m_numTileCols = colIdx;
1196
    
1197
  // check explicit tile row sizes
1198
0
  uint32_t  remainingHeightInCtu  = m_picHeightInCtu;
1199
0
  for( rowIdx = 0; rowIdx < m_numExpTileRows; rowIdx++ )
1200
0
  {
1201
0
    CHECK(m_tileRowHeight[rowIdx] > remainingHeightInCtu,     "Tile row height exceeds picture height");
1202
0
    remainingHeightInCtu -= m_tileRowHeight[rowIdx];
1203
0
  }
1204
    
1205
  // divide remaining picture height into uniform tile rows
1206
0
  uint32_t  uniformTileRowHeight = m_tileRowHeight[rowIdx - 1];
1207
0
  while( remainingHeightInCtu > 0 )
1208
0
  {
1209
0
    uniformTileRowHeight = std::min(remainingHeightInCtu, uniformTileRowHeight);
1210
0
    m_tileRowHeight.push_back( uniformTileRowHeight );
1211
0
    remainingHeightInCtu -= uniformTileRowHeight;
1212
0
    rowIdx++;
1213
0
  }
1214
0
  m_numTileRows = rowIdx;
1215
1216
  // set left column bounaries
1217
0
  m_tileColBd.push_back( 0 );
1218
0
  for( colIdx = 0; colIdx < m_numTileCols; colIdx++ )
1219
0
  {
1220
0
    m_tileColBd.push_back( m_tileColBd[ colIdx ] + m_tileColumnWidth[ colIdx ] );
1221
0
  }
1222
  
1223
  // set top row bounaries
1224
0
  m_tileRowBd.push_back( 0 );
1225
0
  for( rowIdx = 0; rowIdx < m_numTileRows; rowIdx++ )
1226
0
  {
1227
0
    m_tileRowBd.push_back( m_tileRowBd[ rowIdx ] + m_tileRowHeight[ rowIdx ] );
1228
0
  }
1229
1230
  // set mapping between horizontal CTU address and tile column index
1231
0
  colIdx = 0;
1232
0
  for( ctuX = 0; ctuX <= m_picWidthInCtu; ctuX++ )
1233
0
  {
1234
0
    if( ctuX == m_tileColBd[ colIdx + 1 ] )
1235
0
    {
1236
0
      colIdx++;
1237
0
    }
1238
0
    m_ctuToTileCol.push_back( colIdx );
1239
0
  }
1240
  
1241
  // set mapping between vertical CTU address and tile row index
1242
0
  rowIdx = 0;
1243
0
  for( ctuY = 0; ctuY <= m_picHeightInCtu; ctuY++ )
1244
0
  {
1245
0
    if( ctuY == m_tileRowBd[ rowIdx + 1 ] )
1246
0
    {
1247
0
      rowIdx++;
1248
0
    }
1249
0
    m_ctuToTileRow.push_back( rowIdx );
1250
0
  }
1251
0
}
1252
1253
void PPS::initRectSlices()
1254
0
{
1255
0
  CHECK(m_numSlicesInPic > MAX_SLICES, "Number of slices in picture exceeds valid range");
1256
0
  m_rectSlices.resize(m_numSlicesInPic);
1257
0
}
1258
1259
/**
1260
 - initialize mapping between rectangular slices and CTUs
1261
 */
1262
void PPS::initRectSliceMap(const SPS  *sps)
1263
0
{
1264
0
  if( getSingleSlicePerSubPicFlag() )
1265
0
  {
1266
0
    CHECK (sps==nullptr, "RectSliceMap can only be initialized for slice_per_sub_pic_flag with a valid SPS");
1267
0
    m_numSlicesInPic = sps->getNumSubPics();
1268
1269
    // allocate new memory for slice list
1270
0
    CHECK(m_numSlicesInPic > MAX_SLICES, "Number of slices in picture exceeds valid range");
1271
0
    m_sliceMap.resize( m_numSlicesInPic );
1272
1273
0
    if (sps->getNumSubPics() > 1)
1274
0
    {
1275
      // Q2001 v15 equation 29
1276
0
      std::vector<uint32_t> subpicWidthInTiles;
1277
0
      std::vector<uint32_t> subpicHeightInTiles;
1278
0
      std::vector<uint32_t> subpicHeightLessThanOneTileFlag;
1279
0
      subpicWidthInTiles.resize(sps->getNumSubPics());
1280
0
      subpicHeightInTiles.resize(sps->getNumSubPics());
1281
0
      subpicHeightLessThanOneTileFlag.resize(sps->getNumSubPics());
1282
0
      for (uint32_t i = 0; i <sps->getNumSubPics(); i++)
1283
0
      {
1284
0
        uint32_t leftX = sps->getSubPicCtuTopLeftX(i);
1285
0
        uint32_t rightX = leftX + sps->getSubPicWidth(i) - 1;
1286
0
        subpicWidthInTiles[i] = m_ctuToTileCol[rightX] + 1 - m_ctuToTileCol[leftX];
1287
1288
0
        uint32_t topY = sps->getSubPicCtuTopLeftY(i);
1289
0
        uint32_t bottomY = topY + sps->getSubPicHeight(i) - 1;
1290
0
        subpicHeightInTiles[i] = m_ctuToTileRow[bottomY] + 1 - m_ctuToTileRow[topY];
1291
1292
0
        if (subpicHeightInTiles[i] == 1 && sps->getSubPicHeight(i) < m_tileRowHeight[m_ctuToTileRow[topY]] )
1293
0
        {
1294
0
          subpicHeightLessThanOneTileFlag[i] = 1;
1295
0
        }
1296
0
        else
1297
0
        {
1298
0
          subpicHeightLessThanOneTileFlag[i] = 0;
1299
0
        }
1300
0
      }
1301
1302
0
      for( int i = 0; i < m_numSlicesInPic; i++ )
1303
0
      {
1304
0
        CHECK(m_numSlicesInPic != sps->getNumSubPics(), "in single slice per subpic mode, number of slice and subpic shall be equal");
1305
0
        m_sliceMap[ i ].resetSliceMap();
1306
0
        if (subpicHeightLessThanOneTileFlag[i])
1307
0
        {
1308
0
          m_sliceMap[i].addCtusToSlice(sps->getSubPicCtuTopLeftX(i), sps->getSubPicCtuTopLeftX(i) + sps->getSubPicWidth(i),
1309
0
                                       sps->getSubPicCtuTopLeftY(i), sps->getSubPicCtuTopLeftY(i) + sps->getSubPicHeight(i), m_picWidthInCtu);
1310
0
        }
1311
0
        else
1312
0
        {
1313
0
          uint32_t tileX = m_ctuToTileCol[sps->getSubPicCtuTopLeftX(i)];
1314
0
          uint32_t tileY = m_ctuToTileRow[sps->getSubPicCtuTopLeftY(i)];
1315
0
          for (uint32_t j = 0; j< subpicHeightInTiles[i]; j++)
1316
0
          {
1317
0
            for (uint32_t k = 0; k < subpicWidthInTiles[i]; k++)
1318
0
            {
1319
0
              m_sliceMap[i].addCtusToSlice(getTileColumnBd(tileX + k), getTileColumnBd(tileX + k + 1), getTileRowBd(tileY + j), getTileRowBd(tileY + j + 1), m_picWidthInCtu);
1320
0
            }
1321
0
          }
1322
0
        }
1323
0
      }
1324
0
      subpicWidthInTiles.clear();
1325
0
      subpicHeightInTiles.clear();
1326
0
      subpicHeightLessThanOneTileFlag.clear();
1327
0
    }
1328
0
    else
1329
0
    {
1330
0
      m_sliceMap[0].resetSliceMap();
1331
0
      for (int tileY=0; tileY<m_numTileRows; tileY++)
1332
0
      {
1333
0
        for (int tileX=0; tileX<m_numTileCols; tileX++)
1334
0
        {
1335
0
          m_sliceMap[0].addCtusToSlice(getTileColumnBd(tileX), getTileColumnBd(tileX + 1),
1336
0
                                       getTileRowBd(tileY), getTileRowBd(tileY + 1), m_picWidthInCtu);
1337
0
        }
1338
0
      }
1339
0
      m_sliceMap[0].setSliceID(0);
1340
0
    }
1341
0
  }
1342
0
  else
1343
0
  {
1344
    // allocate new memory for slice list
1345
0
    CHECK(m_numSlicesInPic > MAX_SLICES, "Number of slices in picture exceeds valid range");
1346
0
    m_sliceMap.resize( m_numSlicesInPic );
1347
    // generate CTU maps for all rectangular slices in picture
1348
0
    for( uint32_t i = 0; i < m_numSlicesInPic; i++ )
1349
0
    {
1350
0
      m_sliceMap[ i ].resetSliceMap();
1351
1352
      // get position of first tile in slice
1353
0
      uint32_t tileX =  m_rectSlices[ i ].getTileIdx() % m_numTileCols;
1354
0
      uint32_t tileY =  m_rectSlices[ i ].getTileIdx() / m_numTileCols;
1355
1356
      // infer slice size for last slice in picture
1357
0
      if( i == m_numSlicesInPic-1 )
1358
0
      {
1359
0
        m_rectSlices[ i ].setSliceWidthInTiles ( m_numTileCols - tileX );
1360
0
        m_rectSlices[ i ].setSliceHeightInTiles( m_numTileRows - tileY );
1361
0
        m_rectSlices[ i ].setNumSlicesInTile( 1 );
1362
0
      }
1363
1364
      // set slice index
1365
0
      m_sliceMap[ i ].setSliceID(i);
1366
1367
      // complete tiles within a single slice case
1368
0
      if( m_rectSlices[ i ].getSliceWidthInTiles( ) > 1 || m_rectSlices[ i ].getSliceHeightInTiles( ) > 1)
1369
0
      {
1370
0
        for( uint32_t j = 0; j < m_rectSlices[ i ].getSliceHeightInTiles( ); j++ )
1371
0
        {
1372
0
          for( uint32_t k = 0; k < m_rectSlices[ i ].getSliceWidthInTiles( ); k++ )
1373
0
          {
1374
0
            m_sliceMap[ i ].addCtusToSlice( getTileColumnBd(tileX + k), getTileColumnBd(tileX + k +1),
1375
0
                                            getTileRowBd(tileY + j), getTileRowBd(tileY + j +1), m_picWidthInCtu);
1376
0
          }
1377
0
        }
1378
0
      }
1379
      // multiple slices within a single tile case
1380
0
      else
1381
0
      {
1382
0
        uint32_t  numSlicesInTile = m_rectSlices[ i ].getNumSlicesInTile( );
1383
1384
0
        uint32_t ctuY = getTileRowBd( tileY );
1385
0
        for( uint32_t j = 0; j < numSlicesInTile-1; j++ )
1386
0
        {
1387
0
          m_sliceMap[ i ].addCtusToSlice( getTileColumnBd(tileX), getTileColumnBd(tileX+1),
1388
0
                                          ctuY, ctuY + m_rectSlices[ i ].getSliceHeightInCtu(), m_picWidthInCtu);
1389
0
          ctuY += m_rectSlices[ i ].getSliceHeightInCtu();
1390
0
          i++;
1391
0
          m_sliceMap[ i ].resetSliceMap();
1392
0
          m_sliceMap[ i ].setSliceID(i);
1393
0
        }
1394
1395
        // infer slice height for last slice in tile
1396
0
        CHECK( ctuY >= getTileRowBd( tileY + 1 ), "Invalid rectangular slice signalling");
1397
0
        m_rectSlices[ i ].setSliceHeightInCtu( getTileRowBd( tileY + 1 ) - ctuY );
1398
0
        m_sliceMap[ i ].addCtusToSlice( getTileColumnBd(tileX), getTileColumnBd(tileX+1),
1399
0
                                        ctuY, getTileRowBd( tileY + 1 ), m_picWidthInCtu);
1400
0
      }
1401
0
    }
1402
0
  }
1403
  // check for valid rectangular slice map
1404
0
  checkSliceMap();
1405
0
}
1406
1407
/**
1408
- initialize mapping between subpicture and CTUs
1409
*/
1410
void PPS::initSubPic( const SPS &sps )
1411
0
{
1412
0
  if( getSubPicIdMappingPresentFlag() )
1413
0
  {
1414
    // When signalled, the number of subpictures has to match in PPS and SPS
1415
0
    CHECK( getNumSubPics() != sps.getNumSubPics(), "pps_num_subpics_minus1 shall be equal to sps_num_subpics_minus1" );
1416
0
  }
1417
0
  else
1418
0
  {
1419
    // When not signalled  set the numer equal for convenient access
1420
0
    setNumSubPics( sps.getNumSubPics() );
1421
0
  }
1422
1423
0
  CHECK( getNumSubPics() > MAX_NUM_SUB_PICS, "Number of sub-pictures in picture exceeds valid range" );
1424
0
  m_subPics.resize(getNumSubPics());
1425
1426
  // Check that no subpicture is specified outside of the conformance cropping window
1427
0
  for(int i = 0; i < sps.getNumSubPics(); i++)
1428
0
  {
1429
0
    CHECK( (sps.getSubPicCtuTopLeftX(i) * sps.getCTUSize()) >=
1430
0
          (sps.getMaxPicWidthInLumaSamples() - sps.getConformanceWindow().getWindowRightOffset() * SPS::getWinUnitX(sps.getChromaFormatIdc())),
1431
0
          "No subpicture can be located completely outside of the conformance cropping window");
1432
0
    CHECK( ((sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) * sps.getCTUSize()) <= (sps.getConformanceWindow().getWindowLeftOffset() * SPS::getWinUnitX(sps.getChromaFormatIdc())),
1433
0
          "No subpicture can be located completely outside of the conformance cropping window" );
1434
0
    CHECK( (sps.getSubPicCtuTopLeftY(i) * sps.getCTUSize()) >=
1435
0
          (sps.getMaxPicHeightInLumaSamples()  - sps.getConformanceWindow().getWindowBottomOffset() * SPS::getWinUnitY(sps.getChromaFormatIdc())),
1436
0
          "No subpicture can be located completely outside of the conformance cropping window");
1437
0
    CHECK( ((sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)) * sps.getCTUSize()) <= (sps.getConformanceWindow().getWindowTopOffset() * SPS::getWinUnitY(sps.getChromaFormatIdc())),
1438
0
          "No subpicture can be located completely outside of the conformance cropping window");
1439
0
  }
1440
1441
  // m_ctuSize,  m_picWidthInCtu, and m_picHeightInCtu might not be initialized yet.
1442
0
  if( m_ctuSize == 0 || m_picWidthInCtu == 0 || m_picHeightInCtu == 0 )
1443
0
  {
1444
0
    m_ctuSize = sps.getCTUSize();
1445
0
    m_picWidthInCtu = (m_picWidthInLumaSamples + m_ctuSize - 1) / m_ctuSize;
1446
0
    m_picHeightInCtu = (m_picHeightInLumaSamples + m_ctuSize - 1) / m_ctuSize;
1447
0
  }
1448
0
  for( int i=0; i< getNumSubPics(); i++ )
1449
0
  {
1450
0
    m_subPics[i].setSubPicIdx(i);
1451
0
    if( sps.getSubPicIdMappingExplicitlySignalledFlag() )
1452
0
    {
1453
0
      if( m_subPicIdMappingPresentFlag )
1454
0
      {
1455
0
        m_subPics[i].setSubPicID( m_subPicId[i] );
1456
0
      }
1457
0
      else
1458
0
      {
1459
0
        m_subPics[i].setSubPicID( sps.getSubPicId(i) );
1460
0
      }
1461
0
    }
1462
0
    else
1463
0
    {
1464
0
      m_subPics[i].setSubPicID(i);
1465
0
    }
1466
0
    m_subPics[i].setSubPicCtuTopLeftX(sps.getSubPicCtuTopLeftX(i));
1467
0
    m_subPics[i].setSubPicCtuTopLeftY(sps.getSubPicCtuTopLeftY(i));
1468
0
    m_subPics[i].setSubPicWidthInCTUs(sps.getSubPicWidth(i));
1469
0
    m_subPics[i].setSubPicHeightInCTUs(sps.getSubPicHeight(i));
1470
1471
0
    uint32_t firstCTU = sps.getSubPicCtuTopLeftY(i) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i);
1472
0
    m_subPics[i].setFirstCTUInSubPic(firstCTU);
1473
0
    uint32_t lastCTU = (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i) - 1) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i) - 1;
1474
0
    m_subPics[i].setLastCTUInSubPic(lastCTU);
1475
1476
0
    uint32_t left = sps.getSubPicCtuTopLeftX(i) * m_ctuSize;
1477
0
    m_subPics[i].setSubPicLeft(left);
1478
1479
0
    uint32_t right = std::min(m_picWidthInLumaSamples - 1, (sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) * m_ctuSize - 1);
1480
0
    m_subPics[i].setSubPicRight(right);
1481
1482
0
    m_subPics[i].setSubPicWidthInLumaSample(right - left + 1);
1483
1484
0
    uint32_t top = sps.getSubPicCtuTopLeftY(i) * m_ctuSize;
1485
0
    m_subPics[i].setSubPicTop(top);
1486
1487
0
    uint32_t bottom = std::min(m_picHeightInLumaSamples - 1, (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)) * m_ctuSize - 1);
1488
1489
0
    m_subPics[i].setSubPicHeightInLumaSample(bottom - top + 1);
1490
1491
0
    m_subPics[i].setSubPicBottom(bottom);
1492
1493
0
    m_subPics[i].clearCTUAddrList();
1494
1495
0
    if( m_numSlicesInPic == 1 )
1496
0
    {
1497
0
      CHECK( getNumSubPics() != 1, "only one slice in picture, but number of subpic is not one" );
1498
0
      m_subPics[i].addAllCtusInPicToSubPic(0, getPicWidthInCtu(), 0, getPicHeightInCtu(), getPicWidthInCtu());
1499
0
      m_subPics[i].setNumSlicesInSubPic(1);
1500
0
    }
1501
0
    else
1502
0
    {
1503
0
      int numSlicesInSubPic = 0;
1504
0
      int idxLastSliceInSubpic = -1;
1505
0
      int idxFirstSliceAfterSubpic = m_numSlicesInPic;
1506
0
      for( int j = 0; j < m_numSlicesInPic; j++ )
1507
0
      {
1508
0
        uint32_t ctu = m_sliceMap[j].getCtuAddrInSlice(0);
1509
0
        uint32_t ctu_x = ctu % m_picWidthInCtu;
1510
0
        uint32_t ctu_y = ctu / m_picWidthInCtu;
1511
0
        if (ctu_x >= sps.getSubPicCtuTopLeftX(i) &&
1512
0
          ctu_x < (sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) &&
1513
0
          ctu_y >= sps.getSubPicCtuTopLeftY(i) &&
1514
0
          ctu_y < (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)))
1515
0
        {
1516
          // add ctus in a slice to the subpicture it belongs to
1517
0
          m_subPics[i].addCTUsToSubPic(m_sliceMap[j].getCtuAddrList());
1518
0
          numSlicesInSubPic++;
1519
0
          idxLastSliceInSubpic = j;
1520
0
        }
1521
0
        else if (idxFirstSliceAfterSubpic == m_numSlicesInPic && idxLastSliceInSubpic != -1)
1522
0
        {
1523
0
          idxFirstSliceAfterSubpic = j;
1524
0
        }
1525
0
      }
1526
0
      CHECK( idxFirstSliceAfterSubpic < idxLastSliceInSubpic, "The signalling order of slices shall follow the coding order" );
1527
0
      m_subPics[i].setNumSlicesInSubPic(numSlicesInSubPic);
1528
0
    }
1529
0
    m_subPics[i].setTreatedAsPicFlag(sps.getSubPicTreatedAsPicFlag(i));
1530
0
    m_subPics[i].setloopFilterAcrossSubPicEnabledFlag(sps.getLoopFilterAcrossSubpicEnabledFlag(i));
1531
0
  }
1532
0
}
1533
1534
const SubPic& PPS::getSubPicFromPos(const Position& pos)  const
1535
0
{
1536
0
  for (int i = 0; i< m_numSubPics; i++)
1537
0
  {
1538
0
    if (m_subPics[i].isContainingPos(pos))
1539
0
    {
1540
0
      return m_subPics[i];
1541
0
    }
1542
0
  }
1543
0
  return m_subPics[0];
1544
0
}
1545
1546
const SubPic& PPS::getSubPicFromCU(const CodingUnit& cu) const
1547
0
{
1548
0
  const Position lumaPos = cu.Y().valid() ? cu.Y().pos() : recalcPosition(cu.chromaFormat, cu.chType(), CHANNEL_TYPE_LUMA, cu.blocks[cu.chType()].pos());
1549
0
  return getSubPicFromPos(lumaPos);
1550
0
}
1551
1552
uint32_t PPS::getSubPicIdxFromSubPicId( uint32_t subPicId ) const
1553
0
{
1554
0
  for (int i = 0; i < m_numSubPics; i++)
1555
0
  {
1556
0
    if(m_subPics[i].getSubPicID() == subPicId)
1557
0
    {
1558
0
      return i;
1559
0
    }
1560
0
  }
1561
0
  THROW_RECOVERABLE( "subpicture ID does not match any subpicture of the PPS" );
1562
0
}
1563
1564
void PPS::checkSliceMap()
1565
0
{
1566
0
  uint32_t i;
1567
0
  std::vector<uint32_t>  ctuList, sliceList;
1568
0
  uint32_t picSizeInCtu = getPicWidthInCtu() * getPicHeightInCtu();
1569
0
  for( i = 0; i < m_numSlicesInPic; i++ )
1570
0
  {
1571
0
    sliceList = m_sliceMap[ i ].getCtuAddrList();
1572
0
    ctuList.insert( ctuList.end(), sliceList.begin(), sliceList.end() );
1573
0
  }
1574
0
  CHECK( ctuList.size() < picSizeInCtu, "Slice map contains too few CTUs");
1575
0
  CHECK( ctuList.size() > picSizeInCtu, "Slice map contains too many CTUs");
1576
0
  std::sort( ctuList.begin(), ctuList.end() );
1577
0
  for( i = 1; i < ctuList.size(); i++ )
1578
0
  {
1579
0
    CHECK( ctuList[i] > ctuList[i-1]+1, "CTU missing in slice map");
1580
0
    CHECK( ctuList[i] == ctuList[i-1],  "CTU duplicated in slice map");
1581
0
  }
1582
0
}
1583
1584
void PPS::finalizePPSPartitioning( const SPS* pcSPS )
1585
0
{
1586
  // initialize tile/slice info for no partitioning case
1587
0
  if( getNoPicPartitionFlag() )
1588
0
  {
1589
0
    resetTileSliceInfo();
1590
0
    setLog2CtuSize( ( int ) ceil( log2( pcSPS->getCTUSize() ) ) );
1591
0
    setNumExpTileColumns( 1 );
1592
0
    setNumExpTileRows( 1 );
1593
0
    addTileColumnWidth( getPicWidthInCtu()  );
1594
0
    addTileRowHeight  ( getPicHeightInCtu() );
1595
0
    initTiles();
1596
0
    setRectSliceFlag( 1 );
1597
0
    setNumSlicesInPic( 1 );
1598
0
    initRectSlices();
1599
0
    setTileIdxDeltaPresentFlag( 0 );
1600
0
    setSliceTileIdx( 0, 0 );
1601
0
    initRectSliceMap( pcSPS );
1602
    // when no Pic partition, number of sub picture shall be less than 2
1603
0
    CHECK( getNumSubPics() >= 2, "error, no picture partitions, but have equal to or more than 2 sub pictures" );
1604
0
  }
1605
0
  else
1606
0
  {
1607
0
    CHECK( getCtuSize() != pcSPS->getCTUSize(), "PPS CTU size does not match CTU size in SPS" );
1608
0
    if( getRectSliceFlag() )
1609
0
    {
1610
0
      initRectSliceMap( pcSPS );
1611
0
    }
1612
0
  }
1613
1614
0
  initSubPic( *pcSPS );
1615
0
}
1616
1617
1618
SliceMap::SliceMap()
1619
478
{
1620
478
  m_ctuAddrInSlice.clear();
1621
478
}
1622
1623
SliceMap::~SliceMap()
1624
478
{
1625
478
  m_numCtuInSlice = 0;
1626
478
  m_ctuAddrInSlice.clear();
1627
478
}
1628
1629
/** Sorts the deltaPOC and Used by current values in the RPS based on the deltaPOC values.
1630
 *  deltaPOC values are sorted with -ve values before the +ve values.  -ve values are in decreasing order.
1631
 *  +ve values are in increasing order.
1632
 * \returns void
1633
 */
1634
1635
ReferencePictureList::ReferencePictureList()
1636
2.02k
{
1637
2.02k
  ::memset( this, 0, sizeof( *this ) );
1638
2.02k
}
1639
1640
void ReferencePictureList::clear()
1641
0
{
1642
0
  ::memset( this, 0, sizeof( *this ) );
1643
0
}
1644
1645
void ReferencePictureList::setRefPicIdentifier( int idx, int identifier, bool isLongterm, bool isInterLayerRefPic, int interLayerIdx )
1646
821
{
1647
821
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setRefPicIdentifier out of range (0-15)" );
1648
821
  m_refPicIdentifier[idx] = identifier;
1649
821
  m_isLongtermRefPic[idx] = isLongterm;
1650
1651
821
  m_deltaPocMSBPresentFlag[idx] = false;
1652
821
  m_deltaPOCMSBCycleLT[idx] = 0;
1653
  
1654
821
  m_isInterLayerRefPic[idx] = isInterLayerRefPic;
1655
821
  m_interLayerRefPicIdx[idx] = interLayerIdx;
1656
821
}
1657
1658
int ReferencePictureList::getRefPicIdentifier(int idx) const
1659
0
{
1660
0
  return m_refPicIdentifier[idx];
1661
0
}
1662
1663
1664
bool ReferencePictureList::isRefPicLongterm(int idx) const
1665
0
{
1666
0
  return m_isLongtermRefPic[idx];
1667
0
}
1668
1669
void ReferencePictureList::setRefPicLongterm(int idx,bool isLongterm)
1670
0
{
1671
0
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setRefPicLongterm out of range (0-15)" );
1672
0
  m_isLongtermRefPic[idx] = isLongterm;
1673
0
}
1674
1675
void ReferencePictureList::setNumberOfShorttermPictures(int numberOfStrp)
1676
512
{
1677
512
  m_numberOfShorttermPictures = numberOfStrp;
1678
512
}
1679
1680
int ReferencePictureList::getNumberOfShorttermPictures() const
1681
0
{
1682
0
  return m_numberOfShorttermPictures;
1683
0
}
1684
1685
void ReferencePictureList::setNumberOfLongtermPictures(int numberOfLtrp)
1686
597
{
1687
597
  m_numberOfLongtermPictures = numberOfLtrp;
1688
597
}
1689
1690
int ReferencePictureList::getNumberOfLongtermPictures() const
1691
0
{
1692
0
  return m_numberOfLongtermPictures;
1693
0
}
1694
1695
void ReferencePictureList::setPOC(int idx, int POC)
1696
0
{
1697
0
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setPOC out of range (0-15)" );
1698
0
  m_POC[idx] = POC;
1699
0
}
1700
1701
int ReferencePictureList::getPOC(int idx) const
1702
0
{
1703
0
  return m_POC[idx];
1704
0
}
1705
1706
void ReferencePictureList::setDeltaPocMSBCycleLT(int idx, int x)
1707
0
{
1708
0
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setDeltaPocMSBCycleLT out of range (0-15)" );
1709
0
  m_deltaPOCMSBCycleLT[idx] = x;
1710
0
}
1711
1712
void ReferencePictureList::setDeltaPocMSBPresentFlag(int idx, bool x)
1713
0
{
1714
0
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setDeltaPocMSBPresentFlag out of range (0-15)" );
1715
0
  m_deltaPocMSBPresentFlag[idx] = x;
1716
0
}
1717
1718
void ReferencePictureList::setInterLayerRefPicIdx( int idx, int layerIdc )
1719
0
{
1720
0
  CHECK( idx >= MAX_NUM_REF_PICS, "RPL setInterLayerRefPicIdx out of range (0-15)" );
1721
0
  m_interLayerRefPicIdx[idx] = layerIdc;
1722
0
}
1723
1724
void ReferencePictureList::printRefPicInfo() const
1725
0
{
1726
0
  DTRACE(g_trace_ctx, D_RPSINFO, "RefPics = { ");
1727
0
  int numRefPic = getNumberOfShorttermPictures() + getNumberOfLongtermPictures();
1728
0
  for (int ii = 0; ii < numRefPic; ii++)
1729
0
  {
1730
0
    DTRACE(g_trace_ctx, D_RPSINFO, "%d%s ", m_refPicIdentifier[ii], (m_isLongtermRefPic[ii] == 1) ? "[LT]" : "[ST]");
1731
0
  }
1732
0
  DTRACE(g_trace_ctx, D_RPSINFO, "}\n");
1733
0
}
1734
1735
bool ReferencePictureList::findInRefPicList( const Picture* checkRefPic, int currPicPoc, int layerId ) const
1736
0
{
1737
  // loop through all pictures in the Reference Picture Set
1738
  // to see if the picture should be kept as reference picture
1739
0
  for( int i = 0; i < getNumRefEntries(); i++ )
1740
0
  {
1741
0
    if( isInterLayerRefPic( i ) )
1742
0
    {
1743
      // Diagonal inter-layer prediction is not allowed
1744
0
      CHECK( getRefPicIdentifier( i ), "ILRP identifier should be 0" );
1745
1746
0
      if( checkRefPic->poc == currPicPoc )
1747
0
      {
1748
0
        CHECK( checkRefPic->dpbReferenceMark != Picture::LongTerm, "LTRP needs long term mark" );
1749
0
        return true;
1750
0
      }
1751
0
    }
1752
0
    else if( checkRefPic->layerId == layerId )
1753
0
    {
1754
0
      if( isRefPicLongterm( i ) )
1755
0
      {
1756
0
        const int bitsForPoc = checkRefPic->cs->sps->getBitsForPOC();
1757
0
        const int curPoc     = checkRefPic->getPOC();
1758
0
        const int ltRefPoc   = calcLTRefPOC( currPicPoc, bitsForPoc, i );
1759
0
        if( checkRefPic->dpbReferenceMark == Picture::LongTerm && isLTPocEqual( curPoc, ltRefPoc, bitsForPoc, getDeltaPocMSBPresentFlag( i ) ) )
1760
0
        {
1761
0
          return true;
1762
0
        }
1763
0
      }
1764
0
      else
1765
0
      {
1766
0
        if( checkRefPic->poc == currPicPoc + getRefPicIdentifier( i ) )
1767
0
        {
1768
0
          return true;
1769
0
        }
1770
0
      }
1771
0
    }
1772
0
  }
1773
0
  return false;
1774
0
}
1775
1776
int ReferencePictureList::calcLTRefPOC( int currPoc, int bitsForPoc, int refPicIdentifier, bool pocMSBPresent, int deltaPocMSBCycle )
1777
0
{
1778
0
  const int pocCycle = 1 << bitsForPoc;
1779
0
  int64_t   ltrpPoc  = refPicIdentifier & ( pocCycle - 1 );
1780
0
  if( pocMSBPresent )
1781
0
  {
1782
    // 64 bit, because delta_poc_msb_cycle_lt * MaxPicOrderCntLsb can exceed 32 bit
1783
0
    ltrpPoc += currPoc - (int64_t) deltaPocMSBCycle * pocCycle - ( currPoc & ( pocCycle - 1 ) );
1784
0
    CHECK( ltrpPoc < std::numeric_limits<int>::min() || ltrpPoc > std::numeric_limits<int>::max(),
1785
0
           "ltrpPoc overflows 32 bit" );
1786
0
  }
1787
0
  return (int) ltrpPoc;
1788
0
}
1789
1790
int ReferencePictureList::calcLTRefPOC( int currPoc, int bitsForPoc, int refPicIdx ) const
1791
0
{
1792
0
  return calcLTRefPOC( currPoc,
1793
0
                       bitsForPoc,
1794
0
                       this->getRefPicIdentifier( refPicIdx ),
1795
0
                       this->getDeltaPocMSBPresentFlag( refPicIdx ),
1796
0
                       this->getDeltaPocMSBCycleLT( refPicIdx ) );
1797
0
}
1798
1799
bool isLTPocEqual( int poc1, int poc2, int bitsForPoc, bool msbPresent )
1800
0
{
1801
0
  if( msbPresent )
1802
0
  {
1803
0
    return poc1 == poc2;
1804
0
  }
1805
1806
0
  const int pocCycle = 1 << bitsForPoc;
1807
0
  return ( poc1 & ( pocCycle - 1 ) ) == ( poc2 & ( pocCycle - 1 ) );
1808
0
}
1809
1810
1811
ScalingList::ScalingList()
1812
372
{
1813
372
  reset();
1814
372
}
1815
1816
void ScalingList::reset()
1817
421
{
1818
421
  memset( m_scalingListDC, 0, sizeof( m_scalingListDC ) );
1819
1820
12.2k
  for (uint32_t id = 0; id < 28; id++)
1821
11.7k
  {
1822
11.7k
    const int matrixSize = ScalingList::matrixSize( id );
1823
11.7k
    m_scalingListCoef[id].assign( matrixSize * matrixSize, 0 );
1824
11.7k
  }
1825
421
}
1826
1827
void Slice::scaleRefPicList()
1828
0
{
1829
0
  const SPS* sps = getSPS();
1830
0
  const PPS* pps = getPPS();
1831
1832
0
  if( m_eSliceType == I_SLICE )
1833
0
  {
1834
0
    return;
1835
0
  }
1836
  
1837
0
  for( int refList = 0; refList < NUM_REF_PIC_LIST_01; refList++ )
1838
0
  {
1839
0
    if( refList == 1 && m_eSliceType != B_SLICE )
1840
0
    {
1841
0
      continue;
1842
0
    }
1843
1844
0
    for( int rIdx = 0; rIdx < m_aiNumRefIdx[refList]; rIdx++ )
1845
0
    {
1846
      // if rescaling is needed, otherwise just reuse the original picture pointer; it is needed for motion field, otherwise motion field
1847
      // requires a copy as well reference resampling for the whole picture is not applied at decoder
1848
1849
0
      CHECK( !m_apcRefPicList[refList][rIdx], "scaleRefPicList missing ref pic" );
1850
1851
0
      int xScale, yScale;
1852
0
      CU::getRprScaling( sps, pps, m_apcRefPicList[refList][rIdx]->slices[0]->getPPS(), xScale, yScale );
1853
0
      m_scalingRatio[refList][rIdx] = std::pair<int, int>( xScale, yScale );
1854
0
    }
1855
0
  }
1856
1857
  // the collocated motion field is indexed with the current picture's layout (7.4.8)
1858
0
  if( getPicHeader()->getEnableTMVPFlag() )
1859
0
  {
1860
0
    const RefPicList colList = RefPicList( isInterB() ? 1 - getColFromL0Flag() : 0 );
1861
0
    CHECK( getColRefIdx() >= getNumRefIdx( colList ), "collocated_ref_idx shall be less than NumRefIdxActive" );
1862
1863
0
    const Picture* colPic = getRefPic( colList, getColRefIdx() );
1864
0
    CHECK( colPic->isRefScaled( pps ), "the collocated picture shall have the same size and scaling window as the current picture" );
1865
0
  }
1866
0
}
1867
1868
bool             operator == (const ConstraintInfo& op1, const ConstraintInfo& op2)
1869
0
{
1870
0
  if( op1.m_intraOnlyConstraintFlag                      != op2.m_intraOnlyConstraintFlag                        ) return false;
1871
0
  if( op1.m_maxBitDepthConstraintIdc                     != op2.m_maxBitDepthConstraintIdc                       ) return false;
1872
0
  if( op1.m_maxChromaFormatConstraintIdc                 != op2.m_maxChromaFormatConstraintIdc                   ) return false;
1873
0
  if( op1.m_onePictureOnlyConstraintFlag                 != op2.m_onePictureOnlyConstraintFlag                   ) return false;
1874
0
  if( op1.m_lowerBitRateConstraintFlag                   != op2.m_lowerBitRateConstraintFlag                     ) return false;
1875
0
  if (op1.m_allLayersIndependentConstraintFlag           != op2.m_allLayersIndependentConstraintFlag             ) return false;
1876
0
  if (op1.m_noMrlConstraintFlag                          != op2.m_noMrlConstraintFlag                            ) return false;
1877
0
  if (op1.m_noIspConstraintFlag                          != op2.m_noIspConstraintFlag                            ) return false;
1878
0
  if (op1.m_noMipConstraintFlag                          != op2.m_noMipConstraintFlag                            ) return false;
1879
0
  if (op1.m_noLfnstConstraintFlag                        != op2.m_noLfnstConstraintFlag                          ) return false;
1880
0
  if (op1.m_noMmvdConstraintFlag                         != op2.m_noMmvdConstraintFlag                           ) return false;
1881
0
  if (op1.m_noSmvdConstraintFlag                         != op2.m_noSmvdConstraintFlag                           ) return false;
1882
0
  if (op1.m_noProfConstraintFlag                         != op2.m_noProfConstraintFlag                           ) return false;
1883
0
  if (op1.m_noPaletteConstraintFlag                      != op2.m_noPaletteConstraintFlag                        ) return false;
1884
0
  if (op1.m_noActConstraintFlag                          != op2.m_noActConstraintFlag                            ) return false;
1885
0
  if (op1.m_noLmcsConstraintFlag                         != op2.m_noLmcsConstraintFlag                           ) return false;
1886
0
  if (op1.m_noExplicitScaleListConstraintFlag            != op2.m_noExplicitScaleListConstraintFlag              ) return false;
1887
0
  if (op1.m_noVirtualBoundaryConstraintFlag              != op2.m_noVirtualBoundaryConstraintFlag                ) return false;
1888
0
  if (op1.m_noChromaQpOffsetConstraintFlag               != op2.m_noChromaQpOffsetConstraintFlag                 ) return false;
1889
0
  if (op1.m_noRprConstraintFlag                          != op2.m_noRprConstraintFlag                            ) return false;
1890
0
  if (op1.m_noResChangeInClvsConstraintFlag              != op2.m_noResChangeInClvsConstraintFlag                ) return false;
1891
0
  if (op1.m_noMttConstraintFlag                          != op2.m_noMttConstraintFlag                            ) return false;
1892
0
  if( op1.m_noQtbttDualTreeIntraConstraintFlag           != op2.m_noQtbttDualTreeIntraConstraintFlag             ) return false;
1893
0
  if( op1.m_noPartitionConstraintsOverrideConstraintFlag != op2.m_noPartitionConstraintsOverrideConstraintFlag   ) return false;
1894
0
  if( op1.m_noSaoConstraintFlag                          != op2.m_noSaoConstraintFlag                            ) return false;
1895
0
  if( op1.m_noAlfConstraintFlag                          != op2.m_noAlfConstraintFlag                            ) return false;
1896
0
  if( op1.m_noCCAlfConstraintFlag                        != op2.m_noCCAlfConstraintFlag                          ) return false;
1897
0
  if (op1.m_noWeightedPredictionConstraintFlag           != op2.m_noWeightedPredictionConstraintFlag             ) return false;
1898
0
  if( op1.m_noRefWraparoundConstraintFlag                != op2.m_noRefWraparoundConstraintFlag                  ) return false;
1899
0
  if( op1.m_noTemporalMvpConstraintFlag                  != op2.m_noTemporalMvpConstraintFlag                    ) return false;
1900
0
  if( op1.m_noSbtmvpConstraintFlag                       != op2.m_noSbtmvpConstraintFlag                         ) return false;
1901
0
  if( op1.m_noAmvrConstraintFlag                         != op2.m_noAmvrConstraintFlag                           ) return false;
1902
0
  if( op1.m_noBdofConstraintFlag                         != op2.m_noBdofConstraintFlag                           ) return false;
1903
0
  if( op1.m_noDmvrConstraintFlag                         != op2.m_noDmvrConstraintFlag                           ) return false;
1904
0
  if( op1.m_noCclmConstraintFlag                         != op2.m_noCclmConstraintFlag                           ) return false;
1905
0
  if( op1.m_noMtsConstraintFlag                          != op2.m_noMtsConstraintFlag                            ) return false;
1906
0
  if( op1.m_noSbtConstraintFlag                          != op2.m_noSbtConstraintFlag                            ) return false;
1907
0
  if( op1.m_noAffineMotionConstraintFlag                 != op2.m_noAffineMotionConstraintFlag                   ) return false;
1908
0
  if( op1.m_noBcwConstraintFlag                          != op2.m_noBcwConstraintFlag                            ) return false;
1909
0
  if( op1.m_noIbcConstraintFlag                          != op2.m_noIbcConstraintFlag                            ) return false;
1910
0
  if( op1.m_noCiipConstraintFlag                         != op2.m_noCiipConstraintFlag                           ) return false;
1911
0
  if( op1.m_noLadfConstraintFlag                         != op2.m_noLadfConstraintFlag                           ) return false;
1912
0
  if( op1.m_noTransformSkipConstraintFlag                != op2.m_noTransformSkipConstraintFlag                  ) return false;
1913
0
  if( op1.m_noBDPCMConstraintFlag                        != op2.m_noBDPCMConstraintFlag                          ) return false;
1914
0
  if( op1.m_noJointCbCrConstraintFlag                    != op2.m_noJointCbCrConstraintFlag                      ) return false;
1915
0
  if( op1.m_noQpDeltaConstraintFlag                      != op2.m_noQpDeltaConstraintFlag                        ) return false;
1916
0
  if( op1.m_noDepQuantConstraintFlag                     != op2.m_noDepQuantConstraintFlag                       ) return false;
1917
0
  if( op1.m_noSignDataHidingConstraintFlag               != op2.m_noSignDataHidingConstraintFlag                 ) return false;
1918
0
  if( op1.m_noTrailConstraintFlag                        != op2.m_noTrailConstraintFlag                          ) return false;
1919
0
  if( op1.m_noStsaConstraintFlag                         != op2.m_noStsaConstraintFlag                           ) return false;
1920
0
  if( op1.m_noRaslConstraintFlag                         != op2.m_noRaslConstraintFlag                           ) return false;
1921
0
  if( op1.m_noRadlConstraintFlag                         != op2.m_noRadlConstraintFlag                           ) return false;
1922
0
  if( op1.m_noIdrConstraintFlag                          != op2.m_noIdrConstraintFlag                            ) return false;
1923
0
  if( op1.m_noCraConstraintFlag                          != op2.m_noCraConstraintFlag                            ) return false;
1924
0
  if( op1.m_noGdrConstraintFlag                          != op2.m_noGdrConstraintFlag                            ) return false;
1925
0
  if( op1.m_noApsConstraintFlag                          != op2.m_noApsConstraintFlag                            ) return false;
1926
0
  return true;
1927
0
}
1928
bool             operator != (const ConstraintInfo& op1, const ConstraintInfo& op2)
1929
0
{
1930
0
  return !(op1 == op2);
1931
0
}
1932
1933
bool             operator == (const ProfileTierLevel& op1, const ProfileTierLevel& op2)
1934
0
{
1935
0
  if (op1.m_tierFlag        != op2.m_tierFlag) return false;
1936
0
  if (op1.m_profileIdc      != op2.m_profileIdc) return false;
1937
0
  if (op1.m_numSubProfile   != op2.m_numSubProfile) return false;
1938
0
  if (op1.m_levelIdc        != op2.m_levelIdc) return false;
1939
0
  if (op1.m_frameOnlyConstraintFlag != op2.m_frameOnlyConstraintFlag) return false;
1940
0
  if (op1.m_multiLayerEnabledFlag   != op2.m_multiLayerEnabledFlag) return false;
1941
0
  if (op1.m_constraintInfo  != op2.m_constraintInfo) return false;
1942
0
  if (op1.m_subProfileIdc   != op2.m_subProfileIdc) return false;
1943
1944
0
  for (int i = 0; i < MAX_TLAYER - 1; i++)
1945
0
  {
1946
0
    if (op1.m_subLayerLevelPresentFlag[i] != op2.m_subLayerLevelPresentFlag[i])
1947
0
    {
1948
0
      return false;
1949
0
    }
1950
0
  }
1951
0
  for (int i = 0; i < MAX_TLAYER; i++)
1952
0
  {
1953
0
    if (op1.m_subLayerLevelIdc[i] != op2.m_subLayerLevelIdc[i])
1954
0
    {
1955
0
      return false;
1956
0
    }
1957
0
  }
1958
0
  return true;
1959
0
}
1960
bool             operator != (const ProfileTierLevel& op1, const ProfileTierLevel& op2)
1961
0
{
1962
0
  return !(op1 == op2);
1963
0
}
1964
1965
uint32_t
1966
LevelTierFeatures::getMaxPicWidthInLumaSamples()  const
1967
0
{
1968
0
  return uint32_t(sqrt(maxLumaPs*8.0));
1969
0
}
1970
1971
uint32_t
1972
LevelTierFeatures::getMaxPicHeightInLumaSamples() const
1973
0
{
1974
0
  return uint32_t(sqrt(maxLumaPs*8.0));
1975
0
}
1976
1977
static const uint64_t MAX_CNFUINT64 = std::numeric_limits<uint64_t>::max();
1978
1979
static const LevelTierFeatures mainLevelTierInfo[] =
1980
{
1981
      //  level,       maxlumaps,      maxcpb[tier],,  maxSlicesPerAu,maxTilesPerAu,cols, maxLumaSr,       maxBr[tier],,    minCr[tier],,
1982
    { vvdecLevel::VVDEC_LEVEL1  ,    36864, {      350,        0 },       16,        1,        1,     552960ULL, {     128,        0 }, { 2, 2} },
1983
    { vvdecLevel::VVDEC_LEVEL2  ,   122880, {     1500,        0 },       16,        1,        1,    3686400ULL, {    1500,        0 }, { 2, 2} },
1984
    { vvdecLevel::VVDEC_LEVEL2_1,   245760, {     3000,        0 },       20,        1,        1,    7372800ULL, {    3000,        0 }, { 2, 2} },
1985
    { vvdecLevel::VVDEC_LEVEL3  ,   552960, {     6000,        0 },       30,        4,        2,   16588800ULL, {    6000,        0 }, { 2, 2} },
1986
    { vvdecLevel::VVDEC_LEVEL3_1,   983040, {    10000,        0 },       40,        9,        3,   33177600ULL, {   10000,        0 }, { 2, 2} },
1987
    { vvdecLevel::VVDEC_LEVEL4  ,  2228224, {    12000,    30000 },       75,       25,        5,   66846720ULL, {   12000,    30000 }, { 4, 4} },
1988
    { vvdecLevel::VVDEC_LEVEL4_1,  2228224, {    20000,    50000 },       75,       25,        5,  133693440ULL, {   20000,    50000 }, { 4, 4} },
1989
    { vvdecLevel::VVDEC_LEVEL5  ,  8912896, {    25000,   100000 },      200,      110,       10,  267386880ULL, {   25000,   100000 }, { 6, 4} },
1990
    { vvdecLevel::VVDEC_LEVEL5_1,  8912896, {    40000,   160000 },      200,      110,       10,  534773760ULL, {   40000,   160000 }, { 8, 4} },
1991
    { vvdecLevel::VVDEC_LEVEL5_2,  8912896, {    60000,   240000 },      200,      110,       10, 1069547520ULL, {   60000,   240000 }, { 8, 4} },
1992
    { vvdecLevel::VVDEC_LEVEL6  , 35651584, {    80000,   240000 },      600,      440,       20, 1069547520ULL, {   60000,   240000 }, { 8, 4} },
1993
    { vvdecLevel::VVDEC_LEVEL6_1, 35651584, {   120000,   480000 },      600,      440,       20, 2139095040ULL, {  120000,   480000 }, { 8, 4} },
1994
    { vvdecLevel::VVDEC_LEVEL6_2, 35651584, {   180000,   800000 },      600,      440,       20, 4278190080ULL, {  240000,   800000 }, { 8, 4} },
1995
    { vvdecLevel::VVDEC_LEVEL15_5, MAX_UINT,{ MAX_UINT, MAX_UINT }, MAX_UINT, MAX_UINT, MAX_UINT, MAX_CNFUINT64, {MAX_UINT, MAX_UINT }, { 0, 0} },
1996
    { vvdecLevel::VVDEC_LEVEL_NONE    }
1997
};
1998
1999
static const ProfileFeatures validProfiles[] = {
2000
// profile, pNameString, maxBitDepth, maxChrFmt, lvl15.5, cpbvcl, cpbnal, fcf*1000, mincr*100, levelInfo
2001
// most constrained profiles must appear first.
2002
  { Profile::MAIN_10_STILL_PICTURE, "Main_10_Still_Picture", 10, CHROMA_420, true, 1000, 1100, 1875, 100,
2003
    mainLevelTierInfo, true },
2004
  { Profile::MULTILAYER_MAIN_10_STILL_PICTURE, "Multilayer_Main_10_Still_Picture", 10, CHROMA_420, true, 1000, 1100,
2005
    1875, 100, mainLevelTierInfo, true },
2006
  { Profile::MAIN_10_444_STILL_PICTURE, "Main_444_10_Still_Picture", 10, CHROMA_444, true, 2500, 2750, 3750, 75,
2007
    mainLevelTierInfo, true },
2008
  { Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE, "Multilayer_Main_444_10_Still_Picture", 10, CHROMA_444, true, 2500,
2009
    2750, 3750, 75, mainLevelTierInfo, true },
2010
  { Profile::MAIN_10, "Main_10", 10, CHROMA_420, false, 1000, 1100, 1875, 100, mainLevelTierInfo, false },
2011
  { Profile::MULTILAYER_MAIN_10, "Multilayer_Main_10", 10, CHROMA_420, false, 1000, 1100, 1875, 100, mainLevelTierInfo,
2012
    false },
2013
  { Profile::MAIN_10_444, "Main_444_10", 10, CHROMA_444, false, 2500, 2750, 3750, 75, mainLevelTierInfo, false },
2014
  { Profile::MULTILAYER_MAIN_10_444, "Multilayer_Main_444_10", 10, CHROMA_444, false, 2500, 2750, 3750, 75,
2015
    mainLevelTierInfo, false },
2016
  { Profile::NONE, 0 },
2017
};
2018
2019
const ProfileFeatures *ProfileFeatures::getProfileFeatures(const Profile::Name p)
2020
4
{
2021
4
  int i;
2022
24
  for (i = 0; validProfiles[i].profile != Profile::NONE; i++)
2023
22
  {
2024
22
    if (validProfiles[i].profile == p)
2025
2
    {
2026
2
      return &validProfiles[i];
2027
2
    }
2028
22
  }
2029
2030
2
  return &validProfiles[i];
2031
4
}
2032
2033
void
2034
ProfileLevelTierFeatures::extractPTLInformation(const SPS &sps)
2035
0
{
2036
0
  const ProfileTierLevel &spsPtl =*(sps.getProfileTierLevel());
2037
2038
0
  m_tier = spsPtl.getTierFlag();
2039
2040
  // Identify the profile from the profile Idc, and possibly other constraints.
2041
0
  for(int32_t i=0; validProfiles[i].profile != Profile::NONE; i++)
2042
0
  {
2043
0
    if (spsPtl.getProfileIdc() == validProfiles[i].profile)
2044
0
    {
2045
0
      m_pProfile = &(validProfiles[i]);
2046
0
      break;
2047
0
    }
2048
0
  }
2049
2050
0
  if (m_pProfile != 0)
2051
0
  {
2052
    // Now identify the level:
2053
0
    const LevelTierFeatures *pLTF  = m_pProfile->pLevelTiersListInfo;
2054
0
    const vvdecLevel spsLevelName  = spsPtl.getLevelIdc();
2055
0
    if (spsLevelName!=vvdecLevel::VVDEC_LEVEL15_5 || m_pProfile->canUseLevel15p5)
2056
0
    {
2057
0
      for(int i=0; pLTF[i].level!=vvdecLevel::VVDEC_LEVEL_NONE; i++)
2058
0
      {
2059
0
        if (pLTF[i].level == spsLevelName)
2060
0
        {
2061
0
          m_pLevelTier = &(pLTF[i]);
2062
0
        }
2063
0
      }
2064
0
    }
2065
0
  }
2066
0
}
2067
2068
uint64_t ProfileLevelTierFeatures::getCpbSizeInBits() const
2069
0
{
2070
0
  return (m_pLevelTier!=0 && m_pProfile!=0) ? uint64_t(m_pProfile->cpbVclFactor) * m_pLevelTier->maxCpb[m_tier?1:0] : uint64_t(0);
2071
0
}
2072
2073
uint32_t ProfileLevelTierFeatures::getMaxDpbSize( uint32_t picSizeMaxInSamplesY ) const
2074
0
{
2075
0
  const uint32_t maxDpbPicBuf = 8;
2076
0
  uint32_t       maxDpbSize;
2077
2078
0
  if (m_pLevelTier->level == vvdecLevel::VVDEC_LEVEL15_5)
2079
0
  {
2080
    // maxDpbSize is unconstrained in this case
2081
0
    maxDpbSize = std::numeric_limits<uint32_t>::max();
2082
0
  }
2083
0
  else if (2 * picSizeMaxInSamplesY <= m_pLevelTier->maxLumaPs)
2084
0
  {
2085
0
    maxDpbSize = 2 * maxDpbPicBuf;
2086
0
  }
2087
0
  else if (3 * picSizeMaxInSamplesY <= 2 * m_pLevelTier->maxLumaPs)
2088
0
  {
2089
0
    maxDpbSize = 3 * maxDpbPicBuf / 2;
2090
0
  }
2091
0
  else
2092
0
  {
2093
0
    maxDpbSize = maxDpbPicBuf;
2094
0
  }
2095
2096
0
  return maxDpbSize;
2097
0
}
2098
2099
#if ENABLE_TRACING
2100
void xTraceVPSHeader()
2101
{
2102
  DTRACE( g_trace_ctx, D_HEADER, "=========== Video Parameter Set     ===========\n" );
2103
}
2104
void xTraceDCIHeader()
2105
{
2106
  DTRACE( g_trace_ctx, D_HEADER, "=========== DCI     ===========\n" );
2107
}
2108
void xTraceSPSHeader()
2109
{
2110
  DTRACE( g_trace_ctx, D_HEADER, "=========== Sequence Parameter Set  ===========\n" );
2111
}
2112
2113
void xTracePPSHeader()
2114
{
2115
  DTRACE( g_trace_ctx, D_HEADER, "=========== Picture Parameter Set  ===========\n" );
2116
}
2117
2118
void xTraceAPSHeader()
2119
{
2120
  DTRACE(g_trace_ctx, D_HEADER, "=========== Adaptation Parameter Set  ===========\n");
2121
}
2122
2123
void xTracePictureHeader()
2124
{
2125
  DTRACE( g_trace_ctx, D_HEADER, "=========== Picture Header ===========\n" );
2126
}
2127
2128
void xTraceSliceHeader()
2129
{
2130
  DTRACE( g_trace_ctx, D_HEADER, "=========== Slice ===========\n" );
2131
}
2132
2133
void xTraceAccessUnitDelimiter()
2134
{
2135
  DTRACE( g_trace_ctx, D_HEADER, "=========== Access Unit Delimiter ===========\n" );
2136
}
2137
#endif
2138
2139
}