FFmpeg
hdr_dynamic_metadata.c
Go to the documentation of this file.
1 /**
2  * Copyright (c) 2018 Mohammad Izadi <moh.izadi at gmail.com>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include "avassert.h"
22 #include "hdr_dynamic_metadata.h"
23 #include "mem.h"
24 #include "libavcodec/defs.h"
25 #include "libavcodec/get_bits.h"
26 #include "libavcodec/put_bits.h"
27 
28 static const int64_t luminance_den = 1;
29 static const int32_t peak_luminance_den = 15;
30 static const int64_t rgb_den = 100000;
31 static const int32_t fraction_pixel_den = 1000;
32 static const int32_t knee_point_den = 4095;
33 static const int32_t bezier_anchor_den = 1023;
34 static const int32_t saturation_weight_den = 8;
35 
37 {
38  AVDynamicHDRPlus *hdr_plus = av_mallocz(sizeof(AVDynamicHDRPlus));
39 
40  if (size)
41  *size = hdr_plus ? sizeof(*hdr_plus) : 0;
42 
43  return hdr_plus;
44 }
45 
47 {
50  sizeof(AVDynamicHDRPlus));
51  if (!side_data)
52  return NULL;
53 
54  memset(side_data->data, 0, sizeof(AVDynamicHDRPlus));
55 
56  return (AVDynamicHDRPlus *)side_data->data;
57 }
58 
60  size_t size)
61 {
63  GetBitContext gbc, *gb = &gbc;
64  int ret;
65 
66  if (!s)
67  return AVERROR(ENOMEM);
68 
70  return AVERROR(EINVAL);
71 
72  memcpy(padded_buf, data, size);
73  // Zero-initialize the buffer padding to avoid overreads into uninitialized data.
74  memset(padded_buf + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
75 
76  ret = init_get_bits8(gb, padded_buf, size);
77  if (ret < 0)
78  return ret;
79 
80  if (get_bits_left(gb) < 10)
81  return AVERROR_INVALIDDATA;
82 
83  s->application_version = get_bits(gb, 8);
84  s->num_windows = get_bits(gb, 2);
85 
86  if (s->num_windows < 1 || s->num_windows > 3) {
87  return AVERROR_INVALIDDATA;
88  }
89 
90  if (get_bits_left(gb) < ((19 * 8 + 1) * (s->num_windows - 1)))
91  return AVERROR_INVALIDDATA;
92 
93  for (int w = 1; w < s->num_windows; w++) {
94  // The corners are set to absolute coordinates here. They should be
95  // converted to the relative coordinates (in [0, 1]) in the decoder.
96  AVHDRPlusColorTransformParams *params = &s->params[w];
98  (AVRational){get_bits(gb, 16), 1};
100  (AVRational){get_bits(gb, 16), 1};
102  (AVRational){get_bits(gb, 16), 1};
104  (AVRational){get_bits(gb, 16), 1};
105 
106  params->center_of_ellipse_x = get_bits(gb, 16);
107  params->center_of_ellipse_y = get_bits(gb, 16);
108  params->rotation_angle = get_bits(gb, 8);
109  params->semimajor_axis_internal_ellipse = get_bits(gb, 16);
110  params->semimajor_axis_external_ellipse = get_bits(gb, 16);
111  params->semiminor_axis_external_ellipse = get_bits(gb, 16);
112  params->overlap_process_option = get_bits1(gb);
113  }
114 
115  if (get_bits_left(gb) < 28)
116  return AVERROR_INVALIDDATA;
117 
118  s->targeted_system_display_maximum_luminance =
120  s->targeted_system_display_actual_peak_luminance_flag = get_bits1(gb);
121 
122  if (s->targeted_system_display_actual_peak_luminance_flag) {
123  int rows, cols;
124  if (get_bits_left(gb) < 10)
125  return AVERROR_INVALIDDATA;
126  rows = get_bits(gb, 5);
127  cols = get_bits(gb, 5);
128  if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
129  return AVERROR_INVALIDDATA;
130  }
131  s->num_rows_targeted_system_display_actual_peak_luminance = rows;
132  s->num_cols_targeted_system_display_actual_peak_luminance = cols;
133 
134  if (get_bits_left(gb) < (rows * cols * 4))
135  return AVERROR_INVALIDDATA;
136 
137  for (int i = 0; i < rows; i++) {
138  for (int j = 0; j < cols; j++) {
139  s->targeted_system_display_actual_peak_luminance[i][j] =
141  }
142  }
143  }
144  for (int w = 0; w < s->num_windows; w++) {
145  AVHDRPlusColorTransformParams *params = &s->params[w];
146  if (get_bits_left(gb) < (3 * 17 + 17 + 4))
147  return AVERROR_INVALIDDATA;
148 
149  for (int i = 0; i < 3; i++) {
150  params->maxscl[i] =
151  (AVRational){get_bits(gb, 17), rgb_den};
152  }
153  params->average_maxrgb =
154  (AVRational){get_bits(gb, 17), rgb_den};
156 
157  if (get_bits_left(gb) <
159  return AVERROR_INVALIDDATA;
160 
161  for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) {
162  params->distribution_maxrgb[i].percentage = get_bits(gb, 7);
163  params->distribution_maxrgb[i].percentile =
164  (AVRational){get_bits(gb, 17), rgb_den};
165  }
166 
167  if (get_bits_left(gb) < 10)
168  return AVERROR_INVALIDDATA;
169 
171  }
172  if (get_bits_left(gb) < 1)
173  return AVERROR_INVALIDDATA;
174  s->mastering_display_actual_peak_luminance_flag = get_bits1(gb);
175  if (s->mastering_display_actual_peak_luminance_flag) {
176  int rows, cols;
177  if (get_bits_left(gb) < 10)
178  return AVERROR_INVALIDDATA;
179  rows = get_bits(gb, 5);
180  cols = get_bits(gb, 5);
181  if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
182  return AVERROR_INVALIDDATA;
183  }
184  s->num_rows_mastering_display_actual_peak_luminance = rows;
185  s->num_cols_mastering_display_actual_peak_luminance = cols;
186 
187  if (get_bits_left(gb) < (rows * cols * 4))
188  return AVERROR_INVALIDDATA;
189 
190  for (int i = 0; i < rows; i++) {
191  for (int j = 0; j < cols; j++) {
192  s->mastering_display_actual_peak_luminance[i][j] =
194  }
195  }
196  }
197 
198  for (int w = 0; w < s->num_windows; w++) {
199  AVHDRPlusColorTransformParams *params = &s->params[w];
200  if (get_bits_left(gb) < 1)
201  return AVERROR_INVALIDDATA;
202 
203  params->tone_mapping_flag = get_bits1(gb);
204  if (params->tone_mapping_flag) {
205  if (get_bits_left(gb) < 28)
206  return AVERROR_INVALIDDATA;
207 
208  params->knee_point_x =
209  (AVRational){get_bits(gb, 12), knee_point_den};
210  params->knee_point_y =
211  (AVRational){get_bits(gb, 12), knee_point_den};
212  params->num_bezier_curve_anchors = get_bits(gb, 4);
213 
214  if (get_bits_left(gb) < (params->num_bezier_curve_anchors * 10))
215  return AVERROR_INVALIDDATA;
216 
217  for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
218  params->bezier_curve_anchors[i] =
220  }
221  }
222 
223  if (get_bits_left(gb) < 1)
224  return AVERROR_INVALIDDATA;
226  if (params->color_saturation_mapping_flag) {
227  if (get_bits_left(gb) < 6)
228  return AVERROR_INVALIDDATA;
229  params->color_saturation_weight =
231  }
232  }
233 
234  return 0;
235 }
236 
237 int av_dynamic_hdr_plus_to_t35(const AVDynamicHDRPlus *s, uint8_t **data, size_t *size)
238 {
239  uint8_t *buf;
240  size_t size_bits, size_bytes;
241  PutBitContext pbc, *pb = &pbc;
242 
243  if (!s)
244  return AVERROR(EINVAL);
245  if ((!data || *data) && !size)
246  return AVERROR(EINVAL);
247 
248  /**
249  * Buffer size per CTA-861-H p.253-254:
250  * 48 header bits (excluded from the serialized payload)
251  * 8 bits for application_mode
252  * 2 bits for num_windows
253  * 153 bits for window geometry, for each window above 1
254  * 27 bits for targeted_system_display_maximum_luminance
255  * 1-2511 bits for targeted system display peak luminance information
256  * 82-442 bits per window for pixel distribution information
257  * 1-2511 bits for mastering display peak luminance information
258  * 1-179 bits per window for tonemapping information
259  * 1-7 bits per window for color saturation mapping information
260  * Total: 123-7249 bits, excluding trimmed header bits
261  */
262  size_bits = 8;
263 
264  size_bits += 2;
265 
266  for (int w = 1; w < s->num_windows; w++)
267  size_bits += 153;
268 
269  size_bits += 27;
270 
271  size_bits += 1;
272  if (s->targeted_system_display_actual_peak_luminance_flag)
273  size_bits += 10 +
274  s->num_rows_targeted_system_display_actual_peak_luminance *
275  s->num_cols_targeted_system_display_actual_peak_luminance * 4;
276 
277  for (int w = 0; w < s->num_windows; w++)
278  size_bits += 72 + s->params[w].num_distribution_maxrgb_percentiles * 24 + 10;
279 
280  size_bits += 1;
281  if (s->mastering_display_actual_peak_luminance_flag)
282  size_bits += 10 +
283  s->num_rows_mastering_display_actual_peak_luminance *
284  s->num_cols_mastering_display_actual_peak_luminance * 4;
285 
286  for (int w = 0; w < s->num_windows; w++) {
287  size_bits += 1;
288  if (s->params[w].tone_mapping_flag)
289  size_bits += 28 + s->params[w].num_bezier_curve_anchors * 10;
290 
291  size_bits += 1;
292  if (s->params[w].color_saturation_mapping_flag)
293  size_bits += 6;
294  }
295 
296  size_bytes = (size_bits + 7) / 8;
297 
299 
300  if (!data) {
301  *size = size_bytes;
302  return 0;
303  } else if (*data) {
304  if (*size < size_bytes)
306  buf = *data;
307  } else {
308  buf = av_malloc(size_bytes);
309  if (!buf)
310  return AVERROR(ENOMEM);
311  }
312 
313  init_put_bits(pb, buf, size_bytes);
314 
315  // application_mode is set to Application Version 1
316  put_bits(pb, 8, 1);
317 
318  // Payload as per CTA-861-H p.253-254
319  put_bits(pb, 2, s->num_windows);
320 
321  for (int w = 1; w < s->num_windows; w++) {
322  put_bits(pb, 16, s->params[w].window_upper_left_corner_x.num / s->params[w].window_upper_left_corner_x.den);
323  put_bits(pb, 16, s->params[w].window_upper_left_corner_y.num / s->params[w].window_upper_left_corner_y.den);
324  put_bits(pb, 16, s->params[w].window_lower_right_corner_x.num / s->params[w].window_lower_right_corner_x.den);
325  put_bits(pb, 16, s->params[w].window_lower_right_corner_y.num / s->params[w].window_lower_right_corner_y.den);
326  put_bits(pb, 16, s->params[w].center_of_ellipse_x);
327  put_bits(pb, 16, s->params[w].center_of_ellipse_y);
328  put_bits(pb, 8, s->params[w].rotation_angle);
329  put_bits(pb, 16, s->params[w].semimajor_axis_internal_ellipse);
330  put_bits(pb, 16, s->params[w].semimajor_axis_external_ellipse);
331  put_bits(pb, 16, s->params[w].semiminor_axis_external_ellipse);
332  put_bits(pb, 1, s->params[w].overlap_process_option);
333  }
334 
335  put_bits(pb, 27, s->targeted_system_display_maximum_luminance.num * luminance_den /
336  s->targeted_system_display_maximum_luminance.den);
337  put_bits(pb, 1, s->targeted_system_display_actual_peak_luminance_flag);
338  if (s->targeted_system_display_actual_peak_luminance_flag) {
339  put_bits(pb, 5, s->num_rows_targeted_system_display_actual_peak_luminance);
340  put_bits(pb, 5, s->num_cols_targeted_system_display_actual_peak_luminance);
341  for (int i = 0; i < s->num_rows_targeted_system_display_actual_peak_luminance; i++) {
342  for (int j = 0; j < s->num_cols_targeted_system_display_actual_peak_luminance; j++)
343  put_bits(pb, 4, s->targeted_system_display_actual_peak_luminance[i][j].num * peak_luminance_den /
344  s->targeted_system_display_actual_peak_luminance[i][j].den);
345  }
346  }
347 
348  for (int w = 0; w < s->num_windows; w++) {
349  for (int i = 0; i < 3; i++)
350  put_bits(pb, 17, s->params[w].maxscl[i].num * rgb_den / s->params[w].maxscl[i].den);
351  put_bits(pb, 17, s->params[w].average_maxrgb.num * rgb_den / s->params[w].average_maxrgb.den);
352  put_bits(pb, 4, s->params[w].num_distribution_maxrgb_percentiles);
353  for (int i = 0; i < s->params[w].num_distribution_maxrgb_percentiles; i++) {
354  put_bits(pb, 7, s->params[w].distribution_maxrgb[i].percentage);
355  put_bits(pb, 17, s->params[w].distribution_maxrgb[i].percentile.num * rgb_den /
356  s->params[w].distribution_maxrgb[i].percentile.den);
357  }
358  put_bits(pb, 10, s->params[w].fraction_bright_pixels.num * fraction_pixel_den /
359  s->params[w].fraction_bright_pixels.den);
360  }
361 
362  put_bits(pb, 1, s->mastering_display_actual_peak_luminance_flag);
363  if (s->mastering_display_actual_peak_luminance_flag) {
364  put_bits(pb, 5, s->num_rows_mastering_display_actual_peak_luminance);
365  put_bits(pb, 5, s->num_cols_mastering_display_actual_peak_luminance);
366  for (int i = 0; i < s->num_rows_mastering_display_actual_peak_luminance; i++) {
367  for (int j = 0; j < s->num_cols_mastering_display_actual_peak_luminance; j++)
368  put_bits(pb, 4, s->mastering_display_actual_peak_luminance[i][j].num * peak_luminance_den /
369  s->mastering_display_actual_peak_luminance[i][j].den);
370  }
371  }
372 
373  for (int w = 0; w < s->num_windows; w++) {
374  put_bits(pb, 1, s->params[w].tone_mapping_flag);
375  if (s->params[w].tone_mapping_flag) {
376  put_bits(pb, 12, s->params[w].knee_point_x.num * knee_point_den / s->params[w].knee_point_x.den);
377  put_bits(pb, 12, s->params[w].knee_point_y.num * knee_point_den / s->params[w].knee_point_y.den);
378  put_bits(pb, 4, s->params[w].num_bezier_curve_anchors);
379  for (int i = 0; i < s->params[w].num_bezier_curve_anchors; i++)
380  put_bits(pb, 10, s->params[w].bezier_curve_anchors[i].num * bezier_anchor_den /
381  s->params[w].bezier_curve_anchors[i].den);
382  put_bits(pb, 1, s->params[w].color_saturation_mapping_flag);
383  if (s->params[w].color_saturation_mapping_flag)
384  put_bits(pb, 6, s->params[w].color_saturation_weight.num * saturation_weight_den /
385  s->params[w].color_saturation_weight.den);
386  }
387  }
388 
389  flush_put_bits(pb);
390 
391  *data = buf;
392  if (size)
393  *size = size_bytes;
394  return 0;
395 }
396 
398 {
400 
401  if (size)
402  *size = smpte2094_app5 ? sizeof(*smpte2094_app5) : 0;
403 
404  return smpte2094_app5;
405 }
406 
408 {
411  sizeof(AVDynamicHDRSmpte2094App5));
412  if (!side_data)
413  return NULL;
414 
415  memset(side_data->data, 0, sizeof(AVDynamicHDRSmpte2094App5));
416 
417  return (AVDynamicHDRSmpte2094App5 *)side_data->data;
418 }
419 
420 #define GET_BITS_OR_FAIL(var, n) \
421  do { \
422  if (get_bits_left(gb) < n) { \
423  ret = AVERROR_INVALIDDATA; \
424  goto end; \
425  } \
426  var = get_bits(gb, n); \
427  } while (0)
428 
430  size_t size)
431 {
432  GetBitContext gbc, *gb = &gbc;
433  int ret, reserved_zero;
434  size_t padded_size = size + AV_INPUT_BUFFER_PADDING_SIZE;
435 
436  if (!s)
437  return AVERROR(EINVAL);
438 
439  uint8_t *padded_data = av_mallocz(padded_size);
440  if (!padded_data)
441  return AVERROR(ENOMEM);
442 
443  memcpy(padded_data, data, size);
444  ret = init_get_bits8(gb, padded_data, size);
445  if (ret < 0)
446  goto end;
447 
448  // Table C.1
449  GET_BITS_OR_FAIL(s->application_version, 3);
450  GET_BITS_OR_FAIL(s->minimum_application_version, 3);
451  GET_BITS_OR_FAIL(reserved_zero, 2);
452  if (reserved_zero) {
454  goto end;
455  }
456 
457  // Table C.2
458  GET_BITS_OR_FAIL(s->has_custom_hdr_reference_white_flag, 1);
459  GET_BITS_OR_FAIL(s->has_adaptive_tone_map_flag, 1);
460  GET_BITS_OR_FAIL(reserved_zero, 6);
461  if (reserved_zero) {
463  goto end;
464  }
465  if (s->has_custom_hdr_reference_white_flag)
466  GET_BITS_OR_FAIL(s->hdr_reference_white, 16);
467  if (!s->has_adaptive_tone_map_flag) {
468  ret = 0;
469  goto end;
470  }
471 
472  // Table C.3
473  GET_BITS_OR_FAIL(s->baseline_hdr_headroom, 16);
474  GET_BITS_OR_FAIL(s->use_reference_white_tone_mapping_flag, 1);
475  if (s->use_reference_white_tone_mapping_flag) {
476  GET_BITS_OR_FAIL(reserved_zero, 7);
477  ret = reserved_zero ? AVERROR_INVALIDDATA : 0;
478  goto end;
479  }
480  GET_BITS_OR_FAIL(s->num_alternate_images, 3);
481  if (s->num_alternate_images > 4) {
483  goto end;
484  }
485  GET_BITS_OR_FAIL(s->gain_application_space_chromaticities_flag, 2);
486  GET_BITS_OR_FAIL(s->has_common_component_mix_params_flag, 1);
487  GET_BITS_OR_FAIL(s->has_common_curve_params_flag, 1);
488  if (s->gain_application_space_chromaticities_flag == 3)
489  for (int r = 0; r < 8; r++)
490  GET_BITS_OR_FAIL(s->gain_application_space_chromaticities[r], 16);
491 
492  for (int a = 0; a < s->num_alternate_images; a++) {
493  GET_BITS_OR_FAIL(s->alternate_hdr_headrooms[a], 16);
494 
495  // Table C.4
496  if (!a || !s->has_common_component_mix_params_flag) {
497  GET_BITS_OR_FAIL(s->component_mixing_type[a], 2);
498  if (s->component_mixing_type[a] != 3) {
499  GET_BITS_OR_FAIL(reserved_zero, 6);
500  if (reserved_zero) {
502  goto end;
503  }
504  } else {
505  for (int k = 0; k < 6; k++)
506  GET_BITS_OR_FAIL(s->has_component_mixing_coefficient_flag[a][k], 1);
507  for (int k = 0; k < 6; k++) {
508  if (s->has_component_mixing_coefficient_flag[a][k]) {
509  GET_BITS_OR_FAIL(s->component_mixing_coefficient[a][k], 16);
510  } else {
511  s->component_mixing_coefficient[a][k] = 0;
512  }
513  }
514  }
515  } else {
516  s->component_mixing_type[a] = s->component_mixing_type[0];
517  if (s->component_mixing_type[a] == 3) {
518  for (int k = 0; k < 6; k++) {
519  s->has_component_mixing_coefficient_flag[a][k] =
520  s->has_component_mixing_coefficient_flag[0][k];
521  s->component_mixing_coefficient[a][k] = s->component_mixing_coefficient[0][k];
522  }
523  }
524  }
525 
526  // Table C.5
527  if (!a || !s->has_common_curve_params_flag) {
528  GET_BITS_OR_FAIL(s->gain_curve_num_control_points_minus_1[a], 5);
529  if (s->gain_curve_num_control_points_minus_1[a] > 31) {
531  goto end;
532  }
533  GET_BITS_OR_FAIL(s->gain_curve_use_pchip_slope_flag[a], 1);
534  GET_BITS_OR_FAIL(reserved_zero, 2);
535  if (reserved_zero) {
537  goto end;
538  }
539  for (int c = 0; c <= s->gain_curve_num_control_points_minus_1[a]; c++) {
540  GET_BITS_OR_FAIL(s->gain_curve_control_points_x[a][c], 16);
541  }
542  } else {
543  s->gain_curve_num_control_points_minus_1[a] =
544  s->gain_curve_num_control_points_minus_1[0];
545  s->gain_curve_use_pchip_slope_flag[a] = s->gain_curve_use_pchip_slope_flag[0];
546  for (int c = 0; c <= s->gain_curve_num_control_points_minus_1[a]; c++) {
547  s->gain_curve_control_points_x[a][c] = s->gain_curve_control_points_x[0][c];
548  }
549  }
550  for (int c = 0; c <= s->gain_curve_num_control_points_minus_1[a]; c++)
551  GET_BITS_OR_FAIL(s->gain_curve_control_points_y[a][c], 16);
552  if (!s->gain_curve_use_pchip_slope_flag[a]) {
553  for (int c = 0; c <= s->gain_curve_num_control_points_minus_1[a]; c++)
554  GET_BITS_OR_FAIL(s->gain_curve_control_points_theta[a][c], 16);
555  }
556  }
557  ret = 0;
558 end:
559  av_free(padded_data);
560  return ret;
561 }
562 
564  size_t *size)
565 {
566  uint8_t *buf;
567  size_t size_bytes, size_bits;
568  PutBitContext pbc, *pb = &pbc;
569 
570  if (!s)
571  return AVERROR(EINVAL);
572  if ((!data || *data) && !size)
573  return AVERROR(EINVAL);
574 
575  if (s->application_version >= 8 || s->minimum_application_version >= 3)
576  return AVERROR_INVALIDDATA;
577  size_bits = 0;
578  size_bits += 3 + 3 + 2;
579  size_bits += 1 + 1 + 6;
580  if (s->has_custom_hdr_reference_white_flag)
581  size_bits += 16;
582  if (s->has_adaptive_tone_map_flag) {
583  size_bits += 16 + 1;
584  if (s->use_reference_white_tone_mapping_flag) {
585  size_bits += 7;
586  } else {
587  size_bits += 3 + 2 + 1 + 1;
588  if (s->gain_application_space_chromaticities_flag == 3)
589  size_bits += 16 * 8;
590  if (s->num_alternate_images > 4)
591  return AVERROR_INVALIDDATA;
592  for (int a = 0; a < s->num_alternate_images; a++) {
593  size_bits += 16;
594  if (!a || !s->has_common_component_mix_params_flag) {
595  size_bits += 2;
596  if (s->component_mixing_type[a] != 3) {
597  size_bits += 6;
598  } else {
599  size_bits += 6;
600  for (int k = 0; k < 6; k++)
601  if (s->has_component_mixing_coefficient_flag[a][k])
602  size_bits += 16;
603  }
604  }
605  if (!a || !s->has_common_curve_params_flag) {
606  size_bits += 5 + 1 + 2;
607  if (s->gain_curve_num_control_points_minus_1[a] > 31)
608  return AVERROR_INVALIDDATA;
609  size_bits += 16 * (s->gain_curve_num_control_points_minus_1[a] + 1);
610  }
611  size_bits += 16 * (s->gain_curve_num_control_points_minus_1[a] + 1);
612  if (!s->gain_curve_use_pchip_slope_flag[a])
613  size_bits += 16 * (s->gain_curve_num_control_points_minus_1[a] + 1);
614  }
615  }
616  }
617  if (size_bits % 8)
618  return AVERROR_INVALIDDATA;
619  size_bytes = size_bits >> 3;
620 
621  if (!data) {
622  *size = size_bytes;
623  return 0;
624  } else if (*data) {
625  if (*size < size_bytes)
627  buf = *data;
628  } else {
629  buf = av_malloc(size_bytes);
630  if (!buf)
631  return AVERROR(ENOMEM);
632  }
633 
634  init_put_bits(pb, buf, size_bytes);
635 
636  // Table C.1
637  put_bits(pb, 3, s->application_version);
638  put_bits(pb, 3, s->minimum_application_version);
639  put_bits(pb, 2, 0); // reserved_zero
640 
641  // Table C.2
642  put_bits(pb, 1, s->has_custom_hdr_reference_white_flag);
643  put_bits(pb, 1, s->has_adaptive_tone_map_flag);
644  put_bits(pb, 6, 0); // reserved_zero
645 
646  if (s->has_custom_hdr_reference_white_flag)
647  put_bits(pb, 16, s->hdr_reference_white);
648 
649  if (s->has_adaptive_tone_map_flag) {
650  // Table C.3
651  put_bits(pb, 16, s->baseline_hdr_headroom);
652  put_bits(pb, 1, s->use_reference_white_tone_mapping_flag);
653  if (s->use_reference_white_tone_mapping_flag) {
654  put_bits(pb, 7, 0); // reserved_zero
655  } else {
656  put_bits(pb, 3, s->num_alternate_images);
657  put_bits(pb, 2, s->gain_application_space_chromaticities_flag);
658  put_bits(pb, 1, s->has_common_component_mix_params_flag);
659  put_bits(pb, 1, s->has_common_curve_params_flag);
660 
661  if (s->gain_application_space_chromaticities_flag == 3)
662  for (int r = 0; r < 8; r++)
663  put_bits(pb, 16, s->gain_application_space_chromaticities[r]);
664 
665  for (int a = 0; a < s->num_alternate_images; a++) {
666  put_bits(pb, 16, s->alternate_hdr_headrooms[a]);
667 
668  // Table C.4
669  if (!a || !s->has_common_component_mix_params_flag) {
670  put_bits(pb, 2, s->component_mixing_type[a]);
671  if (s->component_mixing_type[a] != 3) {
672  put_bits(pb, 6, 0); // reserved_zero
673  } else {
674  for (int k = 0; k < 6; k++)
675  put_bits(pb, 1, s->has_component_mixing_coefficient_flag[a][k]);
676  for (int k = 0; k < 6; k++)
677  if (s->has_component_mixing_coefficient_flag[a][k])
678  put_bits(pb, 16, s->component_mixing_coefficient[a][k]);
679  }
680  }
681 
682  // Table C.5
683  if (!a || !s->has_common_curve_params_flag) {
684  put_bits(pb, 5, s->gain_curve_num_control_points_minus_1[a]);
685  put_bits(pb, 1, s->gain_curve_use_pchip_slope_flag[a]);
686  put_bits(pb, 2, 0); // reserved_zero
687  for (int c = 0; c <= s->gain_curve_num_control_points_minus_1[a]; c++)
688  put_bits(pb, 16, s->gain_curve_control_points_x[a][c]);
689  }
690  for (int c = 0; c <= s->gain_curve_num_control_points_minus_1[a]; c++)
691  put_bits(pb, 16, s->gain_curve_control_points_y[a][c]);
692  if (!s->gain_curve_use_pchip_slope_flag[a]) {
693  for (int c = 0; c <= s->gain_curve_num_control_points_minus_1[a]; c++)
694  put_bits(pb, 16, s->gain_curve_control_points_theta[a][c]);
695  }
696  }
697  }
698  }
699 
700  flush_put_bits(pb);
701 
702  *data = buf;
703  if (size)
704  *size = size_bytes;
705  return 0;
706 }
AVHDRPlusColorTransformParams::average_maxrgb
AVRational average_maxrgb
The average of linearized maxRGB values in the processing window in the scene.
Definition: hdr_dynamic_metadata.h:164
get_bits_left
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:688
r
const char * r
Definition: vf_curves.c:127
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
av_dynamic_hdr_smpte2094_app5_to_t35
int av_dynamic_hdr_smpte2094_app5_to_t35(const AVDynamicHDRSmpte2094App5 *s, uint8_t **data, size_t *size)
Serialize dynamic SMPTE-2094-50 metadata to a ITU-T T.35 message.
Definition: hdr_dynamic_metadata.c:563
AVHDRPlusColorTransformParams::rotation_angle
uint8_t rotation_angle
The clockwise rotation angle in degree of arc with respect to the positive direction of the x-axis of...
Definition: hdr_dynamic_metadata.h:118
av_frame_new_side_data
AVFrameSideData * av_frame_new_side_data(AVFrame *frame, enum AVFrameSideDataType type, size_t size)
Add a new side data to a frame.
Definition: frame.c:647
AVHDRPlusPercentile::percentile
AVRational percentile
The linearized maxRGB value at a specific percentile in the processing window in the scene.
Definition: hdr_dynamic_metadata.h:52
get_bits_long
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:424
int64_t
long long int64_t
Definition: coverity.c:34
init_put_bits
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition: put_bits.h:62
AVHDRPlusColorTransformParams::semimajor_axis_external_ellipse
uint16_t semimajor_axis_external_ellipse
The semi-major axis value of the external ellipse of the elliptical pixel selector in amount of pixel...
Definition: hdr_dynamic_metadata.h:134
AVHDRPlusColorTransformParams
Color transform parameters at a processing window in a dynamic metadata for SMPTE 2094-40.
Definition: hdr_dynamic_metadata.h:59
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:466
put_bits
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:154
av_dynamic_hdr_plus_to_t35
int av_dynamic_hdr_plus_to_t35(const AVDynamicHDRPlus *s, uint8_t **data, size_t *size)
Serialize dynamic HDR10+ metadata to a user data registered ITU-T T.35 buffer, excluding the first 48...
Definition: hdr_dynamic_metadata.c:237
data
const char data[16]
Definition: mxf.c:149
GET_BITS_OR_FAIL
#define GET_BITS_OR_FAIL(var, n)
Definition: hdr_dynamic_metadata.c:420
AVHDRPlusColorTransformParams::tone_mapping_flag
uint8_t tone_mapping_flag
This flag indicates that the metadata for the tone mapping function in the processing window is prese...
Definition: hdr_dynamic_metadata.h:189
luminance_den
static const int64_t luminance_den
Copyright (c) 2018 Mohammad Izadi <moh.izadi at gmail.com>
Definition: hdr_dynamic_metadata.c:28
AVHDRPlusColorTransformParams::distribution_maxrgb
AVHDRPlusPercentile distribution_maxrgb[15]
The linearized maxRGB values at given percentiles in the processing window in the scene.
Definition: hdr_dynamic_metadata.h:176
AVHDRPlusColorTransformParams::knee_point_x
AVRational knee_point_x
The x coordinate of the separation point between the linear part and the curved part of the tone mapp...
Definition: hdr_dynamic_metadata.h:196
av_dynamic_hdr_smpte2094_app5_alloc
AVDynamicHDRSmpte2094App5 * av_dynamic_hdr_smpte2094_app5_alloc(size_t *size)
Allocate an AVDynamicHDRSmpte2094App5 structure and set its fields to default values.
Definition: hdr_dynamic_metadata.c:397
get_bits
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:337
AVHDRPlusColorTransformParams::color_saturation_mapping_flag
uint8_t color_saturation_mapping_flag
This flag shall be equal to 0 in bitstreams conforming to this version of this Specification.
Definition: hdr_dynamic_metadata.h:222
AVHDRPlusColorTransformParams::center_of_ellipse_x
uint16_t center_of_ellipse_x
The x coordinate of the center position of the concentric internal and external ellipses of the ellip...
Definition: hdr_dynamic_metadata.h:102
GetBitContext
Definition: get_bits.h:109
AVERROR_BUFFER_TOO_SMALL
#define AVERROR_BUFFER_TOO_SMALL
Buffer too small.
Definition: error.h:53
AVHDRPlusColorTransformParams::knee_point_y
AVRational knee_point_y
The y coordinate of the separation point between the linear part and the curved part of the tone mapp...
Definition: hdr_dynamic_metadata.h:203
AVHDRPlusColorTransformParams::num_bezier_curve_anchors
uint8_t num_bezier_curve_anchors
The number of the intermediate anchor parameters of the tone mapping function in the processing windo...
Definition: hdr_dynamic_metadata.h:209
avassert.h
init_get_bits8
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:544
s
#define s(width, name)
Definition: cbs_vp9.c:198
AVHDRPlusColorTransformParams::semiminor_axis_external_ellipse
uint16_t semiminor_axis_external_ellipse
The semi-minor axis value of the external ellipse of the elliptical pixel selector in amount of pixel...
Definition: hdr_dynamic_metadata.h:141
AVHDRPlusColorTransformParams::window_upper_left_corner_y
AVRational window_upper_left_corner_y
The relative y coordinate of the top left pixel of the processing window.
Definition: hdr_dynamic_metadata.h:76
AVHDRPlusColorTransformParams::window_lower_right_corner_x
AVRational window_lower_right_corner_x
The relative x coordinate of the bottom right pixel of the processing window.
Definition: hdr_dynamic_metadata.h:85
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
get_bits.h
AV_FRAME_DATA_DYNAMIC_HDR_SMPTE_2094_APP5
@ AV_FRAME_DATA_DYNAMIC_HDR_SMPTE_2094_APP5
HDR dynamic metadata associated with a video frame.
Definition: frame.h:270
av_mallocz
#define av_mallocz(s)
Definition: tableprint_vlc.h:31
PutBitContext
Definition: put_bits.h:50
AVHDRPlusPercentile::percentage
uint8_t percentage
The percentage value corresponding to a specific percentile linearized RGB value in the processing wi...
Definition: hdr_dynamic_metadata.h:45
if
if(ret)
Definition: filter_design.txt:179
NULL
#define NULL
Definition: coverity.c:32
AVDynamicHDRSmpte2094App5
This struct represents dynamic metadata for color volume transform as specified in the SMPTE 2094-50 ...
Definition: hdr_dynamic_metadata.h:387
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
get_bits1
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:391
AVHDRPlusColorTransformParams::fraction_bright_pixels
AVRational fraction_bright_pixels
The fraction of selected pixels in the image that contains the brightest pixel in the scene.
Definition: hdr_dynamic_metadata.h:183
AVHDRPlusColorTransformParams::color_saturation_weight
AVRational color_saturation_weight
The color saturation gain in the processing window in the scene.
Definition: hdr_dynamic_metadata.h:229
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
size
int size
Definition: twinvq_data.h:10344
AVFrameSideData::data
uint8_t * data
Definition: frame.h:323
AVHDRPlusColorTransformParams::window_lower_right_corner_y
AVRational window_lower_right_corner_y
The relative y coordinate of the bottom right pixel of the processing window.
Definition: hdr_dynamic_metadata.h:94
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
AVHDRPlusColorTransformParams::window_upper_left_corner_x
AVRational window_upper_left_corner_x
The relative x coordinate of the top left pixel of the processing window.
Definition: hdr_dynamic_metadata.h:67
AVHDRPlusColorTransformParams::semimajor_axis_internal_ellipse
uint16_t semimajor_axis_internal_ellipse
The semi-major axis value of the internal ellipse of the elliptical pixel selector in amount of pixel...
Definition: hdr_dynamic_metadata.h:125
av_dynamic_hdr_smpte2094_app5_create_side_data
AVDynamicHDRSmpte2094App5 * av_dynamic_hdr_smpte2094_app5_create_side_data(AVFrame *frame)
Allocate a complete AVDynamicHDRSmpte2094App5 and add it to the frame.
Definition: hdr_dynamic_metadata.c:407
av_malloc
#define av_malloc(s)
Definition: ops_asmgen.c:44
fraction_pixel_den
static const int32_t fraction_pixel_den
Definition: hdr_dynamic_metadata.c:31
AVHDRPlusColorTransformParams::overlap_process_option
enum AVHDRPlusOverlapProcessOption overlap_process_option
Overlap process option indicates one of the two methods of combining rendered pixels in the processin...
Definition: hdr_dynamic_metadata.h:149
AVDynamicHDRPlus
This struct represents dynamic metadata for color volume transform - application 4 of SMPTE 2094-40:2...
Definition: hdr_dynamic_metadata.h:243
av_dynamic_hdr_plus_create_side_data
AVDynamicHDRPlus * av_dynamic_hdr_plus_create_side_data(AVFrame *frame)
Allocate a complete AVDynamicHDRPlus and add it to the frame.
Definition: hdr_dynamic_metadata.c:46
ret
ret
Definition: filter_design.txt:187
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
knee_point_den
static const int32_t knee_point_den
Definition: hdr_dynamic_metadata.c:32
AV_INPUT_BUFFER_PADDING_SIZE
#define AV_INPUT_BUFFER_PADDING_SIZE
Definition: defs.h:40
AV_FRAME_DATA_DYNAMIC_HDR_PLUS
@ AV_FRAME_DATA_DYNAMIC_HDR_PLUS
HDR dynamic metadata associated with a video frame.
Definition: frame.h:159
AV_HDR_PLUS_MAX_PAYLOAD_SIZE
#define AV_HDR_PLUS_MAX_PAYLOAD_SIZE
Definition: hdr_dynamic_metadata.h:356
defs.h
peak_luminance_den
static const int32_t peak_luminance_den
Definition: hdr_dynamic_metadata.c:29
AVHDRPlusColorTransformParams::num_distribution_maxrgb_percentiles
uint8_t num_distribution_maxrgb_percentiles
The number of linearized maxRGB values at given percentiles in the processing window in the scene.
Definition: hdr_dynamic_metadata.h:170
AVHDRPlusColorTransformParams::maxscl
AVRational maxscl[3]
The maximum of the color components of linearized RGB values in the processing window in the scene.
Definition: hdr_dynamic_metadata.h:157
hdr_dynamic_metadata.h
AVHDRPlusColorTransformParams::center_of_ellipse_y
uint16_t center_of_ellipse_y
The y coordinate of the center position of the concentric internal and external ellipses of the ellip...
Definition: hdr_dynamic_metadata.h:110
mem.h
AVFrameSideData
Structure to hold side data for an AVFrame.
Definition: frame.h:321
flush_put_bits
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:153
rgb_den
static const int64_t rgb_den
Definition: hdr_dynamic_metadata.c:30
w
uint8_t w
Definition: llvidencdsp.c:39
av_dynamic_hdr_plus_alloc
AVDynamicHDRPlus * av_dynamic_hdr_plus_alloc(size_t *size)
Allocate an AVDynamicHDRPlus structure and set its fields to default values.
Definition: hdr_dynamic_metadata.c:36
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
av_dynamic_hdr_plus_from_t35
int av_dynamic_hdr_plus_from_t35(AVDynamicHDRPlus *s, const uint8_t *data, size_t size)
Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRPlus).
Definition: hdr_dynamic_metadata.c:59
int32_t
int32_t
Definition: audioconvert.c:56
bezier_anchor_den
static const int32_t bezier_anchor_den
Definition: hdr_dynamic_metadata.c:33
saturation_weight_den
static const int32_t saturation_weight_den
Definition: hdr_dynamic_metadata.c:34
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
put_bits.h
av_dynamic_hdr_smpte2094_app5_from_t35
int av_dynamic_hdr_smpte2094_app5_from_t35(AVDynamicHDRSmpte2094App5 *s, const uint8_t *data, size_t size)
Parse the user data formatted as ITU-T T.35 message to AVDynamicHDRSmpte2094App5.
Definition: hdr_dynamic_metadata.c:429
AVHDRPlusColorTransformParams::bezier_curve_anchors
AVRational bezier_curve_anchors[15]
The intermediate anchor parameters of the tone mapping function in the processing window in the scene...
Definition: hdr_dynamic_metadata.h:216