Coverage Report

Created: 2026-09-13 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/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
30.4k
  if ((vlc = br->get_ ## vlctype()) == UVLC_ERROR) {   \
30
221
    errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);  \
31
221
    return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE; \
32
221
  } \
33
30.4k
  (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
13.3k
  if ((vlc = br->get_uvlc()) == UVLC_ERROR) {   \
51
109
    errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);  \
52
109
    return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE; \
53
109
  } \
54
13.3k
  if (vlc > (maxval)) { \
55
963
    errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);  \
56
963
    vlc = (defaultval); \
57
963
  } \
58
13.2k
  (variable) = vlc;
59
60
61
8.56k
#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
8.51k
#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
20.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
687
{
104
687
  uint32_t vlc;
105
106
687
  nal_hrd_parameters_present_flag = br->get_bits(1);
107
687
  vcl_hrd_parameters_present_flag = br->get_bits(1);
108
109
687
  if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag)
110
590
  {
111
590
    sub_pic_hrd_params_present_flag = br->get_bits(1);
112
590
    if (sub_pic_hrd_params_present_flag)
113
427
    {
114
427
      tick_divisor_minus2 = br->get_bits(8);
115
427
      du_cpb_removal_delay_increment_length_minus1 = br->get_bits(5);
116
427
      sub_pic_cpb_params_in_pic_timing_sei_flag = br->get_bits(1);
117
427
      dpb_output_delay_du_length_minus1 = br->get_bits(5);
118
427
    }
119
590
    bit_rate_scale = br->get_bits(4);
120
590
    cpb_size_scale = br->get_bits(4);
121
122
123
590
    if (sub_pic_hrd_params_present_flag)
124
427
    {
125
427
      cpb_size_du_scale = br->get_bits(4);
126
427
    }
127
590
    initial_cpb_removal_delay_length_minus1 = br->get_bits(5);
128
590
    au_cpb_removal_delay_length_minus1 = br->get_bits(5);
129
590
    dpb_output_delay_length_minus1 = br->get_bits(5);
130
590
  }
131
687
  int  i, nalOrVcl;
132
133
1.12k
  for (i = 0; i < sps->sps_max_sub_layers; i++)
134
687
  {
135
687
    fixed_pic_rate_general_flag[i] = br->get_bits(1);
136
687
    if (!fixed_pic_rate_general_flag[i])
137
373
    {
138
373
      fixed_pic_rate_within_cvs_flag[i] = br->get_bits(1);
139
373
    }
140
314
    else
141
314
    {
142
314
      fixed_pic_rate_within_cvs_flag[i] = true;
143
314
    }
144
145
687
    low_delay_hrd_flag[i] = 0;// Inferred to be 0 when not present
146
687
    cpb_cnt_minus1[i] = 0;    // Inferred to be 0 when not present
147
148
687
    if (fixed_pic_rate_within_cvs_flag[i])
149
350
    {
150
350
      READ_VLC(elemental_duration_in_tc_minus1[i], uvlc);
151
347
    }
152
337
    else
153
337
    {
154
337
      low_delay_hrd_flag[i] = br->get_bits(1);
155
337
    }
156
684
    if (!low_delay_hrd_flag[i])
157
513
    {
158
513
      READ_VLC(cpb_cnt_minus1[i], uvlc);
159
446
      if (cpb_cnt_minus1[i] > 31) {
160
55
  return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
161
55
      }
162
446
    }
163
164
1.54k
    for (nalOrVcl = 0; nalOrVcl < 2; nalOrVcl++)
165
1.11k
    {
166
1.11k
      if (((nalOrVcl == 0) && nal_hrd_parameters_present_flag) ||
167
720
        ((nalOrVcl == 1) && vcl_hrd_parameters_present_flag))
168
891
      {
169
3.44k
        for (uint32_t j = 0; j <= cpb_cnt_minus1[i]; j++)
170
2.68k
        {
171
2.68k
          READ_VLC(bit_rate_value_minus1[i][j][nalOrVcl], uvlc);
172
2.63k
          READ_VLC(cpb_size_value_minus1[i][j][nalOrVcl], uvlc);
173
174
2.58k
          if (sub_pic_hrd_params_present_flag)
175
1.37k
          {
176
1.37k
            READ_VLC(cpb_size_du_value_minus1[i][j][nalOrVcl], uvlc);
177
1.36k
            READ_VLC(bit_rate_du_value_minus1[i][j][nalOrVcl], uvlc);
178
1.33k
          }
179
2.55k
          cbr_flag[i][j][nalOrVcl] = br->get_bits(1);
180
2.55k
        }
181
891
      }
182
1.11k
    }
183
562
  }
184
433
  return DE265_OK;
185
687
}
186
187
de265_error video_usability_information::read(error_queue* errqueue, bitreader* br,
188
                                              const seq_parameter_set* sps)
189
9.93k
{
190
9.93k
  uint32_t vlc;
191
192
193
  // --- sample aspect ratio (SAR) ---
194
195
9.93k
  aspect_ratio_info_present_flag = br->get_bits(1);
196
9.93k
  if (aspect_ratio_info_present_flag) {
197
8.56k
    int aspect_ratio_idc = br->get_bits(8);
198
8.56k
    if (aspect_ratio_idc <= NUM_SAR_PRESETS) {
199
44
      sar_width = sar_presets[aspect_ratio_idc][0];
200
44
      sar_height = sar_presets[aspect_ratio_idc][1];
201
44
    }
202
8.51k
    else if (aspect_ratio_idc == EXTENDED_SAR) {
203
1.95k
      sar_width = br->get_bits(16);
204
1.95k
      sar_height = br->get_bits(16);
205
1.95k
    }
206
6.56k
    else {
207
6.56k
      sar_width = 0;
208
6.56k
      sar_height = 0;
209
6.56k
    }
210
8.56k
  }
211
1.37k
  else {
212
1.37k
    sar_width = 0;
213
1.37k
    sar_height = 0;
214
1.37k
  }
215
216
217
  // --- overscan ---
218
219
9.93k
  overscan_info_present_flag = br->get_bits(1);
220
9.93k
  if (overscan_info_present_flag) {
221
2.94k
    overscan_appropriate_flag = br->get_bits(1);
222
2.94k
  }
223
224
225
  // --- video signal type ---
226
227
9.93k
  { // defaults
228
9.93k
    video_format = VideoFormat_Unspecified;
229
9.93k
    video_full_range_flag = false;
230
9.93k
    colour_primaries = 2;
231
9.93k
    transfer_characteristics = 2;
232
9.93k
    matrix_coeffs = 2;
233
9.93k
  }
234
235
9.93k
  video_signal_type_present_flag = br->get_bits(1);
236
9.93k
  if (video_signal_type_present_flag) {
237
5.86k
    int video_format_idc = br->get_bits(3);
238
5.86k
    if (video_format_idc > 5) {
239
3.20k
      video_format_idc = VideoFormat_Unspecified;
240
3.20k
    }
241
5.86k
    video_format = (VideoFormat)video_format_idc;
242
243
5.86k
    video_full_range_flag = br->get_bits(1);
244
245
5.86k
    colour_description_present_flag = br->get_bits(1);
246
5.86k
    if (colour_description_present_flag) {
247
4.39k
      colour_primaries = br->get_bits(8);
248
4.39k
      if (colour_primaries == 0 ||
249
4.38k
        colour_primaries == 3 ||
250
4.38k
        colour_primaries >= 11) {
251
4.22k
        colour_primaries = 2;
252
4.22k
      }
253
254
4.39k
      transfer_characteristics = br->get_bits(8);
255
4.39k
      if (transfer_characteristics == 0 ||
256
4.28k
        transfer_characteristics == 3 ||
257
4.27k
        transfer_characteristics >= 18) {
258
4.09k
        transfer_characteristics = 2;
259
4.09k
      }
260
261
4.39k
      matrix_coeffs = br->get_bits(8);
262
      
263
4.39k
      if (matrix_coeffs >= 11) {
264
3.97k
        matrix_coeffs = 2;
265
3.97k
      }
266
4.39k
    }
267
5.86k
  }
268
269
270
  // --- chroma / interlaced ---
271
272
9.93k
  chroma_loc_info_present_flag = br->get_bits(1);
273
9.93k
  if (chroma_loc_info_present_flag) {
274
3.49k
    READ_ADVISORY_VLC(chroma_sample_loc_type_top_field,    5, 0);
275
3.49k
    READ_ADVISORY_VLC(chroma_sample_loc_type_bottom_field, 5, 0);
276
3.48k
  }
277
6.44k
  else {
278
6.44k
    chroma_sample_loc_type_top_field = 0;
279
6.44k
    chroma_sample_loc_type_bottom_field = 0;
280
6.44k
  }
281
282
9.93k
  neutral_chroma_indication_flag = br->get_bits(1);
283
9.93k
  field_seq_flag = br->get_bits(1);
284
9.93k
  frame_field_info_present_flag = br->get_bits(1);
285
286
287
  // --- default display window ---
288
289
9.93k
  default_display_window_flag = br->get_bits(1);
290
9.93k
  if (default_display_window_flag) {
291
5.39k
    READ_VLC(def_disp_win_left_offset, uvlc);
292
5.38k
    READ_VLC(def_disp_win_right_offset, uvlc);
293
5.38k
    READ_VLC(def_disp_win_top_offset, uvlc);
294
5.38k
    READ_VLC(def_disp_win_bottom_offset, uvlc);
295
5.37k
  }
296
4.53k
  else {
297
4.53k
    def_disp_win_left_offset = 0;
298
4.53k
    def_disp_win_right_offset = 0;
299
4.53k
    def_disp_win_top_offset = 0;
300
4.53k
    def_disp_win_bottom_offset = 0;
301
4.53k
  }
302
303
304
  // --- timing ---
305
306
9.90k
  vui_timing_info_present_flag = br->get_bits(1);
307
9.90k
  if (vui_timing_info_present_flag) {
308
3.52k
    vui_num_units_in_tick = br->get_bits(32);
309
3.52k
    vui_time_scale = br->get_bits(32);
310
311
3.52k
    vui_poc_proportional_to_timing_flag = br->get_bits(1);
312
3.52k
    if (vui_poc_proportional_to_timing_flag) {
313
574
      if ((vlc = br->get_uvlc()) == UVLC_ERROR) {
314
3
        errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);
315
3
        return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
316
3
      }
317
318
571
      vui_num_ticks_poc_diff_one = vlc + 1;
319
571
    }
320
321
    // --- hrd parameters ---
322
323
3.52k
    vui_hrd_parameters_present_flag = br->get_bits(1);
324
3.52k
    if (vui_hrd_parameters_present_flag) {
325
687
      de265_error err;
326
687
      err = hrd_parameters(errqueue, br, sps);
327
687
      if (err) {
328
254
  return err;
329
254
      }
330
687
    }
331
3.52k
  }
332
333
  // --- bitstream restriction ---
334
335
9.65k
  bitstream_restriction_flag = br->get_bits(1);
336
9.65k
  if (bitstream_restriction_flag) {
337
1.32k
    tiles_fixed_structure_flag = br->get_bits(1);
338
1.32k
    motion_vectors_over_pic_boundaries_flag = br->get_bits(1);
339
1.32k
    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
1.32k
    READ_ADVISORY_VLC(min_spatial_segmentation_idc,  4095, 0);
343
1.30k
    READ_ADVISORY_VLC(max_bytes_per_pic_denom,       16,   2);
344
1.28k
    READ_ADVISORY_VLC(max_bits_per_min_cu_denom,     16,   1);
345
1.23k
    READ_ADVISORY_VLC(log2_max_mv_length_horizontal, 15,   15);
346
1.23k
    READ_ADVISORY_VLC(log2_max_mv_length_vertical,   15,   15);
347
1.22k
  }
348
8.32k
  else {
349
8.32k
    tiles_fixed_structure_flag = false;
350
8.32k
    motion_vectors_over_pic_boundaries_flag = true;
351
8.32k
    restricted_ref_pic_lists_flag = false; // NOTE: default not specified in standard 2014/10
352
353
8.32k
    min_spatial_segmentation_idc = 0;
354
8.32k
    max_bytes_per_pic_denom   = 2;
355
8.32k
    max_bits_per_min_cu_denom = 1;
356
8.32k
    log2_max_mv_length_horizontal = 15;
357
8.32k
    log2_max_mv_length_vertical   = 15;
358
8.32k
  }
359
360
  //vui_read = true;
361
362
9.54k
  return DE265_OK;
363
9.65k
}
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
}