* [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil
@ 2023-02-27 17:33 Raphaël Zumer
2023-03-12 19:08 ` James Almer
2023-03-13 16:09 ` Andreas Rheinhardt
0 siblings, 2 replies; 10+ messages in thread
From: Raphaël Zumer @ 2023-02-27 17:33 UTC (permalink / raw)
To: ffmpeg-devel
Resending this patch set due to my mail client messing with the line wrapping in the messages I sent earlier today.
Below is a copy of the initial explanation.
This patch set implements serialization for HDR10+ dynamic metadata
(AVDynamicHDRPlus), which is the inverse operation of the existing
ff_parse_itu_t_t35_to_dynamic_hdr10_plus() function. It also moves both
functions from libavcodec to libavutil and makes them public. For
consistency, the equivalent vivid HDR parsing function is also migrated,
but I did not implement serialization for it. Finally, the patch renames
those functions to av_dynamic_hdr_plus_from_t35() (for parsing) and
av_dynamic_hdr_plus_to_t35 (for serialization), with the equivalent
change being made for vivid as well.
The motivation for this change is to allow users to easily convert
HDR10+ side data (which is parsed into AVDynamicHDRPlus) to a standard
ITU-T T.35 payload that can be passed directly to applications that
expect HDR10+ dynamic metadata in that format (e.g. x265 and rav1e
encoders).
The return value of the serialization function is AVBufferRef*, which I
expect to be contentious. Payload size is not embedded in the T.35 data,
so it must be calculated, used to allocate a buffer, and returned along
with that buffer to the user. As far as I'm aware, AVBufferRef is the
simplest way to do that, but I will be happy to consider alternative
solutions.
Please let me know if it is preferred to bump libavutil with the first
commit, or with both of them, considering there are public API changes
associated with each one.
Raphaël Zumer
Signed-off-by: Raphaël Zumer <rzumer@tebako.net>
---
libavcodec/Makefile | 3 +-
libavcodec/dynamic_hdr10_plus.c | 198 -------------------------
libavcodec/dynamic_hdr10_plus.h | 35 -----
libavcodec/dynamic_hdr_vivid.c | 139 -----------------
libavcodec/dynamic_hdr_vivid.h | 35 -----
libavcodec/h2645_sei.c | 12 +-
libavutil/hdr_dynamic_metadata.c | 180 ++++++++++++++++++++++
libavutil/hdr_dynamic_metadata.h | 11 ++
libavutil/hdr_dynamic_vivid_metadata.c | 120 +++++++++++++++
libavutil/hdr_dynamic_vivid_metadata.h | 11 ++
10 files changed, 329 insertions(+), 415 deletions(-)
delete mode 100644 libavcodec/dynamic_hdr10_plus.c
delete mode 100644 libavcodec/dynamic_hdr10_plus.h
delete mode 100644 libavcodec/dynamic_hdr_vivid.c
delete mode 100644 libavcodec/dynamic_hdr_vivid.h
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 389253f5d0..4bdfcbab12 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -103,8 +103,7 @@ OBJS-$(CONFIG_H264QPEL) += h264qpel.o
OBJS-$(CONFIG_H264_SEI) += h264_sei.o h2645_sei.o
OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o hevc_ps.o hevc_data.o \
h2645data.o h2645_parse.o h2645_vui.o
-OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o \
- dynamic_hdr10_plus.o dynamic_hdr_vivid.o
+OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o
OBJS-$(CONFIG_HPELDSP) += hpeldsp.o
OBJS-$(CONFIG_HUFFMAN) += huffman.o
OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o
diff --git a/libavcodec/dynamic_hdr10_plus.c b/libavcodec/dynamic_hdr10_plus.c
deleted file mode 100644
index 34a44aac65..0000000000
--- a/libavcodec/dynamic_hdr10_plus.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * 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_hdr10_plus.h"
-#include "get_bits.h"
-
-static const int64_t luminance_den = 1;
-static const int32_t peak_luminance_den = 15;
-static const int64_t rgb_den = 100000;
-static const int32_t fraction_pixel_den = 1000;
-static const int32_t knee_point_den = 4095;
-static const int32_t bezier_anchor_den = 1023;
-static const int32_t saturation_weight_den = 8;
-
-int ff_parse_itu_t_t35_to_dynamic_hdr10_plus(AVDynamicHDRPlus *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) < 10)
- return AVERROR_INVALIDDATA;
-
- s->application_version = get_bits(gb, 8);
- s->num_windows = get_bits(gb, 2);
-
- if (s->num_windows < 1 || s->num_windows > 3) {
- return AVERROR_INVALIDDATA;
- }
-
- if (get_bits_left(gb) < ((19 * 8 + 1) * (s->num_windows - 1)))
- return AVERROR_INVALIDDATA;
-
- for (int w = 1; w < s->num_windows; w++) {
- // The corners are set to absolute coordinates here. They should be
- // converted to the relative coordinates (in [0, 1]) in the decoder.
- AVHDRPlusColorTransformParams *params = &s->params[w];
- params->window_upper_left_corner_x =
- (AVRational){get_bits(gb, 16), 1};
- params->window_upper_left_corner_y =
- (AVRational){get_bits(gb, 16), 1};
- params->window_lower_right_corner_x =
- (AVRational){get_bits(gb, 16), 1};
- params->window_lower_right_corner_y =
- (AVRational){get_bits(gb, 16), 1};
-
- params->center_of_ellipse_x = get_bits(gb, 16);
- params->center_of_ellipse_y = get_bits(gb, 16);
- params->rotation_angle = get_bits(gb, 8);
- params->semimajor_axis_internal_ellipse = get_bits(gb, 16);
- params->semimajor_axis_external_ellipse = get_bits(gb, 16);
- params->semiminor_axis_external_ellipse = get_bits(gb, 16);
- params->overlap_process_option = get_bits1(gb);
- }
-
- if (get_bits_left(gb) < 28)
- return AVERROR_INVALIDDATA;
-
- s->targeted_system_display_maximum_luminance =
- (AVRational){get_bits_long(gb, 27), luminance_den};
- s->targeted_system_display_actual_peak_luminance_flag = get_bits1(gb);
-
- if (s->targeted_system_display_actual_peak_luminance_flag) {
- int rows, cols;
- if (get_bits_left(gb) < 10)
- return AVERROR_INVALIDDATA;
- rows = get_bits(gb, 5);
- cols = get_bits(gb, 5);
- if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
- return AVERROR_INVALIDDATA;
- }
- s->num_rows_targeted_system_display_actual_peak_luminance = rows;
- s->num_cols_targeted_system_display_actual_peak_luminance = cols;
-
- if (get_bits_left(gb) < (rows * cols * 4))
- return AVERROR_INVALIDDATA;
-
- for (int i = 0; i < rows; i++) {
- for (int j = 0; j < cols; j++) {
- s->targeted_system_display_actual_peak_luminance[i][j] =
- (AVRational){get_bits(gb, 4), peak_luminance_den};
- }
- }
- }
- for (int w = 0; w < s->num_windows; w++) {
- AVHDRPlusColorTransformParams *params = &s->params[w];
- if (get_bits_left(gb) < (3 * 17 + 17 + 4))
- return AVERROR_INVALIDDATA;
-
- for (int i = 0; i < 3; i++) {
- params->maxscl[i] =
- (AVRational){get_bits(gb, 17), rgb_den};
- }
- params->average_maxrgb =
- (AVRational){get_bits(gb, 17), rgb_den};
- params->num_distribution_maxrgb_percentiles = get_bits(gb, 4);
-
- if (get_bits_left(gb) <
- (params->num_distribution_maxrgb_percentiles * 24))
- return AVERROR_INVALIDDATA;
-
- for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) {
- params->distribution_maxrgb[i].percentage = get_bits(gb, 7);
- params->distribution_maxrgb[i].percentile =
- (AVRational){get_bits(gb, 17), rgb_den};
- }
-
- if (get_bits_left(gb) < 10)
- return AVERROR_INVALIDDATA;
-
- params->fraction_bright_pixels = (AVRational){get_bits(gb, 10), fraction_pixel_den};
- }
- if (get_bits_left(gb) < 1)
- return AVERROR_INVALIDDATA;
- s->mastering_display_actual_peak_luminance_flag = get_bits1(gb);
- if (s->mastering_display_actual_peak_luminance_flag) {
- int rows, cols;
- if (get_bits_left(gb) < 10)
- return AVERROR_INVALIDDATA;
- rows = get_bits(gb, 5);
- cols = get_bits(gb, 5);
- if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
- return AVERROR_INVALIDDATA;
- }
- s->num_rows_mastering_display_actual_peak_luminance = rows;
- s->num_cols_mastering_display_actual_peak_luminance = cols;
-
- if (get_bits_left(gb) < (rows * cols * 4))
- return AVERROR_INVALIDDATA;
-
- for (int i = 0; i < rows; i++) {
- for (int j = 0; j < cols; j++) {
- s->mastering_display_actual_peak_luminance[i][j] =
- (AVRational){get_bits(gb, 4), peak_luminance_den};
- }
- }
- }
-
- for (int w = 0; w < s->num_windows; w++) {
- AVHDRPlusColorTransformParams *params = &s->params[w];
- if (get_bits_left(gb) < 1)
- return AVERROR_INVALIDDATA;
-
- params->tone_mapping_flag = get_bits1(gb);
- if (params->tone_mapping_flag) {
- if (get_bits_left(gb) < 28)
- return AVERROR_INVALIDDATA;
-
- params->knee_point_x =
- (AVRational){get_bits(gb, 12), knee_point_den};
- params->knee_point_y =
- (AVRational){get_bits(gb, 12), knee_point_den};
- params->num_bezier_curve_anchors = get_bits(gb, 4);
-
- if (get_bits_left(gb) < (params->num_bezier_curve_anchors * 10))
- return AVERROR_INVALIDDATA;
-
- for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
- params->bezier_curve_anchors[i] =
- (AVRational){get_bits(gb, 10), bezier_anchor_den};
- }
- }
-
- if (get_bits_left(gb) < 1)
- return AVERROR_INVALIDDATA;
- params->color_saturation_mapping_flag = get_bits1(gb);
- if (params->color_saturation_mapping_flag) {
- if (get_bits_left(gb) < 6)
- return AVERROR_INVALIDDATA;
- params->color_saturation_weight =
- (AVRational){get_bits(gb, 6), saturation_weight_den};
- }
- }
-
- return 0;
-}
diff --git a/libavcodec/dynamic_hdr10_plus.h b/libavcodec/dynamic_hdr10_plus.h
deleted file mode 100644
index cd7acf0432..0000000000
--- a/libavcodec/dynamic_hdr10_plus.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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
- */
-
-#ifndef AVCODEC_DYNAMIC_HDR10_PLUS_H
-#define AVCODEC_DYNAMIC_HDR10_PLUS_H
-
-#include "libavutil/hdr_dynamic_metadata.h"
-
-/**
- * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRPlus).
- * @param s A pointer containing the decoded AVDynamicHDRPlus structure.
- * @param data The byte array containing the raw ITU-T T.35 data.
- * @param size Size of the data array in bytes.
- *
- * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
- */
-int ff_parse_itu_t_t35_to_dynamic_hdr10_plus(AVDynamicHDRPlus *s, const uint8_t *data,
- int size);
-
-#endif /* AVCODEC_DYNAMIC_HDR10_PLUS_H */
diff --git a/libavcodec/dynamic_hdr_vivid.c b/libavcodec/dynamic_hdr_vivid.c
deleted file mode 100644
index d689669dec..0000000000
--- a/libavcodec/dynamic_hdr_vivid.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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);
- if (s->system_start_code == 0x01) {
- 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);
- if (tm_params->base_param_Delta_enable_mode == 2 || tm_params->base_param_Delta_enable_mode == 6)
- tm_params->base_param_Delta = (AVRational){get_bits(gb, 7) * -1, base_param_Delta_den};
- else
- 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) {
- 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;
- for (int j = 0; j < tm_params->three_Spline_num; j++) {
- tm_params->three_Spline_TH_mode = get_bits(gb, 2);
- if (tm_params->three_Spline_TH_mode == 0 || tm_params->three_Spline_TH_mode == 2) {
- if (get_bits_left(gb) < 8)
- return AVERROR_INVALIDDATA;
- tm_params->three_Spline_TH_enable_MB = (AVRational){get_bits(gb, 8), 255};
- }
- tm_params->three_Spline_TH_enable = (AVRational){get_bits(gb, 12), 4095};
- tm_params->three_Spline_TH_Delta1 = (AVRational){get_bits(gb, 10), 1023};
- tm_params->three_Spline_TH_Delta2 = (AVRational){get_bits(gb, 10), 1023};
- tm_params->three_Spline_enable_Strength = (AVRational){get_bits(gb, 8), 255};
- }
- } else {
- tm_params->three_Spline_num = 1;
- tm_params->three_Spline_TH_mode = 0;
- }
-
- }
- }
- }
-
- 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;
-}
diff --git a/libavcodec/dynamic_hdr_vivid.h b/libavcodec/dynamic_hdr_vivid.h
deleted file mode 100644
index d521b3d263..0000000000
--- a/libavcodec/dynamic_hdr_vivid.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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
- */
-
-#ifndef AVCODEC_DYNAMIC_HDR_VIVID_H
-#define AVCODEC_DYNAMIC_HDR_VIVID_H
-
-#include "libavutil/hdr_dynamic_vivid_metadata.h"
-
-/**
- * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
- * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
- * @param data The byte array containing the raw ITU-T T.35 data.
- * @param size Size of the data array in bytes.
- *
- * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
- */
-int ff_parse_itu_t_t35_to_dynamic_hdr_vivid(AVDynamicHDRVivid *s, const uint8_t *data,
- int size);
-
-#endif /* AVCODEC_DYNAMIC_HDR_VIVID_H */
diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c
index 6e4a9a1af2..7a96bc6056 100644
--- a/libavcodec/h2645_sei.c
+++ b/libavcodec/h2645_sei.c
@@ -27,14 +27,14 @@
#include "libavutil/ambient_viewing_environment.h"
#include "libavutil/display.h"
+#include "libavutil/hdr_dynamic_metadata.h"
+#include "libavutil/hdr_dynamic_vivid_metadata.h"
#include "libavutil/film_grain_params.h"
#include "libavutil/pixdesc.h"
#include "libavutil/stereo3d.h"
#include "atsc_a53.h"
#include "avcodec.h"
-#include "dynamic_hdr10_plus.h"
-#include "dynamic_hdr_vivid.h"
#include "get_bits.h"
#include "golomb.h"
#include "h2645_sei.h"
@@ -52,8 +52,8 @@ static int decode_registered_user_data_dynamic_hdr_plus(HEVCSEIDynamicHDRPlus *s
if (!metadata)
return AVERROR(ENOMEM);
- err = ff_parse_itu_t_t35_to_dynamic_hdr10_plus(metadata, gb->buffer,
- bytestream2_get_bytes_left(gb));
+ err = av_dynamic_hdr_plus_from_t35(metadata, gb->buffer,
+ bytestream2_get_bytes_left(gb));
if (err < 0) {
av_free(metadata);
return err;
@@ -78,8 +78,8 @@ static int decode_registered_user_data_dynamic_hdr_vivid(HEVCSEIDynamicHDRVivid
if (!metadata)
return AVERROR(ENOMEM);
- err = ff_parse_itu_t_t35_to_dynamic_hdr_vivid(metadata,
- gb->buffer, bytestream2_get_bytes_left(gb));
+ err = av_dynamic_hdr_vivid_from_t35(metadata,
+ gb->buffer, bytestream2_get_bytes_left(gb));
if (err < 0) {
av_free(metadata);
return err;
diff --git a/libavutil/hdr_dynamic_metadata.c b/libavutil/hdr_dynamic_metadata.c
index 0fa1ee82de..98f399b032 100644
--- a/libavutil/hdr_dynamic_metadata.c
+++ b/libavutil/hdr_dynamic_metadata.c
@@ -20,6 +20,16 @@
#include "hdr_dynamic_metadata.h"
#include "mem.h"
+#include "libavcodec/get_bits.h"
+#include "libavcodec/put_bits.h"
+
+static const int64_t luminance_den = 1;
+static const int32_t peak_luminance_den = 15;
+static const int64_t rgb_den = 100000;
+static const int32_t fraction_pixel_den = 1000;
+static const int32_t knee_point_den = 4095;
+static const int32_t bezier_anchor_den = 1023;
+static const int32_t saturation_weight_den = 8;
AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size)
{
@@ -45,3 +55,173 @@ AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame)
return (AVDynamicHDRPlus *)side_data->data;
}
+
+int av_dynamic_hdr_plus_from_t35(AVDynamicHDRPlus *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) < 10)
+ return AVERROR_INVALIDDATA;
+
+ s->application_version = get_bits(gb, 8);
+ s->num_windows = get_bits(gb, 2);
+
+ if (s->num_windows < 1 || s->num_windows > 3) {
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (get_bits_left(gb) < ((19 * 8 + 1) * (s->num_windows - 1)))
+ return AVERROR_INVALIDDATA;
+
+ for (int w = 1; w < s->num_windows; w++) {
+ // The corners are set to absolute coordinates here. They should be
+ // converted to the relative coordinates (in [0, 1]) in the decoder.
+ AVHDRPlusColorTransformParams *params = &s->params[w];
+ params->window_upper_left_corner_x =
+ (AVRational){get_bits(gb, 16), 1};
+ params->window_upper_left_corner_y =
+ (AVRational){get_bits(gb, 16), 1};
+ params->window_lower_right_corner_x =
+ (AVRational){get_bits(gb, 16), 1};
+ params->window_lower_right_corner_y =
+ (AVRational){get_bits(gb, 16), 1};
+
+ params->center_of_ellipse_x = get_bits(gb, 16);
+ params->center_of_ellipse_y = get_bits(gb, 16);
+ params->rotation_angle = get_bits(gb, 8);
+ params->semimajor_axis_internal_ellipse = get_bits(gb, 16);
+ params->semimajor_axis_external_ellipse = get_bits(gb, 16);
+ params->semiminor_axis_external_ellipse = get_bits(gb, 16);
+ params->overlap_process_option = get_bits1(gb);
+ }
+
+ if (get_bits_left(gb) < 28)
+ return AVERROR_INVALIDDATA;
+
+ s->targeted_system_display_maximum_luminance =
+ (AVRational){get_bits_long(gb, 27), luminance_den};
+ s->targeted_system_display_actual_peak_luminance_flag = get_bits1(gb);
+
+ if (s->targeted_system_display_actual_peak_luminance_flag) {
+ int rows, cols;
+ if (get_bits_left(gb) < 10)
+ return AVERROR_INVALIDDATA;
+ rows = get_bits(gb, 5);
+ cols = get_bits(gb, 5);
+ if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
+ return AVERROR_INVALIDDATA;
+ }
+ s->num_rows_targeted_system_display_actual_peak_luminance = rows;
+ s->num_cols_targeted_system_display_actual_peak_luminance = cols;
+
+ if (get_bits_left(gb) < (rows * cols * 4))
+ return AVERROR_INVALIDDATA;
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ s->targeted_system_display_actual_peak_luminance[i][j] =
+ (AVRational){get_bits(gb, 4), peak_luminance_den};
+ }
+ }
+ }
+ for (int w = 0; w < s->num_windows; w++) {
+ AVHDRPlusColorTransformParams *params = &s->params[w];
+ if (get_bits_left(gb) < (3 * 17 + 17 + 4))
+ return AVERROR_INVALIDDATA;
+
+ for (int i = 0; i < 3; i++) {
+ params->maxscl[i] =
+ (AVRational){get_bits(gb, 17), rgb_den};
+ }
+ params->average_maxrgb =
+ (AVRational){get_bits(gb, 17), rgb_den};
+ params->num_distribution_maxrgb_percentiles = get_bits(gb, 4);
+
+ if (get_bits_left(gb) <
+ (params->num_distribution_maxrgb_percentiles * 24))
+ return AVERROR_INVALIDDATA;
+
+ for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) {
+ params->distribution_maxrgb[i].percentage = get_bits(gb, 7);
+ params->distribution_maxrgb[i].percentile =
+ (AVRational){get_bits(gb, 17), rgb_den};
+ }
+
+ if (get_bits_left(gb) < 10)
+ return AVERROR_INVALIDDATA;
+
+ params->fraction_bright_pixels = (AVRational){get_bits(gb, 10), fraction_pixel_den};
+ }
+ if (get_bits_left(gb) < 1)
+ return AVERROR_INVALIDDATA;
+ s->mastering_display_actual_peak_luminance_flag = get_bits1(gb);
+ if (s->mastering_display_actual_peak_luminance_flag) {
+ int rows, cols;
+ if (get_bits_left(gb) < 10)
+ return AVERROR_INVALIDDATA;
+ rows = get_bits(gb, 5);
+ cols = get_bits(gb, 5);
+ if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
+ return AVERROR_INVALIDDATA;
+ }
+ s->num_rows_mastering_display_actual_peak_luminance = rows;
+ s->num_cols_mastering_display_actual_peak_luminance = cols;
+
+ if (get_bits_left(gb) < (rows * cols * 4))
+ return AVERROR_INVALIDDATA;
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ s->mastering_display_actual_peak_luminance[i][j] =
+ (AVRational){get_bits(gb, 4), peak_luminance_den};
+ }
+ }
+ }
+
+ for (int w = 0; w < s->num_windows; w++) {
+ AVHDRPlusColorTransformParams *params = &s->params[w];
+ if (get_bits_left(gb) < 1)
+ return AVERROR_INVALIDDATA;
+
+ params->tone_mapping_flag = get_bits1(gb);
+ if (params->tone_mapping_flag) {
+ if (get_bits_left(gb) < 28)
+ return AVERROR_INVALIDDATA;
+
+ params->knee_point_x =
+ (AVRational){get_bits(gb, 12), knee_point_den};
+ params->knee_point_y =
+ (AVRational){get_bits(gb, 12), knee_point_den};
+ params->num_bezier_curve_anchors = get_bits(gb, 4);
+
+ if (get_bits_left(gb) < (params->num_bezier_curve_anchors * 10))
+ return AVERROR_INVALIDDATA;
+
+ for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
+ params->bezier_curve_anchors[i] =
+ (AVRational){get_bits(gb, 10), bezier_anchor_den};
+ }
+ }
+
+ if (get_bits_left(gb) < 1)
+ return AVERROR_INVALIDDATA;
+ params->color_saturation_mapping_flag = get_bits1(gb);
+ if (params->color_saturation_mapping_flag) {
+ if (get_bits_left(gb) < 6)
+ return AVERROR_INVALIDDATA;
+ params->color_saturation_weight =
+ (AVRational){get_bits(gb, 6), saturation_weight_den};
+ }
+ }
+
+ return 0;
+}
diff --git a/libavutil/hdr_dynamic_metadata.h b/libavutil/hdr_dynamic_metadata.h
index 2d72de56ae..1f953ef1f5 100644
--- a/libavutil/hdr_dynamic_metadata.h
+++ b/libavutil/hdr_dynamic_metadata.h
@@ -340,4 +340,15 @@ AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size);
*/
AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame);
+/**
+ * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRPlus).
+ * @param s A pointer containing the decoded AVDynamicHDRPlus structure.
+ * @param data The byte array containing the raw ITU-T T.35 data.
+ * @param size Size of the data array in bytes.
+ *
+ * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
+ */
+int av_dynamic_hdr_plus_from_t35(AVDynamicHDRPlus *s, const uint8_t *data,
+ int size);
+
#endif /* AVUTIL_HDR_DYNAMIC_METADATA_H */
diff --git a/libavutil/hdr_dynamic_vivid_metadata.c b/libavutil/hdr_dynamic_vivid_metadata.c
index 32da01f587..1218644123 100644
--- a/libavutil/hdr_dynamic_vivid_metadata.c
+++ b/libavutil/hdr_dynamic_vivid_metadata.c
@@ -20,6 +20,17 @@
#include "hdr_dynamic_vivid_metadata.h"
#include "mem.h"
+#include "libavcodec/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;
AVDynamicHDRVivid *av_dynamic_hdr_vivid_alloc(size_t *size)
{
@@ -45,3 +56,112 @@ AVDynamicHDRVivid *av_dynamic_hdr_vivid_create_side_data(AVFrame *frame)
return (AVDynamicHDRVivid *)side_data->data;
}
+
+int av_dynamic_hdr_vivid_from_t35(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);
+ if (s->system_start_code == 0x01) {
+ 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);
+ if (tm_params->base_param_Delta_enable_mode == 2 || tm_params->base_param_Delta_enable_mode == 6)
+ tm_params->base_param_Delta = (AVRational){get_bits(gb, 7) * -1, base_param_Delta_den};
+ else
+ 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) {
+ 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;
+ for (int j = 0; j < tm_params->three_Spline_num; j++) {
+ tm_params->three_Spline_TH_mode = get_bits(gb, 2);
+ if (tm_params->three_Spline_TH_mode == 0 || tm_params->three_Spline_TH_mode == 2) {
+ if (get_bits_left(gb) < 8)
+ return AVERROR_INVALIDDATA;
+ tm_params->three_Spline_TH_enable_MB = (AVRational){get_bits(gb, 8), 255};
+ }
+ tm_params->three_Spline_TH_enable = (AVRational){get_bits(gb, 12), 4095};
+ tm_params->three_Spline_TH_Delta1 = (AVRational){get_bits(gb, 10), 1023};
+ tm_params->three_Spline_TH_Delta2 = (AVRational){get_bits(gb, 10), 1023};
+ tm_params->three_Spline_enable_Strength = (AVRational){get_bits(gb, 8), 255};
+ }
+ } else {
+ tm_params->three_Spline_num = 1;
+ tm_params->three_Spline_TH_mode = 0;
+ }
+
+ }
+ }
+ }
+
+ 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;
+}
diff --git a/libavutil/hdr_dynamic_vivid_metadata.h b/libavutil/hdr_dynamic_vivid_metadata.h
index a34f83072c..16a84ce343 100644
--- a/libavutil/hdr_dynamic_vivid_metadata.h
+++ b/libavutil/hdr_dynamic_vivid_metadata.h
@@ -282,4 +282,15 @@ AVDynamicHDRVivid *av_dynamic_hdr_vivid_alloc(size_t *size);
*/
AVDynamicHDRVivid *av_dynamic_hdr_vivid_create_side_data(AVFrame *frame);
+/**
+ * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
+ * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
+ * @param data The byte array containing the raw ITU-T T.35 data.
+ * @param size Size of the data array in bytes.
+ *
+ * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
+ */
+int av_dynamic_hdr_vivid_from_t35(AVDynamicHDRVivid *s, const uint8_t *data,
+ int size);
+
#endif /* AVUTIL_HDR_DYNAMIC_VIVID_METADATA_H */
--
2.39.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil
2023-02-27 17:33 [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil Raphaël Zumer
@ 2023-03-12 19:08 ` James Almer
2023-03-13 16:09 ` Andreas Rheinhardt
1 sibling, 0 replies; 10+ messages in thread
From: James Almer @ 2023-03-12 19:08 UTC (permalink / raw)
To: ffmpeg-devel
On 2/27/2023 2:33 PM, Raphaël Zumer wrote:
> Resending this patch set due to my mail client messing with the line wrapping in the messages I sent earlier today.
>
> Below is a copy of the initial explanation.
>
> This patch set implements serialization for HDR10+ dynamic metadata
> (AVDynamicHDRPlus), which is the inverse operation of the existing
> ff_parse_itu_t_t35_to_dynamic_hdr10_plus() function. It also moves both
> functions from libavcodec to libavutil and makes them public. For
> consistency, the equivalent vivid HDR parsing function is also migrated,
> but I did not implement serialization for it. Finally, the patch renames
> those functions to av_dynamic_hdr_plus_from_t35() (for parsing) and
> av_dynamic_hdr_plus_to_t35 (for serialization), with the equivalent
> change being made for vivid as well.
>
> The motivation for this change is to allow users to easily convert
> HDR10+ side data (which is parsed into AVDynamicHDRPlus) to a standard
> ITU-T T.35 payload that can be passed directly to applications that
> expect HDR10+ dynamic metadata in that format (e.g. x265 and rav1e
> encoders).
>
> The return value of the serialization function is AVBufferRef*, which I
> expect to be contentious. Payload size is not embedded in the T.35 data,
> so it must be calculated, used to allocate a buffer, and returned along
> with that buffer to the user. As far as I'm aware, AVBufferRef is the
> simplest way to do that, but I will be happy to consider alternative
> solutions.
>
> Please let me know if it is preferred to bump libavutil with the first
> commit, or with both of them, considering there are public API changes
> associated with each one.
>
> Raphaël Zumer
Could you resend this patch and the last version of second one in a new
set with proper commit messages for each of them? The text above would
apply to a cover letter (patch 0/2) as it mentions the changes for the
whole set plus review requests, instead of just the changes for this
specific patch.
The single version bump in the second patch is ok, but you should also
add an APIChanges entry to it listing all three functions you added.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil
2023-02-27 17:33 [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil Raphaël Zumer
2023-03-12 19:08 ` James Almer
@ 2023-03-13 16:09 ` Andreas Rheinhardt
2023-03-13 16:56 ` Raphaël Zumer
1 sibling, 1 reply; 10+ messages in thread
From: Andreas Rheinhardt @ 2023-03-13 16:09 UTC (permalink / raw)
To: ffmpeg-devel
Raphaël Zumer:
> Resending this patch set due to my mail client messing with the line wrapping in the messages I sent earlier today.
>
> Below is a copy of the initial explanation.
>
> This patch set implements serialization for HDR10+ dynamic metadata
> (AVDynamicHDRPlus), which is the inverse operation of the existing
> ff_parse_itu_t_t35_to_dynamic_hdr10_plus() function. It also moves both
> functions from libavcodec to libavutil and makes them public. For
> consistency, the equivalent vivid HDR parsing function is also migrated,
> but I did not implement serialization for it. Finally, the patch renames
> those functions to av_dynamic_hdr_plus_from_t35() (for parsing) and
> av_dynamic_hdr_plus_to_t35 (for serialization), with the equivalent
> change being made for vivid as well.
>
> The motivation for this change is to allow users to easily convert
> HDR10+ side data (which is parsed into AVDynamicHDRPlus) to a standard
> ITU-T T.35 payload that can be passed directly to applications that
> expect HDR10+ dynamic metadata in that format (e.g. x265 and rav1e
> encoders).
>
> The return value of the serialization function is AVBufferRef*, which I
> expect to be contentious. Payload size is not embedded in the T.35 data,
> so it must be calculated, used to allocate a buffer, and returned along
> with that buffer to the user. As far as I'm aware, AVBufferRef is the
> simplest way to do that, but I will be happy to consider alternative
> solutions.
>
> Please let me know if it is preferred to bump libavutil with the first
> commit, or with both of them, considering there are public API changes
> associated with each one.
>
> Raphaël Zumer
>
> Signed-off-by: Raphaël Zumer <rzumer@tebako.net>
> ---
> libavcodec/Makefile | 3 +-
> libavcodec/dynamic_hdr10_plus.c | 198 -------------------------
> libavcodec/dynamic_hdr10_plus.h | 35 -----
> libavcodec/dynamic_hdr_vivid.c | 139 -----------------
> libavcodec/dynamic_hdr_vivid.h | 35 -----
> libavcodec/h2645_sei.c | 12 +-
> libavutil/hdr_dynamic_metadata.c | 180 ++++++++++++++++++++++
> libavutil/hdr_dynamic_metadata.h | 11 ++
> libavutil/hdr_dynamic_vivid_metadata.c | 120 +++++++++++++++
> libavutil/hdr_dynamic_vivid_metadata.h | 11 ++
> 10 files changed, 329 insertions(+), 415 deletions(-)
> delete mode 100644 libavcodec/dynamic_hdr10_plus.c
> delete mode 100644 libavcodec/dynamic_hdr10_plus.h
> delete mode 100644 libavcodec/dynamic_hdr_vivid.c
> delete mode 100644 libavcodec/dynamic_hdr_vivid.h
>
> diff --git a/libavcodec/Makefile b/libavcodec/Makefile
> index 389253f5d0..4bdfcbab12 100644
> --- a/libavcodec/Makefile
> +++ b/libavcodec/Makefile
> @@ -103,8 +103,7 @@ OBJS-$(CONFIG_H264QPEL) += h264qpel.o
> OBJS-$(CONFIG_H264_SEI) += h264_sei.o h2645_sei.o
> OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o hevc_ps.o hevc_data.o \
> h2645data.o h2645_parse.o h2645_vui.o
> -OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o \
> - dynamic_hdr10_plus.o dynamic_hdr_vivid.o
> +OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o
> OBJS-$(CONFIG_HPELDSP) += hpeldsp.o
> OBJS-$(CONFIG_HUFFMAN) += huffman.o
> OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o
> diff --git a/libavcodec/dynamic_hdr10_plus.c b/libavcodec/dynamic_hdr10_plus.c
> deleted file mode 100644
> index 34a44aac65..0000000000
> --- a/libavcodec/dynamic_hdr10_plus.c
> +++ /dev/null
> @@ -1,198 +0,0 @@
> -/*
> - * 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_hdr10_plus.h"
> -#include "get_bits.h"
> -
> -static const int64_t luminance_den = 1;
> -static const int32_t peak_luminance_den = 15;
> -static const int64_t rgb_den = 100000;
> -static const int32_t fraction_pixel_den = 1000;
> -static const int32_t knee_point_den = 4095;
> -static const int32_t bezier_anchor_den = 1023;
> -static const int32_t saturation_weight_den = 8;
> -
> -int ff_parse_itu_t_t35_to_dynamic_hdr10_plus(AVDynamicHDRPlus *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) < 10)
> - return AVERROR_INVALIDDATA;
> -
> - s->application_version = get_bits(gb, 8);
> - s->num_windows = get_bits(gb, 2);
> -
> - if (s->num_windows < 1 || s->num_windows > 3) {
> - return AVERROR_INVALIDDATA;
> - }
> -
> - if (get_bits_left(gb) < ((19 * 8 + 1) * (s->num_windows - 1)))
> - return AVERROR_INVALIDDATA;
> -
> - for (int w = 1; w < s->num_windows; w++) {
> - // The corners are set to absolute coordinates here. They should be
> - // converted to the relative coordinates (in [0, 1]) in the decoder.
> - AVHDRPlusColorTransformParams *params = &s->params[w];
> - params->window_upper_left_corner_x =
> - (AVRational){get_bits(gb, 16), 1};
> - params->window_upper_left_corner_y =
> - (AVRational){get_bits(gb, 16), 1};
> - params->window_lower_right_corner_x =
> - (AVRational){get_bits(gb, 16), 1};
> - params->window_lower_right_corner_y =
> - (AVRational){get_bits(gb, 16), 1};
> -
> - params->center_of_ellipse_x = get_bits(gb, 16);
> - params->center_of_ellipse_y = get_bits(gb, 16);
> - params->rotation_angle = get_bits(gb, 8);
> - params->semimajor_axis_internal_ellipse = get_bits(gb, 16);
> - params->semimajor_axis_external_ellipse = get_bits(gb, 16);
> - params->semiminor_axis_external_ellipse = get_bits(gb, 16);
> - params->overlap_process_option = get_bits1(gb);
> - }
> -
> - if (get_bits_left(gb) < 28)
> - return AVERROR_INVALIDDATA;
> -
> - s->targeted_system_display_maximum_luminance =
> - (AVRational){get_bits_long(gb, 27), luminance_den};
> - s->targeted_system_display_actual_peak_luminance_flag = get_bits1(gb);
> -
> - if (s->targeted_system_display_actual_peak_luminance_flag) {
> - int rows, cols;
> - if (get_bits_left(gb) < 10)
> - return AVERROR_INVALIDDATA;
> - rows = get_bits(gb, 5);
> - cols = get_bits(gb, 5);
> - if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
> - return AVERROR_INVALIDDATA;
> - }
> - s->num_rows_targeted_system_display_actual_peak_luminance = rows;
> - s->num_cols_targeted_system_display_actual_peak_luminance = cols;
> -
> - if (get_bits_left(gb) < (rows * cols * 4))
> - return AVERROR_INVALIDDATA;
> -
> - for (int i = 0; i < rows; i++) {
> - for (int j = 0; j < cols; j++) {
> - s->targeted_system_display_actual_peak_luminance[i][j] =
> - (AVRational){get_bits(gb, 4), peak_luminance_den};
> - }
> - }
> - }
> - for (int w = 0; w < s->num_windows; w++) {
> - AVHDRPlusColorTransformParams *params = &s->params[w];
> - if (get_bits_left(gb) < (3 * 17 + 17 + 4))
> - return AVERROR_INVALIDDATA;
> -
> - for (int i = 0; i < 3; i++) {
> - params->maxscl[i] =
> - (AVRational){get_bits(gb, 17), rgb_den};
> - }
> - params->average_maxrgb =
> - (AVRational){get_bits(gb, 17), rgb_den};
> - params->num_distribution_maxrgb_percentiles = get_bits(gb, 4);
> -
> - if (get_bits_left(gb) <
> - (params->num_distribution_maxrgb_percentiles * 24))
> - return AVERROR_INVALIDDATA;
> -
> - for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) {
> - params->distribution_maxrgb[i].percentage = get_bits(gb, 7);
> - params->distribution_maxrgb[i].percentile =
> - (AVRational){get_bits(gb, 17), rgb_den};
> - }
> -
> - if (get_bits_left(gb) < 10)
> - return AVERROR_INVALIDDATA;
> -
> - params->fraction_bright_pixels = (AVRational){get_bits(gb, 10), fraction_pixel_den};
> - }
> - if (get_bits_left(gb) < 1)
> - return AVERROR_INVALIDDATA;
> - s->mastering_display_actual_peak_luminance_flag = get_bits1(gb);
> - if (s->mastering_display_actual_peak_luminance_flag) {
> - int rows, cols;
> - if (get_bits_left(gb) < 10)
> - return AVERROR_INVALIDDATA;
> - rows = get_bits(gb, 5);
> - cols = get_bits(gb, 5);
> - if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
> - return AVERROR_INVALIDDATA;
> - }
> - s->num_rows_mastering_display_actual_peak_luminance = rows;
> - s->num_cols_mastering_display_actual_peak_luminance = cols;
> -
> - if (get_bits_left(gb) < (rows * cols * 4))
> - return AVERROR_INVALIDDATA;
> -
> - for (int i = 0; i < rows; i++) {
> - for (int j = 0; j < cols; j++) {
> - s->mastering_display_actual_peak_luminance[i][j] =
> - (AVRational){get_bits(gb, 4), peak_luminance_den};
> - }
> - }
> - }
> -
> - for (int w = 0; w < s->num_windows; w++) {
> - AVHDRPlusColorTransformParams *params = &s->params[w];
> - if (get_bits_left(gb) < 1)
> - return AVERROR_INVALIDDATA;
> -
> - params->tone_mapping_flag = get_bits1(gb);
> - if (params->tone_mapping_flag) {
> - if (get_bits_left(gb) < 28)
> - return AVERROR_INVALIDDATA;
> -
> - params->knee_point_x =
> - (AVRational){get_bits(gb, 12), knee_point_den};
> - params->knee_point_y =
> - (AVRational){get_bits(gb, 12), knee_point_den};
> - params->num_bezier_curve_anchors = get_bits(gb, 4);
> -
> - if (get_bits_left(gb) < (params->num_bezier_curve_anchors * 10))
> - return AVERROR_INVALIDDATA;
> -
> - for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
> - params->bezier_curve_anchors[i] =
> - (AVRational){get_bits(gb, 10), bezier_anchor_den};
> - }
> - }
> -
> - if (get_bits_left(gb) < 1)
> - return AVERROR_INVALIDDATA;
> - params->color_saturation_mapping_flag = get_bits1(gb);
> - if (params->color_saturation_mapping_flag) {
> - if (get_bits_left(gb) < 6)
> - return AVERROR_INVALIDDATA;
> - params->color_saturation_weight =
> - (AVRational){get_bits(gb, 6), saturation_weight_den};
> - }
> - }
> -
> - return 0;
> -}
> diff --git a/libavcodec/dynamic_hdr10_plus.h b/libavcodec/dynamic_hdr10_plus.h
> deleted file mode 100644
> index cd7acf0432..0000000000
> --- a/libavcodec/dynamic_hdr10_plus.h
> +++ /dev/null
> @@ -1,35 +0,0 @@
> -/*
> - * 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
> - */
> -
> -#ifndef AVCODEC_DYNAMIC_HDR10_PLUS_H
> -#define AVCODEC_DYNAMIC_HDR10_PLUS_H
> -
> -#include "libavutil/hdr_dynamic_metadata.h"
> -
> -/**
> - * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRPlus).
> - * @param s A pointer containing the decoded AVDynamicHDRPlus structure.
> - * @param data The byte array containing the raw ITU-T T.35 data.
> - * @param size Size of the data array in bytes.
> - *
> - * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
> - */
> -int ff_parse_itu_t_t35_to_dynamic_hdr10_plus(AVDynamicHDRPlus *s, const uint8_t *data,
> - int size);
> -
> -#endif /* AVCODEC_DYNAMIC_HDR10_PLUS_H */
> diff --git a/libavcodec/dynamic_hdr_vivid.c b/libavcodec/dynamic_hdr_vivid.c
> deleted file mode 100644
> index d689669dec..0000000000
> --- a/libavcodec/dynamic_hdr_vivid.c
> +++ /dev/null
> @@ -1,139 +0,0 @@
> -/*
> - * 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);
> - if (s->system_start_code == 0x01) {
> - 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);
> - if (tm_params->base_param_Delta_enable_mode == 2 || tm_params->base_param_Delta_enable_mode == 6)
> - tm_params->base_param_Delta = (AVRational){get_bits(gb, 7) * -1, base_param_Delta_den};
> - else
> - 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) {
> - 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;
> - for (int j = 0; j < tm_params->three_Spline_num; j++) {
> - tm_params->three_Spline_TH_mode = get_bits(gb, 2);
> - if (tm_params->three_Spline_TH_mode == 0 || tm_params->three_Spline_TH_mode == 2) {
> - if (get_bits_left(gb) < 8)
> - return AVERROR_INVALIDDATA;
> - tm_params->three_Spline_TH_enable_MB = (AVRational){get_bits(gb, 8), 255};
> - }
> - tm_params->three_Spline_TH_enable = (AVRational){get_bits(gb, 12), 4095};
> - tm_params->three_Spline_TH_Delta1 = (AVRational){get_bits(gb, 10), 1023};
> - tm_params->three_Spline_TH_Delta2 = (AVRational){get_bits(gb, 10), 1023};
> - tm_params->three_Spline_enable_Strength = (AVRational){get_bits(gb, 8), 255};
> - }
> - } else {
> - tm_params->three_Spline_num = 1;
> - tm_params->three_Spline_TH_mode = 0;
> - }
> -
> - }
> - }
> - }
> -
> - 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;
> -}
> diff --git a/libavcodec/dynamic_hdr_vivid.h b/libavcodec/dynamic_hdr_vivid.h
> deleted file mode 100644
> index d521b3d263..0000000000
> --- a/libavcodec/dynamic_hdr_vivid.h
> +++ /dev/null
> @@ -1,35 +0,0 @@
> -/*
> - * 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
> - */
> -
> -#ifndef AVCODEC_DYNAMIC_HDR_VIVID_H
> -#define AVCODEC_DYNAMIC_HDR_VIVID_H
> -
> -#include "libavutil/hdr_dynamic_vivid_metadata.h"
> -
> -/**
> - * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
> - * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
> - * @param data The byte array containing the raw ITU-T T.35 data.
> - * @param size Size of the data array in bytes.
> - *
> - * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
> - */
> -int ff_parse_itu_t_t35_to_dynamic_hdr_vivid(AVDynamicHDRVivid *s, const uint8_t *data,
> - int size);
> -
> -#endif /* AVCODEC_DYNAMIC_HDR_VIVID_H */
> diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c
> index 6e4a9a1af2..7a96bc6056 100644
> --- a/libavcodec/h2645_sei.c
> +++ b/libavcodec/h2645_sei.c
> @@ -27,14 +27,14 @@
>
> #include "libavutil/ambient_viewing_environment.h"
> #include "libavutil/display.h"
> +#include "libavutil/hdr_dynamic_metadata.h"
> +#include "libavutil/hdr_dynamic_vivid_metadata.h"
> #include "libavutil/film_grain_params.h"
> #include "libavutil/pixdesc.h"
> #include "libavutil/stereo3d.h"
>
> #include "atsc_a53.h"
> #include "avcodec.h"
> -#include "dynamic_hdr10_plus.h"
> -#include "dynamic_hdr_vivid.h"
> #include "get_bits.h"
> #include "golomb.h"
> #include "h2645_sei.h"
> @@ -52,8 +52,8 @@ static int decode_registered_user_data_dynamic_hdr_plus(HEVCSEIDynamicHDRPlus *s
> if (!metadata)
> return AVERROR(ENOMEM);
>
> - err = ff_parse_itu_t_t35_to_dynamic_hdr10_plus(metadata, gb->buffer,
> - bytestream2_get_bytes_left(gb));
> + err = av_dynamic_hdr_plus_from_t35(metadata, gb->buffer,
> + bytestream2_get_bytes_left(gb));
> if (err < 0) {
> av_free(metadata);
> return err;
> @@ -78,8 +78,8 @@ static int decode_registered_user_data_dynamic_hdr_vivid(HEVCSEIDynamicHDRVivid
> if (!metadata)
> return AVERROR(ENOMEM);
>
> - err = ff_parse_itu_t_t35_to_dynamic_hdr_vivid(metadata,
> - gb->buffer, bytestream2_get_bytes_left(gb));
> + err = av_dynamic_hdr_vivid_from_t35(metadata,
> + gb->buffer, bytestream2_get_bytes_left(gb));
> if (err < 0) {
> av_free(metadata);
> return err;
> diff --git a/libavutil/hdr_dynamic_metadata.c b/libavutil/hdr_dynamic_metadata.c
> index 0fa1ee82de..98f399b032 100644
> --- a/libavutil/hdr_dynamic_metadata.c
> +++ b/libavutil/hdr_dynamic_metadata.c
> @@ -20,6 +20,16 @@
>
> #include "hdr_dynamic_metadata.h"
> #include "mem.h"
> +#include "libavcodec/get_bits.h"
> +#include "libavcodec/put_bits.h"
> +
> +static const int64_t luminance_den = 1;
> +static const int32_t peak_luminance_den = 15;
> +static const int64_t rgb_den = 100000;
> +static const int32_t fraction_pixel_den = 1000;
> +static const int32_t knee_point_den = 4095;
> +static const int32_t bezier_anchor_den = 1023;
> +static const int32_t saturation_weight_den = 8;
>
> AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size)
> {
> @@ -45,3 +55,173 @@ AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame)
>
> return (AVDynamicHDRPlus *)side_data->data;
> }
> +
> +int av_dynamic_hdr_plus_from_t35(AVDynamicHDRPlus *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) < 10)
> + return AVERROR_INVALIDDATA;
> +
> + s->application_version = get_bits(gb, 8);
> + s->num_windows = get_bits(gb, 2);
> +
> + if (s->num_windows < 1 || s->num_windows > 3) {
> + return AVERROR_INVALIDDATA;
> + }
> +
> + if (get_bits_left(gb) < ((19 * 8 + 1) * (s->num_windows - 1)))
> + return AVERROR_INVALIDDATA;
> +
> + for (int w = 1; w < s->num_windows; w++) {
> + // The corners are set to absolute coordinates here. They should be
> + // converted to the relative coordinates (in [0, 1]) in the decoder.
> + AVHDRPlusColorTransformParams *params = &s->params[w];
> + params->window_upper_left_corner_x =
> + (AVRational){get_bits(gb, 16), 1};
> + params->window_upper_left_corner_y =
> + (AVRational){get_bits(gb, 16), 1};
> + params->window_lower_right_corner_x =
> + (AVRational){get_bits(gb, 16), 1};
> + params->window_lower_right_corner_y =
> + (AVRational){get_bits(gb, 16), 1};
> +
> + params->center_of_ellipse_x = get_bits(gb, 16);
> + params->center_of_ellipse_y = get_bits(gb, 16);
> + params->rotation_angle = get_bits(gb, 8);
> + params->semimajor_axis_internal_ellipse = get_bits(gb, 16);
> + params->semimajor_axis_external_ellipse = get_bits(gb, 16);
> + params->semiminor_axis_external_ellipse = get_bits(gb, 16);
> + params->overlap_process_option = get_bits1(gb);
> + }
> +
> + if (get_bits_left(gb) < 28)
> + return AVERROR_INVALIDDATA;
> +
> + s->targeted_system_display_maximum_luminance =
> + (AVRational){get_bits_long(gb, 27), luminance_den};
> + s->targeted_system_display_actual_peak_luminance_flag = get_bits1(gb);
> +
> + if (s->targeted_system_display_actual_peak_luminance_flag) {
> + int rows, cols;
> + if (get_bits_left(gb) < 10)
> + return AVERROR_INVALIDDATA;
> + rows = get_bits(gb, 5);
> + cols = get_bits(gb, 5);
> + if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
> + return AVERROR_INVALIDDATA;
> + }
> + s->num_rows_targeted_system_display_actual_peak_luminance = rows;
> + s->num_cols_targeted_system_display_actual_peak_luminance = cols;
> +
> + if (get_bits_left(gb) < (rows * cols * 4))
> + return AVERROR_INVALIDDATA;
> +
> + for (int i = 0; i < rows; i++) {
> + for (int j = 0; j < cols; j++) {
> + s->targeted_system_display_actual_peak_luminance[i][j] =
> + (AVRational){get_bits(gb, 4), peak_luminance_den};
> + }
> + }
> + }
> + for (int w = 0; w < s->num_windows; w++) {
> + AVHDRPlusColorTransformParams *params = &s->params[w];
> + if (get_bits_left(gb) < (3 * 17 + 17 + 4))
> + return AVERROR_INVALIDDATA;
> +
> + for (int i = 0; i < 3; i++) {
> + params->maxscl[i] =
> + (AVRational){get_bits(gb, 17), rgb_den};
> + }
> + params->average_maxrgb =
> + (AVRational){get_bits(gb, 17), rgb_den};
> + params->num_distribution_maxrgb_percentiles = get_bits(gb, 4);
> +
> + if (get_bits_left(gb) <
> + (params->num_distribution_maxrgb_percentiles * 24))
> + return AVERROR_INVALIDDATA;
> +
> + for (int i = 0; i < params->num_distribution_maxrgb_percentiles; i++) {
> + params->distribution_maxrgb[i].percentage = get_bits(gb, 7);
> + params->distribution_maxrgb[i].percentile =
> + (AVRational){get_bits(gb, 17), rgb_den};
> + }
> +
> + if (get_bits_left(gb) < 10)
> + return AVERROR_INVALIDDATA;
> +
> + params->fraction_bright_pixels = (AVRational){get_bits(gb, 10), fraction_pixel_den};
> + }
> + if (get_bits_left(gb) < 1)
> + return AVERROR_INVALIDDATA;
> + s->mastering_display_actual_peak_luminance_flag = get_bits1(gb);
> + if (s->mastering_display_actual_peak_luminance_flag) {
> + int rows, cols;
> + if (get_bits_left(gb) < 10)
> + return AVERROR_INVALIDDATA;
> + rows = get_bits(gb, 5);
> + cols = get_bits(gb, 5);
> + if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
> + return AVERROR_INVALIDDATA;
> + }
> + s->num_rows_mastering_display_actual_peak_luminance = rows;
> + s->num_cols_mastering_display_actual_peak_luminance = cols;
> +
> + if (get_bits_left(gb) < (rows * cols * 4))
> + return AVERROR_INVALIDDATA;
> +
> + for (int i = 0; i < rows; i++) {
> + for (int j = 0; j < cols; j++) {
> + s->mastering_display_actual_peak_luminance[i][j] =
> + (AVRational){get_bits(gb, 4), peak_luminance_den};
> + }
> + }
> + }
> +
> + for (int w = 0; w < s->num_windows; w++) {
> + AVHDRPlusColorTransformParams *params = &s->params[w];
> + if (get_bits_left(gb) < 1)
> + return AVERROR_INVALIDDATA;
> +
> + params->tone_mapping_flag = get_bits1(gb);
> + if (params->tone_mapping_flag) {
> + if (get_bits_left(gb) < 28)
> + return AVERROR_INVALIDDATA;
> +
> + params->knee_point_x =
> + (AVRational){get_bits(gb, 12), knee_point_den};
> + params->knee_point_y =
> + (AVRational){get_bits(gb, 12), knee_point_den};
> + params->num_bezier_curve_anchors = get_bits(gb, 4);
> +
> + if (get_bits_left(gb) < (params->num_bezier_curve_anchors * 10))
> + return AVERROR_INVALIDDATA;
> +
> + for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
> + params->bezier_curve_anchors[i] =
> + (AVRational){get_bits(gb, 10), bezier_anchor_den};
> + }
> + }
> +
> + if (get_bits_left(gb) < 1)
> + return AVERROR_INVALIDDATA;
> + params->color_saturation_mapping_flag = get_bits1(gb);
> + if (params->color_saturation_mapping_flag) {
> + if (get_bits_left(gb) < 6)
> + return AVERROR_INVALIDDATA;
> + params->color_saturation_weight =
> + (AVRational){get_bits(gb, 6), saturation_weight_den};
> + }
> + }
> +
> + return 0;
> +}
> diff --git a/libavutil/hdr_dynamic_metadata.h b/libavutil/hdr_dynamic_metadata.h
> index 2d72de56ae..1f953ef1f5 100644
> --- a/libavutil/hdr_dynamic_metadata.h
> +++ b/libavutil/hdr_dynamic_metadata.h
> @@ -340,4 +340,15 @@ AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size);
> */
> AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame);
>
> +/**
> + * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRPlus).
> + * @param s A pointer containing the decoded AVDynamicHDRPlus structure.
> + * @param data The byte array containing the raw ITU-T T.35 data.
> + * @param size Size of the data array in bytes.
> + *
> + * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
> + */
> +int av_dynamic_hdr_plus_from_t35(AVDynamicHDRPlus *s, const uint8_t *data,
> + int size);
> +
> #endif /* AVUTIL_HDR_DYNAMIC_METADATA_H */
> diff --git a/libavutil/hdr_dynamic_vivid_metadata.c b/libavutil/hdr_dynamic_vivid_metadata.c
> index 32da01f587..1218644123 100644
> --- a/libavutil/hdr_dynamic_vivid_metadata.c
> +++ b/libavutil/hdr_dynamic_vivid_metadata.c
> @@ -20,6 +20,17 @@
>
> #include "hdr_dynamic_vivid_metadata.h"
> #include "mem.h"
> +#include "libavcodec/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;
>
> AVDynamicHDRVivid *av_dynamic_hdr_vivid_alloc(size_t *size)
> {
> @@ -45,3 +56,112 @@ AVDynamicHDRVivid *av_dynamic_hdr_vivid_create_side_data(AVFrame *frame)
>
> return (AVDynamicHDRVivid *)side_data->data;
> }
> +
> +int av_dynamic_hdr_vivid_from_t35(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);
> + if (s->system_start_code == 0x01) {
> + 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);
> + if (tm_params->base_param_Delta_enable_mode == 2 || tm_params->base_param_Delta_enable_mode == 6)
> + tm_params->base_param_Delta = (AVRational){get_bits(gb, 7) * -1, base_param_Delta_den};
> + else
> + 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) {
> + 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;
> + for (int j = 0; j < tm_params->three_Spline_num; j++) {
> + tm_params->three_Spline_TH_mode = get_bits(gb, 2);
> + if (tm_params->three_Spline_TH_mode == 0 || tm_params->three_Spline_TH_mode == 2) {
> + if (get_bits_left(gb) < 8)
> + return AVERROR_INVALIDDATA;
> + tm_params->three_Spline_TH_enable_MB = (AVRational){get_bits(gb, 8), 255};
> + }
> + tm_params->three_Spline_TH_enable = (AVRational){get_bits(gb, 12), 4095};
> + tm_params->three_Spline_TH_Delta1 = (AVRational){get_bits(gb, 10), 1023};
> + tm_params->three_Spline_TH_Delta2 = (AVRational){get_bits(gb, 10), 1023};
> + tm_params->three_Spline_enable_Strength = (AVRational){get_bits(gb, 8), 255};
> + }
> + } else {
> + tm_params->three_Spline_num = 1;
> + tm_params->three_Spline_TH_mode = 0;
> + }
> +
> + }
> + }
> + }
> +
> + 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;
> +}
> diff --git a/libavutil/hdr_dynamic_vivid_metadata.h b/libavutil/hdr_dynamic_vivid_metadata.h
> index a34f83072c..16a84ce343 100644
> --- a/libavutil/hdr_dynamic_vivid_metadata.h
> +++ b/libavutil/hdr_dynamic_vivid_metadata.h
> @@ -282,4 +282,15 @@ AVDynamicHDRVivid *av_dynamic_hdr_vivid_alloc(size_t *size);
> */
> AVDynamicHDRVivid *av_dynamic_hdr_vivid_create_side_data(AVFrame *frame);
>
> +/**
> + * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
> + * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
> + * @param data The byte array containing the raw ITU-T T.35 data.
> + * @param size Size of the data array in bytes.
> + *
> + * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
> + */
> +int av_dynamic_hdr_vivid_from_t35(AVDynamicHDRVivid *s, const uint8_t *data,
> + int size);
Who has an interest in this function being public?
- Andreas
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil
2023-03-13 16:09 ` Andreas Rheinhardt
@ 2023-03-13 16:56 ` Raphaël Zumer
2023-03-13 16:58 ` James Almer
0 siblings, 1 reply; 10+ messages in thread
From: Raphaël Zumer @ 2023-03-13 16:56 UTC (permalink / raw)
To: ffmpeg-devel
On 3/13/23 12:09, Andreas Rheinhardt wrote:
>>
>> +/**
>> + * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
>> + * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
>> + * @param data The byte array containing the raw ITU-T T.35 data.
>> + * @param size Size of the data array in bytes.
>> + *
>> + * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
>> + */
>> +int av_dynamic_hdr_vivid_from_t35(AVDynamicHDRVivid *s, const uint8_t *data,
>> + int size);
> Who has an interest in this function being public?
>
> - Andreas
I have no need for it so can change it to avpriv_ considering there's no serialization function available for it, if there's no objection to that.
Raphaël Zumer
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil
2023-03-13 16:56 ` Raphaël Zumer
@ 2023-03-13 16:58 ` James Almer
2023-03-13 17:05 ` Raphaël Zumer
0 siblings, 1 reply; 10+ messages in thread
From: James Almer @ 2023-03-13 16:58 UTC (permalink / raw)
To: ffmpeg-devel
On 3/13/2023 1:56 PM, Raphaël Zumer wrote:
> On 3/13/23 12:09, Andreas Rheinhardt wrote:
>>>
>>> +/**
>>> + * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
>>> + * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
>>> + * @param data The byte array containing the raw ITU-T T.35 data.
>>> + * @param size Size of the data array in bytes.
>>> + *
>>> + * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
>>> + */
>>> +int av_dynamic_hdr_vivid_from_t35(AVDynamicHDRVivid *s, const uint8_t *data,
>>> + int size);
>> Who has an interest in this function being public?
>>
>> - Andreas
>
> I have no need for it so can change it to avpriv_ considering there's no serialization function available for it, if there's no objection to that.
>
> Raphaël Zumer
No, just don't move it out of libavcodec. Unless it's needed elsewhere,
it can stay there as is.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil
2023-03-13 16:58 ` James Almer
@ 2023-03-13 17:05 ` Raphaël Zumer
2023-03-13 17:10 ` James Almer
0 siblings, 1 reply; 10+ messages in thread
From: Raphaël Zumer @ 2023-03-13 17:05 UTC (permalink / raw)
To: ffmpeg-devel
On 3/13/23 12:58, James Almer wrote:
> On 3/13/2023 1:56 PM, Raphaël Zumer wrote:
>> On 3/13/23 12:09, Andreas Rheinhardt wrote:
>>>>
>>>> +/**
>>>> + * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
>>>> + * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
>>>> + * @param data The byte array containing the raw ITU-T T.35 data.
>>>> + * @param size Size of the data array in bytes.
>>>> + *
>>>> + * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
>>>> + */
>>>> +int av_dynamic_hdr_vivid_from_t35(AVDynamicHDRVivid *s, const uint8_t *data,
>>>> + int size);
>>> Who has an interest in this function being public?
>>>
>>> - Andreas
>> I have no need for it so can change it to avpriv_ considering there's no serialization function available for it, if there's no objection to that.
>>
>> Raphaël Zumer
> No, just don't move it out of libavcodec. Unless it's needed elsewhere,
> it can stay there as is.
The inconsistency between HDR10+ and Vivid will be confusing IMO if one of them is left in libavcodec and the other is moved to libavutil. What are the specific concerns with making it public (or avpriv), aside from it not being useful without a corresponding serialization function?
RZ
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil
2023-03-13 17:05 ` Raphaël Zumer
@ 2023-03-13 17:10 ` James Almer
2023-03-13 17:34 ` Raphaël Zumer
0 siblings, 1 reply; 10+ messages in thread
From: James Almer @ 2023-03-13 17:10 UTC (permalink / raw)
To: ffmpeg-devel
On 3/13/2023 2:05 PM, Raphaël Zumer wrote:
> On 3/13/23 12:58, James Almer wrote:
>> On 3/13/2023 1:56 PM, Raphaël Zumer wrote:
>>> On 3/13/23 12:09, Andreas Rheinhardt wrote:
>>>>>
>>>>> +/**
>>>>> + * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
>>>>> + * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
>>>>> + * @param data The byte array containing the raw ITU-T T.35 data.
>>>>> + * @param size Size of the data array in bytes.
>>>>> + *
>>>>> + * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
>>>>> + */
>>>>> +int av_dynamic_hdr_vivid_from_t35(AVDynamicHDRVivid *s, const uint8_t *data,
>>>>> + int size);
>>>> Who has an interest in this function being public?
>>>>
>>>> - Andreas
>>> I have no need for it so can change it to avpriv_ considering there's no serialization function available for it, if there's no objection to that.
>>>
>>> Raphaël Zumer
>> No, just don't move it out of libavcodec. Unless it's needed elsewhere,
>> it can stay there as is.
>
> The inconsistency between HDR10+ and Vivid will be confusing IMO if one of them is left in libavcodec and the other is moved to libavutil.
Why? The HDR10+ one is useful for libraries like lavf and external
container parsers, the Vivid one isn't.
> What are the specific concerns with making it public (or avpriv), aside from it not being useful without a corresponding serialization function?
You said it, it serves no purpose. Making something public (or exposed
internally as avpriv_) is done only when it will be used by code outside
the library where it resides.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil
2023-03-13 17:10 ` James Almer
@ 2023-03-13 17:34 ` Raphaël Zumer
2023-03-13 17:42 ` James Almer
0 siblings, 1 reply; 10+ messages in thread
From: Raphaël Zumer @ 2023-03-13 17:34 UTC (permalink / raw)
To: ffmpeg-devel
On 3/13/23 13:10, James Almer wrote:
> On 3/13/2023 2:05 PM, Raphaël Zumer wrote:
>> On 3/13/23 12:58, James Almer wrote:
>>> On 3/13/2023 1:56 PM, Raphaël Zumer wrote:
>>>> On 3/13/23 12:09, Andreas Rheinhardt wrote:
>>>>>>
>>>>>> +/**
>>>>>> + * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
>>>>>> + * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
>>>>>> + * @param data The byte array containing the raw ITU-T T.35 data.
>>>>>> + * @param size Size of the data array in bytes.
>>>>>> + *
>>>>>> + * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
>>>>>> + */
>>>>>> +int av_dynamic_hdr_vivid_from_t35(AVDynamicHDRVivid *s, const uint8_t *data,
>>>>>> + int size);
>>>>> Who has an interest in this function being public?
>>>>>
>>>>> - Andreas
>>>> I have no need for it so can change it to avpriv_ considering there's no serialization function available for it, if there's no objection to that.
>>>>
>>>> Raphaël Zumer
>>> No, just don't move it out of libavcodec. Unless it's needed elsewhere,
>>> it can stay there as is.
>> The inconsistency between HDR10+ and Vivid will be confusing IMO if one of them is left in libavcodec and the other is moved to libavutil.
> Why? The HDR10+ one is useful for libraries like lavf and external
> container parsers, the Vivid one isn't.
That is obvious in this specific context, but for someone simply looking at the internals and dynamic HDR metadata handling, it would be odd to find a lone function for Vivid HDR parsing sitting in libavcodec while everything else (including the definition for the parsed Vivid metadata structure) is in one place in libavutil.
>> What are the specific concerns with making it public (or avpriv), aside from it not being useful without a corresponding serialization function?
> You said it, it serves no purpose. Making something public (or exposed
> internally as avpriv_) is done only when it will be used by code outside
> the library where it resides.
If it is standard practice in the FFmpeg codebase then I won't argue further, I just think that avpriv accomplishes the desired outcome (keep that function private) without violating best practices (keeping logically-related code together).
RZ
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil
2023-03-13 17:34 ` Raphaël Zumer
@ 2023-03-13 17:42 ` James Almer
0 siblings, 0 replies; 10+ messages in thread
From: James Almer @ 2023-03-13 17:42 UTC (permalink / raw)
To: ffmpeg-devel
On 3/13/2023 2:34 PM, Raphaël Zumer wrote:
>
> On 3/13/23 13:10, James Almer wrote:
>> On 3/13/2023 2:05 PM, Raphaël Zumer wrote:
>>> On 3/13/23 12:58, James Almer wrote:
>>>> On 3/13/2023 1:56 PM, Raphaël Zumer wrote:
>>>>> On 3/13/23 12:09, Andreas Rheinhardt wrote:
>>>>>>>
>>>>>>> +/**
>>>>>>> + * Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRVivid).
>>>>>>> + * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
>>>>>>> + * @param data The byte array containing the raw ITU-T T.35 data.
>>>>>>> + * @param size Size of the data array in bytes.
>>>>>>> + *
>>>>>>> + * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
>>>>>>> + */
>>>>>>> +int av_dynamic_hdr_vivid_from_t35(AVDynamicHDRVivid *s, const uint8_t *data,
>>>>>>> + int size);
>>>>>> Who has an interest in this function being public?
>>>>>>
>>>>>> - Andreas
>>>>> I have no need for it so can change it to avpriv_ considering there's no serialization function available for it, if there's no objection to that.
>>>>>
>>>>> Raphaël Zumer
>>>> No, just don't move it out of libavcodec. Unless it's needed elsewhere,
>>>> it can stay there as is.
>>> The inconsistency between HDR10+ and Vivid will be confusing IMO if one of them is left in libavcodec and the other is moved to libavutil.
>> Why? The HDR10+ one is useful for libraries like lavf and external
>> container parsers, the Vivid one isn't.
>
> That is obvious in this specific context, but for someone simply looking at the internals and dynamic HDR metadata handling, it would be odd to find a lone function for Vivid HDR parsing sitting in libavcodec while everything else (including the definition for the parsed Vivid metadata structure) is in one place in libavutil.
The metadata structures for both HDR10+ and Vivid are in lavu and public
because they are used by AVFrame side data types. The parsing code that
fills the Vivid struct is in lavc and internal because nothing outside
of it needs it. Meanwhile, the function filling the HDR10+ struct can
and will be used by lavf, so moving it to lavu and making it public like
you're doing here makes sense and is useful.
If at some point the Vivid parsing code is deemed useful outside of
lavc, it can be moved and made public.
>
>>> What are the specific concerns with making it public (or avpriv), aside from it not being useful without a corresponding serialization function?
>> You said it, it serves no purpose. Making something public (or exposed
>> internally as avpriv_) is done only when it will be used by code outside
>> the library where it resides.
>
> If it is standard practice in the FFmpeg codebase then I won't argue further, I just think that avpriv accomplishes the desired outcome (keep that function private) without violating best practices (keeping logically-related code together).
Using avpriv_ here would make even less sense. It'd be exposed (And thus
tied to the ABI) yet not public, which is for even less gain since lavc
will still be its sole user.
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread
* [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil
[not found] <ec92f40f-0d6b-109b-d48e-1f24a0106f4b@tebako.net>
@ 2023-02-27 16:53 ` Raphaël Zumer
0 siblings, 0 replies; 10+ messages in thread
From: Raphaël Zumer @ 2023-02-27 16:53 UTC (permalink / raw)
To: ffmpeg-devel
This patch set implements serialization for HDR10+ dynamic metadata
(AVDynamicHDRPlus), which is the inverse operation of the existing
ff_parse_itu_t_t35_to_dynamic_hdr10_plus() function. It also moves both
functions from libavcodec to libavutil and makes them public. For
consistency, the equivalent vivid HDR parsing function is also migrated,
but I did not implement serialization for it. Finally, the patch renames
those functions to av_dynamic_hdr_plus_from_t35() (for parsing) and
av_dynamic_hdr_plus_to_t35 (for serialization), with the equivalent
change being made for vivid as well.
The motivation for this change is to allow users to easily convert
HDR10+ side data (which is parsed into AVDynamicHDRPlus) to a standard
ITU-T T.35 payload that can be passed directly to applications that
expect HDR10+ dynamic metadata in that format (e.g. x265 and rav1e
encoders).
The return value of the serialization function is AVBufferRef*, which I
expect to be contentious. Payload size is not embedded in the T.35 data,
so it must be calculated, used to allocate a buffer, and returned along
with that buffer to the user. As far as I'm aware, AVBufferRef is the
simplest way to do that, but I will be happy to consider alternative
solutions.
Please let me know if it is preferred to bump libavutil with the first
commit, or with both of them, considering there are public API changes
associated with each one.
Raphaël Zumer
Signed-off-by: Raphaël Zumer <rzumer@tebako.net>
---
libavcodec/Makefile | 3 +-
libavcodec/dynamic_hdr10_plus.c | 198 -------------------------
libavcodec/dynamic_hdr10_plus.h | 35 -----
libavcodec/dynamic_hdr_vivid.c | 139 -----------------
libavcodec/dynamic_hdr_vivid.h | 35 -----
libavcodec/h2645_sei.c | 12 +-
libavutil/hdr_dynamic_metadata.c | 180 ++++++++++++++++++++++
libavutil/hdr_dynamic_metadata.h | 11 ++
libavutil/hdr_dynamic_vivid_metadata.c | 120 +++++++++++++++
libavutil/hdr_dynamic_vivid_metadata.h | 11 ++
10 files changed, 329 insertions(+), 415 deletions(-)
delete mode 100644 libavcodec/dynamic_hdr10_plus.c
delete mode 100644 libavcodec/dynamic_hdr10_plus.h
delete mode 100644 libavcodec/dynamic_hdr_vivid.c
delete mode 100644 libavcodec/dynamic_hdr_vivid.h
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 389253f5d0..4bdfcbab12 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -103,8 +103,7 @@ OBJS-$(CONFIG_H264QPEL) += h264qpel.o
OBJS-$(CONFIG_H264_SEI) += h264_sei.o h2645_sei.o
OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o hevc_ps.o
hevc_data.o \
h2645data.o h2645_parse.o
h2645_vui.o
-OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o \
- dynamic_hdr10_plus.o
dynamic_hdr_vivid.o
+OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o
OBJS-$(CONFIG_HPELDSP) += hpeldsp.o
OBJS-$(CONFIG_HUFFMAN) += huffman.o
OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o
diff --git a/libavcodec/dynamic_hdr10_plus.c
b/libavcodec/dynamic_hdr10_plus.c
deleted file mode 100644
index 34a44aac65..0000000000
--- a/libavcodec/dynamic_hdr10_plus.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * 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_hdr10_plus.h"
-#include "get_bits.h"
-
-static const int64_t luminance_den = 1;
-static const int32_t peak_luminance_den = 15;
-static const int64_t rgb_den = 100000;
-static const int32_t fraction_pixel_den = 1000;
-static const int32_t knee_point_den = 4095;
-static const int32_t bezier_anchor_den = 1023;
-static const int32_t saturation_weight_den = 8;
-
-int ff_parse_itu_t_t35_to_dynamic_hdr10_plus(AVDynamicHDRPlus *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) < 10)
- return AVERROR_INVALIDDATA;
-
- s->application_version = get_bits(gb, 8);
- s->num_windows = get_bits(gb, 2);
-
- if (s->num_windows < 1 || s->num_windows > 3) {
- return AVERROR_INVALIDDATA;
- }
-
- if (get_bits_left(gb) < ((19 * 8 + 1) * (s->num_windows - 1)))
- return AVERROR_INVALIDDATA;
-
- for (int w = 1; w < s->num_windows; w++) {
- // The corners are set to absolute coordinates here. They should be
- // converted to the relative coordinates (in [0, 1]) in the
decoder.
- AVHDRPlusColorTransformParams *params = &s->params[w];
- params->window_upper_left_corner_x =
- (AVRational){get_bits(gb, 16), 1};
- params->window_upper_left_corner_y =
- (AVRational){get_bits(gb, 16), 1};
- params->window_lower_right_corner_x =
- (AVRational){get_bits(gb, 16), 1};
- params->window_lower_right_corner_y =
- (AVRational){get_bits(gb, 16), 1};
-
- params->center_of_ellipse_x = get_bits(gb, 16);
- params->center_of_ellipse_y = get_bits(gb, 16);
- params->rotation_angle = get_bits(gb, 8);
- params->semimajor_axis_internal_ellipse = get_bits(gb, 16);
- params->semimajor_axis_external_ellipse = get_bits(gb, 16);
- params->semiminor_axis_external_ellipse = get_bits(gb, 16);
- params->overlap_process_option = get_bits1(gb);
- }
-
- if (get_bits_left(gb) < 28)
- return AVERROR_INVALIDDATA;
-
- s->targeted_system_display_maximum_luminance =
- (AVRational){get_bits_long(gb, 27), luminance_den};
- s->targeted_system_display_actual_peak_luminance_flag = get_bits1(gb);
-
- if (s->targeted_system_display_actual_peak_luminance_flag) {
- int rows, cols;
- if (get_bits_left(gb) < 10)
- return AVERROR_INVALIDDATA;
- rows = get_bits(gb, 5);
- cols = get_bits(gb, 5);
- if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
- return AVERROR_INVALIDDATA;
- }
- s->num_rows_targeted_system_display_actual_peak_luminance = rows;
- s->num_cols_targeted_system_display_actual_peak_luminance = cols;
-
- if (get_bits_left(gb) < (rows * cols * 4))
- return AVERROR_INVALIDDATA;
-
- for (int i = 0; i < rows; i++) {
- for (int j = 0; j < cols; j++) {
- s->targeted_system_display_actual_peak_luminance[i][j] =
- (AVRational){get_bits(gb, 4), peak_luminance_den};
- }
- }
- }
- for (int w = 0; w < s->num_windows; w++) {
- AVHDRPlusColorTransformParams *params = &s->params[w];
- if (get_bits_left(gb) < (3 * 17 + 17 + 4))
- return AVERROR_INVALIDDATA;
-
- for (int i = 0; i < 3; i++) {
- params->maxscl[i] =
- (AVRational){get_bits(gb, 17), rgb_den};
- }
- params->average_maxrgb =
- (AVRational){get_bits(gb, 17), rgb_den};
- params->num_distribution_maxrgb_percentiles = get_bits(gb, 4);
-
- if (get_bits_left(gb) <
- (params->num_distribution_maxrgb_percentiles * 24))
- return AVERROR_INVALIDDATA;
-
- for (int i = 0; i <
params->num_distribution_maxrgb_percentiles; i++) {
- params->distribution_maxrgb[i].percentage = get_bits(gb, 7);
- params->distribution_maxrgb[i].percentile =
- (AVRational){get_bits(gb, 17), rgb_den};
- }
-
- if (get_bits_left(gb) < 10)
- return AVERROR_INVALIDDATA;
-
- params->fraction_bright_pixels = (AVRational){get_bits(gb, 10),
fraction_pixel_den};
- }
- if (get_bits_left(gb) < 1)
- return AVERROR_INVALIDDATA;
- s->mastering_display_actual_peak_luminance_flag = get_bits1(gb);
- if (s->mastering_display_actual_peak_luminance_flag) {
- int rows, cols;
- if (get_bits_left(gb) < 10)
- return AVERROR_INVALIDDATA;
- rows = get_bits(gb, 5);
- cols = get_bits(gb, 5);
- if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
- return AVERROR_INVALIDDATA;
- }
- s->num_rows_mastering_display_actual_peak_luminance = rows;
- s->num_cols_mastering_display_actual_peak_luminance = cols;
-
- if (get_bits_left(gb) < (rows * cols * 4))
- return AVERROR_INVALIDDATA;
-
- for (int i = 0; i < rows; i++) {
- for (int j = 0; j < cols; j++) {
- s->mastering_display_actual_peak_luminance[i][j] =
- (AVRational){get_bits(gb, 4), peak_luminance_den};
- }
- }
- }
-
- for (int w = 0; w < s->num_windows; w++) {
- AVHDRPlusColorTransformParams *params = &s->params[w];
- if (get_bits_left(gb) < 1)
- return AVERROR_INVALIDDATA;
-
- params->tone_mapping_flag = get_bits1(gb);
- if (params->tone_mapping_flag) {
- if (get_bits_left(gb) < 28)
- return AVERROR_INVALIDDATA;
-
- params->knee_point_x =
- (AVRational){get_bits(gb, 12), knee_point_den};
- params->knee_point_y =
- (AVRational){get_bits(gb, 12), knee_point_den};
- params->num_bezier_curve_anchors = get_bits(gb, 4);
-
- if (get_bits_left(gb) < (params->num_bezier_curve_anchors *
10))
- return AVERROR_INVALIDDATA;
-
- for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
- params->bezier_curve_anchors[i] =
- (AVRational){get_bits(gb, 10), bezier_anchor_den};
- }
- }
-
- if (get_bits_left(gb) < 1)
- return AVERROR_INVALIDDATA;
- params->color_saturation_mapping_flag = get_bits1(gb);
- if (params->color_saturation_mapping_flag) {
- if (get_bits_left(gb) < 6)
- return AVERROR_INVALIDDATA;
- params->color_saturation_weight =
- (AVRational){get_bits(gb, 6), saturation_weight_den};
- }
- }
-
- return 0;
-}
diff --git a/libavcodec/dynamic_hdr10_plus.h
b/libavcodec/dynamic_hdr10_plus.h
deleted file mode 100644
index cd7acf0432..0000000000
--- a/libavcodec/dynamic_hdr10_plus.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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
- */
-
-#ifndef AVCODEC_DYNAMIC_HDR10_PLUS_H
-#define AVCODEC_DYNAMIC_HDR10_PLUS_H
-
-#include "libavutil/hdr_dynamic_metadata.h"
-
-/**
- * Parse the user data registered ITU-T T.35 to AVbuffer
(AVDynamicHDRPlus).
- * @param s A pointer containing the decoded AVDynamicHDRPlus structure.
- * @param data The byte array containing the raw ITU-T T.35 data.
- * @param size Size of the data array in bytes.
- *
- * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
- */
-int ff_parse_itu_t_t35_to_dynamic_hdr10_plus(AVDynamicHDRPlus *s, const
uint8_t *data,
- int size);
-
-#endif /* AVCODEC_DYNAMIC_HDR10_PLUS_H */
diff --git a/libavcodec/dynamic_hdr_vivid.c b/libavcodec/dynamic_hdr_vivid.c
deleted file mode 100644
index d689669dec..0000000000
--- a/libavcodec/dynamic_hdr_vivid.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * 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);
- if (s->system_start_code == 0x01) {
- 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);
- if (tm_params->base_param_Delta_enable_mode ==
2 || tm_params->base_param_Delta_enable_mode == 6)
- tm_params->base_param_Delta =
(AVRational){get_bits(gb, 7) * -1, base_param_Delta_den};
- else
- 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) {
- 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;
- for (int j = 0; j <
tm_params->three_Spline_num; j++) {
- tm_params->three_Spline_TH_mode =
get_bits(gb, 2);
- if (tm_params->three_Spline_TH_mode ==
0 || tm_params->three_Spline_TH_mode == 2) {
- if (get_bits_left(gb) < 8)
- return AVERROR_INVALIDDATA;
- tm_params->three_Spline_TH_enable_MB = (AVRational){get_bits(gb, 8),
255};
- }
- tm_params->three_Spline_TH_enable =
(AVRational){get_bits(gb, 12), 4095};
- tm_params->three_Spline_TH_Delta1 =
(AVRational){get_bits(gb, 10), 1023};
- tm_params->three_Spline_TH_Delta2 =
(AVRational){get_bits(gb, 10), 1023};
- tm_params->three_Spline_enable_Strength
= (AVRational){get_bits(gb, 8), 255};
- }
- } else {
- tm_params->three_Spline_num = 1;
- tm_params->three_Spline_TH_mode = 0;
- }
-
- }
- }
- }
-
- 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;
-}
diff --git a/libavcodec/dynamic_hdr_vivid.h b/libavcodec/dynamic_hdr_vivid.h
deleted file mode 100644
index d521b3d263..0000000000
--- a/libavcodec/dynamic_hdr_vivid.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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
- */
-
-#ifndef AVCODEC_DYNAMIC_HDR_VIVID_H
-#define AVCODEC_DYNAMIC_HDR_VIVID_H
-
-#include "libavutil/hdr_dynamic_vivid_metadata.h"
-
-/**
- * Parse the user data registered ITU-T T.35 to AVbuffer
(AVDynamicHDRVivid).
- * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
- * @param data The byte array containing the raw ITU-T T.35 data.
- * @param size Size of the data array in bytes.
- *
- * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
- */
-int ff_parse_itu_t_t35_to_dynamic_hdr_vivid(AVDynamicHDRVivid *s, const
uint8_t *data,
- int size);
-
-#endif /* AVCODEC_DYNAMIC_HDR_VIVID_H */
diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c
index 6e4a9a1af2..7a96bc6056 100644
--- a/libavcodec/h2645_sei.c
+++ b/libavcodec/h2645_sei.c
@@ -27,14 +27,14 @@
#include "libavutil/ambient_viewing_environment.h"
#include "libavutil/display.h"
+#include "libavutil/hdr_dynamic_metadata.h"
+#include "libavutil/hdr_dynamic_vivid_metadata.h"
#include "libavutil/film_grain_params.h"
#include "libavutil/pixdesc.h"
#include "libavutil/stereo3d.h"
#include "atsc_a53.h"
#include "avcodec.h"
-#include "dynamic_hdr10_plus.h"
-#include "dynamic_hdr_vivid.h"
#include "get_bits.h"
#include "golomb.h"
#include "h2645_sei.h"
@@ -52,8 +52,8 @@ static int
decode_registered_user_data_dynamic_hdr_plus(HEVCSEIDynamicHDRPlus *s
if (!metadata)
return AVERROR(ENOMEM);
- err = ff_parse_itu_t_t35_to_dynamic_hdr10_plus(metadata, gb->buffer,
- bytestream2_get_bytes_left(gb));
+ err = av_dynamic_hdr_plus_from_t35(metadata, gb->buffer,
+ bytestream2_get_bytes_left(gb));
if (err < 0) {
av_free(metadata);
return err;
@@ -78,8 +78,8 @@ static int
decode_registered_user_data_dynamic_hdr_vivid(HEVCSEIDynamicHDRVivid
if (!metadata)
return AVERROR(ENOMEM);
- err = ff_parse_itu_t_t35_to_dynamic_hdr_vivid(metadata,
- gb->buffer,
bytestream2_get_bytes_left(gb));
+ err = av_dynamic_hdr_vivid_from_t35(metadata,
+ gb->buffer,
bytestream2_get_bytes_left(gb));
if (err < 0) {
av_free(metadata);
return err;
diff --git a/libavutil/hdr_dynamic_metadata.c
b/libavutil/hdr_dynamic_metadata.c
index 0fa1ee82de..98f399b032 100644
--- a/libavutil/hdr_dynamic_metadata.c
+++ b/libavutil/hdr_dynamic_metadata.c
@@ -20,6 +20,16 @@
#include "hdr_dynamic_metadata.h"
#include "mem.h"
+#include "libavcodec/get_bits.h"
+#include "libavcodec/put_bits.h"
+
+static const int64_t luminance_den = 1;
+static const int32_t peak_luminance_den = 15;
+static const int64_t rgb_den = 100000;
+static const int32_t fraction_pixel_den = 1000;
+static const int32_t knee_point_den = 4095;
+static const int32_t bezier_anchor_den = 1023;
+static const int32_t saturation_weight_den = 8;
AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size)
{
@@ -45,3 +55,173 @@ AVDynamicHDRPlus
*av_dynamic_hdr_plus_create_side_data(AVFrame *frame)
return (AVDynamicHDRPlus *)side_data->data;
}
+
+int av_dynamic_hdr_plus_from_t35(AVDynamicHDRPlus *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) < 10)
+ return AVERROR_INVALIDDATA;
+
+ s->application_version = get_bits(gb, 8);
+ s->num_windows = get_bits(gb, 2);
+
+ if (s->num_windows < 1 || s->num_windows > 3) {
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (get_bits_left(gb) < ((19 * 8 + 1) * (s->num_windows - 1)))
+ return AVERROR_INVALIDDATA;
+
+ for (int w = 1; w < s->num_windows; w++) {
+ // The corners are set to absolute coordinates here. They should be
+ // converted to the relative coordinates (in [0, 1]) in the
decoder.
+ AVHDRPlusColorTransformParams *params = &s->params[w];
+ params->window_upper_left_corner_x =
+ (AVRational){get_bits(gb, 16), 1};
+ params->window_upper_left_corner_y =
+ (AVRational){get_bits(gb, 16), 1};
+ params->window_lower_right_corner_x =
+ (AVRational){get_bits(gb, 16), 1};
+ params->window_lower_right_corner_y =
+ (AVRational){get_bits(gb, 16), 1};
+
+ params->center_of_ellipse_x = get_bits(gb, 16);
+ params->center_of_ellipse_y = get_bits(gb, 16);
+ params->rotation_angle = get_bits(gb, 8);
+ params->semimajor_axis_internal_ellipse = get_bits(gb, 16);
+ params->semimajor_axis_external_ellipse = get_bits(gb, 16);
+ params->semiminor_axis_external_ellipse = get_bits(gb, 16);
+ params->overlap_process_option = get_bits1(gb);
+ }
+
+ if (get_bits_left(gb) < 28)
+ return AVERROR_INVALIDDATA;
+
+ s->targeted_system_display_maximum_luminance =
+ (AVRational){get_bits_long(gb, 27), luminance_den};
+ s->targeted_system_display_actual_peak_luminance_flag = get_bits1(gb);
+
+ if (s->targeted_system_display_actual_peak_luminance_flag) {
+ int rows, cols;
+ if (get_bits_left(gb) < 10)
+ return AVERROR_INVALIDDATA;
+ rows = get_bits(gb, 5);
+ cols = get_bits(gb, 5);
+ if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
+ return AVERROR_INVALIDDATA;
+ }
+ s->num_rows_targeted_system_display_actual_peak_luminance = rows;
+ s->num_cols_targeted_system_display_actual_peak_luminance = cols;
+
+ if (get_bits_left(gb) < (rows * cols * 4))
+ return AVERROR_INVALIDDATA;
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ s->targeted_system_display_actual_peak_luminance[i][j] =
+ (AVRational){get_bits(gb, 4), peak_luminance_den};
+ }
+ }
+ }
+ for (int w = 0; w < s->num_windows; w++) {
+ AVHDRPlusColorTransformParams *params = &s->params[w];
+ if (get_bits_left(gb) < (3 * 17 + 17 + 4))
+ return AVERROR_INVALIDDATA;
+
+ for (int i = 0; i < 3; i++) {
+ params->maxscl[i] =
+ (AVRational){get_bits(gb, 17), rgb_den};
+ }
+ params->average_maxrgb =
+ (AVRational){get_bits(gb, 17), rgb_den};
+ params->num_distribution_maxrgb_percentiles = get_bits(gb, 4);
+
+ if (get_bits_left(gb) <
+ (params->num_distribution_maxrgb_percentiles * 24))
+ return AVERROR_INVALIDDATA;
+
+ for (int i = 0; i <
params->num_distribution_maxrgb_percentiles; i++) {
+ params->distribution_maxrgb[i].percentage = get_bits(gb, 7);
+ params->distribution_maxrgb[i].percentile =
+ (AVRational){get_bits(gb, 17), rgb_den};
+ }
+
+ if (get_bits_left(gb) < 10)
+ return AVERROR_INVALIDDATA;
+
+ params->fraction_bright_pixels = (AVRational){get_bits(gb, 10),
fraction_pixel_den};
+ }
+ if (get_bits_left(gb) < 1)
+ return AVERROR_INVALIDDATA;
+ s->mastering_display_actual_peak_luminance_flag = get_bits1(gb);
+ if (s->mastering_display_actual_peak_luminance_flag) {
+ int rows, cols;
+ if (get_bits_left(gb) < 10)
+ return AVERROR_INVALIDDATA;
+ rows = get_bits(gb, 5);
+ cols = get_bits(gb, 5);
+ if (((rows < 2) || (rows > 25)) || ((cols < 2) || (cols > 25))) {
+ return AVERROR_INVALIDDATA;
+ }
+ s->num_rows_mastering_display_actual_peak_luminance = rows;
+ s->num_cols_mastering_display_actual_peak_luminance = cols;
+
+ if (get_bits_left(gb) < (rows * cols * 4))
+ return AVERROR_INVALIDDATA;
+
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < cols; j++) {
+ s->mastering_display_actual_peak_luminance[i][j] =
+ (AVRational){get_bits(gb, 4), peak_luminance_den};
+ }
+ }
+ }
+
+ for (int w = 0; w < s->num_windows; w++) {
+ AVHDRPlusColorTransformParams *params = &s->params[w];
+ if (get_bits_left(gb) < 1)
+ return AVERROR_INVALIDDATA;
+
+ params->tone_mapping_flag = get_bits1(gb);
+ if (params->tone_mapping_flag) {
+ if (get_bits_left(gb) < 28)
+ return AVERROR_INVALIDDATA;
+
+ params->knee_point_x =
+ (AVRational){get_bits(gb, 12), knee_point_den};
+ params->knee_point_y =
+ (AVRational){get_bits(gb, 12), knee_point_den};
+ params->num_bezier_curve_anchors = get_bits(gb, 4);
+
+ if (get_bits_left(gb) < (params->num_bezier_curve_anchors *
10))
+ return AVERROR_INVALIDDATA;
+
+ for (int i = 0; i < params->num_bezier_curve_anchors; i++) {
+ params->bezier_curve_anchors[i] =
+ (AVRational){get_bits(gb, 10), bezier_anchor_den};
+ }
+ }
+
+ if (get_bits_left(gb) < 1)
+ return AVERROR_INVALIDDATA;
+ params->color_saturation_mapping_flag = get_bits1(gb);
+ if (params->color_saturation_mapping_flag) {
+ if (get_bits_left(gb) < 6)
+ return AVERROR_INVALIDDATA;
+ params->color_saturation_weight =
+ (AVRational){get_bits(gb, 6), saturation_weight_den};
+ }
+ }
+
+ return 0;
+}
diff --git a/libavutil/hdr_dynamic_metadata.h
b/libavutil/hdr_dynamic_metadata.h
index 2d72de56ae..1f953ef1f5 100644
--- a/libavutil/hdr_dynamic_metadata.h
+++ b/libavutil/hdr_dynamic_metadata.h
@@ -340,4 +340,15 @@ AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t
*size);
*/
AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame);
+/**
+ * Parse the user data registered ITU-T T.35 to AVbuffer
(AVDynamicHDRPlus).
+ * @param s A pointer containing the decoded AVDynamicHDRPlus structure.
+ * @param data The byte array containing the raw ITU-T T.35 data.
+ * @param size Size of the data array in bytes.
+ *
+ * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
+ */
+int av_dynamic_hdr_plus_from_t35(AVDynamicHDRPlus *s, const uint8_t *data,
+ int size);
+
#endif /* AVUTIL_HDR_DYNAMIC_METADATA_H */
diff --git a/libavutil/hdr_dynamic_vivid_metadata.c
b/libavutil/hdr_dynamic_vivid_metadata.c
index 32da01f587..1218644123 100644
--- a/libavutil/hdr_dynamic_vivid_metadata.c
+++ b/libavutil/hdr_dynamic_vivid_metadata.c
@@ -20,6 +20,17 @@
#include "hdr_dynamic_vivid_metadata.h"
#include "mem.h"
+#include "libavcodec/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;
AVDynamicHDRVivid *av_dynamic_hdr_vivid_alloc(size_t *size)
{
@@ -45,3 +56,112 @@ AVDynamicHDRVivid
*av_dynamic_hdr_vivid_create_side_data(AVFrame *frame)
return (AVDynamicHDRVivid *)side_data->data;
}
+
+int av_dynamic_hdr_vivid_from_t35(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);
+ if (s->system_start_code == 0x01) {
+ 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);
+ if (tm_params->base_param_Delta_enable_mode ==
2 || tm_params->base_param_Delta_enable_mode == 6)
+ tm_params->base_param_Delta =
(AVRational){get_bits(gb, 7) * -1, base_param_Delta_den};
+ else
+ 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) {
+ 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;
+ for (int j = 0; j <
tm_params->three_Spline_num; j++) {
+ tm_params->three_Spline_TH_mode =
get_bits(gb, 2);
+ if (tm_params->three_Spline_TH_mode ==
0 || tm_params->three_Spline_TH_mode == 2) {
+ if (get_bits_left(gb) < 8)
+ return AVERROR_INVALIDDATA;
+ tm_params->three_Spline_TH_enable_MB = (AVRational){get_bits(gb, 8),
255};
+ }
+ tm_params->three_Spline_TH_enable =
(AVRational){get_bits(gb, 12), 4095};
+ tm_params->three_Spline_TH_Delta1 =
(AVRational){get_bits(gb, 10), 1023};
+ tm_params->three_Spline_TH_Delta2 =
(AVRational){get_bits(gb, 10), 1023};
+ tm_params->three_Spline_enable_Strength
= (AVRational){get_bits(gb, 8), 255};
+ }
+ } else {
+ tm_params->three_Spline_num = 1;
+ tm_params->three_Spline_TH_mode = 0;
+ }
+
+ }
+ }
+ }
+
+ 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;
+}
diff --git a/libavutil/hdr_dynamic_vivid_metadata.h
b/libavutil/hdr_dynamic_vivid_metadata.h
index a34f83072c..16a84ce343 100644
--- a/libavutil/hdr_dynamic_vivid_metadata.h
+++ b/libavutil/hdr_dynamic_vivid_metadata.h
@@ -282,4 +282,15 @@ AVDynamicHDRVivid
*av_dynamic_hdr_vivid_alloc(size_t *size);
*/
AVDynamicHDRVivid *av_dynamic_hdr_vivid_create_side_data(AVFrame *frame);
+/**
+ * Parse the user data registered ITU-T T.35 to AVbuffer
(AVDynamicHDRVivid).
+ * @param s A pointer containing the decoded AVDynamicHDRVivid structure.
+ * @param data The byte array containing the raw ITU-T T.35 data.
+ * @param size Size of the data array in bytes.
+ *
+ * @return 0 if succeed. Otherwise, returns the appropriate AVERROR.
+ */
+int av_dynamic_hdr_vivid_from_t35(AVDynamicHDRVivid *s, const uint8_t
*data,
+ int size);
+
#endif /* AVUTIL_HDR_DYNAMIC_VIVID_METADATA_H */
--
2.39.1
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2023-03-13 17:42 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-27 17:33 [FFmpeg-devel] [PATCH 1/2] avcodec/avutil: move dynamic HDR metadata parsing to libavutil Raphaël Zumer
2023-03-12 19:08 ` James Almer
2023-03-13 16:09 ` Andreas Rheinhardt
2023-03-13 16:56 ` Raphaël Zumer
2023-03-13 16:58 ` James Almer
2023-03-13 17:05 ` Raphaël Zumer
2023-03-13 17:10 ` James Almer
2023-03-13 17:34 ` Raphaël Zumer
2023-03-13 17:42 ` James Almer
[not found] <ec92f40f-0d6b-109b-d48e-1f24a0106f4b@tebako.net>
2023-02-27 16:53 ` Raphaël Zumer
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
This inbox may be cloned and mirrored by anyone:
git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git
# If you have public-inbox 1.1+ installed, you may
# initialize and index your mirror using the following commands:
public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
ffmpegdev@gitmailbox.com
public-inbox-index ffmpegdev
Example config snippet for mirrors.
AGPL code for this site: git clone https://public-inbox.org/public-inbox.git