Coverage Report

Created: 2026-04-01 07:49

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