Coverage Report

Created: 2026-07-16 06:32

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