FFmpeg  4.4.5
dynamic_hdr10_plus.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "dynamic_hdr10_plus.h"
20 #include "get_bits.h"
21 
22 static const int64_t luminance_den = 1;
23 static const int32_t peak_luminance_den = 15;
24 static const int64_t rgb_den = 100000;
25 static const int32_t fraction_pixel_den = 1000;
26 static const int32_t knee_point_den = 4095;
27 static const int32_t bezier_anchor_den = 1023;
28 static const int32_t saturation_weight_den = 8;
29 
31  int size)
32 {
33  GetBitContext gbc, *gb = &gbc;
34  int ret;
35 
36  if (!s)
37  return AVERROR(ENOMEM);
38 
39  ret = init_get_bits8(gb, data, size);
40  if (ret < 0)
41  return ret;
42 
43  s->application_version = get_bits(gb, 8);
44 
45  if (get_bits_left(gb) < 2)
46  return AVERROR_INVALIDDATA;
47  s->num_windows = get_bits(gb, 2);
48 
49  if (s->num_windows < 1 || s->num_windows > 3) {
50  return AVERROR_INVALIDDATA;
51  }
52 
53  if (get_bits_left(gb) < ((19 * 8 + 1) * (s->num_windows - 1)))
54  return AVERROR_INVALIDDATA;
55 
56  for (int w = 1; w < s->num_windows; w++) {
57  // The corners are set to absolute coordinates here. They should be
58  // converted to the relative coordinates (in [0, 1]) in the decoder.
59  AVHDRPlusColorTransformParams *params = &s->params[w];
61  (AVRational){get_bits(gb, 16), 1};
63  (AVRational){get_bits(gb, 16), 1};
65  (AVRational){get_bits(gb, 16), 1};
67  (AVRational){get_bits(gb, 16), 1};
68 
69  params->center_of_ellipse_x = get_bits(gb, 16);
70  params->center_of_ellipse_y = get_bits(gb, 16);
71  params->rotation_angle = get_bits(gb, 8);
72  params->semimajor_axis_internal_ellipse = get_bits(gb, 16);
73  params->semimajor_axis_external_ellipse = get_bits(gb, 16);
74  params->semiminor_axis_external_ellipse = get_bits(gb, 16);
75  params->overlap_process_option = get_bits1(gb);
76  }
77 
78  if (get_bits_left(gb) < 28)
79  return AVERROR(EINVAL);
80 
81  s->targeted_system_display_maximum_luminance =
83  s->targeted_system_display_actual_peak_luminance_flag = get_bits1(gb);
84 
85  if (s->targeted_system_display_actual_peak_luminance_flag) {
86  int rows, cols;
87  if (get_bits_left(gb) < 10)
88  return AVERROR(EINVAL);
89  rows = get_bits(gb, 5);
90  cols = get_bits(gb, 5);
91  if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
92  return AVERROR_INVALIDDATA;
93  }
94  s->num_rows_targeted_system_display_actual_peak_luminance = rows;
95  s->num_cols_targeted_system_display_actual_peak_luminance = cols;
96 
97  if (get_bits_left(gb) < (rows * cols * 4))
98  return AVERROR(EINVAL);
99 
100  for (int i = 0; i < rows; i++) {
101  for (int j = 0; j < cols; j++) {
102  s->targeted_system_display_actual_peak_luminance[i][j] =
104  }
105  }
106  }
107  for (int w = 0; w < s->num_windows; w++) {
108  AVHDRPlusColorTransformParams *params = &s->params[w];
109  if (get_bits_left(gb) < (3 * 17 + 17 + 4))
110  return AVERROR(EINVAL);
111 
112  for (int i = 0; i < 3; i++) {
113  params->maxscl[i] =
114  (AVRational){get_bits(gb, 17), rgb_den};
115  }
116  params->average_maxrgb =
117  (AVRational){get_bits(gb, 17), rgb_den};
119 
120  if (get_bits_left(gb) <
122  return AVERROR(EINVAL);
123 
124  for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) {
125  params->distribution_maxrgb[i].percentage = get_bits(gb, 7);
126  params->distribution_maxrgb[i].percentile =
127  (AVRational){get_bits(gb, 17), rgb_den};
128  }
129 
130  if (get_bits_left(gb) < 10)
131  return AVERROR(EINVAL);
132 
134  }
135  if (get_bits_left(gb) < 1)
136  return AVERROR(EINVAL);
137  s->mastering_display_actual_peak_luminance_flag = get_bits1(gb);
138  if (s->mastering_display_actual_peak_luminance_flag) {
139  int rows, cols;
140  if (get_bits_left(gb) < 10)
141  return AVERROR(EINVAL);
142  rows = get_bits(gb, 5);
143  cols = get_bits(gb, 5);
144  if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
145  return AVERROR_INVALIDDATA;
146  }
147  s->num_rows_mastering_display_actual_peak_luminance = rows;
148  s->num_cols_mastering_display_actual_peak_luminance = cols;
149 
150  if (get_bits_left(gb) < (rows * cols * 4))
151  return AVERROR(EINVAL);
152 
153  for (int i = 0; i < rows; i++) {
154  for (int j = 0; j < cols; j++) {
155  s->mastering_display_actual_peak_luminance[i][j] =
157  }
158  }
159  }
160 
161  for (int w = 0; w < s->num_windows; w++) {
162  AVHDRPlusColorTransformParams *params = &s->params[w];
163  if (get_bits_left(gb) < 1)
164  return AVERROR(EINVAL);
165 
166  params->tone_mapping_flag = get_bits1(gb);
167  if (params->tone_mapping_flag) {
168  if (get_bits_left(gb) < 28)
169  return AVERROR(EINVAL);
170 
171  params->knee_point_x =
172  (AVRational){get_bits(gb, 12), knee_point_den};
173  params->knee_point_y =
174  (AVRational){get_bits(gb, 12), knee_point_den};
175  params->num_bezier_curve_anchors = get_bits(gb, 4);
176 
177  if (get_bits_left(gb) < (params->num_bezier_curve_anchors * 10))
178  return AVERROR(EINVAL);
179 
180  for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
181  params->bezier_curve_anchors[i] =
183  }
184  }
185 
186  if (get_bits_left(gb) < 1)
187  return AVERROR(EINVAL);
189  if (params->color_saturation_mapping_flag) {
190  if (get_bits_left(gb) < 6)
191  return AVERROR(EINVAL);
192  params->color_saturation_weight =
194  }
195  }
196 
197  return 0;
198 }
uint8_t
int32_t
#define s(width, name)
Definition: cbs_vp9.c:257
long long int64_t
Definition: coverity.c:34
static const int64_t rgb_den
static const int32_t peak_luminance_den
int ff_parse_itu_t_t35_to_dynamic_hdr10_plus(AVDynamicHDRPlus *s, const uint8_t *data, int size)
Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRPlus).
static const int32_t bezier_anchor_den
static const int32_t fraction_pixel_den
static const int32_t knee_point_den
static const int32_t saturation_weight_den
static const int64_t luminance_den
bitstream reader API header.
static unsigned int get_bits_long(GetBitContext *s, int n)
Read 0-32 bits.
Definition: get_bits.h:546
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AVERROR(e)
Definition: error.h:43
int i
Definition: input.c:407
uint8_t w
Definition: llviddspenc.c:39
const char data[16]
Definition: mxf.c:142
This struct represents dynamic metadata for color volume transform - application 4 of SMPTE 2094-40:2...
Color transform parameters at a processing window in a dynamic metadata for SMPTE 2094-40.
uint8_t tone_mapping_flag
This flag indicates that the metadata for the tone mapping function in the processing window is prese...
AVRational window_lower_right_corner_y
The relative y coordinate of the bottom right pixel of the processing window.
AVRational fraction_bright_pixels
The fraction of selected pixels in the image that contains the brightest pixel in the scene.
uint8_t rotation_angle
The clockwise rotation angle in degree of arc with respect to the positive direction of the x-axis of...
AVRational knee_point_y
The y coordinate of the separation point between the linear part and the curved part of the tone mapp...
uint16_t semimajor_axis_internal_ellipse
The semi-major axis value of the internal ellipse of the elliptical pixel selector in amount of pixel...
AVRational average_maxrgb
The average of linearized maxRGB values in the processing window in the scene.
uint16_t center_of_ellipse_x
The x coordinate of the center position of the concentric internal and external ellipses of the ellip...
AVRational maxscl[3]
The maximum of the color components of linearized RGB values in the processing window in the scene.
uint16_t semimajor_axis_external_ellipse
The semi-major axis value of the external ellipse of the elliptical pixel selector in amount of pixel...
AVHDRPlusPercentile distribution_maxrgb[15]
The linearized maxRGB values at given percentiles in the processing window in the scene.
AVRational window_lower_right_corner_x
The relative x coordinate of the bottom right pixel of the processing window.
uint8_t color_saturation_mapping_flag
This flag shall be equal to 0 in bitstreams conforming to this version of this Specification.
uint8_t num_distribution_maxrgb_percentiles
The number of linearized maxRGB values at given percentiles in the processing window in the scene.
AVRational window_upper_left_corner_y
The relative y coordinate of the top left pixel of the processing window.
AVRational window_upper_left_corner_x
The relative x coordinate of the top left pixel of the processing window.
uint8_t num_bezier_curve_anchors
The number of the intermediate anchor parameters of the tone mapping function in the processing windo...
uint16_t semiminor_axis_external_ellipse
The semi-minor axis value of the external ellipse of the elliptical pixel selector in amount of pixel...
AVRational knee_point_x
The x coordinate of the separation point between the linear part and the curved part of the tone mapp...
uint16_t center_of_ellipse_y
The y coordinate of the center position of the concentric internal and external ellipses of the ellip...
enum AVHDRPlusOverlapProcessOption overlap_process_option
Overlap process option indicates one of the two methods of combining rendered pixels in the processin...
AVRational color_saturation_weight
The color saturation gain in the processing window in the scene.
AVRational bezier_curve_anchors[15]
The intermediate anchor parameters of the tone mapping function in the processing window in the scene...
AVRational percentile
The linearized maxRGB value at a specific percentile in the processing window in the scene.
uint8_t percentage
The percentage value corresponding to a specific percentile linearized RGB value in the processing wi...
Rational number (pair of numerator and denominator).
Definition: rational.h:58
int size