Coverage Report

Created: 2026-10-28 06:18

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