Coverage Report

Created: 2026-06-16 07:20

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