Coverage Report

Created: 2026-06-15 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/vvdec/source/Lib/DecoderLib/HLSyntaxReader.cpp
Line
Count
Source
1
/* -----------------------------------------------------------------------------
2
The copyright in this software is being made available under the Clear BSD
3
License, included below. No patent rights, trademark rights and/or 
4
other Intellectual Property Rights other than the copyrights concerning 
5
the Software are granted under this license.
6
7
The Clear BSD License
8
9
Copyright (c) 2018-2026, Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. & The VVdeC Authors.
10
All rights reserved.
11
12
Redistribution and use in source and binary forms, with or without modification,
13
are permitted (subject to the limitations in the disclaimer below) provided that
14
the following conditions are met:
15
16
     * Redistributions of source code must retain the above copyright notice,
17
     this list of conditions and the following disclaimer.
18
19
     * Redistributions in binary form must reproduce the above copyright
20
     notice, this list of conditions and the following disclaimer in the
21
     documentation and/or other materials provided with the distribution.
22
23
     * Neither the name of the copyright holder nor the names of its
24
     contributors may be used to endorse or promote products derived from this
25
     software without specific prior written permission.
26
27
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
28
THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
29
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
31
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
32
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
36
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
POSSIBILITY OF SUCH DAMAGE.
39
40
41
------------------------------------------------------------------------------------------- */
42
43
/** \file     HLSyntaxReader.cpp
44
 *  \brief    Reader for high level syntax
45
 */
46
47
//! \ingroup DecoderLib
48
//! \{
49
50
#include "HLSyntaxReader.h"
51
52
#include "CommonLib/CommonDef.h"
53
#include "CommonLib/Rom.h"
54
#include "CommonLib/dtrace_next.h"
55
#include "CommonLib/AdaptiveLoopFilter.h"
56
57
#include "ParameterSetManager.h"
58
59
582
#define CHECK_CONSTRAINT( cond, msg ) CHECK( cond, msg )
60
61
namespace vvdec
62
{
63
64
void AUDReader::parseAccessUnitDelimiter( InputBitstream* bs, uint32_t &picType )
65
4
{
66
4
  setBitstream( bs );
67
68
#if ENABLE_TRACING
69
  xTraceAccessUnitDelimiter();
70
#endif
71
72
4
  X_READ_FLAG( aud_irap_or_gdr_au_flag );
73
4
  (void)aud_irap_or_gdr_au_flag;
74
75
4
  X_READ_CODE_NO_RANGE( aud_pic_type, 3 );
76
4
  picType = aud_pic_type;
77
78
4
  xReadRbspTrailingBits();
79
4
}
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
2
{
207
#if ENABLE_TRACING
208
  xTracePPSHeader();
209
#endif
210
211
2
  X_READ_CODE_NO_RANGE( pps_pic_parameter_set_id, 6 );
212
2
  pcPPS->setPPSId( pps_pic_parameter_set_id );
213
214
2
  X_READ_CODE( pps_seq_parameter_set_id, 4, 0, 15 );
215
2
  const SPS* sps = parameterSetManager->getSPS( pps_seq_parameter_set_id );
216
2
  CHECK( !sps, "SPS with id " << pps_seq_parameter_set_id << " missing." );
217
2
  pcPPS->setSPSId( pps_seq_parameter_set_id );
218
219
2
  const int SubWidthC  = 1 << getChannelTypeScaleX( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() );
220
2
  const int SubHeightC = 1 << getChannelTypeScaleY( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() );
221
222
2
  X_READ_FLAG( pps_mixed_nalu_types_in_pic_flag );
223
2
  pcPPS->setMixedNaluTypesInPicFlag( pps_mixed_nalu_types_in_pic_flag == 1 );
224
225
2
  const int CtbSizeY   = sps->getCTUSize();
226
2
  const int MinCbSizeY = 1 << sps->getLog2MinCodingBlockSize();
227
228
2
  X_READ_UVLC( pps_pic_width_in_luma_samples, 1, sps->getMaxPicWidthInLumaSamples() );
229
2
  CHECK( pps_pic_width_in_luma_samples & std::max( 8 - 1, MinCbSizeY - 1 ), "pps_pic_width_in_luma_samples not a multiple of 8 or MinCbSizeY" );
230
2
  CHECK( !sps->getResChangeInClvsEnabledFlag() && pps_pic_width_in_luma_samples != sps->getMaxPicWidthInLumaSamples(),
231
2
         "When sps_res_change_in_clvs_allowed_flag equal to 0, the value of pps_pic_width_in_luma_samples shall be equal"
232
2
         " to sps_pic_width_max_in_luma_samples." )
233
2
  CHECK( sps->getUseWrapAround() && CtbSizeY / MinCbSizeY + 1 > pps_pic_width_in_luma_samples / MinCbSizeY - 1,
234
2
         "When sps_ref_wraparound_enabled_flag is equal to 1, the value of ( CtbSizeY / MinCbSizeY + 1 ) shall be less than or"
235
2
         " equal to the value of ( pps_pic_width_in_luma_samples / MinCbSizeY − 1 )." );
236
2
  pcPPS->setPicWidthInLumaSamples( pps_pic_width_in_luma_samples );
237
238
2
  X_READ_UVLC( pps_pic_height_in_luma_samples, 1, sps->getMaxPicHeightInLumaSamples() );
239
2
  CHECK( pps_pic_height_in_luma_samples & std::max( 8 - 1, MinCbSizeY - 1 ), "pps_pic_height_in_luma_samples not a multiple of 8 or MinCbSizeY" );
240
2
  CHECK( !sps->getResChangeInClvsEnabledFlag() && pps_pic_height_in_luma_samples != sps->getMaxPicHeightInLumaSamples(),
241
2
         "When sps_res_change_in_clvs_allowed_flag equal to 0, the value of pps_pic_height_in_luma_samples shall be equal"
242
2
         " to sps_pic_height_max_in_luma_samples." )
243
2
  pcPPS->setPicHeightInLumaSamples( pps_pic_height_in_luma_samples );
244
245
2
  const unsigned PicWidthInCtbsY     = ( pps_pic_width_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY;      (void) PicWidthInCtbsY;
246
2
  const unsigned PicHeightInCtbsY    = ( pps_pic_height_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY;     (void) PicHeightInCtbsY;
247
2
  const unsigned PicSizeInCtbsY      = PicWidthInCtbsY * PicHeightInCtbsY;                               (void) PicSizeInCtbsY;
248
2
  const unsigned PicWidthInMinCbsY   = pps_pic_width_in_luma_samples / MinCbSizeY;                       (void) PicWidthInMinCbsY;
249
2
  const unsigned PicHeightInMinCbsY  = pps_pic_height_in_luma_samples / MinCbSizeY;                      (void) PicHeightInMinCbsY;
250
2
  const unsigned PicSizeInMinCbsY    = PicWidthInMinCbsY * PicHeightInMinCbsY;                           (void) PicSizeInMinCbsY;
251
2
  const unsigned PicSizeInSamplesY   = pps_pic_width_in_luma_samples * pps_pic_height_in_luma_samples;   (void) PicSizeInSamplesY;
252
2
  const unsigned PicWidthInSamplesC  = pps_pic_width_in_luma_samples / SubWidthC;                        (void) PicWidthInSamplesC;
253
2
  const unsigned PicHeightInSamplesC = pps_pic_height_in_luma_samples / SubHeightC;                      (void) PicHeightInSamplesC;
254
255
2
  X_READ_FLAG( pps_conformance_window_flag );
256
2
  CHECK( pps_conformance_window_flag != 0 && pcPPS->getPicWidthInLumaSamples() == sps->getMaxPicWidthInLumaSamples()
257
2
           && pcPPS->getPicHeightInLumaSamples() == sps->getMaxPicHeightInLumaSamples(),
258
2
         "pps_conformance_window_flag shall be equal to 0" )
259
2
  pcPPS->setConformanceWindowPresentFlag( pps_conformance_window_flag );
260
261
2
  if( pps_conformance_window_flag != 0 )
262
0
  {
263
0
    X_READ_UVLC_NO_RANGE( pps_conf_win_left_offset );
264
0
    X_READ_UVLC_NO_RANGE( pps_conf_win_right_offset );
265
0
    X_READ_UVLC_NO_RANGE( pps_conf_win_top_offset );
266
0
    X_READ_UVLC_NO_RANGE( pps_conf_win_bottom_offset );
267
268
0
    CHECK( SubWidthC * ( pps_conf_win_left_offset + pps_conf_win_right_offset ) >= pps_pic_width_in_luma_samples,
269
0
           "pps_conf_win_left_offset + pps_conf_win_right_offset too large" );
270
0
    CHECK( SubHeightC * ( pps_conf_win_top_offset + pps_conf_win_bottom_offset ) >= pps_pic_height_in_luma_samples,
271
0
           "pps_conf_win_top_offset + pps_conf_win_bottom_offset too large" );
272
273
0
    Window& conf = pcPPS->getConformanceWindow();
274
0
    conf.setWindowLeftOffset( pps_conf_win_left_offset );
275
0
    conf.setWindowRightOffset( pps_conf_win_right_offset );
276
0
    conf.setWindowTopOffset( pps_conf_win_top_offset );
277
0
    conf.setWindowBottomOffset( pps_conf_win_bottom_offset );
278
0
  }
279
280
2
  X_READ_FLAG_CHECK( pps_scaling_window_explicit_signalling_flag,
281
2
                     !sps->getRprEnabledFlag() && pps_scaling_window_explicit_signalling_flag != 0,
282
2
                     "When sps_ref_pic_resampling_enabled_flag is equal to 0, the value of pps_scaling_window_explicit_signalling_flag shall be equal to 0" );
283
284
2
  if( pps_scaling_window_explicit_signalling_flag != 0 )
285
0
  {
286
0
    X_READ_SVLC_NO_RANGE( pps_scaling_win_left_offset );
287
0
    X_READ_SVLC_NO_RANGE( pps_scaling_win_right_offset );
288
0
    X_READ_SVLC_NO_RANGE( pps_scaling_win_top_offset );
289
0
    X_READ_SVLC_NO_RANGE( pps_scaling_win_bottom_offset );
290
291
0
    CHECK( SubWidthC * pps_scaling_win_left_offset < -(int) pps_pic_width_in_luma_samples * 15
292
0
             || SubWidthC * pps_scaling_win_left_offset >= (int) pps_pic_width_in_luma_samples,
293
0
           "pps_scaling_win_left_offset (" << pps_scaling_win_left_offset << ") out of bounds" );
294
0
    CHECK( SubWidthC * pps_scaling_win_right_offset < -(int) pps_pic_width_in_luma_samples * 15
295
0
             || SubWidthC * pps_scaling_win_right_offset >= (int) pps_pic_width_in_luma_samples,
296
0
           "pps_scaling_win_right_offset (" << pps_scaling_win_right_offset << ") out of bounds" );
297
0
    CHECK( SubHeightC * pps_scaling_win_top_offset < -(int) pps_pic_height_in_luma_samples * 15
298
0
             || SubHeightC * pps_scaling_win_top_offset >= (int) pps_pic_height_in_luma_samples,
299
0
           "pps_scaling_win_top_offset (" << pps_scaling_win_top_offset << ") out of bounds" );
300
0
    CHECK( SubHeightC * pps_scaling_win_bottom_offset < -(int) pps_pic_height_in_luma_samples * 15
301
0
             || SubHeightC * pps_scaling_win_bottom_offset >= (int) pps_pic_height_in_luma_samples,
302
0
           "pps_scaling_win_bottom_offset (" << pps_scaling_win_bottom_offset << ") out of bounds" );
303
304
0
    CHECK( SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) < -(int) pps_pic_width_in_luma_samples * 15
305
0
             || SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) >= (int) pps_pic_width_in_luma_samples,
306
0
           "SubWidthC * ( pps_scaling_win_left_offset + pps_scaling_win_right_offset ) shall be greater than or equal to"
307
0
           " -pps_pic_width_in_luma_samples * 15 and less than pps_pic_width_in_luma_samples."
308
0
           " (pps_scaling_win_left_offset + pps_scaling_win_right_offset = "
309
0
             << pps_scaling_win_left_offset + pps_scaling_win_right_offset << ")" );
310
311
0
    CHECK( SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) < -(int) pps_pic_height_in_luma_samples * 15
312
0
             || SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) >= (int) pps_pic_height_in_luma_samples,
313
0
           "SubHeightC * ( pps_scaling_win_top_offset + pps_scaling_win_bottom_offset ) shall be greater than or equal to"
314
0
           " -pps_pic_height_in_luma_samples * 15 and less than pps_pic_height_in_luma_samples."
315
0
           " (pps_scaling_win_top_offset + pps_scaling_win_bottom_offset = "
316
0
             << pps_scaling_win_top_offset + pps_scaling_win_bottom_offset << ")" )
317
318
#if 0
319
    // these checks need to be moved to the creation of ref pic lists
320
    //
321
    const int CurrPicScalWinWidthL  = pps_pic_width_in_luma_samples - SubWidthC * ( pps_scaling_win_right_offset + pps_scaling_win_left_offset );
322
    const int CurrPicScalWinHeightL = pps_pic_height_in_luma_samples - SubHeightC * ( pps_scaling_win_bottom_offset + pps_scaling_win_top_offset );
323
    CHECK( CurrPicScalWinWidthL * 2 < refPicScalWinWidthL,
324
           "Requirement of bitstream conformance: CurrPicScalWinWidthL * 2 is greater than or equal to refPicScalWinWidthL." );
325
    CHECK( CurrPicScalWinHeightL * 2 < refPicScalWinHeightL,
326
           "Requirement of bitstream conformance: CurrPicScalWinHeightL * 2 is greater than or equal to refPicScalWinHeightL." );
327
    CHECK( CurrPicScalWinWidthL > refPicScalWinWidthL * 8,
328
           "Requirement of bitstream conformance: CurrPicScalWinWidthL is less than or equal to refPicScalWinWidthL * 8." );
329
    CHECK( CurrPicScalWinHeightL > refPicScalWinHeightL * 8,
330
           "Requirement of bitstream conformance: CurrPicScalWinHeightL is less than or equal to refPicScalWinHeightL * 8." );
331
    CHECK( CurrPicScalWinWidthL * sps->getMaxPicWidthInLumaSamples() < refPicScalWinWidthL * ( pps_pic_width_in_luma_samples - std::max( 8, MinCbSizeY ) ),
332
           "Requirement of bitstream conformance: CurrPicScalWinWidthL * sps_pic_width_max_in_luma_samples is greater than or equal to"
333
           " refPicScalWinWidthL * ( pps_pic_width_in_luma_samples - Max( 8, MinCbSizeY ) )." );
334
    CHECK( CurrPicScalWinHeightL * sps->getMaxPicHeightInLumaSamples() < refPicScalWinHeightL * ( pps_pic_height_in_luma_samples - std::max( 8, MinCbSizeY ) ),
335
           "Requirement of bitstream conformance: CurrPicScalWinHeightL * sps_pic_height_max_in_luma_samples is greater than or equal to"
336
           " refPicScalWinHeightL * ( pps_pic_height_in_luma_samples - Max( 8, MinCbSizeY ) )." );
337
#endif
338
339
0
    Window& scalingWindow = pcPPS->getScalingWindow();
340
0
    scalingWindow.setWindowLeftOffset( pps_scaling_win_left_offset );
341
0
    scalingWindow.setWindowRightOffset( pps_scaling_win_right_offset );
342
0
    scalingWindow.setWindowTopOffset( pps_scaling_win_top_offset );
343
0
    scalingWindow.setWindowBottomOffset( pps_scaling_win_bottom_offset );
344
0
  }
345
2
  else
346
2
  {
347
2
    pcPPS->setScalingWindow( pcPPS->getConformanceWindow() );
348
2
  }
349
350
2
  X_READ_FLAG( pps_output_flag_present_flag );
351
2
  pcPPS->setOutputFlagPresentFlag( pps_output_flag_present_flag );
352
353
2
  X_READ_FLAG_CHECK( pps_no_pic_partition_flag,
354
2
                     ( sps->getNumSubPics() > 1 || pps_mixed_nalu_types_in_pic_flag == 1 ) && pps_no_pic_partition_flag != 0,
355
2
                     "When sps_num_subpics_minus1 is greater than 0 or pps_mixed_nalu_types_in_pic_flag is equal to 1, the value of pps_no_pic_partition_flag "
356
2
                     "shall be equal to 0." );
357
2
  pcPPS->setNoPicPartitionFlag( pps_no_pic_partition_flag );
358
359
2
  X_READ_FLAG( pps_subpic_id_mapping_present_flag );
360
2
  CHECK( ( sps->getSubPicIdMappingExplicitlySignalledFlag() == 0 || sps->getSubPicIdMappingPresentFlag() == 1 ) && pps_subpic_id_mapping_present_flag != 0,
361
2
         "If sps_subpic_id_mapping_explicitly_signalled_flag is 0 or sps_subpic_id_mapping_present_flag is equal to 1, the value of"
362
2
         " pps_subpic_id_mapping_present_flag shall be equal to 0." );
363
2
  CHECK( ( sps->getSubPicIdMappingExplicitlySignalledFlag() == 1 && sps->getSubPicIdMappingPresentFlag() == 0 ) && pps_subpic_id_mapping_present_flag != 1,
364
2
         "Otherwise (sps_subpic_id_mapping_explicitly_signalled_flag is equal to 1 and sps_subpic_id_mapping_present_flag is equal to 0), the value of"
365
2
         " pps_subpic_id_mapping_present_flag  shall be equal to 1." );
366
2
  pcPPS->setSubPicIdMappingPresentFlag( pps_subpic_id_mapping_present_flag );
367
368
2
  if( pps_subpic_id_mapping_present_flag )
369
0
  {
370
0
    if( !pps_no_pic_partition_flag )
371
0
    {
372
0
      X_READ_UVLC( pps_num_subpics_minus1, 0, MAX_NUM_SUB_PICS - 1 );
373
0
      CHECK( pps_num_subpics_minus1 != sps->getNumSubPics() - 1, "pps_num_subpics_minus1 shall be equal to sps_num_subpics_minus1" );
374
0
      pcPPS->setNumSubPics( pps_num_subpics_minus1 + 1 );
375
0
    }
376
0
    else
377
0
    {
378
      // When pps_no_pic_partition_flag is equal to 1, the value of pps_num_subpics_minus1 is inferred to be equal to 0.
379
0
      pcPPS->setNumSubPics( 1 );
380
0
    }
381
382
0
    X_READ_UVLC( pps_subpic_id_len_minus1, 0, 15 );
383
0
    CHECK( pps_subpic_id_len_minus1 != sps->getSubPicIdLen() - 1, "pps_subpic_id_len_minus1 shall be equal to sps_subpic_id_len_minus1" );
384
0
    CHECK( ( 1 << ( pps_subpic_id_len_minus1 + 1 ) ) < pcPPS->getNumSubPics(), "pps_subpic_id_len too short" );
385
0
    pcPPS->setSubPicIdLen( pps_subpic_id_len_minus1 + 1 );
386
387
0
    for( int picIdx = 0; picIdx < pcPPS->getNumSubPics(); picIdx++ )
388
0
    {
389
0
      X_READ_CODE_NO_RANGE_idx( pps_subpic_id, "[i]", pcPPS->getSubPicIdLen() );
390
0
      pcPPS->setSubPicId( picIdx, pps_subpic_id );
391
0
    }
392
0
  }
393
2
  else
394
2
  {
395
2
    for( int picIdx = 0; picIdx < MAX_NUM_SUB_PICS; picIdx++ )
396
0
    {
397
0
      pcPPS->setSubPicId( picIdx, sps->getSubPicIdMappingExplicitlySignalledFlag() ? sps->getSubPicId( picIdx ) : picIdx );
398
0
    }
399
2
  }
400
2
  for( int i = 0; i < pcPPS->getNumSubPics(); ++i )
401
0
  {
402
0
    for( int j = 0; j < i; ++j )
403
0
    {
404
0
      CHECK( pcPPS->getSubPicId( i ) == pcPPS->getSubPicId( j ),
405
0
                         "It is a requirement of bitstream conformance that, for any two different values of i and j in the range of"
406
0
                         " 0 to sps_num_subpics_minus1, inclusive, SubpicIdVal[ i ] shall not be equal to SubpicIdVal[ j ]." )
407
0
    }
408
0
  }
409
410
2
  pcPPS->resetTileSliceInfo();
411
412
2
  if( !pps_no_pic_partition_flag )
413
0
  {
414
    // CTU size - required to match size in SPS
415
0
    X_READ_CODE( pps_log2_ctu_size_minus5, 2, 0,2 );
416
0
    CHECK( pps_log2_ctu_size_minus5 != getLog2( sps->getCTUSize() ) - 5, "pps_log2_ctu_size_minus5 shall be equal to sps_log2_ctu_size_minus5" );
417
0
    pcPPS->setLog2CtuSize( pps_log2_ctu_size_minus5 + 5 );
418
419
    // number of explicit tile columns/rows
420
421
0
    X_READ_UVLC( pps_num_exp_tile_columns_minus1, 0, PicWidthInCtbsY - 1 );
422
0
    pcPPS->setNumExpTileColumns( pps_num_exp_tile_columns_minus1 + 1 );
423
424
0
    X_READ_UVLC( pps_num_exp_tile_rows_minus1, 0, PicHeightInCtbsY - 1 );
425
0
    pcPPS->setNumExpTileRows( pps_num_exp_tile_rows_minus1 + 1 );
426
0
    CHECK( pcPPS->getNumExpTileColumns() > MAX_TILE_COLS, "Number of explicit tile columns exceeds valid range" );
427
428
    // tile sizes
429
0
    for( int colIdx = 0; colIdx < pcPPS->getNumExpTileColumns(); colIdx++ )
430
0
    {
431
0
      X_READ_UVLC_idx( pps_tile_column_width_minus1, "[i]", 0, PicWidthInCtbsY - 1 );
432
0
      pcPPS->addTileColumnWidth( pps_tile_column_width_minus1 + 1 );
433
0
    }
434
0
    for( int rowIdx = 0; rowIdx < pcPPS->getNumExpTileRows(); rowIdx++ )
435
0
    {
436
0
      X_READ_UVLC_idx( pps_tile_row_height_minus1, "[i]", 0, PicHeightInCtbsY - 1 );
437
0
      pcPPS->addTileRowHeight( pps_tile_row_height_minus1 + 1 );
438
0
    }
439
0
    pcPPS->initTiles();
440
441
    // rectangular slice signalling
442
0
    if( pcPPS->getNumTiles() > 1 )
443
0
    {
444
0
      X_READ_FLAG( pps_loop_filter_across_tiles_enabled_flag );
445
0
      pcPPS->setLoopFilterAcrossTilesEnabledFlag( pps_loop_filter_across_tiles_enabled_flag );
446
0
      X_READ_FLAG( pps_rect_slice_flag );
447
0
      CHECK( ( sps->getSubPicInfoPresentFlag() || pps_mixed_nalu_types_in_pic_flag ) && pps_rect_slice_flag != 1,
448
0
             "When sps_subpic_info_present_flag is equal to 1 or pps_mixed_nalu_types_in_pic_flag is equal to 1,"
449
0
             " the value of pps_rect_slice_flag shall be equal to 1." );
450
0
      pcPPS->setRectSliceFlag( pps_rect_slice_flag );
451
0
    }
452
0
    else
453
0
    {
454
0
      pcPPS->setLoopFilterAcrossTilesEnabledFlag( false );
455
0
      pcPPS->setRectSliceFlag( true );
456
0
    }
457
458
0
    if( pcPPS->getRectSliceFlag() )
459
0
    {
460
0
      X_READ_FLAG( pps_single_slice_per_subpic_flag );
461
0
      pcPPS->setSingleSlicePerSubPicFlag( pps_single_slice_per_subpic_flag );
462
0
    }
463
464
0
    if( pcPPS->getRectSliceFlag() && !pcPPS->getSingleSlicePerSubPicFlag() )
465
0
    {
466
0
      X_READ_UVLC( pps_num_slices_in_pic_minus1, 0, MAX_SLICES - 1 /*  TODO: should be MaxSlicesPerAU -1  */ );
467
0
      pcPPS->setNumSlicesInPic( pps_num_slices_in_pic_minus1 + 1 );
468
469
0
      if( pps_num_slices_in_pic_minus1 > 1 )
470
0
      {
471
0
        X_READ_FLAG( pps_tile_idx_delta_present_flag );
472
0
        pcPPS->setTileIdxDeltaPresentFlag( pps_tile_idx_delta_present_flag );
473
0
      }
474
0
      pcPPS->initRectSlices();
475
476
0
      int32_t tileIdx = 0;
477
      // read rectangular slice parameters
478
0
      for( int sliceIdx = 0; sliceIdx < pcPPS->getNumSlicesInPic() - 1; sliceIdx++ )
479
0
      {
480
0
        pcPPS->setSliceTileIdx( sliceIdx, tileIdx );   // this is SliceTopLeftTileIdx[ i ]
481
482
        // complete tiles within a single slice
483
0
        if( tileIdx % pcPPS->getNumTileColumns() != pcPPS->getNumTileColumns() - 1 )
484
0
        {
485
0
          X_READ_UVLC_idx( pps_slice_width_in_tiles_minus1, "[i]", 0, pcPPS->getNumTileColumns() - 1 );
486
0
          pcPPS->setSliceWidthInTiles( sliceIdx, pps_slice_width_in_tiles_minus1 + 1 );
487
0
        }
488
0
        else
489
0
        {
490
0
          pcPPS->setSliceWidthInTiles( sliceIdx, 1 );
491
0
        }
492
493
0
        if( tileIdx / pcPPS->getNumTileColumns() != pcPPS->getNumTileRows() - 1
494
0
            && ( pcPPS->getTileIdxDeltaPresentFlag() || tileIdx % pcPPS->getNumTileColumns() == 0 ) )
495
0
        {
496
0
          X_READ_UVLC_idx( pps_slice_height_in_tiles_minus1, "[i]", 0, pcPPS->getNumTileRows() - 1 );
497
0
          pcPPS->setSliceHeightInTiles( sliceIdx, pps_slice_height_in_tiles_minus1 + 1 );
498
0
        }
499
0
        else
500
0
        {
501
0
          if( tileIdx / pcPPS->getNumTileColumns() == pcPPS->getNumTileRows() - 1 )
502
0
          {
503
0
            pcPPS->setSliceHeightInTiles( sliceIdx, 1 );
504
0
          }
505
0
          else
506
0
          {
507
0
            pcPPS->setSliceHeightInTiles( sliceIdx, pcPPS->getSliceHeightInTiles( sliceIdx - 1 ) );
508
0
          }
509
0
        }
510
511
        // multiple slices within a single tile special case
512
0
        if( pcPPS->getSliceWidthInTiles( sliceIdx ) == 1 && pcPPS->getSliceHeightInTiles( sliceIdx ) == 1 )
513
0
        {
514
0
          if( pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) > 1 )
515
0
          {
516
0
            X_READ_UVLC_idx( pps_num_exp_slices_in_tile, "[i]", 0, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) - 1 );
517
0
            if( pps_num_exp_slices_in_tile == 0 )
518
0
            {
519
0
              pcPPS->setNumSlicesInTile( sliceIdx, 1 );
520
0
              pcPPS->setSliceHeightInCtu( sliceIdx, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) );
521
0
            }
522
0
            else   // ( pps_num_exp_slices_in_tile > 0 )
523
0
            {
524
0
              uint32_t remTileRowHeight         = pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() );
525
0
              uint32_t lastExpSliceHeightInCtus = 0;
526
527
0
              int j = 0;
528
0
              for( ; j < pps_num_exp_slices_in_tile; j++ )
529
0
              {
530
0
                X_READ_UVLC_idx( pps_exp_slice_height_in_ctus_minus1, "[i][j]", 0, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) - 1 );
531
0
                pcPPS->setSliceHeightInCtu( sliceIdx + j, pps_exp_slice_height_in_ctus_minus1 + 1 );
532
0
                remTileRowHeight -= ( pps_exp_slice_height_in_ctus_minus1 + 1 );
533
534
0
                lastExpSliceHeightInCtus = pps_exp_slice_height_in_ctus_minus1 + 1;
535
0
              }
536
537
0
              uint32_t uniformSliceHeight = lastExpSliceHeightInCtus;
538
0
              while( remTileRowHeight >= uniformSliceHeight )
539
0
              {
540
0
                pcPPS->setSliceHeightInCtu( sliceIdx + j, uniformSliceHeight );
541
0
                remTileRowHeight -= uniformSliceHeight;
542
0
                j++;
543
0
              }
544
0
              if( remTileRowHeight > 0 )
545
0
              {
546
0
                pcPPS->setSliceHeightInCtu( sliceIdx + j, remTileRowHeight );
547
0
                j++;
548
0
              }
549
0
              for( int k = 0; k < j; k++ )
550
0
              {
551
0
                pcPPS->setNumSlicesInTile( sliceIdx + k, j );
552
0
                pcPPS->setSliceWidthInTiles( sliceIdx + k, 1 );
553
0
                pcPPS->setSliceHeightInTiles( sliceIdx + k, 1 );
554
0
                pcPPS->setSliceTileIdx( sliceIdx + k, tileIdx );
555
0
              }
556
0
              sliceIdx += ( j - 1 );
557
0
            }    // ( pps_num_exp_slices_in_tile > 0 )
558
0
          }
559
0
          else   // ( pps->getTileRowHeight( tileIdx / pps->getNumTileColumns() ) <= 1 )
560
0
          {
561
0
            pcPPS->setNumSlicesInTile( sliceIdx, 1 );
562
0
            pcPPS->setSliceHeightInCtu( sliceIdx, pcPPS->getTileRowHeight( tileIdx / pcPPS->getNumTileColumns() ) );
563
0
          }
564
0
        }   // ( pps->getSliceWidthInTiles(sliceIdx) == 1 && pps->getSliceHeightInTiles(sliceIdx) == 1 )
565
566
        // tile index offset to start of next slice
567
0
        if( sliceIdx < pps_num_slices_in_pic_minus1 )
568
0
        {
569
0
          if( pcPPS->getTileIdxDeltaPresentFlag() )
570
0
          {
571
0
            X_READ_SVLC_idx( pps_tile_idx_delta_val, "[i]", -(int) pcPPS->getNumTiles() + 1, (int) pcPPS->getNumTiles() - 1 );
572
0
            CHECK( pps_tile_idx_delta_val == 0, "When present, the value of pps_tile_idx_delta_val[ i ] shall not be equal to 0." );
573
574
            // TODO: When pps_rect_slice_flag is equal to 1, it is a requirement of bitstrream conformance that, for any two slices, with picture-
575
            //       level slice indices idxA and idxB, that belong to the same picture and different subpictures, when
576
            //       SubpicIdxForSlice[idxA] is less than SubpicIdxForSlice[idxB], the value of idxA shall be less than idxB.
577
            // CHECK( pps->getRectSliceFlag() && /* TODO */ )
578
579
0
            tileIdx += pps_tile_idx_delta_val;
580
0
            CHECK( tileIdx < 0 || tileIdx >= (int) pcPPS->getNumTiles(), "Invalid tile_idx_delta." );
581
0
          }
582
0
          else
583
0
          {
584
0
            tileIdx += pcPPS->getSliceWidthInTiles( sliceIdx );
585
0
            if( tileIdx % pcPPS->getNumTileColumns() == 0 )
586
0
            {
587
0
              tileIdx += ( pcPPS->getSliceHeightInTiles( sliceIdx ) - 1 ) * pcPPS->getNumTileColumns();
588
0
            }
589
0
          }
590
0
        }
591
        // TODO: hier?
592
0
        CHECK( tileIdx < 0 || tileIdx >= (int) pcPPS->getNumTiles(), "Invalid tile_idx_delta." );
593
594
0
      }   // for( int i = 0; i < pps->getNumSlicesInPic()-1; i++ )
595
0
      pcPPS->setSliceTileIdx( pcPPS->getNumSlicesInPic() - 1, tileIdx );
596
597
0
    }   // if( pps->getRectSliceFlag() && !pps->getSingleSlicePerSubPicFlag() )
598
599
0
    if( !pcPPS->getRectSliceFlag() || pcPPS->getSingleSlicePerSubPicFlag() || pcPPS->getNumSlicesInPic() > 1 )
600
0
    {
601
0
      X_READ_FLAG( pps_loop_filter_across_slices_enabled_flag );
602
0
      pcPPS->setLoopFilterAcrossSlicesEnabledFlag( pps_loop_filter_across_slices_enabled_flag );
603
0
    }
604
0
    else
605
0
    {
606
0
      pcPPS->setLoopFilterAcrossSlicesEnabledFlag( false );
607
0
    }
608
0
  }
609
2
  else   // if( !pps_no_pic_partition_flag )
610
2
  {
611
    // When pps_no_pic_partition_flag is equal to 1, the value of pps_single_slice_per_subpic_flag is inferred to be equal to 1.
612
2
    pcPPS->setSingleSlicePerSubPicFlag( 1 );
613
2
  }
614
615
2
  X_READ_FLAG( pps_cabac_init_present_flag );
616
2
  pcPPS->setCabacInitPresentFlag( pps_cabac_init_present_flag );
617
618
2
  {
619
2
    X_READ_UVLC_idx( pps_num_ref_idx_default_active_minus1, "[0]", 0, 14 );
620
2
    pcPPS->setNumRefIdxL0DefaultActive( pps_num_ref_idx_default_active_minus1 + 1 );
621
2
  }
622
2
  {
623
2
    X_READ_UVLC_idx( pps_num_ref_idx_default_active_minus1, "[1]", 0, 14 );
624
2
    pcPPS->setNumRefIdxL1DefaultActive( pps_num_ref_idx_default_active_minus1 + 1 );
625
2
  }
626
627
2
  X_READ_FLAG( pps_rpl1_idx_present_flag );
628
2
  pcPPS->setRpl1IdxPresentFlag( pps_rpl1_idx_present_flag );
629
630
2
  X_READ_FLAG_CHECK( pps_weighted_pred_flag,
631
2
                     sps->getUseWP() == 0 && pps_weighted_pred_flag != 0,
632
2
                     "sps_weighted_pred_flag is equal to 0, the value of pps_weighted_pred_flag shall be equal to 0." );
633
2
  pcPPS->setUseWP( pps_weighted_pred_flag );
634
635
2
  X_READ_FLAG_CHECK( pps_weighted_bipred_flag,
636
2
                     sps->getUseWPBiPred() == 0 && pps_weighted_bipred_flag != 0,
637
2
                     "When sps_weighted_bipred_flag is equal to 0, the value of pps_weighted_bipred_flag shall be equal to 0." );
638
2
  pcPPS->setWPBiPred( pps_weighted_bipred_flag );
639
640
2
  X_READ_FLAG_CHECK( pps_ref_wraparound_enabled_flag,
641
2
                     ( sps->getUseWrapAround() == 0 || CtbSizeY / MinCbSizeY + 1 > pps_pic_width_in_luma_samples / MinCbSizeY - 1 )
642
2
                       && pps_ref_wraparound_enabled_flag != 0,
643
2
                     "When sps_ref_wraparound_enabled_flag is equal to 0 or the value of CtbSizeY / MinCbSizeY + 1 is greater than"
644
2
                     " pps_pic_width_in_luma_samples / MinCbSizeY − 1, the value of pps_ref_wraparound_enabled_flag shall be equal to 0." );
645
2
  pcPPS->setUseWrapAround( pps_ref_wraparound_enabled_flag );
646
647
2
  if( pps_ref_wraparound_enabled_flag )
648
0
  {
649
0
    X_READ_UVLC( pps_pic_width_minus_wraparound_offset, 0, ( pps_pic_width_in_luma_samples / MinCbSizeY ) - ( CtbSizeY / MinCbSizeY ) - 2 );
650
0
    pcPPS->setPicWidthMinusWrapAroundOffset( pps_pic_width_minus_wraparound_offset );
651
0
  }
652
653
2
  X_READ_SVLC( pps_init_qp_minus26, -( 26 + sps->getQpBDOffset() ), 37 );
654
2
  pcPPS->setPicInitQPMinus26( pps_init_qp_minus26 );
655
656
2
  X_READ_FLAG( pps_cu_qp_delta_enabled_flag );
657
2
  pcPPS->setUseDQP( pps_cu_qp_delta_enabled_flag );
658
659
2
  X_READ_FLAG_CHECK( pps_chroma_tool_offsets_present_flag,
660
2
                     sps->getChromaFormatIdc() == 0 && pps_chroma_tool_offsets_present_flag != 0,
661
2
                     "When sps_chroma_format_idc is equal to 0, the value of pps_chroma_tool_offsets_present_flag shall be equal to 0." );
662
2
  pcPPS->setPPSChromaToolFlag( pps_chroma_tool_offsets_present_flag );
663
664
2
  if( pps_chroma_tool_offsets_present_flag )
665
0
  {
666
0
    X_READ_SVLC( pps_cb_qp_offset, -12, 12 );
667
0
    pcPPS->setQpOffset( COMPONENT_Cb, pps_cb_qp_offset );
668
669
0
    X_READ_SVLC( pps_cr_qp_offset, -12, 12 );
670
0
    pcPPS->setQpOffset( COMPONENT_Cr, pps_cr_qp_offset );
671
672
0
    X_READ_FLAG_CHECK( pps_joint_cbcr_qp_offset_present_flag,
673
0
                       ( sps->getChromaFormatIdc() == 0 || sps->getJointCbCrEnabledFlag() == 0 ) && pps_joint_cbcr_qp_offset_present_flag != 0,
674
0
                       "When sps_chroma_format_idc is equal to 0 or sps_joint_cbcr_enabled_flag is equal to 0, the value of"
675
0
                       " pps_joint_cbcr_qp_offset_present_flag shall be equal to 0." );
676
0
    pcPPS->setJointCbCrQpOffsetPresentFlag( pps_joint_cbcr_qp_offset_present_flag );
677
678
0
    if( pps_joint_cbcr_qp_offset_present_flag )
679
0
    {
680
0
      X_READ_SVLC( pps_joint_cbcr_qp_offset_value, -12, 12 );
681
0
      pcPPS->setQpOffset( JOINT_CbCr, pps_joint_cbcr_qp_offset_value );
682
0
    }
683
0
    else
684
0
    {
685
0
      pcPPS->setQpOffset( JOINT_CbCr, 0 );
686
0
    }
687
688
0
    X_READ_FLAG( pps_slice_chroma_qp_offsets_present_flag );
689
0
    pcPPS->setSliceChromaQpFlag( pps_slice_chroma_qp_offsets_present_flag );
690
691
0
    X_READ_FLAG( pps_cu_chroma_qp_offset_list_enabled_flag );
692
0
    if( !pps_cu_chroma_qp_offset_list_enabled_flag )
693
0
    {
694
0
      pcPPS->clearChromaQpOffsetList();
695
0
    }
696
0
    else
697
0
    {
698
0
      X_READ_UVLC( pps_chroma_qp_offset_list_len_minus1, 0, MAX_QP_OFFSET_LIST_SIZE - 1 );
699
700
0
      for( int cuChromaQpOffsetIdx = 0; cuChromaQpOffsetIdx <= pps_chroma_qp_offset_list_len_minus1; cuChromaQpOffsetIdx++ )
701
0
      {
702
0
        X_READ_SVLC_idx( pps_cb_qp_offset_list, "[i]", -12, 12 );
703
0
        X_READ_SVLC_idx( pps_cr_qp_offset_list, "[i]", -12, 12 );
704
0
        int jointCbCrOffset = 0;
705
0
        if( pps_joint_cbcr_qp_offset_present_flag )
706
0
        {
707
0
          X_READ_SVLC_idx( pps_joint_cbcr_qp_offset_list, "[i]", -12, 12 );
708
0
          jointCbCrOffset = pps_joint_cbcr_qp_offset_list;
709
0
        }
710
        // table uses +1 for index (see comment inside the function)
711
0
        pcPPS->setChromaQpOffsetListEntry( cuChromaQpOffsetIdx + 1, pps_cb_qp_offset_list, pps_cr_qp_offset_list, jointCbCrOffset );
712
0
      }
713
0
      CHECK( pcPPS->getChromaQpOffsetListLen() != pps_chroma_qp_offset_list_len_minus1 + 1, "Invalid chroma QP offset list length" );
714
0
    }
715
0
  }
716
2
  else
717
2
  {
718
2
    pcPPS->setQpOffset( COMPONENT_Cb, 0 );
719
2
    pcPPS->setQpOffset( COMPONENT_Cr, 0 );
720
2
    pcPPS->setJointCbCrQpOffsetPresentFlag( 0 );
721
2
    pcPPS->setSliceChromaQpFlag( 0 );
722
2
    pcPPS->clearChromaQpOffsetList();
723
2
  }
724
725
2
  X_READ_FLAG( pps_deblocking_filter_control_present_flag );
726
2
  pcPPS->setDeblockingFilterControlPresentFlag( pps_deblocking_filter_control_present_flag );
727
728
2
  if( pps_deblocking_filter_control_present_flag )
729
0
  {
730
0
    X_READ_FLAG( pps_deblocking_filter_override_enabled_flag );
731
0
    pcPPS->setDeblockingFilterOverrideEnabledFlag( pps_deblocking_filter_override_enabled_flag );
732
733
0
    X_READ_FLAG( pps_deblocking_filter_disabled_flag );
734
0
    pcPPS->setPPSDeblockingFilterDisabledFlag( pps_deblocking_filter_disabled_flag );
735
736
0
    if( !pps_no_pic_partition_flag && pps_deblocking_filter_override_enabled_flag )
737
0
    {
738
0
      X_READ_FLAG( pps_dbf_info_in_ph_flag );
739
0
      pcPPS->setDbfInfoInPhFlag( pps_dbf_info_in_ph_flag );
740
0
    }
741
742
0
    if( !pps_deblocking_filter_disabled_flag )
743
0
    {
744
0
      X_READ_SVLC( pps_luma_beta_offset_div2, -12, 12 );
745
0
      pcPPS->setDeblockingFilterBetaOffsetDiv2( pps_luma_beta_offset_div2 );
746
747
0
      X_READ_SVLC( pps_luma_tc_offset_div2, -12, 12 );
748
0
      pcPPS->setDeblockingFilterTcOffsetDiv2( pps_luma_tc_offset_div2 );
749
750
0
      if( pps_chroma_tool_offsets_present_flag )
751
0
      {
752
0
        X_READ_SVLC( pps_cb_beta_offset_div2, -12, 12 );
753
0
        pcPPS->setDeblockingFilterCbBetaOffsetDiv2( pps_cb_beta_offset_div2 );
754
755
0
        X_READ_SVLC( pps_cb_tc_offset_div2, -12, 12 );
756
0
        pcPPS->setDeblockingFilterCbTcOffsetDiv2( pps_cb_tc_offset_div2 );
757
758
0
        X_READ_SVLC( pps_cr_beta_offset_div2, -12, 12 );
759
0
        pcPPS->setDeblockingFilterCrBetaOffsetDiv2( pps_cr_beta_offset_div2 );
760
761
0
        X_READ_SVLC( pps_cr_tc_offset_div2, -12, 12 );
762
0
        pcPPS->setDeblockingFilterCrTcOffsetDiv2( pps_cr_tc_offset_div2 );
763
0
      }
764
0
      else
765
0
      {
766
0
        pcPPS->setDeblockingFilterCbBetaOffsetDiv2( pps_luma_beta_offset_div2 );
767
0
        pcPPS->setDeblockingFilterCbTcOffsetDiv2( pps_luma_tc_offset_div2 );
768
0
        pcPPS->setDeblockingFilterCrBetaOffsetDiv2( pps_luma_beta_offset_div2 );
769
0
        pcPPS->setDeblockingFilterCrTcOffsetDiv2( pps_luma_tc_offset_div2 );
770
0
      }
771
0
    }
772
0
  }
773
774
2
  if( !pps_no_pic_partition_flag )
775
0
  {
776
0
    X_READ_FLAG( pps_rpl_info_in_ph_flag );
777
0
    pcPPS->setRplInfoInPhFlag( pps_rpl_info_in_ph_flag );
778
779
0
    X_READ_FLAG( pps_sao_info_in_ph_flag );
780
0
    pcPPS->setSaoInfoInPhFlag( pps_sao_info_in_ph_flag );
781
782
0
    X_READ_FLAG( pps_alf_info_in_ph_flag );
783
0
    pcPPS->setAlfInfoInPhFlag( pps_alf_info_in_ph_flag );
784
785
0
    if( ( pps_weighted_pred_flag || pps_weighted_bipred_flag ) && pps_rpl_info_in_ph_flag )
786
0
    {
787
0
      X_READ_FLAG( pps_wp_info_in_ph_flag );
788
0
      pcPPS->setWpInfoInPhFlag( pps_wp_info_in_ph_flag );
789
0
    }
790
791
0
    X_READ_FLAG( pps_qp_delta_info_in_ph_flag );
792
0
    pcPPS->setQpDeltaInfoInPhFlag( pps_qp_delta_info_in_ph_flag );
793
0
  }
794
795
2
  X_READ_FLAG( pps_picture_header_extension_present_flag );
796
2
  pcPPS->setPictureHeaderExtensionPresentFlag( pps_picture_header_extension_present_flag );
797
798
2
  X_READ_FLAG( pps_slice_header_extension_present_flag );
799
2
  pcPPS->setSliceHeaderExtensionPresentFlag( pps_slice_header_extension_present_flag );
800
801
2
  X_READ_FLAG( pps_extension_flag );
802
2
  if( pps_extension_flag )
803
0
  {
804
0
    while( xMoreRbspData() )
805
0
    {
806
0
      X_READ_FLAG( pps_extension_data_flag );
807
0
      (void) pps_extension_data_flag;
808
0
    }
809
0
  }
810
811
2
  xReadRbspTrailingBits();
812
813
  // ================================
814
  //  PPS READING DONE
815
  // ================================
816
817
2
  if( pcPPS->getPicWidthInLumaSamples() == sps->getMaxPicWidthInLumaSamples() && pcPPS->getPicHeightInLumaSamples() == sps->getMaxPicHeightInLumaSamples() )
818
0
  {
819
0
    CHECK( pcPPS->getConformanceWindowPresentFlag(),
820
0
                       "When pps_pic_width_in_luma_samples is equal to sps_pic_width_max_in_luma_samples and "
821
0
                       "pps_pic_height_in_luma_samples is equal to sps_pic_height_max_in_luma_samples, the value of "
822
0
                       "pps_conformance_window_flag shall be equal to 0" );
823
824
0
    pcPPS->setConformanceWindow( sps->getConformanceWindow() );
825
826
0
    if( !pcPPS->getScalingWindow().getWindowEnabledFlag() )
827
0
    {
828
0
      pcPPS->setScalingWindow( pcPPS->getConformanceWindow() );
829
0
    }
830
0
  }
831
832
2
  pcPPS->finalizePPSPartitioning( sps );
833
834
  // set wraparound offset from PPS and SPS info
835
2
  int minCbSizeY = ( 1 << sps->getLog2MinCodingBlockSize() );
836
2
  CHECK( !sps->getUseWrapAround() && pcPPS->getUseWrapAround(),
837
2
         "When sps_ref_wraparound_enabled_flag is equal to 0, the value of pps_ref_wraparound_enabled_flag shall be equal to 0." );
838
2
  CHECK( sps->getCTUSize() / minCbSizeY + 1 > pcPPS->getPicWidthInLumaSamples() / minCbSizeY - 1 && pcPPS->getUseWrapAround(),
839
2
         "When the value of CtbSizeY / MinCbSizeY + 1 is greater than pic_width_in_luma_samples / MinCbSizeY - 1, the value of "
840
2
         "pps_ref_wraparound_enabled_flag shall be equal to 0." );
841
2
  if( pcPPS->getUseWrapAround() )
842
0
  {
843
0
    CHECK( pcPPS->getPicWidthMinusWrapAroundOffset() > pcPPS->getPicWidthInLumaSamples() / minCbSizeY - sps->getCTUSize() / minCbSizeY - 2,
844
0
           "pps_pic_width_minus_wraparound_ofsfet shall be less than or equal to pps_pic_width_in_luma_samples/MinCbSizeY - CtbSizeY/MinCbSizeY-2" );
845
0
    pcPPS->setWrapAroundOffset( minCbSizeY * ( pcPPS->getPicWidthInLumaSamples() / minCbSizeY - pcPPS->getPicWidthMinusWrapAroundOffset() ) );
846
0
  }
847
2
  else
848
2
  {
849
2
    pcPPS->setWrapAroundOffset( 0 );
850
2
  }
851
852
2
  pcPPS->pcv = std::make_unique<PreCalcValues>( *sps, *pcPPS );
853
2
}
854
855
bool HLSyntaxReader::parseAPS( APS* aps )
856
132
{
857
#if ENABLE_TRACING
858
  xTraceAPSHeader();
859
#endif
860
861
132
  X_READ_CODE_NO_RANGE( aps_params_type, 3 );
862
  // if not in supported range, this APS is ignored `switch() -> default`
863
132
  aps->setAPSType( aps_params_type );
864
865
132
  X_READ_CODE_NO_RANGE( adaptation_parameter_set_id, 5 );
866
  // range check happens later in the `switch( aps_params_type )`
867
132
  aps->setAPSId( adaptation_parameter_set_id );
868
869
132
  X_READ_FLAG( aps_chroma_present_flag );
870
132
  aps->chromaPresentFlag = aps_chroma_present_flag;
871
872
132
  switch( aps_params_type )
873
132
  {
874
64
  case ALF_APS:
875
64
    CHECK_READ_RANGE( adaptation_parameter_set_id, 0, 7, "adaptation_parameter_set_id for ALF_APS" );
876
62
    parseAlfAps( aps );
877
62
    break;
878
16
  case LMCS_APS:
879
16
    CHECK_READ_RANGE( adaptation_parameter_set_id, 0, 3, "adaptation_parameter_set_id for LMCS_APS," );
880
16
    parseLmcsAps( aps );
881
16
    break;
882
48
  case SCALING_LIST_APS:
883
48
    CHECK_READ_RANGE( adaptation_parameter_set_id, 0, 7, "adaptation_parameter_set_id for SCALING_APS" );
884
46
    parseScalingListAps( aps );
885
46
    break;
886
4
  default:
887
4
    WARN( "unknown APS type (" << aps_params_type << ")" );
888
4
    return false;
889
132
  }
890
891
44
  X_READ_FLAG( aps_extension_flag );
892
44
  if( aps_extension_flag )
893
32
  {
894
2.75k
    while( xMoreRbspData() )
895
2.72k
    {
896
2.72k
      X_READ_FLAG( aps_extension_data_flag );
897
2.72k
      (void) aps_extension_data_flag;
898
2.72k
    }
899
32
  }
900
44
  xReadRbspTrailingBits();
901
902
44
  return true;
903
132
}
904
905
void HLSyntaxReader::parseAlfAps( APS* aps )
906
62
{
907
62
  AlfSliceParam& param = aps->getAlfAPSParam();
908
62
  param.reset();
909
910
62
  X_READ_FLAG( alf_luma_new_filter );   //  standard: alf_luma_filter_signal_flag
911
62
  param.newFilterFlag[CHANNEL_TYPE_LUMA] = alf_luma_new_filter;
912
913
62
  CcAlfFilterParam& ccAlfParam = aps->getCcAlfAPSParam();
914
62
  ccAlfParam.reset();
915
62
  if( aps->chromaPresentFlag )
916
36
  {
917
36
    X_READ_FLAG( alf_chroma_new_filter );   // standard: alf_chroma_filter_signal_flag
918
36
    param.newFilterFlag[CHANNEL_TYPE_CHROMA] = alf_chroma_new_filter;
919
920
36
    X_READ_FLAG( alf_cc_cb_filter_signal_flag );
921
36
    ccAlfParam.newCcAlfFilter[COMPONENT_Cb - 1] = alf_cc_cb_filter_signal_flag;
922
923
36
    X_READ_FLAG( alf_cc_cr_filter_signal_flag );
924
36
    ccAlfParam.newCcAlfFilter[COMPONENT_Cr - 1] = alf_cc_cr_filter_signal_flag;
925
36
  }
926
62
  CHECK( param.newFilterFlag[CHANNEL_TYPE_LUMA] == 0 && param.newFilterFlag[CHANNEL_TYPE_CHROMA] == 0
927
62
         && ccAlfParam.newCcAlfFilter[COMPONENT_Cb - 1] == 0 && ccAlfParam.newCcAlfFilter[COMPONENT_Cr - 1] == 0,
928
62
         "bitstream conformance error: one of alf_luma_filter_signal_flag, alf_chroma_filter_signal_flag, "
929
62
         "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
60
  static constexpr int NumAlfFilters = MAX_NUM_ALF_CLASSES;
933
934
60
  if( alf_luma_new_filter )
935
34
  {
936
34
    X_READ_FLAG( alf_luma_clip );
937
34
    param.nonLinearFlagLuma = alf_luma_clip;
938
939
34
    X_READ_UVLC( alf_luma_num_filters_signalled_minus1, 0, NumAlfFilters - 1 );
940
34
    param.numLumaFilters = alf_luma_num_filters_signalled_minus1 + 1;
941
942
34
    if( alf_luma_num_filters_signalled_minus1 > 0 )
943
14
    {
944
14
      const int length = (int) ceil( log2( alf_luma_num_filters_signalled_minus1 + 1 ) );
945
244
      for( int filtIdx = 0; filtIdx < NumAlfFilters; filtIdx++ )
946
230
      {
947
230
        X_READ_CODE( alf_luma_coeff_delta_idx, length, 0, alf_luma_num_filters_signalled_minus1 );
948
230
        param.filterCoeffDeltaIdx[filtIdx] = alf_luma_coeff_delta_idx;
949
230
      }
950
14
    }
951
952
34
    alfFilterCoeffs( param, false, 0 );
953
34
  }
954
955
60
  if( param.newFilterFlag[CHANNEL_TYPE_CHROMA] )
956
10
  {
957
10
    X_READ_FLAG( alf_nonlinear_enable_flag_chroma );
958
10
    param.nonLinearFlagChroma = alf_nonlinear_enable_flag_chroma;
959
960
10
    X_READ_UVLC( alf_chroma_num_alts_minus1, 0, MAX_NUM_ALF_ALTERNATIVES_CHROMA - 1 );
961
10
    param.numAlternativesChroma = alf_chroma_num_alts_minus1 + 1;
962
963
30
    for( int altIdx = 0; altIdx <= alf_chroma_num_alts_minus1; ++altIdx )
964
20
    {
965
20
      alfFilterCoeffs( param, true, altIdx );
966
20
    }
967
10
  }
968
969
124
  for( int ccIdx = 0; ccIdx < 2; ccIdx++ )
970
70
  {
971
70
    if( ccAlfParam.newCcAlfFilter[ccIdx] )
972
22
    {
973
22
      uint32_t code;
974
22
      READ_UVLC( code, ccIdx == 0 ? "alf_cc_cb_filters_signalled_minus1" : "alf_cc_cr_filters_signalled_minus1" );
975
22
      CHECK_READ_RANGE( code, 0, 3, ( ccIdx == 0 ? "alf_cc_cb_filters_signalled_minus1" : "alf_cc_cr_filters_signalled_minus1" ) )
976
977
16
      ccAlfParam.ccAlfFilterCount[ccIdx] = code + 1;
978
979
42
      for( int filterIdx = 0; filterIdx < ccAlfParam.ccAlfFilterCount[ccIdx]; filterIdx++ )
980
26
      {
981
26
        ccAlfParam.ccAlfFilterIdxEnabled[ccIdx][filterIdx] = true;
982
983
26
        const int numCoeff = g_alfNumCoeff[CC_ALF];
984
985
26
        short* coeff = ccAlfParam.ccAlfCoeff[ccIdx][filterIdx];
986
        // Filter coefficients
987
194
        for( int i = 0; i < numCoeff - 1; i++ )
988
168
        {
989
168
          READ_CODE( 3, code, ccIdx == 0 ? "alf_cc_cb_mapped_coeff_abs" : "alf_cc_cr_mapped_coeff_abs" );
990
168
          if( code )
991
74
          {
992
74
            coeff[i] = 1 << ( code - 1 );
993
994
74
            READ_FLAG( code, ccIdx == 0 ? "alf_cc_cb_coeff_sign" : "alf_cc_cr_coeff_sign" );
995
74
            coeff[i] *= 1 - 2 * code;
996
74
          }
997
94
          else
998
94
          {
999
94
            coeff[i] = 0;
1000
94
          }
1001
168
        }
1002
1003
26
        DTRACE( g_trace_ctx, D_SYNTAX, "%s coeff filterIdx %d: ", ccIdx == 0 ? "Cb" : "Cr", filterIdx );
1004
186
        for( int i = 0; i < numCoeff; i++ )
1005
160
        {
1006
160
          DTRACE( g_trace_ctx, D_SYNTAX, "%d ", coeff[i] );
1007
160
        }
1008
26
        DTRACE( g_trace_ctx, D_SYNTAX, "\n" );
1009
26
      }
1010
16
    }
1011
70
  }
1012
60
}
1013
1014
void HLSyntaxReader::parseLmcsAps( APS* aps )
1015
16
{
1016
16
  SliceReshapeInfo& info = aps->getReshaperAPSInfo();
1017
16
  info.reset();
1018
1019
16
  X_READ_UVLC( lmcs_min_bin_idx, 0, 15 );
1020
16
  info.reshaperModelMinBinIdx = lmcs_min_bin_idx;
1021
1022
16
  X_READ_UVLC( lmcs_delta_max_bin_idx, 0, 15 );
1023
16
  info.reshaperModelMaxBinIdx = PIC_CODE_CW_BINS - 1 - lmcs_delta_max_bin_idx;
1024
16
  CHECK( info.reshaperModelMaxBinIdx < lmcs_min_bin_idx, "The value of LmcsMaxBinIdx shall be greater than or equal to lmcs_min_bin_idx." );
1025
1026
16
  X_READ_UVLC( lmcs_delta_cw_prec_minus1, 0, 14 );
1027
16
  info.maxNbitsNeededDeltaCW = lmcs_delta_cw_prec_minus1 + 1;
1028
1029
16
  CHECK( info.maxNbitsNeededDeltaCW == 0, "wrong" );
1030
1031
166
  for( uint32_t i = info.reshaperModelMinBinIdx; i <= info.reshaperModelMaxBinIdx; i++ )
1032
150
  {
1033
150
    X_READ_CODE_NO_RANGE_idx( lmcs_delta_abs_cw, "[ i ]", info.maxNbitsNeededDeltaCW );
1034
150
    info.reshaperModelBinCWDelta[i] = lmcs_delta_abs_cw;
1035
150
    if( lmcs_delta_abs_cw )
1036
96
    {
1037
96
      X_READ_FLAG_idx( lmcs_delta_sign_cw_flag, "[ i ]" );
1038
96
      info.reshaperModelBinCWDelta[i] *= 1 - 2 * lmcs_delta_sign_cw_flag;
1039
96
    }
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
150
  }
1048
1049
16
  if( aps->chromaPresentFlag )
1050
8
  {
1051
8
    X_READ_CODE_NO_RANGE( lmcs_delta_abs_crs, 3 );
1052
8
    info.chrResScalingOffset = lmcs_delta_abs_crs;
1053
8
    if( lmcs_delta_abs_crs > 0 )
1054
6
    {
1055
6
      X_READ_FLAG( lmcs_delta_sign_crs_flag );
1056
6
      info.chrResScalingOffset *= ( 1 - 2 * lmcs_delta_sign_crs_flag );
1057
6
    }
1058
8
  }
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
16
}
1063
1064
void HLSyntaxReader::parseScalingListAps( APS* aps )
1065
46
{
1066
46
  ScalingList& info = aps->getScalingList();
1067
46
  parseScalingList( &info, aps->chromaPresentFlag );
1068
46
}
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 (pcVUI->getAspectRatioIdc() > 0 && (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
6
{
1383
6
  CHECK( maxSubLayersMinus1 >= MAX_TLAYER, "maxSubLayersMinus1 out of bounds" );
1384
16
  for( int i = ( subLayerInfoFlag ? 0 : maxSubLayersMinus1 ); i <= maxSubLayersMinus1; i++ )
1385
12
  {
1386
12
    X_READ_UVLC_NO_RANGE_idx( dpb_max_dec_pic_buffering_minus1, "[i]" );
1387
12
    CHECK( i > 0 && dpb_max_dec_pic_buffering_minus1 < pcSPS->getMaxDecPicBuffering( i - 1 ) - 1,
1388
12
           "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
10
    pcSPS->setMaxDecPicBuffering( dpb_max_dec_pic_buffering_minus1 + 1, i );
1390
1391
10
    X_READ_UVLC_idx( dpb_max_num_reorder_pics, "[i]", 0, dpb_max_dec_pic_buffering_minus1 );
1392
10
    CHECK( i > 0 && dpb_max_dec_pic_buffering_minus1 < pcSPS->getNumReorderPics( i - 1 ),
1393
10
           "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
10
    pcSPS->setNumReorderPics( dpb_max_num_reorder_pics, i );
1395
1396
10
    X_READ_UVLC_idx( dpb_max_latency_increase_plus1, "[i]", 0, ( uint64_t( 1 ) << 32 ) - 2 );
1397
10
    pcSPS->setMaxLatencyIncreasePlus1( dpb_max_latency_increase_plus1, i );
1398
10
  }
1399
6
}
1400
1401
void HLSyntaxReader::parseExtraPHBitsStruct( SPS *sps, int numBytes )
1402
16
{
1403
16
  std::vector<bool> presentFlags;
1404
16
  presentFlags.resize ( 8 * numBytes );
1405
1406
208
  for( int i = 0; i < 8 * numBytes; i++ )
1407
192
  {
1408
192
    X_READ_FLAG_idx( sps_extra_ph_bit_present_flag, "[i]" );
1409
192
    presentFlags[i] = sps_extra_ph_bit_present_flag;
1410
192
  }
1411
1412
16
  sps->setExtraPHBitPresentFlags( std::move( presentFlags ) );
1413
16
}
1414
1415
void HLSyntaxReader::parseExtraSHBitsStruct( SPS *sps, int numBytes )
1416
16
{
1417
16
  std::vector<bool> presentFlags;
1418
16
  presentFlags.resize ( 8 * numBytes );
1419
1420
192
  for( int i = 0; i < 8 * numBytes; i++ )
1421
176
  {
1422
176
    X_READ_FLAG_idx( sps_extra_sh_bit_present_flag, "[i]" );
1423
176
    presentFlags[i] = sps_extra_sh_bit_present_flag;
1424
176
  }
1425
1426
16
  sps->setExtraSHBitPresentFlags( std::move( presentFlags ) );
1427
16
}
1428
1429
void HLSyntaxReader::parseSPS( SPS* sps, const ParameterSetManager* parameterSetManager )
1430
108
{
1431
#if ENABLE_TRACING
1432
  xTraceSPSHeader ();
1433
#endif
1434
1435
108
  X_READ_CODE_NO_RANGE( sps_seq_parameter_set_id, 4 );
1436
108
  sps->setSPSId( sps_seq_parameter_set_id );
1437
1438
108
  X_READ_CODE_NO_RANGE( sps_video_parameter_set_id, 4 );
1439
108
  (void) sps_video_parameter_set_id;   // sps->setVPSId( sps_video_parameter_set_id ); // TODO: change to support VPS
1440
108
  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
108
  X_READ_CODE( sps_max_sublayers_minus1, 3, 0, 6 );
1449
108
  CHECK( vps && sps_video_parameter_set_id > vps->getMaxSubLayers(),
1450
108
         "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
108
         "inclusive." )
1452
108
  sps->setMaxTLayers( sps_max_sublayers_minus1 + 1 );
1453
1454
108
  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
108
  sps->setChromaFormatIdc( ChromaFormat( sps_chroma_format_idc ) );
1458
1459
108
  X_READ_CODE( sps_log2_ctu_size_minus5, 2, 0, 2 );
1460
108
  sps->setCTUSize( 1 << ( sps_log2_ctu_size_minus5 + 5 ) );
1461
1462
108
  const int CtbLog2SizeY = sps_log2_ctu_size_minus5 + 5;
1463
108
  const int CtbSizeY     = 1 << CtbLog2SizeY;
1464
108
  sps->setMaxCUWidth( sps->getCTUSize() );
1465
108
  sps->setMaxCUHeight( sps->getCTUSize() );
1466
1467
108
  X_READ_FLAG( sps_ptl_dpb_hrd_params_present_flag );
1468
108
  CHECK( sps_video_parameter_set_id == 0 && !sps_ptl_dpb_hrd_params_present_flag,
1469
108
                     "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
108
  sps->setPtlDpbHrdParamsPresentFlag( sps_ptl_dpb_hrd_params_present_flag );
1471
1472
108
  if( sps_ptl_dpb_hrd_params_present_flag )
1473
52
  {
1474
52
    parseProfileTierLevel( sps->getProfileTierLevel(), true, sps->getMaxTLayers() - 1 );
1475
52
  }
1476
1477
108
  const ProfileTierLevel* ptl = sps->getProfileTierLevel();
1478
108
  const ConstraintInfo*   gci = ptl->getConstraintInfo();
1479
1480
108
  X_READ_FLAG( sps_gdr_enabled_flag );
1481
108
  CHECK_CONSTRAINT( gci->getNoGdrConstraintFlag() && sps_gdr_enabled_flag,
1482
106
                     "When gci_no_gdr_constraint_flag equal to 1 , the value of sps_gdr_enabled_flag shall be equal to 0" );
1483
106
  sps->setGDREnabledFlag( sps_gdr_enabled_flag );
1484
1485
106
  X_READ_FLAG( sps_ref_pic_resampling_enabled_flag );
1486
106
  CHECK_CONSTRAINT( gci->getNoRprConstraintFlag() && sps_ref_pic_resampling_enabled_flag,
1487
104
                    "When gci_no_ref_pic_resampling_constraint_flag is equal to 1, sps_ref_pic_resampling_enabled_flag shall be equal to 0" );
1488
104
  sps->setRprEnabledFlag( sps_ref_pic_resampling_enabled_flag );
1489
1490
104
  if( sps_ref_pic_resampling_enabled_flag )
1491
4
  {
1492
4
    X_READ_FLAG( sps_res_change_in_clvs_allowed_flag );
1493
4
    CHECK_CONSTRAINT( gci->getNoResChangeInClvsConstraintFlag() && sps_res_change_in_clvs_allowed_flag,
1494
4
                      "When no_res_change_in_clvs_constraint_flag is equal to 1, res_change_in_clvs_allowed_flag shall be equal to 0" );
1495
4
    sps->setResChangeInClvsEnabledFlag( sps_res_change_in_clvs_allowed_flag );
1496
4
  }
1497
1498
104
  X_READ_UVLC_NO_RANGE( sps_pic_width_max_in_luma_samples );
1499
104
  sps->setMaxPicWidthInLumaSamples( sps_pic_width_max_in_luma_samples );
1500
1501
104
  X_READ_UVLC_NO_RANGE( sps_pic_height_max_in_luma_samples );
1502
104
  sps->setMaxPicHeightInLumaSamples( sps_pic_height_max_in_luma_samples );
1503
1504
104
  const int SubWidthC  = 1 << getChannelTypeScaleX( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() );
1505
104
  const int SubHeightC = 1 << getChannelTypeScaleY( CHANNEL_TYPE_CHROMA, sps->getChromaFormatIdc() );
1506
1507
104
  X_READ_FLAG( sps_conformance_window_flag );
1508
104
  sps->setConformanceWindowPresentFlag( sps_conformance_window_flag );
1509
1510
104
  if( sps_conformance_window_flag )
1511
24
  {
1512
24
    X_READ_UVLC_NO_RANGE( sps_conf_win_left_offset );
1513
24
    X_READ_UVLC_NO_RANGE( sps_conf_win_right_offset );
1514
24
    X_READ_UVLC_NO_RANGE( sps_conf_win_top_offset );
1515
24
    X_READ_UVLC_NO_RANGE( sps_conf_win_bottom_offset );
1516
1517
24
    CHECK( SubWidthC * ( sps_conf_win_left_offset + sps_conf_win_right_offset ) > sps_pic_width_max_in_luma_samples,
1518
24
           "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
24
    CHECK( SubHeightC * ( sps_conf_win_top_offset + sps_conf_win_bottom_offset ) > sps_pic_height_max_in_luma_samples,
1520
24
           "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
18
    Window& conf = sps->getConformanceWindow();
1523
18
    conf.setWindowLeftOffset( sps_conf_win_left_offset );
1524
18
    conf.setWindowRightOffset( sps_conf_win_right_offset );
1525
18
    conf.setWindowTopOffset( sps_conf_win_top_offset );
1526
18
    conf.setWindowBottomOffset( sps_conf_win_bottom_offset );
1527
18
  }
1528
98
  X_READ_FLAG( sps_subpic_info_present_flag );
1529
98
  CHECK( sps->getResChangeInClvsEnabledFlag() && sps_subpic_info_present_flag,
1530
98
         "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
96
  CHECK_CONSTRAINT( gci->getNoSubpicInfoConstraintFlag() && sps_subpic_info_present_flag,
1532
96
                    "When gci_no_subpic_info_constraint_flag is equal to 1, the value of subpic_info_present_flag shall be equal to 0" );
1533
96
  sps->setSubPicInfoPresentFlag( sps_subpic_info_present_flag );
1534
1535
1536
96
  if( sps_subpic_info_present_flag )
1537
38
  {
1538
38
    X_READ_UVLC_NO_RANGE( sps_num_subpics_minus1 );
1539
38
    CHECK( sps_num_subpics_minus1 + 1 > ( ( sps_pic_width_max_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY )
1540
38
                                                      * ( ( sps_pic_height_max_in_luma_samples + CtbSizeY - 1 ) / CtbSizeY ),
1541
38
                       "Invalid sps_num_subpics_minus1 value" );
1542
36
    sps->setNumSubPics( sps_num_subpics_minus1 + 1 );
1543
1544
36
    if( sps_num_subpics_minus1 == 0 )
1545
8
    {
1546
8
      sps->setSubPicCtuTopLeftX( 0, 0 );
1547
8
      sps->setSubPicCtuTopLeftY( 0, 0 );
1548
8
      sps->setSubPicWidth( 0, ( sps->getMaxPicWidthInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) );
1549
8
      sps->setSubPicHeight( 0, ( sps->getMaxPicHeightInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) );
1550
8
      sps->setIndependentSubPicsFlag( 1 );
1551
8
      sps->setSubPicSameSizeFlag( 0 );
1552
8
      sps->setSubPicTreatedAsPicFlag( 0, 1 );
1553
8
      sps->setLoopFilterAcrossSubpicEnabledFlag( 0, 0 );
1554
8
    }
1555
28
    else   // ( sps_num_subpics_minus1 > 0 )
1556
28
    {
1557
28
      X_READ_FLAG( sps_independent_subpics_flag );
1558
28
      sps->setIndependentSubPicsFlag( sps_independent_subpics_flag );
1559
1560
28
      X_READ_FLAG( sps_subpic_same_size_flag );
1561
28
      sps->setSubPicSameSizeFlag( sps_subpic_same_size_flag );
1562
1563
28
      const uint32_t tmpWidthVal = ( sps->getMaxPicWidthInLumaSamples() + sps->getCTUSize() - 1 ) / sps->getCTUSize();
1564
28
      const uint32_t tmpHeightVal = ( sps->getMaxPicHeightInLumaSamples() + sps->getCTUSize() - 1 ) / sps->getCTUSize();
1565
1566
28
      const int ceilLog2tmpWidth  = (int) ceil( log2( tmpWidthVal ) );
1567
28
      const int ceilLog2tmpHeight = (int) ceil( log2( tmpHeightVal ) );
1568
116
      for( unsigned picIdx = 0; picIdx < sps->getNumSubPics(); picIdx++ )
1569
98
      {
1570
98
        if( !sps_subpic_same_size_flag || picIdx == 0 )
1571
80
        {
1572
80
          if( picIdx > 0 && sps_pic_width_max_in_luma_samples > CtbSizeY )
1573
10
          {
1574
10
            X_READ_CODE_NO_RANGE_idx( sps_subpic_ctu_top_left_x, "[ i ]", ceilLog2tmpWidth );
1575
10
            sps->setSubPicCtuTopLeftX( picIdx, sps_subpic_ctu_top_left_x );
1576
10
          }
1577
70
          else
1578
70
          {
1579
70
            sps->setSubPicCtuTopLeftX( picIdx, 0 );
1580
70
          }
1581
1582
80
          if( picIdx > 0 && sps_pic_height_max_in_luma_samples > CtbSizeY )
1583
42
          {
1584
42
            X_READ_CODE_NO_RANGE_idx( sps_subpic_ctu_top_left_y, "[ i ]", ceilLog2tmpHeight );
1585
42
            sps->setSubPicCtuTopLeftY( picIdx, sps_subpic_ctu_top_left_y );
1586
42
          }
1587
38
          else
1588
38
          {
1589
38
            sps->setSubPicCtuTopLeftY( picIdx, 0 );
1590
38
          }
1591
1592
80
          if( picIdx < sps_num_subpics_minus1 && sps_pic_width_max_in_luma_samples > CtbSizeY )
1593
20
          {
1594
20
            X_READ_CODE_NO_RANGE_idx( sps_subpic_width_minus1, "[ i ]", ceilLog2tmpWidth );
1595
20
            sps->setSubPicWidth( picIdx, sps_subpic_width_minus1 + 1 );
1596
20
          }
1597
60
          else
1598
60
          {
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
60
            sps->setSubPicWidth( picIdx, tmpWidthVal - sps->getSubPicCtuTopLeftX( picIdx ) );
1602
60
          }
1603
1604
80
          if( picIdx < sps_num_subpics_minus1 && sps_pic_height_max_in_luma_samples > CtbSizeY )
1605
44
          {
1606
44
            X_READ_CODE_NO_RANGE_idx( sps_subpic_height_minus1, "[ i ]", ceilLog2tmpHeight );
1607
44
            sps->setSubPicHeight( picIdx, sps_subpic_height_minus1 + 1 );
1608
44
          }
1609
36
          else
1610
36
          {
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
36
            sps->setSubPicHeight( picIdx, tmpHeightVal - sps->getSubPicCtuTopLeftY( picIdx ) );
1614
36
          }
1615
80
        }
1616
18
        else   // ( sps_subpic_same_size_flag && picIdx != 0 )
1617
18
        {
1618
18
          const int numSubpicCols = tmpWidthVal / sps->getSubPicWidth( 0 );
1619
1620
          // const int numSubpicCols = tmpWidthVal / ( sps->getSubPicWidth( 0 ) + 1 );
1621
18
          CHECK( sps_subpic_same_size_flag && numSubpicCols * tmpHeightVal / sps->getSubPicHeight( 0 ) - 1 != sps_num_subpics_minus1,
1622
18
                 "When sps_subpic_same_size_flag is equal to 1, the value of numSubpicCols * tmpHeightVal / ( sps_subpic_height_minus1[ 0 ] + 1 ) − 1"
1623
18
                 " shall be equal to sps_num_subpics_minus1." )
1624
14
          CHECK( sps_subpic_same_size_flag && tmpWidthVal % sps->getSubPicWidth( 0 ) != 0,
1625
14
                 "When sps_subpic_same_size_flag is equal to 1, the value of tmpWidthVal % ( sps_subpic_width_minus1[ 0 ] + 1 ) shall"
1626
14
                 " be equal to 0." );
1627
12
          CHECK( sps_subpic_same_size_flag && tmpHeightVal % sps->getSubPicHeight( 0 ) != 0,
1628
12
                 "When sps_subpic_same_size_flag is equal to 1, the value of tmpHeightVal % ( sps_subpic_height_minus1[ 0 ] + 1 ) shall"
1629
12
                 " 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
12
          sps->setSubPicCtuTopLeftX( picIdx, ( picIdx % numSubpicCols ) * sps->getSubPicWidth( 0 ) );
1634
12
          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
12
          sps->setSubPicWidth( picIdx, sps->getSubPicWidth( 0 ) );
1638
12
          sps->setSubPicHeight( picIdx, sps->getSubPicHeight( 0 ) );
1639
12
        }
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
92
        Window& conf = sps->getConformanceWindow();
1652
92
        CHECK( sps->getSubPicCtuTopLeftX( picIdx ) * CtbSizeY >= sps->getMaxPicWidthInLumaSamples() - conf.getWindowRightOffset() * SubWidthC,
1653
92
               "The value of ( sps_subpic_ctu_top_left_x[ i ] * CtbSizeY )"
1654
92
               " shall be less than ( sps_pic_width_max_in_luma_samples - sps_conf_win_right_offset * SubWidthC )." );
1655
88
        CHECK( ( sps->getSubPicCtuTopLeftX( picIdx ) + sps->getSubPicWidth( picIdx ) ) * CtbSizeY <= conf.getWindowLeftOffset() * SubWidthC,
1656
88
               "The value of ( ( sps_subpic_ctu_top_left_x[ i ] + sps_subpic_width_minus1[ i ] + 1 ) * CtbSizeY )"
1657
88
               " shall be greater than ( sps_conf_win_left_offset * SubWidthC )." );
1658
88
        CHECK( sps->getSubPicCtuTopLeftY( picIdx ) * CtbSizeY >= sps->getMaxPicHeightInLumaSamples() - conf.getWindowBottomOffset() * SubHeightC,
1659
88
               "The value of ( sps_subpic_ctu_top_left_y[ i ] * CtbSizeY )"
1660
88
               " shall  be less than ( sps_pic_height_max_in_luma_samples - sps_conf_win_bottom_offset * SubHeightC )." );
1661
88
        CHECK( ( sps->getSubPicCtuTopLeftY( picIdx ) + sps->getSubPicHeight( picIdx ) ) * CtbSizeY <= conf.getWindowTopOffset() * SubHeightC,
1662
88
               "The value of ( ( sps_subpic_ctu_top_left_y[ i ] + sps_subpic_height_minus1[ i ] + 1 ) * CtbSizeY )"
1663
88
               " shall be greater than ( sps_conf_win_top_offset * SubHeightC )." );
1664
1665
88
        if( !sps_independent_subpics_flag )
1666
62
        {
1667
62
          X_READ_FLAG_idx( sps_subpic_treated_as_pic_flag, "[ i ]" );
1668
62
          sps->setSubPicTreatedAsPicFlag( picIdx, sps_subpic_treated_as_pic_flag );
1669
1670
62
          X_READ_FLAG_idx( sps_loop_filter_across_subpic_enabled_flag, "[ i ]" );
1671
62
          sps->setLoopFilterAcrossSubpicEnabledFlag( picIdx, sps_loop_filter_across_subpic_enabled_flag );
1672
62
        }
1673
26
        else
1674
26
        {
1675
          // should be set as default
1676
26
            sps->setSubPicTreatedAsPicFlag( picIdx, 1 );
1677
26
        }
1678
88
      }   //      for( unsigned picIdx = 0; picIdx < sps->getNumSubPics(); picIdx++ )
1679
28
    }
1680
1681
1682
26
    X_READ_UVLC( sps_subpic_id_len_minus1, 0, 15 );
1683
26
    CHECK( 1 << ( sps_subpic_id_len_minus1 + 1 ) < sps_num_subpics_minus1 + 1,
1684
26
           "The value of 1 << ( sps_subpic_id_len_minus1 + 1 ) shall be greater than or equal to sps_num_subpics_minus1 + 1" );
1685
24
    sps->setSubPicIdLen( sps_subpic_id_len_minus1 + 1 );
1686
1687
24
    X_READ_FLAG( sps_subpic_id_mapping_explicitly_signalled_flag );
1688
24
    sps->setSubPicIdMappingExplicitlySignalledFlag( sps_subpic_id_mapping_explicitly_signalled_flag );
1689
1690
24
    if( sps_subpic_id_mapping_explicitly_signalled_flag )
1691
10
    {
1692
10
      X_READ_FLAG( sps_subpic_id_mapping_present_flag );
1693
10
      sps->setSubPicIdMappingPresentFlag( sps_subpic_id_mapping_present_flag );
1694
1695
10
      if( sps_subpic_id_mapping_present_flag )
1696
8
      {
1697
30
        for( int picIdx = 0; picIdx <= sps_num_subpics_minus1; picIdx++ )
1698
22
        {
1699
22
          X_READ_CODE_NO_RANGE_idx( sps_subpic_id, "[ i ]", sps->getSubPicIdLen() );
1700
22
          sps->setSubPicId( picIdx, sps_subpic_id );
1701
22
        }
1702
8
      }
1703
10
    }
1704
24
  }   // sps_subpic_info_present_flag
1705
58
  else  // ( !sps_subpic_info_present_flag )
1706
58
  {
1707
58
    sps->setSubPicIdMappingExplicitlySignalledFlag( 0 );
1708
58
    sps->setNumSubPics( 1 );
1709
58
    sps->setSubPicCtuTopLeftX( 0, 0 );
1710
58
    sps->setSubPicCtuTopLeftY( 0, 0 );
1711
58
    sps->setSubPicWidth( 0, ( sps->getMaxPicWidthInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) );
1712
58
    sps->setSubPicHeight( 0, ( sps->getMaxPicHeightInLumaSamples() + sps->getCTUSize() - 1 ) >> getLog2( sps->getCTUSize() ) );
1713
58
    sps->setSubPicTreatedAsPicFlag( 0, true );
1714
58
    sps->setLoopFilterAcrossSubpicEnabledFlag( 0, false );
1715
58
  }
1716
1717
82
  if( !sps->getSubPicIdMappingExplicitlySignalledFlag() || !sps->getSubPicIdMappingPresentFlag() )
1718
34
  {
1719
86
    for( int picIdx = 0; picIdx < sps->getNumSubPics(); picIdx++ )
1720
52
    {
1721
52
      sps->setSubPicId( picIdx, picIdx );
1722
52
    }
1723
34
  }
1724
1725
82
  X_READ_UVLC( sps_bitdepth_minus8, 0, 8 );
1726
82
  const Profile::Name profile = sps->getProfileTierLevel()->getProfileIdc();
1727
82
  if( profile != Profile::NONE )
1728
6
  {
1729
6
    CHECK( sps_bitdepth_minus8 + 8 > ProfileFeatures::getProfileFeatures( profile )->maxBitDepth,
1730
6
                       "sps_bitdepth_minus8 exceeds range supported by signalled profile" );
1731
4
  }
1732
80
  sps->setBitDepth( 8 + sps_bitdepth_minus8 );
1733
80
  sps->setQpBDOffset( 6 * sps_bitdepth_minus8 );
1734
80
  const int BitDepth = 8 + sps_bitdepth_minus8;
1735
80
  const int QpBdOffset = 6 * sps_bitdepth_minus8;
1736
1737
80
  X_READ_FLAG( sps_entropy_coding_sync_enabled_flag );
1738
80
  sps->setEntropyCodingSyncEnabledFlag( sps_entropy_coding_sync_enabled_flag );
1739
1740
80
  X_READ_FLAG( sps_entry_point_offsets_present_flag );
1741
80
  sps->setEntryPointsPresentFlag( sps_entry_point_offsets_present_flag );
1742
1743
80
  X_READ_CODE( sps_log2_max_pic_order_cnt_lsb_minus4, 4, 0, 12 );
1744
80
  sps->setBitsForPOC( sps_log2_max_pic_order_cnt_lsb_minus4 + 4 );
1745
1746
80
  X_READ_FLAG( sps_poc_msb_cycle_flag );
1747
80
  sps->setPocMsbFlag( sps_poc_msb_cycle_flag );
1748
1749
80
  if( sps_poc_msb_cycle_flag )
1750
16
  {
1751
16
    X_READ_UVLC( sps_poc_msb_cycle_len_minus1, 0, 32 - sps_log2_max_pic_order_cnt_lsb_minus4 - 5 );
1752
16
    sps->setPocMsbLen( sps_poc_msb_cycle_len_minus1 + 1 );
1753
16
  }
1754
1755
  // extra bits are for future extensions, we will read, but ignore them,
1756
  // unless a meaning is specified in the spec
1757
80
  X_READ_CODE( sps_num_extra_ph_bytes, 2, 0, 2 );
1758
80
  sps->setNumExtraPHBitsBytes( sps_num_extra_ph_bytes );
1759
80
  if( sps_num_extra_ph_bytes )
1760
16
  {
1761
16
    parseExtraPHBitsStruct( sps, sps_num_extra_ph_bytes );
1762
16
  }
1763
1764
80
  X_READ_CODE( sps_num_extra_sh_bytes, 2, 0, 2 );
1765
80
  sps->setNumExtraSHBitsBytes( sps_num_extra_sh_bytes );
1766
80
  if( sps_num_extra_sh_bytes )
1767
16
  {
1768
16
    parseExtraSHBitsStruct( sps, sps_num_extra_sh_bytes );
1769
16
  }
1770
1771
80
  if( sps_ptl_dpb_hrd_params_present_flag )
1772
6
  {
1773
6
    if( sps_max_sublayers_minus1 > 0 )
1774
6
    {
1775
6
      X_READ_FLAG( sps_sublayer_dpb_params_flag );
1776
6
      sps->setSubLayerDpbParamsFlag( sps_sublayer_dpb_params_flag );
1777
6
    }
1778
6
    dpb_parameters( sps_max_sublayers_minus1, sps->getSubLayerDpbParamsFlag(), sps );
1779
6
  }
1780
1781
80
  X_READ_UVLC( sps_log2_min_luma_coding_block_size_minus2, 0, std::min( 4u, sps_log2_ctu_size_minus5 + 3 ) );
1782
80
  sps->setLog2MinCodingBlockSize( sps_log2_min_luma_coding_block_size_minus2 + 2 );
1783
1784
80
  const int MinCbLog2SizeY = sps_log2_min_luma_coding_block_size_minus2 + 2;
1785
80
  const int MinCbSizeY     = 1 << MinCbLog2SizeY;
1786
80
  const int VSize          = std::min( 64, CtbSizeY );
1787
80
  CHECK( MinCbSizeY > VSize, "The value of MinCbSizeY shall be less than or equal to VSize." )
1788
80
  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
80
  CHECK( sps_pic_width_max_in_luma_samples == 0 || sps_pic_width_max_in_luma_samples & ( std::max( 8, MinCbSizeY ) - 1 ),
1792
80
         "sps_pic_width_max_in_luma_samples shall not be equal to 0 and shall be an integer multiple of Max( 8, MinCbSizeY )" );
1793
68
  CHECK( sps_pic_height_max_in_luma_samples == 0 || sps_pic_height_max_in_luma_samples & ( std::max( 8, MinCbSizeY ) - 1 ),
1794
68
         "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
66
  const int minCuSize = 1 << sps->getLog2MinCodingBlockSize();
1797
66
  CHECK( ( sps->getMaxPicWidthInLumaSamples() % ( std::max( 8, minCuSize ) ) ) != 0, "Coded frame width must be a multiple of Max(8, the minimum unit size)" );
1798
66
  CHECK( ( sps->getMaxPicHeightInLumaSamples() % ( std::max( 8, minCuSize ) ) ) != 0, "Coded frame height must be a multiple of Max(8, the minimum unit size)" );
1799
1800
66
  X_READ_FLAG( sps_partition_constraints_override_enabled_flag );
1801
66
  sps->setSplitConsOverrideEnabledFlag( sps_partition_constraints_override_enabled_flag );
1802
1803
66
  X_READ_UVLC( sps_log2_diff_min_qt_min_cb_intra_slice_luma, 0, std::min( 6, CtbLog2SizeY ) - MinCbLog2SizeY );
1804
66
  const unsigned MinQtLog2SizeIntraY = sps_log2_diff_min_qt_min_cb_intra_slice_luma + MinCbLog2SizeY;
1805
1806
66
  X_READ_UVLC( sps_max_mtt_hierarchy_depth_intra_slice_luma, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) );
1807
1808
66
  PartitionConstraints minQT     = { 1u << MinQtLog2SizeIntraY, 0, 0 };
1809
66
  PartitionConstraints maxBTD    = { sps_max_mtt_hierarchy_depth_intra_slice_luma, 0, 0 };
1810
66
  PartitionConstraints maxTTSize = { 1u << MinQtLog2SizeIntraY, 0, 0 };
1811
66
  PartitionConstraints maxBTSize = { 1u << MinQtLog2SizeIntraY, 0, 0 };
1812
1813
66
  int spsLog2DiffMinQtMinCbIntraSliceLuma = 0;
1814
66
  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
66
  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
66
  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
66
  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
66
  X_READ_UVLC( sps_log2_diff_min_qt_min_cb_inter_slice, 0, std::min( 6, CtbLog2SizeY ) - MinCbLog2SizeY );
1863
66
  const int MinQtLog2SizeInterY = sps_log2_diff_min_qt_min_cb_inter_slice + MinCbLog2SizeY;
1864
1865
66
  X_READ_UVLC( sps_max_mtt_hierarchy_depth_inter_slice, 0, 2 * ( CtbLog2SizeY - MinCbLog2SizeY ) );
1866
66
  maxBTD[1] = sps_max_mtt_hierarchy_depth_inter_slice;
1867
1868
66
  minQT[1] = 1 << MinQtLog2SizeInterY;
1869
66
  maxTTSize[1] = maxBTSize[1] = minQT[1];
1870
66
  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
66
  sps->setMinQTSizes( minQT );
1880
66
  sps->setMaxMTTHierarchyDepths( maxBTD );
1881
66
  sps->setMaxBTSizes( maxBTSize );
1882
66
  sps->setMaxTTSizes( maxTTSize );
1883
1884
66
  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
66
  else
1890
66
  {
1891
66
    sps->setLog2MaxTbSize( 5 );
1892
66
  }
1893
1894
66
  X_READ_FLAG( sps_transform_skip_enabled_flag );
1895
66
  sps->setTransformSkipEnabledFlag( sps_transform_skip_enabled_flag );
1896
1897
66
  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
66
  X_READ_FLAG( sps_mts_enabled_flag );
1907
66
  sps->setUseMTS( sps_mts_enabled_flag );
1908
1909
66
  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
66
  X_READ_FLAG( sps_lfnst_enabled_flag );
1919
66
  sps->setUseLFNST( sps_lfnst_enabled_flag );
1920
1921
66
  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, (unsigned) ( 36 - sps_qp_table_start_minus26 ) ); // cast after subtraction to prevent conversion of sps_qp_table_start_minus26 to unsigned
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
66
  X_READ_FLAG( sps_sao_enabled_flag );
1961
66
  sps->setUseSAO( sps_sao_enabled_flag );
1962
1963
66
  X_READ_FLAG( sps_alf_enabled_flag );
1964
66
  sps->setUseALF( sps_alf_enabled_flag );
1965
1966
66
  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
66
  else
1972
66
  {
1973
66
    sps->setUseCCALF( false );
1974
66
  }
1975
1976
66
  X_READ_FLAG( sps_lmcs_enable_flag );
1977
66
  sps->setUseReshaper( sps_lmcs_enable_flag );
1978
1979
66
  X_READ_FLAG( sps_weighted_pred_flag );
1980
66
  sps->setUseWP( sps_weighted_pred_flag );
1981
1982
66
  X_READ_FLAG( sps_weighted_bipred_flag );
1983
66
  sps->setUseWPBiPred( sps_weighted_bipred_flag );
1984
1985
66
  X_READ_FLAG( sps_long_term_ref_pics_flag );
1986
66
  sps->setLongTermRefsPresent( sps_long_term_ref_pics_flag );
1987
1988
66
  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
66
  X_READ_FLAG( sps_idr_rpl_present_flag );
1998
66
  CHECK_CONSTRAINT( gci->getNoIdrRplConstraintFlag() && sps_idr_rpl_present_flag,
1999
66
                    "When gci_no_idr_rpl_constraint_flag equal to 1, the value of sps_idr_rpl_present_flag shall be equal to 0" );
2000
66
  sps->setIDRRefParamListPresent( sps_idr_rpl_present_flag );
2001
2002
66
  X_READ_FLAG( sps_rpl1_same_as_rpl0_flag );
2003
66
  sps->setRPL1CopyFromRPL0Flag( sps_rpl1_same_as_rpl0_flag );
2004
2005
66
  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
66
  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
66
  X_READ_FLAG( sps_ref_wraparound_enabled_flag );
2028
66
  sps->setUseWrapAround( sps_ref_wraparound_enabled_flag );
2029
66
  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
66
  X_READ_FLAG( sps_temporal_mvp_enabled_flag );
2039
66
  sps->setSPSTemporalMVPEnabledFlag( sps_temporal_mvp_enabled_flag );
2040
2041
66
  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
66
  X_READ_FLAG( sps_amvr_enabled_flag );
2048
66
  sps->setAMVREnabledFlag( sps_amvr_enabled_flag );
2049
2050
66
  X_READ_FLAG( sps_bdof_enabled_flag );
2051
66
  sps->setUseBIO( sps_bdof_enabled_flag );
2052
2053
66
  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
66
  X_READ_FLAG( sps_smvd_enabled_flag );
2060
66
  sps->setUseSMVD( sps_smvd_enabled_flag );
2061
2062
66
  X_READ_FLAG( sps_dmvr_enabled_flag );
2063
66
  sps->setUseDMVR( sps_dmvr_enabled_flag );
2064
2065
66
  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
66
  X_READ_FLAG( sps_mmvd_enabled_flag );
2072
66
  sps->setUseMMVD( sps_mmvd_enabled_flag );
2073
2074
66
  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
66
  X_READ_UVLC( sps_six_minus_max_num_merge_cand, 0, 5 );
2081
66
  const unsigned MaxNumMergeCand = MRG_MAX_NUM_CANDS - sps_six_minus_max_num_merge_cand;
2082
66
  sps->setMaxNumMergeCand( MaxNumMergeCand );
2083
2084
66
  X_READ_FLAG( sps_sbt_enabled_flag );
2085
66
  sps->setUseSBT( sps_sbt_enabled_flag );
2086
2087
66
  X_READ_FLAG( sps_affine_enabled_flag );
2088
66
  sps->setUseAffine( sps_affine_enabled_flag );
2089
2090
66
  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
66
  X_READ_FLAG( sps_bcw_enabled_flag );
2115
66
  sps->setUseBcw( sps_bcw_enabled_flag );
2116
2117
66
  X_READ_FLAG( sps_ciip_enabled_flag );
2118
66
  sps->setUseCiip( sps_ciip_enabled_flag );
2119
2120
66
  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
66
  X_READ_UVLC( sps_log2_parallel_merge_level_minus2, 0, CtbLog2SizeY - 2 );
2137
66
  sps->setLog2ParallelMergeLevelMinus2( sps_log2_parallel_merge_level_minus2 );
2138
2139
66
  X_READ_FLAG( sps_isp_enabled_flag );
2140
66
  sps->setUseISP( sps_isp_enabled_flag );
2141
2142
66
  X_READ_FLAG( sps_mrl_enabled_flag );
2143
66
  sps->setUseMRL( sps_mrl_enabled_flag );
2144
2145
66
  X_READ_FLAG( sps_mip_enabled_flag );
2146
66
  sps->setUseMIP( sps_mip_enabled_flag );
2147
2148
66
  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
66
  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
66
  X_READ_FLAG( sps_palette_enabled_flag );
2164
66
  CHECK( sps_palette_enabled_flag, "palette mode is not yet supported" );
2165
2166
66
  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
66
  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
66
  X_READ_FLAG( sps_ibc_enabled_flag );
2179
66
  sps->setIBCFlag( sps_ibc_enabled_flag );
2180
2181
66
  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
66
#  if LUMA_ADAPTIVE_DEBLOCKING_FILTER_QP_OFFSET
2188
66
  X_READ_FLAG( sps_ladf_enabled_flag );
2189
66
  sps->setLadfEnabled( sps_ladf_enabled_flag );
2190
2191
66
  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
66
#endif
2209
2210
66
  X_READ_FLAG( sps_explicit_scaling_list_enabled_flag );
2211
66
  CHECK_CONSTRAINT( gci->getNoExplicitScaleListConstraintFlag() && sps_explicit_scaling_list_enabled_flag,
2212
66
                    "When gci_no_explicit_scaling_list_constraint_flag is equal to 1, sps_explicit_scaling_list_enabled_flag shall be equal to 0" );
2213
66
  sps->setScalingListFlag( sps_explicit_scaling_list_enabled_flag );
2214
2215
66
  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
66
  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
66
  X_READ_FLAG( sps_dep_quant_enabled_flag );
2234
66
  sps->setDepQuantEnabledFlag( sps_dep_quant_enabled_flag );
2235
2236
66
  X_READ_FLAG( sps_sign_data_hiding_enabled_flag );
2237
66
  sps->setSignDataHidingEnabledFlag( sps_sign_data_hiding_enabled_flag );
2238
2239
66
  X_READ_FLAG( sps_virtual_boundaries_enabled_flag );
2240
66
  CHECK_CONSTRAINT( gci->getNoVirtualBoundaryConstraintFlag() && sps_virtual_boundaries_enabled_flag,
2241
66
                    "When gci_no_virtual_boundaries_constraint_flag is equal to 1, sps_virtual_boundaries_enabled_flag shall be equal to 0" );
2242
66
  sps->setVirtualBoundariesEnabledFlag( sps_virtual_boundaries_enabled_flag );
2243
2244
66
  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
66
  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
66
  X_READ_FLAG( sps_field_seq_flag );
2291
66
  sps->setFieldSeqFlag( sps_field_seq_flag );
2292
2293
66
  CHECK_CONSTRAINT( sps->getProfileTierLevel()->getFrameOnlyConstraintFlag() && sps_field_seq_flag,
2294
66
                     "When ptl_frame_only_constraint_flag equal to 1 , the value of sps_field_seq_flag shall be equal to 0" );
2295
2296
66
  X_READ_FLAG( sps_vui_parameters_present_flag );
2297
66
  sps->setVuiParametersPresentFlag( sps_vui_parameters_present_flag );
2298
2299
66
  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
66
  X_READ_FLAG( sps_extension_present_flag );
2314
66
  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
66
  xReadRbspTrailingBits();
2324
66
}
2325
2326
void HLSyntaxReader::parseDCI( DCI* dci )
2327
24
{
2328
#if ENABLE_TRACING
2329
  xTraceDCIHeader();
2330
#endif
2331
24
  X_READ_CODE_NO_RANGE( dci_reserved_zero_4bits, 4 );
2332
24
  (void) dci_reserved_zero_4bits;
2333
2334
24
  X_READ_CODE( dci_num_ptls_minus1, 4, 0, 15 );
2335
24
  CHECK_WARN( dci_num_ptls_minus1 == 15, "reserved dci_num_ptls_minus1==15 used" );
2336
24
  const int numPTLs = dci_num_ptls_minus1 + 1;
2337
2338
24
  std::vector<ProfileTierLevel> ptls( numPTLs );
2339
62
  for( int i = 0; i < numPTLs; i++ )
2340
38
  {
2341
38
    parseProfileTierLevel( &ptls[i], true, 0 );
2342
38
  }
2343
24
  dci->setProfileTierLevel( std::move( ptls ) );
2344
2345
24
  X_READ_FLAG(dci_extension_flag );
2346
24
  if( dci_extension_flag )
2347
6
  {
2348
832
    while( xMoreRbspData() )
2349
826
    {
2350
826
      X_READ_FLAG( dci_extension_data_flag );
2351
826
      (void) dci_extension_data_flag;
2352
826
    }
2353
6
  }
2354
24
  xReadRbspTrailingBits();
2355
24
}
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
6
{
2704
#if ENABLE_TRACING
2705
  xTracePictureHeader();
2706
#endif
2707
2708
6
  X_READ_FLAG( ph_gdr_or_irap_pic_flag );
2709
6
  picHeader->setGdrOrIrapPicFlag( ph_gdr_or_irap_pic_flag );
2710
2711
6
  X_READ_FLAG( ph_non_ref_pic_flag );
2712
6
  picHeader->setNonReferencePictureFlag( ph_non_ref_pic_flag );
2713
2714
6
  if( picHeader->getGdrOrIrapPicFlag() )
2715
2
  {
2716
2
    X_READ_FLAG( ph_gdr_pic_flag );
2717
2
    picHeader->setGdrPicFlag( ph_gdr_pic_flag );
2718
2
  }
2719
2720
6
  X_READ_FLAG( ph_inter_slice_allowed_flag );
2721
6
  picHeader->setPicInterSliceAllowedFlag( ph_inter_slice_allowed_flag );
2722
2723
6
  if( ph_inter_slice_allowed_flag )
2724
2
  {
2725
2
    X_READ_FLAG( ph_intra_slice_allowed_flag );
2726
2
    picHeader->setPicIntraSliceAllowedFlag( ph_intra_slice_allowed_flag );
2727
2
  }
2728
6
  CHECK( picHeader->getPicInterSliceAllowedFlag() == 0 && picHeader->getPicIntraSliceAllowedFlag() == 0,
2729
6
                     "Invalid picture without intra or inter slice" );
2730
2731
  // parameter sets
2732
6
  X_READ_UVLC( ph_pic_parameter_set_id, 0, 63 );
2733
6
  picHeader->setPPSId( ph_pic_parameter_set_id );
2734
2735
6
  const PPS* pps = parameterSetManager->getPPS( picHeader->getPPSId() );
2736
6
  CHECK( !pps, "Invalid PPS" );
2737
2738
6
  picHeader->setSPSId( pps->getSPSId() );
2739
6
  const SPS* sps = parameterSetManager->getSPS( picHeader->getSPSId() );
2740
6
  CHECK( !sps, "Invalid SPS" );
2741
2742
6
  const unsigned CtbSizeY          = sps->getCTUSize();
2743
6
  const unsigned CtbLog2SizeY      = getLog2( CtbSizeY );
2744
6
  const unsigned MinCbLog2SizeY    = sps->getLog2MinCodingBlockSize();
2745
6
  const unsigned MaxPicOrderCntLsb = 1 << sps->getBitsForPOC();
2746
2747
6
  X_READ_CODE_NO_RANGE( ph_pic_order_cnt_lsb, sps->getBitsForPOC() );
2748
6
  picHeader->setPocLsb( ph_pic_order_cnt_lsb );
2749
2750
6
  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
6
  else
2756
6
  {
2757
6
    picHeader->setRecoveryPocCnt( -1 );
2758
6
  }
2759
2760
6
  const std::vector<bool>& phExtraBitsPresent = sps->getExtraPHBitPresentFlags();
2761
6
  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
6
  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
6
  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
6
  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
6
  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
6
  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
6
  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
6
  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
6
  if( pps->getRplInfoInPhFlag() )
2995
0
  {
2996
0
    parsePicOrSliceHeaderRPL( picHeader, sps, pps );
2997
0
  }
2998
2999
  // partitioning constraint overrides
3000
6
  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
6
  PartitionConstraints minQT     = sps->getMinQTSizes();
3008
6
  PartitionConstraints maxBTD    = sps->getMaxMTTHierarchyDepths();
3009
6
  PartitionConstraints maxBTSize = sps->getMaxBTSizes();
3010
6
  PartitionConstraints maxTTSize = sps->getMaxTTSizes();
3011
3012
6
  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
6
  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
6
  picHeader->setMinQTSizes( minQT );
3240
6
  picHeader->setMaxMTTHierarchyDepths( maxBTD );
3241
6
  picHeader->setMaxBTSizes( maxBTSize );
3242
6
  picHeader->setMaxTTSizes( maxTTSize );
3243
3244
  // ibc merge candidate list size
3245
6
  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
6
  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
6
  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
6
  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
6
  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
6
  else // ( pps->getPPSDeblockingFilterDisabledFlag() == 0 || picHeader->getDeblockingFilterOverrideFlag() == 0 )
3288
6
  {
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
6
    picHeader->setDeblockingFilterDisable( pps->getPPSDeblockingFilterDisabledFlag() );
3292
6
  }
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
6
  picHeader->setDeblockingFilterBetaOffsetDiv2( pps->getDeblockingFilterBetaOffsetDiv2() );
3297
6
  picHeader->setDeblockingFilterTcOffsetDiv2( pps->getDeblockingFilterTcOffsetDiv2() );
3298
3299
6
  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
6
  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
6
  else
3333
6
  {
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
6
    picHeader->setDeblockingFilterCbBetaOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCbBetaOffsetDiv2()
3340
6
                                                                                : picHeader->getDeblockingFilterBetaOffsetDiv2() );
3341
6
    picHeader->setDeblockingFilterCbTcOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCbTcOffsetDiv2()
3342
6
                                                                              : 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
6
    picHeader->setDeblockingFilterCrBetaOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCrBetaOffsetDiv2()
3350
6
                                                                                : picHeader->getDeblockingFilterBetaOffsetDiv2() );
3351
6
    picHeader->setDeblockingFilterCrTcOffsetDiv2( pps->getPPSChromaToolFlag() ? pps->getDeblockingFilterCrTcOffsetDiv2()
3352
6
                                                                              : picHeader->getDeblockingFilterTcOffsetDiv2() );
3353
6
  }
3354
3355
  // picture header extension
3356
6
  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
6
  if( readRbspTrailingBits )
3367
0
  {
3368
0
    xReadRbspTrailingBits();
3369
0
  }
3370
6
  picHeader->setValid();
3371
6
}
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
18
{
3452
#if ENABLE_TRACING
3453
  xTraceSliceHeader();
3454
#endif
3455
3456
18
  X_READ_FLAG( sh_picture_header_in_slice_header_flag );
3457
18
  pcSlice->setPictureHeaderInSliceHeader( sh_picture_header_in_slice_header_flag );
3458
3459
18
  if( sh_picture_header_in_slice_header_flag )
3460
2
  {
3461
2
    picHeader.reset( new PicHeader );
3462
2
    parsePictureHeader( picHeader.get(), parameterSetManager, false );
3463
2
  }
3464
18
  CHECK( !picHeader, "Picture Header not allocated" );   // should always be allocated, even if it is not valid
3465
4
  CHECK( !picHeader->isValid(), "Picture Header missing" );
3466
3467
4
  checkAlfNaluTidAndPicTid( pcSlice, picHeader.get(), parameterSetManager );
3468
3469
4
  const PPS* pps = parameterSetManager->getPPS( picHeader->getPPSId() );
3470
4
  CHECK( pps == 0, "Invalid PPS" );
3471
4
  const SPS* sps = parameterSetManager->getSPS( pps->getSPSId() );
3472
4
  CHECK( sps == 0, "Invalid SPS" );
3473
3474
4
  auto gci = sps->getProfileTierLevel()->getConstraintInfo();
3475
4
  CHECK_CONSTRAINT( gci->getPicHeaderInSliceHeaderConstraintFlag() && !sh_picture_header_in_slice_header_flag,
3476
4
                    "PH shall be present in SH, when pic_header_in_slice_header_constraint_flag is equal to 1" );
3477
3478
4
  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
4
  CHECK( sps->getSubPicInfoPresentFlag() == 1 && sps->getVirtualBoundariesEnabledFlag() == 1 && sps->getVirtualBoundariesPresentFlag() == 0,
3491
4
                     "when sps_subpic_info_present_flag is equal to 1 and sps_virtual_boundaries_enabled_flag is equal to 1, "
3492
4
                     "sps_virtual_boundaries_present_flag shall be equal 1" );
3493
3494
3495
4
  const bool bChroma = sps->getChromaFormatIdc() != CHROMA_400;
3496
3497
  // picture order count
3498
4
  const int iPOClsb    = picHeader->getPocLsb();
3499
4
  const int iMaxPOClsb = 1 << sps->getBitsForPOC();
3500
4
  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
4
  else
3514
4
  {
3515
4
    const int iPrevPOC    = prevTid0POC;
3516
4
    const int iPrevPOClsb = iPrevPOC & ( iMaxPOClsb - 1 );
3517
4
    const int iPrevPOCmsb = iPrevPOC - iPrevPOClsb;
3518
4
    int       iPOCmsb;
3519
4
    if( picHeader->getPocMsbPresentFlag() )
3520
0
    {
3521
0
      iPOCmsb = picHeader->getPocMsbVal() * iMaxPOClsb;
3522
0
    }
3523
4
    else
3524
4
    {
3525
4
      if( ( iPOClsb < iPrevPOClsb ) && ( ( iPrevPOClsb - iPOClsb ) >= ( iMaxPOClsb / 2 ) ) )
3526
0
      {
3527
0
        iPOCmsb = iPrevPOCmsb + iMaxPOClsb;
3528
0
      }
3529
4
      else if( ( iPOClsb > iPrevPOClsb ) && ( ( iPOClsb - iPrevPOClsb ) > ( iMaxPOClsb / 2 ) ) )
3530
0
      {
3531
0
        iPOCmsb = iPrevPOCmsb - iMaxPOClsb;
3532
0
      }
3533
4
      else
3534
4
      {
3535
4
        iPOCmsb = iPrevPOCmsb;
3536
4
      }
3537
4
    }
3538
4
    pcSlice->setPOC( iPOCmsb + iPOClsb );
3539
4
  }
3540
3541
4
  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
4
  const unsigned NumTilesInPic = pps->getNumTiles();
3548
3549
4
  uint32_t sliceAddr = 0;
3550
4
  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
4
  else   // rectangular slices
3561
4
  {
3562
    // slice address is the index of the slice within the current sub-picture
3563
4
    const uint32_t currSubPicIdx         = pps->getSubPicIdxFromSubPicId( pcSlice->getSliceSubPicId() );
3564
4
    const SubPic&  currSubPic            = pps->getSubPic( currSubPicIdx );
3565
4
    const unsigned NumSlicesInCurrSubpic = currSubPic.getNumSlicesInSubPic();
3566
4
    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
4
  }
3573
3574
4
  const std::vector<bool>& shExtraBitsPresent = sps->getExtraSHBitPresentFlags();
3575
4
  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
4
  uint32_t numTilesInSlice = 1;
3586
4
  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
4
  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
4
  else
3614
4
  {
3615
4
    uint32_t       picLevelSliceIdx = sliceAddr;
3616
4
    const uint32_t currSubPicIdx    = pps->getSubPicIdxFromSubPicId( pcSlice->getSliceSubPicId() );
3617
4
    for( int subpic = 0; subpic < currSubPicIdx; subpic++ )
3618
0
    {
3619
0
      picLevelSliceIdx += pps->getSubPic( subpic ).getNumSlicesInSubPic();
3620
0
    }
3621
4
    pcSlice->setSliceMap( pps->getSliceMap( picLevelSliceIdx ) );
3622
4
    pcSlice->setSliceID( picLevelSliceIdx );
3623
4
  }
3624
3625
4
  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
4
  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
4
  else
3638
4
  {
3639
4
    pcSlice->setSliceType( I_SLICE );
3640
4
  }
3641
3642
4
  CHECK( !picHeader->getPicIntraSliceAllowedFlag() && pcSlice->getSliceType() != B_SLICE && pcSlice->getSliceType() != P_SLICE,
3643
4
                     "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
4
  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
4
  pcSlice->inheritFromPicHeader( picHeader.get(), pps, sps );
3657
3658
4
  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
4
  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
4
  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
4
  if( pps->getRplInfoInPhFlag() )
3751
0
  {
3752
    // inheritFromPicHeader() already called
3753
0
  }
3754
4
  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
4
  else
3760
4
  {
3761
4
    parsePicOrSliceHeaderRPL( pcSlice, sps, pps );
3762
4
  }
3763
3764
4
  bool     numRefIdxActiveOverrideFlag = true;
3765
4
  unsigned numRefIdxActiveMinus1[2]    = { 0, 0 };
3766
4
  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
4
  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
4
  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
4
  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
4
  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
4
  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
4
  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
4
  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
4
  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
4
  pcSlice->setDeblockingFilterDisable( pps->getPPSDeblockingFilterDisabledFlag() && pcSlice->getDeblockingFilterOverrideFlag()
3921
4
                                       ? 0 : picHeader->getDeblockingFilterDisable() );
3922
3923
4
  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
4
  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
4
  else
3955
4
  {
3956
4
    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
4
    else
3969
4
    {
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
4
      pcSlice->setDeblockingFilterCbBetaOffsetDiv2( pcSlice->getDeblockingFilterBetaOffsetDiv2() );
3976
4
      pcSlice->setDeblockingFilterCbTcOffsetDiv2  ( pcSlice->getDeblockingFilterTcOffsetDiv2()   );
3977
4
      pcSlice->setDeblockingFilterCrBetaOffsetDiv2( pcSlice->getDeblockingFilterBetaOffsetDiv2() );
3978
4
      pcSlice->setDeblockingFilterCrTcOffsetDiv2  ( pcSlice->getDeblockingFilterTcOffsetDiv2()   );
3979
4
    }
3980
4
  }
3981
3982
  // dependent quantization
3983
4
  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
4
  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
4
  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
4
  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
4
  std::vector<uint32_t> entryPointOffset;
4014
4
  pcSlice->setNumEntryPoints( sps, pps );
4015
4
  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
4
  m_pcBitstream->readByteAlignment();
4031
4
#endif
4032
4033
4034
4
  if( pcSlice->getFirstCtuRsAddrInSlice() == 0 )
4035
0
  {
4036
0
    pcSlice->setDefaultClpRng( *sps );
4037
0
  }
4038
4039
4
  pcSlice->clearSubstreamSizes();
4040
4041
4
  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
4
}
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
78
{
4177
78
  uint32_t symbol;
4178
78
  READ_FLAG( symbol, "gci_present_flag" );                                   cinfo->setGciPresentFlag( symbol ? true : false );
4179
78
  if( cinfo->getGciPresentFlag() )
4180
32
  {
4181
    /* general */
4182
32
    READ_FLAG( symbol, "gci_intra_only_constraint_flag" );                   cinfo->setIntraOnlyConstraintFlag( symbol ? true : false );
4183
32
    READ_FLAG( symbol, "gci_all_layers_independent_constraint_flag" );       cinfo->setAllLayersIndependentConstraintFlag( symbol ? true : false );
4184
32
    READ_FLAG( symbol, "gci_one_au_only_constraint_flag" );                  cinfo->setOnePictureOnlyConstraintFlag( symbol ? true : false );
4185
4186
    /* picture format */
4187
32
    READ_CODE( 4, symbol, "gci_sixteen_minus_max_bitdepth_constraint_idc" ); cinfo->setMaxBitDepthConstraintIdc( symbol>8 ? 16 : ( 16 - symbol ) );
4188
32
    CHECK(symbol>8, "gci_sixteen_minus_max_bitdepth_constraint_idc shall be in the range 0 to 8, inclusive");
4189
30
    READ_CODE( 2, symbol, "gci_three_minus_max_chroma_format_constraint_idc" );
4190
30
    cinfo->setMaxChromaFormatConstraintIdc( (ChromaFormat)( 3 - symbol ) );
4191
4192
    /* NAL unit type related */
4193
30
    READ_FLAG( symbol, "gci_no_mixed_nalu_types_in_pic_constraint_flag" );   cinfo->setNoMixedNaluTypesInPicConstraintFlag( symbol > 0 ? true : false );
4194
30
    READ_FLAG( symbol, "gci_no_trail_constraint_flag" );                     cinfo->setNoTrailConstraintFlag( symbol > 0 ? true : false );
4195
30
    READ_FLAG( symbol, "gci_no_stsa_constraint_flag" );                      cinfo->setNoStsaConstraintFlag( symbol > 0 ? true : false );
4196
30
    READ_FLAG( symbol, "gci_no_rasl_constraint_flag" );                      cinfo->setNoRaslConstraintFlag( symbol > 0 ? true : false );
4197
30
    READ_FLAG( symbol, "gci_no_radl_constraint_flag" );                      cinfo->setNoRadlConstraintFlag( symbol > 0 ? true : false );
4198
30
    READ_FLAG( symbol, "gci_no_idr_constraint_flag" );                       cinfo->setNoIdrConstraintFlag( symbol > 0 ? true : false );
4199
30
    READ_FLAG( symbol, "gci_no_cra_constraint_flag" );                       cinfo->setNoCraConstraintFlag( symbol > 0 ? true : false );
4200
30
    READ_FLAG( symbol, "gci_no_gdr_constraint_flag" );                       cinfo->setNoGdrConstraintFlag( symbol > 0 ? true : false );
4201
30
    READ_FLAG( symbol, "gci_no_aps_constraint_flag" );                       cinfo->setNoApsConstraintFlag( symbol > 0 ? true : false );
4202
30
    READ_FLAG( symbol, "gci_no_idr_rpl_constraint_flag" );                   cinfo->setNoIdrRplConstraintFlag( symbol > 0 ? true : false );
4203
4204
    /* tile, slice, subpicture partitioning */
4205
30
    READ_FLAG( symbol, "gci_one_tile_per_pic_constraint_flag" );             cinfo->setOneTilePerPicConstraintFlag( symbol > 0 ? true : false );
4206
30
    READ_FLAG( symbol, "gci_pic_header_in_slice_header_constraint_flag" );   cinfo->setPicHeaderInSliceHeaderConstraintFlag( symbol > 0 ? true : false );
4207
30
    READ_FLAG( symbol, "gci_one_slice_per_pic_constraint_flag" );            cinfo->setOneSlicePerPicConstraintFlag( symbol > 0 ? true : false );
4208
30
    READ_FLAG( symbol, "gci_no_rectangular_slice_constraint_flag" );         cinfo->setNoRectSliceConstraintFlag( symbol > 0 ? true : false );
4209
30
    READ_FLAG( symbol, "gci_one_slice_per_subpic_constraint_flag" );         cinfo->setOneSlicePerSubpicConstraintFlag( symbol > 0 ? true : false );
4210
30
    READ_FLAG( symbol, "gci_no_subpic_info_constraint_flag" );               cinfo->setNoSubpicInfoConstraintFlag( symbol > 0 ? true : false );
4211
4212
    /* CTU and block partitioning */
4213
30
    READ_CODE( 2, symbol, "gci_three_minus_max_log2_ctu_size_constraint_idc");   cinfo->setMaxLog2CtuSizeConstraintIdc( ( ( 3 - symbol ) + 5 ) );
4214
30
    READ_FLAG( symbol, "gci_no_partition_constraints_override_constraint_flag"); cinfo->setNoPartitionConstraintsOverrideConstraintFlag( symbol > 0 ? true : false );
4215
30
    READ_FLAG( symbol, "gci_no_mtt_constraint_flag");                            cinfo->setNoMttConstraintFlag( symbol > 0 ? true : false);
4216
30
    READ_FLAG( symbol, "gci_no_qtbtt_dual_tree_intra_constraint_flag");          cinfo->setNoQtbttDualTreeIntraConstraintFlag( symbol > 0 ? true : false );
4217
4218
    /* intra */
4219
30
    READ_FLAG( symbol, "gci_no_palette_constraint_flag" );                   cinfo->setNoPaletteConstraintFlag( symbol > 0 ? true : false );
4220
30
    READ_FLAG( symbol, "gci_no_ibc_constraint_flag" );                       cinfo->setNoIbcConstraintFlag( symbol > 0 ? true : false );
4221
30
    READ_FLAG( symbol, "gci_no_isp_constraint_flag" );                       cinfo->setNoIspConstraintFlag( symbol > 0 ? true : false );
4222
30
    READ_FLAG( symbol, "gci_no_mrl_constraint_flag" );                       cinfo->setNoMrlConstraintFlag( symbol > 0 ? true : false );
4223
30
    READ_FLAG( symbol, "gci_no_mip_constraint_flag" );                       cinfo->setNoMipConstraintFlag( symbol > 0 ? true : false );
4224
30
    READ_FLAG( symbol, "gci_no_cclm_constraint_flag" );                      cinfo->setNoCclmConstraintFlag( symbol > 0 ? true : false );
4225
4226
    /* inter */
4227
30
    READ_FLAG( symbol, "gci_no_ref_pic_resampling_constraint_flag" );        cinfo->setNoRprConstraintFlag( symbol > 0 ? true : false );
4228
30
    READ_FLAG( symbol, "gci_no_res_change_in_clvs_constraint_flag" );        cinfo->setNoResChangeInClvsConstraintFlag( symbol > 0 ? true : false );
4229
30
    READ_FLAG( symbol, "gci_no_weighted_prediction_constraint_flag" );       cinfo->setNoWeightedPredictionConstraintFlag( symbol > 0 ? true : false );
4230
30
    READ_FLAG( symbol, "gci_no_ref_wraparound_constraint_flag" );            cinfo->setNoRefWraparoundConstraintFlag( symbol > 0 ? true : false );
4231
30
    READ_FLAG( symbol, "gci_no_temporal_mvp_constraint_flag" );              cinfo->setNoTemporalMvpConstraintFlag( symbol > 0 ? true : false );
4232
30
    READ_FLAG( symbol, "gci_no_sbtmvp_constraint_flag" );                    cinfo->setNoSbtmvpConstraintFlag( symbol > 0 ? true : false );
4233
30
    READ_FLAG( symbol, "gci_no_amvr_constraint_flag" );                      cinfo->setNoAmvrConstraintFlag( symbol > 0 ? true : false );
4234
30
    READ_FLAG( symbol, "gci_no_bdof_constraint_flag" );                      cinfo->setNoBdofConstraintFlag( symbol > 0 ? true : false );
4235
30
    READ_FLAG( symbol, "gci_no_smvd_constraint_flag" );                      cinfo->setNoSmvdConstraintFlag( symbol > 0 ? true : false );
4236
30
    READ_FLAG( symbol, "gci_no_dmvr_constraint_flag" );                      cinfo->setNoDmvrConstraintFlag( symbol > 0 ? true : false );
4237
30
    READ_FLAG( symbol, "gci_no_mmvd_constraint_flag" );                      cinfo->setNoMmvdConstraintFlag( symbol > 0 ? true : false );
4238
30
    READ_FLAG( symbol, "gci_no_affine_motion_constraint_flag" );             cinfo->setNoAffineMotionConstraintFlag( symbol > 0 ? true : false );
4239
30
    READ_FLAG( symbol, "gci_no_prof_constraint_flag" );                      cinfo->setNoProfConstraintFlag( symbol > 0 ? true : false );
4240
30
    READ_FLAG( symbol, "gci_no_bcw_constraint_flag" );                       cinfo->setNoBcwConstraintFlag( symbol > 0 ? true : false  );
4241
30
    READ_FLAG( symbol, "gci_no_ciip_constraint_flag" );                      cinfo->setNoCiipConstraintFlag( symbol > 0 ? true : false );
4242
30
    READ_FLAG( symbol, "gci_no_gpm_constraint_flag" );                       cinfo->setNoGeoConstraintFlag( symbol > 0 ? true : false );
4243
4244
    /* transform, quantization, residual */
4245
30
    READ_FLAG( symbol, "gci_no_luma_transform_size_64_constraint_flag" );    cinfo->setNoLumaTransformSize64ConstraintFlag( symbol > 0 ? true : false );
4246
30
    READ_FLAG( symbol, "gci_no_transform_skip_constraint_flag" );            cinfo->setNoTransformSkipConstraintFlag( symbol > 0 ? true : false );
4247
30
    READ_FLAG( symbol, "gci_no_bdpcm_constraint_flag" );                     cinfo->setNoBDPCMConstraintFlag( symbol > 0 ? true : false );
4248
30
    READ_FLAG( symbol, "gci_no_mts_constraint_flag" );                       cinfo->setNoMtsConstraintFlag( symbol > 0 ? true : false );
4249
30
    READ_FLAG( symbol, "gci_no_lfnst_constraint_flag" );                     cinfo->setNoLfnstConstraintFlag( symbol > 0 ? true : false );
4250
30
    READ_FLAG( symbol, "gci_no_joint_cbcr_constraint_flag" );                cinfo->setNoJointCbCrConstraintFlag( symbol > 0 ? true : false );
4251
30
    READ_FLAG( symbol, "gci_no_sbt_constraint_flag" );                       cinfo->setNoSbtConstraintFlag( symbol > 0 ? true : false );
4252
30
    READ_FLAG( symbol, "gci_no_act_constraint_flag" );                       cinfo->setNoActConstraintFlag( symbol > 0 ? true : false );
4253
30
    READ_FLAG( symbol, "gci_no_explicit_scaling_list_constraint_flag" );     cinfo->setNoExplicitScaleListConstraintFlag( symbol > 0 ? true : false );
4254
30
    READ_FLAG( symbol, "gci_no_dep_quant_constraint_flag" );                 cinfo->setNoDepQuantConstraintFlag( symbol > 0 ? true : false );
4255
30
    READ_FLAG( symbol, "gci_no_sign_data_hiding_constraint_flag" );          cinfo->setNoSignDataHidingConstraintFlag( symbol > 0 ? true : false) ;
4256
30
    READ_FLAG( symbol, "gci_no_cu_qp_delta_constraint_flag" );               cinfo->setNoQpDeltaConstraintFlag( symbol > 0 ? true : false );
4257
30
    READ_FLAG( symbol, "gci_no_chroma_qp_offset_constraint_flag" );          cinfo->setNoChromaQpOffsetConstraintFlag( symbol > 0 ? true : false );
4258
4259
    /* loop filter */
4260
30
    READ_FLAG( symbol, "gci_no_sao_constraint_flag" );                       cinfo->setNoSaoConstraintFlag( symbol > 0 ? true : false );
4261
30
    READ_FLAG( symbol, "gci_no_alf_constraint_flag" );                       cinfo->setNoAlfConstraintFlag( symbol > 0 ? true : false );
4262
30
    READ_FLAG( symbol, "gci_no_ccalf_constraint_flag" );                     cinfo->setNoCCAlfConstraintFlag( symbol > 0 ? true : false );
4263
30
    READ_FLAG( symbol, "gci_no_lmcs_constraint_flag" );                      cinfo->setNoLmcsConstraintFlag( symbol > 0 ? true : false );
4264
30
    READ_FLAG( symbol, "gci_no_ladf_constraint_flag" );                      cinfo->setNoLadfConstraintFlag( symbol > 0 ? true : false );
4265
30
    READ_FLAG( symbol, "gci_no_virtual_boundaries_constraint_flag" );        cinfo->setNoVirtualBoundaryConstraintFlag( symbol > 0 ? true : false );
4266
4267
30
    READ_CODE( 8, symbol, "gci_num_reserved_bits" );
4268
30
    uint32_t const numReservedBits = symbol;
4269
50
    for (int i = 0; i < numReservedBits; i++)
4270
28
    {
4271
28
      READ_FLAG( symbol, "gci_reserved_zero_bit" );                          CHECK( symbol != 0, "gci_reserved_zero_bit not equal to zero" );
4272
20
    }
4273
30
  }
4274
340
  while( !isByteAligned() )
4275
280
  {
4276
280
    READ_FLAG( symbol, "gci_alignment_zero_bit" );                           CHECK( symbol != 0, "gci_alignment_zero_bit not equal to zero" );
4277
272
  }
4278
68
}
4279
4280
4281
void HLSyntaxReader::parseProfileTierLevel( ProfileTierLevel *ptl, bool profileTierPresentFlag, int maxNumSubLayersMinus1 )
4282
90
{
4283
90
  if( profileTierPresentFlag )
4284
90
  {
4285
90
    X_READ_CODE_NO_RANGE( general_profile_idc, 7 );
4286
90
    ptl->setProfileIdc( Profile::Name( general_profile_idc ) );
4287
4288
90
    X_READ_FLAG( general_tier_flag );
4289
90
    ptl->setTierFlag( general_tier_flag ? Tier::HIGH : Tier::MAIN );
4290
90
  }
4291
4292
90
  X_READ_CODE_NO_RANGE( general_level_idc, 8 );
4293
90
  ptl->setLevelIdc( vvdecLevel( general_level_idc ) );
4294
4295
90
  X_READ_FLAG( ptl_frame_only_constraint_flag );
4296
90
  ptl->setFrameOnlyConstraintFlag( ptl_frame_only_constraint_flag );
4297
4298
90
  X_READ_FLAG( ptl_multilayer_enabled_flag );
4299
90
  ptl->setMultiLayerEnabledFlag( ptl_multilayer_enabled_flag );
4300
4301
90
  CHECK( ( ptl->getProfileIdc() == Profile::MAIN_10 || ptl->getProfileIdc() == Profile::MAIN_10_444
4302
90
        || ptl->getProfileIdc() == Profile::MAIN_10_STILL_PICTURE
4303
90
        || ptl->getProfileIdc() == Profile::MAIN_10_444_STILL_PICTURE )
4304
90
          && ptl_multilayer_enabled_flag,
4305
90
        "ptl_multilayer_enabled_flag shall be equal to 0 for non-multilayer profiles");
4306
4307
86
  CHECK_UNSUPPORTED( ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10 || ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10_STILL_PICTURE ||
4308
86
         ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10_444 || ptl->getProfileIdc() == Profile::MULTILAYER_MAIN_10_444_STILL_PICTURE,
4309
86
         "Multilayer profiles not yet supported" );
4310
4311
80
  if( ptl->getProfileIdc() == Profile::MAIN_10_444 || ptl->getProfileIdc() == Profile::MAIN_10_444_STILL_PICTURE )
4312
2
  {
4313
2
    msg( WARNING, "Warning: MAIN_10_444 and MAIN_10_444_STILL_PICTURE is still experimental.\n" );
4314
2
  }
4315
4316
80
  if( profileTierPresentFlag )
4317
78
  {
4318
78
    parseConstraintInfo( ptl->getConstraintInfo() );
4319
78
  }
4320
4321
226
  for( int i = maxNumSubLayersMinus1 - 1; i >= 0; i-- )
4322
146
  {
4323
146
    X_READ_FLAG_idx( sub_layer_level_present_flag, "[i]" );
4324
146
    ptl->setSubLayerLevelPresentFlag( i, sub_layer_level_present_flag );
4325
146
  }
4326
4327
158
  while( !isByteAligned() )
4328
78
  {
4329
78
    X_READ_FLAG( ptl_reserved_zero_bit );
4330
78
    CHECK_WARN( ptl_reserved_zero_bit != 0, "ptl_reserved_zero_bit not equal to zero" );
4331
78
  }
4332
4333
80
  ptl->setSubLayerLevelIdc( maxNumSubLayersMinus1, ptl->getLevelIdc() );
4334
226
  for( int i = maxNumSubLayersMinus1 - 1; i >= 0; i-- )
4335
146
  {
4336
146
    if( ptl->getSubLayerLevelPresentFlag( i ) )
4337
26
    {
4338
26
      X_READ_CODE_NO_RANGE_idx( sub_layer_level_idc, "[i]", 8 );
4339
26
      ptl->setSubLayerLevelIdc( i, vvdecLevel( sub_layer_level_idc ) );
4340
26
    }
4341
120
    else
4342
120
    {
4343
120
      ptl->setSubLayerLevelIdc( i, ptl->getSubLayerLevelIdc( i + 1 ) );
4344
120
    }
4345
146
  }
4346
4347
80
  if( profileTierPresentFlag )
4348
52
  {
4349
52
    X_READ_CODE_NO_RANGE( ptl_num_sub_profiles, 8 );
4350
52
    ptl->setNumSubProfile( ptl_num_sub_profiles );
4351
4352
102
    for( int i = 0; i < ptl_num_sub_profiles; i++ )
4353
50
    {
4354
50
      X_READ_CODE_NO_RANGE_idx( general_sub_profile_idc, "[i]", 32 );
4355
50
      ptl->setSubProfileIdc( i, general_sub_profile_idc );
4356
50
    }
4357
52
  }
4358
80
}
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
46
{
4519
46
  scalingList->reset();
4520
4521
924
  for( int id = 0; id < 28; id++ )
4522
878
  {
4523
878
    if( aps_chromaPresentFlag || scalingList->isLumaScalingList( id ) )
4524
406
    {
4525
406
      X_READ_FLAG( scaling_list_copy_mode_flag );
4526
4527
406
      bool scalingListPredModeFlag = false;
4528
406
      if( !scaling_list_copy_mode_flag )
4529
60
      {
4530
60
        X_READ_FLAG( scaling_list_pred_mode_flag );
4531
60
        scalingListPredModeFlag = scaling_list_pred_mode_flag;
4532
60
      }
4533
4534
406
      int scalingListPredIdDelta = 0;
4535
406
      if( ( scaling_list_copy_mode_flag || scalingListPredModeFlag )
4536
370
          && id != SCALING_LIST_1D_START_2x2 && id != SCALING_LIST_1D_START_4x4
4537
326
          && id != SCALING_LIST_1D_START_8x8 )   // Copy Mode
4538
290
      {
4539
290
        const unsigned maxIdDelta = id < 2 ? id : ( id < 8 ? id - 2 : id - 8 );
4540
290
        X_READ_UVLC_idx( scaling_list_pred_id_delta, "[id]", 0, maxIdDelta );
4541
4542
290
        scalingListPredIdDelta = scaling_list_pred_id_delta;
4543
290
      }
4544
4545
406
      decodeScalingList( scalingList, id, scalingListPredIdDelta, scaling_list_copy_mode_flag, scalingListPredModeFlag );
4546
406
    }   // ( aps_chromaPresentFlag || scalingList->isLumaScalingList( id ) )
4547
878
  }
4548
4549
46
  return;
4550
46
}
4551
4552
void HLSyntaxReader::decodeScalingList( ScalingList* scalingList, uint32_t id, uint32_t scalingListPredIdDelta, bool scalingListCopyModeFlag , bool scalingListPredModeFlag)
4553
398
{
4554
398
  const unsigned matrixSize = ScalingList::matrixSize( id );
4555
4556
398
  const int refId = id - scalingListPredIdDelta;
4557
398
  CHECK( refId<0, "refId < 0 doesn't make sense" );
4558
4559
398
  int   scalingMatrixDcPred = 0;
4560
398
  auto& scalingMatrixPred   = scalingList->getScalingListVec( id );   // we use the same storage for scalingMatrixPred and scalingMatrixRec
4561
398
  {
4562
    // Derive scalingMatrixPred and scalingMatrixDcPred
4563
4564
398
    const size_t scalingMatrixPred_size = matrixSize * matrixSize;
4565
398
    CHECK( scalingMatrixPred_size != scalingList->getScalingListVec( id ).size(), "wrong scalingMatrixPred/Rec[] size" )
4566
4567
398
    if( scalingListCopyModeFlag == 0 && scalingListPredModeFlag == 0 )
4568
36
    {
4569
36
      scalingMatrixPred.assign( scalingMatrixPred_size, 8 );
4570
36
      scalingMatrixDcPred = 8;
4571
36
    }
4572
362
    else if( scalingListPredIdDelta == 0 )
4573
330
    {
4574
330
      scalingMatrixPred.assign( scalingMatrixPred_size, 16 );
4575
330
      scalingMatrixDcPred = 16;
4576
330
    }
4577
32
    else
4578
32
    {
4579
32
      CHECK( ( scalingListCopyModeFlag == 0 && scalingListPredModeFlag == 0 ) || scalingListPredIdDelta <= 0,
4580
32
             "wrong condition: Otherwise (either scaling_list_copy_mode_flag[ id ] or scaling_list_pred_mode_flag[ id ] is equal to 1 and"
4581
32
             " scaling_list_pred_id_delta[ id ] is greater than 0)," );
4582
4583
32
      CHECK( scalingListCopyModeFlag == 0 && ( scalingListPredModeFlag == 0 || scalingListPredIdDelta <= 0 ),
4584
32
             "wrong condition: Otherwise (either scaling_list_copy_mode_flag[ id ] or scaling_list_pred_mode_flag[ id ] is equal to 1 and"
4585
32
             " scaling_list_pred_id_delta[ id ] is greater than 0)," );
4586
4587
      // scalingMatrixPred is set equal to ScalingMatrixRec[ refId ]
4588
32
      scalingMatrixPred = scalingList->getScalingListVec( refId );
4589
4590
190
#define MINUS_14 -( 14 * 0 )   // TODO: where did the -14 from the standard go ? when it is there, it breaks decoding.
4591
4592
32
      scalingMatrixDcPred = refId > 13 ? scalingList->getScalingListDC( refId MINUS_14 ) : scalingList->getScalingListVec( id )[0];
4593
32
    }
4594
398
  }
4595
4596
398
  if( scalingListCopyModeFlag )
4597
340
  {
4598
    // When not present, the value of scaling_list_dc_coef[id − 14] is inferred to be equal to 0.
4599
340
    if( id >= 14 )
4600
142
    {
4601
142
      scalingList->setScalingListDC( id MINUS_14, scalingMatrixDcPred );
4602
142
    }
4603
340
    return;
4604
340
  }
4605
4606
58
  const auto& DiagScanOrder = g_scanOrder[SCAN_UNGROUPED];
4607
4608
58
  int nextCoef = 0;
4609
58
  if( id > 13 )
4610
28
  {
4611
28
    X_READ_SVLC_idx( scaling_list_dc_coef, "[id-14]", -128, 127 );
4612
28
    nextCoef += scaling_list_dc_coef;
4613
4614
28
    scalingList->setScalingListDC( id MINUS_14, ( scalingMatrixDcPred + scaling_list_dc_coef ) & 255 );
4615
28
    CHECK( scalingList->getScalingListDC( id MINUS_14 ) <= 0, "The value of ScalingMatrixDcRec[" << id MINUS_14 << "] shall be greater than 0." )
4616
28
  }
4617
4618
1.19k
  for( unsigned i = 0; i < matrixSize * matrixSize; i++ )
4619
1.14k
  {
4620
1.14k
    const int numBits = g_sizeIdxInfo.idxFrom( matrixSize );
4621
1.14k
    const int x       = DiagScanOrder[3][3][i] & ( ( 1 << numBits ) - 1 );
4622
1.14k
    const int y       = DiagScanOrder[3][3][i] >> numBits;
4623
4624
1.14k
    if( !( id > 25 && x >= 4 && y >= 4 ) )
4625
1.01k
    {
4626
1.01k
      X_READ_SVLC_idx( scaling_list_delta_coef, "[id][i]", -128, 127 );
4627
1.01k
      nextCoef += scaling_list_delta_coef;
4628
1.01k
    }
4629
4630
1.14k
    int pos = DiagScanOrder[getLog2( matrixSize )][getLog2( matrixSize )][i];
4631
4632
1.14k
    auto& scalingMatrixRec = scalingList->getScalingListVec( id );
4633
1.14k
    scalingMatrixRec[pos]  = ( scalingMatrixPred[pos] + nextCoef ) & 255;
4634
1.14k
    CHECK( scalingMatrixRec[pos] <= 0, "The value of ScalingMatrixRec[" << id << " ][x][y] shall be greater than 0." )
4635
1.14k
  }
4636
56
}
4637
bool HLSyntaxReader::xMoreRbspData()
4638
3.58k
{
4639
3.58k
  int bitsLeft = m_pcBitstream->getNumBitsLeft();
4640
4641
  // if there are more than 8 bits, it cannot be rbsp_trailing_bits
4642
3.58k
  if( bitsLeft > 8 )
4643
3.38k
  {
4644
3.38k
    return true;
4645
3.38k
  }
4646
4647
204
  uint8_t lastByte = m_pcBitstream->peekBits( bitsLeft );
4648
204
  int cnt = bitsLeft;
4649
4650
  // remove trailing bits equal to zero
4651
438
  while( ( cnt > 0 ) && ( ( lastByte & 1 ) == 0 ) )
4652
234
  {
4653
234
    lastByte >>= 1;
4654
234
    cnt--;
4655
234
  }
4656
  // remove bit equal to one
4657
204
  cnt--;
4658
4659
  // we should not have a negative number of bits
4660
204
  CHECK( cnt<0, "Negative number of bits") ;
4661
4662
  // we have more data, if cnt is not zero
4663
202
  return ( cnt>0 );
4664
204
}
4665
4666
4667
void HLSyntaxReader::alfFilterCoeffs( AlfSliceParam& alfSliceParam, const bool isChroma, const int altIdx )
4668
46
{
4669
46
  const bool isLuma = !isChroma;
4670
4671
  // derive maxGolombIdx
4672
46
  const int numCoeff   = g_alfNumCoeff[isLuma];
4673
46
  const int numFilters = isLuma ? alfSliceParam.numLumaFilters : 1;
4674
46
  short*    coeff      = isLuma ? alfSliceParam.lumaCoeff      : alfSliceParam.chromaCoeff + altIdx * MAX_NUM_ALF_CHROMA_COEFF;
4675
46
  short*    clipp      = isLuma ? alfSliceParam.lumaClipp      : alfSliceParam.chromaClipp + altIdx * MAX_NUM_ALF_CHROMA_COEFF;
4676
4677
  // Filter coefficients
4678
100
  for( int sfIdx = 0; sfIdx < numFilters; ++sfIdx )
4679
60
  {
4680
578
    for( int j = 0; j < numCoeff - 1; j++ )
4681
524
    {
4682
524
      uint32_t code;
4683
524
      READ_UVLC( code, isLuma ? "alf_luma_coeff_abs" : "alf_chroma_coeff_abs" );
4684
524
      CHECK_READ_RANGE( code, 0, 128, ( isLuma ? "alf_luma_coeff_abs[sfIdx][j]" : "alf_chroma_coeff_abs[sfIdx][j]" ) );
4685
518
      coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j] = code;
4686
4687
518
      if( code )
4688
136
      {
4689
136
        READ_FLAG( code, isLuma ? "alf_luma_coeff_sign" : "alf_chroma_coeff_sign" );
4690
4691
136
        const int sign = code ? -1 : 1;
4692
136
        coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j] *= sign;
4693
4694
136
        CHECK_READ_RANGE( coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j],
4695
136
                          -( 1 << 7 ), ( 1 << 7 ) - 1,
4696
136
                          ( isLuma ? "AlfLumaCoeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j]" : "AlfChromaCoeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j]" ) );
4697
136
      }
4698
518
    }
4699
4700
54
    const int factor = 1 << ( AdaptiveLoopFilter::m_NUM_BITS - 1 );
4701
54
    coeff[sfIdx * MAX_NUM_ALF_LUMA_COEFF + numCoeff - 1] = factor;
4702
54
  }
4703
4704
  // Clipping values coding
4705
40
  bool alfClipFlag = isLuma ? alfSliceParam.nonLinearFlagLuma : alfSliceParam.nonLinearFlagChroma;
4706
40
  if( alfClipFlag )
4707
14
  {
4708
    // Filter coefficients
4709
28
    for( int sfIdx = 0; sfIdx < numFilters; ++sfIdx )
4710
14
    {
4711
182
      for( int j = 0; j < numCoeff - 1; j++ )
4712
168
      {
4713
168
        uint32_t code;
4714
168
        READ_CODE( 2, code, isLuma ? "alf_luma_clip_idx" : "alf_chroma_clip_idx" );
4715
168
        clipp[sfIdx * MAX_NUM_ALF_LUMA_COEFF + j] = code;
4716
168
      }
4717
14
    }
4718
14
  }
4719
40
}
4720
4721
}   // namespace vvdec