Coverage Report

Created: 2026-07-25 07:06

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