149 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			149 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * This file is part of FFmpeg.
 | |
|  *
 | |
|  * FFmpeg is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU Lesser General Public
 | |
|  * License as published by the Free Software Foundation; either
 | |
|  * version 2.1 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  * FFmpeg is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  * Lesser General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU Lesser General Public
 | |
|  * License along with FFmpeg; if not, write to the Free Software
 | |
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | |
|  */
 | |
| 
 | |
| #include "dynamic_hdr_vivid.h"
 | |
| #include "get_bits.h"
 | |
| 
 | |
| static const int32_t maxrgb_den = 4095;
 | |
| static const int32_t color_saturation_gain_den = 128;
 | |
| static const int32_t maximum_luminance_den = 4095;
 | |
| static const int32_t base_param_m_p_den = 16383;
 | |
| static const int32_t base_param_m_m_den = 10;
 | |
| static const int32_t base_param_m_a_den = 1023;
 | |
| static const int32_t base_param_m_b_den = 1023;
 | |
| static const int32_t base_param_m_n_den = 10;
 | |
| static const int32_t base_param_Delta_den = 127;
 | |
| 
 | |
| int ff_parse_itu_t_t35_to_dynamic_hdr_vivid(AVDynamicHDRVivid *s, const uint8_t *data,
 | |
|                                              int size)
 | |
| {
 | |
|     GetBitContext gbc, *gb = &gbc;
 | |
|     int ret;
 | |
| 
 | |
|     if (!s)
 | |
|         return AVERROR(ENOMEM);
 | |
| 
 | |
|     ret = init_get_bits8(gb, data, size);
 | |
|     if (ret < 0)
 | |
|         return ret;
 | |
| 
 | |
|     if (get_bits_left(gb) < 8)
 | |
|         return AVERROR_INVALIDDATA;
 | |
| 
 | |
|     s->system_start_code = get_bits(gb, 8);
 | |
|     // T/UWA 005.1-2022, table 11
 | |
|     if (s->system_start_code >= 0x01 && s->system_start_code <= 0x07) {
 | |
|         s->num_windows = 1;
 | |
| 
 | |
|         if (get_bits_left(gb) < 12 * 4 * s->num_windows)
 | |
|             return AVERROR_INVALIDDATA;
 | |
|         for (int w = 0; w < s->num_windows; w++) {
 | |
|             AVHDRVividColorTransformParams *params = &s->params[w];
 | |
| 
 | |
|             params->minimum_maxrgb  = (AVRational){get_bits(gb, 12), maxrgb_den};
 | |
|             params->average_maxrgb  = (AVRational){get_bits(gb, 12), maxrgb_den};
 | |
|             params->variance_maxrgb = (AVRational){get_bits(gb, 12), maxrgb_den};
 | |
|             params->maximum_maxrgb  = (AVRational){get_bits(gb, 12), maxrgb_den};
 | |
|         }
 | |
| 
 | |
|         if (get_bits_left(gb) < 2 * s->num_windows)
 | |
|             return AVERROR_INVALIDDATA;
 | |
|         for (int w = 0; w < s->num_windows; w++) {
 | |
|             AVHDRVividColorTransformParams *params = &s->params[w];
 | |
| 
 | |
|             params->tone_mapping_mode_flag = get_bits(gb, 1);
 | |
|             if (params->tone_mapping_mode_flag) {
 | |
|                 if (get_bits_left(gb) < 1 )
 | |
|                     return AVERROR_INVALIDDATA;
 | |
|                 params->tone_mapping_param_num = get_bits(gb, 1) + 1;
 | |
|                 for (int i = 0; i < params->tone_mapping_param_num; i++) {
 | |
|                     AVHDRVividColorToneMappingParams *tm_params = ¶ms->tm_params[i];
 | |
| 
 | |
|                     if (get_bits_left(gb) < 13)
 | |
|                         return AVERROR_INVALIDDATA;
 | |
|                     tm_params->targeted_system_display_maximum_luminance = (AVRational){get_bits(gb, 12), maximum_luminance_den};
 | |
|                     tm_params->base_enable_flag = get_bits(gb, 1);
 | |
|                     if (tm_params->base_enable_flag) {
 | |
|                         if (get_bits_left(gb) < (14 + 6 + 10 + 10 + 6 + 8 + 10))
 | |
|                             return AVERROR_INVALIDDATA;
 | |
|                         tm_params->base_param_m_p = (AVRational){get_bits(gb, 14), base_param_m_p_den};
 | |
|                         tm_params->base_param_m_m = (AVRational){get_bits(gb,  6), base_param_m_m_den};
 | |
|                         tm_params->base_param_m_a = (AVRational){get_bits(gb, 10), base_param_m_a_den};
 | |
|                         tm_params->base_param_m_b = (AVRational){get_bits(gb, 10), base_param_m_b_den};
 | |
|                         tm_params->base_param_m_n = (AVRational){get_bits(gb,  6), base_param_m_n_den};
 | |
|                         tm_params->base_param_k1 = get_bits(gb, 2);
 | |
|                         tm_params->base_param_k2 = get_bits(gb, 2);
 | |
|                         tm_params->base_param_k3 = get_bits(gb, 4);
 | |
|                         tm_params->base_param_Delta_enable_mode = get_bits(gb, 3);
 | |
|                         tm_params->base_param_Delta = (AVRational){get_bits(gb, 7), base_param_Delta_den};
 | |
|                     }
 | |
|                     if (get_bits_left(gb) < 1)
 | |
|                         return AVERROR_INVALIDDATA;
 | |
|                     tm_params->three_Spline_enable_flag = get_bits(gb, 1);
 | |
|                     if (tm_params->three_Spline_enable_flag) {
 | |
|                         AVHDRVivid3SplineParams *three_spline;
 | |
| 
 | |
|                         if (get_bits_left(gb) < 1 + tm_params->three_Spline_num * (2 + 12 + 28 + 1))
 | |
|                             return AVERROR_INVALIDDATA;
 | |
|                         tm_params->three_Spline_num = get_bits(gb, 1) + 1;
 | |
|                         if (tm_params->three_Spline_num > FF_ARRAY_ELEMS(tm_params->three_spline))
 | |
|                             return AVERROR_INVALIDDATA;
 | |
|                         for (int j = 0; j < tm_params->three_Spline_num; j++) {
 | |
|                             three_spline = &tm_params->three_spline[j];
 | |
|                             three_spline->th_mode = get_bits(gb, 2);
 | |
|                             if (three_spline->th_mode == 0 || three_spline->th_mode == 2) {
 | |
|                                 if (get_bits_left(gb) < 8)
 | |
|                                     return AVERROR_INVALIDDATA;
 | |
|                                 three_spline->th_enable_mb = (AVRational){get_bits(gb, 8),  255};
 | |
|                             }
 | |
|                             three_spline->th_enable = (AVRational){get_bits(gb, 12),  4095};
 | |
|                             three_spline->th_delta1 = (AVRational){get_bits(gb, 10),  1023};
 | |
|                             three_spline->th_delta2 = (AVRational){get_bits(gb, 10),  1023};
 | |
|                             three_spline->enable_strength = (AVRational){get_bits(gb,  8),  255};
 | |
|                         }
 | |
| #if FF_API_HDR_VIVID_THREE_SPLINE
 | |
|                         three_spline = &tm_params->three_spline[0];
 | |
| FF_DISABLE_DEPRECATION_WARNINGS
 | |
|                         tm_params->three_Spline_TH_mode = three_spline->th_mode;
 | |
|                         tm_params->three_Spline_TH_enable_MB = three_spline->th_enable_mb;
 | |
|                         tm_params->three_Spline_TH_enable = three_spline->th_enable;
 | |
|                         tm_params->three_Spline_TH_Delta1 = three_spline->th_delta1;
 | |
|                         tm_params->three_Spline_TH_Delta2 = three_spline->th_delta2;
 | |
|                         tm_params->three_Spline_enable_Strength = three_spline->enable_strength;
 | |
| FF_ENABLE_DEPRECATION_WARNINGS
 | |
| #endif
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             params->color_saturation_mapping_flag = get_bits(gb, 1);
 | |
|             if (params->color_saturation_mapping_flag) {
 | |
|                 if (get_bits_left(gb) < 3 + params->color_saturation_num * 8)
 | |
|                     return AVERROR_INVALIDDATA;
 | |
| 
 | |
|                 params->color_saturation_num = get_bits(gb, 3);
 | |
|                 for (int i = 0; i < params->color_saturation_num; i++) {
 | |
|                     params->color_saturation_gain[i] = (AVRational){get_bits(gb, 8), color_saturation_gain_den};
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return 0;
 | |
| }
 |