Coverage Report

Created: 2026-10-17 06:56

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