Coverage Report

Created: 2026-09-01 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/vvdec/source/Lib/DecoderLib/HLSyntaxReader.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     HLSyntaxReader.cpp
44
 *  \brief    Reader for high level syntax
45
 */
46
47
//! \ingroup DecoderLib
48
//! \{
49
50
#include "HLSyntaxReader.h"
51
52
#include "CommonLib/CommonDef.h"
53
#include "CommonLib/Rom.h"
54
#include "CommonLib/dtrace_next.h"
55
#include "CommonLib/AdaptiveLoopFilter.h"
56
57
#include "ParameterSetManager.h"
58
59
2.27k
#define CHECK_CONSTRAINT( cond, msg ) CHECK( cond, msg )
60
61
namespace vvdec
62
{
63
64
void AUDReader::parseAccessUnitDelimiter( InputBitstream* bs, uint32_t &picType )
65
2
{
66
2
  setBitstream( bs );
67
68
#if ENABLE_TRACING
69
  xTraceAccessUnitDelimiter();
70
#endif
71
72
2
  X_READ_FLAG( aud_irap_or_gdr_au_flag );
73
2
  (void)aud_irap_or_gdr_au_flag;
74
75
2
  X_READ_CODE_NO_RANGE( aud_pic_type, 3 );
76
2
  picType = aud_pic_type;
77
78
2
  xReadRbspTrailingBits();
79
2
}
80
81
void FDReader::parseFillerData( InputBitstream* bs, uint32_t &fdSize )
82
0
{
83
0
  setBitstream( bs );
84
#if ENABLE_TRACING
85
  DTRACE( g_trace_ctx, D_HEADER, "=========== Filler Data ===========\n" );
86
#endif
87
0
  fdSize = 0;
88
0
  while( m_pcBitstream->getNumBitsLeft() > 8 )
89
0
  {
90
0
    X_READ_CODE_NO_RANGE( fd_ff_byte, 8 );
91
0
    CHECK_WARN( fd_ff_byte != 0xff, "Invalid fillter data not '0xff'" );
92
0
    fdSize++;
93
0
  }
94
0
  xReadRbspTrailingBits();
95
0
}
96
97
98
// ====================================================================================================================
99
// Public member functions
100
// ====================================================================================================================
101
102
void HLSyntaxReader::copyRefPicList( const SPS* sps, const ReferencePictureList* source_rpl, ReferencePictureList* dest_rp )
103
122
{
104
122
  memcpy( dest_rp, source_rpl, sizeof( ReferencePictureList ) );
105
106
122
  if( !sps->getLongTermRefsPresent() )
107
58
  {
108
58
    dest_rp->setNumberOfLongtermPictures( 0 );
109
58
  }
110
122
}
111
112
void HLSyntaxReader::parseRefPicList( ReferencePictureList* rpl, int rplIdx, const SPS* sps )
113
548
{
114
548
  X_READ_UVLC_idx( num_ref_entries, "[ listIdx ][ rplsIdx ]", 0, MAX_NUM_REF_PICS );
115
  // The value of num_ref_entries[ listIdx ][ rplsIdx ] shall be in the range of 0 to MaxDpbSize + 13, inclusive,
116
  //  where MaxDpbSize is as specified in clause A.4.2.
117
118
548
  if( sps->getLongTermRefsPresent() && num_ref_entries > 0 && rplIdx != -1 )   // rplsIdx == -1 means it's called from parsePicOrSliceHeader
119
84
  {
120
84
    X_READ_FLAG_idx( ltrp_in_header_flag, "[ listIdx ][ rplsIdx ]" );
121
84
    rpl->setLtrpInSliceHeaderFlag( ltrp_in_header_flag );
122
84
  }
123
464
  else if( sps->getLongTermRefsPresent() )
124
172
  {
125
    // When sps_long_term_ref_pics_flag is equal to 1 and rplsIdx is equal to sps_num_ref_pic_lists[ listIdx ],
126
    //  the value of ltrp_in_header_flag[ listIdx ][ rplsIdx ] is inferred to be equal to 1.
127
172
    rpl->setLtrpInSliceHeaderFlag( 1 );
128
172
  }
129
130
548
  uint32_t numStrp = 0;
131
548
  uint32_t numLtrp = 0;
132
548
  uint32_t numIlrp = 0;
133
134
548
  rpl->setInterLayerPresentFlag( sps->getInterLayerPresentFlag() );
135
136
548
  int prevDelta = 0;
137
1.25k
  for( unsigned ii = 0; ii < num_ref_entries; ii++ )
138
710
  {
139
710
    if( rpl->getInterLayerPresentFlag() )
140
252
    {
141
252
      X_READ_FLAG_idx( inter_layer_ref_pic_flag, "[ listIdx ][ rplsIdx ][ i ]" );
142
252
      if( inter_layer_ref_pic_flag )
143
112
      {
144
112
        X_READ_UVLC_idx( ilrp_idx, "[ listIdx ][ rplsIdx ][ i ]", 0, MAX_VPS_LAYERS );
145
        // The value of ilrp_idx[ listIdx ][ rplsIdx ][ i ] shall be in the range of 0 to NumDirectRefLayers[ GeneralLayerIdx[ nuh_layer_id ] ] − 1, inclusive.
146
112
        rpl->setRefPicIdentifier( ii, 0, true, true, ilrp_idx );
147
112
        numIlrp++;
148
149
112
        continue;
150
112
      }
151
252
    }
152
153
    // if( !inter_layer_ref_pic_flag )  // implicit due to previous `continue`
154
598
    {
155
598
      bool isLongTerm = false;
156
598
      if( sps->getLongTermRefsPresent() )
157
262
      {
158
262
        X_READ_FLAG_idx( st_ref_pic_flag, "[ listIdx ][ rplsIdx ][ i ]" );
159
262
        isLongTerm = !st_ref_pic_flag;
160
262
      }
161
162
598
      if( !isLongTerm )
163
460
      {
164
460
        X_READ_UVLC_idx( abs_delta_poc_st, "[ listIdx ][ rplsIdx ][ i ]", 0, ( 1 << 15 ) - 1 );
165
460
        int deltaPocSt = abs_delta_poc_st;
166
460
        if( ( !sps->getUseWP() && !sps->getUseWPBiPred() ) || ii == 0 )
167
208
        {
168
208
          deltaPocSt++;
169
208
        }
170
171
460
        if( deltaPocSt > 0 )
172
314
        {
173
314
          X_READ_FLAG_idx( strp_entry_sign_flag, "[ listIdx ][ rplsIdx ][ i ]" );
174
314
          if( strp_entry_sign_flag )
175
166
          {
176
166
            deltaPocSt = -deltaPocSt;
177
166
          }
178
314
        }
179
180
460
        deltaPocSt += prevDelta;
181
460
        prevDelta = deltaPocSt;
182
460
        rpl->setRefPicIdentifier( ii, deltaPocSt, false, false, 0 );
183
460
        numStrp++;
184
460
      }
185
138
      else
186
138
      {
187
138
        if( !rpl->getLtrpInSliceHeaderFlag() )
188
50
        {
189
50
          X_READ_CODE_NO_RANGE_idx( rpls_poc_lsb_lt, "[ listIdx ][ rplsIdx ][ j++ ]", sps->getBitsForPOC() );
190
50
          rpl->setRefPicIdentifier( ii, rpls_poc_lsb_lt, true, false, 0 );
191
50
        }
192
88
        else
193
88
        {
194
88
          rpl->setRefPicIdentifier( ii, 0, true, false, 0 );
195
88
        }
196
138
        numLtrp++;
197
138
      }
198
598
    }
199
598
  }
200
548
  rpl->setNumberOfShorttermPictures( numStrp );
201
548
  rpl->setNumberOfLongtermPictures( numLtrp );
202
548
  rpl->setNumberOfInterLayerPictures( numIlrp );
203
548
}
204
205
void HLSyntaxReader::parsePPS( PPS* pcPPS, const ParameterSetManager* parameterSetManager )
206
2
{
207
#if ENABLE_TRACING
208
  xTracePPSHeader();
209
#endif
210
211
2
  X_READ_CODE_NO_RANGE( pps_pic_parameter_set_id, 6 );
212
2
  pcPPS->setPPSId( pps_pic_parameter_set_id );
213
214
2
  X_READ_CODE( pps_seq_parameter_set_id, 4, 0, 15 );
215
2
  const SPS* sps = parameterSetManager->getSPS( pps_seq_parameter_set_id );
216
2
  CHECK( !sps, "SPS with id " << pps_seq_parameter_set_id << " missing." );
217
2
  pcPPS->setSPSId( pps_seq_parameter_set_id );
218
219
2
  const int SubWidthC  = 1 << getChannelTypeScaleX( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() );
220
2
  const int SubHeightC = 1 << getChannelTypeScaleY( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() );
221
222
2
  X_READ_FLAG( pps_mixed_nalu_types_in_pic_flag );
223
2
  pcPPS->setMixedNaluTypesInPicFlag( pps_mixed_nalu_types_in_pic_flag == 1 );
224
225
2
  const int CtbSizeY   = sps->getCTUSize();
226
2
  const int MinCbSizeY = 1 << sps->getLog2MinCodingBlockSize();
227
228
2
  X_READ_UVLC( pps_pic_width_in_luma_samples, 1, sps->getMaxPicWidthInLumaSamples() );
229
2
  CHECK( pps_pic_width_in_luma_samples & std::max( 8 - 1, MinCbSizeY - 1 ), "pps_pic_width_in_luma_samples not a multiple of 8 or MinCbSizeY" );
230
2
  CHECK( !sps->getResChangeInClvsEnabledFlag() && pps_pic_width_in_luma_samples != sps->getMaxPicWidthInLumaSamples(),
231
2
         "When sps_res_change_in_clvs_allowed_flag equal to 0, the value of pps_pic_width_in_luma_samples shall be equal"
232
2
         " to sps_pic_width_max_in_luma_samples." )
233
2
  CHECK( sps->getUseWrapAround() && CtbSizeY / MinCbSizeY + 1 > pps_pic_width_in_luma_samples / MinCbSizeY - 1,
234
2
         "When sps_ref_wraparound_enabled_flag is equal to 1, the value of ( CtbSizeY / MinCbSizeY + 1 ) shall be less than or"
235
2
         " equal to the value of ( pps_pic_width_in_luma_samples / MinCbSizeY − 1 )." );
236
2
  pcPPS->setPicWidthInLumaSamples( pps_pic_width_in_luma_samples );
237
238
2
  X_READ_UVLC( pps_pic_height_in_luma_samples, 1, sps->getMaxPicHeightInLumaSamples() );
239
2
  CHECK( pps_pic_height_in_luma_samples & std::max( 8 - 1, MinCbSizeY - 1 ), "pps_pic_height_in_luma_samples not a multiple of 8 or MinCbSizeY" );
240
2
  CHECK( !sps->getResChangeInClvsEnabledFlag() && pps_pic_height_in_luma_samples != sps->getMaxPicHeightInLumaSamples(),
241
2
         "When sps_res_change_in_clvs_allowed_flag equal to 0, the value of pps_pic_height_in_luma_samples shall be equal"
242
2
         " to sps_pic_height_max_in_luma_samples." )
243
2
  pcPPS->setPicHeightInLumaSamples( pps_pic_height_in_luma_samples );
244
245
2
  const unsigned PicWidthInCtbsY     = ( pps_pic_width_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY;      (void) PicWidthInCtbsY;
246
2
  const unsigned PicHeightInCtbsY    = ( pps_pic_height_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY;     (void) PicHeightInCtbsY;
247
2
  const unsigned PicSizeInCtbsY      = PicWidthInCtbsY * PicHeightInCtbsY;                               (void) PicSizeInCtbsY;
248
2
  const unsigned PicWidthInMinCbsY   = pps_pic_width_in_luma_samples / MinCbSizeY;                       (void) PicWidthInMinCbsY;
249
2
  const unsigned PicHeightInMinCbsY  = pps_pic_height_in_luma_samples / MinCbSizeY;                      (void) PicHeightInMinCbsY;
250
2
  const unsigned PicSizeInMinCbsY    = PicWidthInMinCbsY * PicHeightInMinCbsY;                           (void) PicSizeInMinCbsY;
251
2
  const unsigned PicSizeInSamplesY   = pps_pic_width_in_luma_samples * pps_pic_height_in_luma_samples;   (void) PicSizeInSamplesY;
252
2
  const unsigned PicWidthInSamplesC  = pps_pic_width_in_luma_samples / SubWidthC;                        (void) PicWidthInSamplesC;
253
2
  const unsigned PicHeightInSamplesC = pps_pic_height_in_luma_samples / SubHeightC;                      (void) PicHeightInSamplesC;
254
255
2
  X_READ_FLAG( pps_conformance_window_flag );
256
2
  CHECK( pps_conformance_window_flag != 0 && pcPPS->getPicWidthInLumaSamples() == sps->getMaxPicWidthInLumaSamples()
257
2
           && pcPPS->getPicHeightInLumaSamples() == sps->getMaxPicHeightInLumaSamples(),
258
2
         "pps_conformance_window_flag shall be equal to 0" )
259
2
  pcPPS->setConformanceWindowPresentFlag( pps_conformance_window_flag );
260
261
2
  if( pps_conformance_window_flag != 0 )
262
0
  {
263
0
    X_READ_UVLC_NO_RANGE( pps_conf_win_left_offset );
264
0
    X_READ_UVLC_NO_RANGE( pps_conf_win_right_offset );
265
0
    X_READ_UVLC_NO_RANGE( pps_conf_win_top_offset );
266
0
    X_READ_UVLC_NO_RANGE( pps_conf_win_bottom_offset );
267
268
0
    CHECK( SubWidthC * ( pps_conf_win_left_offset + pps_conf_win_right_offset ) >= pps_pic_width_in_luma_samples,
269
0
           "pps_conf_win_left_offset + pps_conf_win_right_offset too large" );
270
0
    CHECK( SubHeightC * ( pps_conf_win_top_offset + pps_conf_win_bottom_offset ) >= pps_pic_height_in_luma_samples,
271
0
           "pps_conf_win_top_offset + pps_conf_win_bottom_offset too large" );
272
273
0
    Window& conf = pcPPS->getConformanceWindow();
274
0
    conf.setWindowLeftOffset( pps_conf_win_left_offset );
275
0
    conf.setWindowRightOffset( pps_conf_win_right_offset );
276
0
    conf.setWindowTopOffset( pps_conf_win_top_offset );
277
0
    conf.setWindowBottomOffset( pps_conf_win_bottom_offset );
278
0
  }
279
280
2
  X_READ_FLAG_CHECK( pps_scaling_window_explicit_signalling_flag,
281
2
                     !sps->getRprEnabledFlag() && pps_scaling_window_explicit_signalling_flag != 0,
282
2
                     "When sps_ref_pic_resampling_enabled_flag is equal to 0, the value of pps_scaling_window_explicit_signalling_flag shall be equal to 0" );
283
284
2
  if( pps_scaling_window_explicit_signalling_flag != 0 )
285
0
  {
286
0
    X_READ_SVLC_NO_RANGE( pps_scaling_win_left_offset );
287
0
    X_READ_SVLC_NO_RANGE( pps_scaling_win_right_offset );
288
0
    X_READ_SVLC_NO_RANGE( pps_scaling_win_top_offset );
289
0
    X_READ_SVLC_NO_RANGE( pps_scaling_win_bottom_offset );
290
291
0
    CHECK( SubWidthC * pps_scaling_win_left_offset < -(int) pps_pic_width_in_luma_samples * 15
292
0
             || SubWidthC * pps_scaling_win_left_offset >= (int) pps_pic_width_in_luma_samples,
293
0
           "pps_scaling_win_left_offset (" << pps_scaling_win_left_offset << ") out of bounds" );
294
0
    CHECK( SubWidthC * pps_scaling_win_right_offset < -(int) pps_pic_width_in_luma_samples * 15
295
0
             || SubWidthC * pps_scaling_win_right_offset >= (int) pps_pic_width_in_luma_samples,
296
0
           "pps_scaling_win_right_offset (" << pps_scaling_win_right_offset << ") out of bounds" );
297
0
    CHECK( SubHeightC * pps_scaling_win_top_offset < -(int) pps_pic_height_in_luma_samples * 15
298
0
             || SubHeightC * pps_scaling_win_top_offset >= (int) pps_pic_height_in_luma_samples,
299
0
           "pps_scaling_win_top_offset (" << pps_scaling_win_top_offset << ") out of bounds" );
300
0
    CHECK( SubHeightC * pps_scaling_win_bottom_offset < -(int) pps_pic_height_in_luma_samples * 15
301
0
             || SubHeightC * pps_scaling_win_bottom_offset >= (int) pps_pic_height_in_luma_samples,
302
0
           "pps_scaling_win_bottom_offset (" << pps_scaling_win_bottom_offset << ") out of bounds" );
303
304
0
    CHECK( SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) < -(int) pps_pic_width_in_luma_samples * 15
305
0
             || SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) >= (int) pps_pic_width_in_luma_samples,
306
0
           "SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) shall be greater than or equal to"
307
0
           " -pps_pic_width_in_luma_samples * 15 and less than pps_pic_width_in_luma_samples."
308
0
           " (pps_scaling_win_left_offset + pps_scaling_win_right_offset = "
309
0
             << pps_scaling_win_left_offset + pps_scaling_win_right_offset << ")" );
310
311
0
    CHECK( SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) < -(int) pps_pic_height_in_luma_samples * 15
312
0
             || SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) >= (int) pps_pic_height_in_luma_samples,
313
0
           "SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) shall be greater than or equal to"
314
0
           " -pps_pic_height_in_luma_samples * 15 and less than pps_pic_height_in_luma_samples."
315
0
           " (pps_scaling_win_top_offset + pps_scaling_win_bottom_offset = "
316
0
             << pps_scaling_win_top_offset + pps_scaling_win_bottom_offset << ")" )
317
318
#if 0
319
    // these checks need to be moved to the creation of ref pic lists
320
    //
321
    const int CurrPicScalWinWidthL  = pps_pic_width_in_luma_samples - SubWidthC * ( pps_scaling_win_right_offset + pps_scaling_win_left_offset );
322
    const int CurrPicScalWinHeightL = pps_pic_height_in_luma_samples - SubHeightC * ( pps_scaling_win_bottom_offset + pps_scaling_win_top_offset );
323
    CHECK( CurrPicScalWinWidthL * 2 < refPicScalWinWidthL,
324
           "Requirement of bitstream conformance: CurrPicScalWinWidthL * 2 is greater than or equal to refPicScalWinWidthL." );
325
    CHECK( CurrPicScalWinHeightL * 2 < refPicScalWinHeightL,
326
           "Requirement of bitstream conformance: CurrPicScalWinHeightL * 2 is greater than or equal to refPicScalWinHeightL." );
327
    CHECK( CurrPicScalWinWidthL > refPicScalWinWidthL * 8,
328
           "Requirement of bitstream conformance: CurrPicScalWinWidthL is less than or equal to refPicScalWinWidthL * 8." );
329
    CHECK( CurrPicScalWinHeightL > refPicScalWinHeightL * 8,
330
           "Requirement of bitstream conformance: CurrPicScalWinHeightL is less than or equal to refPicScalWinHeightL * 8." );
331
    CHECK( CurrPicScalWinWidthL * sps->getMaxPicWidthInLumaSamples() < refPicScalWinWidthL * ( pps_pic_width_in_luma_samples - std::max( 8, MinCbSizeY ) ),
332
           "Requirement of bitstream conformance: CurrPicScalWinWidthL * sps_pic_width_max_in_luma_samples is greater than or equal to"
333
           " refPicScalWinWidthL * ( pps_pic_width_in_luma_samples - Max( 8, MinCbSizeY ) )." );
334
    CHECK( CurrPicScalWinHeightL * sps->getMaxPicHeightInLumaSamples() < refPicScalWinHeightL * ( pps_pic_height_in_luma_samples - std::max( 8, MinCbSizeY ) ),
335
           "Requirement of bitstream conformance: CurrPicScalWinHeightL * sps_pic_height_max_in_luma_samples is greater than or equal to"
336
           " refPicScalWinHeightL * ( pps_pic_height_in_luma_samples - Max( 8, MinCbSizeY ) )." );
337
#endif
338
339
0
    Window& scalingWindow = pcPPS->getScalingWindow();
340
0
    scalingWindow.setWindowLeftOffset( pps_scaling_win_left_offset );
341
0
    scalingWindow.setWindowRightOffset( pps_scaling_win_right_offset );
342
0
    scalingWindow.setWindowTopOffset( pps_scaling_win_top_offset );
343
0
    scalingWindow.setWindowBottomOffset( pps_scaling_win_bottom_offset );
344
0
  }
345
2
  else
346
2
  {
347
2
    pcPPS->setScalingWindow( pcPPS->getConformanceWindow() );
348
2
  }
349
350
2
  X_READ_FLAG( pps_output_flag_present_flag );
351
2
  pcPPS->setOutputFlagPresentFlag( pps_output_flag_present_flag );
352
353
2
  X_READ_FLAG_CHECK( pps_no_pic_partition_flag,
354
2
                     ( sps->getNumSubPics() > 1 || pps_mixed_nalu_types_in_pic_flag == 1 ) && pps_no_pic_partition_flag != 0,
355
2
                     "When sps_num_subpics_minus1 is greater than 0 or pps_mixed_nalu_types_in_pic_flag is equal to 1, the value of pps_no_pic_partition_flag "
356
2
                     "shall be equal to 0." );
357
2
  pcPPS->setNoPicPartitionFlag( pps_no_pic_partition_flag );
358
359
2
  X_READ_FLAG( pps_subpic_id_mapping_present_flag );
360
2
  CHECK( ( sps->getSubPicIdMappingExplicitlySignalledFlag() == 0 || sps->getSubPicIdMappingPresentFlag() == 1 ) && pps_subpic_id_mapping_present_flag != 0,
361
2
         "If sps_subpic_id_mapping_explicitly_signalled_flag is 0 or sps_subpic_id_mapping_present_flag is equal to 1, the value of"
362
2
         " pps_subpic_id_mapping_present_flag shall be equal to 0." );
363
2
  CHECK( ( sps->getSubPicIdMappingExplicitlySignalledFlag() == 1 && sps->getSubPicIdMappingPresentFlag() == 0 ) && pps_subpic_id_mapping_present_flag != 1,
364
2
         "Otherwise (sps_subpic_id_mapping_explicitly_signalled_flag is equal to 1 and sps_subpic_id_mapping_present_flag is equal to 0), the value of"
365
2
         " pps_subpic_id_mapping_present_flag  shall be equal to 1." );
366
2
  pcPPS->setSubPicIdMappingPresentFlag( pps_subpic_id_mapping_present_flag );
367
368
2
  if( pps_subpic_id_mapping_present_flag )
369
0
  {
370
0
    if( !pps_no_pic_partition_flag )
371
0
    {
372
0
      X_READ_UVLC( pps_num_subpics_minus1, 0, MAX_NUM_SUB_PICS - 1 );
373
0
      CHECK( pps_num_subpics_minus1 != sps->getNumSubPics() - 1, "pps_num_subpics_minus1 shall be equal to sps_num_subpics_minus1" );
374
0
      pcPPS->setNumSubPics( pps_num_subpics_minus1 + 1 );
375
0
    }
376
0
    else
377
0
    {
378
      // When pps_no_pic_partition_flag is equal to 1, the value of pps_num_subpics_minus1 is inferred to be equal to 0.
379
0
      pcPPS->setNumSubPics( 1 );
380
0
    }
381
382
0
    X_READ_UVLC( pps_subpic_id_len_minus1, 0, 15 );
383
0
    CHECK( pps_subpic_id_len_minus1 != sps->getSubPicIdLen() - 1, "pps_subpic_id_len_minus1 shall be equal to sps_subpic_id_len_minus1" );
384
0
    CHECK( ( 1 << ( pps_subpic_id_len_minus1 + 1 ) ) < pcPPS->getNumSubPics(), "pps_subpic_id_len too short" );
385
0
    pcPPS->setSubPicIdLen( pps_subpic_id_len_minus1 + 1 );
386
387
0
    for( int picIdx = 0; picIdx < pcPPS->getNumSubPics(); picIdx++ )
388
0
    {
389
0
      X_READ_CODE_NO_RANGE_idx( pps_subpic_id, "[i]", pcPPS->getSubPicIdLen() );
390
0
      pcPPS->setSubPicId( picIdx, pps_subpic_id );
391
0
    }
392
0
  }
393
2
  else
394
2
  {
395
2
    for( int picIdx = 0; picIdx < MAX_NUM_SUB_PICS; picIdx++ )
396
0
    {
397
0
      pcPPS->setSubPicId( picIdx, sps->getSubPicIdMappingExplicitlySignalledFlag() ? sps->getSubPicId( picIdx ) : picIdx );
398
0
    }
399
2
  }
400
2
  for( int i = 0; i < pcPPS->getNumSubPics(); ++i )
401
0
  {
402
0
    for( int j = 0; j < i; ++j )
403
0
    {
404
0
      CHECK( pcPPS->getSubPicId( i ) == pcPPS->getSubPicId( j ),
405
0
                         "It is a requirement of bitstream conformance that, for any two different values of i and j in the range of"
406
0
                         " 0 to sps_num_subpics_minus1, inclusive, SubpicIdVal[ i ] shall not be equal to SubpicIdVal[ j ]." )
407
0
    }
408
0
  }
409
410
2
  pcPPS->resetTileSliceInfo();
411
412
2
  if( !pps_no_pic_partition_flag )
413
0
  {
414
    // CTU size - required to match size in SPS
415
0
    X_READ_CODE( pps_log2_ctu_size_minus5, 2, 0,2 );
416
0
    CHECK( pps_log2_ctu_size_minus5 != getLog2( sps->getCTUSize() ) - 5, "pps_log2_ctu_size_minus5 shall be equal to sps_log2_ctu_size_minus5" );
417
0
    pcPPS->setLog2CtuSize( pps_log2_ctu_size_minus5 + 5 );
418
419
    // number of explicit tile columns/rows
420
421
0
    X_READ_UVLC( pps_num_exp_tile_columns_minus1, 0, PicWidthInCtbsY - 1 );
422
0
    pcPPS->setNumExpTileColumns( pps_num_exp_tile_columns_minus1 + 1 );
423
424
0
    X_READ_UVLC( pps_num_exp_tile_rows_minus1, 0, PicHeightInCtbsY - 1 );
425
0
    pcPPS->setNumExpTileRows( pps_num_exp_tile_rows_minus1 + 1 );
426
0
    CHECK( pcPPS->getNumExpTileColumns() > MAX_TILE_COLS, "Number of explicit tile columns exceeds valid range" );
427
428
    // tile sizes
429
0
    for( int colIdx = 0; colIdx < pcPPS->getNumExpTileColumns(); colIdx++ )
430
0
    {
431
0
      X_READ_UVLC_idx( pps_tile_column_width_minus1, "[i]", 0, PicWidthInCtbsY - 1 );
432
0
      pcPPS->addTileColumnWidth( pps_tile_column_width_minus1 + 1 );
433
0
    }
434
0
    for( int rowIdx = 0; rowIdx < pcPPS->getNumExpTileRows(); rowIdx++ )
435
0
    {
436
0
      X_READ_UVLC_idx( pps_tile_row_height_minus1, "[i]", 0, PicHeightInCtbsY - 1 );
437
0
      pcPPS->addTileRowHeight( pps_tile_row_height_minus1 + 1 );
438
0
    }
439
0
    pcPPS->initTiles();
440
441
    // rectangular slice signalling
442
0
    if( pcPPS->getNumTiles() > 1 )
443
0
    {
444
0
      X_READ_FLAG( pps_loop_filter_across_tiles_enabled_flag );
445
0
      pcPPS->setLoopFilterAcrossTilesEnabledFlag( pps_loop_filter_across_tiles_enabled_flag );
446
0
      X_READ_FLAG( pps_rect_slice_flag );
447
0
      CHECK( ( sps->getSubPicInfoPresentFlag() || pps_mixed_nalu_types_in_pic_flag ) && pps_rect_slice_flag != 1,
448
0
             "When sps_subpic_info_present_flag is equal to 1 or pps_mixed_nalu_types_in_pic_flag is equal to 1,"
449
0
             " the value of pps_rect_slice_flag shall be equal to 1." );
450
0
      pcPPS->setRectSliceFlag( pps_rect_slice_flag );
451
0
    }
452
0
    else
453
0
    {
454
0
      pcPPS->setLoopFilterAcrossTilesEnabledFlag( false );
455
0
      pcPPS->setRectSliceFlag( true );
456
0
    }
457
458
0
    if( pcPPS->getRectSliceFlag() )
459
0
    {
460
0
      X_READ_FLAG( pps_single_slice_per_subpic_flag );
461
0
      pcPPS->setSingleSlicePerSubPicFlag( pps_single_slice_per_subpic_flag );
462
0
    }
463
464
0
    if( pcPPS->getRectSliceFlag() && !pcPPS->getSingleSlicePerSubPicFlag() )
465
0
    {
466
0
      X_READ_UVLC( pps_num_slices_in_pic_minus1, 0, MAX_SLICES - 1 /*  TODO: should be MaxSlicesPerAU -1  */ );
467
0
      pcPPS->setNumSlicesInPic( pps_num_slices_in_pic_minus1 + 1 );
468
469
0
      if( pps_num_slices_in_pic_minus1 > 1 )
470
0
      {
471
0
        X_READ_FLAG( pps_tile_idx_delta_present_flag );
472
0
        pcPPS->setTileIdxDeltaPresentFlag( pps_tile_idx_delta_present_flag );
473
0
      }
474
0
      pcPPS->initRectSlices();
475
476
0
      int32_t tileIdx = 0;
477
      // read rectangular slice parameters
478
0
      for( int sliceIdx = 0; sliceIdx < pcPPS->getNumSlicesInPic() - 1; sliceIdx++ )
479
0
      {
480
0
        pcPPS->setSliceTileIdx( sliceIdx, tileIdx );   // this is SliceTopLeftTileIdx[ i ]
481
482
        // complete tiles within a single slice
483
0
        if( tileIdx % pcPPS->getNumTileColumns() != pcPPS->getNumTileColumns() - 1 )
484
0
        {
485
0
          X_READ_UVLC_idx( pps_slice_width_in_tiles_minus1, "[i]", 0, pcPPS->getNumTileColumns() - 1 );
486
0
          pcPPS->setSliceWidthInTiles( sliceIdx, pps_slice_width_in_tiles_minus1 + 1 );
487
0
        }
488
0
        else
489
0
        {
490
0
          pcPPS->setSliceWidthInTiles( sliceIdx, 1 );
491
0
        }
492
493
0
        if( tileIdx / pcPPS->getNumTileColumns() != pcPPS->getNumTileRows() - 1
494
0
            && ( pcPPS->getTileIdxDeltaPresentFlag() || tileIdx % pcPPS->getNumTileColumns() == 0 ) )
495
0
        {
496
0
          X_READ_UVLC_idx( pps_slice_height_in_tiles_minus1, "[i]", 0, pcPPS->getNumTileRows() - 1 );
497
0
          pcPPS->setSliceHeightInTiles( sliceIdx, pps_slice_height_in_tiles_minus1 + 1 );
498
0
        }
499
0
        else
500
0
        {
501
0
          if( tileIdx / pcPPS->getNumTileColumns() == pcPPS->getNumTileRows() - 1 )
502
0
          {
503
0
            pcPPS->setSliceHeightInTiles( sliceIdx, 1 );
504
0
          }
505
0
          else
506
0
          {
507
0
            pcPPS->setSliceHeightInTiles( sliceIdx, pcPPS->getSliceHeightInTiles( sliceIdx - 1 ) );
508
0
          }
509
0
        }
510
511
        // multiple slices within a single tile special case
512
0
        if( pcPPS->getSliceWidthInTiles( sliceIdx ) == 1 && pcPPS->getSliceHeightInTiles( sliceIdx ) == 1 )
513
0
        {
514
0
          if( pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) > 1 )
515
0
          {
516
0
            X_READ_UVLC_idx( pps_num_exp_slices_in_tile, "[i]", 0, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) - 1 );
517
0
            if( pps_num_exp_slices_in_tile == 0 )
518
0
            {
519
0
              pcPPS->setNumSlicesInTile( sliceIdx, 1 );
520
0
              pcPPS->setSliceHeightInCtu( sliceIdx, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) );
521
0
            }
522
0
            else   // ( pps_num_exp_slices_in_tile > 0 )
523
0
            {
524
0
              uint32_t remTileRowHeight         = pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() );
525
0
              uint32_t lastExpSliceHeightInCtus = 0;
526
527
0
              int j = 0;
528
0
              for( ; j < pps_num_exp_slices_in_tile; j++ )
529
0
              {
530
0
                X_READ_UVLC_idx( pps_exp_slice_height_in_ctus_minus1, "[i][j]", 0, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) - 1 );
531
0
                pcPPS->setSliceHeightInCtu( sliceIdx + j, pps_exp_slice_height_in_ctus_minus1 + 1 );
532
0
                remTileRowHeight -= ( pps_exp_slice_height_in_ctus_minus1 + 1 );
533
534
0
                lastExpSliceHeightInCtus = pps_exp_slice_height_in_ctus_minus1 + 1;
535
0
              }
536
537
0
              uint32_t uniformSliceHeight = lastExpSliceHeightInCtus;
538
0
              while( remTileRowHeight >= uniformSliceHeight )
539
0
              {
540
0
                pcPPS->setSliceHeightInCtu( sliceIdx + j, uniformSliceHeight );
541
0
                remTileRowHeight -= uniformSliceHeight;
542
0
                j++;
543
0
              }
544
0
              if( remTileRowHeight > 0 )
545
0
              {
546
0
                pcPPS->setSliceHeightInCtu( sliceIdx + j, remTileRowHeight );
547
0
                j++;
548
0
              }
549
0
              for( int k = 0; k < j; k++ )
550
0
              {
551
0
                pcPPS->setNumSlicesInTile( sliceIdx + k, j );
552
0
                pcPPS->setSliceWidthInTiles( sliceIdx + k, 1 );
553
0
                pcPPS->setSliceHeightInTiles( sliceIdx + k, 1 );
554
0
                pcPPS->setSliceTileIdx( sliceIdx + k, tileIdx );
555
0
              }
556
0
              sliceIdx += ( j - 1 );
557
0
            }    // ( pps_num_exp_slices_in_tile > 0 )
558
0
          }
559
0
          else   // ( pps->getTileRowHeight( tileIdx / pps->getNumTileColumns() ) <= 1 )
560
0
          {
561
0
            pcPPS->setNumSlicesInTile( sliceIdx, 1 );
562
0
            pcPPS->setSliceHeightInCtu( sliceIdx, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) );
563
0
          }
564
0
        }   // ( pps->getSliceWidthInTiles(sliceIdx) == 1 && pps->getSliceHeightInTiles(sliceIdx) == 1 )
565
566
        // tile index offset to start of next slice
567
0
        if( sliceIdx < pps_num_slices_in_pic_minus1 )
568
0
        {
569
0
          if( pcPPS->getTileIdxDeltaPresentFlag() )
570
0
          {
571
0
            X_READ_SVLC_idx( pps_tile_idx_delta_val, "[i]", -(int) pcPPS->getNumTiles() + 1, (int) pcPPS->getNumTiles() - 1 );
572
0
            CHECK( pps_tile_idx_delta_val == 0, "When present, the value of pps_tile_idx_delta_val[ i ] shall not be equal to 0." );
573
574
            // TODO: When pps_rect_slice_flag is equal to 1, it is a requirement of bitstrream conformance that, for any two slices, with picture-
575
            //       level slice indices idxA and idxB, that belong to the same picture and different subpictures, when
576
            //       SubpicIdxForSlice[idxA] is less than SubpicIdxForSlice[idxB], the value of idxA shall be less than idxB.
577
            // CHECK( pps->getRectSliceFlag() && /* TODO */ )
578
579
0
            tileIdx += pps_tile_idx_delta_val;
580
0
            CHECK( tileIdx < 0 || tileIdx >= (int) pcPPS->getNumTiles(), "Invalid tile_idx_delta." );
581
0
          }
582
0
          else
583
0
          {
584
0
            tileIdx += pcPPS->getSliceWidthInTiles( sliceIdx );
585
0
            if( tileIdx % pcPPS->getNumTileColumns() == 0 )
586
0
            {
587
0
              tileIdx += ( pcPPS->getSliceHeightInTiles( sliceIdx ) - 1 ) * pcPPS->getNumTileColumns();
588
0
            }
589
0
          }
590
0
        }
591
        // TODO: hier?
592
0
        CHECK( tileIdx < 0 || tileIdx >= (int) pcPPS->getNumTiles(), "Invalid tile_idx_delta." );
593
594
0
      }   // for( int i = 0; i < pps->getNumSlicesInPic()-1; i++ )
595
0
      pcPPS->setSliceTileIdx( pcPPS->getNumSlicesInPic() - 1, tileIdx );
596
597
0
    }   // if( pps->getRectSliceFlag() && !pps->getSingleSlicePerSubPicFlag() )
598
599
0
    if( !pcPPS->getRectSliceFlag() || pcPPS->getSingleSlicePerSubPicFlag() || pcPPS->getNumSlicesInPic() > 1 )
600
0
    {
601
0
      X_READ_FLAG( pps_loop_filter_across_slices_enabled_flag );
602
0
      pcPPS->setLoopFilterAcrossSlicesEnabledFlag( pps_loop_filter_across_slices_enabled_flag );
603
0
    }
604
0
    else
605
0
    {
606
0
      pcPPS->setLoopFilterAcrossSlicesEnabledFlag( false );
607
0
    }
608
0
  }
609
2
  else   // if( !pps_no_pic_partition_flag )
610
2
  {
611
    // When pps_no_pic_partition_flag is equal to 1, the value of pps_single_slice_per_subpic_flag is inferred to be equal to 1.
612
2
    pcPPS->setSingleSlicePerSubPicFlag( 1 );
613
2
  }
614
615
2
  X_READ_FLAG( pps_cabac_init_present_flag );
616
2
  pcPPS->setCabacInitPresentFlag( pps_cabac_init_present_flag );
617
618
2
  {
619
2
    X_READ_UVLC_idx( pps_num_ref_idx_default_active_minus1, "[0]", 0, 14 );
620
2
    pcPPS->setNumRefIdxL0DefaultActive( pps_num_ref_idx_default_active_minus1 + 1 );
621
2
  }
622
2
  {
623
2
    X_READ_UVLC_idx( pps_num_ref_idx_default_active_minus1, "[1]", 0, 14 );
624
2
    pcPPS->setNumRefIdxL1DefaultActive( pps_num_ref_idx_default_active_minus1 + 1 );
625
2
  }
626
627
2
  X_READ_FLAG( pps_rpl1_idx_present_flag );
628
2
  pcPPS->setRpl1IdxPresentFlag( pps_rpl1_idx_present_flag );
629
630
2
  X_READ_FLAG_CHECK( pps_weighted_pred_flag,
631
2
                     sps->getUseWP() == 0 && pps_weighted_pred_flag != 0,
632
2
                     "sps_weighted_pred_flag is equal to 0, the value of pps_weighted_pred_flag shall be equal to 0." );
633
2
  pcPPS->setUseWP( pps_weighted_pred_flag );
634
635
2
  X_READ_FLAG_CHECK( pps_weighted_bipred_flag,
636
2
                     sps->getUseWPBiPred() == 0 && pps_weighted_bipred_flag != 0,
637
2
                     "When sps_weighted_bipred_flag is equal to 0, the value of pps_weighted_bipred_flag shall be equal to 0." );
638
2
  pcPPS->setWPBiPred( pps_weighted_bipred_flag );
639
640
2
  X_READ_FLAG_CHECK( pps_ref_wraparound_enabled_flag,
641
2
                     ( sps->getUseWrapAround() == 0 || CtbSizeY / MinCbSizeY + 1 > pps_pic_width_in_luma_samples / MinCbSizeY - 1 )
642
2
                       && pps_ref_wraparound_enabled_flag != 0,
643
2
                     "When sps_ref_wraparound_enabled_flag is equal to 0 or the value of CtbSizeY / MinCbSizeY + 1 is greater than"
644
2
                     " pps_pic_width_in_luma_samples / MinCbSizeY − 1, the value of pps_ref_wraparound_enabled_flag shall be equal to 0." );
645
2
  pcPPS->setUseWrapAround( pps_ref_wraparound_enabled_flag );
646
647
2
  if( pps_ref_wraparound_enabled_flag )
648
0
  {
649
0
    X_READ_UVLC( pps_pic_width_minus_wraparound_offset, 0, ( pps_pic_width_in_luma_samples / MinCbSizeY ) - ( CtbSizeY / MinCbSizeY ) - 2 );
650
0
    pcPPS->setPicWidthMinusWrapAroundOffset( pps_pic_width_minus_wraparound_offset );
651
0
  }
652
653
2
  X_READ_SVLC( pps_init_qp_minus26, -( 26 + sps->getQpBDOffset() ), 37 );
654
2
  pcPPS->setPicInitQPMinus26( pps_init_qp_minus26 );
655
656
2
  X_READ_FLAG( pps_cu_qp_delta_enabled_flag );
657
2
  pcPPS->setUseDQP( pps_cu_qp_delta_enabled_flag );
658
659
2
  X_READ_FLAG_CHECK( pps_chroma_tool_offsets_present_flag,
660
2
                     sps->getChromaFormatIdc() == 0 && pps_chroma_tool_offsets_present_flag != 0,
661
2
                     "When sps_chroma_format_idc is equal to 0, the value of pps_chroma_tool_offsets_present_flag shall be equal to 0." );
662
2
  pcPPS->setPPSChromaToolFlag( pps_chroma_tool_offsets_present_flag );
663
664
2
  if( pps_chroma_tool_offsets_present_flag )
665
0
  {
666
0
    X_READ_SVLC( pps_cb_qp_offset, -12, 12 );
667
0
    pcPPS->setQpOffset( COMPONENT_Cb, pps_cb_qp_offset );
668
669
0
    X_READ_SVLC( pps_cr_qp_offset, -12, 12 );
670
0
    pcPPS->setQpOffset( COMPONENT_Cr, pps_cr_qp_offset );
671
672
0
    X_READ_FLAG_CHECK( pps_joint_cbcr_qp_offset_present_flag,
673
0
                       ( sps->getChromaFormatIdc() == 0 || sps->getJointCbCrEnabledFlag() == 0 ) && pps_joint_cbcr_qp_offset_present_flag != 0,
674
0
                       "When sps_chroma_format_idc is equal to 0 or sps_joint_cbcr_enabled_flag is equal to 0, the value of"
675
0
                       " pps_joint_cbcr_qp_offset_present_flag shall be equal to 0." );
676
0
    pcPPS->setJointCbCrQpOffsetPresentFlag( pps_joint_cbcr_qp_offset_present_flag );
677
678
0
    if( pps_joint_cbcr_qp_offset_present_flag )
679
0
    {
680
0
      X_READ_SVLC( pps_joint_cbcr_qp_offset_value, -12, 12 );
681
0
      pcPPS->setQpOffset( JOINT_CbCr, pps_joint_cbcr_qp_offset_value );
682
0
    }
683
0
    else
684
0
    {
685
0
      pcPPS->setQpOffset( JOINT_CbCr, 0 );
686
0
    }
687
688
0
    X_READ_FLAG( pps_slice_chroma_qp_offsets_present_flag );
689
0
    pcPPS->setSliceChromaQpFlag( pps_slice_chroma_qp_offsets_present_flag );
690
691
0
    X_READ_FLAG( pps_cu_chroma_qp_offset_list_enabled_flag );
692
0
    if( !pps_cu_chroma_qp_offset_list_enabled_flag )
693
0
    {
694
0
      pcPPS->clearChromaQpOffsetList();
695
0
    }
696
0
    else
697
0
    {
698
0
      X_READ_UVLC( pps_chroma_qp_offset_list_len_minus1, 0, MAX_QP_OFFSET_LIST_SIZE - 1 );
699
700
0
      for( int cuChromaQpOffsetIdx = 0; cuChromaQpOffsetIdx <= pps_chroma_qp_offset_list_len_minus1; cuChromaQpOffsetIdx++ )
701
0
      {
702
0
        X_READ_SVLC_idx( pps_cb_qp_offset_list, "[i]", -12, 12 );
703
0
        X_READ_SVLC_idx( pps_cr_qp_offset_list, "[i]", -12, 12 );
704
0
        int jointCbCrOffset = 0;
705
0
        if( pps_joint_cbcr_qp_offset_present_flag )
706
0
        {
707
0
          X_READ_SVLC_idx( pps_joint_cbcr_qp_offset_list, "[i]", -12, 12 );
708
0
          jointCbCrOffset = pps_joint_cbcr_qp_offset_list;
709
0
        }
710
        // table uses +1 for index (see comment inside the function)
711
0
        pcPPS->setChromaQpOffsetListEntry( cuChromaQpOffsetIdx + 1, pps_cb_qp_offset_list, pps_cr_qp_offset_list, jointCbCrOffset );
712
0
      }
713
0
      CHECK( pcPPS->getChromaQpOffsetListLen() != pps_chroma_qp_offset_list_len_minus1 + 1, "Invalid chroma QP offset list length" );
714
0
    }
715
0
  }
716
2
  else
717
2
  {
718
2
    pcPPS->setQpOffset( COMPONENT_Cb, 0 );
719
2
    pcPPS->setQpOffset( COMPONENT_Cr, 0 );
720
2
    pcPPS->setJointCbCrQpOffsetPresentFlag( 0 );
721
2
    pcPPS->setSliceChromaQpFlag( 0 );
722
2
    pcPPS->clearChromaQpOffsetList();
723
2
  }
724
725
2
  X_READ_FLAG( pps_deblocking_filter_control_present_flag );
726
2
  pcPPS->setDeblockingFilterControlPresentFlag( pps_deblocking_filter_control_present_flag );
727
728
2
  if( pps_deblocking_filter_control_present_flag )
729
0
  {
730
0
    X_READ_FLAG( pps_deblocking_filter_override_enabled_flag );
731
0
    pcPPS->setDeblockingFilterOverrideEnabledFlag( pps_deblocking_filter_override_enabled_flag );
732
733
0
    X_READ_FLAG( pps_deblocking_filter_disabled_flag );
734
0
    pcPPS->setPPSDeblockingFilterDisabledFlag( pps_deblocking_filter_disabled_flag );
735
736
0
    if( !pps_no_pic_partition_flag && pps_deblocking_filter_override_enabled_flag )
737
0
    {
738
0
      X_READ_FLAG( pps_dbf_info_in_ph_flag );
739
0
      pcPPS->setDbfInfoInPhFlag( pps_dbf_info_in_ph_flag );
740
0
    }
741
742
0
    if( !pps_deblocking_filter_disabled_flag )
743
0
    {
744
0
      X_READ_SVLC( pps_luma_beta_offset_div2, -12, 12 );
745
0
      pcPPS->setDeblockingFilterBetaOffsetDiv2( pps_luma_beta_offset_div2 );
746
747
0
      X_READ_SVLC( pps_luma_tc_offset_div2, -12, 12 );
748
0
      pcPPS->setDeblockingFilterTcOffsetDiv2( pps_luma_tc_offset_div2 );
749
750
0
      if( pps_chroma_tool_offsets_present_flag )
751
0
      {
752
0
        X_READ_SVLC( pps_cb_beta_offset_div2, -12, 12 );
753
0
        pcPPS->setDeblockingFilterCbBetaOffsetDiv2( pps_cb_beta_offset_div2 );
754
755
0
        X_READ_SVLC( pps_cb_tc_offset_div2, -12, 12 );
756
0
        pcPPS->setDeblockingFilterCbTcOffsetDiv2( pps_cb_tc_offset_div2 );
757
758
0
        X_READ_SVLC( pps_cr_beta_offset_div2, -12, 12 );
759
0
        pcPPS->setDeblockingFilterCrBetaOffsetDiv2( pps_cr_beta_offset_div2 );
760
761
0
        X_READ_SVLC( pps_cr_tc_offset_div2, -12, 12 );
762
0
        pcPPS->setDeblockingFilterCrTcOffsetDiv2( pps_cr_tc_offset_div2 );
763
0
      }
764
0
      else
765
0
      {
766
0
        pcPPS->setDeblockingFilterCbBetaOffsetDiv2( pps_luma_beta_offset_div2 );
767
0
        pcPPS->setDeblockingFilterCbTcOffsetDiv2( pps_luma_tc_offset_div2 );
768
0
        pcPPS->setDeblockingFilterCrBetaOffsetDiv2( pps_luma_beta_offset_div2 );
769
0
        pcPPS->setDeblockingFilterCrTcOffsetDiv2( pps_luma_tc_offset_div2 );
770
0
      }
771
0
    }
772
0
  }
773
774
2
  if( !pps_no_pic_partition_flag )
775
0
  {
776
0
    X_READ_FLAG( pps_rpl_info_in_ph_flag );
777
0
    pcPPS->setRplInfoInPhFlag( pps_rpl_info_in_ph_flag );
778
779
0
    X_READ_FLAG( pps_sao_info_in_ph_flag );
780
0
    pcPPS->setSaoInfoInPhFlag( pps_sao_info_in_ph_flag );
781
782
0
    X_READ_FLAG( pps_alf_info_in_ph_flag );
783
0
    pcPPS->setAlfInfoInPhFlag( pps_alf_info_in_ph_flag );
784
785
0
    if( ( pps_weighted_pred_flag || pps_weighted_bipred_flag ) && pps_rpl_info_in_ph_flag )
786
0
    {
787
0
      X_READ_FLAG( pps_wp_info_in_ph_flag );
788
0
      pcPPS->setWpInfoInPhFlag( pps_wp_info_in_ph_flag );
789
0
    }
790
791
0
    X_READ_FLAG( pps_qp_delta_info_in_ph_flag );
792
0
    pcPPS->setQpDeltaInfoInPhFlag( pps_qp_delta_info_in_ph_flag );
793
0
  }
794
795
2
  X_READ_FLAG( pps_picture_header_extension_present_flag );
796
2
  pcPPS->setPictureHeaderExtensionPresentFlag( pps_picture_header_extension_present_flag );
797
798
2
  X_READ_FLAG( pps_slice_header_extension_present_flag );
799
2
  pcPPS->setSliceHeaderExtensionPresentFlag( pps_slice_header_extension_present_flag );
800
801
2
  X_READ_FLAG( pps_extension_flag );
802
2
  if( pps_extension_flag )
803
0
  {
804
0
    while( xMoreRbspData() )
805
0
    {
806
0
      X_READ_FLAG( pps_extension_data_flag );
807
0
      (void) pps_extension_data_flag;
808
0
    }
809
0
  }
810
811
2
  xReadRbspTrailingBits();
812
813
  // ================================
814
  //  PPS READING DONE
815
  // ================================
816
817
2
  if( pcPPS->getPicWidthInLumaSamples() == sps->getMaxPicWidthInLumaSamples() && pcPPS->getPicHeightInLumaSamples() == sps->getMaxPicHeightInLumaSamples() )
818
0
  {
819
0
    CHECK( pcPPS->getConformanceWindowPresentFlag(),
820
0
                       "When pps_pic_width_in_luma_samples is equal to sps_pic_width_max_in_luma_samples and "
821
0
                       "pps_pic_height_in_luma_samples is equal to sps_pic_height_max_in_luma_samples, the value of "
822
0
                       "pps_conformance_window_flag shall be equal to 0" );
823
824
0
    pcPPS->setConformanceWindow( sps->getConformanceWindow() );
825
826
0
    if( !pcPPS->getScalingWindow().getWindowEnabledFlag() )
827
0
    {
828
0
      pcPPS->setScalingWindow( pcPPS->getConformanceWindow() );
829
0
    }
830
0
  }
831
832
2
  pcPPS->finalizePPSPartitioning( sps );
833
834
  // set wraparound offset from PPS and SPS info
835
2
  int minCbSizeY = ( 1 << sps->getLog2MinCodingBlockSize() );
836
2
  CHECK( !sps->getUseWrapAround() && pcPPS->getUseWrapAround(),
837
2
         "When sps_ref_wraparound_enabled_flag is equal to 0, the value of pps_ref_wraparound_enabled_flag shall be equal to 0." );
838
2
  CHECK( sps->getCTUSize() / minCbSizeY + 1 > pcPPS->getPicWidthInLumaSamples() / minCbSizeY - 1 && pcPPS->getUseWrapAround(),
839
2
         "When the value of CtbSizeY / MinCbSizeY + 1 is greater than pic_width_in_luma_samples / MinCbSizeY - 1, the value of "
840
2
         "pps_ref_wraparound_enabled_flag shall be equal to 0." );
841
2
  if( pcPPS->getUseWrapAround() )
842
0
  {
843
0
    CHECK( pcPPS->getPicWidthMinusWrapAroundOffset() > pcPPS->getPicWidthInLumaSamples() / minCbSizeY - sps->getCTUSize() / minCbSizeY - 2,
844
0
           "pps_pic_width_minus_wraparound_ofsfet shall be less than or equal to pps_pic_width_in_luma_samples/MinCbSizeY - CtbSizeY/MinCbSizeY-2" );
845
0
    pcPPS->setWrapAroundOffset( minCbSizeY * ( pcPPS->getPicWidthInLumaSamples() / minCbSizeY - pcPPS->getPicWidthMinusWrapAroundOffset() ) );
846
0
  }
847
2
  else
848
2
  {
849
2
    pcPPS->setWrapAroundOffset( 0 );
850
2
  }
851
852
2
  pcPPS->pcv = std::make_unique<PreCalcValues>( *sps, *pcPPS );
853
2
}
854
855
bool HLSyntaxReader::parseAPS( APS* aps )
856
170
{
857
#if ENABLE_TRACING
858
  xTraceAPSHeader();
859
#endif
860
861
170
  X_READ_CODE_NO_RANGE( aps_params_type, 3 );
862
  // if not in supported range, this APS is ignored `switch() -> default`
863
170
  aps->setAPSType( aps_params_type );
864
865
170
  X_READ_CODE_NO_RANGE( adaptation_parameter_set_id, 5 );
866
  // range check happens later in the `switch( aps_params_type )`
867
170
  aps->setAPSId( adaptation_parameter_set_id );
868
869
170
  X_READ_FLAG( aps_chroma_present_flag );
870
170
  aps->chromaPresentFlag = aps_chroma_present_flag;
871
872
170
  switch( aps_params_type )
873
170
  {
874
62
  case ALF_APS:
875
62
    CHECK_READ_RANGE( adaptation_parameter_set_id, 0, 7, "adaptation_parameter_set_id for ALF_APS" );
876
60
    parseAlfAps( aps );
877
60
    break;
878
32
  case LMCS_APS:
879
32
    CHECK_READ_RANGE( adaptation_parameter_set_id, 0, 3, "adaptation_parameter_set_id for LMCS_APS," );
880
28
    parseLmcsAps( aps );
881
28
    break;
882
70
  case SCALING_LIST_APS:
883
70
    CHECK_READ_RANGE( adaptation_parameter_set_id, 0, 7, "adaptation_parameter_set_id for SCALING_APS" );
884
68
    parseScalingListAps( aps );
885
68
    break;
886
6
  default:
887
6
    WARN( "unknown APS type (" << aps_params_type << ")" );
888
6
    return false;
889
170
  }
890
891
54
  X_READ_FLAG( aps_extension_flag );
892
54
  if( aps_extension_flag )
893
38
  {
894
3.04k
    while( xMoreRbspData() )
895
3.00k
    {
896
3.00k
      X_READ_FLAG( aps_extension_data_flag );
897
3.00k
      (void) aps_extension_data_flag;
898
3.00k
    }
899
38
  }
900
54
  xReadRbspTrailingBits();
901
902
54
  return true;
903
170
}
904
905
void HLSyntaxReader::parseAlfAps( APS* aps )
906
60
{
907
60
  AlfSliceParam& param = aps->getAlfAPSParam();
908
60
  param.reset();
909
910
60
  X_READ_FLAG( alf_luma_new_filter );   //  standard: alf_luma_filter_signal_flag
911
60
  param.newFilterFlag[CHANNEL_TYPE_LUMA] = alf_luma_new_filter;
912
913
60
  CcAlfFilterParam& ccAlfParam = aps->getCcAlfAPSParam();
914
60
  ccAlfParam.reset();
915
60
  if( aps->chromaPresentFlag )
916
48
  {
917
48
    X_READ_FLAG( alf_chroma_new_filter );   // standard: alf_chroma_filter_signal_flag
918
48
    param.newFilterFlag[CHANNEL_TYPE_CHROMA] = alf_chroma_new_filter;
919
920
48
    X_READ_FLAG( alf_cc_cb_filter_signal_flag );
921
48
    ccAlfParam.newCcAlfFilter[COMPONENT_Cb - 1] = alf_cc_cb_filter_signal_flag;
922
923
48
    X_READ_FLAG( alf_cc_cr_filter_signal_flag );
924
48
    ccAlfParam.newCcAlfFilter[COMPONENT_Cr - 1] = alf_cc_cr_filter_signal_flag;
925
48
  }
926
60
  CHECK( param.newFilterFlag[CHANNEL_TYPE_LUMA] == 0 && param.newFilterFlag[CHANNEL_TYPE_CHROMA] == 0
927
60
         && ccAlfParam.newCcAlfFilter[COMPONENT_Cb - 1] == 0 && ccAlfParam.newCcAlfFilter[COMPONENT_Cr - 1] == 0,
928
60
         "bitstream conformance error: one of alf_luma_filter_signal_flag, alf_chroma_filter_signal_flag, "
929
60
         "alf_cross_component_cb_filter_signal_flag, and alf_cross_component_cr_filter_signal_flag shall be nonzero" );
930
931
  // The variable NumAlfFilters specifying the number of different adaptive loop filters is set equal to 25.
932
58
  static constexpr int NumAlfFilters = MAX_NUM_ALF_CLASSES;
933
934
58
  if( alf_luma_new_filter )
935
40
  {
936
40
    X_READ_FLAG( alf_luma_clip );
937
40
    param.nonLinearFlagLuma = alf_luma_clip;
938
939
40
    X_READ_UVLC( alf_luma_num_filters_signalled_minus1, 0, NumAlfFilters - 1 );
940
40
    param.numLumaFilters = alf_luma_num_filters_signalled_minus1 + 1;
941
942
40
    if( alf_luma_num_filters_signalled_minus1 > 0 )
943
14
    {
944
14
      const int length = (int) ceil( log2( alf_luma_num_filters_signalled_minus1 + 1 ) );
945
276
      for( int filtIdx = 0; filtIdx < NumAlfFilters; filtIdx++ )
946
262
      {
947
262
        X_READ_CODE( alf_luma_coeff_delta_idx, length, 0, alf_luma_num_filters_signalled_minus1 );
948
262
        param.filterCoeffDeltaIdx[filtIdx] = alf_luma_coeff_delta_idx;
949
262
      }
950
14
    }
951
952
40
    alfFilterCoeffs( param, false, 0 );
953
40
  }
954
955
58
  if( param.newFilterFlag[CHANNEL_TYPE_CHROMA] )
956
30
  {
957
30
    X_READ_FLAG( alf_nonlinear_enable_flag_chroma );
958
30
    param.nonLinearFlagChroma = alf_nonlinear_enable_flag_chroma;
959
960
30
    X_READ_UVLC( alf_chroma_num_alts_minus1, 0, MAX_NUM_ALF_ALTERNATIVES_CHROMA - 1 );
961
30
    param.numAlternativesChroma = alf_chroma_num_alts_minus1 + 1;
962
963
146
    for( int altIdx = 0; altIdx <= alf_chroma_num_alts_minus1; ++altIdx )
964
116
    {
965
116
      alfFilterCoeffs( param, true, altIdx );
966
116
    }
967
30
  }
968
969
108
  for( int ccIdx = 0; ccIdx < 2; ccIdx++ )
970
56
  {
971
56
    if( ccAlfParam.newCcAlfFilter[ccIdx] )
972
34
    {
973
34
      uint32_t code;
974
34
      READ_UVLC( code, ccIdx == 0 ? "alf_cc_cb_filters_signalled_minus1" : "alf_cc_cr_filters_signalled_minus1" );
975
34
      CHECK_READ_RANGE( code, 0, 3, ( ccIdx == 0 ? "alf_cc_cb_filters_signalled_minus1" : "alf_cc_cr_filters_signalled_minus1" ) )
976
977
28
      ccAlfParam.ccAlfFilterCount[ccIdx] = code + 1;
978
979
76
      for( int filterIdx = 0; filterIdx < ccAlfParam.ccAlfFilterCount[ccIdx]; filterIdx++ )
980
48
      {
981
48
        ccAlfParam.ccAlfFilterIdxEnabled[ccIdx][filterIdx] = true;
982
983
48
        const int numCoeff = g_alfNumCoeff[CC_ALF];
984
985
48
        short* coeff = ccAlfParam.ccAlfCoeff[ccIdx][filterIdx];
986
        // Filter coefficients
987
368
        for( int i = 0; i < numCoeff - 1; i++ )
988
320
        {
989
320
          READ_CODE( 3, code, ccIdx == 0 ? "alf_cc_cb_mapped_coeff_abs" : "alf_cc_cr_mapped_coeff_abs" );
990
320
          if( code )
991
178
          {
992
178
            coeff[i] = 1 << ( code - 1 );
993
994
178
            READ_FLAG( code, ccIdx == 0 ? "alf_cc_cb_coeff_sign" : "alf_cc_cr_coeff_sign" );
995
178
            coeff[i] *= 1 - 2 * code;
996
178
          }
997
142
          else
998
142
          {
999
142
            coeff[i] = 0;
1000
142
          }
1001
320
        }
1002
1003
48
        DTRACE( g_trace_ctx, D_SYNTAX, "%s coeff filterIdx %d: ", ccIdx == 0 ? "Cb" : "Cr", filterIdx );
1004
400
        for( int i = 0; i < numCoeff; i++ )
1005
352
        {
1006
352
          DTRACE( g_trace_ctx, D_SYNTAX, "%d ", coeff[i] );
1007
352
        }
1008
48
        DTRACE( g_trace_ctx, D_SYNTAX, "\n" );
1009
48
      }
1010
28
    }
1011
56
  }
1012
58
}
1013
1014
void HLSyntaxReader::parseLmcsAps( APS* aps )
1015
28
{
1016
28
  SliceReshapeInfo& info = aps->getReshaperAPSInfo();
1017
28
  info.reset();
1018
1019
28
  X_READ_UVLC( lmcs_min_bin_idx, 0, 15 );
1020
28
  info.reshaperModelMinBinIdx = lmcs_min_bin_idx;
1021
1022
28
  X_READ_UVLC( lmcs_delta_max_bin_idx, 0, 15 );
1023
28
  info.reshaperModelMaxBinIdx = PIC_CODE_CW_BINS - 1 - lmcs_delta_max_bin_idx;
1024
28
  CHECK( info.reshaperModelMaxBinIdx < lmcs_min_bin_idx, "The value of LmcsMaxBinIdx shall be greater than or equal to lmcs_min_bin_idx." );
1025
1026
26
  X_READ_UVLC( lmcs_delta_cw_prec_minus1, 0, 14 );
1027
26
  info.maxNbitsNeededDeltaCW = lmcs_delta_cw_prec_minus1 + 1;
1028
1029
26
  CHECK( info.maxNbitsNeededDeltaCW == 0, "wrong" );
1030
1031
232
  for( uint32_t i = info.reshaperModelMinBinIdx; i <= info.reshaperModelMaxBinIdx; i++ )
1032
206
  {
1033
206
    X_READ_CODE_NO_RANGE_idx( lmcs_delta_abs_cw, "[ i ]", info.maxNbitsNeededDeltaCW );
1034
206
    info.reshaperModelBinCWDelta[i] = lmcs_delta_abs_cw;
1035
206
    if( lmcs_delta_abs_cw )
1036
154
    {
1037
154
      X_READ_FLAG_idx( lmcs_delta_sign_cw_flag, "[ i ]" );
1038
154
      info.reshaperModelBinCWDelta[i] *= 1 - 2 * lmcs_delta_sign_cw_flag;
1039
154
    }
1040
    // lmcsCW[i] range is checked in Reshape::constructReshaper()
1041
206
  }
1042
1043
26
  if( aps->chromaPresentFlag )
1044
16
  {
1045
16
    X_READ_CODE_NO_RANGE( lmcs_delta_abs_crs, 3 );
1046
16
    info.chrResScalingOffset = lmcs_delta_abs_crs;
1047
16
    if( lmcs_delta_abs_crs > 0 )
1048
8
    {
1049
8
      X_READ_FLAG( lmcs_delta_sign_crs_flag );
1050
8
      info.chrResScalingOffset *= ( 1 - 2 * lmcs_delta_sign_crs_flag );
1051
8
    }
1052
    // lmcsDeltaCrs range is checked in Reshape::constructReshaper()
1053
16
  }
1054
26
}
1055
1056
void HLSyntaxReader::parseScalingListAps( APS* aps )
1057
68
{
1058
68
  ScalingList& info = aps->getScalingList();
1059
68
  parseScalingList( &info, aps->chromaPresentFlag );
1060
68
}
1061
1062
static const int SARFixedRatios[][2] =
1063
{
1064
    { 1,  1 },
1065
    { 12, 11 },
1066
    { 10, 11 },
1067
    { 16, 11 },
1068
    { 40, 33 },
1069
    { 24, 11 },
1070
    { 20, 11 },
1071
    { 32, 11 },
1072
    { 80, 33 },
1073
    { 18, 11 },
1074
    { 15, 11 },
1075
    { 64, 33 },
1076
    { 160, 99 },
1077
    { 4, 3 },
1078
    { 3, 2 },
1079
    { 2, 1 },
1080
};
1081
1082
void HLSyntaxReader::parseVUI( VUI* pcVUI, unsigned vuiPayloadSize )
1083
54
{
1084
#if ENABLE_TRACING
1085
  DTRACE( g_trace_ctx, D_HEADER, "----------- vui_parameters -----------\n");
1086
#endif
1087
54
  InputBitstream *bs = getBitstream();
1088
54
  auto substream = bs->extractSubstream( vuiPayloadSize * 8 );
1089
54
  setBitstream( substream.get() );
1090
1091
54
  X_READ_FLAG( vui_general_progressive_source_flag );
1092
54
  pcVUI->setProgressiveSourceFlag( vui_general_progressive_source_flag );
1093
1094
54
  X_READ_FLAG( vui_general_interlaced_source_flag );
1095
54
  pcVUI->setInterlacedSourceFlag( vui_general_interlaced_source_flag );
1096
1097
54
  X_READ_FLAG( vui_non_packed_constraint_flag );
1098
54
  pcVUI->setNonPackedFlag( vui_non_packed_constraint_flag );
1099
1100
54
  X_READ_FLAG( vui_non_projected_constraint_flag );
1101
54
  pcVUI->setNonProjectedFlag( vui_non_projected_constraint_flag );
1102
1103
54
  X_READ_FLAG( vui_aspect_ratio_info_present_flag );
1104
54
  pcVUI->setAspectRatioInfoPresentFlag( vui_aspect_ratio_info_present_flag );
1105
1106
54
  if( vui_aspect_ratio_info_present_flag )
1107
16
  {
1108
16
    X_READ_FLAG( vui_aspect_ratio_constant_flag );
1109
16
    pcVUI->setAspectRatioConstantFlag( vui_aspect_ratio_constant_flag );
1110
1111
16
    X_READ_CODE_NO_RANGE( vui_aspect_ratio_idc, 8 );
1112
16
    pcVUI->setAspectRatioIdc( vui_aspect_ratio_idc );
1113
1114
16
    if( pcVUI->getAspectRatioIdc() == 255 )
1115
2
    {
1116
2
      X_READ_CODE_NO_RANGE( vui_sar_width, 16 );
1117
2
      pcVUI->setSarWidth( vui_sar_width );
1118
1119
2
      X_READ_CODE_NO_RANGE( vui_sar_height, 16 );
1120
2
      pcVUI->setSarHeight( vui_sar_height );
1121
2
    }
1122
14
    else if (pcVUI->getAspectRatioIdc() > 0 && (size_t)pcVUI->getAspectRatioIdc() <= sizeof(SARFixedRatios) / sizeof(SARFixedRatios[0]))
1123
2
    {
1124
2
      pcVUI->setSarWidth( SARFixedRatios[pcVUI->getAspectRatioIdc() - 1][0] );
1125
2
      pcVUI->setSarHeight( SARFixedRatios[pcVUI->getAspectRatioIdc() - 1][1] );
1126
2
    }
1127
16
  }
1128
1129
54
  X_READ_FLAG( vui_overscan_info_present_flag );
1130
54
  pcVUI->setOverscanInfoPresentFlag( vui_overscan_info_present_flag );
1131
1132
54
  if( vui_overscan_info_present_flag )
1133
16
  {
1134
16
    X_READ_FLAG( vui_overscan_appropriate_flag );
1135
16
    pcVUI->setOverscanAppropriateFlag( vui_overscan_appropriate_flag );
1136
16
  }
1137
1138
54
  X_READ_FLAG( vui_colour_description_present_flag );
1139
54
  pcVUI->setColourDescriptionPresentFlag( vui_colour_description_present_flag );
1140
1141
54
  if( vui_colour_description_present_flag )
1142
8
  {
1143
8
    X_READ_CODE_NO_RANGE( vui_colour_primaries, 8 );
1144
8
    pcVUI->setColourPrimaries( vui_colour_primaries );
1145
1146
8
    X_READ_CODE_NO_RANGE( vui_transfer_characteristics, 8 );
1147
8
    pcVUI->setTransferCharacteristics( vui_transfer_characteristics );
1148
1149
8
    X_READ_CODE_NO_RANGE( vui_matrix_coeffs, 8 );
1150
8
    pcVUI->setMatrixCoefficients( vui_matrix_coeffs );
1151
1152
8
    X_READ_FLAG( vui_video_full_range_flag );
1153
8
    pcVUI->setVideoFullRangeFlag( vui_video_full_range_flag );
1154
8
  }
1155
1156
54
  X_READ_FLAG( vui_chroma_loc_info_present_flag );
1157
54
  pcVUI->setChromaLocInfoPresentFlag( vui_chroma_loc_info_present_flag );
1158
1159
54
  if( vui_chroma_loc_info_present_flag )
1160
26
  {
1161
26
    if( vui_general_progressive_source_flag && !vui_general_interlaced_source_flag )
1162
8
    {
1163
8
      X_READ_UVLC( vui_chroma_sample_loc_type_frame, 0, 6 );
1164
8
      pcVUI->setChromaSampleLocType( vui_chroma_sample_loc_type_frame );
1165
8
    }
1166
18
    else
1167
18
    {
1168
18
      X_READ_UVLC( vui_chroma_sample_loc_type_top_field, 0, 6 );
1169
18
      pcVUI->setChromaSampleLocTypeTopField( vui_chroma_sample_loc_type_top_field );
1170
1171
18
      X_READ_UVLC( vui_chroma_sample_loc_type_bottom_field, 0, 6 );
1172
18
      pcVUI->setChromaSampleLocTypeBottomField( vui_chroma_sample_loc_type_bottom_field );
1173
18
    }
1174
26
  }
1175
1176
54
  int payloadBitsRem = getBitstream()->getNumBitsLeft();
1177
54
  if( payloadBitsRem )      //Corresponds to more_data_in_payload()
1178
18
  {
1179
154
    while( payloadBitsRem > 9 )    //payload_extension_present()
1180
136
    {
1181
136
      X_READ_FLAG( vui_reserved_payload_extension_data );
1182
136
      (void) vui_reserved_payload_extension_data;
1183
136
      payloadBitsRem--;
1184
136
    }
1185
18
    int finalBits = getBitstream()->peekBits( payloadBitsRem );
1186
18
    int numFinalZeroBits = 0;
1187
18
    int mask = 0xff;
1188
112
    while( finalBits & (mask >> numFinalZeroBits) )
1189
94
    {
1190
94
      numFinalZeroBits++;
1191
94
    }
1192
100
    while( payloadBitsRem > 9-numFinalZeroBits )     //payload_extension_present()
1193
82
    {
1194
82
      X_READ_FLAG( vui_reserved_payload_extension_data );
1195
82
      (void) vui_reserved_payload_extension_data;
1196
82
      payloadBitsRem--;
1197
82
    }
1198
18
    X_READ_FLAG_CHECK( vui_payload_bit_equal_to_one, vui_payload_bit_equal_to_one != 1, "vui_payload_bit_equal_to_one not equal to 1" );
1199
18
    (void)vui_payload_bit_equal_to_one;
1200
18
    payloadBitsRem--;
1201
52
    while( payloadBitsRem )
1202
34
    {
1203
34
      X_READ_FLAG_CHECK( vui_payload_bit_equal_to_zero, vui_payload_bit_equal_to_zero != 0, "vui_payload_bit_equal_to_zero not equal to 0" );
1204
34
      (void)vui_payload_bit_equal_to_zero;
1205
34
      payloadBitsRem--;
1206
34
    }
1207
18
  }
1208
54
  setBitstream( bs );
1209
54
}
1210
1211
void HLSyntaxReader::parseGeneralHrdParameters( GeneralHrdParams *hrd )
1212
0
{
1213
0
  X_READ_CODE_NO_RANGE( num_units_in_tick, 32 );
1214
0
  CHECK( num_units_in_tick <= 0, "num_units_in_tick shall be greater than 0" );
1215
0
  hrd->setNumUnitsInTick( num_units_in_tick );
1216
1217
0
  X_READ_CODE_NO_RANGE( time_scale, 32 );
1218
0
  CHECK( time_scale <= 0, "The value of time_scale shall be greater than 0." );
1219
0
  hrd->setTimeScale( time_scale );
1220
1221
0
  X_READ_FLAG( general_nal_hrd_params_present_flag );
1222
0
  hrd->setGeneralNalHrdParamsPresentFlag( general_nal_hrd_params_present_flag );
1223
1224
0
  X_READ_FLAG( general_vcl_hrd_params_present_flag );
1225
0
  hrd->setGeneralVclHrdParamsPresentFlag( general_vcl_hrd_params_present_flag );
1226
1227
0
  if( general_nal_hrd_params_present_flag || general_vcl_hrd_params_present_flag )
1228
0
  {
1229
0
    X_READ_FLAG( general_same_pic_timing_in_all_ols_flag );
1230
0
    hrd->setGeneralSamePicTimingInAllOlsFlag( general_same_pic_timing_in_all_ols_flag );
1231
1232
0
    X_READ_FLAG( general_du_hrd_params_present_flag );
1233
0
    hrd->setGeneralDuHrdParamsPresentFlag( general_du_hrd_params_present_flag );
1234
1235
0
    if( general_du_hrd_params_present_flag )
1236
0
    {
1237
0
      X_READ_CODE_NO_RANGE( tick_divisor_minus2, 8 );
1238
0
      hrd->setTickDivisorMinus2( tick_divisor_minus2 );
1239
0
    }
1240
1241
0
    X_READ_CODE_NO_RANGE( bit_rate_scale, 4 );
1242
0
    hrd->setBitRateScale( bit_rate_scale );
1243
1244
0
    X_READ_CODE_NO_RANGE( cpb_size_scale, 4 );
1245
0
    hrd->setCpbSizeScale( cpb_size_scale );
1246
1247
0
    if( general_du_hrd_params_present_flag )
1248
0
    {
1249
0
      X_READ_CODE_NO_RANGE( cpb_size_du_scale, 4 );
1250
0
      hrd->setCpbSizeDuScale( cpb_size_du_scale );
1251
0
    }
1252
1253
0
    X_READ_UVLC( hrd_cpb_cnt_minus1, 0, MAX_CPB_CNT - 1 );
1254
0
    hrd->setHrdCpbCntMinus1( hrd_cpb_cnt_minus1 );
1255
0
  }
1256
0
}
1257
1258
void HLSyntaxReader::parseOlsHrdParameters( GeneralHrdParams * generalHrd, std::vector<OlsHrdParams>& olsHrd, uint32_t firstSubLayer, uint32_t maxNumSubLayersMinus1 )
1259
0
{
1260
0
  olsHrd.resize( maxNumSubLayersMinus1 + 1 );
1261
1262
0
  for( unsigned i = firstSubLayer; i <= maxNumSubLayersMinus1; i++ )
1263
0
  {
1264
0
    OlsHrdParams& hrd = olsHrd[i];
1265
1266
0
    X_READ_FLAG( fixed_pic_rate_general_flag );
1267
0
    hrd.setFixedPicRateGeneralFlag( fixed_pic_rate_general_flag );
1268
1269
    // When fixed_pic_rate_general_flag[ i ] is equal to 1, the value of fixed_pic_rate_within_cvs_flag[ i ] is inferred to be equal to 1.
1270
0
    hrd.setFixedPicRateWithinCvsFlag( fixed_pic_rate_general_flag );
1271
0
    if( !fixed_pic_rate_general_flag )
1272
0
    {
1273
0
      X_READ_FLAG( fixed_pic_rate_within_cvs_flag );
1274
0
      hrd.setFixedPicRateWithinCvsFlag( fixed_pic_rate_within_cvs_flag );
1275
0
    }
1276
1277
    // TODO: It is a requirement of bitstream conformance that when general_nal_hrd_params_present_flag and
1278
    //       general_vcl_hrd_params_present_flag are both equal to 0, there shall be at least one value of
1279
    //       fixed_pic_rate_within_cvs_flag[ i ] equal to 1 for i in the range of 0 to MaxSubLayersVal − 1, inclusive.
1280
1281
0
    hrd.setLowDelayHrdFlag( false );   // Inferred to be 0 when not present
1282
1283
0
    if( hrd.getFixedPicRateWithinCvsFlag() )
1284
0
    {
1285
0
      X_READ_UVLC( elemental_duration_in_tc_minus1, 0, 2047 );
1286
0
      hrd.setElementDurationInTcMinus1( elemental_duration_in_tc_minus1 );
1287
0
    }
1288
0
    else if( ( generalHrd->getGeneralNalHrdParamsPresentFlag() || generalHrd->getGeneralVclHrdParamsPresentFlag() )
1289
0
             && generalHrd->getHrdCpbCntMinus1() == 0 )
1290
0
    {
1291
0
      X_READ_FLAG( low_delay_hrd_flag );
1292
0
      hrd.setLowDelayHrdFlag( low_delay_hrd_flag );
1293
0
    }
1294
1295
0
    using NalOrVcl = enum { NAL = 0, VCL = 1 };
1296
0
    for( NalOrVcl nalOrVcl: { NAL, VCL } )
1297
0
    {
1298
0
      if( ( nalOrVcl == NAL && generalHrd->getGeneralNalHrdParamsPresentFlag() ) ||   //
1299
0
          ( nalOrVcl == VCL && generalHrd->getGeneralVclHrdParamsPresentFlag() ) )
1300
0
      {
1301
0
        for( int j = 0; j <= generalHrd->getHrdCpbCntMinus1(); j++ )
1302
0
        {
1303
0
          CHECK( generalHrd->getHrdCpbCntMinus1() >= MAX_CPB_CNT, "hrd_cpb_cnt_minus1 out of bounds" );
1304
1305
0
          X_READ_UVLC_NO_RANGE( bit_rate_value_minus1 );
1306
0
          CHECK( j > 0 && bit_rate_value_minus1 <= hrd.getBitRateValueMinus1( j - 1, nalOrVcl ),
1307
0
                 "For any j greater than 0 and any particular value of i, bit_rate_value_minus1[ i ][ j ]"
1308
0
                 " shall be greater than bit_rate_value_minus1[ i ][ j − 1 ]." );
1309
0
          hrd.setBitRateValueMinus1( j, nalOrVcl, bit_rate_value_minus1 );
1310
1311
0
          X_READ_UVLC( cpb_size_value_minus1, 0, ( 1ull << 32 ) - 2 );
1312
0
          CHECK( j > 0 && cpb_size_value_minus1 > hrd.getCpbSizeValueMinus1( j - 1, nalOrVcl ),
1313
0
                 "For any j greater than 0 and any particular value of i, cpb_size_value_minus1[ i ][ j ]"
1314
0
                 " shall be less than or equal to cpb_size_value_minus1[ i ][ j − 1 ]." );
1315
0
          hrd.setCpbSizeValueMinus1( j, nalOrVcl, cpb_size_value_minus1 );
1316
1317
0
          if( generalHrd->getGeneralDuHrdParamsPresentFlag() )
1318
0
          {
1319
0
            X_READ_UVLC( cpb_size_du_value_minus1, 0, ( 1ull << 32 ) - 2 );
1320
0
            CHECK( j > 0 && cpb_size_du_value_minus1 > hrd.getDuCpbSizeValueMinus1( j - 1, nalOrVcl ),
1321
0
                   "For any j greater than 0 and any particular value of i, cpb_size_du_value_minus1[ i ][ j ]"
1322
0
                   " shall be less than or equal to cpb_size_du_value_minus1[ i ][ j − 1 ]." )
1323
0
            hrd.setDuCpbSizeValueMinus1( j, nalOrVcl, cpb_size_du_value_minus1 );
1324
1325
0
            X_READ_UVLC( bit_rate_du_value_minus1, 0, ( 1ull << 32 ) - 2 );
1326
0
            CHECK( j > 0 && bit_rate_du_value_minus1 <= hrd.getDuBitRateValueMinus1( j - 1, nalOrVcl ),
1327
0
                   "For any j greater than 0 and any particular value of i, bit_rate_du_value_minus1[ i ][ j ]"
1328
0
                   " shall be greater than bit_rate_du_value_minus1[ i ][ j − 1 ]" )
1329
0
            hrd.setDuBitRateValueMinus1( j, nalOrVcl, bit_rate_du_value_minus1 );
1330
0
          }
1331
0
          X_READ_FLAG( cbr_flag );
1332
0
          hrd.setCbrFlag( j, nalOrVcl, cbr_flag );
1333
0
        }
1334
0
      }
1335
0
    }
1336
0
  }
1337
1338
0
  for( int i = 0; i < firstSubLayer; i++ )
1339
0
  {
1340
0
    OlsHrdParams* hrdHighestTLayer = &( olsHrd[maxNumSubLayersMinus1] );
1341
0
    OlsHrdParams* hrdTemp = &( olsHrd[i] );
1342
0
    bool tempFlag = hrdHighestTLayer->getFixedPicRateGeneralFlag();
1343
0
    hrdTemp->setFixedPicRateGeneralFlag( tempFlag );
1344
0
    tempFlag = hrdHighestTLayer->getFixedPicRateWithinCvsFlag();
1345
0
    hrdTemp->setFixedPicRateWithinCvsFlag( tempFlag );
1346
0
    uint32_t tempElementDurationInTcMinus1 = hrdHighestTLayer->getElementDurationInTcMinus1();
1347
0
    hrdTemp->setElementDurationInTcMinus1( tempElementDurationInTcMinus1 );
1348
0
    for( int nalOrVcl = 0; nalOrVcl < 2; nalOrVcl++ )
1349
0
    {
1350
0
      if( ( nalOrVcl == 0 && generalHrd->getGeneralNalHrdParamsPresentFlag() ) || ( nalOrVcl == 1 && generalHrd->getGeneralVclHrdParamsPresentFlag() ) )
1351
0
      {
1352
0
        for( int j = 0; j <= (generalHrd->getHrdCpbCntMinus1()); j++ )
1353
0
        {
1354
0
          uint32_t bitRate = hrdHighestTLayer->getBitRateValueMinus1( j, nalOrVcl );
1355
0
          hrdTemp->setBitRateValueMinus1( j, nalOrVcl, bitRate );
1356
0
          uint32_t cpbSize = hrdHighestTLayer->getCpbSizeValueMinus1( j, nalOrVcl );
1357
0
          hrdTemp->setCpbSizeValueMinus1( j, nalOrVcl, cpbSize );
1358
0
          if( generalHrd->getGeneralDuHrdParamsPresentFlag() )
1359
0
          {
1360
0
            uint32_t bitRateDu = hrdHighestTLayer->getDuBitRateValueMinus1( j, nalOrVcl );
1361
0
            hrdTemp->setDuBitRateValueMinus1(j, nalOrVcl, bitRateDu);
1362
0
            uint32_t cpbSizeDu = hrdHighestTLayer->getDuCpbSizeValueMinus1( j, nalOrVcl );
1363
0
            hrdTemp->setDuCpbSizeValueMinus1( j, nalOrVcl, cpbSizeDu );
1364
0
          }
1365
0
          bool flag = hrdHighestTLayer->getCbrFlag( j, nalOrVcl );
1366
0
          hrdTemp->setCbrFlag( j, nalOrVcl, flag );
1367
0
        }
1368
0
      }
1369
0
    }
1370
0
  }
1371
0
}
1372
1373
void HLSyntaxReader::dpb_parameters( int maxSubLayersMinus1, bool subLayerInfoFlag, SPS *pcSPS )
1374
10
{
1375
10
  CHECK( maxSubLayersMinus1 >= MAX_TLAYER, "maxSubLayersMinus1 out of bounds" );
1376
34
  for( int i = ( subLayerInfoFlag ? 0 : maxSubLayersMinus1 ); i <= maxSubLayersMinus1; i++ )
1377
28
  {
1378
28
    X_READ_UVLC_NO_RANGE_idx( dpb_max_dec_pic_buffering_minus1, "[i]" );
1379
28
    CHECK( i > 0 && dpb_max_dec_pic_buffering_minus1 < pcSPS->getMaxDecPicBuffering( i - 1 ) - 1,
1380
28
           "When i is greater than 0, dpb_max_dec_pic_buffering_minus1[ i ] shall be greater than or equal to dpb_max_dec_pic_buffering_minus1[ i − 1 ]." );
1381
24
    pcSPS->setMaxDecPicBuffering( dpb_max_dec_pic_buffering_minus1 + 1, i );
1382
1383
24
    X_READ_UVLC_idx( dpb_max_num_reorder_pics, "[i]", 0, dpb_max_dec_pic_buffering_minus1 );
1384
24
    CHECK( i > 0 && dpb_max_dec_pic_buffering_minus1 < pcSPS->getNumReorderPics( i - 1 ),
1385
24
           "When i is greater than 0, dpb_max_num_reorder_pics[ i ] shall be greater than or equal to dpb_max_num_reorder_pics[ i − 1 ]." );
1386
24
    pcSPS->setNumReorderPics( dpb_max_num_reorder_pics, i );
1387
1388
24
    X_READ_UVLC_idx( dpb_max_latency_increase_plus1, "[i]", 0, ( uint64_t( 1 ) << 32 ) - 2 );
1389
24
    pcSPS->setMaxLatencyIncreasePlus1( dpb_max_latency_increase_plus1, i );
1390
24
  }
1391
10
}
1392
1393
void HLSyntaxReader::parseExtraPHBitsStruct( SPS *sps, int numBytes )
1394
138
{
1395
138
  std::vector<bool> presentFlags;
1396
138
  presentFlags.resize ( 8 * numBytes );
1397
1398
1.91k
  for( int i = 0; i < 8 * numBytes; i++ )
1399
1.77k
  {
1400
1.77k
    X_READ_FLAG_idx( sps_extra_ph_bit_present_flag, "[i]" );
1401
1.77k
    presentFlags[i] = sps_extra_ph_bit_present_flag;
1402
1.77k
  }
1403
1404
138
  sps->setExtraPHBitPresentFlags( std::move( presentFlags ) );
1405
138
}
1406
1407
void HLSyntaxReader::parseExtraSHBitsStruct( SPS *sps, int numBytes )
1408
224
{
1409
224
  std::vector<bool> presentFlags;
1410
224
  presentFlags.resize ( 8 * numBytes );
1411
1412
3.50k
  for( int i = 0; i < 8 * numBytes; i++ )
1413
3.28k
  {
1414
3.28k
    X_READ_FLAG_idx( sps_extra_sh_bit_present_flag, "[i]" );
1415
3.28k
    presentFlags[i] = sps_extra_sh_bit_present_flag;
1416
3.28k
  }
1417
1418
224
  sps->setExtraSHBitPresentFlags( std::move( presentFlags ) );
1419
224
}
1420
1421
void HLSyntaxReader::parseSPS( SPS* sps, const ParameterSetManager* parameterSetManager )
1422
362
{
1423
#if ENABLE_TRACING
1424
  xTraceSPSHeader ();
1425
#endif
1426
1427
362
  X_READ_CODE_NO_RANGE( sps_seq_parameter_set_id, 4 );
1428
362
  sps->setSPSId( sps_seq_parameter_set_id );
1429
1430
362
  X_READ_CODE_NO_RANGE( sps_video_parameter_set_id, 4 );
1431
362
  (void) sps_video_parameter_set_id;   // sps->setVPSId( sps_video_parameter_set_id ); // TODO: change to support VPS
1432
362
  const VPS* vps = nullptr;
1433
#if 0
1434
  if( sps_video_parameter_set_id > 0 && parameterSetManager->getVPS( sps_video_parameter_set_id ) )
1435
  {
1436
    vps = parameterSetManager->getVPS( sps_video_parameter_set_id );
1437
  }
1438
#endif
1439
1440
362
  X_READ_CODE( sps_max_sublayers_minus1, 3, 0, 6 );
1441
362
  CHECK( vps && sps_video_parameter_set_id > vps->getMaxSubLayers(),
1442
362
         "If sps_video_parameter_set_id is greater than 0, the value of sps_max_sublayers_minus1 shall be in the range of 0 to vps_max_sublayers_minus1, "
1443
362
         "inclusive." )
1444
362
  sps->setMaxTLayers( sps_max_sublayers_minus1 + 1 );
1445
1446
362
  X_READ_CODE_NO_RANGE( sps_chroma_format_idc, 2 );
1447
  // it is a requirement of bitstream conformance that the value of sps_chroma_format_idc shall
1448
  // be less than or equal to the value of vps_ols_dpb_chroma_format[ i ].
1449
362
  sps->setChromaFormatIdc( ChromaFormat( sps_chroma_format_idc ) );
1450
1451
362
  X_READ_CODE( sps_log2_ctu_size_minus5, 2, 0, 2 );
1452
362
  sps->setCTUSize( 1 << ( sps_log2_ctu_size_minus5 + 5 ) );
1453
1454
362
  const int CtbLog2SizeY = sps_log2_ctu_size_minus5 + 5;
1455
362
  const int CtbSizeY     = 1 << CtbLog2SizeY;
1456
362
  sps->setMaxCUWidth( sps->getCTUSize() );
1457
362
  sps->setMaxCUHeight( sps->getCTUSize() );
1458
1459
362
  X_READ_FLAG( sps_ptl_dpb_hrd_params_present_flag );
1460
362
  CHECK( sps_video_parameter_set_id == 0 && !sps_ptl_dpb_hrd_params_present_flag,
1461
362
                     "When sps_video_parameter_set_id is equal to 0, the value of sps_ptl_dpb_hrd_params_present_flag shall be equal to 1" );
1462
358
  sps->setPtlDpbHrdParamsPresentFlag( sps_ptl_dpb_hrd_params_present_flag );
1463
1464
358
  if( sps_ptl_dpb_hrd_params_present_flag )
1465
44
  {
1466
44
    parseProfileTierLevel( sps->getProfileTierLevel(), true, sps->getMaxTLayers() - 1 );
1467
44
  }
1468
1469
358
  const ProfileTierLevel* ptl = sps->getProfileTierLevel();
1470
358
  const ConstraintInfo*   gci = ptl->getConstraintInfo();
1471
1472
358
  X_READ_FLAG( sps_gdr_enabled_flag );
1473
358
  CHECK_CONSTRAINT( gci->getNoGdrConstraintFlag() && sps_gdr_enabled_flag,
1474
356
                     "When gci_no_gdr_constraint_flag equal to 1 , the value of sps_gdr_enabled_flag shall be equal to 0" );
1475
356
  sps->setGDREnabledFlag( sps_gdr_enabled_flag );
1476
1477
356
  X_READ_FLAG( sps_ref_pic_resampling_enabled_flag );
1478
356
  CHECK_CONSTRAINT( gci->getNoRprConstraintFlag() && sps_ref_pic_resampling_enabled_flag,
1479
354
                    "When gci_no_ref_pic_resampling_constraint_flag is equal to 1, sps_ref_pic_resampling_enabled_flag shall be equal to 0" );
1480
354
  sps->setRprEnabledFlag( sps_ref_pic_resampling_enabled_flag );
1481
1482
354
  if( sps_ref_pic_resampling_enabled_flag )
1483
12
  {
1484
12
    X_READ_FLAG( sps_res_change_in_clvs_allowed_flag );
1485
12
    CHECK_CONSTRAINT( gci->getNoResChangeInClvsConstraintFlag() && sps_res_change_in_clvs_allowed_flag,
1486
10
                      "When no_res_change_in_clvs_constraint_flag is equal to 1, res_change_in_clvs_allowed_flag shall be equal to 0" );
1487
10
    sps->setResChangeInClvsEnabledFlag( sps_res_change_in_clvs_allowed_flag );
1488
10
  }
1489
1490
352
  X_READ_UVLC_NO_RANGE( sps_pic_width_max_in_luma_samples );
1491
352
  sps->setMaxPicWidthInLumaSamples( sps_pic_width_max_in_luma_samples );
1492
1493
352
  X_READ_UVLC_NO_RANGE( sps_pic_height_max_in_luma_samples );
1494
352
  sps->setMaxPicHeightInLumaSamples( sps_pic_height_max_in_luma_samples );
1495
1496
352
  const int SubWidthC  = 1 << getChannelTypeScaleX( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() );
1497
352
  const int SubHeightC = 1 << getChannelTypeScaleY( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() );
1498
1499
352
  X_READ_FLAG( sps_conformance_window_flag );
1500
352
  sps->setConformanceWindowPresentFlag( sps_conformance_window_flag );
1501
1502
352
  if( sps_conformance_window_flag )
1503
268
  {
1504
268
    X_READ_UVLC_NO_RANGE( sps_conf_win_left_offset );
1505
268
    X_READ_UVLC_NO_RANGE( sps_conf_win_right_offset );
1506
268
    X_READ_UVLC_NO_RANGE( sps_conf_win_top_offset );
1507
268
    X_READ_UVLC_NO_RANGE( sps_conf_win_bottom_offset );
1508
1509
268
    CHECK( SubWidthC * ( sps_conf_win_left_offset + sps_conf_win_right_offset ) > sps_pic_width_max_in_luma_samples,
1510
268
           "The value of SubWidthC * ( sps_conf_win_left_offset + sps_conf_win_right_offset ) shall be less than sps_pic_width_max_in_luma_samples." );
1511
266
    CHECK( SubHeightC * ( sps_conf_win_top_offset + sps_conf_win_bottom_offset ) > sps_pic_height_max_in_luma_samples,
1512
266
           "The value of SubHeightC * ( sps_conf_win_top_offset + sps_conf_win_bottom_offset ) shall be less than sps_pic_height_max_in_luma_samples." );
1513
1514
262
    Window& conf = sps->getConformanceWindow();
1515
262
    conf.setWindowLeftOffset( sps_conf_win_left_offset );
1516
262
    conf.setWindowRightOffset( sps_conf_win_right_offset );
1517
262
    conf.setWindowTopOffset( sps_conf_win_top_offset );
1518
262
    conf.setWindowBottomOffset( sps_conf_win_bottom_offset );
1519
262
  }
1520
346
  X_READ_FLAG( sps_subpic_info_present_flag );
1521
346
  CHECK( sps->getResChangeInClvsEnabledFlag() && sps_subpic_info_present_flag,
1522
346
         "When sps_res_change_in_clvs_allowed_flag is equal to 1, the value of sps_subpic_info_present_flag shall be equal to 0." )
1523
344
  CHECK_CONSTRAINT( gci->getNoSubpicInfoConstraintFlag() && sps_subpic_info_present_flag,
1524
342
                    "When gci_no_subpic_info_constraint_flag is equal to 1, the value of subpic_info_present_flag shall be equal to 0" );
1525
342
  sps->setSubPicInfoPresentFlag( sps_subpic_info_present_flag );
1526
1527
1528
342
  if( sps_subpic_info_present_flag )
1529
266
  {
1530
266
    X_READ_UVLC_NO_RANGE( sps_num_subpics_minus1 );
1531
266
    CHECK( sps_num_subpics_minus1 + 1 > ( ( sps_pic_width_max_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY )
1532
266
                                                      * ( ( sps_pic_height_max_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY ),
1533
266
                       "Invalid sps_num_subpics_minus1 value" );
1534
264
    sps->setNumSubPics( sps_num_subpics_minus1 + 1 );
1535
1536
264
    if( sps_num_subpics_minus1 == 0 )
1537
194
    {
1538
194
      sps->setSubPicCtuTopLeftX( 0, 0 );
1539
194
      sps->setSubPicCtuTopLeftY( 0, 0 );
1540
194
      sps->setSubPicWidth( 0, ( sps->getMaxPicWidthInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) );
1541
194
      sps->setSubPicHeight( 0, ( sps->getMaxPicHeightInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) );
1542
194
      sps->setIndependentSubPicsFlag( 1 );
1543
194
      sps->setSubPicSameSizeFlag( 0 );
1544
194
      sps->setSubPicTreatedAsPicFlag( 0, 1 );
1545
194
      sps->setLoopFilterAcrossSubpicEnabledFlag( 0, 0 );
1546
194
    }
1547
70
    else   // ( sps_num_subpics_minus1 > 0 )
1548
70
    {
1549
70
      X_READ_FLAG( sps_independent_subpics_flag );
1550
70
      sps->setIndependentSubPicsFlag( sps_independent_subpics_flag );
1551
1552
70
      X_READ_FLAG( sps_subpic_same_size_flag );
1553
70
      sps->setSubPicSameSizeFlag( sps_subpic_same_size_flag );
1554
1555
70
      const uint32_t tmpWidthVal = ( sps->getMaxPicWidthInLumaSamples() + sps->getCTUSize() - 1 ) / sps->getCTUSize();
1556
70
      const uint32_t tmpHeightVal = ( sps->getMaxPicHeightInLumaSamples() + sps->getCTUSize() - 1 ) / sps->getCTUSize();
1557
1558
70
      const int ceilLog2tmpWidth  = (int) ceil( log2( tmpWidthVal ) );
1559
70
      const int ceilLog2tmpHeight = (int) ceil( log2( tmpHeightVal ) );
1560
368
      for( unsigned picIdx = 0; picIdx < sps->getNumSubPics(); picIdx++ )
1561
316
      {
1562
316
        if( !sps_subpic_same_size_flag || picIdx == 0 )
1563
292
        {
1564
292
          if( picIdx > 0 && sps_pic_width_max_in_luma_samples > CtbSizeY )
1565
202
          {
1566
202
            X_READ_CODE_NO_RANGE_idx( sps_subpic_ctu_top_left_x, "[ i ]", ceilLog2tmpWidth );
1567
202
            sps->setSubPicCtuTopLeftX( picIdx, sps_subpic_ctu_top_left_x );
1568
202
          }
1569
90
          else
1570
90
          {
1571
90
            sps->setSubPicCtuTopLeftX( picIdx, 0 );
1572
90
          }
1573
1574
292
          if( picIdx > 0 && sps_pic_height_max_in_luma_samples > CtbSizeY )
1575
172
          {
1576
172
            X_READ_CODE_NO_RANGE_idx( sps_subpic_ctu_top_left_y, "[ i ]", ceilLog2tmpHeight );
1577
172
            sps->setSubPicCtuTopLeftY( picIdx, sps_subpic_ctu_top_left_y );
1578
172
          }
1579
120
          else
1580
120
          {
1581
120
            sps->setSubPicCtuTopLeftY( picIdx, 0 );
1582
120
          }
1583
1584
292
          if( picIdx < sps_num_subpics_minus1 && sps_pic_width_max_in_luma_samples > CtbSizeY )
1585
226
          {
1586
226
            X_READ_CODE_NO_RANGE_idx( sps_subpic_width_minus1, "[ i ]", ceilLog2tmpWidth );
1587
226
            sps->setSubPicWidth( picIdx, sps_subpic_width_minus1 + 1 );
1588
226
          }
1589
66
          else
1590
66
          {
1591
            // If sps_subpic_same_size_flag is equal to 0 or i is equal to 0, the value of sps_subpic_width_minus1[ i ] is inferred
1592
            //   to be equal to tmpWidthVal - sps_subpic_ctu_top_left_x[ i ] - 1.
1593
66
            sps->setSubPicWidth( picIdx, tmpWidthVal - sps->getSubPicCtuTopLeftX( picIdx ) );
1594
66
          }
1595
1596
292
          if( picIdx < sps_num_subpics_minus1 && sps_pic_height_max_in_luma_samples > CtbSizeY )
1597
186
          {
1598
186
            X_READ_CODE_NO_RANGE_idx( sps_subpic_height_minus1, "[ i ]", ceilLog2tmpHeight );
1599
186
            sps->setSubPicHeight( picIdx, sps_subpic_height_minus1 + 1 );
1600
186
          }
1601
106
          else
1602
106
          {
1603
            // If sps_subpic_same_size_flag is equal to 0 or i is equal to 0, the value of sps_subpic_height_minus1[ i ] is inferred
1604
            //   to be equal to tmpHeightVal - sps_subpic_ctu_top_left_y[ i ] − 1.
1605
106
            sps->setSubPicHeight( picIdx, tmpHeightVal - sps->getSubPicCtuTopLeftY( picIdx ) );
1606
106
          }
1607
292
        }
1608
24
        else   // ( sps_subpic_same_size_flag && picIdx != 0 )
1609
24
        {
1610
24
          const int numSubpicCols = tmpWidthVal / sps->getSubPicWidth( 0 );
1611
1612
          // const int numSubpicCols = tmpWidthVal / ( sps->getSubPicWidth( 0 ) + 1 );
1613
24
          CHECK( sps_subpic_same_size_flag && numSubpicCols * tmpHeightVal / sps->getSubPicHeight( 0 ) - 1 != sps_num_subpics_minus1,
1614
24
                 "When sps_subpic_same_size_flag is equal to 1, the value of numSubpicCols * tmpHeightVal / ( sps_subpic_height_minus1[ 0 ] + 1 ) − 1"
1615
24
                 " shall be equal to sps_num_subpics_minus1." )
1616
20
          CHECK( sps_subpic_same_size_flag && tmpWidthVal % sps->getSubPicWidth( 0 ) != 0,
1617
20
                 "When sps_subpic_same_size_flag is equal to 1, the value of tmpWidthVal % ( sps_subpic_width_minus1[ 0 ] + 1 ) shall"
1618
20
                 " be equal to 0." );
1619
18
          CHECK( sps_subpic_same_size_flag && tmpHeightVal % sps->getSubPicHeight( 0 ) != 0,
1620
18
                 "When sps_subpic_same_size_flag is equal to 1, the value of tmpHeightVal % ( sps_subpic_height_minus1[ 0 ] + 1 ) shall"
1621
18
                 " be equal to 0." )
1622
1623
          // Otherwise, the value of sps_subpic_ctu_top_left_x[ i ] is inferred to be equal to ( i % numSubpicCols ) * ( sps_subpic_width_minus1[ 0 ] + 1 ).
1624
          // Otherwise, the value of sps_subpic_ctu_top_left_y[ i ] is inferred to be equal to ( i / numSubpicCols ) * ( sps_subpic_height_minus1[ 0 ] + 1 ).
1625
16
          sps->setSubPicCtuTopLeftX( picIdx, ( picIdx % numSubpicCols ) * sps->getSubPicWidth( 0 ) );
1626
16
          sps->setSubPicCtuTopLeftY( picIdx, ( picIdx / numSubpicCols ) * sps->getSubPicHeight( 0 ) );
1627
          // Otherwise, the value of sps_subpic_width_minus1[ i ] is inferred to be equal to sps_subpic_width_minus1[ 0 ].
1628
          // Otherwise, the value of sps_subpic_height_minus1[ i ] is inferred to be equal to sps_subpic_height_minus1[ 0 ].
1629
16
          sps->setSubPicWidth( picIdx, sps->getSubPicWidth( 0 ) );
1630
16
          sps->setSubPicHeight( picIdx, sps->getSubPicHeight( 0 ) );
1631
16
        }
1632
1633
        // TODO: It is a requirement of bitstream conformance that the shapes of the subpictures shall be such that each subpicture, when
1634
        //       decoded, shall have its entire left boundary and entire top boundary consisting of picture boundaries or consisting of
1635
        //       boundaries of previously decoded subpictures.
1636
        //       For each subpicture with subpicture index i in the range of 0 to sps_num_subpics_minus1, inclusive, it is a requirement
1637
        //       of bitstream conformance that all of the following conditions are true:
1638
        //       - The value of ( sps_subpic_ctu_top_left_x[ i ] * CtbSizeY ) shall be less than ( sps_pic_width_max_in_luma_samples - sps_conf_win_right_offset * SubWidthC ).
1639
        //       - The value of ( ( sps_subpic_ctu_top_left_x[ i ] + sps_subpic_width_minus1[ i ] + 1 ) * CtbSizeY ) shall be greater than ( sps_conf_win_left_offset * SubWidthC ).
1640
        //       - The value of ( sps_subpic_ctu_top_left_y[ i ] * CtbSizeY ) shall  be less than ( sps_pic_height_max_in_luma_samples - sps_conf_win_bottom_offset * SubHeightC ).
1641
        //       - The value of ( ( sps_subpic_ctu_top_left_y[ i ] + sps_subpic_height_minus1[ i ] + 1 ) * CtbSizeY ) shall be greater than ( sps_conf_win_top_offset * SubHeightC ).
1642
1643
308
        Window& conf = sps->getConformanceWindow();
1644
308
        CHECK( sps->getSubPicCtuTopLeftX( picIdx ) * CtbSizeY >= sps->getMaxPicWidthInLumaSamples() - conf.getWindowRightOffset() * SubWidthC,
1645
308
               "The value of ( sps_subpic_ctu_top_left_x[ i ] * CtbSizeY )"
1646
308
               " shall be less than ( sps_pic_width_max_in_luma_samples - sps_conf_win_right_offset * SubWidthC )." );
1647
302
        CHECK( ( sps->getSubPicCtuTopLeftX( picIdx ) + sps->getSubPicWidth( picIdx ) ) * CtbSizeY <= conf.getWindowLeftOffset() * SubWidthC,
1648
302
               "The value of ( ( sps_subpic_ctu_top_left_x[ i ] + sps_subpic_width_minus1[ i ] + 1 ) * CtbSizeY )"
1649
302
               " shall be greater than ( sps_conf_win_left_offset * SubWidthC )." );
1650
302
        CHECK( sps->getSubPicCtuTopLeftY( picIdx ) * CtbSizeY >= sps->getMaxPicHeightInLumaSamples() - conf.getWindowBottomOffset() * SubHeightC,
1651
302
               "The value of ( sps_subpic_ctu_top_left_y[ i ] * CtbSizeY )"
1652
302
               " shall  be less than ( sps_pic_height_max_in_luma_samples - sps_conf_win_bottom_offset * SubHeightC )." );
1653
300
        CHECK( ( sps->getSubPicCtuTopLeftY( picIdx ) + sps->getSubPicHeight( picIdx ) ) * CtbSizeY <= conf.getWindowTopOffset() * SubHeightC,
1654
300
               "The value of ( ( sps_subpic_ctu_top_left_y[ i ] + sps_subpic_height_minus1[ i ] + 1 ) * CtbSizeY )"
1655
300
               " shall be greater than ( sps_conf_win_top_offset * SubHeightC )." );
1656
1657
298
        if( !sps_independent_subpics_flag )
1658
174
        {
1659
174
          X_READ_FLAG_idx( sps_subpic_treated_as_pic_flag, "[ i ]" );
1660
174
          sps->setSubPicTreatedAsPicFlag( picIdx, sps_subpic_treated_as_pic_flag );
1661
1662
174
          X_READ_FLAG_idx( sps_loop_filter_across_subpic_enabled_flag, "[ i ]" );
1663
174
          sps->setLoopFilterAcrossSubpicEnabledFlag( picIdx, sps_loop_filter_across_subpic_enabled_flag );
1664
174
        }
1665
124
        else
1666
124
        {
1667
          // should be set as default
1668
124
            sps->setSubPicTreatedAsPicFlag( picIdx, 1 );
1669
124
        }
1670
298
      }   //      for( unsigned picIdx = 0; picIdx < sps->getNumSubPics(); picIdx++ )
1671
70
    }
1672
1673
1674
246
    X_READ_UVLC( sps_subpic_id_len_minus1, 0, 15 );
1675
246
    CHECK( 1 << ( sps_subpic_id_len_minus1 + 1 ) < sps_num_subpics_minus1 + 1,
1676
246
           "The value of 1 << ( sps_subpic_id_len_minus1 + 1 ) shall be greater than or equal to sps_num_subpics_minus1 + 1" );
1677
244
    sps->setSubPicIdLen( sps_subpic_id_len_minus1 + 1 );
1678
1679
244
    X_READ_FLAG( sps_subpic_id_mapping_explicitly_signalled_flag );
1680
244
    sps->setSubPicIdMappingExplicitlySignalledFlag( sps_subpic_id_mapping_explicitly_signalled_flag );
1681
1682
244
    if( sps_subpic_id_mapping_explicitly_signalled_flag )
1683
206
    {
1684
206
      X_READ_FLAG( sps_subpic_id_mapping_present_flag );
1685
206
      sps->setSubPicIdMappingPresentFlag( sps_subpic_id_mapping_present_flag );
1686
1687
206
      if( sps_subpic_id_mapping_present_flag )
1688
194
      {
1689
422
        for( int picIdx = 0; picIdx <= sps_num_subpics_minus1; picIdx++ )
1690
228
        {
1691
228
          X_READ_CODE_NO_RANGE_idx( sps_subpic_id, "[ i ]", sps->getSubPicIdLen() );
1692
228
          sps->setSubPicId( picIdx, sps_subpic_id );
1693
228
        }
1694
194
      }
1695
206
    }
1696
244
  }   // sps_subpic_info_present_flag
1697
76
  else  // ( !sps_subpic_info_present_flag )
1698
76
  {
1699
76
    sps->setSubPicIdMappingExplicitlySignalledFlag( 0 );
1700
76
    sps->setNumSubPics( 1 );
1701
76
    sps->setSubPicCtuTopLeftX( 0, 0 );
1702
76
    sps->setSubPicCtuTopLeftY( 0, 0 );
1703
76
    sps->setSubPicWidth( 0, ( sps->getMaxPicWidthInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) );
1704
76
    sps->setSubPicHeight( 0, ( sps->getMaxPicHeightInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) );
1705
76
    sps->setSubPicTreatedAsPicFlag( 0, true );
1706
76
    sps->setLoopFilterAcrossSubpicEnabledFlag( 0, false );
1707
76
  }
1708
1709
320
  if( !sps->getSubPicIdMappingExplicitlySignalledFlag() || !sps->getSubPicIdMappingPresentFlag() )
1710
90
  {
1711
242
    for( int picIdx = 0; picIdx < sps->getNumSubPics(); picIdx++ )
1712
152
    {
1713
152
      sps->setSubPicId( picIdx, picIdx );
1714
152
    }
1715
90
  }
1716
1717
320
  X_READ_UVLC( sps_bitdepth_minus8, 0, 8 );
1718
320
  const Profile::Name profile = sps->getProfileTierLevel()->getProfileIdc();
1719
320
  if( profile != Profile::NONE )
1720
2
  {
1721
2
    CHECK( sps_bitdepth_minus8 + 8 > ProfileFeatures::getProfileFeatures( profile )->maxBitDepth,
1722
2
                       "sps_bitdepth_minus8 exceeds range supported by signalled profile" );
1723
0
  }
1724
318
  sps->setBitDepth( 8 + sps_bitdepth_minus8 );
1725
318
  sps->setQpBDOffset( 6 * sps_bitdepth_minus8 );
1726
318
  const int BitDepth = 8 + sps_bitdepth_minus8;
1727
318
  const int QpBdOffset = 6 * sps_bitdepth_minus8;
1728
1729
318
  X_READ_FLAG( sps_entropy_coding_sync_enabled_flag );
1730
318
  sps->setEntropyCodingSyncEnabledFlag( sps_entropy_coding_sync_enabled_flag );
1731
1732
318
  X_READ_FLAG( sps_entry_point_offsets_present_flag );
1733
318
  sps->setEntryPointsPresentFlag( sps_entry_point_offsets_present_flag );
1734
1735
318
  X_READ_CODE( sps_log2_max_pic_order_cnt_lsb_minus4, 4, 0, 12 );
1736
318
  sps->setBitsForPOC( sps_log2_max_pic_order_cnt_lsb_minus4 + 4 );
1737
1738
318
  X_READ_FLAG( sps_poc_msb_cycle_flag );
1739
318
  sps->setPocMsbFlag( sps_poc_msb_cycle_flag );
1740
1741
318
  if( sps_poc_msb_cycle_flag )
1742
182
  {
1743
182
    X_READ_UVLC( sps_poc_msb_cycle_len_minus1, 0, 32 - sps_log2_max_pic_order_cnt_lsb_minus4 - 5 );
1744
182
    sps->setPocMsbLen( sps_poc_msb_cycle_len_minus1 + 1 );
1745
182
  }
1746
1747
  // extra bits are for future extensions, we will read, but ignore them,
1748
  // unless a meaning is specified in the spec
1749
318
  X_READ_CODE( sps_num_extra_ph_bytes, 2, 0, 2 );
1750
318
  sps->setNumExtraPHBitsBytes( sps_num_extra_ph_bytes );
1751
318
  if( sps_num_extra_ph_bytes )
1752
138
  {
1753
138
    parseExtraPHBitsStruct( sps, sps_num_extra_ph_bytes );
1754
138
  }
1755
1756
318
  X_READ_CODE( sps_num_extra_sh_bytes, 2, 0, 2 );
1757
318
  sps->setNumExtraSHBitsBytes( sps_num_extra_sh_bytes );
1758
318
  if( sps_num_extra_sh_bytes )
1759
224
  {
1760
224
    parseExtraSHBitsStruct( sps, sps_num_extra_sh_bytes );
1761
224
  }
1762
1763
318
  if( sps_ptl_dpb_hrd_params_present_flag )
1764
10
  {
1765
10
    if( sps_max_sublayers_minus1 > 0 )
1766
10
    {
1767
10
      X_READ_FLAG( sps_sublayer_dpb_params_flag );
1768
10
      sps->setSubLayerDpbParamsFlag( sps_sublayer_dpb_params_flag );
1769
10
    }
1770
10
    dpb_parameters( sps_max_sublayers_minus1, sps->getSubLayerDpbParamsFlag(), sps );
1771
10
  }
1772
1773
318
  X_READ_UVLC( sps_log2_min_luma_coding_block_size_minus2, 0, std::min( 4u, sps_log2_ctu_size_minus5 + 3 ) );
1774
318
  sps->setLog2MinCodingBlockSize( sps_log2_min_luma_coding_block_size_minus2 + 2 );
1775
1776
318
  const int MinCbLog2SizeY = sps_log2_min_luma_coding_block_size_minus2 + 2;
1777
318
  const int MinCbSizeY     = 1 << MinCbLog2SizeY;
1778
318
  const int VSize          = std::min( 64, CtbSizeY );
1779
318
  CHECK( MinCbSizeY > VSize, "The value of MinCbSizeY shall be less than or equal to VSize." )
1780
318
  CHECK( MinCbLog2SizeY > CtbLog2SizeY, "Invalid log2_min_luma_coding_block_size_minus2 signalled" );
1781
1782
  // postponed checks for sps_pic_{width,height}_max_in_luma_samples,
1783
318
  CHECK( sps_pic_width_max_in_luma_samples == 0 || sps_pic_width_max_in_luma_samples & ( std::max( 8, MinCbSizeY ) - 1 ),
1784
318
         "sps_pic_width_max_in_luma_samples shall not be equal to 0 and shall be an integer multiple of Max( 8, MinCbSizeY )" );
1785
312
  CHECK( sps_pic_height_max_in_luma_samples == 0 || sps_pic_height_max_in_luma_samples & ( std::max( 8, MinCbSizeY ) - 1 ),
1786
312
         "sps_pic_height_max_in_luma_samples shall not be equal to 0 and shall be an integer multiple of Max( 8, MinCbSizeY )" );
1787
1788
308
  const int minCuSize = 1 << sps->getLog2MinCodingBlockSize();
1789
308
  CHECK( ( sps->getMaxPicWidthInLumaSamples() % ( std::max( 8, minCuSize ) ) ) != 0, "Coded frame width must be a multiple of Max(8, the minimum unit size)" );
1790
308
  CHECK( ( sps->getMaxPicHeightInLumaSamples() % ( std::max( 8, minCuSize ) ) ) != 0, "Coded frame height must be a multiple of Max(8, the minimum unit size)" );
1791
1792
308
  X_READ_FLAG( sps_partition_constraints_override_enabled_flag );
1793
308
  sps->setSplitConsOverrideEnabledFlag( sps_partition_constraints_override_enabled_flag );
1794
1795
308
  X_READ_UVLC( sps_log2_diff_min_qt_min_cb_intra_slice_luma, 0, std::min( 6, CtbLog2SizeY ) - MinCbLog2SizeY );
1796
308
  const unsigned MinQtLog2SizeIntraY = sps_log2_diff_min_qt_min_cb_intra_slice_luma + MinCbLog2SizeY;
1797
1798
308
  X_READ_UVLC( sps_max_mtt_hierarchy_depth_intra_slice_luma, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) );
1799
1800
308
  PartitionConstraints minQT     = { 1u << MinQtLog2SizeIntraY, 0, 0 };
1801
308
  PartitionConstraints maxBTD    = { sps_max_mtt_hierarchy_depth_intra_slice_luma, 0, 0 };
1802
308
  PartitionConstraints maxTTSize = { 1u << MinQtLog2SizeIntraY, 0, 0 };
1803
308
  PartitionConstraints maxBTSize = { 1u << MinQtLog2SizeIntraY, 0, 0 };
1804
1805
308
  int spsLog2DiffMinQtMinCbIntraSliceLuma = 0;
1806
308
  if( sps_max_mtt_hierarchy_depth_intra_slice_luma != 0 )
1807
60
  {
1808
60
    X_READ_UVLC( sps_log2_diff_max_bt_min_qt_intra_slice_luma, 0, CtbLog2SizeY - MinQtLog2SizeIntraY );
1809
60
    maxBTSize[0] <<= sps_log2_diff_max_bt_min_qt_intra_slice_luma;
1810
60
    spsLog2DiffMinQtMinCbIntraSliceLuma = sps_log2_diff_max_bt_min_qt_intra_slice_luma;
1811
1812
60
    X_READ_UVLC( sps_log2_diff_max_tt_min_qt_intra_slice_luma, 0, std::min( 6, CtbLog2SizeY ) - MinQtLog2SizeIntraY );
1813
60
    maxTTSize[0] <<= sps_log2_diff_max_tt_min_qt_intra_slice_luma;
1814
60
  }
1815
308
  CHECK( maxTTSize[0] > 64, "The value of sps_log2_diff_max_tt_min_qt_intra_slice_luma shall be in the range of 0 to min(6,CtbLog2SizeY) - MinQtLog2SizeIntraY" );
1816
1817
308
  if( sps_chroma_format_idc != CHROMA_400 )
1818
150
  {
1819
150
    X_READ_FLAG( sps_qtbtt_dual_tree_intra_flag );
1820
150
    sps->setUseDualITree( sps_qtbtt_dual_tree_intra_flag );
1821
1822
150
    (void)spsLog2DiffMinQtMinCbIntraSliceLuma;
1823
    // this breaks the testset (TREE_C_HHI_3.bit) although specified in the spec
1824
    // CHECK( spsLog2DiffMinQtMinCbIntraSliceLuma > std::min( 6, CtbLog2SizeY ) - MinQtLog2SizeIntraY && sps_qtbtt_dual_tree_intra_flag,
1825
    //        "When sps_log2_diff_max_bt_min_qt_intra_slice_luma is greater than Min( 6, CtbLog2SizeY ) - MinQtLog2SizeIntraY, the value of "
1826
    //        "sps_qtbtt_dual_tree_intra_flag shall be equal to 0." )
1827
150
  }
1828
1829
1830
308
  if( sps->getUseDualITree() )
1831
56
  {
1832
56
    X_READ_UVLC( sps_log2_diff_min_qt_min_cb_intra_slice_chroma, 0, std::min( 6, CtbLog2SizeY ) - MinCbLog2SizeY );
1833
56
    const int MinQtLog2SizeIntraC = sps_log2_diff_min_qt_min_cb_intra_slice_chroma + MinCbLog2SizeY;
1834
1835
56
    X_READ_UVLC( sps_max_mtt_hierarchy_depth_intra_slice_chroma, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) );
1836
56
    maxBTD[2] = sps_max_mtt_hierarchy_depth_intra_slice_chroma;
1837
1838
56
    minQT[2] = 1 << MinQtLog2SizeIntraC;
1839
56
    maxTTSize[2] = maxBTSize[2] = minQT[2];
1840
56
    if( sps_max_mtt_hierarchy_depth_intra_slice_chroma != 0 )
1841
16
    {
1842
16
      X_READ_UVLC( sps_log2_diff_max_bt_min_qt_intra_slice_chroma, 0, std::min( 6, CtbLog2SizeY ) - MinQtLog2SizeIntraC );
1843
16
      maxBTSize[2] <<= sps_log2_diff_max_bt_min_qt_intra_slice_chroma;
1844
1845
16
      X_READ_UVLC( sps_log2_diff_max_tt_min_qt_intra_slice_chroma, 0, std::min( 6, CtbLog2SizeY ) - MinQtLog2SizeIntraC );
1846
16
      maxTTSize[2] <<= sps_log2_diff_max_tt_min_qt_intra_slice_chroma;
1847
1848
16
      CHECK( maxTTSize[2] > 64, "The value of sps_log2_diff_max_tt_min_qt_intra_slice_chroma shall be in the range of 0 to min(6,CtbLog2SizeY) - MinQtLog2SizeIntraChroma" );
1849
16
      CHECK( maxBTSize[2] > 64, "The value of sps_log2_diff_max_bt_min_qt_intra_slice_chroma shall be in the range of 0 to min(6,CtbLog2SizeY) - MinQtLog2SizeIntraChroma" );
1850
16
    }
1851
56
  }
1852
  // minQT[2] = 1 << MinQtLog2SizeIntraC; // THIS WAS MISSING? -> only read for dual tree
1853
1854
308
  X_READ_UVLC( sps_log2_diff_min_qt_min_cb_inter_slice, 0, std::min( 6, CtbLog2SizeY ) - MinCbLog2SizeY );
1855
308
  const int MinQtLog2SizeInterY = sps_log2_diff_min_qt_min_cb_inter_slice + MinCbLog2SizeY;
1856
1857
308
  X_READ_UVLC( sps_max_mtt_hierarchy_depth_inter_slice, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) );
1858
308
  maxBTD[1] = sps_max_mtt_hierarchy_depth_inter_slice;
1859
1860
308
  minQT[1] = 1 << MinQtLog2SizeInterY;
1861
308
  maxTTSize[1] = maxBTSize[1] = minQT[1];
1862
308
  if( sps_max_mtt_hierarchy_depth_inter_slice != 0 )
1863
44
  {
1864
44
    X_READ_UVLC( sps_log2_diff_max_bt_min_qt_inter_slice, 0, CtbLog2SizeY - MinQtLog2SizeInterY );
1865
44
    maxBTSize[1] <<= sps_log2_diff_max_bt_min_qt_inter_slice;
1866
1867
44
    X_READ_UVLC( sps_log2_diff_max_tt_min_qt_inter_slice, 0, std::min( 6, CtbLog2SizeY ) - MinQtLog2SizeInterY );
1868
44
    maxTTSize[1] <<= sps_log2_diff_max_tt_min_qt_inter_slice;
1869
44
  }
1870
1871
308
  sps->setMinQTSizes( minQT );
1872
308
  sps->setMaxMTTHierarchyDepths( maxBTD );
1873
308
  sps->setMaxBTSizes( maxBTSize );
1874
308
  sps->setMaxTTSizes( maxTTSize );
1875
1876
308
  if( CtbSizeY > 32 )
1877
116
  {
1878
116
    X_READ_FLAG( sps_max_luma_transform_size_64_flag );
1879
116
    sps->setLog2MaxTbSize( 5 + sps_max_luma_transform_size_64_flag );
1880
116
  }
1881
192
  else
1882
192
  {
1883
192
    sps->setLog2MaxTbSize( 5 );
1884
192
  }
1885
1886
308
  X_READ_FLAG( sps_transform_skip_enabled_flag );
1887
308
  sps->setTransformSkipEnabledFlag( sps_transform_skip_enabled_flag );
1888
1889
308
  if( sps_transform_skip_enabled_flag )
1890
158
  {
1891
158
    X_READ_UVLC( sps_log2_transform_skip_max_size_minus2, 0, 3 );
1892
158
    sps->setLog2MaxTransformSkipBlockSize( sps_log2_transform_skip_max_size_minus2 + 2 );
1893
1894
158
    X_READ_FLAG( sps_bdpcm_enabled_flag );
1895
158
    sps->setBDPCMEnabledFlag( sps_bdpcm_enabled_flag );
1896
158
  }
1897
1898
308
  X_READ_FLAG( sps_mts_enabled_flag );
1899
308
  sps->setUseMTS( sps_mts_enabled_flag );
1900
1901
308
  if( sps_mts_enabled_flag )
1902
82
  {
1903
82
    X_READ_FLAG( sps_explicit_mts_intra_enabled_flag );
1904
82
    sps->setUseIntraMTS( sps_explicit_mts_intra_enabled_flag );
1905
1906
82
    X_READ_FLAG( sps_explicit_mts_inter_enabled_flag );
1907
82
    sps->setUseInterMTS( sps_explicit_mts_inter_enabled_flag );
1908
82
  }
1909
1910
308
  X_READ_FLAG( sps_lfnst_enabled_flag );
1911
308
  sps->setUseLFNST( sps_lfnst_enabled_flag );
1912
1913
308
  if( sps_chroma_format_idc != CHROMA_400 )
1914
132
  {
1915
132
    X_READ_FLAG( sps_joint_cbcr_enabled_flag );
1916
132
    sps->setJointCbCrEnabledFlag( sps_joint_cbcr_enabled_flag );
1917
1918
132
    X_READ_FLAG( sps_same_qp_table_for_chroma_flag );
1919
132
    ChromaQpMappingTableParams chromaQpMappingTableParams;
1920
132
    chromaQpMappingTableParams.setSameCQPTableForAllChromaFlag( sps_same_qp_table_for_chroma_flag );
1921
1922
132
    const int numQpTables = sps_same_qp_table_for_chroma_flag ? 1 : ( sps_joint_cbcr_enabled_flag ? 3 : 2 );
1923
132
    chromaQpMappingTableParams.setNumQpTables( numQpTables );
1924
1925
362
    for( int i = 0; i < numQpTables; i++ )
1926
230
    {
1927
230
      X_READ_SVLC( sps_qp_table_start_minus26, -26 - QpBdOffset, 36 );
1928
230
      chromaQpMappingTableParams.setQpTableStartMinus26( i, sps_qp_table_start_minus26 );
1929
1930
230
      X_READ_UVLC( sps_num_points_in_qp_table_minus1, 0, (unsigned) ( 36 - sps_qp_table_start_minus26 ) ); // cast after subtraction to prevent conversion of sps_qp_table_start_minus26 to unsigned
1931
230
      chromaQpMappingTableParams.setNumPtsInCQPTableMinus1( i, sps_num_points_in_qp_table_minus1 );
1932
1933
230
      std::vector<int> deltaQpInValMinus1( sps_num_points_in_qp_table_minus1 + 1 );
1934
230
      std::vector<int> deltaQpOutVal( sps_num_points_in_qp_table_minus1 + 1 );
1935
668
      for( unsigned j = 0; j <= sps_num_points_in_qp_table_minus1; j++ )
1936
438
      {
1937
438
        X_READ_UVLC_NO_RANGE( sps_delta_qp_in_val_minus1 );   // checked later in ChromaQpMappingTable::deriveChromaQPMappingTables()
1938
438
        deltaQpInValMinus1[j] = sps_delta_qp_in_val_minus1;
1939
1940
438
        X_READ_UVLC_NO_RANGE( sps_delta_qp_diff_val );   // checked later in ChromaQpMappingTable::deriveChromaQPMappingTables()
1941
438
        deltaQpOutVal[j] = sps_delta_qp_diff_val ^ deltaQpInValMinus1[j];
1942
438
      }
1943
230
      chromaQpMappingTableParams.setDeltaQpInValMinus1( i, deltaQpInValMinus1 );
1944
230
      chromaQpMappingTableParams.setDeltaQpOutVal( i, deltaQpOutVal );
1945
230
    }
1946
132
    chromaQpMappingTableParams.m_qpBdOffset = sps->getQpBDOffset();
1947
132
    sps->setChromaQpMappingTableFromParams( std::move( chromaQpMappingTableParams ) );
1948
132
    sps->deriveChromaQPMappingTables();
1949
132
  }
1950
1951
1952
308
  X_READ_FLAG( sps_sao_enabled_flag );
1953
308
  sps->setUseSAO( sps_sao_enabled_flag );
1954
1955
308
  X_READ_FLAG( sps_alf_enabled_flag );
1956
308
  sps->setUseALF( sps_alf_enabled_flag );
1957
1958
308
  if( sps_alf_enabled_flag && sps_chroma_format_idc != CHROMA_400 )
1959
36
  {
1960
36
    X_READ_FLAG( sps_ccalf_enabled_flag );
1961
36
    sps->setUseCCALF( sps_ccalf_enabled_flag );
1962
36
  }
1963
272
  else
1964
272
  {
1965
272
    sps->setUseCCALF( false );
1966
272
  }
1967
1968
308
  X_READ_FLAG( sps_lmcs_enable_flag );
1969
308
  sps->setUseReshaper( sps_lmcs_enable_flag );
1970
1971
308
  X_READ_FLAG( sps_weighted_pred_flag );
1972
308
  sps->setUseWP( sps_weighted_pred_flag );
1973
1974
308
  X_READ_FLAG( sps_weighted_bipred_flag );
1975
308
  sps->setUseWPBiPred( sps_weighted_bipred_flag );
1976
1977
308
  X_READ_FLAG( sps_long_term_ref_pics_flag );
1978
308
  sps->setLongTermRefsPresent( sps_long_term_ref_pics_flag );
1979
1980
308
  if( sps_video_parameter_set_id > 0 )
1981
180
  {
1982
180
    X_READ_FLAG( sps_inter_layer_prediction_enabled_flag );
1983
180
    sps->setInterLayerPresentFlag( sps_inter_layer_prediction_enabled_flag );
1984
    // CHECK( vps->getIndependentLayerFlag( vps->getGeneralLayerIdx( nuh_layer_id ) ) == 1 && sps_inter_layer_prediction_enabled_flag != 0,
1985
    //        "When vps_independent_layer_flag[ GeneralLayerIdx[ nuh_layer_id ] ] is equal to 1,"
1986
    //        " the value of sps_inter_layer_prediction_enabled_flag shall be equal to 0." )
1987
180
  }
1988
1989
308
  X_READ_FLAG( sps_idr_rpl_present_flag );
1990
308
  CHECK_CONSTRAINT( gci->getNoIdrRplConstraintFlag() && sps_idr_rpl_present_flag,
1991
308
                    "When gci_no_idr_rpl_constraint_flag equal to 1, the value of sps_idr_rpl_present_flag shall be equal to 0" );
1992
308
  sps->setIDRRefParamListPresent( sps_idr_rpl_present_flag );
1993
1994
308
  X_READ_FLAG( sps_rpl1_same_as_rpl0_flag );
1995
308
  sps->setRPL1CopyFromRPL0Flag( sps_rpl1_same_as_rpl0_flag );
1996
1997
544
  for( unsigned i = 0; i < ( sps_rpl1_same_as_rpl0_flag ? 1 : 2 ); i++ )
1998
236
  {
1999
236
    X_READ_UVLC_idx( sps_num_ref_pic_lists, "[i]", 0, 64 );
2000
2001
236
    RPLList& rplList = sps->createRPLList( i, sps_num_ref_pic_lists );
2002
784
    for( unsigned j = 0; j < sps_num_ref_pic_lists; j++ )
2003
548
    {
2004
548
      parseRefPicList( &rplList[j], j, sps );
2005
548
    }
2006
236
  }
2007
308
  if( sps_rpl1_same_as_rpl0_flag )
2008
96
  {
2009
96
    const unsigned numberOfRPL   = sps->getNumRPL( 0 );
2010
96
    const RPLList& rplListSource = sps->getRPLList( 0 );
2011
96
    RPLList&       rplListDest   = sps->createRPLList( 1, numberOfRPL );
2012
218
    for( unsigned j = 0; j < numberOfRPL; j++ )
2013
122
    {
2014
122
      copyRefPicList( sps, &rplListSource[j], &rplListDest[j] );
2015
122
    }
2016
96
  }
2017
2018
2019
308
  X_READ_FLAG( sps_ref_wraparound_enabled_flag );
2020
308
  sps->setUseWrapAround( sps_ref_wraparound_enabled_flag );
2021
452
  for( int i = 0; i < sps->getNumSubPics(); ++i )
2022
150
  {
2023
150
    CHECK( sps->getSubPicTreatedAsPicFlag( i ) == 1 && sps->getSubPicWidth( i ) != ( sps_pic_width_max_in_luma_samples + CtbSizeY - 1 ) >> CtbLog2SizeY
2024
150
             && sps_ref_wraparound_enabled_flag != 0,
2025
150
           "It is a requirement of bitstream conformance that, when there is one or more values of i in the range of 0 to sps_num_subpics_minus1, inclusive,"
2026
150
           " for which sps_subpic_treated_as_pic_flag[ i ] is equal to 1 and sps_subpic_width_minus1[ i ] plus 1 is not equal to"
2027
150
           " ( sps_pic_width_max_in_luma_samples + CtbSizeY− 1 ) >> CtbLog2SizeY ), the value of sps_ref_wraparound_enabled_flag shall be equal to 0." );
2028
144
  }
2029
2030
302
  X_READ_FLAG( sps_temporal_mvp_enabled_flag );
2031
302
  sps->setSPSTemporalMVPEnabledFlag( sps_temporal_mvp_enabled_flag );
2032
2033
302
  if( sps_temporal_mvp_enabled_flag )
2034
100
  {
2035
100
    X_READ_FLAG( sps_sbtmvp_enabled_flag );
2036
100
    sps->setSBTMVPEnabledFlag( sps_sbtmvp_enabled_flag );
2037
100
  }
2038
2039
302
  X_READ_FLAG( sps_amvr_enabled_flag );
2040
302
  sps->setAMVREnabledFlag( sps_amvr_enabled_flag );
2041
2042
302
  X_READ_FLAG( sps_bdof_enabled_flag );
2043
302
  sps->setUseBIO( sps_bdof_enabled_flag );
2044
2045
302
  if( sps_bdof_enabled_flag )
2046
98
  {
2047
98
    X_READ_FLAG( sps_bdof_control_present_in_ph_flag );
2048
98
    sps->setBdofControlPresentInPhFlag( sps_bdof_control_present_in_ph_flag );
2049
98
  }
2050
2051
302
  X_READ_FLAG( sps_smvd_enabled_flag );
2052
302
  sps->setUseSMVD( sps_smvd_enabled_flag );
2053
2054
302
  X_READ_FLAG( sps_dmvr_enabled_flag );
2055
302
  sps->setUseDMVR( sps_dmvr_enabled_flag );
2056
2057
302
  if( sps_dmvr_enabled_flag )
2058
102
  {
2059
102
    X_READ_FLAG( sps_dmvr_control_present_in_ph_flag );
2060
102
    sps->setDmvrControlPresentInPhFlag( sps_dmvr_control_present_in_ph_flag );
2061
102
  }
2062
2063
302
  X_READ_FLAG( sps_mmvd_enabled_flag );
2064
302
  sps->setUseMMVD( sps_mmvd_enabled_flag );
2065
2066
302
  if( sps->getUseMMVD() )
2067
108
  {
2068
108
    X_READ_FLAG( sps_mmvd_fullpel_only_flag );
2069
108
    sps->setFpelMmvdEnabledFlag( sps_mmvd_fullpel_only_flag );
2070
108
  }
2071
2072
302
  X_READ_UVLC( sps_six_minus_max_num_merge_cand, 0, 5 );
2073
302
  const unsigned MaxNumMergeCand = MRG_MAX_NUM_CANDS - sps_six_minus_max_num_merge_cand;
2074
302
  sps->setMaxNumMergeCand( MaxNumMergeCand );
2075
2076
302
  X_READ_FLAG( sps_sbt_enabled_flag );
2077
302
  sps->setUseSBT( sps_sbt_enabled_flag );
2078
2079
302
  X_READ_FLAG( sps_affine_enabled_flag );
2080
302
  sps->setUseAffine( sps_affine_enabled_flag );
2081
2082
302
  if( sps_affine_enabled_flag )
2083
38
  {
2084
38
    X_READ_UVLC( sps_five_minus_max_num_subblock_merge_cand, 0, 5 - sps->getSBTMVPEnabledFlag() );
2085
38
    sps->setMaxNumAffineMergeCand( AFFINE_MRG_MAX_NUM_CANDS - sps_five_minus_max_num_subblock_merge_cand );
2086
2087
38
    X_READ_FLAG( sps_6param_affine_enabled_flag );
2088
38
    sps->setUseAffineType( sps_6param_affine_enabled_flag );
2089
2090
38
    if( sps_amvr_enabled_flag )
2091
26
    {
2092
26
      X_READ_FLAG( sps_affine_amvr_enabled_flag );
2093
26
      sps->setAffineAmvrEnabledFlag( sps_affine_amvr_enabled_flag );
2094
26
    }
2095
2096
38
    X_READ_FLAG( sps_affine_prof_enabled_flag );
2097
38
    sps->setUsePROF( sps_affine_prof_enabled_flag );
2098
2099
38
    if( sps_affine_prof_enabled_flag )
2100
26
    {
2101
26
      X_READ_FLAG( sps_prof_control_present_in_ph_flag );
2102
26
      sps->setProfControlPresentInPhFlag( sps_prof_control_present_in_ph_flag );
2103
26
    }
2104
38
  }
2105
2106
302
  X_READ_FLAG( sps_bcw_enabled_flag );
2107
302
  sps->setUseBcw( sps_bcw_enabled_flag );
2108
2109
302
  X_READ_FLAG( sps_ciip_enabled_flag );
2110
302
  sps->setUseCiip( sps_ciip_enabled_flag );
2111
2112
302
  if( MaxNumMergeCand >= 2 )
2113
120
  {
2114
120
    X_READ_FLAG( sps_gpm_enabled_flag );
2115
120
    sps->setUseGeo( sps_gpm_enabled_flag );
2116
2117
120
    if( sps_gpm_enabled_flag && MaxNumMergeCand >= 3 )
2118
74
    {
2119
74
      X_READ_UVLC( sps_max_num_merge_cand_minus_max_num_gpm_cand, 0, MaxNumMergeCand - 2 );
2120
74
      sps->setMaxNumGeoCand( MaxNumMergeCand - sps_max_num_merge_cand_minus_max_num_gpm_cand );
2121
74
    }
2122
46
    else if( sps_gpm_enabled_flag )
2123
4
    {
2124
4
      sps->setMaxNumGeoCand( 2 );
2125
4
    }
2126
120
  }
2127
2128
302
  X_READ_UVLC( sps_log2_parallel_merge_level_minus2, 0, CtbLog2SizeY - 2 );
2129
302
  sps->setLog2ParallelMergeLevelMinus2( sps_log2_parallel_merge_level_minus2 );
2130
2131
302
  X_READ_FLAG( sps_isp_enabled_flag );
2132
302
  sps->setUseISP( sps_isp_enabled_flag );
2133
2134
302
  X_READ_FLAG( sps_mrl_enabled_flag );
2135
302
  sps->setUseMRL( sps_mrl_enabled_flag );
2136
2137
302
  X_READ_FLAG( sps_mip_enabled_flag );
2138
302
  sps->setUseMIP( sps_mip_enabled_flag );
2139
2140
302
  if( sps_chroma_format_idc != CHROMA_400 )
2141
78
  {
2142
78
    X_READ_FLAG( sps_cclm_enabled_flag );
2143
78
    sps->setUseLMChroma( sps_cclm_enabled_flag );
2144
78
  }
2145
2146
302
  if( sps_chroma_format_idc == CHROMA_420 )
2147
50
  {
2148
50
    X_READ_FLAG( sps_chroma_horizontal_collocated_flag );
2149
50
    sps->setHorCollocatedChromaFlag( sps_chroma_horizontal_collocated_flag );
2150
2151
50
    X_READ_FLAG( sps_chroma_vertical_collocated_flag );
2152
50
    sps->setVerCollocatedChromaFlag( sps_chroma_vertical_collocated_flag );
2153
50
  }
2154
2155
302
  X_READ_FLAG( sps_palette_enabled_flag );
2156
302
  CHECK( sps_palette_enabled_flag, "palette mode is not yet supported" );
2157
2158
294
  if( sps_chroma_format_idc == CHROMA_444 && sps->getLog2MaxTbSize() != 6 )
2159
18
  {
2160
18
    X_READ_FLAG( sps_act_enabled_flag );
2161
18
    sps->setUseColorTrans( sps_act_enabled_flag );
2162
18
  }
2163
2164
294
  if( sps_transform_skip_enabled_flag || sps_palette_enabled_flag )
2165
88
  {
2166
88
    X_READ_UVLC( sps_internal_bit_depth_minus_input_bit_depth, 0, 8 );   // Why is this called sps_min_qp_prime_ts in the standard?
2167
88
    sps->setInternalMinusInputBitDepth( sps_internal_bit_depth_minus_input_bit_depth );
2168
88
  }
2169
2170
294
  X_READ_FLAG( sps_ibc_enabled_flag );
2171
294
  sps->setIBCFlag( sps_ibc_enabled_flag );
2172
2173
294
  if( sps_ibc_enabled_flag )
2174
62
  {
2175
62
    X_READ_UVLC( sps_six_minus_max_num_ibc_merge_cand, 0, 5 );
2176
62
    sps->setMaxNumIBCMergeCand( IBC_MRG_MAX_NUM_CANDS - sps_six_minus_max_num_ibc_merge_cand );
2177
62
  }
2178
2179
294
#  if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
2180
294
  X_READ_FLAG( sps_ladf_enabled_flag );
2181
294
  sps->setLadfEnabled( sps_ladf_enabled_flag );
2182
2183
294
  if( sps->getLadfEnabled() )
2184
44
  {
2185
44
    X_READ_CODE( sps_num_ladf_intervals_minus2, 2, 0, 3 );
2186
44
    sps->setLadfNumIntervals( sps_num_ladf_intervals_minus2 + 2 );
2187
2188
44
    X_READ_SVLC( sps_ladf_lowest_interval_qp_offset, -63, 63 );
2189
44
    sps->setLadfQpOffset( sps_ladf_lowest_interval_qp_offset, 0 );
2190
2191
138
    for( unsigned i = 0; i < sps_num_ladf_intervals_minus2 + 1; i++ )
2192
94
    {
2193
94
      X_READ_SVLC_idx( sps_ladf_qp_offset, "[i]", -63, 63 );
2194
94
      sps->setLadfQpOffset( sps_ladf_qp_offset, i + 1 );
2195
2196
94
      X_READ_UVLC_idx( sps_ladf_delta_threshold_minus1, "[i]", 0, ( 1 << BitDepth ) - 3 );
2197
94
      sps->setLadfIntervalLowerBound( sps->getLadfIntervalLowerBound( i ) + sps_ladf_delta_threshold_minus1 + 1, i + 1 );
2198
94
    }
2199
44
  }
2200
294
#endif
2201
2202
294
  X_READ_FLAG( sps_explicit_scaling_list_enabled_flag );
2203
294
  CHECK_CONSTRAINT( gci->getNoExplicitScaleListConstraintFlag() && sps_explicit_scaling_list_enabled_flag,
2204
294
                    "When gci_no_explicit_scaling_list_constraint_flag is equal to 1, sps_explicit_scaling_list_enabled_flag shall be equal to 0" );
2205
294
  sps->setScalingListFlag( sps_explicit_scaling_list_enabled_flag );
2206
2207
294
  if( sps_lfnst_enabled_flag && sps_explicit_scaling_list_enabled_flag )
2208
12
  {
2209
12
    X_READ_FLAG( sps_scaling_matrix_for_lfnst_disabled_flag );
2210
12
    sps->setDisableScalingMatrixForLfnstBlks( sps_scaling_matrix_for_lfnst_disabled_flag );
2211
12
  }
2212
2213
294
  if( sps->getUseColorTrans() && sps_explicit_scaling_list_enabled_flag )
2214
8
  {
2215
8
    X_READ_FLAG( sps_scaling_matrix_for_alternative_colour_space_disabled_flag );
2216
8
    sps->setScalingMatrixForAlternativeColourSpaceDisabledFlag( sps_scaling_matrix_for_alternative_colour_space_disabled_flag );
2217
2218
8
    if( sps_scaling_matrix_for_alternative_colour_space_disabled_flag )
2219
6
    {
2220
6
      X_READ_FLAG( sps_scaling_matrix_designated_colour_space_flag );
2221
6
      sps->setScalingMatrixDesignatedColourSpaceFlag( sps_scaling_matrix_designated_colour_space_flag );
2222
6
    }
2223
8
  }
2224
2225
294
  X_READ_FLAG( sps_dep_quant_enabled_flag );
2226
294
  sps->setDepQuantEnabledFlag( sps_dep_quant_enabled_flag );
2227
2228
294
  X_READ_FLAG( sps_sign_data_hiding_enabled_flag );
2229
294
  sps->setSignDataHidingEnabledFlag( sps_sign_data_hiding_enabled_flag );
2230
2231
294
  X_READ_FLAG( sps_virtual_boundaries_enabled_flag );
2232
294
  CHECK_CONSTRAINT( gci->getNoVirtualBoundaryConstraintFlag() && sps_virtual_boundaries_enabled_flag,
2233
294
                    "When gci_no_virtual_boundaries_constraint_flag is equal to 1, sps_virtual_boundaries_enabled_flag shall be equal to 0" );
2234
294
  sps->setVirtualBoundariesEnabledFlag( sps_virtual_boundaries_enabled_flag );
2235
2236
294
  if( sps_virtual_boundaries_enabled_flag )
2237
24
  {
2238
24
    X_READ_FLAG( sps_virtual_boundaries_present_flag );
2239
24
    sps->setVirtualBoundariesPresentFlag( sps_virtual_boundaries_present_flag );
2240
2241
24
    if( sps_virtual_boundaries_present_flag )
2242
20
    {
2243
20
      X_READ_UVLC( sps_num_ver_virtual_boundaries, 0, sps_pic_width_max_in_luma_samples <= 8 ? 0 : 3 );
2244
20
      sps->setNumVerVirtualBoundaries( sps_num_ver_virtual_boundaries );
2245
2246
34
      for( unsigned i = 0; i < sps_num_ver_virtual_boundaries; i++ )
2247
14
      {
2248
14
        X_READ_UVLC_idx( sps_virtual_boundary_pos_x_minus1, "[i]", 0, ( sps_pic_width_max_in_luma_samples + 7 ) / 8 - 2 );
2249
14
        sps->setVirtualBoundariesPosX( ( sps_virtual_boundary_pos_x_minus1 + 1 ) << 3, i );
2250
14
      }
2251
2252
20
      X_READ_UVLC_idx( sps_num_hor_virtual_boundaries, "[i]", 0, sps_pic_height_max_in_luma_samples <= 8 ? 0 : 3  );
2253
20
      sps->setNumHorVirtualBoundaries( sps_num_hor_virtual_boundaries );
2254
2255
38
      for( unsigned i = 0; i <sps_num_hor_virtual_boundaries; i++ )
2256
18
      {
2257
18
        X_READ_UVLC_idx( sps_virtual_boundary_pos_y_minus1, "[i]", 0, ( sps_pic_height_max_in_luma_samples + 7 ) / 8 - 2 );
2258
18
        sps->setVirtualBoundariesPosY( (sps_virtual_boundary_pos_y_minus1 + 1) << 3, i );
2259
18
      }
2260
20
    }
2261
24
  }
2262
2263
294
  if( sps_ptl_dpb_hrd_params_present_flag )
2264
0
  {
2265
0
    X_READ_FLAG( sps_timing_hrd_params_present_flag );
2266
0
    sps->setGeneralHrdParametersPresentFlag( sps_timing_hrd_params_present_flag );
2267
2268
0
    if( sps_timing_hrd_params_present_flag )
2269
0
    {
2270
0
      parseGeneralHrdParameters( sps->getGeneralHrdParameters() );
2271
0
      if( sps_max_sublayers_minus1 > 0 )
2272
0
      {
2273
0
        X_READ_FLAG( sps_sublayer_cpb_params_present_flag );
2274
0
        sps->setSubLayerParametersPresentFlag( sps_sublayer_cpb_params_present_flag );
2275
0
      }
2276
2277
0
      uint32_t firstSubLayer = sps->getSubLayerParametersPresentFlag() ? 0 : sps_max_sublayers_minus1;
2278
0
      parseOlsHrdParameters( sps->getGeneralHrdParameters(), sps->getOlsHrdParameters(), firstSubLayer, sps_max_sublayers_minus1 );
2279
0
    }
2280
0
  }
2281
2282
294
  X_READ_FLAG( sps_field_seq_flag );
2283
294
  sps->setFieldSeqFlag( sps_field_seq_flag );
2284
2285
294
  CHECK_CONSTRAINT( sps->getProfileTierLevel()->getFrameOnlyConstraintFlag() && sps_field_seq_flag,
2286
288
                     "When ptl_frame_only_constraint_flag equal to 1 , the value of sps_field_seq_flag shall be equal to 0" );
2287
2288
288
  X_READ_FLAG( sps_vui_parameters_present_flag );
2289
288
  sps->setVuiParametersPresentFlag( sps_vui_parameters_present_flag );
2290
2291
288
  if( sps_vui_parameters_present_flag )
2292
60
  {
2293
60
    X_READ_UVLC( sps_vui_payload_size_minus1, 0, 1023 );
2294
60
    sps->setVuiPayloadSize( sps_vui_payload_size_minus1 + 1 );
2295
2296
218
    while( !isByteAligned() )
2297
162
    {
2298
162
      X_READ_FLAG( sps_vui_alignment_zero_bit );
2299
162
      CHECK( sps_vui_alignment_zero_bit, "sps_vui_alignment_zero_bit not equal to 0" );
2300
158
    }
2301
2302
56
    parseVUI( sps->getVuiParameters(), sps->getVuiPayloadSize() );
2303
56
  }
2304
2305
284
  X_READ_FLAG( sps_extension_present_flag );
2306
284
  if( sps_extension_present_flag )
2307
14
  {
2308
502
    while( xMoreRbspData() )
2309
488
    {
2310
488
      X_READ_FLAG( sps_extension_data_flag );
2311
488
      (void)sps_extension_data_flag;
2312
488
    }
2313
14
  }
2314
2315
284
  xReadRbspTrailingBits();
2316
284
}
2317
2318
void HLSyntaxReader::parseDCI( DCI* dci )
2319
36
{
2320
#if ENABLE_TRACING
2321
  xTraceDCIHeader();
2322
#endif
2323
36
  X_READ_CODE_NO_RANGE( dci_reserved_zero_4bits, 4 );
2324
36
  (void) dci_reserved_zero_4bits;
2325
2326
36
  X_READ_CODE( dci_num_ptls_minus1, 4, 0, 15 );
2327
36
  CHECK_WARN( dci_num_ptls_minus1 == 15, "reserved dci_num_ptls_minus1==15 used" );
2328
36
  const int numPTLs = dci_num_ptls_minus1 + 1;
2329
2330
36
  std::vector<ProfileTierLevel> ptls( numPTLs );
2331
90
  for( int i = 0; i < numPTLs; i++ )
2332
54
  {
2333
54
    parseProfileTierLevel( &ptls[i], true, 0 );
2334
54
  }
2335
36
  dci->setProfileTierLevel( std::move( ptls ) );
2336
2337
36
  X_READ_FLAG(dci_extension_flag );
2338
36
  if( dci_extension_flag )
2339
10
  {
2340
828
    while( xMoreRbspData() )
2341
818
    {
2342
818
      X_READ_FLAG( dci_extension_data_flag );
2343
818
      (void) dci_extension_data_flag;
2344
818
    }
2345
10
  }
2346
36
  xReadRbspTrailingBits();
2347
36
}
2348
2349
#if 0
2350
// We don't parse the VPS, because the needed bounds checks in parseVPS() are not yet implemented, and we don't process it anyways
2351
void HLSyntaxReader::parseVPS( VPS* pcVPS )
2352
{
2353
#if ENABLE_TRACING
2354
  xTraceVPSHeader();
2355
#endif
2356
  uint32_t  uiCode;
2357
2358
  //CHECK( true, "needs to be adjusted, e.g. sublayer and independent layer stuff -> see VTM-9.0" );
2359
2360
  READ_CODE( 4, uiCode, "vps_video_parameter_set_id" );                      pcVPS->setVPSId( uiCode );
2361
  CHECK( uiCode == 0, "vps_video_parameter_set_id equal to zero is reserved and shall not be used in a bitstream" );
2362
2363
  READ_CODE( 6, uiCode, "vps_max_layers_minus1" );                           pcVPS->setMaxLayers( uiCode + 1 );
2364
  CHECK( uiCode + 1 > MAX_VPS_LAYERS, "Signalled number of layers larger than MAX_VPS_LAYERS." );
2365
2366
  if( pcVPS->getMaxLayers() - 1 == 0 )
2367
  {
2368
    pcVPS->setEachLayerIsAnOlsFlag( 1 );
2369
  }
2370
  READ_CODE( 3, uiCode, "vps_max_sublayers_minus1" );                        pcVPS->setMaxSubLayers( uiCode + 1 );
2371
  CHECK( uiCode + 1 > MAX_VPS_SUBLAYERS, "Signalled number of sublayers larger than MAX_VPS_SUBLAYERS." );
2372
2373
  if( pcVPS->getMaxLayers() > 1 && pcVPS->getMaxSubLayers() > 1 )
2374
  {
2375
    READ_FLAG( uiCode, "vps_default_ptl_dpb_hrd_max_tid_flag" );             pcVPS->setAllLayersSameNumSublayersFlag( uiCode );
2376
  }
2377
  else
2378
  {
2379
    pcVPS->setAllLayersSameNumSublayersFlag( 1 );
2380
  }
2381
  if( pcVPS->getMaxLayers() > 1 )
2382
  {
2383
    READ_FLAG( uiCode, "vps_all_independent_layers_flag" );                  pcVPS->setAllIndependentLayersFlag( uiCode );
2384
    if( pcVPS->getAllIndependentLayersFlag() == 0 )
2385
    {
2386
      pcVPS->setEachLayerIsAnOlsFlag( 0 );
2387
    }
2388
  }
2389
  for( uint32_t i = 0; i < pcVPS->getMaxLayers(); i++ )
2390
  {
2391
    READ_CODE( 6, uiCode, "vps_layer_id[i]" );                             pcVPS->setLayerId( i, uiCode );
2392
    pcVPS->setGeneralLayerIdx( uiCode, i );
2393
2394
    if( i > 0 && !pcVPS->getAllIndependentLayersFlag() )
2395
    {
2396
      READ_FLAG( uiCode, "vps_independent_layer_flag[i]" );                pcVPS->setIndependentLayerFlag( i, uiCode );
2397
      if( !pcVPS->getIndependentLayerFlag( i ) )
2398
      {
2399
        READ_FLAG( uiCode, "vps_max_tid_ref_present_flag[i]" );
2400
        bool vpsMaxTidRefPresentFlag = ( uiCode == 1 );
2401
2402
        uint16_t sumUiCode = 0;
2403
        for( int j = 0, k = 0; j < i; j++ )
2404
        {
2405
          READ_FLAG( uiCode, "vps_direct_ref_layer_flag[ i ][ j ]" );        pcVPS->setDirectRefLayerFlag( i, j, uiCode );
2406
          if( uiCode )
2407
          {
2408
            pcVPS->setInterLayerRefIdc( i, j, k );
2409
            pcVPS->setDirectRefLayerIdx( i, k++, j );
2410
            sumUiCode++;
2411
            if( vpsMaxTidRefPresentFlag )
2412
            {
2413
              READ_CODE( 3, uiCode, "vps_max_tid_il_ref_pics_plus1[i][ j ]" );
2414
//              pcVPS->setMaxTidIlRefPicsPlus1( i, uiCode );
2415
            }
2416
          }
2417
        }
2418
        CHECK(sumUiCode == 0, "There has to be at least one value of j such that the value of vps_direct_dependency_flag[i][ j ] is equal to 1,when vps_independent_layer_flag[i] is equal to 0 " );
2419
//        if( uiCode )
2420
//        {
2421
//          READ_CODE( 3, uiCode, "max_tid_il_ref_pics_plus1[i]" ); pcVPS->setMaxTidIlRefPicsPlus1( i, uiCode );
2422
//        }
2423
//        else
2424
//        {
2425
//          pcVPS->setMaxTidIlRefPicsPlus1( i, 7) ;
2426
//        }
2427
      }
2428
    }
2429
  }
2430
2431
  if( pcVPS->getMaxLayers() > 1 )
2432
  {
2433
    if( pcVPS->getAllIndependentLayersFlag() )
2434
    {
2435
      READ_FLAG( uiCode, "vps_each_layer_is_an_ols_flag" );                  pcVPS->setEachLayerIsAnOlsFlag( uiCode );
2436
      if( pcVPS->getEachLayerIsAnOlsFlag() == 0 )
2437
      {
2438
        pcVPS->setOlsModeIdc( 2 );
2439
      }
2440
    }
2441
    if( !pcVPS->getEachLayerIsAnOlsFlag() )
2442
    {
2443
      if( !pcVPS->getAllIndependentLayersFlag() )
2444
      {
2445
        READ_CODE( 2, uiCode, "vps_ols_mode_idc" );                          pcVPS->setOlsModeIdc( uiCode );
2446
        CHECK( uiCode > MAX_VPS_OLS_MODE_IDC, "ols_mode_idc shall be in the rage of 0 to 2" );
2447
      }
2448
      if( pcVPS->getOlsModeIdc() == 2 )
2449
      {
2450
        READ_CODE( 8, uiCode, "vps_num_output_layer_sets_minus2" );          pcVPS->setNumOutputLayerSets( uiCode + 2 );
2451
        for( uint32_t i = 1; i <= pcVPS->getNumOutputLayerSets() - 1; i++ )
2452
        {
2453
          for( uint32_t j = 0; j < pcVPS->getMaxLayers(); j++ )
2454
          {
2455
            READ_FLAG( uiCode, "vps_ols_output_layer_flag[i][ j ]" );      pcVPS->setOlsOutputLayerFlag( i, j, uiCode );
2456
          }
2457
        }
2458
      }
2459
    }
2460
    READ_CODE( 8, uiCode, "vps_num_ptls_minus1" );                           pcVPS->setNumPtls( uiCode + 1 );
2461
  }
2462
  else
2463
  {
2464
    pcVPS->setNumPtls( 1 );
2465
  }
2466
2467
  pcVPS->deriveOutputLayerSets();
2468
  CHECK( uiCode >= pcVPS->getTotalNumOLSs(), "The value of vps_num_ptls_minus1 shall be less than TotalNumOlss" );
2469
2470
  std::vector<bool> isPTLReferred( pcVPS->getNumPtls(), false );
2471
  for( int i = 0; i < pcVPS->getNumPtls(); i++ )
2472
  {
2473
    if( i > 0 )
2474
    {
2475
      READ_FLAG( uiCode, "pt_present_flag[i]" );                           pcVPS->setPtPresentFlag( i, uiCode );
2476
    }
2477
    else
2478
    {
2479
       pcVPS->setPtPresentFlag( 0, 1 );
2480
    }
2481
2482
    if( !pcVPS->getAllLayersSameNumSublayersFlag() )
2483
    {
2484
      READ_CODE( 3, uiCode, "ptl_max_tid[i]" );                            pcVPS->setPtlMaxTemporalId( i, uiCode );
2485
    }
2486
    else
2487
    {
2488
      pcVPS->setPtlMaxTemporalId( i, pcVPS->getMaxSubLayers() - 1 );
2489
    }
2490
  }
2491
  int cnt = 0;
2492
  while( m_pcBitstream->getNumBitsUntilByteAligned() )
2493
  {
2494
    READ_FLAG( uiCode, "vps_ptl_reserved_zero_bit" );
2495
    CHECK( uiCode!=0, "Alignment bit is not '0'" );
2496
    cnt++;
2497
  }
2498
  CHECK( cnt >= 8, "Read more than '8' alignment bits" );
2499
  {
2500
    std::vector<ProfileTierLevel> ptls( pcVPS->getNumPtls() );
2501
    for( int i = 0; i < pcVPS->getNumPtls(); i++ )
2502
    {
2503
      parseProfileTierLevel( &ptls[i], pcVPS->getPtPresentFlag( i ), pcVPS->getPtlMaxTemporalId( i ) );
2504
    }
2505
    pcVPS->setProfileTierLevel( std::move( ptls ) );
2506
  }
2507
  for( int i = 0; i < pcVPS->getTotalNumOLSs(); i++ )
2508
  {
2509
    if( pcVPS->getNumPtls() > 1 && pcVPS->getNumPtls() != pcVPS->getTotalNumOLSs() )
2510
    {
2511
      READ_CODE( 8, uiCode, "vps_ols_ptl_idx[i]" );                        pcVPS->setOlsPtlIdx( i, uiCode );
2512
    }
2513
    else if( pcVPS->getNumPtls() == pcVPS->getTotalNumOLSs() )
2514
    {
2515
      pcVPS->setOlsPtlIdx( i, i );
2516
    }
2517
    else
2518
    {
2519
      pcVPS->setOlsPtlIdx( i, 0 );
2520
    }
2521
    isPTLReferred[pcVPS->getOlsPtlIdx( i )] = true;
2522
  }
2523
  for( int i = 0; i < pcVPS->getNumPtls(); i++ )
2524
  {
2525
    CHECK( !isPTLReferred[i],"Each profile_tier_level( ) syntax structure in the VPS shall be referred to by at least one value of vps_ols_ptl_idx[i] for i in the range of 0 to TotalNumOlss ? 1, inclusive" );
2526
  }
2527
2528
  if( !pcVPS->getEachLayerIsAnOlsFlag() )
2529
  {
2530
    READ_UVLC( uiCode, "vps_num_dpb_params_minus1" );                        pcVPS->m_numDpbParams = uiCode + 1;
2531
2532
    CHECK( pcVPS->m_numDpbParams > pcVPS->getNumMultiLayeredOlss(), "The value of vps_num_dpb_params_minus1 shall be in the range of 0 to NumMultiLayerOlss - 1, inclusive" );
2533
    std::vector<bool> isDPBParamReferred( pcVPS->m_numDpbParams, false );
2534
2535
    if( pcVPS->m_numDpbParams > 0 && pcVPS->getMaxSubLayers() > 1 )
2536
    {
2537
      READ_FLAG( uiCode, "vps_sublayer_dpb_params_present_flag" );           pcVPS->m_sublayerDpbParamsPresentFlag = uiCode;
2538
    }
2539
2540
    pcVPS->m_dpbParameters.resize( pcVPS->m_numDpbParams );
2541
2542
    for( int i = 0; i < pcVPS->m_numDpbParams; i++ )
2543
    {
2544
      if( !pcVPS->getAllLayersSameNumSublayersFlag() )
2545
      {
2546
        READ_CODE( 3, uiCode, "vps_dpb_max_tid[i]" );
2547
        pcVPS->m_dpbMaxTemporalId.push_back( uiCode );
2548
        CHECK( uiCode > ( pcVPS->getMaxSubLayers() - 1 ), "The value of vps_dpb_max_tid[i] shall be in the range of 0 to vps_max_sublayers_minus1, inclusive." )
2549
      }
2550
      else
2551
      {
2552
        pcVPS->m_dpbMaxTemporalId.push_back( pcVPS->getMaxSubLayers() - 1 );
2553
      }
2554
2555
      for( int j = ( pcVPS->m_sublayerDpbParamsPresentFlag ? 0 : pcVPS->m_dpbMaxTemporalId[i] ); j <= pcVPS->m_dpbMaxTemporalId[i]; j++ )
2556
      {
2557
        READ_UVLC( uiCode, "dpb_max_dec_pic_buffering_minus1[i]" );        pcVPS->m_dpbParameters[i].m_maxDecPicBuffering[j] = uiCode + 1;
2558
        READ_UVLC( uiCode, "dpb_max_num_reorder_pics[i]" );                pcVPS->m_dpbParameters[i].m_numReorderPics[j] = uiCode;
2559
        READ_UVLC( uiCode, "dpb_max_latency_increase_plus1[i]" );          pcVPS->m_dpbParameters[i].m_maxLatencyIncreasePlus1[j] = uiCode;
2560
      }
2561
2562
      for( int j = ( pcVPS->m_sublayerDpbParamsPresentFlag ? pcVPS->m_dpbMaxTemporalId[i] : 0 ); j < pcVPS->m_dpbMaxTemporalId[i]; j++ )
2563
      {
2564
        // When max_dec_pic_buffering_minus1[i] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_dec_pic_buffering_minus1[ maxSubLayersMinus1 ].
2565
        pcVPS->m_dpbParameters[i].m_maxDecPicBuffering[j] = pcVPS->m_dpbParameters[i].m_maxDecPicBuffering[pcVPS->m_dpbMaxTemporalId[i]];
2566
2567
        // When max_num_reorder_pics[i] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_num_reorder_pics[ maxSubLayersMinus1 ].
2568
        pcVPS->m_dpbParameters[i].m_numReorderPics[j] = pcVPS->m_dpbParameters[i].m_numReorderPics[pcVPS->m_dpbMaxTemporalId[i]];
2569
2570
        // When max_latency_increase_plus1[i] is not present for i in the range of 0 to maxSubLayersMinus1 - 1, inclusive, due to subLayerInfoFlag being equal to 0, it is inferred to be equal to max_latency_increase_plus1[ maxSubLayersMinus1 ].
2571
        pcVPS->m_dpbParameters[i].m_maxLatencyIncreasePlus1[j] = pcVPS->m_dpbParameters[i].m_maxLatencyIncreasePlus1[pcVPS->m_dpbMaxTemporalId[i]];
2572
      }
2573
    }
2574
2575
    for( int i = 0, j=0; i < pcVPS->getTotalNumOLSs(); i++ )
2576
    {
2577
      if( pcVPS->m_numLayersInOls[i] > 1 )
2578
      {
2579
        READ_UVLC( uiCode, "vps_ols_dpb_pic_width[i]" );                   pcVPS->setOlsDpbPicWidth( i, uiCode );
2580
        READ_UVLC( uiCode, "vps_ols_dpb_pic_height[i]" );                  pcVPS->setOlsDpbPicHeight( i, uiCode );
2581
        READ_CODE( 2, uiCode, "vps_ols_dpb_chroma_format[i]" );            pcVPS->setOlsDpbChromaFormatIdc( i, uiCode );
2582
        READ_UVLC( uiCode, "vps_ols_dpb_bitdepth_minus8[i]" );             pcVPS->setOlsDpbBitDepthMinus8( i, uiCode );
2583
        const Profile::Name profile = pcVPS->getProfileTierLevel( pcVPS->getOlsPtlIdx( i ) ).getProfileIdc();
2584
        if( profile != Profile::NONE )
2585
        {
2586
          CHECK( uiCode + 8 > ProfileFeatures::getProfileFeatures( profile )->maxBitDepth,
2587
                 "vps_ols_dpb_bitdepth_minus8[ i ] exceeds range supported by signalled profile" );
2588
        }
2589
        if( ( pcVPS->m_numDpbParams > 1 ) && ( pcVPS->m_numDpbParams != pcVPS->m_numMultiLayeredOlss) )
2590
        {
2591
          READ_UVLC( uiCode, "vps_ols_dpb_params_idx[i]" );                pcVPS->setOlsDpbParamsIdx( i, uiCode );
2592
        }
2593
        else if( pcVPS->m_numDpbParams == 1 )
2594
        {
2595
          pcVPS->setOlsDpbParamsIdx( i, 0 );
2596
        }
2597
        else
2598
        {
2599
          pcVPS->setOlsDpbParamsIdx( i, j );
2600
        }
2601
        j += 1;
2602
        isDPBParamReferred[pcVPS->getOlsDpbParamsIdx( i )] = true;
2603
      }
2604
    }
2605
    for( int i = 0; i < pcVPS->m_numDpbParams; i++ )
2606
    {
2607
      CHECK( !isDPBParamReferred[i], "Each dpb_parameters() syntax structure in the VPS shall be referred to by at least one value of vps_ols_dpb_params_idx[i] for i in the range of 0 to NumMultiLayerOlss - 1, inclusive" );
2608
    }
2609
  }
2610
2611
  if( !pcVPS->getEachLayerIsAnOlsFlag() )
2612
  {
2613
    READ_FLAG( uiCode, "vps_general_hrd_params_present_flag" );              pcVPS->setVPSGeneralHrdParamsPresentFlag( uiCode );
2614
  }
2615
  if( pcVPS->getVPSGeneralHrdParamsPresentFlag() )
2616
  {
2617
    parseGeneralHrdParameters( pcVPS->getGeneralHrdParameters() );
2618
    if( ( pcVPS->getMaxSubLayers() - 1 ) > 0 )
2619
    {
2620
      READ_FLAG( uiCode, "vps_sublayer_cpb_params_present_flag" );           pcVPS->setVPSSublayerCpbParamsPresentFlag( uiCode );
2621
    }
2622
    else
2623
    {
2624
      pcVPS->setVPSSublayerCpbParamsPresentFlag( 0 );
2625
    }
2626
2627
    READ_UVLC( uiCode, "vps_num_ols_hrd_params_minus1" );                    pcVPS->setNumOlsHrdParamsMinus1( uiCode );
2628
    CHECK( uiCode >= pcVPS->getNumMultiLayeredOlss(), "The value of vps_num_ols_hrd_params_minus1 shall be in the range of 0 to NumMultiLayerOlss - 1, inclusive" );
2629
    std::vector<bool> isHRDParamReferred( uiCode + 1, false );
2630
    pcVPS->m_olsHrdParams.clear();
2631
    pcVPS->m_olsHrdParams.resize( pcVPS->getNumOlsHrdParamsMinus1() + 1, std::vector<OlsHrdParams>( pcVPS->getMaxSubLayers() ) );
2632
    for( int i = 0; i <= pcVPS->getNumOlsHrdParamsMinus1(); i++ )
2633
    {
2634
      if( !pcVPS->getAllLayersSameNumSublayersFlag() )
2635
      {
2636
        READ_CODE( 3, uiCode, "vps_hrd_max_tid[i]" );                      pcVPS->setHrdMaxTid(i, uiCode );
2637
        CHECK( uiCode > ( pcVPS->getMaxSubLayers() - 1 ), "The value of vps_hrd_max_tid[i] shall be in the range of 0 to vps_max_sublayers_minus1, inclusive." );
2638
      }
2639
      else
2640
      {
2641
        pcVPS->setHrdMaxTid( i, pcVPS->getMaxSubLayers() - 1 );
2642
      }
2643
      uint32_t firstSublayer = pcVPS->getVPSSublayerCpbParamsPresentFlag() ? 0 : pcVPS->getHrdMaxTid( i );
2644
      parseOlsHrdParameters( pcVPS->getGeneralHrdParameters(), pcVPS->getOlsHrdParameters( i ), firstSublayer, pcVPS->getHrdMaxTid( i ) );
2645
    }
2646
    for( int i = pcVPS->getNumOlsHrdParamsMinus1() + 1; i < pcVPS->getTotalNumOLSs(); i++ )
2647
    {
2648
      pcVPS->setHrdMaxTid( i, pcVPS->getMaxSubLayers() - 1 );
2649
    }
2650
    for( int i = 0; i < pcVPS->m_numMultiLayeredOlss; i++ )
2651
    {
2652
      if( ( ( pcVPS->getNumOlsHrdParamsMinus1() + 1 ) != pcVPS->m_numMultiLayeredOlss ) && ( pcVPS->getNumOlsHrdParamsMinus1() > 0 ) )
2653
      {
2654
        READ_UVLC( uiCode, "vps_ols_hrd_idx[i]" );                         pcVPS->setOlsHrdIdx( i, uiCode );
2655
        CHECK( uiCode > pcVPS->getNumOlsHrdParamsMinus1(), "The value of ols_hrd_idx[[i] shall be in the range of 0 to num_ols_hrd_params_minus1, inclusive." );
2656
      }
2657
      else if( pcVPS->getNumOlsHrdParamsMinus1() == 0 )
2658
      {
2659
        pcVPS->setOlsHrdIdx( i, 0 );
2660
      }
2661
      else
2662
      {
2663
        pcVPS->setOlsHrdIdx( i, i );
2664
      }
2665
      isHRDParamReferred[pcVPS->getOlsHrdIdx( i )] = true;
2666
    }
2667
    for( int i = 0; i <= pcVPS->getNumOlsHrdParamsMinus1(); i++ )
2668
    {
2669
      CHECK( !isHRDParamReferred[i], "Each ols_hrd_parameters( ) syntax structure in the VPS shall be referred to by at least one value of vps_ols_hrd_idx[i] for i in the range of 1 to NumMultiLayerOlss - 1, inclusive");
2670
    }
2671
  }
2672
  else
2673
  {
2674
    for( int i = 0; i < pcVPS->getTotalNumOLSs(); i++ )
2675
    {
2676
      pcVPS->setHrdMaxTid( i, pcVPS->getMaxSubLayers() - 1 );
2677
    }
2678
  }
2679
2680
2681
  READ_FLAG( uiCode, "vps_extension_flag" );
2682
  if( uiCode )
2683
  {
2684
    while( xMoreRbspData() )
2685
    {
2686
      READ_FLAG( uiCode, "vps_extension_data_flag" );
2687
    }
2688
  }
2689
  pcVPS->checkVPS();
2690
  xReadRbspTrailingBits();
2691
}
2692
#endif
2693
2694
void HLSyntaxReader::parsePictureHeader( PicHeader* picHeader, const ParameterSetManager *parameterSetManager, bool readRbspTrailingBits )
2695
10
{
2696
#if ENABLE_TRACING
2697
  xTracePictureHeader();
2698
#endif
2699
2700
10
  X_READ_FLAG( ph_gdr_or_irap_pic_flag );
2701
10
  picHeader->setGdrOrIrapPicFlag( ph_gdr_or_irap_pic_flag );
2702
2703
10
  X_READ_FLAG( ph_non_ref_pic_flag );
2704
10
  picHeader->setNonReferencePictureFlag( ph_non_ref_pic_flag );
2705
2706
10
  if( picHeader->getGdrOrIrapPicFlag() )
2707
8
  {
2708
8
    X_READ_FLAG( ph_gdr_pic_flag );
2709
8
    picHeader->setGdrPicFlag( ph_gdr_pic_flag );
2710
8
  }
2711
2712
10
  X_READ_FLAG( ph_inter_slice_allowed_flag );
2713
10
  picHeader->setPicInterSliceAllowedFlag( ph_inter_slice_allowed_flag );
2714
2715
10
  if( ph_inter_slice_allowed_flag )
2716
4
  {
2717
4
    X_READ_FLAG( ph_intra_slice_allowed_flag );
2718
4
    picHeader->setPicIntraSliceAllowedFlag( ph_intra_slice_allowed_flag );
2719
4
  }
2720
10
  CHECK( picHeader->getPicInterSliceAllowedFlag() == 0 && picHeader->getPicIntraSliceAllowedFlag() == 0,
2721
10
                     "Invalid picture without intra or inter slice" );
2722
2723
  // parameter sets
2724
10
  X_READ_UVLC( ph_pic_parameter_set_id, 0, 63 );
2725
10
  picHeader->setPPSId( ph_pic_parameter_set_id );
2726
2727
10
  const PPS* pps = parameterSetManager->getPPS( picHeader->getPPSId() );
2728
10
  CHECK( !pps, "Invalid PPS" );
2729
2730
10
  picHeader->setSPSId( pps->getSPSId() );
2731
10
  const SPS* sps = parameterSetManager->getSPS( picHeader->getSPSId() );
2732
10
  CHECK( !sps, "Invalid SPS" );
2733
2734
10
  const unsigned CtbSizeY          = sps->getCTUSize();
2735
10
  const unsigned CtbLog2SizeY      = getLog2( CtbSizeY );
2736
10
  const unsigned MinCbLog2SizeY    = sps->getLog2MinCodingBlockSize();
2737
10
  const unsigned MaxPicOrderCntLsb = 1 << sps->getBitsForPOC();
2738
2739
10
  X_READ_CODE_NO_RANGE( ph_pic_order_cnt_lsb, sps->getBitsForPOC() );
2740
10
  picHeader->setPocLsb( ph_pic_order_cnt_lsb );
2741
2742
10
  if( picHeader->getGdrPicFlag() )
2743
0
  {
2744
0
    X_READ_UVLC( ph_recovery_poc_cnt, 0, MaxPicOrderCntLsb );
2745
0
    picHeader->setRecoveryPocCnt( ph_recovery_poc_cnt );
2746
0
  }
2747
10
  else
2748
10
  {
2749
10
    picHeader->setRecoveryPocCnt( -1 );
2750
10
  }
2751
2752
10
  const std::vector<bool>& phExtraBitsPresent = sps->getExtraPHBitPresentFlags();
2753
10
  for( int i = 0; i < sps->getNumExtraPHBitsBytes() * 8; i++ )
2754
0
  {
2755
    // extra bits are ignored (when present)
2756
0
    if( phExtraBitsPresent[i] )
2757
0
    {
2758
0
      X_READ_FLAG_idx( ph_extra_bit, "[i]" );
2759
0
      (void) ph_extra_bit;
2760
0
    }
2761
0
  }
2762
2763
10
  if( sps->getPocMsbFlag() )
2764
0
  {
2765
0
    X_READ_FLAG( ph_poc_msb_cycle_present_flag );
2766
0
    picHeader->setPocMsbPresentFlag( ph_poc_msb_cycle_present_flag );
2767
2768
0
    if( ph_poc_msb_cycle_present_flag )
2769
0
    {
2770
0
      X_READ_CODE_NO_RANGE( ph_poc_msb_cycle_val, sps->getPocMsbLen() );
2771
0
      picHeader->setPocMsbVal( ph_poc_msb_cycle_val );
2772
0
    }
2773
0
  }
2774
2775
  // alf enable flags and aps IDs
2776
10
  if( sps->getUseALF() && pps->getAlfInfoInPhFlag() )
2777
0
  {
2778
0
    X_READ_FLAG( ph_alf_enabled_flag );
2779
0
    picHeader->setAlfEnabledFlag( COMPONENT_Y, ph_alf_enabled_flag );
2780
2781
0
    if( ph_alf_enabled_flag )
2782
0
    {
2783
0
      X_READ_CODE( ph_num_alf_aps_ids_luma, 3, 0, MAX_NUM_ALF_APS_IDS );
2784
0
      picHeader->setNumAlfAps( ph_num_alf_aps_ids_luma );
2785
2786
      // auto* alfAPSs = parameterSetManager->getAlfAPSs();
2787
2788
0
      AlfApsIdVec apsId( ph_num_alf_aps_ids_luma, -1 );
2789
0
      for( int i = 0; i < ph_num_alf_aps_ids_luma; i++ )
2790
0
      {
2791
0
        X_READ_CODE_NO_RANGE_idx( ph_alf_aps_id_luma, "[i]", 3 );
2792
0
        apsId[i] = ph_alf_aps_id_luma;
2793
2794
        // auto* alfAPS = parameterSetManager->getAPS( ALF_APS, ph_alf_aps_id_luma );
2795
        // CHECK( !alfAPS, "ALF APS with ph_alf_aps_id_luma == " << ph_alf_aps_id_luma << " not available.");
2796
        // CHECK( alfAPS->getAlfAPSParam().newFilterFlag[CHANNEL_TYPE_LUMA] != 1,
2797
        //        "The value of alf_luma_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS "
2798
        //        " and aps_adaptation_parameter_set_id equal to ph_alf_aps_id_luma[ i ] shall be equal to 1." );
2799
        // /*CHECK( parameterSetManager->getAPS( ALF_APS, ph_alf_aps_id_luma )->getTemporalId() > todo: don't know curr temp ID
2800
        //        "The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and aps_adaptation_parameter_set_id"
2801
        //        " equal to ph_alf_aps_id_luma[ i ] shall be less than or equal to the TemporalId of the current picture." );*/
2802
        // CHECK( sps->getChromaFormatIdc() == 0 && alfAPS->chromaPresentFlag != 0,
2803
        //        "When sps_chroma_format_idc is equal to 0, the value of aps_chroma_present_flag of the APS NAL unit having aps_params_type"
2804
        //        " equal to ALF_APS and aps_adaptation_parameter_set_id equal to ph_alf_aps_id_luma[ i ] shall be equal to 0." );
2805
        // CHECK( sps->getUseCCALF() == 0
2806
        //          && ( alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cb - 1] != 0 || alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cr - 1] != 0 ),
2807
        //        "When sps_ccalf_enabled_flag is equal to 0, the values of alf_cc_cb_filter_signal_flag and alf_cc_cr_filter_signal_flag of the APS NAL unit "
2808
        //        " having aps_params_type equal to ALF_APS and aps_adaptation_parameter_set_id equal to ph_alf_aps_id_luma[ i ] shall be equal to 0." );
2809
0
      }
2810
0
      picHeader->setAlfAPSIds( apsId );
2811
2812
0
      if( sps->getChromaFormatIdc() != CHROMA_400 )
2813
0
      {
2814
0
        X_READ_FLAG( ph_alf_cb_enabled_flag );
2815
0
        picHeader->setAlfEnabledFlag( COMPONENT_Cb, ph_alf_cb_enabled_flag );
2816
2817
0
        X_READ_FLAG( ph_alf_cr_enabled_flag );
2818
0
        picHeader->setAlfEnabledFlag( COMPONENT_Cr, ph_alf_cr_enabled_flag );
2819
0
      }
2820
2821
0
      if( picHeader->getAlfEnabledFlag( COMPONENT_Cb ) || picHeader->getAlfEnabledFlag( COMPONENT_Cr ) )
2822
0
      {
2823
0
        X_READ_CODE_NO_RANGE( ph_alf_aps_id_chroma, 3 );
2824
0
        picHeader->setAlfApsIdChroma( ph_alf_aps_id_chroma );
2825
2826
        // auto* alfAPS = parameterSetManager->getAPS( ALF_APS, ph_alf_aps_id_chroma );
2827
        // CHECK( !alfAPS, "ALF APS with ph_alf_aps_id_chroma == " << ph_alf_aps_id_chroma << " not available.");
2828
2829
        // CHECK( alfAPS->getCcAlfAPSParam().newCcAlfFilter[CHANNEL_TYPE_CHROMA] != 1,
2830
        //        "The value of alf_chroma_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and"
2831
        //        " aps_adaptation_parameter_set_id equal to ph_alf_aps_id_chroma shall be equal to 1." );
2832
        // // The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and
2833
        // // aps_adaptation_parameter_set_id equal to ph_alf_aps_id_chroma shall be less than or equal to the TemporalId of the
2834
        // // current picture.
2835
2836
        // CHECK( sps->getUseCCALF() == 0
2837
        //          && ( alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cb - 1] != 0 || alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cr - 1] != 0 ),
2838
        //        "When sps_ccalf_enabled_flag is equal to 0, the values of alf_cc_cb_filter_signal_flag and alf_cc_cr_filter_signal_flag of the APS NAL unit "
2839
        //        " having aps_params_type equal to ALF_APS and aps_adaptation_parameter_set_id equal to ph_alf_aps_id_chroma shall be equal to 0." );
2840
0
      }
2841
2842
0
      if( sps->getUseCCALF() )
2843
0
      {
2844
0
        X_READ_FLAG( ph_alf_cc_cb_enabled_flag );
2845
0
        picHeader->setCcAlfEnabledFlag( COMPONENT_Cb, ph_alf_cc_cb_enabled_flag );
2846
2847
0
        if( ph_alf_cc_cb_enabled_flag )
2848
0
        {
2849
0
          X_READ_CODE_NO_RANGE( ph_alf_cc_cb_aps_id, 3 );
2850
0
          picHeader->setCcAlfCbApsId( ph_alf_cc_cb_aps_id );
2851
2852
          // auto* alfAPS = parameterSetManager->getAPS( ALF_APS, ph_alf_cc_cb_aps_id );
2853
          // CHECK( !alfAPS, "ALF APS with ph_alf_cc_cb_aps_id == " << ph_alf_cc_cb_aps_id << " not available.");
2854
          // CHECK( alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cb - 1] != 1,
2855
          //        "The value of alf_cc_cb_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and"
2856
          //        " aps_adaptation_parameter_set_id equal to ph_alf_cc_cb_aps_id shall be equal to 1." );
2857
          // // The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and
2858
          // // aps_adaptation_parameter_set_id equal to ph_alf_cc_cb_aps_id shall be less than or equal to the TemporalId of the
2859
          // // current picture.
2860
0
        }
2861
2862
0
        X_READ_FLAG( ph_alf_cc_cr_enabled_flag );
2863
0
        picHeader->setCcAlfEnabledFlag( COMPONENT_Cr, ph_alf_cc_cr_enabled_flag );
2864
2865
0
        if( ph_alf_cc_cr_enabled_flag )
2866
0
        {
2867
0
          X_READ_CODE_NO_RANGE( ph_alf_cc_cr_aps_id, 3 );
2868
0
          picHeader->setCcAlfCrApsId( ph_alf_cc_cr_aps_id );
2869
2870
          // auto* alfAPS = parameterSetManager->getAPS( ALF_APS, ph_alf_cc_cr_aps_id );
2871
          // CHECK( !alfAPS, "ALF APS with ph_alf_cc_cr_aps_id == " << ph_alf_cc_cr_aps_id << " not available." );
2872
          // CHECK( alfAPS->getCcAlfAPSParam().newCcAlfFilter[COMPONENT_Cr - 1] != 1,
2873
          //        "The value of alf_cc_cr_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and"
2874
          //        " aps_adaptation_parameter_set_id equal to ph_alf_cc_cr_aps_id shall be equal to 1." );
2875
          // // The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and
2876
          // // aps_adaptation_parameter_set_id equal to ph_alf_cc_cr_aps_id shall be less than or equal to the TemporalId of the
2877
          // // current picture.
2878
0
        }
2879
0
      }
2880
0
    }   // if( ph_alf_enabled_flag )
2881
0
  }     // if( sps->getUseALF() && pps->getAlfInfoInPhFlag() )
2882
2883
  // luma mapping / chroma scaling controls
2884
10
  if( sps->getUseReshaper() )
2885
0
  {
2886
0
    X_READ_FLAG( ph_lmcs_enabled_flag );
2887
0
    picHeader->setLmcsEnabledFlag( ph_lmcs_enabled_flag );
2888
2889
0
    if( ph_lmcs_enabled_flag )
2890
0
    {
2891
0
      X_READ_CODE_NO_RANGE( ph_lmcs_aps_id, 2 );
2892
0
      picHeader->setLmcsAPSId( ph_lmcs_aps_id );
2893
2894
0
      if( sps->getChromaFormatIdc() != CHROMA_400 )
2895
0
      {
2896
0
        X_READ_FLAG( ph_chroma_residual_scale_flag );
2897
0
        picHeader->setLmcsChromaResidualScaleFlag( ph_chroma_residual_scale_flag );
2898
0
      }
2899
0
    }
2900
0
  }
2901
2902
  // quantization scaling lists
2903
10
  if( sps->getScalingListFlag() )
2904
0
  {
2905
0
    X_READ_FLAG( ph_explicit_scaling_list_enabled_flag );
2906
0
    picHeader->setExplicitScalingListEnabledFlag( ph_explicit_scaling_list_enabled_flag );
2907
2908
0
    if( ph_explicit_scaling_list_enabled_flag )
2909
0
    {
2910
0
      X_READ_CODE_NO_RANGE( ph_scaling_list_aps_id, 3 );
2911
0
      picHeader->setScalingListAPSId( ph_scaling_list_aps_id );
2912
0
    }
2913
0
  }
2914
2915
  // virtual boundaries
2916
10
  if( sps->getVirtualBoundariesEnabledFlag() && !sps->getVirtualBoundariesPresentFlag() )
2917
0
  {
2918
0
    X_READ_FLAG( ph_virtual_boundaries_present_flag );
2919
0
    picHeader->setVirtualBoundariesPresentFlag( ph_virtual_boundaries_present_flag );
2920
2921
0
    if( ph_virtual_boundaries_present_flag )
2922
0
    {
2923
0
      X_READ_UVLC( ph_num_ver_virtual_boundaries, 0, pps->getPicWidthInLumaSamples() <= 8 ? 0 : 3 );
2924
0
      picHeader->setNumVerVirtualBoundaries( ph_num_ver_virtual_boundaries );
2925
2926
0
      for( unsigned i = 0, prevBoundPos = 0; i < ph_num_ver_virtual_boundaries; i++ )
2927
0
      {
2928
0
        X_READ_UVLC_idx( ph_virtual_boundary_pos_x_minus1, "[ i ]", 0, ( pps->getPicWidthInLumaSamples() + 7 ) / 8 - 2 );
2929
2930
0
        const unsigned virtBoundPosX = ( ph_virtual_boundary_pos_x_minus1 + 1 ) << 3;
2931
0
        CHECK( i > 0 && virtBoundPosX < prevBoundPos + CtbSizeY,
2932
0
               "The distance between any two vertical virtual boundaries shall be greater than or equal to CtbSizeY luma samples." );
2933
0
        picHeader->setVirtualBoundariesPosX( virtBoundPosX, i );
2934
2935
0
        prevBoundPos = virtBoundPosX;
2936
0
      }
2937
2938
0
      X_READ_UVLC( ph_num_hor_virtual_boundaries, 0, pps->getPicHeightInLumaSamples() <= 8 ? 0 : 3 );
2939
0
      picHeader->setNumHorVirtualBoundaries( ph_num_hor_virtual_boundaries );
2940
2941
0
      for( unsigned i = 0, prevBoundPos = 0; i < ph_num_hor_virtual_boundaries; i++ )
2942
0
      {
2943
0
        X_READ_UVLC_idx( ph_virtual_boundary_pos_y_minus1, "[ i ]", 0, ( pps->getPicHeightInLumaSamples() + 7 ) / 8 - 2 );
2944
2945
0
        const unsigned virtBoundPosY = ( ph_virtual_boundary_pos_y_minus1 + 1 ) << 3;
2946
0
        CHECK( i > 0 && virtBoundPosY < prevBoundPos + CtbSizeY,
2947
0
               "The distance between any two horizontal virtual boundaries shall be greater than or equal to CtbSizeY luma samples." );
2948
0
        picHeader->setVirtualBoundariesPosY( virtBoundPosY, i );
2949
2950
0
        prevBoundPos = virtBoundPosY;
2951
0
      }
2952
0
      CHECK( ph_num_ver_virtual_boundaries + ph_num_hor_virtual_boundaries <= 0,
2953
0
             "When sps_virtual_boundaries_enabled_flag is equal to 1 and ph_virtual_boundaries_present_flag is equal to 1, the sum"
2954
0
             " of ph_num_ver_virtual_boundaries and ph_num_hor_virtual_boundaries shall be greater than 0." );
2955
0
    }
2956
0
  }
2957
10
  else if( sps->getVirtualBoundariesPresentFlag() )
2958
0
  {
2959
0
    picHeader->setVirtualBoundariesPresentFlag( true );
2960
0
    picHeader->setNumVerVirtualBoundaries( sps->getNumVerVirtualBoundaries() );
2961
0
    picHeader->setNumHorVirtualBoundaries( sps->getNumHorVirtualBoundaries() );
2962
2963
0
    for( unsigned i = 0, prevBoundPosX = 0, prevBoundPosY = 0; i < 3; i++ )
2964
0
    {
2965
0
      picHeader->setVirtualBoundariesPosX( sps->getVirtualBoundariesPosX( i ), i );
2966
0
      picHeader->setVirtualBoundariesPosY( sps->getVirtualBoundariesPosY( i ), i );
2967
2968
0
      CHECK( i > 0 && i < picHeader->getNumVerVirtualBoundaries() && picHeader->getVirtualBoundariesPosX( i ) < prevBoundPosX + CtbSizeY,
2969
0
             "The distance between any two vertical virtual boundaries shall be greater than or equal to CtbSizeY luma samples." );
2970
0
      CHECK( i > 0 && i < picHeader->getNumHorVirtualBoundaries() && picHeader->getVirtualBoundariesPosY( i ) < prevBoundPosY + CtbSizeY,
2971
0
             "The distance between any two horizontal virtual boundaries shall be greater than or equal to CtbSizeY luma samples." );
2972
2973
0
      prevBoundPosX = picHeader->getVirtualBoundariesPosX( i );
2974
0
      prevBoundPosY = picHeader->getVirtualBoundariesPosY( i );
2975
0
    }
2976
0
  }
2977
2978
  // picture output flag
2979
10
  if( pps->getOutputFlagPresentFlag() && !picHeader->getNonReferencePictureFlag() )
2980
0
  {
2981
0
    X_READ_FLAG( ph_pic_output_flag );
2982
0
    picHeader->setPicOutputFlag( ph_pic_output_flag);
2983
0
  }
2984
2985
  // reference picture lists
2986
10
  if( pps->getRplInfoInPhFlag() )
2987
0
  {
2988
0
    parsePicOrSliceHeaderRPL( picHeader, sps, pps );
2989
0
  }
2990
2991
  // partitioning constraint overrides
2992
10
  if( sps->getSplitConsOverrideEnabledFlag() )
2993
0
  {
2994
0
    X_READ_FLAG( ph_partition_constraints_override_flag );
2995
0
    picHeader->setSplitConsOverrideFlag( ph_partition_constraints_override_flag );
2996
0
  }
2997
2998
  // inherit constraint values from SPS
2999
10
  PartitionConstraints minQT     = sps->getMinQTSizes();
3000
10
  PartitionConstraints maxBTD    = sps->getMaxMTTHierarchyDepths();
3001
10
  PartitionConstraints maxBTSize = sps->getMaxBTSizes();
3002
10
  PartitionConstraints maxTTSize = sps->getMaxTTSizes();
3003
3004
10
  if( picHeader->getPicIntraSliceAllowedFlag() )
3005
0
  {
3006
0
    unsigned MinQtLog2SizeIntraY = getLog2( minQT[0] );
3007
0
    if( picHeader->getSplitConsOverrideFlag() )
3008
0
    {
3009
0
      X_READ_UVLC( ph_log2_diff_min_qt_min_cb_intra_slice_luma, 0, std::min( 6u, CtbLog2SizeY ) - MinCbLog2SizeY );
3010
0
      MinQtLog2SizeIntraY = ph_log2_diff_min_qt_min_cb_intra_slice_luma + MinCbLog2SizeY;
3011
0
      minQT[0] = 1 << MinQtLog2SizeIntraY;
3012
3013
0
      X_READ_UVLC( ph_max_mtt_hierarchy_depth_intra_slice_luma, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) );
3014
0
      maxBTD[0] = ph_max_mtt_hierarchy_depth_intra_slice_luma;
3015
      // TODO: When not present, the value of ph_max_mtt_hierarchy_depth_intra_slice_luma is inferred to be equal to sps_max_mtt_hierarchy_depth_intra_slice_luma.
3016
3017
0
      maxTTSize[0] = maxBTSize[0] = minQT[0];
3018
0
      if( maxBTD[0] != 0 )
3019
0
      {
3020
0
        X_READ_UVLC( ph_log2_diff_max_bt_min_qt_intra_slice_luma,
3021
0
                     0, ( sps->getUseDualITree() ? std::min( 6u, CtbLog2SizeY ) : CtbLog2SizeY ) - MinQtLog2SizeIntraY );
3022
0
        maxBTSize[0] <<= ph_log2_diff_max_bt_min_qt_intra_slice_luma;
3023
        // TODO: When not present, the value of ph_log2_diff_max_bt_min_qt_intra_slice_luma is inferred to be equal to
3024
        //       sps_log2_diff_max_bt_min_qt_intra_slice_luma.
3025
3026
0
        X_READ_UVLC( ph_log2_diff_max_tt_min_qt_intra_slice_luma, 0, std::min( 6u, CtbLog2SizeY ) - MinQtLog2SizeIntraY );
3027
0
        maxTTSize[0] <<= ph_log2_diff_max_tt_min_qt_intra_slice_luma;
3028
        // TODO: When not present, the value of ph_log2_diff_max_tt_min_qt_intra_slice_luma is inferred to be equal to
3029
        //       sps_log2_diff_max_tt_min_qt_intra_slice_luma.
3030
0
      }
3031
0
      if( sps->getUseDualITree() )
3032
0
      {
3033
0
        X_READ_UVLC( ph_log2_diff_min_qt_min_cb_intra_slice_chroma, 0, std::min( 6u, CtbLog2SizeY ) - MinCbLog2SizeY );
3034
0
        unsigned MinQtLog2SizeIntraC = ph_log2_diff_min_qt_min_cb_intra_slice_chroma + MinCbLog2SizeY;
3035
0
        minQT[2] = 1 << MinQtLog2SizeIntraC;
3036
        // TODO: When not present, the value of ph_log2_diff_min_qt_min_cb_intra_slice_chroma is inferred to be equal to
3037
        //       sps_log2_diff_min_qt_min_cb_intra_slice_chroma.
3038
3039
0
        X_READ_UVLC( ph_max_mtt_hierarchy_depth_intra_slice_chroma, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) );
3040
0
        maxBTD[2]    = ph_max_mtt_hierarchy_depth_intra_slice_chroma;
3041
        // TODO: When not present, the value of ph_max_mtt_hierarchy_depth_intra_slice_chroma is inferred to be equal to
3042
        //       sps_max_mtt_hierarchy_depth_intra_slice_chroma.
3043
3044
0
        maxTTSize[2] = maxBTSize[2] = minQT[2];
3045
0
        if( ph_max_mtt_hierarchy_depth_intra_slice_chroma )
3046
0
        {
3047
0
          X_READ_UVLC( ph_log2_diff_max_bt_min_qt_intra_slice_chroma, 0, std::min( 6u, CtbLog2SizeY ) - MinQtLog2SizeIntraC );
3048
0
          maxBTSize[2] <<= ph_log2_diff_max_bt_min_qt_intra_slice_chroma;
3049
          // TODO: When not present, the value of ph_log2_diff_max_bt_min_qt_intra_slice_chroma is inferred to be equal to
3050
          //       sps_log2_diff_max_bt_min_qt_intra_slice_chroma.
3051
3052
0
          X_READ_UVLC( ph_log2_diff_max_tt_min_qt_intra_slice_chroma, 0, std::min( 6u, CtbLog2SizeY ) - MinQtLog2SizeIntraC );
3053
0
          maxTTSize[2] <<= ph_log2_diff_max_tt_min_qt_intra_slice_chroma;
3054
          // TODO: When not present, the value of ph_log2_diff_max_tt_min_qt_intra_slice_chroma is inferred to be equal to
3055
          //       sps_log2_diff_max_tt_min_qt_intra_slice_chroma.
3056
0
        }
3057
0
      }   // if( sps->getUseDualITree() )
3058
0
    }     // if( picHeader->getSplitConsOverrideFlag() )
3059
3060
    // delta quantization and chrom and chroma offset
3061
0
    if( pps->getUseDQP() )
3062
0
    {
3063
0
      X_READ_UVLC( ph_cu_qp_delta_subdiv_intra_slice,
3064
0
                   0, 2 * ( CtbLog2SizeY - MinQtLog2SizeIntraY + maxBTD[0] /*ph_max_mtt_hierarchy_depth_intra_slice_luma*/ ) );
3065
0
      picHeader->setCuQpDeltaSubdivIntra( ph_cu_qp_delta_subdiv_intra_slice );
3066
0
    }
3067
3068
0
    if( pps->getCuChromaQpOffsetEnabledFlag() )
3069
0
    {
3070
0
      X_READ_UVLC( ph_cu_chroma_qp_offset_subdiv_intra_slice,
3071
0
                   0, 2 * ( CtbLog2SizeY - MinQtLog2SizeIntraY + maxBTD[0] /*ph_max_mtt_hierarchy_depth_intra_slice_luma*/ ) );
3072
0
      picHeader->setCuChromaQpOffsetSubdivIntra( ph_cu_chroma_qp_offset_subdiv_intra_slice );
3073
0
    }
3074
0
  }   // if( picHeader->getPicIntraSliceAllowedFlag() )
3075
3076
10
  if( ph_inter_slice_allowed_flag )
3077
0
  {
3078
0
    unsigned MinQtLog2SizeInterY = MinCbLog2SizeY;
3079
0
    if( picHeader->getSplitConsOverrideFlag() )
3080
0
    {
3081
0
      X_READ_UVLC( ph_log2_diff_min_qt_min_cb_inter_slice, 0, std::min( 6u, CtbLog2SizeY ) - MinCbLog2SizeY );
3082
0
      MinQtLog2SizeInterY += ph_log2_diff_min_qt_min_cb_inter_slice;
3083
0
      minQT[1] = 1 << MinQtLog2SizeInterY;
3084
3085
0
      X_READ_UVLC( ph_max_mtt_hierarchy_depth_inter_slice, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) );
3086
0
      maxBTD[1] = ph_max_mtt_hierarchy_depth_inter_slice;
3087
3088
0
      maxTTSize[1] = maxBTSize[1] = minQT[1];
3089
0
      if( maxBTD[1] != 0 )
3090
0
      {
3091
0
        X_READ_UVLC( ph_log2_diff_max_bt_min_qt_inter_slice, 0, CtbLog2SizeY - MinQtLog2SizeInterY );
3092
0
        maxBTSize[1] <<= ph_log2_diff_max_bt_min_qt_inter_slice;
3093
3094
0
        X_READ_UVLC( ph_log2_diff_max_tt_min_qt_inter_slice, 0, std::min( 6u, CtbLog2SizeY ) - MinQtLog2SizeInterY );
3095
0
        maxTTSize[1] <<= ph_log2_diff_max_tt_min_qt_inter_slice;
3096
0
      }
3097
0
    }
3098
3099
    // delta quantization and chrom and chroma offset
3100
0
    if( pps->getUseDQP() )
3101
0
    {
3102
0
      X_READ_UVLC( ph_cu_qp_delta_subdiv_inter_slice, 0, 2 * ( CtbLog2SizeY - MinQtLog2SizeInterY + maxBTD[1] /*ph_max_mtt_hierarchy_depth_inter_slice*/ ) );
3103
0
      picHeader->setCuQpDeltaSubdivInter( ph_cu_qp_delta_subdiv_inter_slice );
3104
0
    }
3105
3106
0
    if( pps->getCuChromaQpOffsetEnabledFlag() )
3107
0
    {
3108
0
      X_READ_UVLC( ph_cu_chroma_qp_offset_subdiv_inter_slice,
3109
0
                   0, 2 * ( CtbLog2SizeY - MinQtLog2SizeInterY + maxBTD[1] /*ph_max_mtt_hierarchy_depth_inter_slice*/ ) );
3110
0
      picHeader->setCuChromaQpOffsetSubdivInter( ph_cu_chroma_qp_offset_subdiv_inter_slice );
3111
0
    }
3112
3113
    // temporal motion vector prediction
3114
0
    if( sps->getSPSTemporalMVPEnabledFlag() )
3115
0
    {
3116
0
      X_READ_FLAG( ph_temporal_mvp_enabled_flag );
3117
0
      picHeader->setEnableTMVPFlag( ph_temporal_mvp_enabled_flag );
3118
3119
0
      if( ph_temporal_mvp_enabled_flag && pps->getRplInfoInPhFlag() )
3120
0
      {
3121
0
        if( picHeader->getRPL( REF_PIC_LIST_1 )->getNumRefEntries() > 0 )
3122
0
        {
3123
0
          X_READ_FLAG( ph_collocated_from_l0_flag );
3124
0
          picHeader->setPicColFromL0Flag( ph_collocated_from_l0_flag );
3125
0
        }
3126
0
        else   // ( num_ref_entries[ 1 ][ RplsIdx[ 1 ] ] == 0 )
3127
0
        {
3128
          // When ph_temporal_mvp_enabled_flag and pps_rpl_info_in_ph_flag are both equal to 1 and num_ref_entries[ 1 ][ RplsIdx[ 1 ] ] is equal to 0, the value
3129
          // of ph_collocated_from_l0_flag is inferred to be equal to 1.
3130
0
          picHeader->setPicColFromL0Flag( 1 );
3131
0
        }
3132
3133
0
        if( ( picHeader->getPicColFromL0Flag() && picHeader->getRPL( REF_PIC_LIST_0 )->getNumRefEntries() > 1 )
3134
0
            || ( !picHeader->getPicColFromL0Flag() && picHeader->getRPL( REF_PIC_LIST_1 )->getNumRefEntries() > 1 ) )
3135
0
        {
3136
0
          X_READ_UVLC_NO_RANGE( ph_collocated_ref_idx );
3137
0
          if( picHeader->getPicColFromL0Flag() )
3138
0
          {
3139
0
            CHECK( ph_collocated_ref_idx > picHeader->getRPL( REF_PIC_LIST_0 )->getNumRefEntries() - 1,
3140
0
                   "When ph_collocated_from_l0_flag is equal to 1, ph_collocated_ref_idx refers to an entry in RPL 0, and the value of ph_collocated_ref_idx"
3141
0
                   " shall be in the range of 0 to num_ref_entries[ 0 ][ RplsIdx[ 0 ] ] − 1, inclusive." )
3142
0
          }
3143
0
          else
3144
0
          {
3145
0
            CHECK( ph_collocated_ref_idx > picHeader->getRPL( REF_PIC_LIST_1 )->getNumRefEntries() - 1,
3146
0
                   "When ph_collocated_from_l0_flag is equal to 0, ph_collocated_ref_idx refers to an entry in RPL 1, and the value of ph_collocated_ref_idx"
3147
0
                   " shall be in the range of 0 to num_ref_entries[ 1 ][ RplsIdx[ 1 ] ] − 1, inclusive." );
3148
0
          }
3149
0
          picHeader->setColRefIdx( ph_collocated_ref_idx );
3150
0
        }
3151
0
      }
3152
0
    }
3153
3154
    // merge candidate list size
3155
    // subblock merge candidate list size
3156
0
    if( sps->getUseAffine() )
3157
0
    {
3158
0
      picHeader->setMaxNumAffineMergeCand( sps->getMaxNumAffineMergeCand() );
3159
0
    }
3160
0
    else
3161
0
    {
3162
0
      picHeader->setMaxNumAffineMergeCand( sps->getSBTMVPEnabledFlag() && picHeader->getEnableTMVPFlag() );
3163
0
    }
3164
3165
    // full-pel MMVD flag
3166
0
    if( sps->getFpelMmvdEnabledFlag() )
3167
0
    {
3168
0
      X_READ_FLAG( ph_fpel_mmvd_enabled_flag );
3169
0
      picHeader->setDisFracMMVD( ph_fpel_mmvd_enabled_flag );
3170
0
    }
3171
3172
0
    bool presenceFlag = 0;
3173
0
    if( !pps->getRplInfoInPhFlag() )   // This condition is intentionally not merged into the next, to avoid possible interpretation of RplsIdx[ i ] not having
3174
0
    {                                  // a specified value.
3175
0
      presenceFlag = 1;
3176
0
    }
3177
0
    else if( picHeader->getRPL( REF_PIC_LIST_1 )->getNumRefEntries() > 0 )
3178
0
    {
3179
0
      presenceFlag = 1;
3180
0
    }
3181
3182
    // If sps_bdof_control_present_in_ph_flag is equal to 0, the value of ph_bdof_disabled_flag is inferred to be equal to 1 - sps_bdof_enabled_flag
3183
    // Otherwise (sps_bdof_control_present_in_ph_flag is equal to 1), the value of ph_bdof_disabled_flag is inferred to be  equal to 1.
3184
0
    picHeader->setDisBdofFlag( sps->getBdofControlPresentInPhFlag() == 0 ? 1 - sps->getUseBIO() : 1 );
3185
3186
    // If sps_dmvr_control_present_in_ph_flag is equal to 0, the value of ph_dmvr_disabled_flag is inferred to be equal to 1 - sps_dmvr_enabled_flag.
3187
    // Otherwise (sps_dmvr_control_present_in_ph_flag is equal to 1), the value of ph_dmvr_disabled_flag is inferred to be equal to 1.
3188
0
    picHeader->setDisDmvrFlag( sps->getDmvrControlPresentInPhFlag() == 0 ? 1 - sps->getUseDMVR() : 1 );
3189
3190
0
    if( presenceFlag )
3191
0
    {
3192
      // mvd L1 zero flag
3193
0
      X_READ_FLAG( ph_mvd_l1_zero_flag );
3194
0
      picHeader->setMvdL1ZeroFlag( ph_mvd_l1_zero_flag );
3195
3196
      // picture level BDOF disable flags
3197
0
      if( sps->getBdofControlPresentInPhFlag() )
3198
0
      {
3199
0
        X_READ_FLAG( ph_bdof_disabled_flag );
3200
0
        picHeader->setDisBdofFlag( ph_bdof_disabled_flag );
3201
0
      }
3202
3203
      // picture level DMVR disable flags
3204
0
      if( sps->getDmvrControlPresentInPhFlag() )
3205
0
      {
3206
0
        X_READ_FLAG( ph_dmvr_disabled_flag );
3207
0
        picHeader->setDisDmvrFlag( ph_dmvr_disabled_flag );
3208
0
      }
3209
0
    }
3210
3211
    // picture level PROF disable flags
3212
0
    if( sps->getProfControlPresentInPhFlag() )
3213
0
    {
3214
0
      X_READ_FLAG( ph_prof_disabled_flag );
3215
0
      picHeader->setDisProfFlag( ph_prof_disabled_flag );
3216
0
    }
3217
0
    else
3218
0
    {
3219
      // If sps_affine_prof_enabled_flag is equal to 1, the value of ph_prof_disabled_flag is inferred to be equal to 0.
3220
      // Otherwise (sps_affine_prof_enabled_flag is equal to 0), the value of ph_prof_disabled_flag is inferred to be equal to 1.
3221
3222
0
      picHeader->setDisProfFlag( !sps->getUsePROF() );
3223
0
    }
3224
3225
0
    if( ( pps->getUseWP() || pps->getWPBiPred() ) && pps->getWpInfoInPhFlag() )
3226
0
    {
3227
0
      parsePredWeightTable( picHeader, sps, pps );
3228
0
    }
3229
0
  }   // if( ph_inter_slice_allowed_flag )
3230
3231
10
  picHeader->setMinQTSizes( minQT );
3232
10
  picHeader->setMaxMTTHierarchyDepths( maxBTD );
3233
10
  picHeader->setMaxBTSizes( maxBTSize );
3234
10
  picHeader->setMaxTTSizes( maxTTSize );
3235
3236
  // ibc merge candidate list size
3237
10
  if( pps->getQpDeltaInfoInPhFlag() )
3238
0
  {
3239
0
   X_READ_SVLC_NO_RANGE( ph_qp_delta );
3240
0
   int SliceQpY = 26 + pps->getPicInitQPMinus26() + ph_qp_delta;
3241
0
   CHECK( SliceQpY < -sps->getQpBDOffset() || SliceQpY > 63, "The value of SliceQpY shall be in the range of −QpBdOffset to +63, inclusive." );
3242
0
   picHeader->setQpDelta( ph_qp_delta );
3243
0
  }
3244
3245
  // joint Cb/Cr sign flag
3246
10
  if( sps->getJointCbCrEnabledFlag() )
3247
0
  {
3248
0
    X_READ_FLAG( ph_joint_cbcr_sign_flag );
3249
0
    picHeader->setJointCbCrSignFlag( ph_joint_cbcr_sign_flag );
3250
0
  }
3251
3252
  // sao enable flags
3253
10
  if( sps->getUseSAO() && pps->getSaoInfoInPhFlag() )
3254
0
  {
3255
0
    X_READ_FLAG( ph_sao_luma_enabled_flag );
3256
0
    picHeader->setSaoEnabledFlag( CHANNEL_TYPE_LUMA, ph_sao_luma_enabled_flag );
3257
3258
0
    if( sps->getChromaFormatIdc() != CHROMA_400 )
3259
0
    {
3260
0
      X_READ_FLAG( ph_sao_chroma_enabled_flag );
3261
0
      picHeader->setSaoEnabledFlag( CHANNEL_TYPE_CHROMA, ph_sao_chroma_enabled_flag );
3262
0
    }
3263
0
  }
3264
3265
  // deblocking filter controls
3266
3267
10
  if( pps->getDbfInfoInPhFlag() )
3268
0
  {
3269
0
    X_READ_FLAG( ph_deblocking_params_present_flag );
3270
0
    picHeader->setDeblockingFilterOverrideFlag( ph_deblocking_params_present_flag );
3271
0
  }
3272
3273
10
  if( pps->getPPSDeblockingFilterDisabledFlag() == 1 && picHeader->getDeblockingFilterOverrideFlag() == 1 )
3274
0
  {
3275
    // If pps_deblocking_filter_disabled_flag and ph_deblocking_params_present_flag are both equal to 1, the value of ph_deblocking_filter_disabled_flag
3276
    // is inferred to be equal to 0.
3277
0
    picHeader->setDeblockingFilterDisable( false );
3278
0
  }
3279
10
  else // ( pps->getPPSDeblockingFilterDisabledFlag() == 0 || picHeader->getDeblockingFilterOverrideFlag() == 0 )
3280
10
  {
3281
    // Otherwise (pps_deblocking_filter_disabled_flag or ph_deblocking_params_present_flag is equal to 0), the value of ph_deblocking_filter_disabled_flag is
3282
    // inferred to be equal to pps_deblocking_filter_disabled_flag.
3283
10
    picHeader->setDeblockingFilterDisable( pps->getPPSDeblockingFilterDisabledFlag() );
3284
10
  }
3285
3286
  // When not present, the values of ph_luma_beta_offset_div2 and ph_luma_tc_offset_div2 are inferred to be equal to pps_luma_beta_offset_div2 and
3287
  // pps_luma_tc_offset_div2, respectively.
3288
10
  picHeader->setDeblockingFilterBetaOffsetDiv2( pps->getDeblockingFilterBetaOffsetDiv2() );
3289
10
  picHeader->setDeblockingFilterTcOffsetDiv2( pps->getDeblockingFilterTcOffsetDiv2() );
3290
3291
10
  if( picHeader->getDeblockingFilterOverrideFlag() /*ph_deblocking_params_present_flag*/ )
3292
0
  {
3293
0
    if( !pps->getPPSDeblockingFilterDisabledFlag() )
3294
0
    {
3295
0
      X_READ_FLAG( ph_deblocking_filter_disabled_flag );
3296
0
      picHeader->setDeblockingFilterDisable( ph_deblocking_filter_disabled_flag );
3297
0
    }
3298
3299
0
    if( !picHeader->getDeblockingFilterDisable() )
3300
0
    {
3301
0
      X_READ_SVLC( ph_luma_beta_offset_div2, -12, 12 );
3302
0
      picHeader->setDeblockingFilterBetaOffsetDiv2( ph_luma_beta_offset_div2 );
3303
3304
0
      X_READ_SVLC( ph_luma_tc_offset_div2, -12, 12 );
3305
0
      picHeader->setDeblockingFilterTcOffsetDiv2( ph_luma_tc_offset_div2 );
3306
0
    }
3307
0
  }
3308
3309
10
  if( picHeader->getDeblockingFilterOverrideFlag() /*ph_deblocking_params_present_flag*/
3310
0
      && !picHeader->getDeblockingFilterDisable() && pps->getPPSChromaToolFlag() )
3311
0
  {
3312
0
    X_READ_SVLC( ph_cb_beta_offset_div2, -12, 12 );
3313
0
    picHeader->setDeblockingFilterCbBetaOffsetDiv2( ph_cb_beta_offset_div2 );
3314
3315
0
    X_READ_SVLC( ph_cb_tc_offset_div2, -12, 12 );
3316
0
    picHeader->setDeblockingFilterCbTcOffsetDiv2( ph_cb_tc_offset_div2 );
3317
3318
0
    X_READ_SVLC( ph_cr_beta_offset_div2, -12, 12 );
3319
0
    picHeader->setDeblockingFilterCrBetaOffsetDiv2( ph_cr_beta_offset_div2 );
3320
3321
0
    X_READ_SVLC( ph_cr_tc_offset_div2, -12, 12 );
3322
0
    picHeader->setDeblockingFilterCrTcOffsetDiv2( ph_cr_tc_offset_div2 );
3323
0
  }
3324
10
  else
3325
10
  {
3326
    // When not present, the values of ph_cb_beta_offset_div2 and ph_cb_tc_offset_div2 are inferred as follows:
3327
    // If pps_chroma_tool_offsets_present_flag is equal to 1, the values of ph_cb_beta_offset_div2 and ph_cb_tc_offset_div2 are inferred to be equal to
3328
    // pps_cb_beta_offset_div2 and pps_cb_tc_offset_div2, respectively.
3329
    // Otherwise (pps_chroma_tool_offsets_present_flag is equal to 0), the values of ph_cb_beta_offset_div2 and ph_cb_tc_offset_div2 are inferred to be equal
3330
    // to ph_luma_beta_offset_div2 and ph_luma_tc_offset_div2, respectively.
3331
10
    picHeader->setDeblockingFilterCbBetaOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCbBetaOffsetDiv2()
3332
10
                                                                                : picHeader->getDeblockingFilterBetaOffsetDiv2() );
3333
10
    picHeader->setDeblockingFilterCbTcOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCbTcOffsetDiv2()
3334
10
                                                                              : picHeader->getDeblockingFilterTcOffsetDiv2() );
3335
3336
    // When not present, the values of ph_cr_beta_offset_div2 and ph_cr_tc_offset_div2 are inferred as follows:
3337
    // If pps_chroma_tool_offsets_present_flag is equal to 1, the values of ph_cr_beta_offset_div2 and ph_cr_tc_offset_div2 are inferred to be equal to
3338
    // pps_cr_beta_offset_div2 and pps_cr_tc_offset_div2, respectively.
3339
    // Otherwise (pps_chroma_tool_offsets_present_flag is equal to 0), the values of ph_cr_beta_offset_div2 and ph_cr_tc_offset_div2 are inferred to be equal
3340
    // to ph_luma_beta_offset_div2 and ph_luma_tc_offset_div2, respectively.
3341
10
    picHeader->setDeblockingFilterCrBetaOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCrBetaOffsetDiv2()
3342
10
                                                                                : picHeader->getDeblockingFilterBetaOffsetDiv2() );
3343
10
    picHeader->setDeblockingFilterCrTcOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCrTcOffsetDiv2()
3344
10
                                                                              : picHeader->getDeblockingFilterTcOffsetDiv2() );
3345
10
  }
3346
3347
  // picture header extension
3348
10
  if( pps->getPictureHeaderExtensionPresentFlag() )
3349
0
  {
3350
0
    X_READ_UVLC( ph_extension_length, 0, 256 );
3351
0
    for( unsigned i = 0; i < ph_extension_length; i++ )
3352
0
    {
3353
0
      X_READ_CODE_NO_RANGE_idx( ph_extension_data_byte, "[i]", 8 );
3354
0
      (void) ph_extension_data_byte;
3355
0
    }
3356
0
  }
3357
3358
10
  if( readRbspTrailingBits )
3359
0
  {
3360
0
    xReadRbspTrailingBits();
3361
0
  }
3362
10
  picHeader->setValid();
3363
10
}
3364
3365
void HLSyntaxReader::checkAlfNaluTidAndPicTid( const Slice* pcSlice, const PicHeader* picHeader, const ParameterSetManager *parameterSetManager )
3366
0
{
3367
0
  const SPS* sps = parameterSetManager->getSPS(picHeader->getSPSId());
3368
0
  const PPS* pps = parameterSetManager->getPPS(picHeader->getPPSId());
3369
3370
0
  int  curPicTid = pcSlice->getTLayer();
3371
0
  const APS* aps = nullptr;
3372
3373
0
  if( sps->getUseALF() && pps->getAlfInfoInPhFlag() && picHeader->getAlfEnabledFlag( COMPONENT_Y ) )
3374
0
  {
3375
0
    const auto& apsIds = picHeader->getAlfAPSIds();
3376
    //luma
3377
0
    for( int i = 0; i < picHeader->getNumAlfAps(); i++ )
3378
0
    {
3379
0
      aps = parameterSetManager->getAPS( apsIds[i], ALF_APS );
3380
0
      CHECK( aps->getTemporalId() > curPicTid, "The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and adaptation_parameter_set_id equal to ph_alf_aps_id_luma[i] shall be less than or equal to the TemporalId of the picture associated with the PH." );
3381
0
      if( pcSlice->getNalUnitLayerId() != aps->getLayerId() )
3382
0
      {
3383
0
        CHECK( aps->getLayerId() > pcSlice->getNalUnitLayerId(), "Layer Id of APS cannot be greater than layer Id of VCL NAL unit the refer to it" );
3384
0
        CHECK( sps->getVPSId() == 0, "VPSId of the referred SPS cannot be 0 when layer Id of APS and layer Id of current slice are different" );
3385
0
        const VPS* vps = parameterSetManager->getVPS( sps->getVPSId() );
3386
0
        for( int i = 0; i < vps->getNumOutputLayerSets(); i++ )
3387
0
        {
3388
0
          bool isCurrLayerInOls = false;
3389
0
          bool isRefLayerInOls = false;
3390
0
          for( int j = vps->getNumLayersInOls(i) - 1; j >= 0; j-- )
3391
0
          {
3392
0
            if( vps->getLayerIdInOls(i, j) == pcSlice->getNalUnitLayerId() )
3393
0
            {
3394
0
              isCurrLayerInOls = true;
3395
0
            }
3396
0
            if( vps->getLayerIdInOls(i, j) == aps->getLayerId() )
3397
0
            {
3398
0
              isRefLayerInOls = true;
3399
0
            }
3400
0
          }
3401
0
          CHECK( isCurrLayerInOls && !isRefLayerInOls, "When VCL NAl unit in layer A refers to APS in layer B, all OLS that contains layer A shall also contains layer B" );
3402
0
        }
3403
0
      }
3404
0
    }
3405
    //chroma
3406
0
    if( picHeader->getAlfEnabledFlag(COMPONENT_Cb) || picHeader->getAlfEnabledFlag( COMPONENT_Cr ) )
3407
0
    {
3408
0
      int chromaAlfApsId = picHeader->getAlfApsIdChroma();
3409
0
      aps = parameterSetManager->getAPS( chromaAlfApsId, ALF_APS );
3410
0
      CHECK( aps->getTemporalId() > curPicTid, "The TemporalId of the APS NAL unit having aps_params_type equal to ALF_APS and adaptation_parameter_set_id equal to ph_alf_aps_id_chroma shall be less than or equal to the TemporalId of the picture associated with the PH.") ;
3411
0
      if( pcSlice->getNalUnitLayerId() != aps->getLayerId() )
3412
0
      {
3413
0
        CHECK( aps->getLayerId() > pcSlice->getNalUnitLayerId(), "Layer Id of APS cannot be greater than layer Id of VCL NAL unit the refer to it" );
3414
0
        CHECK( sps->getVPSId() == 0, "VPSId of the referred SPS cannot be 0 when layer Id of APS and layer Id of current slice are different" );
3415
0
        const VPS* vps = parameterSetManager->getVPS( sps->getVPSId() );
3416
0
        for( int i = 0; i < vps->getNumOutputLayerSets(); i++ )
3417
0
        {
3418
0
          bool isCurrLayerInOls = false;
3419
0
          bool isRefLayerInOls = false;
3420
0
          for( int j = vps->getNumLayersInOls(i) - 1; j >= 0; j-- )
3421
0
          {
3422
0
            if( vps->getLayerIdInOls( i, j ) == pcSlice->getNalUnitLayerId() )
3423
0
            {
3424
0
              isCurrLayerInOls = true;
3425
0
            }
3426
0
            if( vps->getLayerIdInOls(i, j) == aps->getLayerId() )
3427
0
            {
3428
0
              isRefLayerInOls = true;
3429
0
            }
3430
0
          }
3431
0
          CHECK( isCurrLayerInOls && !isRefLayerInOls, "When VCL NAl unit in layer A refers to APS in layer B, all OLS that contains layer A shall also contains layer B" );
3432
0
        }
3433
0
      }
3434
0
    }
3435
0
  }
3436
0
}
3437
3438
void HLSyntaxReader::parseSliceHeader( Slice*                      pcSlice,
3439
                                       std::shared_ptr<PicHeader>& picHeader,
3440
                                       const ParameterSetManager*  parameterSetManager,
3441
                                       const int                   prevTid0POC,
3442
                                       bool&                       firstSliceInPic )
3443
22
{
3444
#if ENABLE_TRACING
3445
  xTraceSliceHeader();
3446
#endif
3447
3448
22
  X_READ_FLAG( sh_picture_header_in_slice_header_flag );
3449
22
  pcSlice->setPictureHeaderInSliceHeader( sh_picture_header_in_slice_header_flag );
3450
3451
22
  if( sh_picture_header_in_slice_header_flag )
3452
8
  {
3453
8
    picHeader.reset( new PicHeader );
3454
8
    parsePictureHeader( picHeader.get(), parameterSetManager, false );
3455
8
  }
3456
22
  CHECK( !picHeader, "Picture Header not allocated" );   // should always be allocated, even if it is not valid
3457
10
  CHECK( !picHeader->isValid(), "Picture Header missing" );
3458
3459
10
  checkAlfNaluTidAndPicTid( pcSlice, picHeader.get(), parameterSetManager );
3460
3461
10
  const PPS* pps = parameterSetManager->getPPS( picHeader->getPPSId() );
3462
10
  CHECK( pps == 0, "Invalid PPS" );
3463
10
  const SPS* sps = parameterSetManager->getSPS( pps->getSPSId() );
3464
10
  CHECK( sps == 0, "Invalid SPS" );
3465
3466
10
  auto gci = sps->getProfileTierLevel()->getConstraintInfo();
3467
10
  CHECK_CONSTRAINT( gci->getPicHeaderInSliceHeaderConstraintFlag() && !sh_picture_header_in_slice_header_flag,
3468
10
                    "PH shall be present in SH, when pic_header_in_slice_header_constraint_flag is equal to 1" );
3469
3470
10
  if( sh_picture_header_in_slice_header_flag )
3471
0
  {
3472
0
    CHECK( pps->getRplInfoInPhFlag() == 1, "When sh_picture_header_in_slice_header_flag is equal to 1, rpl_info_in_ph_flag shall be equal to 0" );
3473
0
    CHECK( pps->getDbfInfoInPhFlag() == 1, "When sh_picture_header_in_slice_header_flag is equal to 1, dbf_info_in_ph_flag shall be equal to 0" );
3474
0
    CHECK( pps->getSaoInfoInPhFlag() == 1, "When sh_picture_header_in_slice_header_flag is equal to 1, sao_info_in_ph_flag shall be equal to 0" );
3475
0
    CHECK( pps->getAlfInfoInPhFlag() == 1, "When sh_picture_header_in_slice_header_flag is equal to 1, alf_info_in_ph_flag shall be equal to 0" );
3476
0
    CHECK( pps->getWpInfoInPhFlag() == 1, "When sh_picture_header_in_slice_header_flag is equal to 1, wp_info_in_ph_flag shall be equal to 0" );
3477
0
    CHECK( pps->getQpDeltaInfoInPhFlag() == 1,
3478
0
                       "When sh_picture_header_in_slice_header_flag is equal to 1, qp_delta_info_in_ph_flag shall be equal to 0" );
3479
0
    CHECK( sps->getSubPicInfoPresentFlag() == 1,
3480
0
                       "When sps_subpic_info_present_flag is equal to 1, the value of sh_picture_header_in_slice_header_flag shall be equal to 0" );
3481
0
  }
3482
10
  CHECK( sps->getSubPicInfoPresentFlag() == 1 && sps->getVirtualBoundariesEnabledFlag() == 1 && sps->getVirtualBoundariesPresentFlag() == 0,
3483
10
                     "when sps_subpic_info_present_flag is equal to 1 and sps_virtual_boundaries_enabled_flag is equal to 1, "
3484
10
                     "sps_virtual_boundaries_present_flag shall be equal 1" );
3485
3486
3487
10
  const bool bChroma = sps->getChromaFormatIdc() != CHROMA_400;
3488
3489
  // picture order count
3490
10
  const int iPOClsb    = picHeader->getPocLsb();
3491
10
  const int iMaxPOClsb = 1 << sps->getBitsForPOC();
3492
10
  if( pcSlice->getIdrPicFlag() )
3493
0
  {
3494
0
    int iPOCmsb;
3495
0
    if( picHeader->getPocMsbPresentFlag() )
3496
0
    {
3497
0
      iPOCmsb = picHeader->getPocMsbVal() * iMaxPOClsb;
3498
0
    }
3499
0
    else
3500
0
    {
3501
0
      iPOCmsb = 0;
3502
0
    }
3503
0
    pcSlice->setPOC( iPOCmsb + iPOClsb );
3504
0
  }
3505
10
  else
3506
10
  {
3507
10
    const int iPrevPOC    = prevTid0POC;
3508
10
    const int iPrevPOClsb = iPrevPOC & ( iMaxPOClsb - 1 );
3509
10
    const int iPrevPOCmsb = iPrevPOC - iPrevPOClsb;
3510
10
    int       iPOCmsb;
3511
10
    if( picHeader->getPocMsbPresentFlag() )
3512
0
    {
3513
0
      iPOCmsb = picHeader->getPocMsbVal() * iMaxPOClsb;
3514
0
    }
3515
10
    else
3516
10
    {
3517
10
      if( ( iPOClsb < iPrevPOClsb ) && ( ( iPrevPOClsb - iPOClsb ) >= ( iMaxPOClsb / 2 ) ) )
3518
0
      {
3519
0
        iPOCmsb = iPrevPOCmsb + iMaxPOClsb;
3520
0
      }
3521
10
      else if( ( iPOClsb > iPrevPOClsb ) && ( ( iPOClsb - iPrevPOClsb ) > ( iMaxPOClsb / 2 ) ) )
3522
0
      {
3523
0
        iPOCmsb = iPrevPOCmsb - iMaxPOClsb;
3524
0
      }
3525
10
      else
3526
10
      {
3527
10
        iPOCmsb = iPrevPOCmsb;
3528
10
      }
3529
10
    }
3530
10
    pcSlice->setPOC( iPOCmsb + iPOClsb );
3531
10
  }
3532
3533
10
  if( sps->getSubPicInfoPresentFlag() )
3534
0
  {
3535
0
    X_READ_CODE_NO_RANGE( sh_subpic_id, sps->getSubPicIdLen() );
3536
0
    pcSlice->setSliceSubPicId( sh_subpic_id );
3537
0
  }
3538
3539
10
  const unsigned NumTilesInPic = pps->getNumTiles();
3540
3541
10
  uint32_t sliceAddr = 0;
3542
10
  if( !pps->getRectSliceFlag() )   // raster scan slices
3543
0
  {
3544
0
    if( NumTilesInPic > 1 )
3545
0
    {
3546
      // slice address is the raster scan tile index of first tile in slice
3547
0
      const int bitsSliceAddress = (int) std::ceil( std::log2( NumTilesInPic ) );
3548
0
      X_READ_CODE( sh_slice_address, bitsSliceAddress, 0, NumTilesInPic - 1 );
3549
0
      sliceAddr = sh_slice_address;
3550
0
    }
3551
0
  }
3552
10
  else   // rectangular slices
3553
10
  {
3554
    // slice address is the index of the slice within the current sub-picture
3555
10
    const uint32_t currSubPicIdx         = pps->getSubPicIdxFromSubPicId( pcSlice->getSliceSubPicId() );
3556
10
    const SubPic&  currSubPic            = pps->getSubPic( currSubPicIdx );
3557
10
    const unsigned NumSlicesInCurrSubpic = currSubPic.getNumSlicesInSubPic();
3558
10
    if( NumSlicesInCurrSubpic > 1 )
3559
0
    {
3560
0
      const int bitsSliceAddress = (int) std::ceil( std::log2( NumSlicesInCurrSubpic ) );
3561
0
      X_READ_CODE( sh_slice_address, bitsSliceAddress, 0, NumSlicesInCurrSubpic - 1 );
3562
0
      sliceAddr = sh_slice_address;
3563
0
    }
3564
10
  }
3565
3566
10
  const std::vector<bool>& shExtraBitsPresent = sps->getExtraSHBitPresentFlags();
3567
10
  for( int i = 0; i < sps->getNumExtraSHBitsBytes() * 8; i++ )
3568
0
  {
3569
    // extra bits are ignored (when present)
3570
0
    if( shExtraBitsPresent[i] )
3571
0
    {
3572
0
      X_READ_FLAG_idx( sh_extra_bit, "[i]" );
3573
0
      (void) sh_extra_bit;
3574
0
    }
3575
0
  }
3576
3577
10
  uint32_t numTilesInSlice = 1;
3578
10
  if( !pps->getRectSliceFlag() && (int) NumTilesInPic - (int) sliceAddr > 1 )
3579
0
  {
3580
0
    X_READ_UVLC( sh_num_tiles_in_slice_minus1, 0, NumTilesInPic - 1 );
3581
0
    CHECK_CONSTRAINT( gci->getOneSlicePerPicConstraintFlag() && sh_num_tiles_in_slice_minus1 != NumTilesInPic - 1,
3582
0
                      "When rect_slice_flag is equal to 0 and one_slice_per_pic_constraint_flag equal to 1, the value of num_tiles_in_slice_minus1 present in"
3583
0
                      " each slice header shall be equal to NumTilesInPic - 1" );
3584
0
    numTilesInSlice = sh_num_tiles_in_slice_minus1 + 1;
3585
0
  }
3586
3587
10
  if( !pps->getRectSliceFlag() )
3588
0
  {
3589
0
    CHECK( sliceAddr >= pps->getNumTiles(), "Invalid slice address" );
3590
3591
0
    pcSlice->resetSliceMap();
3592
0
    pcSlice->setSliceID( sliceAddr );
3593
3594
    // NumCtusInCurrSlice = 0;
3595
0
    for( uint32_t tileIdx = sliceAddr; tileIdx < sliceAddr + numTilesInSlice; tileIdx++ )
3596
0
    {
3597
0
      uint32_t tileX = tileIdx % pps->getNumTileColumns();
3598
0
      uint32_t tileY = tileIdx / pps->getNumTileColumns();
3599
0
      CHECK( tileY >= pps->getNumTileRows(), "Number of tiles in slice exceeds the remaining number of tiles in picture" );
3600
3601
0
      pcSlice->addCtusToSlice( pps->getTileColumnBd( tileX ), pps->getTileColumnBd( tileX + 1 ),
3602
0
                               pps->getTileRowBd( tileY ), pps->getTileRowBd( tileY + 1 ), pps->getPicWidthInCtu() );
3603
0
    }
3604
0
  }
3605
10
  else
3606
10
  {
3607
10
    uint32_t       picLevelSliceIdx = sliceAddr;
3608
10
    const uint32_t currSubPicIdx    = pps->getSubPicIdxFromSubPicId( pcSlice->getSliceSubPicId() );
3609
10
    for( int subpic = 0; subpic < currSubPicIdx; subpic++ )
3610
0
    {
3611
0
      picLevelSliceIdx += pps->getSubPic( subpic ).getNumSlicesInSubPic();
3612
0
    }
3613
10
    pcSlice->setSliceMap( pps->getSliceMap( picLevelSliceIdx ) );
3614
10
    pcSlice->setSliceID( picLevelSliceIdx );
3615
10
  }
3616
3617
10
  if( firstSliceInPic != ( pcSlice->getCtuAddrInSlice( 0 ) == 0 ) )
3618
0
  {
3619
    // exit early, because we need to start again with some fields copied from previous slice
3620
0
    firstSliceInPic = false;
3621
0
    return;
3622
0
  }
3623
3624
10
  if( picHeader->getPicInterSliceAllowedFlag() )
3625
0
  {
3626
0
    X_READ_UVLC( sh_slice_type, 0, 2 );
3627
0
    pcSlice->setSliceType( (SliceType) sh_slice_type );
3628
0
  }
3629
10
  else
3630
10
  {
3631
10
    pcSlice->setSliceType( I_SLICE );
3632
10
  }
3633
3634
10
  CHECK( !picHeader->getPicIntraSliceAllowedFlag() && pcSlice->getSliceType() != B_SLICE && pcSlice->getSliceType() != P_SLICE,
3635
10
                     "When ph_intra_slice_allowed_flag is equal to 0, the value of sh_slice_type shall be equal to 0 or 1." );
3636
3637
10
  if( pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL
3638
0
      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP
3639
0
      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA
3640
0
      || pcSlice->getNalUnitType() == NAL_UNIT_CODED_SLICE_GDR )
3641
0
  {
3642
0
    X_READ_FLAG( sh_no_output_of_prior_pics_flag );
3643
0
    pcSlice->setNoOutputOfPriorPicsFlag( sh_no_output_of_prior_pics_flag );
3644
0
  }
3645
3646
  // inherit values from picture header
3647
  //   set default values in case slice overrides are disabled
3648
10
  pcSlice->inheritFromPicHeader( picHeader.get(), pps, sps );
3649
3650
10
  if( sps->getUseALF() && !pps->getAlfInfoInPhFlag() )
3651
0
  {
3652
0
    X_READ_FLAG( sh_alf_enabled_flag );
3653
0
    pcSlice->setAlfEnabledFlag( COMPONENT_Y, sh_alf_enabled_flag );
3654
3655
0
    if( sh_alf_enabled_flag )
3656
0
    {
3657
0
      X_READ_CODE_NO_RANGE( sh_num_alf_aps_ids_luma, 3 );
3658
0
      pcSlice->setNumAlfAps( sh_num_alf_aps_ids_luma );
3659
3660
0
      AlfApsIdVec apsId( sh_num_alf_aps_ids_luma, -1 );
3661
0
      for( int i = 0; i < sh_num_alf_aps_ids_luma; i++ )
3662
0
      {
3663
0
        X_READ_CODE_NO_RANGE_idx( sh_alf_aps_id_luma, "[i]", 3 );
3664
0
        apsId[i] = sh_alf_aps_id_luma;
3665
3666
0
        const APS* APStoCheckLuma = parameterSetManager->getAPS( apsId[i], ALF_APS );
3667
0
        CHECK( APStoCheckLuma == nullptr, "referenced APS not found" );
3668
0
        CHECK( APStoCheckLuma->getAlfAPSParam().newFilterFlag[CHANNEL_TYPE_LUMA] != 1,
3669
0
                           "The value of alf_luma_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and"
3670
0
                           " aps_adaptation_parameter_set_id equal to sh_alf_aps_id_luma[ i ] shall be equal to 1." );
3671
0
      }
3672
0
      pcSlice->setAlfApsIdsLuma( apsId );
3673
3674
0
      if( bChroma )
3675
0
      {
3676
0
        X_READ_FLAG( sh_alf_cb_enabled_flag );
3677
0
        pcSlice->setAlfEnabledFlag( COMPONENT_Cb, sh_alf_cb_enabled_flag );
3678
3679
0
        X_READ_FLAG( sh_alf_cr_enabled_flag );
3680
0
        pcSlice->setAlfEnabledFlag( COMPONENT_Cr, sh_alf_cr_enabled_flag );
3681
0
      }
3682
3683
0
      if( pcSlice->getAlfEnabledFlag( COMPONENT_Cb ) || pcSlice->getAlfEnabledFlag( COMPONENT_Cr ) )
3684
0
      {
3685
0
        X_READ_CODE_NO_RANGE( sh_alf_aps_id_chroma, 3 );
3686
0
        pcSlice->setAlfApsIdChroma( sh_alf_aps_id_chroma );
3687
3688
0
        const APS* APStoCheckChroma = parameterSetManager->getAPS( sh_alf_aps_id_chroma, ALF_APS );
3689
0
        CHECK( APStoCheckChroma == nullptr, "referenced APS not found" );
3690
0
        CHECK( APStoCheckChroma->getAlfAPSParam().newFilterFlag[CHANNEL_TYPE_CHROMA] != 1,
3691
0
                           "The value of alf_chroma_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and"
3692
0
                           " aps_adaptation_parameter_set_id equal to sh_alf_aps_id_chroma shall be equal to 1." );
3693
0
      }
3694
3695
0
      if( sps->getUseCCALF() )
3696
0
      {
3697
0
        X_READ_FLAG( sh_alf_cc_cb_enabled_flag );
3698
0
        pcSlice->setCcAlfCbEnabledFlag( sh_alf_cc_cb_enabled_flag );
3699
3700
0
        if( sh_alf_cc_cb_enabled_flag )
3701
0
        {
3702
0
          X_READ_CODE_NO_RANGE( sh_alf_cc_cb_aps_id, 3 );
3703
0
          pcSlice->setCcAlfCbApsId( sh_alf_cc_cb_aps_id );
3704
3705
0
          const APS* APStoCheckCcCb = parameterSetManager->getAPS( sh_alf_cc_cb_aps_id, ALF_APS );
3706
0
          CHECK( !APStoCheckCcCb, "referenced APS not found" );
3707
0
          CHECK( APStoCheckCcCb->getCcAlfAPSParam().newCcAlfFilter[0] != 1,
3708
0
                             "The value of alf_cc_cb_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and "
3709
0
                             "aps_adaptation_parameter_set_id equal to sh_alf_cc_cb_aps_id shall be equal to 1." );
3710
0
        }
3711
3712
0
        X_READ_FLAG( sh_alf_cc_cr_enabled_flag );
3713
0
        pcSlice->setCcAlfCrEnabledFlag( sh_alf_cc_cr_enabled_flag );
3714
3715
0
        if( sh_alf_cc_cr_enabled_flag )
3716
0
        {
3717
0
          X_READ_CODE_NO_RANGE( sh_alf_cc_cr_aps_id, 3 );
3718
0
          pcSlice->setCcAlfCrApsId( sh_alf_cc_cr_aps_id );
3719
3720
0
          const APS* APStoCheckCcCr = parameterSetManager->getAPS( sh_alf_cc_cr_aps_id, ALF_APS );
3721
0
          CHECK( !APStoCheckCcCr, "referenced APS not found" );
3722
0
          CHECK( APStoCheckCcCr->getCcAlfAPSParam().newCcAlfFilter[1] != 1,
3723
0
                             "The value of alf_cc_cr_filter_signal_flag of the APS NAL unit having aps_params_type equal to ALF_APS and "
3724
0
                             "aps_adaptation_parameter_set_id equal to sh_alf_cc_cr_aps_id shall be equal to 1." );
3725
0
        }
3726
0
      }
3727
0
    }
3728
0
  }
3729
3730
10
  if( picHeader->getLmcsEnabledFlag() && !sh_picture_header_in_slice_header_flag )
3731
0
  {
3732
0
    X_READ_FLAG( sh_lmcs_used_flag );
3733
0
    pcSlice->setLmcsEnabledFlag( sh_lmcs_used_flag );
3734
0
  }
3735
3736
10
  if( picHeader->getExplicitScalingListEnabledFlag() && !sh_picture_header_in_slice_header_flag )
3737
0
  {
3738
0
    X_READ_FLAG( sh_explicit_scaling_list_used_flag );
3739
0
    pcSlice->setExplicitScalingListUsed( sh_explicit_scaling_list_used_flag );
3740
0
  }
3741
3742
10
  if( pps->getRplInfoInPhFlag() )
3743
0
  {
3744
    // inheritFromPicHeader() already called
3745
0
  }
3746
10
  else if( pcSlice->getIdrPicFlag() && !sps->getIDRRefParamListPresent() )
3747
0
  {
3748
0
    pcSlice->clearRPL( REF_PIC_LIST_0 );
3749
0
    pcSlice->clearRPL( REF_PIC_LIST_1 );
3750
0
  }
3751
10
  else
3752
10
  {
3753
10
    parsePicOrSliceHeaderRPL( pcSlice, sps, pps );
3754
10
  }
3755
3756
10
  bool     numRefIdxActiveOverrideFlag = true;
3757
10
  unsigned numRefIdxActiveMinus1[2]    = { 0, 0 };
3758
10
  if( ( !pcSlice->isIntra() && pcSlice->getRPL( REF_PIC_LIST_0 )->getNumRefEntries() > 1 ) ||   //
3759
0
      ( pcSlice->isInterB() && pcSlice->getRPL( REF_PIC_LIST_1 )->getNumRefEntries() > 1 ) )
3760
0
  {
3761
0
    X_READ_FLAG( sh_num_ref_idx_active_override_flag );
3762
0
    numRefIdxActiveOverrideFlag = sh_num_ref_idx_active_override_flag;
3763
3764
0
    if( sh_num_ref_idx_active_override_flag )
3765
0
    {
3766
0
      for( int i = 0; i < ( pcSlice->isInterB() ? 2 : 1 ); ++i )
3767
0
      {
3768
0
        if( pcSlice->getRPL( (RefPicList) i )->getNumRefEntries() > 1 )
3769
0
        {
3770
0
          X_READ_UVLC_idx( sh_num_ref_idx_active_minus1, "[ i ]", 0, 14 );
3771
0
          numRefIdxActiveMinus1[i] = sh_num_ref_idx_active_minus1;
3772
0
        }
3773
0
      }
3774
0
    }
3775
0
  }
3776
3777
10
  for( auto i: { REF_PIC_LIST_0, REF_PIC_LIST_1 } )
3778
0
  {
3779
0
    if( pcSlice->isInterB() || ( pcSlice->isInterP() && i == REF_PIC_LIST_0 ) )
3780
0
    {
3781
0
      if( numRefIdxActiveOverrideFlag )
3782
0
      {
3783
0
        pcSlice->setNumRefIdx( i, numRefIdxActiveMinus1[i] + 1 );
3784
0
      }
3785
0
      else
3786
0
      {
3787
0
        const int pps_num_ref_idx_default_active_minus1 = ( i == 0 ? pps->getNumRefIdxL0DefaultActive() : pps->getNumRefIdxL1DefaultActive() ) - 1;
3788
0
        if( pcSlice->getRPL( i )->getNumRefEntries() >= pps_num_ref_idx_default_active_minus1 + 1 )
3789
0
        {
3790
0
          pcSlice->setNumRefIdx( i, pps_num_ref_idx_default_active_minus1 + 1 );
3791
0
        }
3792
0
        else
3793
0
        {
3794
0
          pcSlice->setNumRefIdx( i, pcSlice->getRPL( i )->getNumRefEntries() );
3795
0
        }
3796
0
      }
3797
0
    }
3798
0
    else /* sh_slice_type == I || ( sh_slice_type == P && i == 1 ) */
3799
0
    {
3800
0
      pcSlice->setNumRefIdx( i, 0 );
3801
0
    }
3802
0
  }
3803
3804
10
  if( pcSlice->isInterP() || pcSlice->isInterB() )
3805
0
  {
3806
0
    CHECK( pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) == 0, "Number of active entries in RPL0 of P or B picture shall be greater than 0" );
3807
0
    if( pcSlice->isInterB() )
3808
0
    {
3809
0
      CHECK( pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) == 0, "Number of active entries in RPL1 of B picture shall be greater than 0" );
3810
0
    }
3811
0
  }
3812
3813
10
  if( !pcSlice->isIntra() )
3814
0
  {
3815
0
    if( pps->getCabacInitPresentFlag() )
3816
0
    {
3817
0
      X_READ_FLAG( sh_cabac_init_flag );
3818
0
      pcSlice->setCabacInitFlag( sh_cabac_init_flag );
3819
0
    }
3820
3821
0
    if( picHeader->getEnableTMVPFlag() && !pps->getRplInfoInPhFlag() )
3822
0
    {
3823
0
      if( pcSlice->isInterB() )
3824
0
      {
3825
0
        X_READ_FLAG( sh_collocated_from_l0_flag );
3826
0
        pcSlice->setColFromL0Flag( sh_collocated_from_l0_flag );
3827
0
      }
3828
3829
0
      if( ( pcSlice->getColFromL0Flag() && pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) > 1 )
3830
0
          || ( !pcSlice->getColFromL0Flag() && pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) > 1 ) )
3831
0
      {
3832
0
        X_READ_UVLC( sh_collocated_ref_idx, 0, pcSlice->getNumRefIdx( pcSlice->getColFromL0Flag() ? REF_PIC_LIST_0 : REF_PIC_LIST_1 ) - 1u );
3833
3834
0
        pcSlice->setColRefIdx( sh_collocated_ref_idx );
3835
0
      }
3836
0
    }
3837
3838
0
    if( !pps->getWpInfoInPhFlag() &&
3839
0
        ( ( pps->getUseWP() && pcSlice->isInterP() ) || ( pps->getWPBiPred() && pcSlice->isInterB() ) ) )
3840
0
    {
3841
0
      parsePredWeightTable( pcSlice, sps, pps, { pcSlice->getNumRefIdx( REF_PIC_LIST_0 ), pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) } );
3842
0
    }
3843
3844
0
    if( pps->getWpInfoInPhFlag() )
3845
0
    {
3846
0
      CHECK( pps->getUseWP() && pcSlice->isInterP() && pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) > picHeader->getNumL0Weights(),
3847
0
             "When pps_wp_info_in_ph_flag is equal to 1, pps_weighted_pred_flag is equal to 1, and sh_slice_type is equal to P,"
3848
0
             " NumRefIdxActive[ 0 ] shall be less than or equal to the value of NumWeightsL0." );
3849
0
      CHECK( pps->getWPBiPred() && pcSlice->isInterB() && pcSlice->getNumRefIdx( REF_PIC_LIST_0 ) > picHeader->getNumL0Weights(),
3850
0
             "When pps_wp_info_in_ph_flag is equal to 1, pps_weighted_bipred_flag is equal to 1, and sh_slice_type is equal to B,"
3851
0
             " NumRefIdxActive[ 0 ] shall be less than or equal to the value of NumWeightsL0." );
3852
0
      CHECK( pps->getWPBiPred() && pcSlice->isInterB() && pcSlice->getNumRefIdx( REF_PIC_LIST_1 ) > picHeader->getNumL1Weights(),
3853
0
             "When pps_wp_info_in_ph_flag is equal to 1, pps_weighted_bipred_flag is equal to 1, and sh_slice_type is equal to B, "
3854
0
             " the value of NumRefIdxActive[ 1 ] shall be less than or equal to the value of NumWeightsL1." );
3855
0
    }
3856
0
  }
3857
3858
10
  if( !pps->getQpDeltaInfoInPhFlag() )
3859
0
  {
3860
0
    X_READ_SVLC_NO_RANGE( sh_qp_delta );
3861
3862
0
    int SliceQpY = 26 + pps->getPicInitQPMinus26() + sh_qp_delta;
3863
0
    CHECK_READ_RANGE( SliceQpY, -sps->getQpBDOffset(), MAX_QP, SliceQpY );
3864
3865
0
    pcSlice->setSliceQp( SliceQpY );
3866
0
  }
3867
3868
10
  if( pps->getSliceChromaQpFlag() )
3869
0
  {
3870
0
    X_READ_SVLC( sh_cb_qp_offset, -12, +12 );
3871
0
    CHECK_READ_RANGE( sh_cb_qp_offset + pps->getQpOffset( COMPONENT_Cb ), -12, +12, "pps_cb_qp_offset + sh_cb_qp_offset" );
3872
0
    pcSlice->setSliceChromaQpDelta( COMPONENT_Cb, sh_cb_qp_offset );
3873
3874
0
    X_READ_SVLC( sh_cr_qp_offset, -12, +12 );
3875
0
    CHECK_READ_RANGE( sh_cr_qp_offset + pps->getQpOffset( COMPONENT_Cr ), -12, +12, "pps_cr_qp_offset + sh_cr_qp_offset" );
3876
0
    pcSlice->setSliceChromaQpDelta( COMPONENT_Cr, sh_cr_qp_offset );
3877
3878
0
    if( sps->getJointCbCrEnabledFlag() )
3879
0
    {
3880
0
      X_READ_SVLC( sh_joint_cbcr_qp_offset, -12, +12 );
3881
0
      CHECK_READ_RANGE( sh_joint_cbcr_qp_offset + pps->getQpOffset( JOINT_CbCr ), -12, +12, "pps_joint_cbcr_qp_offset_value + sh_joint_cbcr_qp_offset" );
3882
0
      pcSlice->setSliceChromaQpDelta( JOINT_CbCr, sh_joint_cbcr_qp_offset );
3883
0
    }
3884
0
  }
3885
10
  if( pps->getCuChromaQpOffsetEnabledFlag() )
3886
0
  {
3887
0
    X_READ_FLAG( sh_cu_chroma_qp_offset_enabled_flag );
3888
0
    pcSlice->setUseChromaQpAdj( sh_cu_chroma_qp_offset_enabled_flag );
3889
0
  }
3890
3891
10
  if( sps->getUseSAO() && !pps->getSaoInfoInPhFlag() )
3892
0
  {
3893
0
    X_READ_FLAG( sh_sao_luma_used_flag );
3894
0
    pcSlice->setSaoEnabledFlag( CHANNEL_TYPE_LUMA, sh_sao_luma_used_flag );
3895
3896
0
    if( bChroma )
3897
0
    {
3898
0
      X_READ_FLAG( sh_sao_chroma_used_flag );
3899
0
      pcSlice->setSaoEnabledFlag( CHANNEL_TYPE_CHROMA, sh_sao_chroma_used_flag );
3900
0
    }
3901
0
  }
3902
3903
10
  if( pps->getDeblockingFilterOverrideEnabledFlag() && !pps->getDbfInfoInPhFlag() )
3904
0
  {
3905
0
    X_READ_FLAG( sh_deblocking_params_present_flag );
3906
0
    pcSlice->setDeblockingFilterOverrideFlag( sh_deblocking_params_present_flag );
3907
0
  }
3908
  // If pps_deblocking_filter_disabled_flag and sh_deblocking_params_present_flag are both equal to 1, the value of sh_deblocking_filter_disabled_flag is
3909
  // inferred to be equal to 0.
3910
  // Otherwise (pps_deblocking_filter_disabled_flag or sh_deblocking_params_present_flag is equal to 0), the value of sh_deblocking_filter_disabled_flag is
3911
  // inferred to be equal to ph_deblocking_filter_disabled_flag.
3912
10
  pcSlice->setDeblockingFilterDisable( pps->getPPSDeblockingFilterDisabledFlag() && pcSlice->getDeblockingFilterOverrideFlag()
3913
10
                                       ? 0 : picHeader->getDeblockingFilterDisable() );
3914
3915
10
  if( pcSlice->getDeblockingFilterOverrideFlag() )
3916
0
  {
3917
0
    if( !pps->getPPSDeblockingFilterDisabledFlag() )
3918
0
    {
3919
0
      X_READ_FLAG( sh_deblocking_filter_disabled_flag );
3920
0
      pcSlice->setDeblockingFilterDisable( sh_deblocking_filter_disabled_flag );
3921
0
    }
3922
3923
0
    if( !pcSlice->getDeblockingFilterDisable() )
3924
0
    {
3925
0
      X_READ_SVLC( sh_luma_beta_offset_div2, -12, 12 );
3926
0
      pcSlice->setDeblockingFilterBetaOffsetDiv2( sh_luma_beta_offset_div2 );
3927
0
      X_READ_SVLC( sh_luma_tc_offset_div2, -12, 12 );
3928
0
      pcSlice->setDeblockingFilterTcOffsetDiv2( sh_luma_tc_offset_div2 );
3929
0
    }
3930
0
  }
3931
3932
10
  if( pcSlice->getDeblockingFilterOverrideFlag() && !pcSlice->getDeblockingFilterDisable() && pps->getPPSChromaToolFlag() )
3933
0
  {
3934
0
    X_READ_SVLC( sh_cb_beta_offset_div2, -12, 12 );
3935
0
    pcSlice->setDeblockingFilterCbBetaOffsetDiv2( sh_cb_beta_offset_div2 );
3936
3937
0
    X_READ_SVLC( sh_cb_tc_offset_div2, -12, 12 );
3938
0
    pcSlice->setDeblockingFilterCbTcOffsetDiv2( sh_cb_tc_offset_div2 );
3939
3940
0
    X_READ_SVLC( sh_cr_beta_offset_div2, -12, 12 );
3941
0
    pcSlice->setDeblockingFilterCrBetaOffsetDiv2( sh_cr_beta_offset_div2 );
3942
3943
0
    X_READ_SVLC( sh_cr_tc_offset_div2, -12, 12 );
3944
0
    pcSlice->setDeblockingFilterCrTcOffsetDiv2( sh_cr_tc_offset_div2 );
3945
0
  }
3946
10
  else
3947
10
  {
3948
10
    if( pps->getPPSChromaToolFlag() )
3949
0
    {
3950
      // If pps_chroma_tool_offsets_present_flag is equal to 1, the values of sh_cb_beta_offset_div2 and sh_cb_tc_offset_div2 are inferred to be equal to
3951
      // ph_cb_beta_offset_div2 and ph_cb_tc_offset_div2, respectively.
3952
      // If pps_chroma_tool_offsets_present_flag is equal to 1, the values of sh_cr_beta_offset_div2 and sh_cr_tc_offset_div2 are inferred to be equal to
3953
      // ph_cr_beta_offset_div2 and ph_cr_tc_offset_div2, respectively.
3954
3955
0
      pcSlice->setDeblockingFilterCbBetaOffsetDiv2( picHeader->getDeblockingFilterCbBetaOffsetDiv2() );
3956
0
      pcSlice->setDeblockingFilterCbTcOffsetDiv2  ( picHeader->getDeblockingFilterCbTcOffsetDiv2()   );
3957
0
      pcSlice->setDeblockingFilterCrBetaOffsetDiv2( picHeader->getDeblockingFilterCrBetaOffsetDiv2() );
3958
0
      pcSlice->setDeblockingFilterCrTcOffsetDiv2  ( picHeader->getDeblockingFilterCrTcOffsetDiv2()   );
3959
0
    }
3960
10
    else
3961
10
    {
3962
      // Otherwise (pps_chroma_tool_offsets_present_flag is equal to 0), the values of sh_cb_beta_offset_div2 and sh_cb_tc_offset_div2 are inferred to be equal to
3963
      // sh_luma_beta_offset_div2 and sh_luma_tc_offset_div2, respectively.
3964
      // Otherwise( pps_chroma_tool_offsets_present_flag is equal to 0 ), the values of sh_cr_beta_offset_div2 and sh_cr_tc_offset_div2 are inferred to be equal
3965
      // to sh_luma_beta_offset_div2 and sh_luma_tc_offset_div2, respectively.
3966
3967
10
      pcSlice->setDeblockingFilterCbBetaOffsetDiv2( pcSlice->getDeblockingFilterBetaOffsetDiv2() );
3968
10
      pcSlice->setDeblockingFilterCbTcOffsetDiv2  ( pcSlice->getDeblockingFilterTcOffsetDiv2()   );
3969
10
      pcSlice->setDeblockingFilterCrBetaOffsetDiv2( pcSlice->getDeblockingFilterBetaOffsetDiv2() );
3970
10
      pcSlice->setDeblockingFilterCrTcOffsetDiv2  ( pcSlice->getDeblockingFilterTcOffsetDiv2()   );
3971
10
    }
3972
10
  }
3973
3974
  // dependent quantization
3975
10
  if( sps->getDepQuantEnabledFlag() )
3976
0
  {
3977
0
    X_READ_FLAG( sh_dep_quant_used_flag );
3978
0
    pcSlice->setDepQuantEnabledFlag( sh_dep_quant_used_flag );
3979
0
  }
3980
3981
  // sign data hiding
3982
10
  if( sps->getSignDataHidingEnabledFlag() && !pcSlice->getDepQuantEnabledFlag() )
3983
0
  {
3984
0
    X_READ_FLAG( sh_sign_data_hiding_used_flag );
3985
0
    pcSlice->setSignDataHidingEnabledFlag( sh_sign_data_hiding_used_flag );
3986
0
  }
3987
3988
  // signal TS residual coding disabled flag
3989
10
  if( sps->getTransformSkipEnabledFlag() && !pcSlice->getDepQuantEnabledFlag() && !pcSlice->getSignDataHidingEnabledFlag() )
3990
0
  {
3991
0
    X_READ_FLAG( sh_ts_residual_coding_disabled_flag );
3992
0
    pcSlice->setTSResidualCodingDisabledFlag( sh_ts_residual_coding_disabled_flag );
3993
0
  }
3994
3995
10
  if( pps->getSliceHeaderExtensionPresentFlag() )
3996
0
  {
3997
0
    X_READ_UVLC( sh_slice_header_extension_length, 0, 256 );
3998
0
    for( int i = 0; i < sh_slice_header_extension_length; i++ )
3999
0
    {
4000
0
      X_READ_CODE_NO_RANGE_idx( sh_slice_header_extension_data_byte, "[ i ]", 8 );
4001
0
      (void) sh_slice_header_extension_data_byte;
4002
0
    }
4003
0
  }
4004
4005
10
  std::vector<uint32_t> entryPointOffset;
4006
10
  pcSlice->setNumEntryPoints( sps, pps );
4007
10
  if( pcSlice->getNumEntryPoints() > 0 )
4008
0
  {
4009
0
    entryPointOffset.resize( pcSlice->getNumEntryPoints() );
4010
4011
0
    X_READ_UVLC( sh_entry_offset_len_minus1, 0, 31 );
4012
0
    for( uint32_t idx = 0; idx < pcSlice->getNumEntryPoints(); idx++ )
4013
0
    {
4014
0
      X_READ_CODE_NO_RANGE_idx( sh_entry_point_offset_minus1, "[i]", sh_entry_offset_len_minus1 + 1 );
4015
0
      entryPointOffset[idx] = sh_entry_point_offset_minus1 + 1;
4016
0
    }
4017
0
  }
4018
4019
#if RExt__DECODER_DEBUG_BIT_STATISTICS
4020
  CodingStatistics::IncrementStatisticEP(STATS__BYTE_ALIGNMENT_BITS,m_pcBitstream->readByteAlignment(),0);
4021
#else
4022
10
  m_pcBitstream->readByteAlignment();
4023
10
#endif
4024
4025
4026
10
  if( pcSlice->getFirstCtuRsAddrInSlice() == 0 )
4027
0
  {
4028
0
    pcSlice->setDefaultClpRng( *sps );
4029
0
  }
4030
4031
10
  pcSlice->clearSubstreamSizes();
4032
4033
10
  if( pcSlice->getNumEntryPoints() > 0 )
4034
0
  {
4035
0
    int endOfSliceHeaderLocation = m_pcBitstream->getByteLocation();
4036
4037
    // Adjust endOfSliceHeaderLocation to account for emulation prevention bytes in the slice segment header
4038
0
    for( uint32_t curByteIdx = 0; curByteIdx < m_pcBitstream->numEmulationPreventionBytesRead(); curByteIdx++ )
4039
0
    {
4040
0
      if( m_pcBitstream->getEmulationPreventionByteLocation( curByteIdx ) < endOfSliceHeaderLocation )
4041
0
      {
4042
0
        endOfSliceHeaderLocation++;
4043
0
      }
4044
0
    }
4045
4046
0
    uint32_t prevEntryPoint = 0;
4047
0
    for( uint32_t idx = 0; idx < entryPointOffset.size(); idx++ )
4048
0
    {
4049
0
      const uint32_t currEntryPoint = prevEntryPoint + entryPointOffset[idx];
4050
4051
0
      int emulationPreventionByteCount = 0;
4052
0
      for( uint32_t curByteIdx = 0; curByteIdx < m_pcBitstream->numEmulationPreventionBytesRead(); curByteIdx++ )
4053
0
      {
4054
0
        if( m_pcBitstream->getEmulationPreventionByteLocation( curByteIdx ) >= prevEntryPoint + endOfSliceHeaderLocation
4055
0
            && m_pcBitstream->getEmulationPreventionByteLocation( curByteIdx ) < currEntryPoint + endOfSliceHeaderLocation )
4056
0
        {
4057
0
          emulationPreventionByteCount++;
4058
0
        }
4059
0
      }
4060
4061
0
      entryPointOffset[idx] -= emulationPreventionByteCount;
4062
4063
0
      prevEntryPoint = currEntryPoint;
4064
0
    }
4065
4066
0
    pcSlice->setSubstreamSizes( std::move( entryPointOffset ) );
4067
0
  }
4068
10
}
4069
4070
template<typename HeaderT>
4071
void HLSyntaxReader::parsePicOrSliceHeaderRPL( HeaderT* header, const SPS* sps, const PPS* pps )
4072
0
{
4073
0
  bool rplSpsFlag[2] = { false, false };
4074
4075
  // List0 and List1
4076
0
  for( RefPicList listIdx: { REF_PIC_LIST_0, REF_PIC_LIST_1 } )
4077
0
  {
4078
0
    const unsigned sps_num_ref_pic_lists_i   = sps->getNumRPL( listIdx );
4079
0
    const bool     pps_rpl1_idx_present_flag = pps->getRpl1IdxPresentFlag();
4080
4081
0
    if( sps_num_ref_pic_lists_i > 0 && ( listIdx == 0 || ( listIdx == 1 && pps_rpl1_idx_present_flag ) ) )
4082
0
    {
4083
0
      X_READ_FLAG_idx( ref_pic_list_sps_flag, "[i]" );   // rpl_sps_flag[i] in the standard
4084
0
      rplSpsFlag[listIdx] = ref_pic_list_sps_flag;
4085
0
    }
4086
0
    else if( sps_num_ref_pic_lists_i == 0 )
4087
0
    {
4088
0
      rplSpsFlag[listIdx] = false;
4089
0
    }
4090
0
    else if( sps_num_ref_pic_lists_i > 0 && !pps_rpl1_idx_present_flag && listIdx == REF_PIC_LIST_1 )
4091
0
    {
4092
0
      rplSpsFlag[listIdx] = rplSpsFlag[0];
4093
0
    }
4094
4095
0
    if( rplSpsFlag[listIdx] )
4096
0
    {
4097
      // When rpl_sps_flag[ i ] is equal to 1 and sps_num_ref_pic_lists[ i ] is equal to 1, the value of rpl_idx[ i ] is inferred to be
4098
      // equal to 0. When rpl_sps_flag[ 1 ] is equal to 1, pps_rpl1_idx_present_flag is equal to 0, and sps_num_ref_pic_lists[ 1 ]
4099
      // is greater than 1, the value of rpl_idx[ 1 ] is inferred to be equal to rpl_idx[ 0 ].
4100
0
      int rpl_idx_i = 0;
4101
0
      if( rplSpsFlag[listIdx] && sps_num_ref_pic_lists_i == 1 )
4102
0
      {
4103
0
        rpl_idx_i = 0;
4104
0
      }
4105
0
      else if( listIdx == REF_PIC_LIST_1 && rplSpsFlag[1] && !pps_rpl1_idx_present_flag && sps->getNumRPL( REF_PIC_LIST_1 ) > 1 )
4106
0
      {
4107
0
        rpl_idx_i = header->getRPLIdx( REF_PIC_LIST_0 );
4108
0
      }
4109
4110
0
      if( sps_num_ref_pic_lists_i > 1 && ( listIdx == REF_PIC_LIST_0 || ( listIdx == REF_PIC_LIST_1 && pps_rpl1_idx_present_flag ) ) )
4111
0
      {
4112
0
        int numBits = std::ceil( std::log2( sps_num_ref_pic_lists_i ) );
4113
0
        X_READ_CODE_idx( ref_pic_list_idx, "[ listIdx ]", numBits, 0, sps_num_ref_pic_lists_i - 1 );   // rpl_idx[i] in the standard
4114
0
        rpl_idx_i = ref_pic_list_idx;
4115
0
      }
4116
4117
0
      CHECK( rpl_idx_i < 0 || rpl_idx_i > (int) sps_num_ref_pic_lists_i - 1,
4118
0
             "The value of rpl_idx[ i ] shall be in the range of 0 to sps_num_ref_pic_lists[ i ] - 1, inclusive." );
4119
4120
0
      header->setRPL( listIdx, sps->getRPLList( listIdx )[rpl_idx_i] );
4121
0
      header->setRPLIdx( listIdx, rpl_idx_i );
4122
0
    }
4123
0
    else
4124
0
    {
4125
0
      header->clearRPL( listIdx );
4126
0
      parseRefPicList( header->getRPL( listIdx ), -1, sps );   // ref_pic_list_struct( i, sps_num_ref_pic_lists[ i ] )
4127
0
      header->setRPLIdx( listIdx, -1 );
4128
0
    }
4129
4130
0
    if( std::is_same<HeaderT, PicHeader>::value )   // The contained CHECK is only valid, when we are in a PicHeader.
4131
0
    {
4132
      // The reinterpret_cast<> is a no-op, but it's needed for compilation. It's never executed in the case, when HeaderT is not a PicHeader due to the
4133
      // surrounding if-condition
4134
0
      CHECK( pps->getRplInfoInPhFlag() && reinterpret_cast<PicHeader*>( header )->getPicInterSliceAllowedFlag()
4135
0
               && header->getRPL( REF_PIC_LIST_0 )->getNumRefEntries() <= 0,
4136
0
             "When pps_rpl_info_in_ph_flag is equal to 1 and ph_inter_slice_allowed_flag is equal to 1, the value of"
4137
0
             " num_ref_entries[ 0 ][ RplsIdx[ 0 ] ] shall be greater than 0." )
4138
0
    }
4139
4140
    // Deal POC Msb cycle signalling for LTRP
4141
0
    auto* rpl = header->getRPL( listIdx );
4142
0
    for( int j = 0; j < rpl->getNumRefEntries(); ++j )
4143
0
    {
4144
0
      if( !rpl->isRefPicLongterm( j ) )
4145
0
      {
4146
0
        continue;
4147
0
      }
4148
4149
0
      if( rpl->getLtrpInSliceHeaderFlag() )
4150
0
      {
4151
0
        X_READ_CODE_NO_RANGE_idx( poc_lsb_lt, "[i][j]", sps->getBitsForPOC() );
4152
0
        rpl->setRefPicIdentifier( j, poc_lsb_lt, true, false, 0 );
4153
0
      }
4154
4155
0
      X_READ_FLAG_idx( delta_poc_msb_cycle_present_flag, "[i][j]" );
4156
0
      rpl->setDeltaPocMSBPresentFlag( j, delta_poc_msb_cycle_present_flag );
4157
4158
0
      if( delta_poc_msb_cycle_present_flag )
4159
0
      {
4160
0
        X_READ_UVLC( delta_poc_msb_cycle_lt, 0, 1 << ( 32 - sps->getBitsForPOC() ) );
4161
0
        rpl->setDeltaPocMSBCycleLT( j, delta_poc_msb_cycle_lt );
4162
0
      }
4163
0
    }
4164
0
  }
4165
0
}
Unexecuted instantiation: void vvdec::HLSyntaxReader::parsePicOrSliceHeaderRPL<vvdec::PicHeader>(vvdec::PicHeader*, vvdec::SPS const*, vvdec::PPS const*)
Unexecuted instantiation: void vvdec::HLSyntaxReader::parsePicOrSliceHeaderRPL<vvdec::Slice>(vvdec::Slice*, vvdec::SPS const*, vvdec::PPS const*)
4166
4167
void HLSyntaxReader::parseConstraintInfo( ConstraintInfo *cinfo )
4168
86
{
4169
86
  uint32_t symbol;
4170
86
  READ_FLAG( symbol, "gci_present_flag" );                                   cinfo->setGciPresentFlag( symbol ? true : false );
4171
86
  if( cinfo->getGciPresentFlag() )
4172
50
  {
4173
    /* general */
4174
50
    READ_FLAG( symbol, "gci_intra_only_constraint_flag" );                   cinfo->setIntraOnlyConstraintFlag( symbol ? true : false );
4175
50
    READ_FLAG( symbol, "gci_all_layers_independent_constraint_flag" );       cinfo->setAllLayersIndependentConstraintFlag( symbol ? true : false );
4176
50
    READ_FLAG( symbol, "gci_one_au_only_constraint_flag" );                  cinfo->setOnePictureOnlyConstraintFlag( symbol ? true : false );
4177
4178
    /* picture format */
4179
50
    READ_CODE( 4, symbol, "gci_sixteen_minus_max_bitdepth_constraint_idc" ); cinfo->setMaxBitDepthConstraintIdc( symbol>8 ? 16 : ( 16 - symbol ) );
4180
50
    CHECK(symbol>8, "gci_sixteen_minus_max_bitdepth_constraint_idc shall be in the range 0 to 8, inclusive");
4181
44
    READ_CODE( 2, symbol, "gci_three_minus_max_chroma_format_constraint_idc" );
4182
44
    cinfo->setMaxChromaFormatConstraintIdc( (ChromaFormat)( 3 - symbol ) );
4183
4184
    /* NAL unit type related */
4185
44
    READ_FLAG( symbol, "gci_no_mixed_nalu_types_in_pic_constraint_flag" );   cinfo->setNoMixedNaluTypesInPicConstraintFlag( symbol > 0 ? true : false );
4186
44
    READ_FLAG( symbol, "gci_no_trail_constraint_flag" );                     cinfo->setNoTrailConstraintFlag( symbol > 0 ? true : false );
4187
44
    READ_FLAG( symbol, "gci_no_stsa_constraint_flag" );                      cinfo->setNoStsaConstraintFlag( symbol > 0 ? true : false );
4188
44
    READ_FLAG( symbol, "gci_no_rasl_constraint_flag" );                      cinfo->setNoRaslConstraintFlag( symbol > 0 ? true : false );
4189
44
    READ_FLAG( symbol, "gci_no_radl_constraint_flag" );                      cinfo->setNoRadlConstraintFlag( symbol > 0 ? true : false );
4190
44
    READ_FLAG( symbol, "gci_no_idr_constraint_flag" );                       cinfo->setNoIdrConstraintFlag( symbol > 0 ? true : false );
4191
44
    READ_FLAG( symbol, "gci_no_cra_constraint_flag" );                       cinfo->setNoCraConstraintFlag( symbol > 0 ? true : false );
4192
44
    READ_FLAG( symbol, "gci_no_gdr_constraint_flag" );                       cinfo->setNoGdrConstraintFlag( symbol > 0 ? true : false );
4193
44
    READ_FLAG( symbol, "gci_no_aps_constraint_flag" );                       cinfo->setNoApsConstraintFlag( symbol > 0 ? true : false );
4194
44
    READ_FLAG( symbol, "gci_no_idr_rpl_constraint_flag" );                   cinfo->setNoIdrRplConstraintFlag( symbol > 0 ? true : false );
4195
4196
    /* tile, slice, subpicture partitioning */
4197
44
    READ_FLAG( symbol, "gci_one_tile_per_pic_constraint_flag" );             cinfo->setOneTilePerPicConstraintFlag( symbol > 0 ? true : false );
4198
44
    READ_FLAG( symbol, "gci_pic_header_in_slice_header_constraint_flag" );   cinfo->setPicHeaderInSliceHeaderConstraintFlag( symbol > 0 ? true : false );
4199
44
    READ_FLAG( symbol, "gci_one_slice_per_pic_constraint_flag" );            cinfo->setOneSlicePerPicConstraintFlag( symbol > 0 ? true : false );
4200
44
    READ_FLAG( symbol, "gci_no_rectangular_slice_constraint_flag" );         cinfo->setNoRectSliceConstraintFlag( symbol > 0 ? true : false );
4201
44
    READ_FLAG( symbol, "gci_one_slice_per_subpic_constraint_flag" );         cinfo->setOneSlicePerSubpicConstraintFlag( symbol > 0 ? true : false );
4202
44
    READ_FLAG( symbol, "gci_no_subpic_info_constraint_flag" );               cinfo->setNoSubpicInfoConstraintFlag( symbol > 0 ? true : false );
4203
4204
    /* CTU and block partitioning */
4205
44
    READ_CODE( 2, symbol, "gci_three_minus_max_log2_ctu_size_constraint_idc");   cinfo->setMaxLog2CtuSizeConstraintIdc( ( ( 3 - symbol ) + 5 ) );
4206
44
    READ_FLAG( symbol, "gci_no_partition_constraints_override_constraint_flag"); cinfo->setNoPartitionConstraintsOverrideConstraintFlag( symbol > 0 ? true : false );
4207
44
    READ_FLAG( symbol, "gci_no_mtt_constraint_flag");                            cinfo->setNoMttConstraintFlag( symbol > 0 ? true : false);
4208
44
    READ_FLAG( symbol, "gci_no_qtbtt_dual_tree_intra_constraint_flag");          cinfo->setNoQtbttDualTreeIntraConstraintFlag( symbol > 0 ? true : false );
4209
4210
    /* intra */
4211
44
    READ_FLAG( symbol, "gci_no_palette_constraint_flag" );                   cinfo->setNoPaletteConstraintFlag( symbol > 0 ? true : false );
4212
44
    READ_FLAG( symbol, "gci_no_ibc_constraint_flag" );                       cinfo->setNoIbcConstraintFlag( symbol > 0 ? true : false );
4213
44
    READ_FLAG( symbol, "gci_no_isp_constraint_flag" );                       cinfo->setNoIspConstraintFlag( symbol > 0 ? true : false );
4214
44
    READ_FLAG( symbol, "gci_no_mrl_constraint_flag" );                       cinfo->setNoMrlConstraintFlag( symbol > 0 ? true : false );
4215
44
    READ_FLAG( symbol, "gci_no_mip_constraint_flag" );                       cinfo->setNoMipConstraintFlag( symbol > 0 ? true : false );
4216
44
    READ_FLAG( symbol, "gci_no_cclm_constraint_flag" );                      cinfo->setNoCclmConstraintFlag( symbol > 0 ? true : false );
4217
4218
    /* inter */
4219
44
    READ_FLAG( symbol, "gci_no_ref_pic_resampling_constraint_flag" );        cinfo->setNoRprConstraintFlag( symbol > 0 ? true : false );
4220
44
    READ_FLAG( symbol, "gci_no_res_change_in_clvs_constraint_flag" );        cinfo->setNoResChangeInClvsConstraintFlag( symbol > 0 ? true : false );
4221
44
    READ_FLAG( symbol, "gci_no_weighted_prediction_constraint_flag" );       cinfo->setNoWeightedPredictionConstraintFlag( symbol > 0 ? true : false );
4222
44
    READ_FLAG( symbol, "gci_no_ref_wraparound_constraint_flag" );            cinfo->setNoRefWraparoundConstraintFlag( symbol > 0 ? true : false );
4223
44
    READ_FLAG( symbol, "gci_no_temporal_mvp_constraint_flag" );              cinfo->setNoTemporalMvpConstraintFlag( symbol > 0 ? true : false );
4224
44
    READ_FLAG( symbol, "gci_no_sbtmvp_constraint_flag" );                    cinfo->setNoSbtmvpConstraintFlag( symbol > 0 ? true : false );
4225
44
    READ_FLAG( symbol, "gci_no_amvr_constraint_flag" );                      cinfo->setNoAmvrConstraintFlag( symbol > 0 ? true : false );
4226
44
    READ_FLAG( symbol, "gci_no_bdof_constraint_flag" );                      cinfo->setNoBdofConstraintFlag( symbol > 0 ? true : false );
4227
44
    READ_FLAG( symbol, "gci_no_smvd_constraint_flag" );                      cinfo->setNoSmvdConstraintFlag( symbol > 0 ? true : false );
4228
44
    READ_FLAG( symbol, "gci_no_dmvr_constraint_flag" );                      cinfo->setNoDmvrConstraintFlag( symbol > 0 ? true : false );
4229
44
    READ_FLAG( symbol, "gci_no_mmvd_constraint_flag" );                      cinfo->setNoMmvdConstraintFlag( symbol > 0 ? true : false );
4230
44
    READ_FLAG( symbol, "gci_no_affine_motion_constraint_flag" );             cinfo->setNoAffineMotionConstraintFlag( symbol > 0 ? true : false );
4231
44
    READ_FLAG( symbol, "gci_no_prof_constraint_flag" );                      cinfo->setNoProfConstraintFlag( symbol > 0 ? true : false );
4232
44
    READ_FLAG( symbol, "gci_no_bcw_constraint_flag" );                       cinfo->setNoBcwConstraintFlag( symbol > 0 ? true : false  );
4233
44
    READ_FLAG( symbol, "gci_no_ciip_constraint_flag" );                      cinfo->setNoCiipConstraintFlag( symbol > 0 ? true : false );
4234
44
    READ_FLAG( symbol, "gci_no_gpm_constraint_flag" );                       cinfo->setNoGeoConstraintFlag( symbol > 0 ? true : false );
4235
4236
    /* transform, quantization, residual */
4237
44
    READ_FLAG( symbol, "gci_no_luma_transform_size_64_constraint_flag" );    cinfo->setNoLumaTransformSize64ConstraintFlag( symbol > 0 ? true : false );
4238
44
    READ_FLAG( symbol, "gci_no_transform_skip_constraint_flag" );            cinfo->setNoTransformSkipConstraintFlag( symbol > 0 ? true : false );
4239
44
    READ_FLAG( symbol, "gci_no_bdpcm_constraint_flag" );                     cinfo->setNoBDPCMConstraintFlag( symbol > 0 ? true : false );
4240
44
    READ_FLAG( symbol, "gci_no_mts_constraint_flag" );                       cinfo->setNoMtsConstraintFlag( symbol > 0 ? true : false );
4241
44
    READ_FLAG( symbol, "gci_no_lfnst_constraint_flag" );                     cinfo->setNoLfnstConstraintFlag( symbol > 0 ? true : false );
4242
44
    READ_FLAG( symbol, "gci_no_joint_cbcr_constraint_flag" );                cinfo->setNoJointCbCrConstraintFlag( symbol > 0 ? true : false );
4243
44
    READ_FLAG( symbol, "gci_no_sbt_constraint_flag" );                       cinfo->setNoSbtConstraintFlag( symbol > 0 ? true : false );
4244
44
    READ_FLAG( symbol, "gci_no_act_constraint_flag" );                       cinfo->setNoActConstraintFlag( symbol > 0 ? true : false );
4245
44
    READ_FLAG( symbol, "gci_no_explicit_scaling_list_constraint_flag" );     cinfo->setNoExplicitScaleListConstraintFlag( symbol > 0 ? true : false );
4246
44
    READ_FLAG( symbol, "gci_no_dep_quant_constraint_flag" );                 cinfo->setNoDepQuantConstraintFlag( symbol > 0 ? true : false );
4247
44
    READ_FLAG( symbol, "gci_no_sign_data_hiding_constraint_flag" );          cinfo->setNoSignDataHidingConstraintFlag( symbol > 0 ? true : false) ;
4248
44
    READ_FLAG( symbol, "gci_no_cu_qp_delta_constraint_flag" );               cinfo->setNoQpDeltaConstraintFlag( symbol > 0 ? true : false );
4249
44
    READ_FLAG( symbol, "gci_no_chroma_qp_offset_constraint_flag" );          cinfo->setNoChromaQpOffsetConstraintFlag( symbol > 0 ? true : false );
4250
4251
    /* loop filter */
4252
44
    READ_FLAG( symbol, "gci_no_sao_constraint_flag" );                       cinfo->setNoSaoConstraintFlag( symbol > 0 ? true : false );
4253
44
    READ_FLAG( symbol, "gci_no_alf_constraint_flag" );                       cinfo->setNoAlfConstraintFlag( symbol > 0 ? true : false );
4254
44
    READ_FLAG( symbol, "gci_no_ccalf_constraint_flag" );                     cinfo->setNoCCAlfConstraintFlag( symbol > 0 ? true : false );
4255
44
    READ_FLAG( symbol, "gci_no_lmcs_constraint_flag" );                      cinfo->setNoLmcsConstraintFlag( symbol > 0 ? true : false );
4256
44
    READ_FLAG( symbol, "gci_no_ladf_constraint_flag" );                      cinfo->setNoLadfConstraintFlag( symbol > 0 ? true : false );
4257
44
    READ_FLAG( symbol, "gci_no_virtual_boundaries_constraint_flag" );        cinfo->setNoVirtualBoundaryConstraintFlag( symbol > 0 ? true : false );
4258
4259
44
    READ_CODE( 8, symbol, "gci_num_reserved_bits" );
4260
44
    uint32_t const numReservedBits = symbol;
4261
144
    for (int i = 0; i < numReservedBits; i++)
4262
112
    {
4263
112
      READ_FLAG( symbol, "gci_reserved_zero_bit" );                          CHECK( symbol != 0, "gci_reserved_zero_bit not equal to zero" );
4264
100
    }
4265
44
  }
4266
376
  while( !isByteAligned() )
4267
310
  {
4268
310
    READ_FLAG( symbol, "gci_alignment_zero_bit" );                           CHECK( symbol != 0, "gci_alignment_zero_bit not equal to zero" );
4269
308
  }
4270
68
}
4271
4272
4273
void HLSyntaxReader::parseProfileTierLevel( ProfileTierLevel *ptl, bool profileTierPresentFlag, int maxNumSubLayersMinus1 )
4274
98
{
4275
98
  if( profileTierPresentFlag )
4276
98
  {
4277
98
    X_READ_CODE_NO_RANGE( general_profile_idc, 7 );
4278
98
    ptl->setProfileIdc( Profile::Name( general_profile_idc ) );
4279
4280
98
    X_READ_FLAG( general_tier_flag );
4281
98
    ptl->setTierFlag( general_tier_flag ? Tier::HIGH : Tier::MAIN );
4282
98
  }
4283
4284
98
  X_READ_CODE_NO_RANGE( general_level_idc, 8 );
4285
98
  ptl->setLevelIdc( vvdecLevel( general_level_idc ) );
4286
4287
98
  X_READ_FLAG( ptl_frame_only_constraint_flag );
4288
98
  ptl->setFrameOnlyConstraintFlag( ptl_frame_only_constraint_flag );
4289
4290
98
  X_READ_FLAG( ptl_multilayer_enabled_flag );
4291
98
  ptl->setMultiLayerEnabledFlag( ptl_multilayer_enabled_flag );
4292
4293
98
  CHECK( ( ptl->getProfileIdc() == Profile::MAIN_10 || ptl->getProfileIdc() == Profile::MAIN_10_444
4294
98
        || ptl->getProfileIdc() == Profile::MAIN_10_STILL_PICTURE
4295
98
        || ptl->getProfileIdc() == Profile::MAIN_10_444_STILL_PICTURE )
4296
98
          && ptl_multilayer_enabled_flag,
4297
98
        "ptl_multilayer_enabled_flag shall be equal to 0 for non-multilayer profiles");
4298
4299
94
  CHECK_UNSUPPORTED( ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10 || ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10_STILL_PICTURE ||
4300
94
         ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10_444 || ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE,
4301
94
         "Multilayer profiles not yet supported" );
4302
4303
88
  if( ptl->getProfileIdc() == Profile::MAIN_10_444 || ptl->getProfileIdc() == Profile::MAIN_10_444_STILL_PICTURE )
4304
4
  {
4305
4
    msg( WARNING, "Warning: MAIN_10_444 and MAIN_10_444_STILL_PICTURE is still experimental.\n" );
4306
4
  }
4307
4308
88
  if( profileTierPresentFlag )
4309
86
  {
4310
86
    parseConstraintInfo( ptl->getConstraintInfo() );
4311
86
  }
4312
4313
214
  for( int i = maxNumSubLayersMinus1 - 1; i >= 0; i-- )
4314
126
  {
4315
126
    X_READ_FLAG_idx( sub_layer_level_present_flag, "[i]" );
4316
126
    ptl->setSubLayerLevelPresentFlag( i, sub_layer_level_present_flag );
4317
126
  }
4318
4319
170
  while( !isByteAligned() )
4320
82
  {
4321
82
    X_READ_FLAG( ptl_reserved_zero_bit );
4322
82
    CHECK_WARN( ptl_reserved_zero_bit != 0, "ptl_reserved_zero_bit not equal to zero" );
4323
82
  }
4324
4325
88
  ptl->setSubLayerLevelIdc( maxNumSubLayersMinus1, ptl->getLevelIdc() );
4326
214
  for( int i = maxNumSubLayersMinus1 - 1; i >= 0; i-- )
4327
126
  {
4328
126
    if( ptl->getSubLayerLevelPresentFlag( i ) )
4329
18
    {
4330
18
      X_READ_CODE_NO_RANGE_idx( sub_layer_level_idc, "[i]", 8 );
4331
18
      ptl->setSubLayerLevelIdc( i, vvdecLevel( sub_layer_level_idc ) );
4332
18
    }
4333
108
    else
4334
108
    {
4335
108
      ptl->setSubLayerLevelIdc( i, ptl->getSubLayerLevelIdc( i + 1 ) );
4336
108
    }
4337
126
  }
4338
4339
88
  if( profileTierPresentFlag )
4340
64
  {
4341
64
    X_READ_CODE_NO_RANGE( ptl_num_sub_profiles, 8 );
4342
64
    ptl->setNumSubProfile( ptl_num_sub_profiles );
4343
4344
126
    for( int i = 0; i < ptl_num_sub_profiles; i++ )
4345
62
    {
4346
62
      X_READ_CODE_NO_RANGE_idx( general_sub_profile_idc, "[i]", 32 );
4347
62
      ptl->setSubProfileIdc( i, general_sub_profile_idc );
4348
62
    }
4349
64
  }
4350
88
}
4351
4352
4353
// ====================================================================================================================
4354
// Protected member functions
4355
// ====================================================================================================================
4356
4357
//! parse explicit wp tables
4358
template<typename HeaderT>
4359
void HLSyntaxReader::parsePredWeightTable( HeaderT* sh_or_ph, const SPS* sps, const PPS* pps, std::array<int, 2> numRefIdxActive )
4360
0
{
4361
0
  const bool bChroma                  = sps->getChromaFormatIdc() != CHROMA_400;
4362
0
  const bool pps_wp_info_in_ph_flag   = pps->getWpInfoInPhFlag();
4363
0
  const bool pps_weighted_bipred_flag = pps->getWPBiPred();
4364
4365
0
  uint32_t log2WeightDenomChroma = 0;
4366
0
  uint32_t sumWeightFlags        = 0;
4367
4368
0
  X_READ_UVLC( luma_log2_weight_denom, 0, 7 );
4369
0
  if( bChroma )
4370
0
  {
4371
0
    X_READ_SVLC_NO_RANGE( delta_chroma_log2_weight_denom );
4372
0
    CHECK_READ_RANGE( luma_log2_weight_denom + delta_chroma_log2_weight_denom, 0, 7, "luma_log2_weight_denom + delta_chroma_log2_weight_denom" )
4373
4374
0
    log2WeightDenomChroma = luma_log2_weight_denom + delta_chroma_log2_weight_denom;
4375
0
  }
4376
4377
0
  for( auto& l: { REF_PIC_LIST_0, REF_PIC_LIST_1 } )
4378
0
  {
4379
0
    const int num_ref_entries = sh_or_ph->getRPL( l )->getNumRefEntries();
4380
4381
0
    unsigned numWeights = numRefIdxActive[l];
4382
0
    if( l == REF_PIC_LIST_0 )
4383
0
    {
4384
      // derive NumWeightsL0
4385
0
      if( pps_wp_info_in_ph_flag )
4386
0
      {
4387
0
        X_READ_UVLC( num_l0_weights, 1, std::min<unsigned>( 15, num_ref_entries ) );
4388
0
        numWeights = num_l0_weights;
4389
4390
0
        CHECK( ( !std::is_same<HeaderT, PicHeader>::value ),
4391
0
               "Implementation error: parsePredWeightTable() should not be called with a Slice, when pps_wp_info_in_ph_flag is true." );
4392
0
        if( std::is_same<HeaderT, PicHeader>::value )
4393
0
        {
4394
          // We know HeaderT is a PicHeader, so we use reinterpret_cast here just so it compiles for the HeaderT==Slice case.
4395
0
          reinterpret_cast<PicHeader*>( sh_or_ph )->setNumL0Weights( num_l0_weights );
4396
0
        }
4397
0
      }
4398
0
    }
4399
0
    else if( l == REF_PIC_LIST_1 )
4400
0
    {
4401
      // The variable NumWeightsL1 is derived as follows (semantics section):
4402
0
      if( !pps_weighted_bipred_flag || ( pps_wp_info_in_ph_flag && num_ref_entries == 0 ) )
4403
0
      {
4404
0
        numWeights = 0;
4405
0
      }
4406
0
      else if( pps_weighted_bipred_flag )   // condition from semantics section
4407
0
      {
4408
        // What should numWeights be set, when pps_weighted_bipred_flag && !pps_wp_info_in_ph_flag && num_ref_entries > 0 ?
4409
        // According to the syntax section num_l1_weights isn't read, but the semantics says, we should set NumWeightsL1 = num_l1_weights.
4410
        // It seems to work, when we leave numWeights set to NumRefIdxActive[ 1 ].
4411
        //CHECK( pps_weighted_bipred_flag && !pps_wp_info_in_ph_flag && num_ref_entries > 0,
4412
        //       "don't know how to set NumWeightsL1: it's missing from the spec" );
4413
4414
0
        if( pps_weighted_bipred_flag && pps_wp_info_in_ph_flag && num_ref_entries > 0 )   // condition from syntax section
4415
0
        {
4416
0
          X_READ_UVLC( num_l1_weights, 1, std::min<unsigned>( 15, num_ref_entries ) );
4417
0
          numWeights = num_l1_weights;
4418
4419
0
          CHECK( ( !std::is_same<HeaderT, PicHeader>::value ),
4420
0
                 "Implementation error: parsePredWeightTable() should not be called with a Slice, when pps_wp_info_in_ph_flag is true." );
4421
0
          if( std::is_same<HeaderT, PicHeader>::value )
4422
0
          {
4423
            // We know HeaderT is a PicHeader, so we use reinterpret_cast here just so it compiles for the HeaderT==Slice case.
4424
0
            reinterpret_cast<PicHeader*>( sh_or_ph )->setNumL1Weights( num_l1_weights );
4425
0
          }
4426
0
        }
4427
0
      }
4428
0
    }
4429
4430
0
    for( int i = 0; i < numWeights; i++ )
4431
0
    {
4432
0
      WPScalingParam* wp;
4433
0
      sh_or_ph->getWpScaling( l, i, wp );
4434
4435
0
      X_READ_FLAG_idx( luma_weight_lX_flag, "[i]" );
4436
0
      wp[COMPONENT_Y].bPresentFlag      = luma_weight_lX_flag;
4437
0
      wp[COMPONENT_Y].uiLog2WeightDenom = luma_log2_weight_denom;
4438
4439
0
      sumWeightFlags += luma_weight_lX_flag;
4440
0
    }
4441
4442
0
    if( bChroma )
4443
0
    {
4444
0
      for( int i = 0; i < numWeights; i++ )
4445
0
      {
4446
0
        WPScalingParam* wp;
4447
0
        sh_or_ph->getWpScaling( l, i, wp );
4448
4449
0
        X_READ_FLAG_idx( chroma_weight_lX_flag, "[i]" );
4450
0
        wp[COMPONENT_Cb].bPresentFlag      = wp[COMPONENT_Cr].bPresentFlag      = chroma_weight_lX_flag;
4451
0
        wp[COMPONENT_Cb].uiLog2WeightDenom = wp[COMPONENT_Cr].uiLog2WeightDenom = log2WeightDenomChroma;
4452
4453
0
        sumWeightFlags += 2 * chroma_weight_lX_flag;
4454
0
      }
4455
0
    }
4456
4457
0
    for( int i = 0; i < numWeights; i++ )
4458
0
    {
4459
0
      WPScalingParam* wp;
4460
0
      sh_or_ph->getWpScaling( l, i, wp );
4461
4462
0
      wp[COMPONENT_Y].iWeight = ( 1 << wp[COMPONENT_Y].uiLog2WeightDenom );
4463
0
      wp[COMPONENT_Y].iOffset = 0;
4464
4465
0
      if( wp[COMPONENT_Y].bPresentFlag /*luma_weight_l0_flag[i]*/ )
4466
0
      {
4467
0
        X_READ_SVLC_idx( delta_luma_weight_lX, "[i]", -128, 127 );
4468
0
        wp[COMPONENT_Y].iWeight += delta_luma_weight_lX;
4469
4470
0
        X_READ_SVLC_idx( luma_offset_lX, "[i]", -128, 127 );
4471
0
        wp[COMPONENT_Y].iOffset = luma_offset_lX;
4472
0
      }
4473
4474
0
      for( int j = COMPONENT_Cb; j < MAX_NUM_COMPONENT; j++ )
4475
0
      {
4476
0
        wp[j].iWeight = ( 1 << wp[j].uiLog2WeightDenom );
4477
0
        wp[j].iOffset = 0;
4478
0
        if( wp[j].bPresentFlag /*chroma_weight_l0_flag[i]*/ )
4479
0
        {
4480
0
          X_READ_SVLC_idx( delta_chroma_weight_lX, "[i][j]", -128, 127 );
4481
0
          wp[j].iWeight += delta_chroma_weight_lX;
4482
4483
0
          X_READ_SVLC_idx( delta_chroma_offset_lX, "[i][j]", -4 * 128, 4 * 127 );
4484
0
          wp[j].iOffset = Clip3( -128, 127, 128 + delta_chroma_offset_lX - ( ( 128 * wp[j].iWeight ) >> wp[j].uiLog2WeightDenom ) );
4485
0
        }
4486
0
      }
4487
0
    }
4488
4489
0
    for( int iRefIdx = numWeights; iRefIdx < MAX_NUM_REF; iRefIdx++ )
4490
0
    {
4491
0
      WPScalingParam* wp;
4492
0
      sh_or_ph->getWpScaling( l, iRefIdx, wp );
4493
4494
0
      wp[0].bPresentFlag = false;
4495
0
      wp[1].bPresentFlag = false;
4496
0
      wp[2].bPresentFlag = false;
4497
0
    }
4498
0
  }
4499
4500
0
  CHECK( sumWeightFlags > 24,
4501
0
         "It is a requirement of bitstream conformance that, when sh_slice_type is equal to P, sumWeightL0Flags shall be less than"
4502
0
         " or equal to 24 and when sh_slice_type is equal to B, the sum of sumWeightL0Flags and sumWeightL1Flags shall be less"
4503
0
         " than or equal to 24." );
4504
0
}
Unexecuted instantiation: void vvdec::HLSyntaxReader::parsePredWeightTable<vvdec::PicHeader>(vvdec::PicHeader*, vvdec::SPS const*, vvdec::PPS const*, std::__1::array<int, 2ul>)
Unexecuted instantiation: void vvdec::HLSyntaxReader::parsePredWeightTable<vvdec::Slice>(vvdec::Slice*, vvdec::SPS const*, vvdec::PPS const*, std::__1::array<int, 2ul>)
4505
4506
/** decode quantization matrix
4507
* \param scalingList quantization matrix information
4508
*/
4509
void HLSyntaxReader::parseScalingList( ScalingList *scalingList, bool aps_chromaPresentFlag )
4510
68
{
4511
68
  scalingList->reset();
4512
4513
1.32k
  for( int id = 0; id < 28; id++ )
4514
1.25k
  {
4515
1.25k
    if( aps_chromaPresentFlag || scalingList->isLumaScalingList( id ) )
4516
646
    {
4517
646
      X_READ_FLAG( scaling_list_copy_mode_flag );
4518
4519
646
      bool scalingListPredModeFlag = false;
4520
646
      if( !scaling_list_copy_mode_flag )
4521
108
      {
4522
108
        X_READ_FLAG( scaling_list_pred_mode_flag );
4523
108
        scalingListPredModeFlag = scaling_list_pred_mode_flag;
4524
108
      }
4525
4526
646
      int scalingListPredIdDelta = 0;
4527
646
      if( ( scaling_list_copy_mode_flag || scalingListPredModeFlag )
4528
564
          && id != SCALING_LIST_1D_START_2x2 && id != SCALING_LIST_1D_START_4x4
4529
496
          && id != SCALING_LIST_1D_START_8x8 )   // Copy Mode
4530
446
      {
4531
446
        const unsigned maxIdDelta = id < 2 ? id : ( id < 8 ? id - 2 : id - 8 );
4532
446
        X_READ_UVLC_idx( scaling_list_pred_id_delta, "[id]", 0, maxIdDelta );
4533
4534
446
        scalingListPredIdDelta = scaling_list_pred_id_delta;
4535
446
      }
4536
4537
646
      decodeScalingList( scalingList, id, scalingListPredIdDelta, scaling_list_copy_mode_flag, scalingListPredModeFlag );
4538
646
    }   // ( aps_chromaPresentFlag || scalingList->isLumaScalingList( id ) )
4539
1.25k
  }
4540
4541
68
  return;
4542
68
}
4543
4544
void HLSyntaxReader::decodeScalingList( ScalingList* scalingList, uint32_t id, uint32_t scalingListPredIdDelta, bool scalingListCopyModeFlag , bool scalingListPredModeFlag)
4545
630
{
4546
630
  const unsigned matrixSize = ScalingList::matrixSize( id );
4547
4548
630
  const int refId = id - scalingListPredIdDelta;
4549
630
  CHECK( refId<0, "refId < 0 doesn't make sense" );
4550
4551
630
  int   scalingMatrixDcPred = 0;
4552
630
  auto& scalingMatrixPred   = scalingList->getScalingListVec( id );   // we use the same storage for scalingMatrixPred and scalingMatrixRec
4553
630
  {
4554
    // Derive scalingMatrixPred and scalingMatrixDcPred
4555
4556
630
    const size_t scalingMatrixPred_size = matrixSize * matrixSize;
4557
630
    CHECK( scalingMatrixPred_size != scalingList->getScalingListVec( id ).size(), "wrong scalingMatrixPred/Rec[] size" )
4558
4559
630
    if( scalingListCopyModeFlag == 0 && scalingListPredModeFlag == 0 )
4560
80
    {
4561
80
      scalingMatrixPred.assign( scalingMatrixPred_size, 8 );
4562
80
      scalingMatrixDcPred = 8;
4563
80
    }
4564
550
    else if( scalingListPredIdDelta == 0 )
4565
500
    {
4566
500
      scalingMatrixPred.assign( scalingMatrixPred_size, 16 );
4567
500
      scalingMatrixDcPred = 16;
4568
500
    }
4569
50
    else
4570
50
    {
4571
50
      CHECK( ( scalingListCopyModeFlag == 0 && scalingListPredModeFlag == 0 ) || scalingListPredIdDelta <= 0,
4572
50
             "wrong condition: Otherwise (either scaling_list_copy_mode_flag[ id ] or scaling_list_pred_mode_flag[ id ] is equal to 1 and"
4573
50
             " scaling_list_pred_id_delta[ id ] is greater than 0)," );
4574
4575
50
      CHECK( scalingListCopyModeFlag == 0 && ( scalingListPredModeFlag == 0 || scalingListPredIdDelta <= 0 ),
4576
50
             "wrong condition: Otherwise (either scaling_list_copy_mode_flag[ id ] or scaling_list_pred_mode_flag[ id ] is equal to 1 and"
4577
50
             " scaling_list_pred_id_delta[ id ] is greater than 0)," );
4578
4579
      // scalingMatrixPred is set equal to ScalingMatrixRec[ refId ]
4580
50
      scalingMatrixPred = scalingList->getScalingListVec( refId );
4581
4582
260
#define MINUS_14 -( 14 * 0 )   // TODO: where did the -14 from the standard go ? when it is there, it breaks decoding.
4583
4584
50
      scalingMatrixDcPred = refId > 13 ? scalingList->getScalingListDC( refId MINUS_14 ) : scalingList->getScalingListVec( id )[0];
4585
50
    }
4586
630
  }
4587
4588
630
  if( scalingListCopyModeFlag )
4589
524
  {
4590
    // When not present, the value of scaling_list_dc_coef[id − 14] is inferred to be equal to 0.
4591
524
    if( id >= 14 )
4592
188
    {
4593
188
      scalingList->setScalingListDC( id MINUS_14, scalingMatrixDcPred );
4594
188
    }
4595
524
    return;
4596
524
  }
4597
4598
106
  const auto& DiagScanOrder = g_scanOrder[SCAN_UNGROUPED];
4599
4600
106
  int nextCoef = 0;
4601
106
  if( id > 13 )
4602
48
  {
4603
48
    X_READ_SVLC_idx( scaling_list_dc_coef, "[id-14]", -128, 127 );
4604
48
    nextCoef += scaling_list_dc_coef;
4605
4606
48
    scalingList->setScalingListDC( id MINUS_14, ( scalingMatrixDcPred + scaling_list_dc_coef ) & 255 );
4607
48
    CHECK( scalingList->getScalingListDC( id MINUS_14 ) <= 0, "The value of ScalingMatrixDcRec[" << id MINUS_14 << "] shall be greater than 0." )
4608
48
  }
4609
4610
2.82k
  for( unsigned i = 0; i < matrixSize * matrixSize; i++ )
4611
2.73k
  {
4612
2.73k
    const int numBits = g_sizeIdxInfo.idxFrom( matrixSize );
4613
2.73k
    const int x       = DiagScanOrder[3][3][i] & ( ( 1 << numBits ) - 1 );
4614
2.73k
    const int y       = DiagScanOrder[3][3][i] >> numBits;
4615
4616
2.73k
    if( !( id > 25 && x >= 4 && y >= 4 ) )
4617
2.45k
    {
4618
2.45k
      X_READ_SVLC_idx( scaling_list_delta_coef, "[id][i]", -128, 127 );
4619
2.45k
      nextCoef += scaling_list_delta_coef;
4620
2.45k
    }
4621
4622
2.73k
    int pos = DiagScanOrder[getLog2( matrixSize )][getLog2( matrixSize )][i];
4623
4624
2.73k
    auto& scalingMatrixRec = scalingList->getScalingListVec( id );
4625
2.73k
    scalingMatrixRec[pos]  = ( scalingMatrixPred[pos] + nextCoef ) & 255;
4626
2.73k
    CHECK( scalingMatrixRec[pos] <= 0, "The value of ScalingMatrixRec[" << id << " ][x][y] shall be greater than 0." )
4627
2.73k
  }
4628
104
}
4629
bool HLSyntaxReader::xMoreRbspData()
4630
4.37k
{
4631
4.37k
  int bitsLeft = m_pcBitstream->getNumBitsLeft();
4632
4633
  // if there are more than 8 bits, it cannot be rbsp_trailing_bits
4634
4.37k
  if( bitsLeft > 8 )
4635
4.06k
  {
4636
4.06k
    return true;
4637
4.06k
  }
4638
4639
306
  uint8_t lastByte = m_pcBitstream->peekBits( bitsLeft );
4640
306
  int cnt = bitsLeft;
4641
4642
  // remove trailing bits equal to zero
4643
728
  while( ( cnt > 0 ) && ( ( lastByte & 1 ) == 0 ) )
4644
422
  {
4645
422
    lastByte >>= 1;
4646
422
    cnt--;
4647
422
  }
4648
  // remove bit equal to one
4649
306
  cnt--;
4650
4651
  // we should not have a negative number of bits
4652
306
  CHECK( cnt<0, "Negative number of bits") ;
4653
4654
  // we have more data, if cnt is not zero
4655
304
  return ( cnt>0 );
4656
306
}
4657
4658
4659
void HLSyntaxReader::alfFilterCoeffs( AlfSliceParam& alfSliceParam, const bool isChroma, const int altIdx )
4660
150
{
4661
150
  const bool isLuma = !isChroma;
4662
4663
  // derive maxGolombIdx
4664
150
  const int numCoeff   = g_alfNumCoeff[isLuma];
4665
150
  const int numFilters = isLuma ? alfSliceParam.numLumaFilters : 1;
4666
150
  short*    coeff      = isLuma ? alfSliceParam.lumaCoeff      : alfSliceParam.chromaCoeff + altIdx * MAX_NUM_ALF_CHROMA_COEFF;
4667
150
  short*    clipp      = isLuma ? alfSliceParam.lumaClipp      : alfSliceParam.chromaClipp + altIdx * MAX_NUM_ALF_CHROMA_COEFF;
4668
4669
  // Filter coefficients
4670
300
  for( int sfIdx = 0; sfIdx < numFilters; ++sfIdx )
4671
160
  {
4672
1.29k
    for( int j = 0; j < numCoeff - 1; j++ )
4673
1.14k
    {
4674
1.14k
      uint32_t code;
4675
1.14k
      READ_UVLC( code, isLuma ? "alf_luma_coeff_abs" : "alf_chroma_coeff_abs" );
4676
1.14k
      CHECK_READ_RANGE( code, 0, 128, ( isLuma ? "alf_luma_coeff_abs[sfIdx][j]" : "alf_chroma_coeff_abs[sfIdx][j]" ) );
4677
1.13k
      coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j] = code;
4678
4679
1.13k
      if( code )
4680
354
      {
4681
354
        READ_FLAG( code, isLuma ? "alf_luma_coeff_sign" : "alf_chroma_coeff_sign" );
4682
4683
354
        const int sign = code ? -1 : 1;
4684
354
        coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j] *= sign;
4685
4686
354
        CHECK_READ_RANGE( coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j],
4687
352
                          -( 1 << 7 ), ( 1 << 7 ) - 1,
4688
352
                          ( isLuma ? "AlfLumaCoeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j]" : "AlfChromaCoeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j]" ) );
4689
352
      }
4690
1.13k
    }
4691
4692
150
    const int factor = 1 << ( AdaptiveLoopFilter::m_NUM_BITS - 1 );
4693
150
    coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + numCoeff - 1] = factor;
4694
150
  }
4695
4696
  // Clipping values coding
4697
140
  bool alfClipFlag = isLuma ? alfSliceParam.nonLinearFlagLuma : alfSliceParam.nonLinearFlagChroma;
4698
140
  if( alfClipFlag )
4699
44
  {
4700
    // Filter coefficients
4701
92
    for( int sfIdx = 0; sfIdx < numFilters; ++sfIdx )
4702
48
    {
4703
494
      for( int j = 0; j < numCoeff - 1; j++ )
4704
446
      {
4705
446
        uint32_t code;
4706
446
        READ_CODE( 2, code, isLuma ? "alf_luma_clip_idx" : "alf_chroma_clip_idx" );
4707
446
        clipp[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j] = code;
4708
446
      }
4709
48
    }
4710
44
  }
4711
140
}
4712
4713
}   // namespace vvdec