Coverage Report

Created: 2026-04-01 07:49

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