Coverage Report

Created: 2026-02-14 07:09

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_OFFSET(variable, vlctype, offset)   \
29
2.86k
  if ((vlc = get_ ## vlctype(br)) == UVLC_ERROR) {   \
30
18
    errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);  \
31
18
    return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE; \
32
18
  } \
33
2.86k
  variable = vlc + offset;
34
35
2.82k
#define READ_VLC(variable, vlctype)  READ_VLC_OFFSET(variable,vlctype,0)
36
37
38
936
#define NUM_SAR_PRESETS 17
39
40
static uint16_t sar_presets[NUM_SAR_PRESETS+1][2] = {
41
  { 0,0 },
42
  { 1,1 },
43
  { 12,11 },
44
  { 10,11 },
45
  { 16,11 },
46
  { 40,33 },
47
  { 24,11 },
48
  { 20,11 },
49
  { 32,11 },
50
  { 80,33 },
51
  { 18,11 },
52
  { 15,11 },
53
  { 64,33 },
54
  { 160,99 },
55
  { 4,3 },
56
  { 3,2 },
57
  { 2,1 }
58
};
59
60
873
#define EXTENDED_SAR 255
61
62
63
const char* get_video_format_name(enum VideoFormat format)
64
0
{
65
0
  switch (format) {
66
0
  case VideoFormat_Component: return "component";
67
0
  case VideoFormat_PAL:       return "PAL";
68
0
  case VideoFormat_NTSC:      return "NTSC";
69
0
  case VideoFormat_SECAM:     return "SECAM";
70
0
  case VideoFormat_MAC:       return "MAC";
71
0
  default:                    return "unspecified";
72
0
  }
73
0
}
74
75
76
video_usability_information::video_usability_information()
77
4.65k
{
78
4.65k
  aspect_ratio_info_present_flag = false;
79
4.65k
  sar_width  = 0;
80
4.65k
  sar_height = 0;
81
82
83
  // --- overscan ---
84
85
4.65k
  overscan_info_present_flag = false;
86
4.65k
  overscan_appropriate_flag  = false;
87
88
89
  // --- video signal type ---
90
91
4.65k
  video_signal_type_present_flag = false;
92
4.65k
  video_format = VideoFormat_Unspecified;
93
4.65k
  video_full_range_flag = false;
94
4.65k
  colour_description_present_flag = false;
95
4.65k
  colour_primaries = 2;
96
4.65k
  transfer_characteristics = 2;
97
4.65k
  matrix_coeffs = 2;
98
99
  // --- chroma / interlaced ---
100
101
4.65k
  chroma_loc_info_present_flag = false;
102
4.65k
  chroma_sample_loc_type_top_field    = 0;
103
4.65k
  chroma_sample_loc_type_bottom_field = 0;
104
105
4.65k
  neutral_chroma_indication_flag = false;
106
4.65k
  field_seq_flag = false;
107
4.65k
  frame_field_info_present_flag = false;
108
109
  // --- default display window ---
110
111
4.65k
  default_display_window_flag = false;
112
4.65k
  def_disp_win_left_offset   = 0;
113
4.65k
  def_disp_win_right_offset  = 0;
114
4.65k
  def_disp_win_top_offset    = 0;
115
4.65k
  def_disp_win_bottom_offset = 0;
116
117
118
  // --- timing ---
119
120
4.65k
  vui_timing_info_present_flag = false;
121
4.65k
  vui_num_units_in_tick = 0;
122
4.65k
  vui_time_scale = 0;
123
124
4.65k
  vui_poc_proportional_to_timing_flag = false;
125
4.65k
  vui_num_ticks_poc_diff_one = 1;
126
127
128
  // --- hrd parameters ---
129
130
4.65k
  vui_hrd_parameters_present_flag = false;
131
 
132
133
  // --- bitstream restriction ---
134
135
4.65k
  bitstream_restriction_flag = false;
136
4.65k
  tiles_fixed_structure_flag = false;
137
4.65k
  motion_vectors_over_pic_boundaries_flag = true;
138
4.65k
  restricted_ref_pic_lists_flag = false;
139
4.65k
  min_spatial_segmentation_idc = 0;
140
4.65k
  max_bytes_per_pic_denom   = 2;
141
4.65k
  max_bits_per_min_cu_denom = 1;
142
4.65k
  log2_max_mv_length_horizontal = 15;
143
4.65k
  log2_max_mv_length_vertical   = 15;
144
4.65k
}
145
146
147
de265_error video_usability_information::hrd_parameters(error_queue* errqueue, bitreader* br, const seq_parameter_set* sps)
148
98
{
149
98
  int vlc;
150
151
98
  nal_hrd_parameters_present_flag = get_bits(br, 1);
152
98
  vcl_hrd_parameters_present_flag = get_bits(br, 1);
153
154
98
  if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag)
155
3
  {
156
3
    sub_pic_hrd_params_present_flag = get_bits(br, 1);
157
3
    if (sub_pic_hrd_params_present_flag)
158
2
    {
159
2
      tick_divisor_minus2 = get_bits(br, 8);
160
2
      du_cpb_removal_delay_increment_length_minus1 = get_bits(br, 5);
161
2
      sub_pic_cpb_params_in_pic_timing_sei_flag = get_bits(br, 1);
162
2
      dpb_output_delay_du_length_minus1 = get_bits(br, 5);
163
2
    }
164
3
    bit_rate_scale = get_bits(br, 4);
165
3
    cpb_size_scale = get_bits(br, 4);
166
167
168
3
    if (sub_pic_hrd_params_present_flag)
169
2
    {
170
2
      cpb_size_du_scale = get_bits(br, 4);
171
2
    }
172
3
    initial_cpb_removal_delay_length_minus1 = get_bits(br, 5);
173
3
    au_cpb_removal_delay_length_minus1 = get_bits(br, 5);
174
3
    dpb_output_delay_length_minus1 = get_bits(br, 5);
175
3
  }
176
98
  int  i, j, nalOrVcl;
177
178
191
  for (i = 0; i < sps->sps_max_sub_layers; i++)
179
98
  {
180
98
    fixed_pic_rate_general_flag[i] = get_bits(br, 1);
181
98
    if (!fixed_pic_rate_general_flag[i])
182
96
    {
183
96
      fixed_pic_rate_within_cvs_flag[i] = get_bits(br, 1);
184
96
    }
185
2
    else
186
2
    {
187
2
      fixed_pic_rate_within_cvs_flag[i] = true;
188
2
    }
189
190
98
    low_delay_hrd_flag[i] = 0;// Inferred to be 0 when not present
191
98
    cpb_cnt_minus1[i] = 0;    // Inferred to be 0 when not present
192
193
98
    if (fixed_pic_rate_within_cvs_flag[i])
194
3
    {
195
3
      READ_VLC_OFFSET(elemental_duration_in_tc_minus1[i], uvlc, 0);
196
2
    }
197
95
    else
198
95
    {
199
95
      low_delay_hrd_flag[i] = get_bits(br, 1);
200
95
    }
201
97
    if (!low_delay_hrd_flag[i])
202
36
    {
203
36
      READ_VLC_OFFSET(cpb_cnt_minus1[i], uvlc, 0);
204
34
      if (cpb_cnt_minus1[i] > 31) {
205
1
  return DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE;
206
1
      }
207
34
    }
208
209
280
    for (nalOrVcl = 0; nalOrVcl < 2; nalOrVcl++)
210
187
    {
211
187
      if (((nalOrVcl == 0) && nal_hrd_parameters_present_flag) ||
212
186
        ((nalOrVcl == 1) && vcl_hrd_parameters_present_flag))
213
1
      {
214
1
        for (j = 0; j <= cpb_cnt_minus1[i]; j++)
215
1
        {
216
1
          READ_VLC_OFFSET(bit_rate_value_minus1[i][j][nalOrVcl], uvlc, 0);
217
1
          READ_VLC_OFFSET(cpb_size_value_minus1[i][j][nalOrVcl], uvlc, 0);
218
219
0
          if (sub_pic_hrd_params_present_flag)
220
0
          {
221
0
            READ_VLC_OFFSET(cpb_size_du_value_minus1[i][j][nalOrVcl], uvlc, 0);
222
0
            READ_VLC_OFFSET(bit_rate_du_value_minus1[i][j][nalOrVcl], uvlc, 0);
223
0
          }
224
0
          cbr_flag[i][j][nalOrVcl] = get_bits(br, 1);
225
0
        }
226
1
      }
227
187
    }
228
94
  }
229
93
  return DE265_OK;
230
98
}
231
232
de265_error video_usability_information::read(error_queue* errqueue, bitreader* br,
233
                                              const seq_parameter_set* sps)
234
2.86k
{
235
2.86k
  int vlc;
236
237
238
  // --- sample aspect ratio (SAR) ---
239
240
2.86k
  aspect_ratio_info_present_flag = get_bits(br, 1);
241
2.86k
  if (aspect_ratio_info_present_flag) {
242
936
    int aspect_ratio_idc = get_bits(br, 8);
243
936
    if (aspect_ratio_idc <= NUM_SAR_PRESETS) {
244
63
      sar_width = sar_presets[aspect_ratio_idc][0];
245
63
      sar_height = sar_presets[aspect_ratio_idc][1];
246
63
    }
247
873
    else if (aspect_ratio_idc == EXTENDED_SAR) {
248
622
      sar_width = get_bits(br, 16);
249
622
      sar_height = get_bits(br, 16);
250
622
    }
251
251
    else {
252
251
      sar_width = 0;
253
251
      sar_height = 0;
254
251
    }
255
936
  }
256
1.93k
  else {
257
1.93k
    sar_width = 0;
258
1.93k
    sar_height = 0;
259
1.93k
  }
260
261
262
  // --- overscan ---
263
264
2.86k
  overscan_info_present_flag = get_bits(br, 1);
265
2.86k
  if (overscan_info_present_flag) {
266
686
    overscan_appropriate_flag = get_bits(br, 1);
267
686
  }
268
269
270
  // --- video signal type ---
271
272
2.86k
  { // defaults
273
2.86k
    video_format = VideoFormat_Unspecified;
274
2.86k
    video_full_range_flag = false;
275
2.86k
    colour_primaries = 2;
276
2.86k
    transfer_characteristics = 2;
277
2.86k
    matrix_coeffs = 2;
278
2.86k
  }
279
280
2.86k
  video_signal_type_present_flag = get_bits(br, 1);
281
2.86k
  if (video_signal_type_present_flag) {
282
2.71k
    int video_format_idc = get_bits(br, 3);
283
2.71k
    if (video_format_idc > 5) {
284
401
      video_format_idc = VideoFormat_Unspecified;
285
401
    }
286
2.71k
    video_format = (VideoFormat)video_format_idc;
287
288
2.71k
    video_full_range_flag = get_bits(br, 1);
289
290
2.71k
    colour_description_present_flag = get_bits(br, 1);
291
2.71k
    if (colour_description_present_flag) {
292
2.18k
      colour_primaries = get_bits(br, 8);
293
2.18k
      if (colour_primaries == 0 ||
294
2.17k
        colour_primaries == 3 ||
295
2.15k
        colour_primaries >= 11) {
296
869
        colour_primaries = 2;
297
869
      }
298
299
2.18k
      transfer_characteristics = get_bits(br, 8);
300
2.18k
      if (transfer_characteristics == 0 ||
301
1.87k
        transfer_characteristics == 3 ||
302
1.82k
        transfer_characteristics >= 18) {
303
656
        transfer_characteristics = 2;
304
656
      }
305
306
2.18k
      matrix_coeffs = get_bits(br, 8);
307
      
308
2.18k
      if (matrix_coeffs >= 11) {
309
143
        matrix_coeffs = 2;
310
143
      }
311
2.18k
    }
312
2.71k
  }
313
314
315
  // --- chroma / interlaced ---
316
317
2.86k
  chroma_loc_info_present_flag = get_bits(br, 1);
318
2.86k
  if (chroma_loc_info_present_flag) {
319
378
    READ_VLC(chroma_sample_loc_type_top_field, uvlc);
320
377
    READ_VLC(chroma_sample_loc_type_bottom_field, uvlc);
321
376
  }
322
2.49k
  else {
323
2.49k
    chroma_sample_loc_type_top_field = 0;
324
2.49k
    chroma_sample_loc_type_bottom_field = 0;
325
2.49k
  }
326
327
2.86k
  neutral_chroma_indication_flag = get_bits(br, 1);
328
2.86k
  field_seq_flag = get_bits(br, 1);
329
2.86k
  frame_field_info_present_flag = get_bits(br, 1);
330
331
332
  // --- default display window ---
333
334
2.86k
  default_display_window_flag = get_bits(br, 1);
335
2.86k
  if (default_display_window_flag) {
336
266
    READ_VLC(def_disp_win_left_offset, uvlc);
337
265
    READ_VLC(def_disp_win_right_offset, uvlc);
338
264
    READ_VLC(def_disp_win_top_offset, uvlc);
339
263
    READ_VLC(def_disp_win_bottom_offset, uvlc);
340
262
  }
341
2.60k
  else {
342
2.60k
    def_disp_win_left_offset = 0;
343
2.60k
    def_disp_win_right_offset = 0;
344
2.60k
    def_disp_win_top_offset = 0;
345
2.60k
    def_disp_win_bottom_offset = 0;
346
2.60k
  }
347
348
349
  // --- timing ---
350
351
2.86k
  vui_timing_info_present_flag = get_bits(br, 1);
352
2.86k
  if (vui_timing_info_present_flag) {
353
1.77k
    vui_num_units_in_tick = get_bits(br, 32);
354
1.77k
    vui_time_scale = get_bits(br, 32);
355
356
1.77k
    vui_poc_proportional_to_timing_flag = get_bits(br, 1);
357
1.77k
    if (vui_poc_proportional_to_timing_flag) {
358
7
      READ_VLC_OFFSET(vui_num_ticks_poc_diff_one, uvlc, 1);
359
6
    }
360
361
    // --- hrd parameters ---
362
363
1.77k
    vui_hrd_parameters_present_flag = get_bits(br, 1);
364
1.77k
    if (vui_hrd_parameters_present_flag) {
365
98
      de265_error err;
366
98
      err = hrd_parameters(errqueue, br, sps);
367
98
      if (err) {
368
5
  return err;
369
5
      }
370
98
    }
371
1.77k
  }
372
373
  // --- bitstream restriction ---
374
375
2.85k
  bitstream_restriction_flag = get_bits(br,1);
376
2.85k
  if (bitstream_restriction_flag) {
377
205
    tiles_fixed_structure_flag = get_bits(br,1);
378
205
    motion_vectors_over_pic_boundaries_flag = get_bits(br,1);
379
205
    restricted_ref_pic_lists_flag = get_bits(br,1);
380
381
205
    READ_VLC(min_spatial_segmentation_idc, uvlc);
382
203
    if (min_spatial_segmentation_idc > 4095) {
383
1
      errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);
384
1
      min_spatial_segmentation_idc = 0;
385
1
    }
386
387
203
    READ_VLC(max_bytes_per_pic_denom, uvlc);
388
201
    if (max_bytes_per_pic_denom > 16) {
389
10
      errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);
390
10
      max_bytes_per_pic_denom = 2;
391
10
    }
392
393
201
    READ_VLC(max_bits_per_min_cu_denom, uvlc);
394
200
    if (max_bits_per_min_cu_denom > 16) {
395
25
      errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);
396
25
      max_bits_per_min_cu_denom = 1;
397
25
    }
398
399
200
    READ_VLC(log2_max_mv_length_horizontal, uvlc);
400
199
    if (log2_max_mv_length_horizontal > 15) {
401
6
      errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);
402
6
      log2_max_mv_length_horizontal = 15;
403
6
    }
404
405
199
    READ_VLC(log2_max_mv_length_vertical, uvlc);
406
198
    if (log2_max_mv_length_vertical > 15) {
407
18
      errqueue->add_warning(DE265_ERROR_CODED_PARAMETER_OUT_OF_RANGE, false);
408
18
      log2_max_mv_length_vertical = 15;
409
18
    }
410
198
  }
411
2.65k
  else {
412
2.65k
    tiles_fixed_structure_flag = false;
413
2.65k
    motion_vectors_over_pic_boundaries_flag = true;
414
2.65k
    restricted_ref_pic_lists_flag = false; // NOTE: default not specified in standard 2014/10
415
416
2.65k
    min_spatial_segmentation_idc = 0;
417
2.65k
    max_bytes_per_pic_denom   = 2;
418
2.65k
    max_bits_per_min_cu_denom = 1;
419
2.65k
    log2_max_mv_length_horizontal = 15;
420
2.65k
    log2_max_mv_length_vertical   = 15;
421
2.65k
  }
422
423
  //vui_read = true;
424
425
2.85k
  return DE265_OK;
426
2.85k
}
427
428
429
void video_usability_information::dump(int fd) const
430
0
{
431
  //#if (_MSC_VER >= 1500)
432
  //#define LOG0(t) loginfo(LogHeaders, t)
433
  //#define LOG1(t,d) loginfo(LogHeaders, t,d)
434
  //#define LOG2(t,d1,d2) loginfo(LogHeaders, t,d1,d2)
435
  //#define LOG3(t,d1,d2,d3) loginfo(LogHeaders, t,d1,d2,d3)
436
437
0
  FILE* fh;
438
0
  if (fd==1) fh=stdout;
439
0
  else if (fd==2) fh=stderr;
440
0
  else { return; }
441
442
0
#define LOG0(t) log2fh(fh, t)
443
0
#define LOG1(t,d) log2fh(fh, t,d)
444
0
#define LOG2(t,d1,d2) log2fh(fh, t,d1,d2)
445
0
#define LOG3(t,d1,d2,d3) log2fh(fh, t,d1,d2,d3)
446
447
0
  LOG0("----------------- VUI -----------------\n");
448
0
  LOG2("sample aspect ratio        : %d:%d\n", sar_width,sar_height);
449
0
  LOG1("overscan_info_present_flag : %d\n", overscan_info_present_flag);
450
0
  LOG1("overscan_appropriate_flag  : %d\n", overscan_appropriate_flag);
451
452
0
  LOG1("video_signal_type_present_flag: %d\n", video_signal_type_present_flag);
453
0
  if (video_signal_type_present_flag) {
454
0
    LOG1("  video_format                : %s\n", get_video_format_name(video_format));
455
0
    LOG1("  video_full_range_flag       : %d\n", video_full_range_flag);
456
0
    LOG1("  colour_description_present_flag : %d\n", colour_description_present_flag);
457
0
    LOG1("  colour_primaries            : %d\n", colour_primaries);
458
0
    LOG1("  transfer_characteristics    : %d\n", transfer_characteristics);
459
0
    LOG1("  matrix_coeffs               : %d\n", matrix_coeffs);
460
0
  }
461
462
0
  LOG1("chroma_loc_info_present_flag: %d\n", chroma_loc_info_present_flag);
463
0
  if (chroma_loc_info_present_flag) {
464
0
    LOG1("  chroma_sample_loc_type_top_field   : %d\n", chroma_sample_loc_type_top_field);
465
0
    LOG1("  chroma_sample_loc_type_bottom_field: %d\n", chroma_sample_loc_type_bottom_field);
466
0
  }
467
468
0
  LOG1("neutral_chroma_indication_flag: %d\n", neutral_chroma_indication_flag);
469
0
  LOG1("field_seq_flag                : %d\n", field_seq_flag);
470
0
  LOG1("frame_field_info_present_flag : %d\n", frame_field_info_present_flag);
471
472
0
  LOG1("default_display_window_flag   : %d\n", default_display_window_flag);
473
0
  LOG1("  def_disp_win_left_offset    : %d\n", def_disp_win_left_offset);
474
0
  LOG1("  def_disp_win_right_offset   : %d\n", def_disp_win_right_offset);
475
0
  LOG1("  def_disp_win_top_offset     : %d\n", def_disp_win_top_offset);
476
0
  LOG1("  def_disp_win_bottom_offset  : %d\n", def_disp_win_bottom_offset);
477
478
0
  LOG1("vui_timing_info_present_flag  : %d\n", vui_timing_info_present_flag);
479
0
  if (vui_timing_info_present_flag) {
480
0
    LOG1("  vui_num_units_in_tick       : %d\n", vui_num_units_in_tick);
481
0
    LOG1("  vui_time_scale              : %d\n", vui_time_scale);
482
0
  }
483
484
0
  LOG1("vui_poc_proportional_to_timing_flag : %d\n", vui_poc_proportional_to_timing_flag);
485
0
  LOG1("vui_num_ticks_poc_diff_one          : %d\n", vui_num_ticks_poc_diff_one);
486
487
0
  LOG1("vui_hrd_parameters_present_flag : %d\n", vui_hrd_parameters_present_flag);
488
0
  if (vui_hrd_parameters_present_flag) {
489
    //hrd_parameters vui_hrd_parameters;
490
0
  }
491
492
493
  // --- bitstream restriction ---
494
495
0
  LOG1("bitstream_restriction_flag         : %d\n", bitstream_restriction_flag);
496
0
  if (bitstream_restriction_flag) {
497
0
    LOG1("  tiles_fixed_structure_flag       : %d\n", tiles_fixed_structure_flag);
498
0
    LOG1("  motion_vectors_over_pic_boundaries_flag : %d\n", motion_vectors_over_pic_boundaries_flag);
499
0
    LOG1("  restricted_ref_pic_lists_flag    : %d\n", restricted_ref_pic_lists_flag);
500
0
    LOG1("  min_spatial_segmentation_idc     : %d\n", min_spatial_segmentation_idc);
501
0
    LOG1("  max_bytes_per_pic_denom          : %d\n", max_bytes_per_pic_denom);
502
0
    LOG1("  max_bits_per_min_cu_denom        : %d\n", max_bits_per_min_cu_denom);
503
0
    LOG1("  log2_max_mv_length_horizontal    : %d\n", log2_max_mv_length_horizontal);
504
0
    LOG1("  log2_max_mv_length_vertical      : %d\n", log2_max_mv_length_vertical);
505
0
  }
506
507
0
#undef LOG0
508
0
#undef LOG1
509
0
#undef LOG2
510
0
#undef LOG3
511
  //#endif
512
0
}