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 22static const int64_t luminance_den = 1; 23static const int32_t peak_luminance_den = 15; 24static const int64_t rgb_den = 100000; 25static const int32_t fraction_pixel_den = 1000; 26static const int32_t knee_point_den = 4095; 27static const int32_t bezier_anchor_den = 1023; 28static const int32_t saturation_weight_den = 8; 29 30int ff_parse_itu_t_t35_to_dynamic_hdr10_plus(AVDynamicHDRPlus *s, const uint8_t *data, 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 if (get_bits_left(gb) < 10) 44 return AVERROR_INVALIDDATA; 45 46 s->application_version = get_bits(gb, 8); 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]; 60 params->window_upper_left_corner_x = 61 (AVRational){get_bits(gb, 16), 1}; 62 params->window_upper_left_corner_y = 63 (AVRational){get_bits(gb, 16), 1}; 64 params->window_lower_right_corner_x = 65 (AVRational){get_bits(gb, 16), 1}; 66 params->window_lower_right_corner_y = 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_INVALIDDATA; 80 81 s->targeted_system_display_maximum_luminance = 82 (AVRational){get_bits_long(gb, 27), luminance_den}; 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_INVALIDDATA; 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_INVALIDDATA; 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] = 103 (AVRational){get_bits(gb, 4), peak_luminance_den}; 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_INVALIDDATA; 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}; 118 params->num_distribution_maxrgb_percentiles = get_bits(gb, 4); 119 120 if (get_bits_left(gb) < 121 (params->num_distribution_maxrgb_percentiles * 24)) 122 return AVERROR_INVALIDDATA; 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_INVALIDDATA; 132 133 params->fraction_bright_pixels = (AVRational){get_bits(gb, 10), fraction_pixel_den}; 134 } 135 if (get_bits_left(gb) < 1) 136 return AVERROR_INVALIDDATA; 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_INVALIDDATA; 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_INVALIDDATA; 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] = 156 (AVRational){get_bits(gb, 4), peak_luminance_den}; 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_INVALIDDATA; 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_INVALIDDATA; 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_INVALIDDATA; 179 180 for (int i = 0; i < params->num_bezier_curve_anchors; i++) { 181 params->bezier_curve_anchors[i] = 182 (AVRational){get_bits(gb, 10), bezier_anchor_den}; 183 } 184 } 185 186 if (get_bits_left(gb) < 1) 187 return AVERROR_INVALIDDATA; 188 params->color_saturation_mapping_flag = get_bits1(gb); 189 if (params->color_saturation_mapping_flag) { 190 if (get_bits_left(gb) < 6) 191 return AVERROR_INVALIDDATA; 192 params->color_saturation_weight = 193 (AVRational){get_bits(gb, 6), saturation_weight_den}; 194 } 195 } 196 197 return 0; 198} 199