Coverage Report

Created: 2026-10-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libde265/libde265/vui.cc
Line
Count
Source
1
/*
2
 * H.265 video codec.
3
 * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
4
 *
5
 * This file is part of libde265.
6
 *
7
 * libde265 is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Lesser General Public License as
9
 * published by the Free Software Foundation, either version 3 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * libde265 is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with libde265.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
21
#include "vui.h"
22
#include "decctx.h"
23
24
#include <assert.h>
25
#include <stdlib.h>
26
#include <string.h>
27
28
#define READ_VLC(variable, vlctype)   \
29
4.49k
  if ((vlc = br->get_ ## vlctype()) == UVLC_ERROR) {   \
30
50
    errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);  \
31
50
    return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE; \
32
50
  } \
33
4.49k
  (variable) = vlc;
34
35
36
/* Read an advisory ue(v) VUI syntax element.
37
38
   A malformed exp-Golomb code (UVLC_ERROR) is a hard error: we lost the bit
39
   position and nothing after it can be parsed.
40
41
   A well-formed value that merely exceeds the range allowed by the standard is
42
   only a warning. The chroma siting and bitstream_restriction() elements are
43
   hints for the decoder that are never used in the decoding process, so an
44
   out-of-range value cannot affect correctness or memory safety. Real-world
45
   streams (e.g. HEIF images from consumer encoders) contain such values, so we
46
   clamp to the value the standard infers when the element is absent and keep
47
   parsing instead of rejecting the whole SPS (issue #539).
48
 */
49
#define READ_ADVISORY_VLC(variable, maxval, defaultval)   \
50
44.8k
  if ((vlc = br->get_uvlc()) == UVLC_ERROR) {   \
51
104
    errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);  \
52
104
    return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE; \
53
104
  } \
54
44.8k
  if (vlc > (maxval)) { \
55
243
    errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);  \
56
243
    vlc = (defaultval); \
57
243
  } \
58
44.7k
  (variable) = vlc;
59
60
61
1.06k
#define NUM_SAR_PRESETS 17
62
63
static uint16_t sar_presets[NUM_SAR_PRESETS+1][2] = {
64
  { 0,0 },
65
  { 1,1 },
66
  { 12,11 },
67
  { 10,11 },
68
  { 16,11 },
69
  { 40,33 },
70
  { 24,11 },
71
  { 20,11 },
72
  { 32,11 },
73
  { 80,33 },
74
  { 18,11 },
75
  { 15,11 },
76
  { 64,33 },
77
  { 160,99 },
78
  { 4,3 },
79
  { 3,2 },
80
  { 2,1 }
81
};
82
83
1.01k
#define EXTENDED_SAR 255
84
85
86
const char* get_video_format_name(enum VideoFormat format)
87
0
{
88
0
  switch (format) {
89
0
  case VideoFormat_Component: return "component";
90
0
  case VideoFormat_PAL:       return "PAL";
91
0
  case VideoFormat_NTSC:      return "NTSC";
92
0
  case VideoFormat_SECAM:     return "SECAM";
93
0
  case VideoFormat_MAC:       return "MAC";
94
0
  default:                    return "unspecified";
95
0
  }
96
0
}
97
98
99
13.3k
video_usability_information::video_usability_information() = default;
100
101
102
de265_error video_usability_information::hrd_parameters(error_queue* errqueue, bitreader* br, const seq_parameter_set* sps)
103
70
{
104
70
  uint32_t vlc;
105
106
70
  nal_hrd_parameters_present_flag = br->get_bits(1);
107
70
  vcl_hrd_parameters_present_flag = br->get_bits(1);
108
109
70
  if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag)
110
43
  {
111
43
    sub_pic_hrd_params_present_flag = br->get_bits(1);
112
43
    if (sub_pic_hrd_params_present_flag)
113
22
    {
114
22
      tick_divisor_minus2 = br->get_bits(8);
115
22
      du_cpb_removal_delay_increment_length_minus1 = br->get_bits(5);
116
22
      sub_pic_cpb_params_in_pic_timing_sei_flag = br->get_bits(1);
117
22
      dpb_output_delay_du_length_minus1 = br->get_bits(5);
118
22
    }
119
43
    bit_rate_scale = br->get_bits(4);
120
43
    cpb_size_scale = br->get_bits(4);
121
122
123
43
    if (sub_pic_hrd_params_present_flag)
124
22
    {
125
22
      cpb_size_du_scale = br->get_bits(4);
126
22
    }
127
43
    initial_cpb_removal_delay_length_minus1 = br->get_bits(5);
128
43
    au_cpb_removal_delay_length_minus1 = br->get_bits(5);
129
43
    dpb_output_delay_length_minus1 = br->get_bits(5);
130
43
  }
131
70
  int  i, nalOrVcl;
132
133
113
  for (i = 0; i < sps->sps_max_sub_layers; i++)
134
70
  {
135
70
    fixed_pic_rate_general_flag[i] = br->get_bits(1);
136
70
    if (!fixed_pic_rate_general_flag[i])
137
60
    {
138
60
      fixed_pic_rate_within_cvs_flag[i] = br->get_bits(1);
139
60
    }
140
10
    else
141
10
    {
142
10
      fixed_pic_rate_within_cvs_flag[i] = true;
143
10
    }
144
145
70
    low_delay_hrd_flag[i] = 0;// Inferred to be 0 when not present
146
70
    cpb_cnt_minus1[i] = 0;    // Inferred to be 0 when not present
147
148
70
    if (fixed_pic_rate_within_cvs_flag[i])
149
34
    {
150
34
      READ_VLC(elemental_duration_in_tc_minus1[i], uvlc);
151
33
    }
152
36
    else
153
36
    {
154
36
      low_delay_hrd_flag[i] = br->get_bits(1);
155
36
    }
156
69
    if (!low_delay_hrd_flag[i])
157
60
    {
158
60
      READ_VLC(cpb_cnt_minus1[i], uvlc);
159
54
      if (cpb_cnt_minus1[i] > 31) {
160
1
  return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
161
1
      }
162
54
    }
163
164
156
    for (nalOrVcl = 0; nalOrVcl < 2; nalOrVcl++)
165
113
    {
166
113
      if (((nalOrVcl == 0) && nal_hrd_parameters_present_flag) ||
167
79
        ((nalOrVcl == 1) && vcl_hrd_parameters_present_flag))
168
57
      {
169
623
        for (uint32_t j = 0; j <= cpb_cnt_minus1[i]; j++)
170
585
        {
171
585
          READ_VLC(bit_rate_value_minus1[i][j][nalOrVcl], uvlc);
172
576
          READ_VLC(cpb_size_value_minus1[i][j][nalOrVcl], uvlc);
173
174
570
          if (sub_pic_hrd_params_present_flag)
175
429
          {
176
429
            READ_VLC(cpb_size_du_value_minus1[i][j][nalOrVcl], uvlc);
177
428
            READ_VLC(bit_rate_du_value_minus1[i][j][nalOrVcl], uvlc);
178
425
          }
179
566
          cbr_flag[i][j][nalOrVcl] = br->get_bits(1);
180
566
        }
181
57
      }
182
113
    }
183
62
  }
184
43
  return DE265_OK;
185
70
}
186
187
de265_error video_usability_information::read(error_queue* errqueue, bitreader* br,
188
                                              const seq_parameter_set* sps)
189
11.4k
{
190
11.4k
  uint32_t vlc;
191
192
193
  // --- sample aspect ratio (SAR) ---
194
195
11.4k
  aspect_ratio_info_present_flag = br->get_bits(1);
196
11.4k
  if (aspect_ratio_info_present_flag) {
197
1.06k
    int aspect_ratio_idc = br->get_bits(8);
198
1.06k
    if (aspect_ratio_idc <= NUM_SAR_PRESETS) {
199
49
      sar_width = sar_presets[aspect_ratio_idc][0];
200
49
      sar_height = sar_presets[aspect_ratio_idc][1];
201
49
    }
202
1.01k
    else if (aspect_ratio_idc == EXTENDED_SAR) {
203
253
      sar_width = br->get_bits(16);
204
253
      sar_height = br->get_bits(16);
205
253
    }
206
766
    else {
207
766
      sar_width = 0;
208
766
      sar_height = 0;
209
766
    }
210
1.06k
  }
211
10.3k
  else {
212
10.3k
    sar_width = 0;
213
10.3k
    sar_height = 0;
214
10.3k
  }
215
216
217
  // --- overscan ---
218
219
11.4k
  overscan_info_present_flag = br->get_bits(1);
220
11.4k
  if (overscan_info_present_flag) {
221
1.01k
    overscan_appropriate_flag = br->get_bits(1);
222
1.01k
  }
223
224
225
  // --- video signal type ---
226
227
11.4k
  { // defaults
228
11.4k
    video_format = VideoFormat_Unspecified;
229
11.4k
    video_full_range_flag = false;
230
11.4k
    colour_primaries = 2;
231
11.4k
    transfer_characteristics = 2;
232
11.4k
    matrix_coeffs = 2;
233
11.4k
  }
234
235
11.4k
  video_signal_type_present_flag = br->get_bits(1);
236
11.4k
  if (video_signal_type_present_flag) {
237
10.5k
    int video_format_idc = br->get_bits(3);
238
10.5k
    if (video_format_idc > 5) {
239
825
      video_format_idc = VideoFormat_Unspecified;
240
825
    }
241
10.5k
    video_format = (VideoFormat)video_format_idc;
242
243
10.5k
    video_full_range_flag = br->get_bits(1);
244
245
10.5k
    colour_description_present_flag = br->get_bits(1);
246
10.5k
    if (colour_description_present_flag) {
247
10.1k
      colour_primaries = br->get_bits(8);
248
10.1k
      if (colour_primaries == 0 ||
249
1.58k
        colour_primaries == 3 ||
250
9.36k
        colour_primaries >= 11) {
251
9.36k
        colour_primaries = 2;
252
9.36k
      }
253
254
10.1k
      transfer_characteristics = br->get_bits(8);
255
10.1k
      if (transfer_characteristics == 0 ||
256
9.86k
        transfer_characteristics == 3 ||
257
9.85k
        transfer_characteristics >= 18) {
258
1.04k
        transfer_characteristics = 2;
259
1.04k
      }
260
261
10.1k
      matrix_coeffs = br->get_bits(8);
262
      
263
10.1k
      if (matrix_coeffs >= 11) {
264
551
        matrix_coeffs = 2;
265
551
      }
266
10.1k
    }
267
10.5k
  }
268
269
270
  // --- chroma / interlaced ---
271
272
11.4k
  chroma_loc_info_present_flag = br->get_bits(1);
273
11.4k
  if (chroma_loc_info_present_flag) {
274
511
    READ_ADVISORY_VLC(chroma_sample_loc_type_top_field,    5, 0);
275
501
    READ_ADVISORY_VLC(chroma_sample_loc_type_bottom_field, 5, 0);
276
491
  }
277
10.9k
  else {
278
10.9k
    chroma_sample_loc_type_top_field = 0;
279
10.9k
    chroma_sample_loc_type_bottom_field = 0;
280
10.9k
  }
281
282
11.4k
  neutral_chroma_indication_flag = br->get_bits(1);
283
11.4k
  field_seq_flag = br->get_bits(1);
284
11.4k
  frame_field_info_present_flag = br->get_bits(1);
285
286
287
  // --- default display window ---
288
289
11.4k
  default_display_window_flag = br->get_bits(1);
290
11.4k
  if (default_display_window_flag) {
291
605
    READ_VLC(def_disp_win_left_offset, uvlc);
292
604
    READ_VLC(def_disp_win_right_offset, uvlc);
293
587
    READ_VLC(def_disp_win_top_offset, uvlc);
294
584
    READ_VLC(def_disp_win_bottom_offset, uvlc);
295
581
  }
296
10.7k
  else {
297
10.7k
    def_disp_win_left_offset = 0;
298
10.7k
    def_disp_win_right_offset = 0;
299
10.7k
    def_disp_win_top_offset = 0;
300
10.7k
    def_disp_win_bottom_offset = 0;
301
10.7k
  }
302
303
304
  // --- timing ---
305
306
11.3k
  vui_timing_info_present_flag = br->get_bits(1);
307
11.3k
  if (vui_timing_info_present_flag) {
308
1.02k
    vui_num_units_in_tick = br->get_bits(32);
309
1.02k
    vui_time_scale = br->get_bits(32);
310
311
1.02k
    vui_poc_proportional_to_timing_flag = br->get_bits(1);
312
1.02k
    if (vui_poc_proportional_to_timing_flag) {
313
50
      if ((vlc = br->get_uvlc()) == UVLC_ERROR) {
314
1
        errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);
315
1
        return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
316
1
      }
317
318
49
      vui_num_ticks_poc_diff_one = vlc + 1;
319
49
    }
320
321
    // --- hrd parameters ---
322
323
1.02k
    vui_hrd_parameters_present_flag = br->get_bits(1);
324
1.02k
    if (vui_hrd_parameters_present_flag) {
325
70
      de265_error err;
326
70
      err = hrd_parameters(errqueue, br, sps);
327
70
      if (err) {
328
27
  return err;
329
27
      }
330
70
    }
331
1.02k
  }
332
333
  // --- bitstream restriction ---
334
335
11.3k
  bitstream_restriction_flag = br->get_bits(1);
336
11.3k
  if (bitstream_restriction_flag) {
337
8.79k
    tiles_fixed_structure_flag = br->get_bits(1);
338
8.79k
    motion_vectors_over_pic_boundaries_flag = br->get_bits(1);
339
8.79k
    restricted_ref_pic_lists_flag = br->get_bits(1);
340
341
    // Same defaults as in the else-branch below (the values inferred when absent).
342
8.79k
    READ_ADVISORY_VLC(min_spatial_segmentation_idc,  4095, 0);
343
8.78k
    READ_ADVISORY_VLC(max_bytes_per_pic_denom,       16,   2);
344
8.76k
    READ_ADVISORY_VLC(max_bits_per_min_cu_denom,     16,   1);
345
8.74k
    READ_ADVISORY_VLC(log2_max_mv_length_horizontal, 15,   15);
346
8.74k
    READ_ADVISORY_VLC(log2_max_mv_length_vertical,   15,   15);
347
8.71k
  }
348
2.55k
  else {
349
2.55k
    tiles_fixed_structure_flag = false;
350
2.55k
    motion_vectors_over_pic_boundaries_flag = true;
351
2.55k
    restricted_ref_pic_lists_flag = false; // NOTE: default not specified in standard 2014/10
352
353
2.55k
    min_spatial_segmentation_idc = 0;
354
2.55k
    max_bytes_per_pic_denom   = 2;
355
2.55k
    max_bits_per_min_cu_denom = 1;
356
2.55k
    log2_max_mv_length_horizontal = 15;
357
2.55k
    log2_max_mv_length_vertical   = 15;
358
2.55k
  }
359
360
  //vui_read = true;
361
362
11.2k
  return DE265_OK;
363
11.3k
}
364
365
366
void video_usability_information::dump(int fd) const
367
0
{
368
  //#if (_MSC_VER >= 1500)
369
  //#define LOG0(t) loginfo(LogHeaders, t)
370
  //#define LOG1(t,d) loginfo(LogHeaders, t,d)
371
  //#define LOG2(t,d1,d2) loginfo(LogHeaders, t,d1,d2)
372
  //#define LOG3(t,d1,d2,d3) loginfo(LogHeaders, t,d1,d2,d3)
373
374
0
  FILE* fh;
375
0
  if (fd==1) fh=stdout;
376
0
  else if (fd==2) fh=stderr;
377
0
  else { return; }
378
379
0
#define LOG0(t) log2fh(fh, t)
380
0
#define LOG1(t,d) log2fh(fh, t,d)
381
0
#define LOG2(t,d1,d2) log2fh(fh, t,d1,d2)
382
0
#define LOG3(t,d1,d2,d3) log2fh(fh, t,d1,d2,d3)
383
384
0
  LOG0("----------------- VUI -----------------\n");
385
0
  LOG2("sample aspect ratio        : %d:%d\n", sar_width,sar_height);
386
0
  LOG1("overscan_info_present_flag : %d\n", overscan_info_present_flag);
387
0
  LOG1("overscan_appropriate_flag  : %d\n", overscan_appropriate_flag);
388
389
0
  LOG1("video_signal_type_present_flag: %d\n", video_signal_type_present_flag);
390
0
  if (video_signal_type_present_flag) {
391
0
    LOG1("  video_format                : %s\n", get_video_format_name(video_format));
392
0
    LOG1("  video_full_range_flag       : %d\n", video_full_range_flag);
393
0
    LOG1("  colour_description_present_flag : %d\n", colour_description_present_flag);
394
0
    LOG1("  colour_primaries            : %d\n", colour_primaries);
395
0
    LOG1("  transfer_characteristics    : %d\n", transfer_characteristics);
396
0
    LOG1("  matrix_coeffs               : %d\n", matrix_coeffs);
397
0
  }
398
399
0
  LOG1("chroma_loc_info_present_flag: %d\n", chroma_loc_info_present_flag);
400
0
  if (chroma_loc_info_present_flag) {
401
0
    LOG1("  chroma_sample_loc_type_top_field   : %d\n", chroma_sample_loc_type_top_field);
402
0
    LOG1("  chroma_sample_loc_type_bottom_field: %d\n", chroma_sample_loc_type_bottom_field);
403
0
  }
404
405
0
  LOG1("neutral_chroma_indication_flag: %d\n", neutral_chroma_indication_flag);
406
0
  LOG1("field_seq_flag                : %d\n", field_seq_flag);
407
0
  LOG1("frame_field_info_present_flag : %d\n", frame_field_info_present_flag);
408
409
0
  LOG1("default_display_window_flag   : %d\n", default_display_window_flag);
410
0
  LOG1("  def_disp_win_left_offset    : %d\n", def_disp_win_left_offset);
411
0
  LOG1("  def_disp_win_right_offset   : %d\n", def_disp_win_right_offset);
412
0
  LOG1("  def_disp_win_top_offset     : %d\n", def_disp_win_top_offset);
413
0
  LOG1("  def_disp_win_bottom_offset  : %d\n", def_disp_win_bottom_offset);
414
415
0
  LOG1("vui_timing_info_present_flag  : %d\n", vui_timing_info_present_flag);
416
0
  if (vui_timing_info_present_flag) {
417
0
    LOG1("  vui_num_units_in_tick       : %d\n", vui_num_units_in_tick);
418
0
    LOG1("  vui_time_scale              : %d\n", vui_time_scale);
419
0
  }
420
421
0
  LOG1("vui_poc_proportional_to_timing_flag : %d\n", vui_poc_proportional_to_timing_flag);
422
0
  LOG1("vui_num_ticks_poc_diff_one          : %d\n", vui_num_ticks_poc_diff_one);
423
424
0
  LOG1("vui_hrd_parameters_present_flag : %d\n", vui_hrd_parameters_present_flag);
425
0
  if (vui_hrd_parameters_present_flag) {
426
    //hrd_parameters vui_hrd_parameters;
427
0
  }
428
429
430
  // --- bitstream restriction ---
431
432
0
  LOG1("bitstream_restriction_flag         : %d\n", bitstream_restriction_flag);
433
0
  if (bitstream_restriction_flag) {
434
0
    LOG1("  tiles_fixed_structure_flag       : %d\n", tiles_fixed_structure_flag);
435
0
    LOG1("  motion_vectors_over_pic_boundaries_flag : %d\n", motion_vectors_over_pic_boundaries_flag);
436
0
    LOG1("  restricted_ref_pic_lists_flag    : %d\n", restricted_ref_pic_lists_flag);
437
0
    LOG1("  min_spatial_segmentation_idc     : %d\n", min_spatial_segmentation_idc);
438
0
    LOG1("  max_bytes_per_pic_denom          : %d\n", max_bytes_per_pic_denom);
439
0
    LOG1("  max_bits_per_min_cu_denom        : %d\n", max_bits_per_min_cu_denom);
440
0
    LOG1("  log2_max_mv_length_horizontal    : %d\n", log2_max_mv_length_horizontal);
441
0
    LOG1("  log2_max_mv_length_vertical      : %d\n", log2_max_mv_length_vertical);
442
0
  }
443
444
0
#undef LOG0
445
0
#undef LOG1
446
0
#undef LOG2
447
0
#undef LOG3
448
  //#endif
449
0
}