* [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file
@ 2025-01-25 20:21 James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 02/14] avutil/frame: allow the addition of internal fields to AVSideDataDescriptor James Almer
` (12 more replies)
0 siblings, 13 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
Should reduce clutter in frame.c, plus allow us to make opaque changes to
side data handling.
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/Makefile | 1 +
libavutil/frame.c | 318 +-----------------------------------------
libavutil/side_data.c | 313 +++++++++++++++++++++++++++++++++++++++++
libavutil/side_data.h | 30 ++++
4 files changed, 351 insertions(+), 311 deletions(-)
create mode 100644 libavutil/side_data.c
create mode 100644 libavutil/side_data.h
diff --git a/libavutil/Makefile b/libavutil/Makefile
index f8031815bd..7677a04d12 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -171,6 +171,7 @@ OBJS = adler32.o \
rc4.o \
ripemd.o \
samplefmt.o \
+ side_data.o \
sha.o \
sha512.o \
slicethread.o \
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 10b59545f0..70a3b59123 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -26,41 +26,9 @@
#include "imgutils.h"
#include "mem.h"
#include "samplefmt.h"
+#include "side_data.h"
#include "hwcontext.h"
-static const AVSideDataDescriptor sd_props[] = {
- [AV_FRAME_DATA_PANSCAN] = { "AVPanScan", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_A53_CC] = { "ATSC A53 Part 4 Closed Captions" },
- [AV_FRAME_DATA_MATRIXENCODING] = { "AVMatrixEncoding" },
- [AV_FRAME_DATA_DOWNMIX_INFO] = { "Metadata relevant to a downmix procedure" },
- [AV_FRAME_DATA_AFD] = { "Active format description" },
- [AV_FRAME_DATA_MOTION_VECTORS] = { "Motion vectors", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_SKIP_SAMPLES] = { "Skip samples" },
- [AV_FRAME_DATA_GOP_TIMECODE] = { "GOP timecode" },
- [AV_FRAME_DATA_S12M_TIMECODE] = { "SMPTE 12-1 timecode" },
- [AV_FRAME_DATA_DYNAMIC_HDR_PLUS] = { "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_DYNAMIC_HDR_VIVID] = { "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_REGIONS_OF_INTEREST] = { "Regions Of Interest", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_VIDEO_ENC_PARAMS] = { "Video encoding parameters" },
- [AV_FRAME_DATA_FILM_GRAIN_PARAMS] = { "Film grain parameters" },
- [AV_FRAME_DATA_DETECTION_BBOXES] = { "Bounding boxes for object detection and classification", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_DOVI_RPU_BUFFER] = { "Dolby Vision RPU Data", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_DOVI_METADATA] = { "Dolby Vision Metadata", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_LCEVC] = { "LCEVC NAL data", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_VIEW_ID] = { "View ID" },
- [AV_FRAME_DATA_STEREO3D] = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL },
- [AV_FRAME_DATA_REPLAYGAIN] = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL },
- [AV_FRAME_DATA_DISPLAYMATRIX] = { "3x3 displaymatrix", AV_SIDE_DATA_PROP_GLOBAL },
- [AV_FRAME_DATA_AUDIO_SERVICE_TYPE] = { "Audio service type", AV_SIDE_DATA_PROP_GLOBAL },
- [AV_FRAME_DATA_MASTERING_DISPLAY_METADATA] = { "Mastering display metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_CONTENT_LIGHT_LEVEL] = { "Content light level metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT] = { "Ambient viewing environment", AV_SIDE_DATA_PROP_GLOBAL },
- [AV_FRAME_DATA_SPHERICAL] = { "Spherical Mapping", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_ICC_PROFILE] = { "ICC profile", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_SEI_UNREGISTERED] = { "H.26[45] User Data Unregistered SEI message", AV_SIDE_DATA_PROP_MULTI },
- [AV_FRAME_DATA_VIDEO_HINT] = { "Encoding video hint", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
-};
-
static void get_frame_defaults(AVFrame *frame)
{
memset(frame, 0, sizeof(*frame));
@@ -87,67 +55,6 @@ FF_ENABLE_DEPRECATION_WARNINGS
frame->flags = 0;
}
-static void free_side_data(AVFrameSideData **ptr_sd)
-{
- AVFrameSideData *sd = *ptr_sd;
-
- av_buffer_unref(&sd->buf);
- av_dict_free(&sd->metadata);
- av_freep(ptr_sd);
-}
-
-static void wipe_side_data(AVFrameSideData ***sd, int *nb_side_data)
-{
- for (int i = 0; i < *nb_side_data; i++) {
- free_side_data(&((*sd)[i]));
- }
- *nb_side_data = 0;
-
- av_freep(sd);
-}
-
-static void frame_side_data_wipe(AVFrame *frame)
-{
- wipe_side_data(&frame->side_data, &frame->nb_side_data);
-}
-
-void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd)
-{
- wipe_side_data(sd, nb_sd);
-}
-
-static void remove_side_data(AVFrameSideData ***sd, int *nb_side_data,
- const enum AVFrameSideDataType type)
-{
- for (int i = *nb_side_data - 1; i >= 0; i--) {
- AVFrameSideData *entry = ((*sd)[i]);
- if (entry->type != type)
- continue;
-
- free_side_data(&entry);
-
- ((*sd)[i]) = ((*sd)[*nb_side_data - 1]);
- (*nb_side_data)--;
- }
-}
-
-static void remove_side_data_by_entry(AVFrameSideData ***sd, int *nb_sd,
- const AVFrameSideData *target)
-{
- for (int i = *nb_sd - 1; i >= 0; i--) {
- AVFrameSideData *entry = ((*sd)[i]);
- if (entry != target)
- continue;
-
- free_side_data(&entry);
-
- ((*sd)[i]) = ((*sd)[*nb_sd - 1]);
- (*nb_sd)--;
-
- return;
- }
-}
-
AVFrame *av_frame_alloc(void)
{
AVFrame *frame = av_malloc(sizeof(*frame));
@@ -377,7 +284,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
sd_dst = av_frame_new_side_data(dst, sd_src->type,
sd_src->size);
if (!sd_dst) {
- frame_side_data_wipe(dst);
+ av_frame_side_data_free(&dst->side_data, &dst->nb_side_data);
return AVERROR(ENOMEM);
}
memcpy(sd_dst->data, sd_src->data, sd_src->size);
@@ -386,7 +293,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
if (!sd_dst) {
av_buffer_unref(&ref);
- frame_side_data_wipe(dst);
+ av_frame_side_data_free(&dst->side_data, &dst->nb_side_data);
return AVERROR(ENOMEM);
}
}
@@ -526,7 +433,7 @@ int av_frame_replace(AVFrame *dst, const AVFrame *src)
if (ret < 0)
goto fail;
- frame_side_data_wipe(dst);
+ av_frame_side_data_free(&dst->side_data, &dst->nb_side_data);
av_dict_free(&dst->metadata);
ret = frame_copy_props(dst, src, 0);
if (ret < 0)
@@ -625,7 +532,7 @@ void av_frame_unref(AVFrame *frame)
if (!frame)
return;
- frame_side_data_wipe(frame);
+ av_frame_side_data_free(&frame->side_data, &frame->nb_side_data);
for (int i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
av_buffer_unref(&frame->buf[i]);
@@ -758,54 +665,12 @@ AVBufferRef *av_frame_get_plane_buffer(const AVFrame *frame, int plane)
return NULL;
}
-static AVFrameSideData *add_side_data_from_buf_ext(AVFrameSideData ***sd,
- int *nb_sd,
- enum AVFrameSideDataType type,
- AVBufferRef *buf, uint8_t *data,
- size_t size)
-{
- AVFrameSideData *ret, **tmp;
-
- // *nb_sd + 1 needs to fit into an int and a size_t.
- if ((unsigned)*nb_sd >= FFMIN(INT_MAX, SIZE_MAX))
- return NULL;
-
- tmp = av_realloc_array(*sd, sizeof(**sd), *nb_sd + 1);
- if (!tmp)
- return NULL;
- *sd = tmp;
-
- ret = av_mallocz(sizeof(*ret));
- if (!ret)
- return NULL;
-
- ret->buf = buf;
- ret->data = data;
- ret->size = size;
- ret->type = type;
-
- (*sd)[(*nb_sd)++] = ret;
-
- return ret;
-}
-
-static AVFrameSideData *add_side_data_from_buf(AVFrameSideData ***sd,
- int *nb_sd,
- enum AVFrameSideDataType type,
- AVBufferRef *buf)
-{
- if (!buf)
- return NULL;
-
- return add_side_data_from_buf_ext(sd, nb_sd, type, buf, buf->data, buf->size);
-}
-
AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
enum AVFrameSideDataType type,
AVBufferRef *buf)
{
return
- add_side_data_from_buf(
+ ff_frame_side_data_add_from_buf(
&frame->side_data, &frame->nb_side_data, type, buf);
}
@@ -821,161 +686,6 @@ AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
return ret;
}
-static AVFrameSideData *replace_side_data_from_buf(AVFrameSideData *dst,
- AVBufferRef *buf, int flags)
-{
- if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE))
- return NULL;
-
- av_dict_free(&dst->metadata);
- av_buffer_unref(&dst->buf);
- dst->buf = buf;
- dst->data = buf->data;
- dst->size = buf->size;
- return dst;
-}
-
-AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
- enum AVFrameSideDataType type,
- size_t size, unsigned int flags)
-{
- const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
- AVBufferRef *buf = av_buffer_alloc(size);
- AVFrameSideData *ret = NULL;
-
- if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
- remove_side_data(sd, nb_sd, type);
- if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
- (ret = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, type))) {
- ret = replace_side_data_from_buf(ret, buf, flags);
- if (!ret)
- av_buffer_unref(&buf);
- return ret;
- }
-
- ret = add_side_data_from_buf(sd, nb_sd, type, buf);
- if (!ret)
- av_buffer_unref(&buf);
-
- return ret;
-}
-
-AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
- enum AVFrameSideDataType type,
- AVBufferRef **pbuf, unsigned int flags)
-{
- const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
- AVFrameSideData *sd_dst = NULL;
- AVBufferRef *buf = *pbuf;
-
- if ((flags & AV_FRAME_SIDE_DATA_FLAG_NEW_REF) && !(buf = av_buffer_ref(*pbuf)))
- return NULL;
- if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
- remove_side_data(sd, nb_sd, type);
- if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
- (sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, type))) {
- sd_dst = replace_side_data_from_buf(sd_dst, buf, flags);
- } else
- sd_dst = add_side_data_from_buf(sd, nb_sd, type, buf);
-
- if (sd_dst && !(flags & AV_FRAME_SIDE_DATA_FLAG_NEW_REF))
- *pbuf = NULL;
- else if (!sd_dst && (flags & AV_FRAME_SIDE_DATA_FLAG_NEW_REF))
- av_buffer_unref(&buf);
- return sd_dst;
-}
-
-int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
- const AVFrameSideData *src, unsigned int flags)
-{
- const AVSideDataDescriptor *desc;
- AVBufferRef *buf = NULL;
- AVFrameSideData *sd_dst = NULL;
- int ret = AVERROR_BUG;
-
- if (!sd || !src || !nb_sd || (*nb_sd && !*sd))
- return AVERROR(EINVAL);
-
- desc = av_frame_side_data_desc(src->type);
- if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
- remove_side_data(sd, nb_sd, src->type);
- if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
- (sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, src->type))) {
- AVDictionary *dict = NULL;
-
- if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE))
- return AVERROR(EEXIST);
-
- ret = av_dict_copy(&dict, src->metadata, 0);
- if (ret < 0)
- return ret;
-
- ret = av_buffer_replace(&sd_dst->buf, src->buf);
- if (ret < 0) {
- av_dict_free(&dict);
- return ret;
- }
-
- av_dict_free(&sd_dst->metadata);
- sd_dst->metadata = dict;
- sd_dst->data = src->data;
- sd_dst->size = src->size;
- return 0;
- }
-
- buf = av_buffer_ref(src->buf);
- if (!buf)
- return AVERROR(ENOMEM);
-
- sd_dst = add_side_data_from_buf_ext(sd, nb_sd, src->type, buf,
- src->data, src->size);
- if (!sd_dst) {
- av_buffer_unref(&buf);
- return AVERROR(ENOMEM);
- }
-
- ret = av_dict_copy(&sd_dst->metadata, src->metadata, 0);
- if (ret < 0) {
- remove_side_data_by_entry(sd, nb_sd, sd_dst);
- return ret;
- }
-
- return 0;
-}
-
-const AVFrameSideData *av_frame_side_data_get_c(const AVFrameSideData * const *sd,
- const int nb_sd,
- enum AVFrameSideDataType type)
-{
- for (int i = 0; i < nb_sd; i++) {
- if (sd[i]->type == type)
- return sd[i];
- }
- return NULL;
-}
-
-void av_frame_side_data_remove(AVFrameSideData ***sd, int *nb_sd,
- enum AVFrameSideDataType type)
-{
- remove_side_data(sd, nb_sd, type);
-}
-
-void av_frame_side_data_remove_by_props(AVFrameSideData ***sd, int *nb_sd,
- int props)
-{
- for (int i = *nb_sd - 1; i >= 0; i--) {
- AVFrameSideData *entry = ((*sd)[i]);
- const AVSideDataDescriptor *desc = av_frame_side_data_desc(entry->type);
- if (!desc || !(desc->props & props))
- continue;
-
- free_side_data(&entry);
-
- ((*sd)[i]) = ((*sd)[*nb_sd - 1]);
- (*nb_sd)--;
- }
-}
-
AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
enum AVFrameSideDataType type)
{
@@ -1044,21 +754,7 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src)
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
{
- remove_side_data(&frame->side_data, &frame->nb_side_data, type);
-}
-
-const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type)
-{
- unsigned t = type;
- if (t < FF_ARRAY_ELEMS(sd_props) && sd_props[t].name)
- return &sd_props[t];
- return NULL;
-}
-
-const char *av_frame_side_data_name(enum AVFrameSideDataType type)
-{
- const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
- return desc ? desc->name : NULL;
+ av_frame_side_data_remove(&frame->side_data, &frame->nb_side_data, type);
}
static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame,
diff --git a/libavutil/side_data.c b/libavutil/side_data.c
new file mode 100644
index 0000000000..b071971c9d
--- /dev/null
+++ b/libavutil/side_data.c
@@ -0,0 +1,313 @@
+/*
+ * 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 "avassert.h"
+#include "buffer.h"
+#include "common.h"
+#include "dict.h"
+#include "frame.h"
+#include "mem.h"
+#include "side_data.h"
+
+static const AVSideDataDescriptor sd_props[] = {
+ [AV_FRAME_DATA_PANSCAN] = { "AVPanScan", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
+ [AV_FRAME_DATA_A53_CC] = { "ATSC A53 Part 4 Closed Captions" },
+ [AV_FRAME_DATA_MATRIXENCODING] = { "AVMatrixEncoding" },
+ [AV_FRAME_DATA_DOWNMIX_INFO] = { "Metadata relevant to a downmix procedure" },
+ [AV_FRAME_DATA_AFD] = { "Active format description" },
+ [AV_FRAME_DATA_MOTION_VECTORS] = { "Motion vectors", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
+ [AV_FRAME_DATA_SKIP_SAMPLES] = { "Skip samples" },
+ [AV_FRAME_DATA_GOP_TIMECODE] = { "GOP timecode" },
+ [AV_FRAME_DATA_S12M_TIMECODE] = { "SMPTE 12-1 timecode" },
+ [AV_FRAME_DATA_DYNAMIC_HDR_PLUS] = { "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
+ [AV_FRAME_DATA_DYNAMIC_HDR_VIVID] = { "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
+ [AV_FRAME_DATA_REGIONS_OF_INTEREST] = { "Regions Of Interest", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
+ [AV_FRAME_DATA_VIDEO_ENC_PARAMS] = { "Video encoding parameters" },
+ [AV_FRAME_DATA_FILM_GRAIN_PARAMS] = { "Film grain parameters" },
+ [AV_FRAME_DATA_DETECTION_BBOXES] = { "Bounding boxes for object detection and classification", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
+ [AV_FRAME_DATA_DOVI_RPU_BUFFER] = { "Dolby Vision RPU Data", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
+ [AV_FRAME_DATA_DOVI_METADATA] = { "Dolby Vision Metadata", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
+ [AV_FRAME_DATA_LCEVC] = { "LCEVC NAL data", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
+ [AV_FRAME_DATA_VIEW_ID] = { "View ID" },
+ [AV_FRAME_DATA_STEREO3D] = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_REPLAYGAIN] = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_DISPLAYMATRIX] = { "3x3 displaymatrix", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_AUDIO_SERVICE_TYPE] = { "Audio service type", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_MASTERING_DISPLAY_METADATA] = { "Mastering display metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
+ [AV_FRAME_DATA_CONTENT_LIGHT_LEVEL] = { "Content light level metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
+ [AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT] = { "Ambient viewing environment", AV_SIDE_DATA_PROP_GLOBAL },
+ [AV_FRAME_DATA_SPHERICAL] = { "Spherical Mapping", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
+ [AV_FRAME_DATA_ICC_PROFILE] = { "ICC profile", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
+ [AV_FRAME_DATA_SEI_UNREGISTERED] = { "H.26[45] User Data Unregistered SEI message", AV_SIDE_DATA_PROP_MULTI },
+ [AV_FRAME_DATA_VIDEO_HINT] = { "Encoding video hint", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
+};
+
+const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type)
+{
+ unsigned t = type;
+ if (t < FF_ARRAY_ELEMS(sd_props) && sd_props[t].name)
+ return &sd_props[t];
+ return NULL;
+}
+
+const char *av_frame_side_data_name(enum AVFrameSideDataType type)
+{
+ const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
+ return desc ? desc->name : NULL;
+}
+
+static void free_side_data_entry(AVFrameSideData **ptr_sd)
+{
+ AVFrameSideData *sd = *ptr_sd;
+
+ av_buffer_unref(&sd->buf);
+ av_dict_free(&sd->metadata);
+ av_freep(ptr_sd);
+}
+
+static void remove_side_data_by_entry(AVFrameSideData ***sd, int *nb_sd,
+ const AVFrameSideData *target)
+{
+ for (int i = *nb_sd - 1; i >= 0; i--) {
+ AVFrameSideData *entry = ((*sd)[i]);
+ if (entry != target)
+ continue;
+
+ free_side_data_entry(&entry);
+
+ ((*sd)[i]) = ((*sd)[*nb_sd - 1]);
+ (*nb_sd)--;
+
+ return;
+ }
+}
+
+void av_frame_side_data_remove(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type)
+{
+ for (int i = *nb_sd - 1; i >= 0; i--) {
+ AVFrameSideData *entry = ((*sd)[i]);
+ if (entry->type != type)
+ continue;
+
+ free_side_data_entry(&entry);
+
+ ((*sd)[i]) = ((*sd)[*nb_sd - 1]);
+ (*nb_sd)--;
+ }
+}
+
+void av_frame_side_data_remove_by_props(AVFrameSideData ***sd, int *nb_sd,
+ int props)
+{
+ for (int i = *nb_sd - 1; i >= 0; i--) {
+ AVFrameSideData *entry = ((*sd)[i]);
+ const AVSideDataDescriptor *desc = av_frame_side_data_desc(entry->type);
+ if (!desc || !(desc->props & props))
+ continue;
+
+ free_side_data_entry(&entry);
+
+ ((*sd)[i]) = ((*sd)[*nb_sd - 1]);
+ (*nb_sd)--;
+ }
+}
+
+void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd)
+{
+ for (int i = 0; i < *nb_sd; i++)
+ free_side_data_entry(&((*sd)[i]));
+ *nb_sd = 0;
+
+ av_freep(sd);
+}
+
+static AVFrameSideData *add_side_data_from_buf_ext(AVFrameSideData ***sd,
+ int *nb_sd,
+ enum AVFrameSideDataType type,
+ AVBufferRef *buf, uint8_t *data,
+ size_t size)
+{
+ AVFrameSideData *ret, **tmp;
+
+ // *nb_sd + 1 needs to fit into an int and a size_t.
+ if ((unsigned)*nb_sd >= FFMIN(INT_MAX, SIZE_MAX))
+ return NULL;
+
+ tmp = av_realloc_array(*sd, sizeof(**sd), *nb_sd + 1);
+ if (!tmp)
+ return NULL;
+ *sd = tmp;
+
+ ret = av_mallocz(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->buf = buf;
+ ret->data = data;
+ ret->size = size;
+ ret->type = type;
+
+ (*sd)[(*nb_sd)++] = ret;
+
+ return ret;
+}
+
+AVFrameSideData *ff_frame_side_data_add_from_buf(AVFrameSideData ***sd,
+ int *nb_sd,
+ enum AVFrameSideDataType type,
+ AVBufferRef *buf)
+{
+ if (!buf)
+ return NULL;
+
+ return add_side_data_from_buf_ext(sd, nb_sd, type, buf, buf->data, buf->size);
+}
+
+static AVFrameSideData *replace_side_data_from_buf(AVFrameSideData *dst,
+ AVBufferRef *buf, int flags)
+{
+ if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE))
+ return NULL;
+
+ av_dict_free(&dst->metadata);
+ av_buffer_unref(&dst->buf);
+ dst->buf = buf;
+ dst->data = buf->data;
+ dst->size = buf->size;
+ return dst;
+}
+
+AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ size_t size, unsigned int flags)
+{
+ const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
+ AVBufferRef *buf = av_buffer_alloc(size);
+ AVFrameSideData *ret = NULL;
+
+ if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
+ av_frame_side_data_remove(sd, nb_sd, type);
+ if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
+ (ret = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, type))) {
+ ret = replace_side_data_from_buf(ret, buf, flags);
+ if (!ret)
+ av_buffer_unref(&buf);
+ return ret;
+ }
+
+ ret = ff_frame_side_data_add_from_buf(sd, nb_sd, type, buf);
+ if (!ret)
+ av_buffer_unref(&buf);
+
+ return ret;
+}
+
+AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ AVBufferRef **pbuf, unsigned int flags)
+{
+ const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
+ AVFrameSideData *sd_dst = NULL;
+ AVBufferRef *buf = *pbuf;
+
+ if ((flags & AV_FRAME_SIDE_DATA_FLAG_NEW_REF) && !(buf = av_buffer_ref(*pbuf)))
+ return NULL;
+ if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
+ av_frame_side_data_remove(sd, nb_sd, type);
+ if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
+ (sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, type))) {
+ sd_dst = replace_side_data_from_buf(sd_dst, buf, flags);
+ } else
+ sd_dst = ff_frame_side_data_add_from_buf(sd, nb_sd, type, buf);
+
+ if (sd_dst && !(flags & AV_FRAME_SIDE_DATA_FLAG_NEW_REF))
+ *pbuf = NULL;
+ else if (!sd_dst && (flags & AV_FRAME_SIDE_DATA_FLAG_NEW_REF))
+ av_buffer_unref(&buf);
+ return sd_dst;
+}
+
+int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
+ const AVFrameSideData *src, unsigned int flags)
+{
+ const AVSideDataDescriptor *desc;
+ AVBufferRef *buf = NULL;
+ AVFrameSideData *sd_dst = NULL;
+ int ret = AVERROR_BUG;
+
+ if (!sd || !src || !nb_sd || (*nb_sd && !*sd))
+ return AVERROR(EINVAL);
+
+ desc = av_frame_side_data_desc(src->type);
+ if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
+ av_frame_side_data_remove(sd, nb_sd, src->type);
+ if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
+ (sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, src->type))) {
+ AVDictionary *dict = NULL;
+
+ if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE))
+ return AVERROR(EEXIST);
+
+ ret = av_dict_copy(&dict, src->metadata, 0);
+ if (ret < 0)
+ return ret;
+
+ ret = av_buffer_replace(&sd_dst->buf, src->buf);
+ if (ret < 0) {
+ av_dict_free(&dict);
+ return ret;
+ }
+
+ av_dict_free(&sd_dst->metadata);
+ sd_dst->metadata = dict;
+ sd_dst->data = src->data;
+ sd_dst->size = src->size;
+ return 0;
+ }
+
+ buf = av_buffer_ref(src->buf);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ sd_dst = add_side_data_from_buf_ext(sd, nb_sd, src->type, buf,
+ src->data, src->size);
+ if (!sd_dst) {
+ av_buffer_unref(&buf);
+ return AVERROR(ENOMEM);
+ }
+
+ ret = av_dict_copy(&sd_dst->metadata, src->metadata, 0);
+ if (ret < 0) {
+ remove_side_data_by_entry(sd, nb_sd, sd_dst);
+ return ret;
+ }
+
+ return 0;
+}
+
+const AVFrameSideData *av_frame_side_data_get_c(const AVFrameSideData * const *sd,
+ const int nb_sd,
+ enum AVFrameSideDataType type)
+{
+ for (int i = 0; i < nb_sd; i++) {
+ if (sd[i]->type == type)
+ return sd[i];
+ }
+ return NULL;
+}
diff --git a/libavutil/side_data.h b/libavutil/side_data.h
new file mode 100644
index 0000000000..8275aa35a5
--- /dev/null
+++ b/libavutil/side_data.h
@@ -0,0 +1,30 @@
+/*
+ * 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 AVUTIL_SIDE_DATA_H
+#define AVUTIL_SIDE_DATA_H
+
+#include "buffer.h"
+#include "frame.h"
+
+AVFrameSideData *ff_frame_side_data_add_from_buf(AVFrameSideData ***sd,
+ int *nb_sd,
+ enum AVFrameSideDataType type,
+ AVBufferRef *buf);
+
+#endif // AVUTIL_SIDE_DATA_H
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 02/14] avutil/frame: allow the addition of internal fields to AVSideDataDescriptor
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 03/14] avutil/frame: allow the addition of internal fields to AVFrameSideData James Almer
` (11 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
Will be useful in the following commits to add fields that don't need to be
exposed.
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/side_data.c | 70 +++++++++++++++++++++++--------------------
1 file changed, 37 insertions(+), 33 deletions(-)
diff --git a/libavutil/side_data.c b/libavutil/side_data.c
index b071971c9d..5770be0639 100644
--- a/libavutil/side_data.c
+++ b/libavutil/side_data.c
@@ -24,44 +24,48 @@
#include "mem.h"
#include "side_data.h"
-static const AVSideDataDescriptor sd_props[] = {
- [AV_FRAME_DATA_PANSCAN] = { "AVPanScan", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_A53_CC] = { "ATSC A53 Part 4 Closed Captions" },
- [AV_FRAME_DATA_MATRIXENCODING] = { "AVMatrixEncoding" },
- [AV_FRAME_DATA_DOWNMIX_INFO] = { "Metadata relevant to a downmix procedure" },
- [AV_FRAME_DATA_AFD] = { "Active format description" },
- [AV_FRAME_DATA_MOTION_VECTORS] = { "Motion vectors", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_SKIP_SAMPLES] = { "Skip samples" },
- [AV_FRAME_DATA_GOP_TIMECODE] = { "GOP timecode" },
- [AV_FRAME_DATA_S12M_TIMECODE] = { "SMPTE 12-1 timecode" },
- [AV_FRAME_DATA_DYNAMIC_HDR_PLUS] = { "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_DYNAMIC_HDR_VIVID] = { "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_REGIONS_OF_INTEREST] = { "Regions Of Interest", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_VIDEO_ENC_PARAMS] = { "Video encoding parameters" },
- [AV_FRAME_DATA_FILM_GRAIN_PARAMS] = { "Film grain parameters" },
- [AV_FRAME_DATA_DETECTION_BBOXES] = { "Bounding boxes for object detection and classification", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_DOVI_RPU_BUFFER] = { "Dolby Vision RPU Data", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_DOVI_METADATA] = { "Dolby Vision Metadata", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_LCEVC] = { "LCEVC NAL data", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_VIEW_ID] = { "View ID" },
- [AV_FRAME_DATA_STEREO3D] = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL },
- [AV_FRAME_DATA_REPLAYGAIN] = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL },
- [AV_FRAME_DATA_DISPLAYMATRIX] = { "3x3 displaymatrix", AV_SIDE_DATA_PROP_GLOBAL },
- [AV_FRAME_DATA_AUDIO_SERVICE_TYPE] = { "Audio service type", AV_SIDE_DATA_PROP_GLOBAL },
- [AV_FRAME_DATA_MASTERING_DISPLAY_METADATA] = { "Mastering display metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_CONTENT_LIGHT_LEVEL] = { "Content light level metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT] = { "Ambient viewing environment", AV_SIDE_DATA_PROP_GLOBAL },
- [AV_FRAME_DATA_SPHERICAL] = { "Spherical Mapping", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
- [AV_FRAME_DATA_ICC_PROFILE] = { "ICC profile", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
- [AV_FRAME_DATA_SEI_UNREGISTERED] = { "H.26[45] User Data Unregistered SEI message", AV_SIDE_DATA_PROP_MULTI },
- [AV_FRAME_DATA_VIDEO_HINT] = { "Encoding video hint", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
+typedef struct FFSideDataDescriptor {
+ AVSideDataDescriptor p;
+} FFSideDataDescriptor;
+
+static const FFSideDataDescriptor sd_props[] = {
+ [AV_FRAME_DATA_PANSCAN] = { .p = { "AVPanScan", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
+ [AV_FRAME_DATA_A53_CC] = { .p = { "ATSC A53 Part 4 Closed Captions" } },
+ [AV_FRAME_DATA_MATRIXENCODING] = { .p = { "AVMatrixEncoding" } },
+ [AV_FRAME_DATA_DOWNMIX_INFO] = { .p = { "Metadata relevant to a downmix procedure" } },
+ [AV_FRAME_DATA_AFD] = { .p = { "Active format description" } },
+ [AV_FRAME_DATA_MOTION_VECTORS] = { .p = { "Motion vectors", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
+ [AV_FRAME_DATA_SKIP_SAMPLES] = { .p = { "Skip samples" } },
+ [AV_FRAME_DATA_GOP_TIMECODE] = { .p = { "GOP timecode" } },
+ [AV_FRAME_DATA_S12M_TIMECODE] = { .p = { "SMPTE 12-1 timecode" } },
+ [AV_FRAME_DATA_DYNAMIC_HDR_PLUS] = { .p = { "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
+ [AV_FRAME_DATA_DYNAMIC_HDR_VIVID] = { .p = { "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
+ [AV_FRAME_DATA_REGIONS_OF_INTEREST] = { .p = { "Regions Of Interest", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
+ [AV_FRAME_DATA_VIDEO_ENC_PARAMS] = { .p = { "Video encoding parameters" } },
+ [AV_FRAME_DATA_FILM_GRAIN_PARAMS] = { .p = { "Film grain parameters" } },
+ [AV_FRAME_DATA_DETECTION_BBOXES] = { .p = { "Bounding boxes for object detection and classification", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
+ [AV_FRAME_DATA_DOVI_RPU_BUFFER] = { .p = { "Dolby Vision RPU Data", AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
+ [AV_FRAME_DATA_DOVI_METADATA] = { .p = { "Dolby Vision Metadata", AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
+ [AV_FRAME_DATA_LCEVC] = { .p = { "LCEVC NAL data", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
+ [AV_FRAME_DATA_VIEW_ID] = { .p = { "View ID" } },
+ [AV_FRAME_DATA_STEREO3D] = { .p = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL } },
+ [AV_FRAME_DATA_REPLAYGAIN] = { .p = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL } },
+ [AV_FRAME_DATA_DISPLAYMATRIX] = { .p = { "3x3 displaymatrix", AV_SIDE_DATA_PROP_GLOBAL } },
+ [AV_FRAME_DATA_AUDIO_SERVICE_TYPE] = { .p = { "Audio service type", AV_SIDE_DATA_PROP_GLOBAL } },
+ [AV_FRAME_DATA_MASTERING_DISPLAY_METADATA] = { .p = { "Mastering display metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
+ [AV_FRAME_DATA_CONTENT_LIGHT_LEVEL] = { .p = { "Content light level metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
+ [AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT] = { .p = { "Ambient viewing environment", AV_SIDE_DATA_PROP_GLOBAL } },
+ [AV_FRAME_DATA_SPHERICAL] = { .p = { "Spherical Mapping", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
+ [AV_FRAME_DATA_ICC_PROFILE] = { .p = { "ICC profile", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
+ [AV_FRAME_DATA_SEI_UNREGISTERED] = { .p = { "H.26[45] User Data Unregistered SEI message", AV_SIDE_DATA_PROP_MULTI } },
+ [AV_FRAME_DATA_VIDEO_HINT] = { .p = { "Encoding video hint", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
};
const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type)
{
unsigned t = type;
- if (t < FF_ARRAY_ELEMS(sd_props) && sd_props[t].name)
- return &sd_props[t];
+ if (t < FF_ARRAY_ELEMS(sd_props) && sd_props[t].p.name)
+ return &sd_props[t].p;
return NULL;
}
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 03/14] avutil/frame: allow the addition of internal fields to AVFrameSideData
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 02/14] avutil/frame: allow the addition of internal fields to AVSideDataDescriptor James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 04/14] avutil/frame: schedule making AVFrameSideData.buf internal James Almer
` (10 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
Will be useful in the following commits to add fields that don't need to be
exposed.
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/side_data.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/libavutil/side_data.c b/libavutil/side_data.c
index 5770be0639..eb6e001f94 100644
--- a/libavutil/side_data.c
+++ b/libavutil/side_data.c
@@ -24,6 +24,10 @@
#include "mem.h"
#include "side_data.h"
+typedef struct FFFrameSideData {
+ AVFrameSideData p;
+} FFFrameSideData;
+
typedef struct FFSideDataDescriptor {
AVSideDataDescriptor p;
} FFSideDataDescriptor;
@@ -147,6 +151,7 @@ static AVFrameSideData *add_side_data_from_buf_ext(AVFrameSideData ***sd,
AVBufferRef *buf, uint8_t *data,
size_t size)
{
+ FFFrameSideData *sdp;
AVFrameSideData *ret, **tmp;
// *nb_sd + 1 needs to fit into an int and a size_t.
@@ -158,10 +163,11 @@ static AVFrameSideData *add_side_data_from_buf_ext(AVFrameSideData ***sd,
return NULL;
*sd = tmp;
- ret = av_mallocz(sizeof(*ret));
- if (!ret)
+ sdp = av_mallocz(sizeof(*sdp));
+ if (!sdp)
return NULL;
+ ret = &sdp->p;
ret->buf = buf;
ret->data = data;
ret->size = size;
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 04/14] avutil/frame: schedule making AVFrameSideData.buf internal
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 02/14] avutil/frame: allow the addition of internal fields to AVSideDataDescriptor James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 03/14] avutil/frame: allow the addition of internal fields to AVFrameSideData James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 05/14] avutil/frame: add functions to check and ensure a side data entry is writable James Almer
` (9 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
This is in preparation for a new type of backing for the side data that will be
introduced in a following commit. The user only cares about the data pointer.
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/frame.h | 3 +++
libavutil/side_data.c | 48 +++++++++++++++++++++++++++++++++++++++++++
libavutil/version.h | 1 +
3 files changed, 52 insertions(+)
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 628f2b5b3a..019adaac0e 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -267,7 +267,10 @@ typedef struct AVFrameSideData {
uint8_t *data;
size_t size;
AVDictionary *metadata;
+#if FF_API_SIDE_DATA_BUF
+ attribute_deprecated
AVBufferRef *buf;
+#endif
} AVFrameSideData;
enum AVSideDataProps {
diff --git a/libavutil/side_data.c b/libavutil/side_data.c
index eb6e001f94..7be1c346cd 100644
--- a/libavutil/side_data.c
+++ b/libavutil/side_data.c
@@ -26,6 +26,10 @@
typedef struct FFFrameSideData {
AVFrameSideData p;
+
+#if FF_API_SIDE_DATA_BUF == 0
+ AVBufferRef *buf;
+#endif
} FFFrameSideData;
typedef struct FFSideDataDescriptor {
@@ -65,6 +69,16 @@ static const FFSideDataDescriptor sd_props[] = {
[AV_FRAME_DATA_VIDEO_HINT] = { .p = { "Encoding video hint", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
};
+static FFFrameSideData *sdp_from_sd(AVFrameSideData *sd)
+{
+ return (FFFrameSideData *)sd;
+}
+
+static const FFFrameSideData *csdp_from_sd(const AVFrameSideData *sd)
+{
+ return (const FFFrameSideData *)sd;
+}
+
const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type)
{
unsigned t = type;
@@ -82,8 +96,15 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type)
static void free_side_data_entry(AVFrameSideData **ptr_sd)
{
AVFrameSideData *sd = *ptr_sd;
+ FFFrameSideData *sdp = sdp_from_sd(sd);
+#if FF_API_SIDE_DATA_BUF
+FF_DISABLE_DEPRECATION_WARNINGS
av_buffer_unref(&sd->buf);
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ av_buffer_unref(&sdp->buf);
+#endif
av_dict_free(&sd->metadata);
av_freep(ptr_sd);
}
@@ -168,7 +189,13 @@ static AVFrameSideData *add_side_data_from_buf_ext(AVFrameSideData ***sd,
return NULL;
ret = &sdp->p;
+#if FF_API_SIDE_DATA_BUF
+FF_DISABLE_DEPRECATION_WARNINGS
ret->buf = buf;
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ sdp->buf = buf;
+#endif
ret->data = data;
ret->size = size;
ret->type = type;
@@ -196,8 +223,15 @@ static AVFrameSideData *replace_side_data_from_buf(AVFrameSideData *dst,
return NULL;
av_dict_free(&dst->metadata);
+#if FF_API_SIDE_DATA_BUF
+FF_DISABLE_DEPRECATION_WARNINGS
av_buffer_unref(&dst->buf);
dst->buf = buf;
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ av_buffer_unref(&sdp_from_sd(dst)->buf);
+ sdp_from_sd(dst)->buf = buf;
+#endif
dst->data = buf->data;
dst->size = buf->size;
return dst;
@@ -257,6 +291,7 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
const AVFrameSideData *src, unsigned int flags)
{
const AVSideDataDescriptor *desc;
+ const FFFrameSideData *srcp = csdp_from_sd(src);
AVBufferRef *buf = NULL;
AVFrameSideData *sd_dst = NULL;
int ret = AVERROR_BUG;
@@ -269,6 +304,7 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
av_frame_side_data_remove(sd, nb_sd, src->type);
if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
(sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, src->type))) {
+ FFFrameSideData *dstp = sdp_from_sd(sd_dst);
AVDictionary *dict = NULL;
if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE))
@@ -278,7 +314,13 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
if (ret < 0)
return ret;
+#if FF_API_SIDE_DATA_BUF
+FF_DISABLE_DEPRECATION_WARNINGS
ret = av_buffer_replace(&sd_dst->buf, src->buf);
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ ret = av_buffer_replace(&dstp->buf, srcp->buf);
+#endif
if (ret < 0) {
av_dict_free(&dict);
return ret;
@@ -291,7 +333,13 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
return 0;
}
+#if FF_API_SIDE_DATA_BUF
+FF_DISABLE_DEPRECATION_WARNINGS
buf = av_buffer_ref(src->buf);
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ buf = av_buffer_ref(srcp->buf);
+#endif
if (!buf)
return AVERROR(ENOMEM);
diff --git a/libavutil/version.h b/libavutil/version.h
index a6f344a4c3..e736484a1e 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -117,6 +117,7 @@
#define FF_API_VULKAN_FIXED_QUEUES (LIBAVUTIL_VERSION_MAJOR < 60)
#define FF_API_OPT_INT_LIST (LIBAVUTIL_VERSION_MAJOR < 60)
#define FF_API_OPT_PTR (LIBAVUTIL_VERSION_MAJOR < 60)
+#define FF_API_SIDE_DATA_BUF (LIBAVUTIL_VERSION_MAJOR < 60)
/**
* @}
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 05/14] avutil/frame: add functions to check and ensure a side data entry is writable
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
` (2 preceding siblings ...)
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 04/14] avutil/frame: schedule making AVFrameSideData.buf internal James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 06/14] avutil/frame: av_frame_side_data_new_struct() James Almer
` (8 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/frame.h | 19 ++++++++++++++++++
libavutil/side_data.c | 45 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 019adaac0e..aa4e619ad2 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -1207,6 +1207,25 @@ void av_frame_side_data_remove(AVFrameSideData ***sd, int *nb_sd,
void av_frame_side_data_remove_by_props(AVFrameSideData ***sd, int *nb_sd,
int props);
+/**
+ * Check whether the data described by a given AVFrameSideData can be
+ * written to.
+ *
+ * @return 1 if the caller may write to the data, 0 otherwise.
+ */
+int av_frame_side_data_is_writable(const AVFrameSideData *sd);
+
+/**
+ * Create a writable reference for the data described by a given
+ * AVFrameSideData, avoiding data copy if possible.
+ *
+ * @param sd Side data whose data should be made writable.
+ *
+ * @return 0 on success, a negative AVERROR on failure. On failure, the
+ * side data is unchanged.
+ */
+int av_frame_side_data_make_writable(AVFrameSideData *sd);
+
/**
* @}
*/
diff --git a/libavutil/side_data.c b/libavutil/side_data.c
index 7be1c346cd..8fb9dfed2b 100644
--- a/libavutil/side_data.c
+++ b/libavutil/side_data.c
@@ -369,3 +369,48 @@ const AVFrameSideData *av_frame_side_data_get_c(const AVFrameSideData * const *s
}
return NULL;
}
+
+int av_frame_side_data_is_writable(const AVFrameSideData *sd)
+{
+#if FF_API_SIDE_DATA_BUF
+FF_DISABLE_DEPRECATION_WARNINGS
+ return !!av_buffer_is_writable(sd->buf);
+#else
+ const FFFrameSideData *sdp = csdp_from_sd(sd);
+ return !!av_buffer_is_writable(sdp->buf);
+#endif
+}
+
+int av_frame_side_data_make_writable(AVFrameSideData *sd)
+{
+ FFFrameSideData *sdp = sdp_from_sd(sd);
+ AVBufferRef *buf = NULL;
+
+#if FF_API_SIDE_DATA_BUF
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (av_buffer_is_writable(sd->buf))
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ if (av_buffer_is_writable(sdp->buf))
+#endif
+ return 0;
+
+ buf = av_buffer_alloc(sd->size);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ if (sd->size)
+ memcpy(buf->data, sd->data, sd->size);
+#if FF_API_SIDE_DATA_BUF
+FF_DISABLE_DEPRECATION_WARNINGS
+ av_buffer_unref(&sd->buf);
+ sd->buf = buf;
+FF_ENABLE_DEPRECATION_WARNINGS
+#else
+ av_buffer_unref(&sdp->buf);
+ sdp->buf = buf;
+#endif
+ sd->data = buf->data;
+
+ return 0;
+}
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 06/14] avutil/frame: av_frame_side_data_new_struct()
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
` (3 preceding siblings ...)
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 05/14] avutil/frame: add functions to check and ensure a side data entry is writable James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 07/14] avutil/frame: add support for RefStruct as backing for side data James Almer
` (7 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
As well as the AV_SIDE_DATA_PROP_STRUCT prop, to define types that describe
a fixed-size C struct and not a flat byte array.
This excludes types like VIDEO_ENC_PARAMS as the struct it describes may have
extra bytes allocated past the end of the struct.
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/ambient_viewing_environment.c | 9 ++-
libavutil/frame.h | 11 ++++
libavutil/mastering_display_metadata.c | 9 ++-
libavutil/side_data.c | 78 +++++++++++++++++++++----
libavutil/side_data.h | 4 ++
libavutil/spherical.c | 10 +++-
6 files changed, 102 insertions(+), 19 deletions(-)
diff --git a/libavutil/ambient_viewing_environment.c b/libavutil/ambient_viewing_environment.c
index e359727776..ee2e9427cd 100644
--- a/libavutil/ambient_viewing_environment.c
+++ b/libavutil/ambient_viewing_environment.c
@@ -20,9 +20,12 @@
#include "ambient_viewing_environment.h"
#include "mem.h"
+#include "side_data.h"
-static void get_defaults(AVAmbientViewingEnvironment *env)
+void ff_ave_get_defaults(void *obj)
{
+ AVAmbientViewingEnvironment *env = obj;
+
env->ambient_illuminance =
env->ambient_light_x =
env->ambient_light_y = (AVRational) { 0, 1 };
@@ -35,7 +38,7 @@ AVAmbientViewingEnvironment *av_ambient_viewing_environment_alloc(size_t *size)
if (!env)
return NULL;
- get_defaults(env);
+ ff_ave_get_defaults(env);
if (size)
*size = sizeof(*env);
@@ -53,7 +56,7 @@ AVAmbientViewingEnvironment *av_ambient_viewing_environment_create_side_data(AVF
return NULL;
memset(side_data->data, 0, side_data->size);
- get_defaults((AVAmbientViewingEnvironment *)side_data->data);
+ ff_ave_get_defaults(side_data->data);
return (AVAmbientViewingEnvironment *)side_data->data;
}
diff --git a/libavutil/frame.h b/libavutil/frame.h
index aa4e619ad2..1feb11506a 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -300,6 +300,13 @@ enum AVSideDataProps {
* adapting to a different set of primaries or transfer characteristics.
*/
AV_SIDE_DATA_PROP_COLOR_DEPENDENT = (1 << 3),
+
+ /**
+ * Side data stores a fixed-size C struct and not a flat byte array.
+ * Entries of this type should be allocated with
+ * @ref av_frame_side_data_new_struct(), and their size is not user settable.
+ */
+ AV_SIDE_DATA_PROP_STRUCT = (1 << 5),
};
/**
@@ -1117,6 +1124,10 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
enum AVFrameSideDataType type,
size_t size, unsigned int flags);
+AVFrameSideData *av_frame_side_data_new_struct(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ unsigned int flags);
+
/**
* Add a new side data entry to an array from an existing AVBufferRef.
*
diff --git a/libavutil/mastering_display_metadata.c b/libavutil/mastering_display_metadata.c
index dd37ed7d0e..4948f30523 100644
--- a/libavutil/mastering_display_metadata.c
+++ b/libavutil/mastering_display_metadata.c
@@ -24,9 +24,12 @@
#include "mastering_display_metadata.h"
#include "mem.h"
+#include "side_data.h"
-static void get_defaults(AVMasteringDisplayMetadata *mastering)
+void ff_mdm_get_defaults(void *obj)
{
+ AVMasteringDisplayMetadata *mastering = obj;
+
for (int i = 0; i < 3; i++)
for (int j = 0; j < 2; j++)
mastering->display_primaries[i][j] = (AVRational) { 0, 1 };
@@ -47,7 +50,7 @@ AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc_size(size_t *siz
if (!mastering)
return NULL;
- get_defaults(mastering);
+ ff_mdm_get_defaults(mastering);
if (size)
*size = sizeof(*mastering);
@@ -64,7 +67,7 @@ AVMasteringDisplayMetadata *av_mastering_display_metadata_create_side_data(AVFra
return NULL;
memset(side_data->data, 0, sizeof(AVMasteringDisplayMetadata));
- get_defaults((AVMasteringDisplayMetadata *)side_data->data);
+ ff_mdm_get_defaults(side_data->data);
return (AVMasteringDisplayMetadata *)side_data->data;
}
diff --git a/libavutil/side_data.c b/libavutil/side_data.c
index 8fb9dfed2b..671dcecb82 100644
--- a/libavutil/side_data.c
+++ b/libavutil/side_data.c
@@ -22,8 +22,21 @@
#include "dict.h"
#include "frame.h"
#include "mem.h"
+#include "refstruct.h"
#include "side_data.h"
+// headers for struct sizes
+#include "libavcodec/defs.h"
+#include "ambient_viewing_environment.h"
+#include "downmix_info.h"
+#include "hdr_dynamic_metadata.h"
+#include "hdr_dynamic_vivid_metadata.h"
+#include "mastering_display_metadata.h"
+#include "motion_vector.h"
+#include "replaygain.h"
+#include "spherical.h"
+#include "stereo3d.h"
+
typedef struct FFFrameSideData {
AVFrameSideData p;
@@ -34,36 +47,54 @@ typedef struct FFFrameSideData {
typedef struct FFSideDataDescriptor {
AVSideDataDescriptor p;
+
+ void (*init)(void *obj);
+
+ size_t size;
} FFSideDataDescriptor;
static const FFSideDataDescriptor sd_props[] = {
- [AV_FRAME_DATA_PANSCAN] = { .p = { "AVPanScan", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
+ [AV_FRAME_DATA_PANSCAN] = { .p = { "AVPanScan", AV_SIDE_DATA_PROP_STRUCT | AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
+ .size = sizeof(AVPanScan) },
[AV_FRAME_DATA_A53_CC] = { .p = { "ATSC A53 Part 4 Closed Captions" } },
[AV_FRAME_DATA_MATRIXENCODING] = { .p = { "AVMatrixEncoding" } },
- [AV_FRAME_DATA_DOWNMIX_INFO] = { .p = { "Metadata relevant to a downmix procedure" } },
+ [AV_FRAME_DATA_DOWNMIX_INFO] = { .p = { "Metadata relevant to a downmix procedure", AV_SIDE_DATA_PROP_STRUCT },
+ .size = sizeof(AVDownmixInfo) },
[AV_FRAME_DATA_AFD] = { .p = { "Active format description" } },
- [AV_FRAME_DATA_MOTION_VECTORS] = { .p = { "Motion vectors", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
+ [AV_FRAME_DATA_MOTION_VECTORS] = { .p = { "Motion vectors", AV_SIDE_DATA_PROP_STRUCT | AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
+ .size = sizeof(AVMotionVector) },
[AV_FRAME_DATA_SKIP_SAMPLES] = { .p = { "Skip samples" } },
[AV_FRAME_DATA_GOP_TIMECODE] = { .p = { "GOP timecode" } },
[AV_FRAME_DATA_S12M_TIMECODE] = { .p = { "SMPTE 12-1 timecode" } },
- [AV_FRAME_DATA_DYNAMIC_HDR_PLUS] = { .p = { "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
- [AV_FRAME_DATA_DYNAMIC_HDR_VIVID] = { .p = { "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
+ [AV_FRAME_DATA_DYNAMIC_HDR_PLUS] = { .p = { "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)", AV_SIDE_DATA_PROP_STRUCT| AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
+ .size = sizeof(AVDynamicHDRPlus) },
+ [AV_FRAME_DATA_DYNAMIC_HDR_VIVID] = { .p = { "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)", AV_SIDE_DATA_PROP_STRUCT | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
+ .size = sizeof(AVDynamicHDRVivid) },
[AV_FRAME_DATA_REGIONS_OF_INTEREST] = { .p = { "Regions Of Interest", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
[AV_FRAME_DATA_VIDEO_ENC_PARAMS] = { .p = { "Video encoding parameters" } },
- [AV_FRAME_DATA_FILM_GRAIN_PARAMS] = { .p = { "Film grain parameters" } },
+ [AV_FRAME_DATA_FILM_GRAIN_PARAMS] = { .p = { "Film grain parameters", AV_SIDE_DATA_PROP_STRUCT } },
[AV_FRAME_DATA_DETECTION_BBOXES] = { .p = { "Bounding boxes for object detection and classification", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
[AV_FRAME_DATA_DOVI_RPU_BUFFER] = { .p = { "Dolby Vision RPU Data", AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
[AV_FRAME_DATA_DOVI_METADATA] = { .p = { "Dolby Vision Metadata", AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
[AV_FRAME_DATA_LCEVC] = { .p = { "LCEVC NAL data", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
[AV_FRAME_DATA_VIEW_ID] = { .p = { "View ID" } },
- [AV_FRAME_DATA_STEREO3D] = { .p = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL } },
- [AV_FRAME_DATA_REPLAYGAIN] = { .p = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL } },
+ [AV_FRAME_DATA_STEREO3D] = { .p = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT },
+ .size = sizeof(AVStereo3D) },
+ [AV_FRAME_DATA_REPLAYGAIN] = { .p = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT },
+ .size = sizeof(AVReplayGain) },
[AV_FRAME_DATA_DISPLAYMATRIX] = { .p = { "3x3 displaymatrix", AV_SIDE_DATA_PROP_GLOBAL } },
[AV_FRAME_DATA_AUDIO_SERVICE_TYPE] = { .p = { "Audio service type", AV_SIDE_DATA_PROP_GLOBAL } },
- [AV_FRAME_DATA_MASTERING_DISPLAY_METADATA] = { .p = { "Mastering display metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
- [AV_FRAME_DATA_CONTENT_LIGHT_LEVEL] = { .p = { "Content light level metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
- [AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT] = { .p = { "Ambient viewing environment", AV_SIDE_DATA_PROP_GLOBAL } },
- [AV_FRAME_DATA_SPHERICAL] = { .p = { "Spherical Mapping", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
+ [AV_FRAME_DATA_MASTERING_DISPLAY_METADATA] = { .p = { "Mastering display metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
+ .init = ff_mdm_get_defaults,
+ .size = sizeof(AVMasteringDisplayMetadata) },
+ [AV_FRAME_DATA_CONTENT_LIGHT_LEVEL] = { .p = { "Content light level metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
+ .size = sizeof(AVContentLightMetadata) },
+ [AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT] = { .p = { "Ambient viewing environment", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT },
+ .init = ff_ave_get_defaults,
+ .size = sizeof(AVAmbientViewingEnvironment) },
+ [AV_FRAME_DATA_SPHERICAL] = { .p = { "Spherical Mapping", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT | AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
+ .init = ff_spherical_get_defaults,
+ .size = sizeof(AVSphericalMapping) },
[AV_FRAME_DATA_ICC_PROFILE] = { .p = { "ICC profile", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
[AV_FRAME_DATA_SEI_UNREGISTERED] = { .p = { "H.26[45] User Data Unregistered SEI message", AV_SIDE_DATA_PROP_MULTI } },
[AV_FRAME_DATA_VIDEO_HINT] = { .p = { "Encoding video hint", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
@@ -79,6 +110,11 @@ static const FFFrameSideData *csdp_from_sd(const AVFrameSideData *sd)
return (const FFFrameSideData *)sd;
}
+static const FFSideDataDescriptor *dp_from_desc(const AVSideDataDescriptor *desc)
+{
+ return (const FFSideDataDescriptor *)desc;
+}
+
const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type)
{
unsigned t = type;
@@ -287,6 +323,24 @@ AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
return sd_dst;
}
+AVFrameSideData *av_frame_side_data_new_struct(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ unsigned int flags)
+{
+ const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
+ const FFSideDataDescriptor *dp = dp_from_desc(desc);
+ AVFrameSideData *ret;
+
+ if (!desc || !(desc->props & AV_SIDE_DATA_PROP_STRUCT))
+ return NULL;
+
+ av_assert0(dp->size);
+ ret = av_frame_side_data_new(sd, nb_sd, type, dp->size, flags);
+ if (ret && dp->init)
+ dp->init(ret->data);
+ return ret;
+}
+
int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
const AVFrameSideData *src, unsigned int flags)
{
diff --git a/libavutil/side_data.h b/libavutil/side_data.h
index 8275aa35a5..5d25833882 100644
--- a/libavutil/side_data.h
+++ b/libavutil/side_data.h
@@ -27,4 +27,8 @@ AVFrameSideData *ff_frame_side_data_add_from_buf(AVFrameSideData ***sd,
enum AVFrameSideDataType type,
AVBufferRef *buf);
+void ff_mdm_get_defaults(void *obj);
+void ff_ave_get_defaults(void *obj);
+void ff_spherical_get_defaults(void *obj);
+
#endif // AVUTIL_SIDE_DATA_H
diff --git a/libavutil/spherical.c b/libavutil/spherical.c
index 64ade1d0ec..4ef2c225c2 100644
--- a/libavutil/spherical.c
+++ b/libavutil/spherical.c
@@ -21,15 +21,23 @@
#include "avstring.h"
#include "macros.h"
#include "mem.h"
+#include "side_data.h"
#include "spherical.h"
+void ff_spherical_get_defaults(void *obj)
+{
+ AVSphericalMapping *spherical = obj;
+
+ spherical->projection = AV_SPHERICAL_RECTILINEAR;
+}
+
AVSphericalMapping *av_spherical_alloc(size_t *size)
{
AVSphericalMapping *spherical = av_mallocz(sizeof(AVSphericalMapping));
if (!spherical)
return NULL;
- spherical->projection = AV_SPHERICAL_RECTILINEAR;
+ ff_spherical_get_defaults(spherical);
if (size)
*size = sizeof(*spherical);
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 07/14] avutil/frame: add support for RefStruct as backing for side data
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
` (4 preceding siblings ...)
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 06/14] avutil/frame: av_frame_side_data_new_struct() James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PoC][PATCH 08/14] avutil/frame: add a param change side data type James Almer
` (6 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
With this, complex structs can be used as side data entries.
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/frame.c | 7 +-
libavutil/side_data.c | 209 +++++++++++++++++++++++++++++++++++++++++-
libavutil/side_data.h | 3 +
3 files changed, 210 insertions(+), 9 deletions(-)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 70a3b59123..05138a4919 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -281,13 +281,12 @@ FF_ENABLE_DEPRECATION_WARNINGS
&& (src->width != dst->width || src->height != dst->height))
continue;
if (force_copy) {
- sd_dst = av_frame_new_side_data(dst, sd_src->type,
- sd_src->size);
+ sd_dst = ff_frame_side_data_copy(&dst->side_data, &dst->nb_side_data,
+ sd_src);
if (!sd_dst) {
av_frame_side_data_free(&dst->side_data, &dst->nb_side_data);
return AVERROR(ENOMEM);
}
- memcpy(sd_dst->data, sd_src->data, sd_src->size);
} else {
AVBufferRef *ref = av_buffer_ref(sd_src->buf);
sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
@@ -296,8 +295,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
av_frame_side_data_free(&dst->side_data, &dst->nb_side_data);
return AVERROR(ENOMEM);
}
+ av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0);
}
- av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0);
}
ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
diff --git a/libavutil/side_data.c b/libavutil/side_data.c
index 671dcecb82..597228baf1 100644
--- a/libavutil/side_data.c
+++ b/libavutil/side_data.c
@@ -43,12 +43,22 @@ typedef struct FFFrameSideData {
#if FF_API_SIDE_DATA_BUF == 0
AVBufferRef *buf;
#endif
+ void *refstruct;
} FFFrameSideData;
+enum FFSideDataProps {
+ FF_SIDE_DATA_PROP_REFSTRUCT = (1 << 0),
+};
+
typedef struct FFSideDataDescriptor {
AVSideDataDescriptor p;
+
+ unsigned props;
+
void (*init)(void *obj);
+ int (*copy)(void *dst, const void *src);
+ void (*uninit)(AVRefStructOpaque opaque, void *obj);
size_t size;
} FFSideDataDescriptor;
@@ -141,6 +151,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
#else
av_buffer_unref(&sdp->buf);
#endif
+ av_refstruct_unref(&sdp->refstruct);
av_dict_free(&sd->metadata);
av_freep(ptr_sd);
}
@@ -208,6 +219,8 @@ static AVFrameSideData *add_side_data_from_buf_ext(AVFrameSideData ***sd,
AVBufferRef *buf, uint8_t *data,
size_t size)
{
+ const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
+ const FFSideDataDescriptor *dp = dp_from_desc(desc);
FFFrameSideData *sdp;
AVFrameSideData *ret, **tmp;
@@ -215,6 +228,9 @@ static AVFrameSideData *add_side_data_from_buf_ext(AVFrameSideData ***sd,
if ((unsigned)*nb_sd >= FFMIN(INT_MAX, SIZE_MAX))
return NULL;
+ if (dp && (dp->props & FF_SIDE_DATA_PROP_REFSTRUCT))
+ return NULL;
+
tmp = av_realloc_array(*sd, sizeof(**sd), *nb_sd + 1);
if (!tmp)
return NULL;
@@ -255,9 +271,15 @@ AVFrameSideData *ff_frame_side_data_add_from_buf(AVFrameSideData ***sd,
static AVFrameSideData *replace_side_data_from_buf(AVFrameSideData *dst,
AVBufferRef *buf, int flags)
{
+ const AVSideDataDescriptor *desc = av_frame_side_data_desc(dst->type);
+ const FFSideDataDescriptor *dp = dp_from_desc(desc);
+
if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE))
return NULL;
+ if (dp && (dp->props & FF_SIDE_DATA_PROP_REFSTRUCT))
+ return NULL;
+
av_dict_free(&dst->metadata);
#if FF_API_SIDE_DATA_BUF
FF_DISABLE_DEPRECATION_WARNINGS
@@ -323,6 +345,64 @@ AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
return sd_dst;
}
+static AVFrameSideData *add_side_data_from_refstruct(AVFrameSideData ***sd,
+ int *nb_sd,
+ enum AVFrameSideDataType type,
+ void *obj, size_t size)
+{
+ const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
+ const FFSideDataDescriptor *dp = dp_from_desc(desc);
+ FFFrameSideData *sdp;
+ AVFrameSideData *ret, **tmp;
+
+ // *nb_sd + 1 needs to fit into an int and a size_t.
+ if ((unsigned)*nb_sd >= FFMIN(INT_MAX, SIZE_MAX))
+ return NULL;
+
+ if (dp && (dp->props & FF_SIDE_DATA_PROP_REFSTRUCT))
+ return NULL;
+
+ tmp = av_realloc_array(*sd, sizeof(**sd), *nb_sd + 1);
+ if (!tmp)
+ return NULL;
+ *sd = tmp;
+
+ sdp = av_mallocz(sizeof(*sdp));
+ if (!sdp)
+ return NULL;
+
+ sdp->refstruct = obj;
+ ret = &sdp->p;
+ ret->data = obj;
+ ret->size = size;
+ ret->type = type;
+
+ (*sd)[(*nb_sd)++] = ret;
+
+ return ret;
+}
+
+static AVFrameSideData *replace_side_data_from_refstruct(AVFrameSideData *sd,
+ void *obj, size_t size, int flags)
+{
+ FFFrameSideData *sdp = sdp_from_sd(sd);
+
+ if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE))
+ return NULL;
+
+ av_dict_free(&sd->metadata);
+#if FF_API_SIDE_DATA_BUF
+FF_DISABLE_DEPRECATION_WARNINGS
+ av_buffer_unref(&sd->buf);
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ av_refstruct_unref(&sdp->refstruct);
+ sdp->refstruct = obj;
+ sd->data = obj;
+ sd->size = size;
+ return sd;
+}
+
AVFrameSideData *av_frame_side_data_new_struct(AVFrameSideData ***sd, int *nb_sd,
enum AVFrameSideDataType type,
unsigned int flags)
@@ -330,36 +410,110 @@ AVFrameSideData *av_frame_side_data_new_struct(AVFrameSideData ***sd, int *nb_sd
const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
const FFSideDataDescriptor *dp = dp_from_desc(desc);
AVFrameSideData *ret;
+ void *obj;
if (!desc || !(desc->props & AV_SIDE_DATA_PROP_STRUCT))
return NULL;
av_assert0(dp->size);
+
+ if (!(dp->props & FF_SIDE_DATA_PROP_REFSTRUCT)) {
ret = av_frame_side_data_new(sd, nb_sd, type, dp->size, flags);
if (ret && dp->init)
dp->init(ret->data);
return ret;
+ }
+
+ if (!(obj = av_refstruct_alloc_ext(dp->size, 0, NULL, dp->uninit)))
+ return NULL;
+ if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
+ av_frame_side_data_remove(sd, nb_sd, type);
+ if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
+ (ret = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, type))) {
+ ret = replace_side_data_from_refstruct(ret, obj, dp->size, flags);
+ if (!ret)
+ av_refstruct_unref(&obj);
+ return ret;
+ }
+
+ ret = add_side_data_from_refstruct(sd, nb_sd, type, obj, dp->size);
+ if (!ret)
+ av_refstruct_unref(&obj);
+
+ return ret;
+}
+
+AVFrameSideData *ff_frame_side_data_copy(AVFrameSideData ***sd, int *nb_sd,
+ const AVFrameSideData *src)
+{
+ const AVSideDataDescriptor *desc;
+ const FFSideDataDescriptor *dp;
+ const FFFrameSideData *srcp = csdp_from_sd(src);
+ AVBufferRef *buf = NULL;
+ AVFrameSideData *sd_dst = NULL;
+ void *obj = NULL;
+ int ret = AVERROR_BUG;
+
+ if (!sd || !src || !nb_sd || (*nb_sd && !*sd))
+ return NULL;
+
+ desc = av_frame_side_data_desc(src->type);
+ dp = dp_from_desc(desc);
+
+ if (dp && (dp->props & FF_SIDE_DATA_PROP_REFSTRUCT)) {
+ obj = av_refstruct_alloc_ext(dp->size, 0, NULL, dp->uninit);
+ if (!obj || dp->copy(obj, srcp->refstruct) < 0) {
+ av_refstruct_unref(&obj);
+ return NULL;
+ }
+ sd_dst = add_side_data_from_refstruct(sd, nb_sd, src->type, obj,
+ dp->size);
+ } else {
+ buf = av_buffer_alloc(src->size);
+ if (!buf)
+ return NULL;
+ memcpy(buf->data, src->data, src->size);
+ sd_dst = ff_frame_side_data_add_from_buf(sd, nb_sd, src->type, buf);
+ }
+ if (!sd_dst) {
+ av_buffer_unref(&buf);
+ av_refstruct_unref(&obj);
+ return NULL;
+ }
+
+ ret = av_dict_copy(&sd_dst->metadata, src->metadata, 0);
+ if (ret < 0) {
+ remove_side_data_by_entry(sd, nb_sd, sd_dst);
+ return NULL;
+ }
+
+ return sd_dst;
}
int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
const AVFrameSideData *src, unsigned int flags)
{
const AVSideDataDescriptor *desc;
+ const FFSideDataDescriptor *dp;
const FFFrameSideData *srcp = csdp_from_sd(src);
AVBufferRef *buf = NULL;
AVFrameSideData *sd_dst = NULL;
+ void *obj = NULL;
int ret = AVERROR_BUG;
if (!sd || !src || !nb_sd || (*nb_sd && !*sd))
return AVERROR(EINVAL);
desc = av_frame_side_data_desc(src->type);
+ dp = dp_from_desc(desc);
if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
av_frame_side_data_remove(sd, nb_sd, src->type);
if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
(sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, src->type))) {
FFFrameSideData *dstp = sdp_from_sd(sd_dst);
AVDictionary *dict = NULL;
+ uint8_t *data;
+ size_t size;
if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE))
return AVERROR(EEXIST);
@@ -368,6 +522,11 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
if (ret < 0)
return ret;
+ if (dp && (dp->props & FF_SIDE_DATA_PROP_REFSTRUCT)) {
+ av_refstruct_replace(&dstp->refstruct, srcp->refstruct);
+ data = dstp->refstruct;
+ size = dp->size;
+ } else {
#if FF_API_SIDE_DATA_BUF
FF_DISABLE_DEPRECATION_WARNINGS
ret = av_buffer_replace(&sd_dst->buf, src->buf);
@@ -375,6 +534,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
#else
ret = av_buffer_replace(&dstp->buf, srcp->buf);
#endif
+ data = src->data;
+ size = src->size;
+ }
if (ret < 0) {
av_dict_free(&dict);
return ret;
@@ -382,11 +544,16 @@ FF_ENABLE_DEPRECATION_WARNINGS
av_dict_free(&sd_dst->metadata);
sd_dst->metadata = dict;
- sd_dst->data = src->data;
- sd_dst->size = src->size;
+ sd_dst->data = data;
+ sd_dst->size = size;
return 0;
}
+ if (dp && (dp->props & FF_SIDE_DATA_PROP_REFSTRUCT)) {
+ obj = av_refstruct_ref(srcp->refstruct);
+ sd_dst = add_side_data_from_refstruct(sd, nb_sd, src->type, obj,
+ dp->size);
+ } else {
#if FF_API_SIDE_DATA_BUF
FF_DISABLE_DEPRECATION_WARNINGS
buf = av_buffer_ref(src->buf);
@@ -399,8 +566,10 @@ FF_ENABLE_DEPRECATION_WARNINGS
sd_dst = add_side_data_from_buf_ext(sd, nb_sd, src->type, buf,
src->data, src->size);
+ }
if (!sd_dst) {
av_buffer_unref(&buf);
+ av_refstruct_unref(&obj);
return AVERROR(ENOMEM);
}
@@ -426,20 +595,46 @@ const AVFrameSideData *av_frame_side_data_get_c(const AVFrameSideData * const *s
int av_frame_side_data_is_writable(const AVFrameSideData *sd)
{
+ const AVSideDataDescriptor *desc = av_frame_side_data_desc(sd->type);
+ const FFSideDataDescriptor *dp = dp_from_desc(desc);
+ const FFFrameSideData *sdp = csdp_from_sd(sd);
+
+ if (dp && (dp->props & FF_SIDE_DATA_PROP_REFSTRUCT)) {
+ return av_refstruct_exclusive(sdp->refstruct);
+ } else {
#if FF_API_SIDE_DATA_BUF
FF_DISABLE_DEPRECATION_WARNINGS
return !!av_buffer_is_writable(sd->buf);
#else
- const FFFrameSideData *sdp = csdp_from_sd(sd);
return !!av_buffer_is_writable(sdp->buf);
#endif
+ }
}
int av_frame_side_data_make_writable(AVFrameSideData *sd)
{
+ const AVSideDataDescriptor *desc = av_frame_side_data_desc(sd->type);
+ const FFSideDataDescriptor *dp = dp_from_desc(desc);
FFFrameSideData *sdp = sdp_from_sd(sd);
AVBufferRef *buf = NULL;
-
+ void *obj = NULL;
+ uint8_t *data;
+
+ if (dp && (dp->props & FF_SIDE_DATA_PROP_REFSTRUCT)) {
+ void *obj;
+ int ret;
+ if (av_refstruct_exclusive(sdp->refstruct))
+ return 0;
+ obj = av_refstruct_alloc_ext(dp->size, 0, NULL, dp->uninit);
+ if (!obj)
+ return AVERROR(ENOMEM);
+ ret = dp->copy(obj, sdp->refstruct);
+ if (ret < 0) {
+ av_refstruct_unref(&obj);
+ return ret;
+ }
+ data = obj;
+ } else {
#if FF_API_SIDE_DATA_BUF
FF_DISABLE_DEPRECATION_WARNINGS
if (av_buffer_is_writable(sd->buf))
@@ -455,6 +650,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (sd->size)
memcpy(buf->data, sd->data, sd->size);
+ data = buf->data;
+ }
#if FF_API_SIDE_DATA_BUF
FF_DISABLE_DEPRECATION_WARNINGS
av_buffer_unref(&sd->buf);
@@ -464,7 +661,9 @@ FF_ENABLE_DEPRECATION_WARNINGS
av_buffer_unref(&sdp->buf);
sdp->buf = buf;
#endif
- sd->data = buf->data;
+ av_refstruct_unref(&sdp->refstruct);
+ sdp->refstruct = obj;
+ sd->data = data;
return 0;
}
diff --git a/libavutil/side_data.h b/libavutil/side_data.h
index 5d25833882..5a3aeccab0 100644
--- a/libavutil/side_data.h
+++ b/libavutil/side_data.h
@@ -27,6 +27,9 @@ AVFrameSideData *ff_frame_side_data_add_from_buf(AVFrameSideData ***sd,
enum AVFrameSideDataType type,
AVBufferRef *buf);
+AVFrameSideData *ff_frame_side_data_copy(AVFrameSideData ***sd, int *nb_sd,
+ const AVFrameSideData *src);
+
void ff_mdm_get_defaults(void *obj);
void ff_ave_get_defaults(void *obj);
void ff_spherical_get_defaults(void *obj);
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PoC][PATCH 08/14] avutil/frame: add a param change side data type
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
` (5 preceding siblings ...)
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 07/14] avutil/frame: add support for RefStruct as backing for side data James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-29 12:29 ` Andreas Rheinhardt
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 09/14] avutil/ambient_viewing_environment: deprecate av_ambient_viewing_environment_create_side_data() James Almer
` (5 subsequent siblings)
12 siblings, 1 reply; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
Similar in purpose as the packet side data of the same name, but for encoders.
Signed-off-by: James Almer <jamrial@gmail.com>
---
An example of RefCount used for side data, including a copy and uninit callback
to handle allocations within the entry.
libavutil/frame.h | 14 ++++++++++++++
libavutil/side_data.c | 23 +++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 1feb11506a..c677407781 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -243,8 +243,22 @@ enum AVFrameSideDataType {
* The data is an int storing the view ID.
*/
AV_FRAME_DATA_VIEW_ID,
+
+ /**
+ * A side data used to signal an encoder that certain parameters changed.
+ * The payload is an AVParamChange struct.
+ */
+ AV_FRAME_DATA_PARAM_CHANGE,
};
+typedef struct AVParamChange {
+ /**
+ * A dictionary filled with options to be passed to an already initialized
+ * encoder. May contain global and encoder private options.
+ */
+ AVDictionary *opts;
+} AVParamChange;
+
enum AVActiveFormatDescription {
AV_AFD_SAME = 8,
AV_AFD_4_3 = 9,
diff --git a/libavutil/side_data.c b/libavutil/side_data.c
index 597228baf1..c156d2bef8 100644
--- a/libavutil/side_data.c
+++ b/libavutil/side_data.c
@@ -63,6 +63,24 @@ typedef struct FFSideDataDescriptor {
size_t size;
} FFSideDataDescriptor;
+/* Type specific refstruct callbacks */
+
+static int copy_param_change(void *_dst, const void *_src)
+{
+ const AVParamChange *src = _src;
+ AVParamChange *dst = _dst;
+ int ret = av_dict_copy(&dst->opts, src->opts, 0);
+ if (ret < 0)
+ av_dict_free(&dst->opts);
+ return ret;
+}
+
+static void uninit_param_change(AVRefStructOpaque opaque, void *obj)
+{
+ AVParamChange *param = obj;
+ av_dict_free(¶m->opts);
+}
+
static const FFSideDataDescriptor sd_props[] = {
[AV_FRAME_DATA_PANSCAN] = { .p = { "AVPanScan", AV_SIDE_DATA_PROP_STRUCT | AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
.size = sizeof(AVPanScan) },
@@ -88,6 +106,11 @@ static const FFSideDataDescriptor sd_props[] = {
[AV_FRAME_DATA_DOVI_METADATA] = { .p = { "Dolby Vision Metadata", AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
[AV_FRAME_DATA_LCEVC] = { .p = { "LCEVC NAL data", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
[AV_FRAME_DATA_VIEW_ID] = { .p = { "View ID" } },
+ [AV_FRAME_DATA_PARAM_CHANGE] = { .p = { "Param Change", AV_SIDE_DATA_PROP_STRUCT },
+ .props = FF_SIDE_DATA_PROP_REFSTRUCT,
+ .copy = copy_param_change,
+ .uninit = uninit_param_change,
+ .size = sizeof(AVParamChange) },
[AV_FRAME_DATA_STEREO3D] = { .p = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT },
.size = sizeof(AVStereo3D) },
[AV_FRAME_DATA_REPLAYGAIN] = { .p = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT },
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 09/14] avutil/ambient_viewing_environment: deprecate av_ambient_viewing_environment_create_side_data()
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
` (6 preceding siblings ...)
2025-01-25 20:21 ` [FFmpeg-devel] [PoC][PATCH 08/14] avutil/frame: add a param change side data type James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 10/14] avutil/downmix_info: deprecate av_downmix_info_update_side_data() James Almer
` (4 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
It's no longer needed after the addition of av_frame_side_data_new_struct()
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/ambient_viewing_environment.c | 2 ++
libavutil/ambient_viewing_environment.h | 6 ++++++
libavutil/version.h | 1 +
3 files changed, 9 insertions(+)
diff --git a/libavutil/ambient_viewing_environment.c b/libavutil/ambient_viewing_environment.c
index ee2e9427cd..16858bf206 100644
--- a/libavutil/ambient_viewing_environment.c
+++ b/libavutil/ambient_viewing_environment.c
@@ -46,6 +46,7 @@ AVAmbientViewingEnvironment *av_ambient_viewing_environment_alloc(size_t *size)
return env;
}
+#if FF_API_CREATE_SIDE_DATA
AVAmbientViewingEnvironment *av_ambient_viewing_environment_create_side_data(AVFrame *frame)
{
AVFrameSideData *side_data =
@@ -60,3 +61,4 @@ AVAmbientViewingEnvironment *av_ambient_viewing_environment_create_side_data(AVF
return (AVAmbientViewingEnvironment *)side_data->data;
}
+#endif
diff --git a/libavutil/ambient_viewing_environment.h b/libavutil/ambient_viewing_environment.h
index e5e4ac2173..08aac686f0 100644
--- a/libavutil/ambient_viewing_environment.h
+++ b/libavutil/ambient_viewing_environment.h
@@ -22,8 +22,10 @@
#define AVUTIL_AMBIENT_VIEWING_ENVIRONMENT_H
#include <stddef.h>
+#include "attributes.h"
#include "frame.h"
#include "rational.h"
+#include "version.h"
/**
* Ambient viewing environment metadata as defined by H.274. The values are
@@ -61,12 +63,16 @@ typedef struct AVAmbientViewingEnvironment {
*/
AVAmbientViewingEnvironment *av_ambient_viewing_environment_alloc(size_t *size);
+#if FF_API_CREATE_SIDE_DATA
/**
* Allocate and add an AVAmbientViewingEnvironment structure to an existing
* AVFrame as side data.
*
+ * @deprecated use @ref av_frame_side_data_new_struct()
* @return the newly allocated struct, or NULL on failure
*/
+attribute_deprecated
AVAmbientViewingEnvironment *av_ambient_viewing_environment_create_side_data(AVFrame *frame);
+#endif
#endif /* AVUTIL_AMBIENT_VIEWING_ENVIRONMENT_H */
diff --git a/libavutil/version.h b/libavutil/version.h
index e736484a1e..d4229178ab 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -118,6 +118,7 @@
#define FF_API_OPT_INT_LIST (LIBAVUTIL_VERSION_MAJOR < 60)
#define FF_API_OPT_PTR (LIBAVUTIL_VERSION_MAJOR < 60)
#define FF_API_SIDE_DATA_BUF (LIBAVUTIL_VERSION_MAJOR < 60)
+#define FF_API_CREATE_SIDE_DATA (LIBAVUTIL_VERSION_MAJOR < 60)
/**
* @}
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 10/14] avutil/downmix_info: deprecate av_downmix_info_update_side_data()
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
` (7 preceding siblings ...)
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 09/14] avutil/ambient_viewing_environment: deprecate av_ambient_viewing_environment_create_side_data() James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 11/14] avutil/hdr_dynamic_metadata: deprecate av_dynamic_hdr_plus_create_side_data() James Almer
` (3 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
It's no longer needed after the addition of av_frame_side_data_new_struct()
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/downmix_info.c | 2 ++
libavutil/downmix_info.h | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/libavutil/downmix_info.c b/libavutil/downmix_info.c
index c634c6a79f..73d0f6b261 100644
--- a/libavutil/downmix_info.c
+++ b/libavutil/downmix_info.c
@@ -21,6 +21,7 @@
#include "downmix_info.h"
#include "frame.h"
+#if FF_API_CREATE_SIDE_DATA
AVDownmixInfo *av_downmix_info_update_side_data(AVFrame *frame)
{
AVFrameSideData *side_data;
@@ -36,3 +37,4 @@ AVDownmixInfo *av_downmix_info_update_side_data(AVFrame *frame)
return (AVDownmixInfo*)side_data->data;
}
+#endif
diff --git a/libavutil/downmix_info.h b/libavutil/downmix_info.h
index 221cf5bf9b..6580f8873e 100644
--- a/libavutil/downmix_info.h
+++ b/libavutil/downmix_info.h
@@ -21,7 +21,9 @@
#ifndef AVUTIL_DOWNMIX_INFO_H
#define AVUTIL_DOWNMIX_INFO_H
+#include "attributes.h"
#include "frame.h"
+#include "version.h"
/**
* @file
@@ -92,6 +94,7 @@ typedef struct AVDownmixInfo {
double lfe_mix_level;
} AVDownmixInfo;
+#if FF_API_CREATE_SIDE_DATA
/**
* Get a frame's AV_FRAME_DATA_DOWNMIX_INFO side data for editing.
*
@@ -99,10 +102,13 @@ typedef struct AVDownmixInfo {
*
* @param frame the frame for which the side data is to be obtained or created
*
+ * @deprecated use @ref av_frame_side_data_new_struct() and @ref av_frame_side_data_get()
* @return the AVDownmixInfo structure to be edited by the caller, or NULL if
* the structure cannot be allocated.
*/
+attribute_deprecated
AVDownmixInfo *av_downmix_info_update_side_data(AVFrame *frame);
+#endif
/**
* @}
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 11/14] avutil/hdr_dynamic_metadata: deprecate av_dynamic_hdr_plus_create_side_data()
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
` (8 preceding siblings ...)
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 10/14] avutil/downmix_info: deprecate av_downmix_info_update_side_data() James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 12/14] avutil/hdr_dynamic_vivid_metadata: deprecate av_dynamic_hdr_vivid_create_side_data() James Almer
` (2 subsequent siblings)
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
It's no longer needed after the addition of av_frame_side_data_new_struct()
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/hdr_dynamic_metadata.c | 2 ++
libavutil/hdr_dynamic_metadata.h | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/libavutil/hdr_dynamic_metadata.c b/libavutil/hdr_dynamic_metadata.c
index 7033f060c0..25ea6544c1 100644
--- a/libavutil/hdr_dynamic_metadata.c
+++ b/libavutil/hdr_dynamic_metadata.c
@@ -45,6 +45,7 @@ AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size)
return hdr_plus;
}
+#if FF_API_CREATE_SIDE_DATA
AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame)
{
AVFrameSideData *side_data = av_frame_new_side_data(frame,
@@ -57,6 +58,7 @@ AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame)
return (AVDynamicHDRPlus *)side_data->data;
}
+#endif
int av_dynamic_hdr_plus_from_t35(AVDynamicHDRPlus *s, const uint8_t *data,
size_t size)
diff --git a/libavutil/hdr_dynamic_metadata.h b/libavutil/hdr_dynamic_metadata.h
index 5100ed6f41..415b1b1fbd 100644
--- a/libavutil/hdr_dynamic_metadata.h
+++ b/libavutil/hdr_dynamic_metadata.h
@@ -21,8 +21,10 @@
#ifndef AVUTIL_HDR_DYNAMIC_METADATA_H
#define AVUTIL_HDR_DYNAMIC_METADATA_H
+#include "attributes.h"
#include "frame.h"
#include "rational.h"
+#include "version.h"
/**
* Option for overlapping elliptical pixel selectors in an image.
@@ -331,14 +333,18 @@ typedef struct AVDynamicHDRPlus {
*/
AVDynamicHDRPlus *av_dynamic_hdr_plus_alloc(size_t *size);
+#if FF_API_CREATE_SIDE_DATA
/**
* Allocate a complete AVDynamicHDRPlus and add it to the frame.
* @param frame The frame which side data is added to.
*
+ * @deprecated use @ref av_frame_side_data_new_struct()
* @return The AVDynamicHDRPlus structure to be filled by caller or NULL
* on failure.
*/
+attribute_deprecated
AVDynamicHDRPlus *av_dynamic_hdr_plus_create_side_data(AVFrame *frame);
+#endif
/**
* Parse the user data registered ITU-T T.35 to AVbuffer (AVDynamicHDRPlus).
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 12/14] avutil/hdr_dynamic_vivid_metadata: deprecate av_dynamic_hdr_vivid_create_side_data()
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
` (9 preceding siblings ...)
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 11/14] avutil/hdr_dynamic_metadata: deprecate av_dynamic_hdr_plus_create_side_data() James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 13/14] avutil/mastering_display_metadata: deprecate av_{content_light, mastering_display_metadata}_create_side_data() James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 14/14] avutil/stereo3d: deprecate av_stereo3d_create_side_data() James Almer
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
It's no longer needed after the addition of av_frame_side_data_new_struct()
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/hdr_dynamic_vivid_metadata.c | 2 ++
libavutil/hdr_dynamic_vivid_metadata.h | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/libavutil/hdr_dynamic_vivid_metadata.c b/libavutil/hdr_dynamic_vivid_metadata.c
index 32da01f587..140a4df4c2 100644
--- a/libavutil/hdr_dynamic_vivid_metadata.c
+++ b/libavutil/hdr_dynamic_vivid_metadata.c
@@ -33,6 +33,7 @@ AVDynamicHDRVivid *av_dynamic_hdr_vivid_alloc(size_t *size)
return hdr_vivid;
}
+#if FF_API_CREATE_SIDE_DATA
AVDynamicHDRVivid *av_dynamic_hdr_vivid_create_side_data(AVFrame *frame)
{
AVFrameSideData *side_data = av_frame_new_side_data(frame,
@@ -45,3 +46,4 @@ AVDynamicHDRVivid *av_dynamic_hdr_vivid_create_side_data(AVFrame *frame)
return (AVDynamicHDRVivid *)side_data->data;
}
+#endif
diff --git a/libavutil/hdr_dynamic_vivid_metadata.h b/libavutil/hdr_dynamic_vivid_metadata.h
index 4524a81557..0b42ccc7d0 100644
--- a/libavutil/hdr_dynamic_vivid_metadata.h
+++ b/libavutil/hdr_dynamic_vivid_metadata.h
@@ -21,8 +21,10 @@
#ifndef AVUTIL_HDR_DYNAMIC_VIVID_METADATA_H
#define AVUTIL_HDR_DYNAMIC_VIVID_METADATA_H
+#include "attributes.h"
#include "frame.h"
#include "rational.h"
+#include "version.h"
/**
* HDR Vivid three spline params.
@@ -334,13 +336,17 @@ typedef struct AVDynamicHDRVivid {
*/
AVDynamicHDRVivid *av_dynamic_hdr_vivid_alloc(size_t *size);
+#if FF_API_CREATE_SIDE_DATA
/**
* Allocate a complete AVDynamicHDRVivid and add it to the frame.
* @param frame The frame which side data is added to.
*
+ * @deprecated use @ref av_frame_side_data_new_struct()
* @return The AVDynamicHDRVivid structure to be filled by caller or NULL
* on failure.
*/
+attribute_deprecated
AVDynamicHDRVivid *av_dynamic_hdr_vivid_create_side_data(AVFrame *frame);
+#endif
#endif /* AVUTIL_HDR_DYNAMIC_VIVID_METADATA_H */
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 13/14] avutil/mastering_display_metadata: deprecate av_{content_light, mastering_display_metadata}_create_side_data()
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
` (10 preceding siblings ...)
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 12/14] avutil/hdr_dynamic_vivid_metadata: deprecate av_dynamic_hdr_vivid_create_side_data() James Almer
@ 2025-01-25 20:21 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 14/14] avutil/stereo3d: deprecate av_stereo3d_create_side_data() James Almer
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
It's no longer needed after the addition of av_frame_side_data_new_struct()
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/mastering_display_metadata.c | 4 ++++
libavutil/mastering_display_metadata.h | 10 ++++++++++
2 files changed, 14 insertions(+)
diff --git a/libavutil/mastering_display_metadata.c b/libavutil/mastering_display_metadata.c
index 4948f30523..48d8b04cc8 100644
--- a/libavutil/mastering_display_metadata.c
+++ b/libavutil/mastering_display_metadata.c
@@ -58,6 +58,7 @@ AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc_size(size_t *siz
return mastering;
}
+#if FF_API_CREATE_SIDE_DATA
AVMasteringDisplayMetadata *av_mastering_display_metadata_create_side_data(AVFrame *frame)
{
AVFrameSideData *side_data = av_frame_new_side_data(frame,
@@ -71,6 +72,7 @@ AVMasteringDisplayMetadata *av_mastering_display_metadata_create_side_data(AVFra
return (AVMasteringDisplayMetadata *)side_data->data;
}
+#endif
AVContentLightMetadata *av_content_light_metadata_alloc(size_t *size)
{
@@ -82,6 +84,7 @@ AVContentLightMetadata *av_content_light_metadata_alloc(size_t *size)
return metadata;
}
+#if FF_API_CREATE_SIDE_DATA
AVContentLightMetadata *av_content_light_metadata_create_side_data(AVFrame *frame)
{
AVFrameSideData *side_data = av_frame_new_side_data(frame,
@@ -94,3 +97,4 @@ AVContentLightMetadata *av_content_light_metadata_create_side_data(AVFrame *fram
return (AVContentLightMetadata *)side_data->data;
}
+#endif
diff --git a/libavutil/mastering_display_metadata.h b/libavutil/mastering_display_metadata.h
index 52fcef9e37..60ca817eff 100644
--- a/libavutil/mastering_display_metadata.h
+++ b/libavutil/mastering_display_metadata.h
@@ -21,8 +21,10 @@
#ifndef AVUTIL_MASTERING_DISPLAY_METADATA_H
#define AVUTIL_MASTERING_DISPLAY_METADATA_H
+#include "attributes.h"
#include "frame.h"
#include "rational.h"
+#include "version.h"
/**
@@ -86,14 +88,18 @@ AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc(void);
*/
AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc_size(size_t *size);
+#if FF_API_CREATE_SIDE_DATA
/**
* Allocate a complete AVMasteringDisplayMetadata and add it to the frame.
*
* @param frame The frame which side data is added to.
*
+ * @deprecated use @ref av_frame_side_data_new_struct()
* @return The AVMasteringDisplayMetadata structure to be filled by caller.
*/
+attribute_deprecated
AVMasteringDisplayMetadata *av_mastering_display_metadata_create_side_data(AVFrame *frame);
+#endif
/**
* Content light level needed by to transmit HDR over HDMI (CTA-861.3).
@@ -125,13 +131,17 @@ typedef struct AVContentLightMetadata {
*/
AVContentLightMetadata *av_content_light_metadata_alloc(size_t *size);
+#if FF_API_CREATE_SIDE_DATA
/**
* Allocate a complete AVContentLightMetadata and add it to the frame.
*
* @param frame The frame which side data is added to.
*
+ * @deprecated use @ref av_frame_side_data_new_struct()
* @return The AVContentLightMetadata structure to be filled by caller.
*/
+attribute_deprecated
AVContentLightMetadata *av_content_light_metadata_create_side_data(AVFrame *frame);
+#endif
#endif /* AVUTIL_MASTERING_DISPLAY_METADATA_H */
--
2.48.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] 16+ messages in thread
* [FFmpeg-devel] [PATCH 14/14] avutil/stereo3d: deprecate av_stereo3d_create_side_data()
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
` (11 preceding siblings ...)
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 13/14] avutil/mastering_display_metadata: deprecate av_{content_light, mastering_display_metadata}_create_side_data() James Almer
@ 2025-01-25 20:21 ` James Almer
12 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-25 20:21 UTC (permalink / raw)
To: ffmpeg-devel
It's no longer needed after the addition of av_frame_side_data_new_struct()
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/stereo3d.c | 2 ++
libavutil/stereo3d.h | 6 ++++++
2 files changed, 8 insertions(+)
diff --git a/libavutil/stereo3d.c b/libavutil/stereo3d.c
index d6de476532..8a21cfd407 100644
--- a/libavutil/stereo3d.c
+++ b/libavutil/stereo3d.c
@@ -51,6 +51,7 @@ AVStereo3D *av_stereo3d_alloc_size(size_t *size)
return stereo;
}
+#if FF_API_CREATE_SIDE_DATA
AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame)
{
AVFrameSideData *side_data = av_frame_new_side_data(frame,
@@ -64,6 +65,7 @@ AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame)
return (AVStereo3D *)side_data->data;
}
+#endif
static const char * const stereo3d_type_names[] = {
[AV_STEREO3D_2D] = "2D",
diff --git a/libavutil/stereo3d.h b/libavutil/stereo3d.h
index c0a4ab3f2d..4f679b9bb1 100644
--- a/libavutil/stereo3d.h
+++ b/libavutil/stereo3d.h
@@ -29,7 +29,9 @@
#include <stdint.h>
+#include "attributes.h"
#include "frame.h"
+#include "version.h"
/**
* @defgroup lavu_video_stereo3d Stereo3D types and functions
@@ -255,14 +257,18 @@ AVStereo3D *av_stereo3d_alloc(void);
*/
AVStereo3D *av_stereo3d_alloc_size(size_t *size);
+#if FF_API_CREATE_SIDE_DATA
/**
* Allocate a complete AVFrameSideData and add it to the frame.
*
* @param frame The frame which side data is added to.
*
+ * @deprecated use @ref av_frame_side_data_new_struct()
* @return The AVStereo3D structure to be filled by caller.
*/
+attribute_deprecated
AVStereo3D *av_stereo3d_create_side_data(AVFrame *frame);
+#endif
/**
* Provide a human-readable name of a given stereo3d type.
--
2.48.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] 16+ messages in thread
* Re: [FFmpeg-devel] [PoC][PATCH 08/14] avutil/frame: add a param change side data type
2025-01-25 20:21 ` [FFmpeg-devel] [PoC][PATCH 08/14] avutil/frame: add a param change side data type James Almer
@ 2025-01-29 12:29 ` Andreas Rheinhardt
2025-01-29 13:53 ` James Almer
0 siblings, 1 reply; 16+ messages in thread
From: Andreas Rheinhardt @ 2025-01-29 12:29 UTC (permalink / raw)
To: ffmpeg-devel
James Almer:
> Similar in purpose as the packet side data of the same name, but for encoders.
>
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> An example of RefCount used for side data, including a copy and uninit callback
> to handle allocations within the entry.
>
> libavutil/frame.h | 14 ++++++++++++++
> libavutil/side_data.c | 23 +++++++++++++++++++++++
> 2 files changed, 37 insertions(+)
>
> diff --git a/libavutil/frame.h b/libavutil/frame.h
> index 1feb11506a..c677407781 100644
> --- a/libavutil/frame.h
> +++ b/libavutil/frame.h
> @@ -243,8 +243,22 @@ enum AVFrameSideDataType {
> * The data is an int storing the view ID.
> */
> AV_FRAME_DATA_VIEW_ID,
> +
> + /**
> + * A side data used to signal an encoder that certain parameters changed.
> + * The payload is an AVParamChange struct.
> + */
> + AV_FRAME_DATA_PARAM_CHANGE,
> };
>
> +typedef struct AVParamChange {
> + /**
> + * A dictionary filled with options to be passed to an already initialized
> + * encoder. May contain global and encoder private options.
> + */
> + AVDictionary *opts;
> +} AVParamChange;
> +
> enum AVActiveFormatDescription {
> AV_AFD_SAME = 8,
> AV_AFD_4_3 = 9,
> diff --git a/libavutil/side_data.c b/libavutil/side_data.c
> index 597228baf1..c156d2bef8 100644
> --- a/libavutil/side_data.c
> +++ b/libavutil/side_data.c
> @@ -63,6 +63,24 @@ typedef struct FFSideDataDescriptor {
> size_t size;
> } FFSideDataDescriptor;
>
> +/* Type specific refstruct callbacks */
> +
> +static int copy_param_change(void *_dst, const void *_src)
> +{
> + const AVParamChange *src = _src;
> + AVParamChange *dst = _dst;
> + int ret = av_dict_copy(&dst->opts, src->opts, 0);
> + if (ret < 0)
> + av_dict_free(&dst->opts);
> + return ret;
> +}
> +
> +static void uninit_param_change(AVRefStructOpaque opaque, void *obj)
> +{
> + AVParamChange *param = obj;
> + av_dict_free(¶m->opts);
> +}
> +
> static const FFSideDataDescriptor sd_props[] = {
> [AV_FRAME_DATA_PANSCAN] = { .p = { "AVPanScan", AV_SIDE_DATA_PROP_STRUCT | AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
> .size = sizeof(AVPanScan) },
> @@ -88,6 +106,11 @@ static const FFSideDataDescriptor sd_props[] = {
> [AV_FRAME_DATA_DOVI_METADATA] = { .p = { "Dolby Vision Metadata", AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
> [AV_FRAME_DATA_LCEVC] = { .p = { "LCEVC NAL data", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
> [AV_FRAME_DATA_VIEW_ID] = { .p = { "View ID" } },
> + [AV_FRAME_DATA_PARAM_CHANGE] = { .p = { "Param Change", AV_SIDE_DATA_PROP_STRUCT },
> + .props = FF_SIDE_DATA_PROP_REFSTRUCT,
> + .copy = copy_param_change,
> + .uninit = uninit_param_change,
> + .size = sizeof(AVParamChange) },
> [AV_FRAME_DATA_STEREO3D] = { .p = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT },
> .size = sizeof(AVStereo3D) },
> [AV_FRAME_DATA_REPLAYGAIN] = { .p = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT },
I dislike the whole approach: Frame side data is supposed to contain
side-data that applies to the frame; yet a lot of encoder options which
will ultimately be added to this side data (if it gets committed) are
not frame properties at all.
Furthermore, this approach necessitates checking every frame (even of
encoders that do not support parameter changes) for the existence of
said side-data, although this side data will not exist in the
overwhelming majority of cases. Why not add a new function for this
task? (This does not imply that I am in favor of the reconfiguration
approach at all. I'm still leaning towards "close+reopen".)
- 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] 16+ messages in thread
* Re: [FFmpeg-devel] [PoC][PATCH 08/14] avutil/frame: add a param change side data type
2025-01-29 12:29 ` Andreas Rheinhardt
@ 2025-01-29 13:53 ` James Almer
0 siblings, 0 replies; 16+ messages in thread
From: James Almer @ 2025-01-29 13:53 UTC (permalink / raw)
To: ffmpeg-devel
[-- Attachment #1.1.1: Type: text/plain, Size: 5420 bytes --]
On 1/29/2025 9:29 AM, Andreas Rheinhardt wrote:
> James Almer:
>> Similar in purpose as the packet side data of the same name, but for encoders.
>>
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>> An example of RefCount used for side data, including a copy and uninit callback
>> to handle allocations within the entry.
>>
>> libavutil/frame.h | 14 ++++++++++++++
>> libavutil/side_data.c | 23 +++++++++++++++++++++++
>> 2 files changed, 37 insertions(+)
>>
>> diff --git a/libavutil/frame.h b/libavutil/frame.h
>> index 1feb11506a..c677407781 100644
>> --- a/libavutil/frame.h
>> +++ b/libavutil/frame.h
>> @@ -243,8 +243,22 @@ enum AVFrameSideDataType {
>> * The data is an int storing the view ID.
>> */
>> AV_FRAME_DATA_VIEW_ID,
>> +
>> + /**
>> + * A side data used to signal an encoder that certain parameters changed.
>> + * The payload is an AVParamChange struct.
>> + */
>> + AV_FRAME_DATA_PARAM_CHANGE,
>> };
>>
>> +typedef struct AVParamChange {
>> + /**
>> + * A dictionary filled with options to be passed to an already initialized
>> + * encoder. May contain global and encoder private options.
>> + */
>> + AVDictionary *opts;
>> +} AVParamChange;
>> +
>> enum AVActiveFormatDescription {
>> AV_AFD_SAME = 8,
>> AV_AFD_4_3 = 9,
>> diff --git a/libavutil/side_data.c b/libavutil/side_data.c
>> index 597228baf1..c156d2bef8 100644
>> --- a/libavutil/side_data.c
>> +++ b/libavutil/side_data.c
>> @@ -63,6 +63,24 @@ typedef struct FFSideDataDescriptor {
>> size_t size;
>> } FFSideDataDescriptor;
>>
>> +/* Type specific refstruct callbacks */
>> +
>> +static int copy_param_change(void *_dst, const void *_src)
>> +{
>> + const AVParamChange *src = _src;
>> + AVParamChange *dst = _dst;
>> + int ret = av_dict_copy(&dst->opts, src->opts, 0);
>> + if (ret < 0)
>> + av_dict_free(&dst->opts);
>> + return ret;
>> +}
>> +
>> +static void uninit_param_change(AVRefStructOpaque opaque, void *obj)
>> +{
>> + AVParamChange *param = obj;
>> + av_dict_free(¶m->opts);
>> +}
>> +
>> static const FFSideDataDescriptor sd_props[] = {
>> [AV_FRAME_DATA_PANSCAN] = { .p = { "AVPanScan", AV_SIDE_DATA_PROP_STRUCT | AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
>> .size = sizeof(AVPanScan) },
>> @@ -88,6 +106,11 @@ static const FFSideDataDescriptor sd_props[] = {
>> [AV_FRAME_DATA_DOVI_METADATA] = { .p = { "Dolby Vision Metadata", AV_SIDE_DATA_PROP_COLOR_DEPENDENT } },
>> [AV_FRAME_DATA_LCEVC] = { .p = { "LCEVC NAL data", AV_SIDE_DATA_PROP_SIZE_DEPENDENT } },
>> [AV_FRAME_DATA_VIEW_ID] = { .p = { "View ID" } },
>> + [AV_FRAME_DATA_PARAM_CHANGE] = { .p = { "Param Change", AV_SIDE_DATA_PROP_STRUCT },
>> + .props = FF_SIDE_DATA_PROP_REFSTRUCT,
>> + .copy = copy_param_change,
>> + .uninit = uninit_param_change,
>> + .size = sizeof(AVParamChange) },
>> [AV_FRAME_DATA_STEREO3D] = { .p = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT },
>> .size = sizeof(AVStereo3D) },
>> [AV_FRAME_DATA_REPLAYGAIN] = { .p = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_STRUCT },
>
> I dislike the whole approach: Frame side data is supposed to contain
> side-data that applies to the frame; yet a lot of encoder options which
> will ultimately be added to this side data (if it gets committed) are
> not frame properties at all.
Fair enough.
>
> Furthermore, this approach necessitates checking every frame (even of
> encoders that do not support parameter changes) for the existence of
> said side-data, although this side data will not exist in the
There's no need to check them. I just copied the check done for the
packet side data of the same name, which aborts if it's present when it
shouldn't. We can always just silently ignore it instead if the encoder
doesn't care about it.
> overwhelming majority of cases. Why not add a new function for this
> task? (This does not imply that I am in favor of the reconfiguration
> approach at all. I'm still leaning towards "close+reopen".)
Like i said, there are some cases where it's better to do a graceful
re-initialization for the sake of compression if you only care about
changing a few values. If we can implement a way to do it that's not
invasive, then it's IMO worth giving the option.
Right now, libx264 does it silently if it detects changes to the avctx
or the private struct, which is not ok as it gives the user the
impression it can be done for every encoder, when that's clearly not the
case and can even result in crazy behavior for some.
I'll look into making it a function later.
[-- Attachment #1.2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
[-- Attachment #2: Type: text/plain, Size: 251 bytes --]
_______________________________________________
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] 16+ messages in thread
end of thread, other threads:[~2025-01-29 13:53 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-01-25 20:21 [FFmpeg-devel] [PATCH 01/14] avutil/frame: move side data helpers to a new file James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 02/14] avutil/frame: allow the addition of internal fields to AVSideDataDescriptor James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 03/14] avutil/frame: allow the addition of internal fields to AVFrameSideData James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 04/14] avutil/frame: schedule making AVFrameSideData.buf internal James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 05/14] avutil/frame: add functions to check and ensure a side data entry is writable James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 06/14] avutil/frame: av_frame_side_data_new_struct() James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 07/14] avutil/frame: add support for RefStruct as backing for side data James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PoC][PATCH 08/14] avutil/frame: add a param change side data type James Almer
2025-01-29 12:29 ` Andreas Rheinhardt
2025-01-29 13:53 ` James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 09/14] avutil/ambient_viewing_environment: deprecate av_ambient_viewing_environment_create_side_data() James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 10/14] avutil/downmix_info: deprecate av_downmix_info_update_side_data() James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 11/14] avutil/hdr_dynamic_metadata: deprecate av_dynamic_hdr_plus_create_side_data() James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 12/14] avutil/hdr_dynamic_vivid_metadata: deprecate av_dynamic_hdr_vivid_create_side_data() James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 13/14] avutil/mastering_display_metadata: deprecate av_{content_light, mastering_display_metadata}_create_side_data() James Almer
2025-01-25 20:21 ` [FFmpeg-devel] [PATCH 14/14] avutil/stereo3d: deprecate av_stereo3d_create_side_data() James Almer
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