1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * This file is part of FFmpeg. 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12cabdff1aSopenharmony_ci * Lesser General Public License for more details. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17cabdff1aSopenharmony_ci */ 18cabdff1aSopenharmony_ci 19cabdff1aSopenharmony_ci#include "dynamic_hdr_vivid.h" 20cabdff1aSopenharmony_ci#include "get_bits.h" 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_cistatic const int32_t maxrgb_den = 4095; 23cabdff1aSopenharmony_cistatic const int32_t color_saturation_gain_den = 128; 24cabdff1aSopenharmony_cistatic const int32_t maximum_luminance_den = 4095; 25cabdff1aSopenharmony_cistatic const int32_t base_param_m_p_den = 16383; 26cabdff1aSopenharmony_cistatic const int32_t base_param_m_m_den = 10; 27cabdff1aSopenharmony_cistatic const int32_t base_param_m_a_den = 1023; 28cabdff1aSopenharmony_cistatic const int32_t base_param_m_b_den = 1023; 29cabdff1aSopenharmony_cistatic const int32_t base_param_m_n_den = 10; 30cabdff1aSopenharmony_cistatic const int32_t base_param_Delta_den = 127; 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_ciint ff_parse_itu_t_t35_to_dynamic_hdr_vivid(AVDynamicHDRVivid *s, const uint8_t *data, 33cabdff1aSopenharmony_ci int size) 34cabdff1aSopenharmony_ci{ 35cabdff1aSopenharmony_ci GetBitContext gbc, *gb = &gbc; 36cabdff1aSopenharmony_ci int ret; 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_ci if (!s) 39cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_ci ret = init_get_bits8(gb, data, size); 42cabdff1aSopenharmony_ci if (ret < 0) 43cabdff1aSopenharmony_ci return ret; 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci if (get_bits_left(gb) < 8) 46cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 47cabdff1aSopenharmony_ci 48cabdff1aSopenharmony_ci s->system_start_code = get_bits(gb, 8); 49cabdff1aSopenharmony_ci if (s->system_start_code == 0x01) { 50cabdff1aSopenharmony_ci s->num_windows = 1; 51cabdff1aSopenharmony_ci 52cabdff1aSopenharmony_ci if (get_bits_left(gb) < 12 * 4 * s->num_windows) 53cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 54cabdff1aSopenharmony_ci for (int w = 0; w < s->num_windows; w++) { 55cabdff1aSopenharmony_ci AVHDRVividColorTransformParams *params = &s->params[w]; 56cabdff1aSopenharmony_ci 57cabdff1aSopenharmony_ci params->minimum_maxrgb = (AVRational){get_bits(gb, 12), maxrgb_den}; 58cabdff1aSopenharmony_ci params->average_maxrgb = (AVRational){get_bits(gb, 12), maxrgb_den}; 59cabdff1aSopenharmony_ci params->variance_maxrgb = (AVRational){get_bits(gb, 12), maxrgb_den}; 60cabdff1aSopenharmony_ci params->maximum_maxrgb = (AVRational){get_bits(gb, 12), maxrgb_den}; 61cabdff1aSopenharmony_ci } 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_ci if (get_bits_left(gb) < 2 * s->num_windows) 64cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 65cabdff1aSopenharmony_ci for (int w = 0; w < s->num_windows; w++) { 66cabdff1aSopenharmony_ci AVHDRVividColorTransformParams *params = &s->params[w]; 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_ci params->tone_mapping_mode_flag = get_bits(gb, 1); 69cabdff1aSopenharmony_ci if (params->tone_mapping_mode_flag) { 70cabdff1aSopenharmony_ci if (get_bits_left(gb) < 1 ) 71cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 72cabdff1aSopenharmony_ci params->tone_mapping_param_num = get_bits(gb, 1) + 1; 73cabdff1aSopenharmony_ci for (int i = 0; i < params->tone_mapping_param_num; i++) { 74cabdff1aSopenharmony_ci AVHDRVividColorToneMappingParams *tm_params = ¶ms->tm_params[i]; 75cabdff1aSopenharmony_ci 76cabdff1aSopenharmony_ci if (get_bits_left(gb) < 13) 77cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 78cabdff1aSopenharmony_ci tm_params->targeted_system_display_maximum_luminance = (AVRational){get_bits(gb, 12), maximum_luminance_den}; 79cabdff1aSopenharmony_ci tm_params->base_enable_flag = get_bits(gb, 1); 80cabdff1aSopenharmony_ci if (tm_params->base_enable_flag) { 81cabdff1aSopenharmony_ci if (get_bits_left(gb) < (14 + 6 + 10 + 10 + 6 + 8 + 10)) 82cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 83cabdff1aSopenharmony_ci tm_params->base_param_m_p = (AVRational){get_bits(gb, 14), base_param_m_p_den}; 84cabdff1aSopenharmony_ci tm_params->base_param_m_m = (AVRational){get_bits(gb, 6), base_param_m_m_den}; 85cabdff1aSopenharmony_ci tm_params->base_param_m_a = (AVRational){get_bits(gb, 10), base_param_m_a_den}; 86cabdff1aSopenharmony_ci tm_params->base_param_m_b = (AVRational){get_bits(gb, 10), base_param_m_b_den}; 87cabdff1aSopenharmony_ci tm_params->base_param_m_n = (AVRational){get_bits(gb, 6), base_param_m_n_den}; 88cabdff1aSopenharmony_ci tm_params->base_param_k1 = get_bits(gb, 2); 89cabdff1aSopenharmony_ci tm_params->base_param_k2 = get_bits(gb, 2); 90cabdff1aSopenharmony_ci tm_params->base_param_k3 = get_bits(gb, 4); 91cabdff1aSopenharmony_ci tm_params->base_param_Delta_enable_mode = get_bits(gb, 3); 92cabdff1aSopenharmony_ci if (tm_params->base_param_Delta_enable_mode == 2 || tm_params->base_param_Delta_enable_mode == 6) 93cabdff1aSopenharmony_ci tm_params->base_param_Delta = (AVRational){get_bits(gb, 7) * -1, base_param_Delta_den}; 94cabdff1aSopenharmony_ci else 95cabdff1aSopenharmony_ci tm_params->base_param_Delta = (AVRational){get_bits(gb, 7), base_param_Delta_den}; 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_ci if (get_bits_left(gb) < 1) 98cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 99cabdff1aSopenharmony_ci tm_params->three_Spline_enable_flag = get_bits(gb, 1); 100cabdff1aSopenharmony_ci if (tm_params->three_Spline_enable_flag) { 101cabdff1aSopenharmony_ci if (get_bits_left(gb) < 1 + tm_params->three_Spline_num * (2 + 12 + 28 + 1)) 102cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 103cabdff1aSopenharmony_ci tm_params->three_Spline_num = get_bits(gb, 1) + 1; 104cabdff1aSopenharmony_ci for (int j = 0; j < tm_params->three_Spline_num; j++) { 105cabdff1aSopenharmony_ci tm_params->three_Spline_TH_mode = get_bits(gb, 2); 106cabdff1aSopenharmony_ci if (tm_params->three_Spline_TH_mode == 0 || tm_params->three_Spline_TH_mode == 2) { 107cabdff1aSopenharmony_ci if (get_bits_left(gb) < 8) 108cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 109cabdff1aSopenharmony_ci tm_params->three_Spline_TH_enable_MB = (AVRational){get_bits(gb, 8), 255}; 110cabdff1aSopenharmony_ci } 111cabdff1aSopenharmony_ci tm_params->three_Spline_TH_enable = (AVRational){get_bits(gb, 12), 4095}; 112cabdff1aSopenharmony_ci tm_params->three_Spline_TH_Delta1 = (AVRational){get_bits(gb, 10), 1023}; 113cabdff1aSopenharmony_ci tm_params->three_Spline_TH_Delta2 = (AVRational){get_bits(gb, 10), 1023}; 114cabdff1aSopenharmony_ci tm_params->three_Spline_enable_Strength = (AVRational){get_bits(gb, 8), 255}; 115cabdff1aSopenharmony_ci } 116cabdff1aSopenharmony_ci } else { 117cabdff1aSopenharmony_ci tm_params->three_Spline_num = 1; 118cabdff1aSopenharmony_ci tm_params->three_Spline_TH_mode = 0; 119cabdff1aSopenharmony_ci } 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci } 122cabdff1aSopenharmony_ci } 123cabdff1aSopenharmony_ci } 124cabdff1aSopenharmony_ci 125cabdff1aSopenharmony_ci params->color_saturation_mapping_flag = get_bits(gb, 1); 126cabdff1aSopenharmony_ci if (params->color_saturation_mapping_flag) { 127cabdff1aSopenharmony_ci if (get_bits_left(gb) < 3 + params->color_saturation_num * 8) 128cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci params->color_saturation_num = get_bits(gb, 3); 131cabdff1aSopenharmony_ci for (int i = 0; i < params->color_saturation_num; i++) { 132cabdff1aSopenharmony_ci params->color_saturation_gain[i] = (AVRational){get_bits(gb, 8), color_saturation_gain_den}; 133cabdff1aSopenharmony_ci } 134cabdff1aSopenharmony_ci } 135cabdff1aSopenharmony_ci } 136cabdff1aSopenharmony_ci } 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ci return 0; 139cabdff1aSopenharmony_ci} 140