Coverage Report

Created: 2026-07-25 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vvdec/source/Lib/CommonLib/Slice.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
The copyright in this software is being made available under the Clear BSD
3
License, included below. No patent rights, trademark rights and/or 
4
other Intellectual Property Rights other than the copyrights concerning 
5
the Software are granted under this license.
6
7
The Clear BSD License
8
9
Copyright (c) 2018-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVdeC Authors.
10
All rights reserved.
11
12
Redistribution and use in source and binary forms, with or without modification,
13
are permitted (subject to the limitations in the disclaimer below) provided that
14
the following conditions are met:
15
16
     * Redistributions of source code must retain the above copyright notice,
17
     this list of conditions and the following disclaimer.
18
19
     * Redistributions in binary form must reproduce the above copyright
20
     notice, this list of conditions and the following disclaimer in the
21
     documentation and/or other materials provided with the distribution.
22
23
     * Neither the name of the copyright holder nor the names of its
24
     contributors may be used to endorse or promote products derived from this
25
     software without specific prior written permission.
26
27
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
28
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
29
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
31
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
32
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
36
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
POSSIBILITY OF SUCH DAMAGE.
39
40
41
------------------------------------------------------------------------------------------- */
42
43
/** \file     Slice.cpp
44
    \brief    slice header and SPS class
45
*/
46
47
#include "CommonDef.h"
48
#include "Unit.h"
49
#include "Slice.h"
50
#include "Picture.h"
51
#include "dtrace_next.h"
52
53
#include "UnitTools.h"
54
#include "vvdec/sei.h"
55
56
namespace vvdec
57
{
58
59
void VPS::deriveOutputLayerSets()
60
0
{
61
0
  if( m_uiMaxLayers == 1 )
62
0
  {
63
0
    m_totalNumOLSs = 1;
64
0
  }
65
0
  else if( m_vpsEachLayerIsAnOlsFlag || m_vpsOlsModeIdc < 2 )
66
0
  {
67
0
    m_totalNumOLSs = m_uiMaxLayers;
68
0
  }
69
0
  else if( m_vpsOlsModeIdc == 2 )
70
0
  {
71
0
    m_totalNumOLSs = m_vpsNumOutputLayerSets;
72
0
  }
73
74
0
  m_olsDpbParamsIdx.resize( m_totalNumOLSs );
75
0
  m_olsDpbPicSize.resize( m_totalNumOLSs, Size(0, 0) );
76
0
  m_numOutputLayersInOls.resize( m_totalNumOLSs );
77
0
  m_numLayersInOls.resize( m_totalNumOLSs );
78
0
  m_outputLayerIdInOls.resize( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
79
0
  m_layerIdInOls.resize( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
80
81
0
  std::vector<int> numRefLayers( m_uiMaxLayers );
82
0
  std::vector<std::vector<int>> outputLayerIdx( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
83
0
  std::vector<std::vector<int>> layerIncludedInOlsFlag( m_totalNumOLSs, std::vector<int>( m_uiMaxLayers, 0 ) );
84
0
  std::vector<std::vector<int>> dependencyFlag( m_uiMaxLayers, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
85
0
  std::vector<std::vector<int>> refLayerIdx( m_uiMaxLayers, std::vector<int>( m_uiMaxLayers, NOT_VALID ) );
86
0
  std::vector<int> layerUsedAsRefLayerFlag( m_uiMaxLayers, 0 );
87
0
  std::vector<int> layerUsedAsOutputLayerFlag( m_uiMaxLayers, NOT_VALID );
88
0
  for( int i = 0; i < m_uiMaxLayers; i++ )
89
0
  {
90
0
    int r = 0;
91
92
0
    for( int j = 0; j < m_uiMaxLayers; j++ )
93
0
    {
94
0
      dependencyFlag[i][j] = m_vpsDirectRefLayerFlag[i][j];
95
96
0
      for( int k = 0; k < i; k++ )
97
0
      {
98
0
        if( m_vpsDirectRefLayerFlag[i][k] && dependencyFlag[k][j] )
99
0
        {
100
0
          dependencyFlag[i][j] = 1;
101
0
        }
102
0
      }
103
0
      if (m_vpsDirectRefLayerFlag[i][j])
104
0
      {
105
0
        layerUsedAsRefLayerFlag[j] = 1;
106
0
      }
107
0
      if( dependencyFlag[i][j] )
108
0
      {
109
0
        refLayerIdx[i][r++] = j;
110
0
      }
111
0
    }
112
113
0
    numRefLayers[i] = r;
114
0
  }
115
116
0
  m_numOutputLayersInOls[0] = 1;
117
0
  m_outputLayerIdInOls[0][0] = m_vpsLayerId[0];
118
0
  layerUsedAsOutputLayerFlag[0] = 1;
119
0
  for (int i = 1; i < m_uiMaxLayers; i++)
120
0
  {
121
0
    if (m_vpsEachLayerIsAnOlsFlag || m_vpsOlsModeIdc < 2)
122
0
    {
123
0
      layerUsedAsOutputLayerFlag[i] = 1;
124
0
    }
125
0
    else
126
0
    {
127
0
      layerUsedAsOutputLayerFlag[i] = 0;
128
0
    }
129
0
  }
130
0
  for( int i = 1; i < m_totalNumOLSs; i++ )
131
0
  {
132
0
    if( m_vpsEachLayerIsAnOlsFlag || m_vpsOlsModeIdc == 0 )
133
0
    {
134
0
      m_numOutputLayersInOls[i] = 1;
135
0
      m_outputLayerIdInOls[i][0] = m_vpsLayerId[i];
136
0
    }
137
0
    else if( m_vpsOlsModeIdc == 1 )
138
0
    {
139
0
      m_numOutputLayersInOls[i] = i + 1;
140
141
0
      for( int j = 0; j < m_numOutputLayersInOls[i]; j++ )
142
0
      {
143
0
        m_outputLayerIdInOls[i][j] = m_vpsLayerId[j];
144
0
      }
145
0
    }
146
0
    else if( m_vpsOlsModeIdc == 2 )
147
0
    {
148
0
      int j = 0;
149
0
      for( int k = 0; k < m_uiMaxLayers; k++ )
150
0
      {
151
0
        if( m_vpsOlsOutputLayerFlag[i][k] )
152
0
        {
153
0
          layerIncludedInOlsFlag[i][k] = 1;
154
0
          layerUsedAsOutputLayerFlag[k] = 1;
155
0
          outputLayerIdx[i][j] = k;
156
0
          m_outputLayerIdInOls[i][j++] = m_vpsLayerId[k];
157
0
        }
158
0
      }
159
0
      m_numOutputLayersInOls[i] = j;
160
161
0
      for( j = 0; j < m_numOutputLayersInOls[i]; j++ )
162
0
      {
163
0
        int idx = outputLayerIdx[i][j];
164
0
        for( int k = 0; k < numRefLayers[idx]; k++ )
165
0
        {
166
0
          layerIncludedInOlsFlag[i][refLayerIdx[idx][k]] = 1;
167
0
        }
168
0
      }
169
0
    }
170
0
  }
171
0
  for (int i = 0; i < m_uiMaxLayers; i++)
172
0
  {
173
0
    CHECK(layerUsedAsRefLayerFlag[i] == 0 && layerUsedAsOutputLayerFlag[i] == 0, "There shall be no layer that is neither an output layer nor a direct reference layer");
174
0
  }
175
176
0
  m_numLayersInOls[0]   = 1;
177
0
  m_layerIdInOls[0][0]  = m_vpsLayerId[0];
178
0
  m_numMultiLayeredOlss = 0;
179
180
0
  for( int i = 1; i < m_totalNumOLSs; i++ )
181
0
  {
182
0
    if( m_vpsEachLayerIsAnOlsFlag )
183
0
    {
184
0
      m_numLayersInOls[i] = 1;
185
0
      m_layerIdInOls[i][0] = m_vpsLayerId[i];
186
0
    }
187
0
    else if( m_vpsOlsModeIdc == 0 || m_vpsOlsModeIdc == 1 )
188
0
    {
189
0
      m_numLayersInOls[i] = i + 1;
190
0
      for( int j = 0; j < m_numLayersInOls[i]; j++ )
191
0
      {
192
0
        m_layerIdInOls[i][j] = m_vpsLayerId[j];
193
0
      }
194
0
    }
195
0
    else if( m_vpsOlsModeIdc == 2 )
196
0
    {
197
0
      int j = 0;
198
0
      for( int k = 0; k < m_uiMaxLayers; k++ )
199
0
      {
200
0
        if( layerIncludedInOlsFlag[i][k] )
201
0
        {
202
0
          m_layerIdInOls[i][j++] = m_vpsLayerId[k];
203
0
        }
204
0
      }
205
206
0
      m_numLayersInOls[i] = j;
207
0
    }
208
0
    if( m_numLayersInOls[i] > 1 )
209
0
    {
210
0
      m_multiLayerOlsIdx[i] = m_numMultiLayeredOlss;
211
0
      m_numMultiLayeredOlss++;
212
0
    }
213
0
  }
214
0
  m_multiLayerOlsIdxToOlsIdx.resize(m_numMultiLayeredOlss);
215
216
0
  for (int i=0, j=0; i<m_totalNumOLSs; i++)
217
0
  {
218
0
    if (m_numLayersInOls[i] > 1)
219
0
    {
220
0
      m_multiLayerOlsIdxToOlsIdx[j] = i;
221
0
    }
222
0
  }
223
0
}
224
225
void VPS::checkVPS()
226
0
{
227
0
  for (int multiLayerOlsIdx=0; multiLayerOlsIdx < m_numMultiLayeredOlss; multiLayerOlsIdx++)
228
0
  {
229
0
    const int olsIdx = m_multiLayerOlsIdxToOlsIdx[multiLayerOlsIdx];
230
0
    const int olsHrdIdx = getOlsHrdIdx(multiLayerOlsIdx);
231
0
    const int olsPtlIdx = getOlsPtlIdx(olsIdx);
232
0
    CHECK( getHrdMaxTid(olsHrdIdx) < getPtlMaxTemporalId(olsPtlIdx),
233
0
           "The value of vps_hrd_max_tid[vps_ols_timing_hrd_idx[m]] shall be greater than or equal to "
234
0
           "vps_ptl_max_tid[ vps_ols_ptl_idx[n]] for each m-th multi-layer OLS for m from 0 to "
235
0
           "NumMultiLayerOlss - 1, inclusive, and n being the OLS index of the m-th multi-layer OLS among all OLSs." );
236
0
    const int olsDpbParamsIdx = getOlsDpbParamsIdx(multiLayerOlsIdx);
237
0
    CHECK( m_dpbMaxTemporalId[olsDpbParamsIdx] < getPtlMaxTemporalId(olsPtlIdx),
238
0
           "The value of vps_dpb_max_tid[vps_ols_dpb_params_idx[m]] shall be greater than or equal to "
239
0
           "vps_ptl_max_tid[ vps_ols_ptl_idx[n]] for each m-th multi-layer OLS for m from 0 to "
240
0
           "NumMultiLayerOlss - 1, inclusive, and n being the OLS index of the m-th multi-layer OLS among all OLSs." );
241
0
  }
242
0
}
243
244
void VPS::deriveTargetOutputLayerSet( int targetOlsIdx )
245
0
{
246
0
  m_iTargetLayer = targetOlsIdx < 0 ? m_uiMaxLayers - 1 : targetOlsIdx;
247
0
  m_targetOutputLayerIdSet.clear();
248
0
  m_targetLayerIdSet.clear();
249
250
0
  for( int i = 0; i < m_numOutputLayersInOls[m_iTargetLayer]; i++ )
251
0
  {
252
0
    m_targetOutputLayerIdSet.push_back( m_outputLayerIdInOls[m_iTargetLayer][i] );
253
0
  }
254
255
0
  for( int i = 0; i < m_numLayersInOls[m_iTargetLayer]; i++ )
256
0
  {
257
0
    m_targetLayerIdSet.push_back( m_layerIdInOls[m_iTargetLayer][i] );
258
0
  }
259
0
}
260
261
Slice::Slice()
262
1.64k
{
263
4.94k
  for( uint32_t i = 0; i < NUM_REF_PIC_LIST_01; i++ )
264
3.29k
  {
265
56.0k
    for(int iNumCount = 0; iNumCount < MAX_NUM_REF; iNumCount++)
266
52.7k
    {
267
52.7k
      m_apcRefPicList [i][iNumCount] = nullptr;
268
52.7k
      m_aiRefPOCList  [i][iNumCount] = 0;
269
52.7k
    }
270
271
3.29k
    m_apcRefPicList[i][MAX_NUM_REF] = nullptr;
272
3.29k
    m_aiRefPOCList [i][MAX_NUM_REF] = 0;
273
3.29k
  }
274
275
1.64k
  resetWpScaling();
276
1.64k
  initWpAcDcParam();
277
278
1.64k
  memset( m_alfApss, 0, sizeof( m_alfApss ) );
279
1.64k
}
280
281
282
void Slice::initSlice()
283
752
{
284
2.25k
  for(uint32_t i=0; i<NUM_REF_PIC_LIST_01; i++)
285
1.50k
  {
286
1.50k
    m_aiNumRefIdx[i]      = 0;
287
1.50k
  }
288
752
  m_colFromL0Flag = true;
289
752
  m_colRefIdx = 0;
290
291
752
  m_bCheckLDC = false;
292
293
752
  m_biDirPred = false;
294
752
  m_symRefIdx[0] = -1;
295
752
  m_symRefIdx[1] = -1;
296
297
3.00k
  for (uint32_t component = 0; component < MAX_NUM_COMPONENT; component++)
298
2.25k
  {
299
2.25k
    m_iSliceChromaQpDelta[component] = 0;
300
2.25k
  }
301
752
  m_iSliceChromaQpDelta[JOINT_CbCr] = 0;
302
303
304
752
  m_substreamSizes.clear();
305
752
  m_cabacInitFlag        = false;
306
752
  resetAlfEnabledFlag();
307
752
  resetCcAlfEnabledFlags();
308
752
  m_sliceMap.resetSliceMap();
309
752
}
310
311
void Slice::inheritFromPicHeader( const PicHeader* picHeader, const PPS* pps, const SPS* sps )
312
741
{
313
741
  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
741
  setColFromL0Flag( isInterB() ? picHeader->getPicColFromL0Flag() : true );
330
741
  setColRefIdx( pps->getRplInfoInPhFlag() ? picHeader->getColRefIdx() : 0 );
331
332
741
  if( pps->getQpDeltaInfoInPhFlag() )
333
0
  {
334
0
    setSliceQp( 26 + pps->getPicInitQPMinus26() + picHeader->getQpDelta() );
335
0
  }
336
337
741
  setDeblockingFilterDisable( picHeader->getDeblockingFilterDisable() );
338
741
  setDeblockingFilterBetaOffsetDiv2( picHeader->getDeblockingFilterBetaOffsetDiv2() );
339
741
  setDeblockingFilterTcOffsetDiv2  ( picHeader->getDeblockingFilterTcOffsetDiv2()   );
340
741
  if( pps->getPPSChromaToolFlag() )
341
741
  {
342
741
    setDeblockingFilterCbBetaOffsetDiv2( picHeader->getDeblockingFilterCbBetaOffsetDiv2() );
343
741
    setDeblockingFilterCbTcOffsetDiv2  ( picHeader->getDeblockingFilterCbTcOffsetDiv2()   );
344
741
    setDeblockingFilterCrBetaOffsetDiv2( picHeader->getDeblockingFilterCrBetaOffsetDiv2() );
345
741
    setDeblockingFilterCrTcOffsetDiv2  ( picHeader->getDeblockingFilterCrTcOffsetDiv2()   );
346
741
  }
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
741
  setSaoEnabledFlag( CHANNEL_TYPE_LUMA,   picHeader->getSaoEnabledFlag( CHANNEL_TYPE_LUMA ) );
356
741
  setSaoEnabledFlag( CHANNEL_TYPE_CHROMA, picHeader->getSaoEnabledFlag( CHANNEL_TYPE_CHROMA ) );
357
358
741
  setAlfEnabledFlag( COMPONENT_Y,  picHeader->getAlfEnabledFlag( COMPONENT_Y ) );
359
741
  setAlfEnabledFlag( COMPONENT_Cb, picHeader->getAlfEnabledFlag( COMPONENT_Cb ) );
360
741
  setAlfEnabledFlag( COMPONENT_Cr, picHeader->getAlfEnabledFlag( COMPONENT_Cr ) );
361
362
741
  setNumAlfAps( picHeader->getNumAlfAps() );
363
741
  setAlfApsIdsLuma( picHeader->getAlfAPSIds() );
364
741
  setAlfApsIdChroma( picHeader->getAlfApsIdChroma() );
365
741
  setCcAlfCbEnabledFlag( picHeader->getCcAlfEnabledFlag( COMPONENT_Cb ) );
366
741
  setCcAlfCrEnabledFlag( picHeader->getCcAlfEnabledFlag( COMPONENT_Cr ) );
367
741
  setCcAlfCbApsId( picHeader->getCcAlfCbApsId() );
368
741
  setCcAlfCrApsId( picHeader->getCcAlfCrApsId() );
369
370
741
  setLmcsEnabledFlag        ( getPictureHeaderInSliceHeader() ? picHeader->getLmcsEnabledFlag()                : false );
371
741
  setExplicitScalingListUsed( getPictureHeaderInSliceHeader() ? picHeader->getExplicitScalingListEnabledFlag() : false );
372
741
}
373
374
void  Slice::setNumEntryPoints( const SPS *sps, const PPS *pps )
375
718
{
376
718
  m_numEntryPoints = 0;
377
378
718
  if( !sps->getEntryPointsPresentFlag() )
379
0
  {
380
0
    return;
381
0
  }
382
383
718
  uint32_t prevCtuX = m_sliceMap.getCtuAddrInSlice( 0 ) % pps->getPicWidthInCtu();
384
718
  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
9.28k
  for( uint32_t i = 1; i < m_sliceMap.getNumCtuInSlice(); i++ )
388
8.56k
  {
389
8.56k
    const uint32_t ctuAddr = m_sliceMap.getCtuAddrInSlice( i );
390
8.56k
    const uint32_t ctuX    = ctuAddr % pps->getPicWidthInCtu();
391
8.56k
    const uint32_t ctuY    = ctuAddr / pps->getPicWidthInCtu();
392
393
8.56k
    if( pps->ctuToTileRowBd( ctuY ) != pps->ctuToTileRowBd( prevCtuY )
394
8.56k
        || pps->ctuToTileColBd( ctuX ) != pps->ctuToTileColBd( prevCtuX )
395
8.56k
        || ( ctuY != prevCtuY && sps->getEntropyCodingSyncEnabledFlag() ) )
396
0
    {
397
0
      m_numEntryPoints++;
398
0
    }
399
400
8.56k
    prevCtuX = ctuX;
401
8.56k
    prevCtuY = ctuY;
402
8.56k
  }
403
718
}
404
405
void Slice::setDefaultClpRng( const SPS& sps )
406
714
{
407
714
  m_clpRngs.bd = sps.getBitDepth();
408
714
}
409
410
411
bool Slice::getRapPicFlag() const
412
1.42k
{
413
1.42k
  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
1.42k
}
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
713
{
457
713
  ::memset(m_bIsUsedAsLongTerm, 0, sizeof(m_bIsUsedAsLongTerm));
458
713
  if (m_eSliceType == I_SLICE)
459
713
  {
460
713
    ::memset(m_apcRefPicList, 0, sizeof(m_apcRefPicList));
461
713
    ::memset(m_aiRefPOCList, 0, sizeof(m_aiRefPOCList));
462
713
    ::memset(m_aiNumRefIdx, 0, sizeof(m_aiNumRefIdx));
463
713
    return;
464
713
  }
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
1.64k
{
1007
6.59k
  for(int iComp = 0; iComp < MAX_NUM_COMPONENT; iComp++ )
1008
4.94k
  {
1009
4.94k
    m_weightACDCParam[iComp].iAC = 0;
1010
4.94k
    m_weightACDCParam[iComp].iDC = 0;
1011
4.94k
  }
1012
1.64k
}
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
1.64k
{
1030
4.94k
  for ( int e=0 ; e<NUM_REF_PIC_LIST_01 ; e++ )
1031
3.29k
  {
1032
56.0k
    for ( int i=0 ; i<MAX_NUM_REF ; i++ )
1033
52.7k
    {
1034
211k
      for ( int yuv=0 ; yuv<MAX_NUM_COMPONENT ; yuv++ )
1035
158k
      {
1036
158k
        WPScalingParam  *pwp = &(m_weightPredTable[e][i][yuv]);
1037
158k
        pwp->bPresentFlag      = false;
1038
158k
        pwp->uiLog2WeightDenom = 0;
1039
158k
        pwp->uiLog2WeightDenom = 0;
1040
158k
        pwp->iWeight           = 1;
1041
158k
        pwp->iOffset           = 0;
1042
158k
      }
1043
52.7k
    }
1044
3.29k
  }
1045
1.64k
}
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
1.73k
{
1090
1.73k
  m_RPLList[l].resize( numRPL );
1091
1.73k
  m_numRPL[l] = numRPL;
1092
1.73k
  m_rpl1IdxPresentFlag = ( m_RPLList[0].size() != m_RPLList[1].size() );
1093
1.73k
  return m_RPLList[l];
1094
1.73k
}
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
878
{
1103
1.75k
  for (int i = 0; i < getNumQpTables(); i++)
1104
884
  {
1105
884
    const int qpBdOffsetC = m_qpBdOffset;
1106
884
    const int numPtsInCQPTableMinus1 = getNumPtsInCQPTableMinus1(i);
1107
884
    std::vector<int> qpInVal( numPtsInCQPTableMinus1 + 2 );
1108
884
    std::vector<int> qpOutVal( numPtsInCQPTableMinus1 + 2 );
1109
1110
884
    qpInVal[0] = getQpTableStartMinus26(i) + 26;
1111
884
    qpOutVal[0] = qpInVal[0];
1112
3.54k
    for (int j = 0; j <= numPtsInCQPTableMinus1; j++)
1113
2.66k
    {
1114
2.66k
      qpInVal[j + 1] = qpInVal[j] + getDeltaQpInValMinus1(i, j) + 1;
1115
2.66k
      qpOutVal[j + 1] = qpOutVal[j] + getDeltaQpOutVal(i, j);
1116
2.66k
    }
1117
1118
4.41k
    for( int j = 0; j <= numPtsInCQPTableMinus1 + 1; j++ )
1119
3.53k
    {
1120
3.53k
      CHECK(qpInVal[j]  < -qpBdOffsetC || qpInVal[j]  > MAX_QP, "qpInVal out of range");
1121
3.52k
      CHECK(qpOutVal[j] < -qpBdOffsetC || qpOutVal[j] > MAX_QP, "qpOutVal out of range");
1122
3.52k
    }
1123
1124
877
    m_chromaQpMappingTables[i].resize( MAX_QP + qpBdOffsetC + 1 );
1125
877
    m_chromaQpMappingTables[i][qpInVal[0] + qpBdOffsetC] = qpOutVal[0];   // +qpBdOffsetC, because we use a vector here, instead of a map as in VTM
1126
15.8k
    for( int k = qpInVal[0] - 1; k >= -qpBdOffsetC; k-- )
1127
15.0k
    {
1128
15.0k
      m_chromaQpMappingTables[i][k + qpBdOffsetC] = Clip3( -qpBdOffsetC, MAX_QP, m_chromaQpMappingTables[i][k + 1 + qpBdOffsetC] - 1 );
1129
15.0k
    }
1130
3.49k
    for( int j = 0; j <= numPtsInCQPTableMinus1; j++ )
1131
2.62k
    {
1132
2.62k
      int sh = ( getDeltaQpInValMinus1( i, j ) + 1 ) >> 1;
1133
24.1k
      for( int k = qpInVal[j] + 1, m = 1; k <= qpInVal[j + 1]; k++, m++ )
1134
21.5k
      {
1135
21.5k
        m_chromaQpMappingTables[i][k + qpBdOffsetC] =
1136
21.5k
          m_chromaQpMappingTables[i][qpInVal[j] + qpBdOffsetC] + ( ( qpOutVal[j + 1] - qpOutVal[j] ) * m + sh ) / ( getDeltaQpInValMinus1( i, j ) + 1 );
1137
21.5k
      }
1138
2.62k
    }
1139
19.5k
    for( int k = qpInVal[numPtsInCQPTableMinus1 + 1] + 1; k <= MAX_QP; k++ )
1140
18.6k
    {
1141
18.6k
      m_chromaQpMappingTables[i][k + qpBdOffsetC] = Clip3( -qpBdOffsetC, MAX_QP, m_chromaQpMappingTables[i][k - 1 + qpBdOffsetC] + 1 );
1142
18.6k
    }
1143
877
  }
1144
878
}
1145
1146
1147
void PPS::resetTileSliceInfo()
1148
1.60k
{
1149
1.60k
  m_numExpTileCols = 0;
1150
1.60k
  m_numExpTileRows = 0;
1151
1.60k
  m_numTileCols    = 0;
1152
1.60k
  m_numTileRows    = 0;
1153
1.60k
  m_numSlicesInPic = 0;
1154
1.60k
  m_tileColumnWidth.clear();
1155
1.60k
  m_tileRowHeight.clear();
1156
1.60k
  m_tileColBd.clear();
1157
1.60k
  m_tileRowBd.clear();
1158
1.60k
  m_ctuToTileCol.clear();
1159
1.60k
  m_ctuToTileRow.clear();
1160
1.60k
  m_rectSlices.clear();
1161
1.60k
  m_sliceMap.clear();
1162
1.60k
}
1163
1164
/**
1165
 - initialize tile row/column sizes and boundaries
1166
 */
1167
void PPS::initTiles()
1168
802
{
1169
802
  int       colIdx, rowIdx;
1170
802
  int       ctuX, ctuY;
1171
  
1172
  // check explicit tile column sizes
1173
802
  uint32_t  remainingWidthInCtu  = m_picWidthInCtu;
1174
1.60k
  for( colIdx = 0; colIdx < m_numExpTileCols; colIdx++ )
1175
802
  {
1176
802
    CHECK(m_tileColumnWidth[colIdx] > remainingWidthInCtu,    "Tile column width exceeds picture width");
1177
802
    remainingWidthInCtu -= m_tileColumnWidth[colIdx];
1178
802
  }
1179
1180
  // divide remaining picture width into uniform tile columns
1181
802
  uint32_t  uniformTileColWidth = m_tileColumnWidth[colIdx-1];
1182
802
  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
802
  m_numTileCols = colIdx;
1191
    
1192
  // check explicit tile row sizes
1193
802
  uint32_t  remainingHeightInCtu  = m_picHeightInCtu;
1194
1.60k
  for( rowIdx = 0; rowIdx < m_numExpTileRows; rowIdx++ )
1195
802
  {
1196
802
    CHECK(m_tileRowHeight[rowIdx] > remainingHeightInCtu,     "Tile row height exceeds picture height");
1197
802
    remainingHeightInCtu -= m_tileRowHeight[rowIdx];
1198
802
  }
1199
    
1200
  // divide remaining picture height into uniform tile rows
1201
802
  uint32_t  uniformTileRowHeight = m_tileRowHeight[rowIdx - 1];
1202
802
  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
802
  m_numTileRows = rowIdx;
1210
1211
  // set left column bounaries
1212
802
  m_tileColBd.push_back( 0 );
1213
1.60k
  for( colIdx = 0; colIdx < m_numTileCols; colIdx++ )
1214
802
  {
1215
802
    m_tileColBd.push_back( m_tileColBd[ colIdx ] + m_tileColumnWidth[ colIdx ] );
1216
802
  }
1217
  
1218
  // set top row bounaries
1219
802
  m_tileRowBd.push_back( 0 );
1220
1.60k
  for( rowIdx = 0; rowIdx < m_numTileRows; rowIdx++ )
1221
802
  {
1222
802
    m_tileRowBd.push_back( m_tileRowBd[ rowIdx ] + m_tileRowHeight[ rowIdx ] );
1223
802
  }
1224
1225
  // set mapping between horizontal CTU address and tile column index
1226
802
  colIdx = 0;
1227
4.24k
  for( ctuX = 0; ctuX <= m_picWidthInCtu; ctuX++ )
1228
3.44k
  {
1229
3.44k
    if( ctuX == m_tileColBd[ colIdx + 1 ] )
1230
802
    {
1231
802
      colIdx++;
1232
802
    }
1233
3.44k
    m_ctuToTileCol.push_back( colIdx );
1234
3.44k
  }
1235
  
1236
  // set mapping between vertical CTU address and tile row index
1237
802
  rowIdx = 0;
1238
4.24k
  for( ctuY = 0; ctuY <= m_picHeightInCtu; ctuY++ )
1239
3.44k
  {
1240
3.44k
    if( ctuY == m_tileRowBd[ rowIdx + 1 ] )
1241
802
    {
1242
802
      rowIdx++;
1243
802
    }
1244
3.44k
    m_ctuToTileRow.push_back( rowIdx );
1245
3.44k
  }
1246
802
}
1247
1248
void PPS::initRectSlices()
1249
802
{
1250
802
  CHECK(m_numSlicesInPic > MAX_SLICES, "Number of slices in picture exceeds valid range");
1251
802
  m_rectSlices.resize(m_numSlicesInPic);
1252
802
}
1253
1254
/**
1255
 - initialize mapping between rectangular slices and CTUs
1256
 */
1257
void PPS::initRectSliceMap(const SPS  *sps)
1258
802
{
1259
802
  if( getSingleSlicePerSubPicFlag() )
1260
802
  {
1261
802
    CHECK (sps==nullptr, "RectSliceMap can only be initialized for slice_per_sub_pic_flag with a valid SPS");
1262
802
    m_numSlicesInPic = sps->getNumSubPics();
1263
1264
    // allocate new memory for slice list
1265
802
    CHECK(m_numSlicesInPic > MAX_SLICES, "Number of slices in picture exceeds valid range");
1266
802
    m_sliceMap.resize( m_numSlicesInPic );
1267
1268
802
    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
802
    else
1324
802
    {
1325
802
      m_sliceMap[0].resetSliceMap();
1326
1.60k
      for (int tileY=0; tileY<m_numTileRows; tileY++)
1327
802
      {
1328
1.60k
        for (int tileX=0; tileX<m_numTileCols; tileX++)
1329
802
        {
1330
802
          m_sliceMap[0].addCtusToSlice(getTileColumnBd(tileX), getTileColumnBd(tileX + 1),
1331
802
                                       getTileRowBd(tileY), getTileRowBd(tileY + 1), m_picWidthInCtu);
1332
802
        }
1333
802
      }
1334
802
      m_sliceMap[0].setSliceID(0);
1335
802
    }
1336
802
  }
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
802
  checkSliceMap();
1400
802
}
1401
1402
/**
1403
- initialize mapping between subpicture and CTUs
1404
*/
1405
void PPS::initSubPic( const SPS &sps )
1406
802
{
1407
802
  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
802
  else
1413
802
  {
1414
    // When not signalled  set the numer equal for convenient access
1415
802
    setNumSubPics( sps.getNumSubPics() );
1416
802
  }
1417
1418
802
  CHECK( getNumSubPics() > MAX_NUM_SUB_PICS, "Number of sub-pictures in picture exceeds valid range" );
1419
802
  m_subPics.resize(getNumSubPics());
1420
1421
  // Check that no subpicture is specified outside of the conformance cropping window
1422
1.60k
  for(int i = 0; i < sps.getNumSubPics(); i++)
1423
802
  {
1424
802
    CHECK( (sps.getSubPicCtuTopLeftX(i) * sps.getCTUSize()) >=
1425
802
          (sps.getMaxPicWidthInLumaSamples() - sps.getConformanceWindow().getWindowRightOffset() * SPS::getWinUnitX(sps.getChromaFormatIdc())),
1426
802
          "No subpicture can be located completely outside of the conformance cropping window");
1427
802
    CHECK( ((sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) * sps.getCTUSize()) <= (sps.getConformanceWindow().getWindowLeftOffset() * SPS::getWinUnitX(sps.getChromaFormatIdc())),
1428
802
          "No subpicture can be located completely outside of the conformance cropping window" );
1429
802
    CHECK( (sps.getSubPicCtuTopLeftY(i) * sps.getCTUSize()) >=
1430
802
          (sps.getMaxPicHeightInLumaSamples()  - sps.getConformanceWindow().getWindowBottomOffset() * SPS::getWinUnitY(sps.getChromaFormatIdc())),
1431
802
          "No subpicture can be located completely outside of the conformance cropping window");
1432
802
    CHECK( ((sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)) * sps.getCTUSize()) <= (sps.getConformanceWindow().getWindowTopOffset() * SPS::getWinUnitY(sps.getChromaFormatIdc())),
1433
802
          "No subpicture can be located completely outside of the conformance cropping window");
1434
802
  }
1435
1436
  // m_ctuSize,  m_picWidthInCtu, and m_picHeightInCtu might not be initialized yet.
1437
802
  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
1.60k
  for( int i=0; i< getNumSubPics(); i++ )
1444
802
  {
1445
802
    m_subPics[i].setSubPicIdx(i);
1446
802
    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
802
    else
1458
802
    {
1459
802
      m_subPics[i].setSubPicID(i);
1460
802
    }
1461
802
    m_subPics[i].setSubPicCtuTopLeftX(sps.getSubPicCtuTopLeftX(i));
1462
802
    m_subPics[i].setSubPicCtuTopLeftY(sps.getSubPicCtuTopLeftY(i));
1463
802
    m_subPics[i].setSubPicWidthInCTUs(sps.getSubPicWidth(i));
1464
802
    m_subPics[i].setSubPicHeightInCTUs(sps.getSubPicHeight(i));
1465
1466
802
    uint32_t firstCTU = sps.getSubPicCtuTopLeftY(i) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i);
1467
802
    m_subPics[i].setFirstCTUInSubPic(firstCTU);
1468
802
    uint32_t lastCTU = (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i) - 1) * m_picWidthInCtu + sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i) - 1;
1469
802
    m_subPics[i].setLastCTUInSubPic(lastCTU);
1470
1471
802
    uint32_t left = sps.getSubPicCtuTopLeftX(i) * m_ctuSize;
1472
802
    m_subPics[i].setSubPicLeft(left);
1473
1474
802
    uint32_t right = std::min(m_picWidthInLumaSamples - 1, (sps.getSubPicCtuTopLeftX(i) + sps.getSubPicWidth(i)) * m_ctuSize - 1);
1475
802
    m_subPics[i].setSubPicRight(right);
1476
1477
802
    m_subPics[i].setSubPicWidthInLumaSample(right - left + 1);
1478
1479
802
    uint32_t top = sps.getSubPicCtuTopLeftY(i) * m_ctuSize;
1480
802
    m_subPics[i].setSubPicTop(top);
1481
1482
802
    uint32_t bottom = std::min(m_picHeightInLumaSamples - 1, (sps.getSubPicCtuTopLeftY(i) + sps.getSubPicHeight(i)) * m_ctuSize - 1);
1483
1484
802
    m_subPics[i].setSubPicHeightInLumaSample(bottom - top + 1);
1485
1486
802
    m_subPics[i].setSubPicBottom(bottom);
1487
1488
802
    m_subPics[i].clearCTUAddrList();
1489
1490
802
    if( m_numSlicesInPic == 1 )
1491
802
    {
1492
802
      CHECK( getNumSubPics() != 1, "only one slice in picture, but number of subpic is not one" );
1493
802
      m_subPics[i].addAllCtusInPicToSubPic(0, getPicWidthInCtu(), 0, getPicHeightInCtu(), getPicWidthInCtu());
1494
802
      m_subPics[i].setNumSlicesInSubPic(1);
1495
802
    }
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
802
    m_subPics[i].setTreatedAsPicFlag(sps.getSubPicTreatedAsPicFlag(i));
1525
802
    m_subPics[i].setloopFilterAcrossSubPicEnabledFlag(sps.getLoopFilterAcrossSubpicEnabledFlag(i));
1526
802
  }
1527
802
}
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
2.19k
{
1549
2.19k
  for (int i = 0; i < m_numSubPics; i++)
1550
2.19k
  {
1551
2.19k
    if(m_subPics[i].getSubPicID() == subPicId)
1552
2.19k
    {
1553
2.19k
      return i;
1554
2.19k
    }
1555
2.19k
  }
1556
0
  return 0;
1557
2.19k
}
1558
1559
void PPS::checkSliceMap()
1560
802
{
1561
802
  uint32_t i;
1562
802
  std::vector<uint32_t>  ctuList, sliceList;
1563
802
  uint32_t picSizeInCtu = getPicWidthInCtu() * getPicHeightInCtu();
1564
1.60k
  for( i = 0; i < m_numSlicesInPic; i++ )
1565
802
  {
1566
802
    sliceList = m_sliceMap[ i ].getCtuAddrList();
1567
802
    ctuList.insert( ctuList.end(), sliceList.begin(), sliceList.end() );
1568
802
  }
1569
802
  CHECK( ctuList.size() < picSizeInCtu, "Slice map contains too few CTUs");
1570
802
  CHECK( ctuList.size() > picSizeInCtu, "Slice map contains too many CTUs");
1571
802
  std::sort( ctuList.begin(), ctuList.end() );
1572
10.0k
  for( i = 1; i < ctuList.size(); i++ )
1573
9.21k
  {
1574
9.21k
    CHECK( ctuList[i] > ctuList[i-1]+1, "CTU missing in slice map");
1575
9.21k
    CHECK( ctuList[i] == ctuList[i-1],  "CTU duplicated in slice map");
1576
9.21k
  }
1577
802
}
1578
1579
void PPS::finalizePPSPartitioning( const SPS* pcSPS )
1580
802
{
1581
  // initialize tile/slice info for no partitioning case
1582
802
  if( getNoPicPartitionFlag() )
1583
802
  {
1584
802
    resetTileSliceInfo();
1585
802
    setLog2CtuSize( ( int ) ceil( log2( pcSPS->getCTUSize() ) ) );
1586
802
    setNumExpTileColumns( 1 );
1587
802
    setNumExpTileRows( 1 );
1588
802
    addTileColumnWidth( getPicWidthInCtu()  );
1589
802
    addTileRowHeight  ( getPicHeightInCtu() );
1590
802
    initTiles();
1591
802
    setRectSliceFlag( 1 );
1592
802
    setNumSlicesInPic( 1 );
1593
802
    initRectSlices();
1594
802
    setTileIdxDeltaPresentFlag( 0 );
1595
802
    setSliceTileIdx( 0, 0 );
1596
802
    initRectSliceMap( pcSPS );
1597
    // when no Pic partition, number of sub picture shall be less than 2
1598
802
    CHECK( getNumSubPics() >= 2, "error, no picture partitions, but have equal to or more than 2 sub pictures" );
1599
802
  }
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
802
  initSubPic( *pcSPS );
1610
802
}
1611
1612
1613
SliceMap::SliceMap()
1614
2.45k
{
1615
2.45k
  m_ctuAddrInSlice.clear();
1616
2.45k
}
1617
1618
SliceMap::~SliceMap()
1619
3.19k
{
1620
3.19k
  m_numCtuInSlice = 0;
1621
3.19k
  m_ctuAddrInSlice.clear();
1622
3.19k
}
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
45.0k
{
1632
45.0k
  ::memset( this, 0, sizeof( *this ) );
1633
45.0k
}
1634
1635
void ReferencePictureList::clear()
1636
1.45k
{
1637
1.45k
  ::memset( this, 0, sizeof( *this ) );
1638
1.45k
}
1639
1640
void ReferencePictureList::setRefPicIdentifier( int idx, int identifier, bool isLongterm, bool isInterLayerRefPic, int interLayerIdx )
1641
97.4k
{
1642
97.4k
  CHECK( idx > MAX_NUM_REF_PICS, "RPL setRefPicIdentifier out of range (0-15)" );
1643
97.4k
  m_refPicIdentifier[idx] = identifier;
1644
97.4k
  m_isLongtermRefPic[idx] = isLongterm;
1645
1646
97.4k
  m_deltaPocMSBPresentFlag[idx] = false;
1647
97.4k
  m_deltaPOCMSBCycleLT[idx] = 0;
1648
  
1649
97.4k
  m_isInterLayerRefPic[idx] = isInterLayerRefPic;
1650
97.4k
  m_interLayerRefPicIdx[idx] = interLayerIdx;
1651
97.4k
}
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
32
{
1661
32
  return m_isLongtermRefPic[idx];
1662
32
}
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
40.1k
{
1672
40.1k
  m_numberOfShorttermPictures = numberOfStrp;
1673
40.1k
}
1674
1675
int ReferencePictureList::getNumberOfShorttermPictures() const
1676
0
{
1677
0
  return m_numberOfShorttermPictures;
1678
0
}
1679
1680
void ReferencePictureList::setNumberOfLongtermPictures(int numberOfLtrp)
1681
40.1k
{
1682
40.1k
  m_numberOfLongtermPictures = numberOfLtrp;
1683
40.1k
}
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
2.51k
{
1805
2.51k
  reset();
1806
2.51k
}
1807
1808
void ScalingList::reset()
1809
2.51k
{
1810
2.51k
  memset( m_scalingListDC, 0, sizeof( m_scalingListDC ) );
1811
1812
72.9k
  for (uint32_t id = 0; id < 28; id++)
1813
70.4k
  {
1814
70.4k
    const int matrixSize = ScalingList::matrixSize( id );
1815
70.4k
    m_scalingListCoef[id].assign( matrixSize * matrixSize, 0 );
1816
70.4k
  }
1817
2.51k
}
1818
1819
void Slice::scaleRefPicList( const PicHeader* picHeader )
1820
713
{
1821
713
  const SPS* sps = getSPS();
1822
713
  const PPS* pps = getPPS();
1823
1824
713
  bool refPicIsSameRes = false;
1825
1826
713
  if( m_eSliceType == I_SLICE )
1827
713
  {
1828
713
    return;
1829
713
  }
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
899
{
2015
899
  int i;
2016
4.49k
  for (i = 0; validProfiles[i].profile != Profile::NONE; i++)
2017
4.49k
  {
2018
4.49k
    if (validProfiles[i].profile == p)
2019
898
    {
2020
898
      return &validProfiles[i];
2021
898
    }
2022
4.49k
  }
2023
2024
1
  return &validProfiles[i];
2025
899
}
2026
2027
void
2028
ProfileLevelTierFeatures::extractPTLInformation(const SPS &sps)
2029
714
{
2030
714
  const ProfileTierLevel &spsPtl =*(sps.getProfileTierLevel());
2031
2032
714
  m_tier = spsPtl.getTierFlag();
2033
2034
  // Identify the profile from the profile Idc, and possibly other constraints.
2035
3.57k
  for(int32_t i=0; validProfiles[i].profile != Profile::NONE; i++)
2036
3.57k
  {
2037
3.57k
    if (spsPtl.getProfileIdc() == validProfiles[i].profile)
2038
714
    {
2039
714
      m_pProfile = &(validProfiles[i]);
2040
714
      break;
2041
714
    }
2042
3.57k
  }
2043
2044
714
  if (m_pProfile != 0)
2045
714
  {
2046
    // Now identify the level:
2047
714
    const LevelTierFeatures *pLTF  = m_pProfile->pLevelTiersListInfo;
2048
714
    const vvdecLevel spsLevelName  = spsPtl.getLevelIdc();
2049
714
    if (spsLevelName!=vvdecLevel::VVDEC_LEVEL15_5 || m_pProfile->canUseLevel15p5)
2050
714
    {
2051
10.7k
      for(int i=0; pLTF[i].level!=vvdecLevel::VVDEC_LEVEL_NONE; i++)
2052
9.99k
      {
2053
9.99k
        if (pLTF[i].level == spsLevelName)
2054
713
        {
2055
713
          m_pLevelTier = &(pLTF[i]);
2056
713
        }
2057
9.99k
      }
2058
714
    }
2059
714
  }
2060
714
}
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
}