* [FFmpeg-devel] [PATCH v8 01/14] avutil/frame: split side data list wiping out to non-AVFrame function
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 02/14] avutil/frame: add helper for freeing arrays of side data Jan Ekström
` (12 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
This will make it possible to to reuse logic in further commits.
---
libavutil/frame.c | 23 ++++++++++++++---------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 079cf6595b..ab425b2235 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -63,14 +63,19 @@ static void free_side_data(AVFrameSideData **ptr_sd)
av_freep(ptr_sd);
}
-static void wipe_side_data(AVFrame *frame)
+static void wipe_side_data(AVFrameSideData ***sd, int *nb_side_data)
{
- for (int i = 0; i < frame->nb_side_data; i++) {
- free_side_data(&frame->side_data[i]);
+ for (int i = 0; i < *nb_side_data; i++) {
+ free_side_data(&((*sd)[i]));
}
- frame->nb_side_data = 0;
+ *nb_side_data = 0;
+
+ av_freep(sd);
+}
- av_freep(&frame->side_data);
+static void frame_side_data_wipe(AVFrame *frame)
+{
+ wipe_side_data(&frame->side_data, &frame->nb_side_data);
}
AVFrame *av_frame_alloc(void)
@@ -288,7 +293,7 @@ FF_ENABLE_DEPRECATION_WARNINGS
sd_dst = av_frame_new_side_data(dst, sd_src->type,
sd_src->size);
if (!sd_dst) {
- wipe_side_data(dst);
+ frame_side_data_wipe(dst);
return AVERROR(ENOMEM);
}
memcpy(sd_dst->data, sd_src->data, sd_src->size);
@@ -297,7 +302,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);
- wipe_side_data(dst);
+ frame_side_data_wipe(dst);
return AVERROR(ENOMEM);
}
}
@@ -437,7 +442,7 @@ int av_frame_replace(AVFrame *dst, const AVFrame *src)
if (ret < 0)
goto fail;
- wipe_side_data(dst);
+ frame_side_data_wipe(dst);
av_dict_free(&dst->metadata);
ret = frame_copy_props(dst, src, 0);
if (ret < 0)
@@ -536,7 +541,7 @@ void av_frame_unref(AVFrame *frame)
if (!frame)
return;
- wipe_side_data(frame);
+ frame_side_data_wipe(frame);
for (int i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
av_buffer_unref(&frame->buf[i]);
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 02/14] avutil/frame: add helper for freeing arrays of side data
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 01/14] avutil/frame: split side data list wiping out to non-AVFrame function Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 03/14] avutil/frame: split side_data_from_buf to base and AVFrame func Jan Ekström
` (11 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
---
libavutil/frame.c | 5 +++++
libavutil/frame.h | 11 +++++++++++
2 files changed, 16 insertions(+)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index ab425b2235..baac0706db 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -78,6 +78,11 @@ 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);
+}
+
AVFrame *av_frame_alloc(void)
{
AVFrame *frame = av_malloc(sizeof(*frame));
diff --git a/libavutil/frame.h b/libavutil/frame.h
index b94687941d..27281c168f 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -988,6 +988,17 @@ int av_frame_apply_cropping(AVFrame *frame, int flags);
*/
const char *av_frame_side_data_name(enum AVFrameSideDataType type);
+/**
+ * Free all side data entries and their contents, then zeroes out the
+ * values which the pointers are pointing to.
+ *
+ * @param sd pointer to array of side data to free. Will be set to NULL
+ * upon return.
+ * @param nb_sd pointer to an integer containing the number of entries in
+ * the array. Will be set to 0 upon return.
+ */
+void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd);
+
/**
* @}
*/
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 03/14] avutil/frame: split side_data_from_buf to base and AVFrame func
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 01/14] avutil/frame: split side data list wiping out to non-AVFrame function Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 02/14] avutil/frame: add helper for freeing arrays of side data Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 04/14] avutil/frame: split side data removal out to non-AVFrame function Jan Ekström
` (10 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
---
libavutil/frame.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index baac0706db..9ebe830c5c 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -679,23 +679,23 @@ AVBufferRef *av_frame_get_plane_buffer(const AVFrame *frame, int plane)
return NULL;
}
-AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
- enum AVFrameSideDataType type,
- AVBufferRef *buf)
+static AVFrameSideData *add_side_data_to_set_from_buf(AVFrameSideData ***sd,
+ int *nb_sd,
+ enum AVFrameSideDataType type,
+ AVBufferRef *buf)
{
AVFrameSideData *ret, **tmp;
if (!buf)
return NULL;
- if (frame->nb_side_data > INT_MAX / sizeof(*frame->side_data) - 1)
+ if (*nb_sd > INT_MAX / sizeof(*sd) - 1)
return NULL;
- tmp = av_realloc(frame->side_data,
- (frame->nb_side_data + 1) * sizeof(*frame->side_data));
+ tmp = av_realloc(*sd, (*nb_sd + 1) * sizeof(*sd));
if (!tmp)
return NULL;
- frame->side_data = tmp;
+ *sd = tmp;
ret = av_mallocz(sizeof(*ret));
if (!ret)
@@ -706,11 +706,20 @@ AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
ret->size = buf->size;
ret->type = type;
- frame->side_data[frame->nb_side_data++] = ret;
+ (*sd)[(*nb_sd)++] = ret;
return ret;
}
+AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
+ enum AVFrameSideDataType type,
+ AVBufferRef *buf)
+{
+ return
+ add_side_data_to_set_from_buf(&frame->side_data, &frame->nb_side_data,
+ type, buf);
+}
+
AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
enum AVFrameSideDataType type,
size_t size)
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 04/14] avutil/frame: split side data removal out to non-AVFrame function
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
` (2 preceding siblings ...)
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 03/14] avutil/frame: split side_data_from_buf to base and AVFrame func Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 05/14] avutil/frame: add helper for adding side data to array Jan Ekström
` (9 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
This will make it possible to reuse logic in further commits.
---
libavutil/frame.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 9ebe830c5c..dd27456031 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -83,6 +83,21 @@ 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)--;
+ }
+}
+
AVFrame *av_frame_alloc(void)
{
AVFrame *frame = av_malloc(sizeof(*frame));
@@ -801,14 +816,7 @@ int av_frame_copy(AVFrame *dst, const AVFrame *src)
void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
{
- for (int i = frame->nb_side_data - 1; i >= 0; i--) {
- AVFrameSideData *sd = frame->side_data[i];
- if (sd->type == type) {
- free_side_data(&frame->side_data[i]);
- frame->side_data[i] = frame->side_data[frame->nb_side_data - 1];
- frame->nb_side_data--;
- }
- }
+ remove_side_data(&frame->side_data, &frame->nb_side_data, type);
}
const char *av_frame_side_data_name(enum AVFrameSideDataType type)
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 05/14] avutil/frame: add helper for adding side data to array
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
` (3 preceding siblings ...)
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 04/14] avutil/frame: split side data removal out to non-AVFrame function Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 06/14] avutil/frame: add helper for adding existing " Jan Ekström
` (8 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
Additionally, add an API test to check that the no-duplicates
addition works after duplicates have been inserted.
---
libavutil/Makefile | 1 +
libavutil/frame.c | 17 ++++++
libavutil/frame.h | 22 +++++++
libavutil/tests/side_data_set.c | 103 ++++++++++++++++++++++++++++++++
tests/fate/libavutil.mak | 4 ++
tests/ref/fate/side_data_set | 14 +++++
6 files changed, 161 insertions(+)
create mode 100644 libavutil/tests/side_data_set.c
create mode 100644 tests/ref/fate/side_data_set
diff --git a/libavutil/Makefile b/libavutil/Makefile
index e7709b97d0..4415c913a1 100644
--- a/libavutil/Makefile
+++ b/libavutil/Makefile
@@ -271,6 +271,7 @@ TESTPROGS = adler32 \
ripemd \
sha \
sha512 \
+ side_data_set \
softfloat \
tree \
twofish \
diff --git a/libavutil/frame.c b/libavutil/frame.c
index dd27456031..4074391a92 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -747,6 +747,23 @@ AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
return ret;
}
+AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ size_t size, unsigned int flags)
+{
+ AVBufferRef *buf = av_buffer_alloc(size);
+ AVFrameSideData *ret = NULL;
+
+ if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
+ remove_side_data(sd, nb_sd, type);
+
+ ret = add_side_data_to_set_from_buf(sd, nb_sd, type, buf);
+ if (!ret)
+ av_buffer_unref(&buf);
+
+ return ret;
+}
+
AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
enum AVFrameSideDataType type)
{
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 27281c168f..5d68d1e7af 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -999,6 +999,28 @@ const char *av_frame_side_data_name(enum AVFrameSideDataType type);
*/
void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd);
+#define AV_FRAME_SIDE_DATA_FLAG_UNIQUE (1 << 0)
+
+/**
+ * Add new side data entry to an array.
+ *
+ * @param sd pointer to array of side data to which to add another entry,
+ * or to NULL in order to start a new array.
+ * @param nb_sd pointer to an integer containing the number of entries in
+ * the array.
+ * @param type type of the added side data
+ * @param size size of the side data
+ * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0.
+ *
+ * @return newly added side data on success, NULL on error. In case of
+ * AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of matching
+ * AVFrameSideDataType will be removed before the addition is
+ * attempted.
+ */
+AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ size_t size, unsigned int flags);
+
/**
* @}
*/
diff --git a/libavutil/tests/side_data_set.c b/libavutil/tests/side_data_set.c
new file mode 100644
index 0000000000..793a62c009
--- /dev/null
+++ b/libavutil/tests/side_data_set.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2023 Jan Ekström <jeebjp@gmail.com>
+ *
+ * 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 <stdio.h>
+#include "libavutil/frame.c"
+#include "libavutil/mastering_display_metadata.h"
+
+static void print_clls(const AVFrameSideData **sd, const int nb_sd)
+{
+ for (int i = 0; i < nb_sd; i++) {
+ const AVFrameSideData *entry = sd[i];
+
+ printf("sd %d, %s",
+ i, av_frame_side_data_name(entry->type));
+
+ if (entry->type != AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) {
+ putchar('\n');
+ continue;
+ }
+
+ printf(": MaxCLL: %u\n",
+ ((AVContentLightMetadata *)entry->data)->MaxCLL);
+ }
+}
+
+typedef struct FrameSideDataSet {
+ AVFrameSideData **sd;
+ int nb_sd;
+} FrameSideDataSet;
+
+int main(void)
+{
+ FrameSideDataSet set = { 0 };
+
+ av_assert0(
+ av_frame_side_data_new(&set.sd, &set.nb_sd,
+ AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT,
+ 0, 0));
+
+ // test entries in the middle
+ for (int value = 1; value < 4; value++) {
+ AVFrameSideData *sd = av_frame_side_data_new(
+ &set.sd, &set.nb_sd, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
+ sizeof(AVContentLightMetadata), 0);
+
+ av_assert0(sd);
+
+ ((AVContentLightMetadata *)sd->data)->MaxCLL = value;
+ }
+
+ av_assert0(
+ av_frame_side_data_new(
+ &set.sd, &set.nb_sd, AV_FRAME_DATA_SPHERICAL, 0, 0));
+
+ // test entries at the end
+ for (int value = 1; value < 4; value++) {
+ AVFrameSideData *sd = av_frame_side_data_new(
+ &set.sd, &set.nb_sd, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
+ sizeof(AVContentLightMetadata), 0);
+
+ av_assert0(sd);
+
+ ((AVContentLightMetadata *)sd->data)->MaxCLL = value + 3;
+ }
+
+ puts("Initial addition results with duplicates:");
+ print_clls((const AVFrameSideData **)set.sd, set.nb_sd);
+
+ {
+ AVFrameSideData *sd = av_frame_side_data_new(
+ &set.sd, &set.nb_sd, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
+ sizeof(AVContentLightMetadata),
+ AV_FRAME_SIDE_DATA_FLAG_UNIQUE);
+
+ av_assert0(sd);
+
+ ((AVContentLightMetadata *)sd->data)->MaxCLL = 1337;
+ }
+
+ puts("\nFinal state after a single 'no-duplicates' addition:");
+ print_clls((const AVFrameSideData **)set.sd, set.nb_sd);
+
+ av_frame_side_data_free(&set.sd, &set.nb_sd);
+
+ return 0;
+}
diff --git a/tests/fate/libavutil.mak b/tests/fate/libavutil.mak
index 80153f4395..6864ea9c03 100644
--- a/tests/fate/libavutil.mak
+++ b/tests/fate/libavutil.mak
@@ -148,6 +148,10 @@ FATE_LIBAVUTIL += fate-sha512
fate-sha512: libavutil/tests/sha512$(EXESUF)
fate-sha512: CMD = run libavutil/tests/sha512$(EXESUF)
+FATE_LIBAVUTIL += fate-side_data_set
+fate-side_data_set: libavutil/tests/side_data_set$(EXESUF)
+fate-side_data_set: CMD = run libavutil/tests/side_data_set$(EXESUF)
+
FATE_LIBAVUTIL += fate-tree
fate-tree: libavutil/tests/tree$(EXESUF)
fate-tree: CMD = run libavutil/tests/tree$(EXESUF)
diff --git a/tests/ref/fate/side_data_set b/tests/ref/fate/side_data_set
new file mode 100644
index 0000000000..7d8c684d8f
--- /dev/null
+++ b/tests/ref/fate/side_data_set
@@ -0,0 +1,14 @@
+Initial addition results with duplicates:
+sd 0, Ambient viewing environment
+sd 1, Content light level metadata: MaxCLL: 1
+sd 2, Content light level metadata: MaxCLL: 2
+sd 3, Content light level metadata: MaxCLL: 3
+sd 4, Spherical Mapping
+sd 5, Content light level metadata: MaxCLL: 4
+sd 6, Content light level metadata: MaxCLL: 5
+sd 7, Content light level metadata: MaxCLL: 6
+
+Final state after a single 'no-duplicates' addition:
+sd 0, Ambient viewing environment
+sd 1, Spherical Mapping
+sd 2, Content light level metadata: MaxCLL: 1337
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 06/14] avutil/frame: add helper for adding existing side data to array
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
` (4 preceding siblings ...)
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 05/14] avutil/frame: add helper for adding side data to array Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-12 21:06 ` James Almer
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 07/14] avutil/frame: add helper for adding side data w/ AVBufferRef " Jan Ekström
` (7 subsequent siblings)
13 siblings, 1 reply; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
---
libavutil/frame.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++
libavutil/frame.h | 20 +++++++++++++++++++
2 files changed, 69 insertions(+)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 4074391a92..46f976a3ed 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -98,6 +98,23 @@ static void remove_side_data(AVFrameSideData ***sd, int *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));
@@ -764,6 +781,38 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
return ret;
}
+int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
+ const AVFrameSideData *src, unsigned int flags)
+{
+ AVBufferRef *buf = NULL;
+ AVFrameSideData *sd_dst = NULL;
+ int ret = AVERROR_BUG;
+
+ if (!sd || !src || !nb_sd || (*nb_sd && !*sd))
+ return AVERROR(EINVAL);
+
+ buf = av_buffer_ref(src->buf);
+ if (!buf)
+ return AVERROR(ENOMEM);
+
+ if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
+ remove_side_data(sd, nb_sd, src->type);
+
+ sd_dst = add_side_data_to_set_from_buf(sd, nb_sd, src->type, buf);
+ 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;
+}
+
AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
enum AVFrameSideDataType type)
{
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 5d68d1e7af..ce93421d60 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -1021,6 +1021,26 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
enum AVFrameSideDataType type,
size_t size, unsigned int flags);
+/**
+ * Add a new side data entry to an array based on existing side data, taking
+ * a reference towards the contained AVBufferRef.
+ *
+ * @param sd pointer to array of side data to which to add another entry,
+ * or to NULL in order to start a new array.
+ * @param nb_sd pointer to an integer containing the number of entries in
+ * the array.
+ * @param src side data to be cloned, with a new reference utilized
+ * for the buffer.
+ * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0.
+ *
+ * @return negative error code on failure, >=0 on success. In case of
+ * AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of matching
+ * AVFrameSideDataType will be removed before the addition is
+ * attempted.
+ */
+int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
+ const AVFrameSideData *src, unsigned int flags);
+
/**
* @}
*/
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* Re: [FFmpeg-devel] [PATCH v8 06/14] avutil/frame: add helper for adding existing side data to array
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 06/14] avutil/frame: add helper for adding existing " Jan Ekström
@ 2024-03-12 21:06 ` James Almer
0 siblings, 0 replies; 19+ messages in thread
From: James Almer @ 2024-03-12 21:06 UTC (permalink / raw)
To: ffmpeg-devel
On 3/11/2024 5:58 PM, Jan Ekström wrote:
> ---
> libavutil/frame.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++
> libavutil/frame.h | 20 +++++++++++++++++++
> 2 files changed, 69 insertions(+)
>
> diff --git a/libavutil/frame.c b/libavutil/frame.c
> index 4074391a92..46f976a3ed 100644
> --- a/libavutil/frame.c
> +++ b/libavutil/frame.c
> @@ -98,6 +98,23 @@ static void remove_side_data(AVFrameSideData ***sd, int *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));
> @@ -764,6 +781,38 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
> return ret;
> }
>
> +int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
> + const AVFrameSideData *src, unsigned int flags)
> +{
> + AVBufferRef *buf = NULL;
> + AVFrameSideData *sd_dst = NULL;
> + int ret = AVERROR_BUG;
> +
> + if (!sd || !src || !nb_sd || (*nb_sd && !*sd))
> + return AVERROR(EINVAL);
> +
> + buf = av_buffer_ref(src->buf);
> + if (!buf)
> + return AVERROR(ENOMEM);
> +
> + if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
> + remove_side_data(sd, nb_sd, src->type);
> +
> + sd_dst = add_side_data_to_set_from_buf(sd, nb_sd, src->type, buf);
> + 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;
> +}
> +
> AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
> enum AVFrameSideDataType type)
> {
> diff --git a/libavutil/frame.h b/libavutil/frame.h
> index 5d68d1e7af..ce93421d60 100644
> --- a/libavutil/frame.h
> +++ b/libavutil/frame.h
> @@ -1021,6 +1021,26 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
> enum AVFrameSideDataType type,
> size_t size, unsigned int flags);
>
> +/**
> + * Add a new side data entry to an array based on existing side data, taking
> + * a reference towards the contained AVBufferRef.
> + *
> + * @param sd pointer to array of side data to which to add another entry,
> + * or to NULL in order to start a new array.
> + * @param nb_sd pointer to an integer containing the number of entries in
> + * the array.
> + * @param src side data to be cloned, with a new reference utilized
> + * for the buffer.
> + * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0.
> + *
> + * @return negative error code on failure, >=0 on success. In case of
> + * AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of matching
> + * AVFrameSideDataType will be removed before the addition is
> + * attempted.
> + */
> +int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
> + const AVFrameSideData *src, unsigned int flags);
> +
> /**
> * @}
> */
Patches 1 to 6 LGTM.
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 07/14] avutil/frame: add helper for adding side data w/ AVBufferRef to array
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
` (5 preceding siblings ...)
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 06/14] avutil/frame: add helper for adding existing " Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-12 21:14 ` James Almer
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 08/14] avutil/frame: add helper for getting side data from array Jan Ekström
` (6 subsequent siblings)
13 siblings, 1 reply; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
This was requested to be added in review.
---
libavutil/frame.c | 43 ++++++++++++++++++++++++++++++-------------
libavutil/frame.h | 21 +++++++++++++++++++++
2 files changed, 51 insertions(+), 13 deletions(-)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 46f976a3ed..30db83a5e5 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -781,29 +781,46 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
return ret;
}
-int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
- const AVFrameSideData *src, unsigned int flags)
+AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ const AVBufferRef *buf,
+ unsigned int flags)
{
- AVBufferRef *buf = NULL;
- AVFrameSideData *sd_dst = NULL;
- int ret = AVERROR_BUG;
+ AVBufferRef *new_buf = NULL;
+ AVFrameSideData *sd_dst = NULL;
- if (!sd || !src || !nb_sd || (*nb_sd && !*sd))
- return AVERROR(EINVAL);
+ if (!sd || !buf || !nb_sd || (*nb_sd && !*sd))
+ return NULL;
- buf = av_buffer_ref(src->buf);
+ new_buf = av_buffer_ref(buf);
if (!buf)
- return AVERROR(ENOMEM);
+ return NULL;
if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
- remove_side_data(sd, nb_sd, src->type);
+ remove_side_data(sd, nb_sd, type);
- sd_dst = add_side_data_to_set_from_buf(sd, nb_sd, src->type, buf);
+ sd_dst = add_side_data_to_set_from_buf(sd, nb_sd, type, new_buf);
if (!sd_dst) {
- av_buffer_unref(&buf);
- return AVERROR(ENOMEM);
+ av_buffer_unref(&new_buf);
+ return NULL;
}
+ return sd_dst;
+}
+
+int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
+ const AVFrameSideData *src, unsigned int flags)
+{
+ AVFrameSideData *sd_dst = NULL;
+ int ret = AVERROR_BUG;
+
+ if (!src)
+ return AVERROR(EINVAL);
+
+ sd_dst = av_frame_side_data_add(sd, nb_sd, src->type, src->buf, flags);
+ if (!sd_dst)
+ 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);
diff --git a/libavutil/frame.h b/libavutil/frame.h
index ce93421d60..a7e62ded15 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -1021,6 +1021,27 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
enum AVFrameSideDataType type,
size_t size, unsigned int flags);
+/**
+ * Add a new side data entry to an array from an existing AVBufferRef.
+ *
+ * @param sd pointer to array of side data to which to add another entry,
+ * or to NULL in order to start a new array.
+ * @param nb_sd pointer to an integer containing the number of entries in
+ * the array.
+ * @param type type of the added side data
+ * @param buf AVBufferRef for which a new reference will be made
+ * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0.
+ *
+ * @return newly added side data on success, NULL on error. In case of
+ * AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of matching
+ * AVFrameSideDataType will be removed before the addition is
+ * attempted.
+ */
+AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ const AVBufferRef *buf,
+ unsigned int flags);
+
/**
* Add a new side data entry to an array based on existing side data, taking
* a reference towards the contained AVBufferRef.
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* Re: [FFmpeg-devel] [PATCH v8 07/14] avutil/frame: add helper for adding side data w/ AVBufferRef to array
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 07/14] avutil/frame: add helper for adding side data w/ AVBufferRef " Jan Ekström
@ 2024-03-12 21:14 ` James Almer
0 siblings, 0 replies; 19+ messages in thread
From: James Almer @ 2024-03-12 21:14 UTC (permalink / raw)
To: ffmpeg-devel
On 3/11/2024 5:58 PM, Jan Ekström wrote:
> This was requested to be added in review.
> ---
> libavutil/frame.c | 43 ++++++++++++++++++++++++++++++-------------
> libavutil/frame.h | 21 +++++++++++++++++++++
> 2 files changed, 51 insertions(+), 13 deletions(-)
>
> diff --git a/libavutil/frame.c b/libavutil/frame.c
> index 46f976a3ed..30db83a5e5 100644
> --- a/libavutil/frame.c
> +++ b/libavutil/frame.c
> @@ -781,29 +781,46 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
> return ret;
> }
>
> -int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
> - const AVFrameSideData *src, unsigned int flags)
> +AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
> + enum AVFrameSideDataType type,
> + const AVBufferRef *buf,
> + unsigned int flags)
> {
> - AVBufferRef *buf = NULL;
> - AVFrameSideData *sd_dst = NULL;
> - int ret = AVERROR_BUG;
> + AVBufferRef *new_buf = NULL;
> + AVFrameSideData *sd_dst = NULL;
>
> - if (!sd || !src || !nb_sd || (*nb_sd && !*sd))
> - return AVERROR(EINVAL);
> + if (!sd || !buf || !nb_sd || (*nb_sd && !*sd))
> + return NULL;
>
> - buf = av_buffer_ref(src->buf);
> + new_buf = av_buffer_ref(buf);
> if (!buf)
> - return AVERROR(ENOMEM);
> + return NULL;
>
> if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
> - remove_side_data(sd, nb_sd, src->type);
> + remove_side_data(sd, nb_sd, type);
>
> - sd_dst = add_side_data_to_set_from_buf(sd, nb_sd, src->type, buf);
> + sd_dst = add_side_data_to_set_from_buf(sd, nb_sd, type, new_buf);
> if (!sd_dst) {
> - av_buffer_unref(&buf);
> - return AVERROR(ENOMEM);
> + av_buffer_unref(&new_buf);
> + return NULL;
> }
>
> + return sd_dst;
> +}
> +
> +int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
> + const AVFrameSideData *src, unsigned int flags)
> +{
> + AVFrameSideData *sd_dst = NULL;
> + int ret = AVERROR_BUG;
> +
> + if (!src)
> + return AVERROR(EINVAL);
> +
> + sd_dst = av_frame_side_data_add(sd, nb_sd, src->type, src->buf, flags);
> + if (!sd_dst)
> + 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);
> diff --git a/libavutil/frame.h b/libavutil/frame.h
> index ce93421d60..a7e62ded15 100644
> --- a/libavutil/frame.h
> +++ b/libavutil/frame.h
> @@ -1021,6 +1021,27 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
> enum AVFrameSideDataType type,
> size_t size, unsigned int flags);
>
> +/**
> + * Add a new side data entry to an array from an existing AVBufferRef.
> + *
> + * @param sd pointer to array of side data to which to add another entry,
> + * or to NULL in order to start a new array.
> + * @param nb_sd pointer to an integer containing the number of entries in
> + * the array.
> + * @param type type of the added side data
> + * @param buf AVBufferRef for which a new reference will be made
> + * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0.
> + *
> + * @return newly added side data on success, NULL on error. In case of
> + * AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of matching
> + * AVFrameSideDataType will be removed before the addition is
> + * attempted.
> + */
> +AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
> + enum AVFrameSideDataType type,
> + const AVBufferRef *buf,
> + unsigned int flags);
> +
> /**
> * Add a new side data entry to an array based on existing side data, taking
> * a reference towards the contained AVBufferRef.
This also LGTM, but Anton has expressed a dislike for the function
signature, preferring instead one that takes ownership of the buffer by
taking a pointer to pointer, and clearing it on success.
The argument was that the user may not care about keeping a reference to
the buffer after it's added to the side data array, but seeing how the
very first user in this patch does, I personally think this more
appropriate.
If others agree with him then I'll not oppose to it.
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 08/14] avutil/frame: add helper for getting side data from array
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
` (6 preceding siblings ...)
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 07/14] avutil/frame: add helper for adding side data w/ AVBufferRef " Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-12 21:26 ` James Almer
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 09/14] avcodec: add frame side data array to AVCodecContext Jan Ekström
` (5 subsequent siblings)
13 siblings, 1 reply; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
---
libavutil/frame.c | 20 +++++++++++++++-----
libavutil/frame.h | 14 ++++++++++++++
2 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 30db83a5e5..47ecd964b8 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -830,16 +830,26 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
return 0;
}
-AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
- enum AVFrameSideDataType type)
+const AVFrameSideData *av_frame_side_data_get(const AVFrameSideData **sd,
+ const int nb_sd,
+ enum AVFrameSideDataType type)
{
- for (int i = 0; i < frame->nb_side_data; i++) {
- if (frame->side_data[i]->type == type)
- return frame->side_data[i];
+ for (int i = 0; i < nb_sd; i++) {
+ if (sd[i]->type == type)
+ return sd[i];
}
return NULL;
}
+AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
+ enum AVFrameSideDataType type)
+{
+ return (AVFrameSideData *)av_frame_side_data_get(
+ (const AVFrameSideData **)frame->side_data, frame->nb_side_data,
+ type
+ );
+}
+
static int frame_copy_video(AVFrame *dst, const AVFrame *src)
{
int planes;
diff --git a/libavutil/frame.h b/libavutil/frame.h
index a7e62ded15..e59f033cce 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -1062,6 +1062,20 @@ AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
const AVFrameSideData *src, unsigned int flags);
+/**
+ * Get a side data entry of a specific type from an array.
+ *
+ * @param sd array of side data.
+ * @param nb_sd integer containing the number of entries in the array.
+ * @param type type of side data to be queried
+ *
+ * @return a pointer to the side data of a given type on success, NULL if there
+ * is no side data with such type in this set.
+ */
+const AVFrameSideData *av_frame_side_data_get(const AVFrameSideData **sd,
+ const int nb_sd,
+ enum AVFrameSideDataType type);
+
/**
* @}
*/
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* Re: [FFmpeg-devel] [PATCH v8 08/14] avutil/frame: add helper for getting side data from array
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 08/14] avutil/frame: add helper for getting side data from array Jan Ekström
@ 2024-03-12 21:26 ` James Almer
0 siblings, 0 replies; 19+ messages in thread
From: James Almer @ 2024-03-12 21:26 UTC (permalink / raw)
To: ffmpeg-devel
On 3/11/2024 5:58 PM, Jan Ekström wrote:
> ---
> libavutil/frame.c | 20 +++++++++++++++-----
> libavutil/frame.h | 14 ++++++++++++++
> 2 files changed, 29 insertions(+), 5 deletions(-)
>
> diff --git a/libavutil/frame.c b/libavutil/frame.c
> index 30db83a5e5..47ecd964b8 100644
> --- a/libavutil/frame.c
> +++ b/libavutil/frame.c
> @@ -830,16 +830,26 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
> return 0;
> }
>
> -AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
> - enum AVFrameSideDataType type)
> +const AVFrameSideData *av_frame_side_data_get(const AVFrameSideData **sd,
> + const int nb_sd,
> + enum AVFrameSideDataType type)
> {
> - for (int i = 0; i < frame->nb_side_data; i++) {
> - if (frame->side_data[i]->type == type)
> - return frame->side_data[i];
> + for (int i = 0; i < nb_sd; i++) {
> + if (sd[i]->type == type)
> + return sd[i];
> }
> return NULL;
> }
>
> +AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
> + enum AVFrameSideDataType type)
> +{
> + return (AVFrameSideData *)av_frame_side_data_get(
> + (const AVFrameSideData **)frame->side_data, frame->nb_side_data,
> + type
> + );
> +}
> +
> static int frame_copy_video(AVFrame *dst, const AVFrame *src)
> {
> int planes;
> diff --git a/libavutil/frame.h b/libavutil/frame.h
> index a7e62ded15..e59f033cce 100644
> --- a/libavutil/frame.h
> +++ b/libavutil/frame.h
> @@ -1062,6 +1062,20 @@ AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
> int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
> const AVFrameSideData *src, unsigned int flags);
>
> +/**
> + * Get a side data entry of a specific type from an array.
> + *
> + * @param sd array of side data.
> + * @param nb_sd integer containing the number of entries in the array.
> + * @param type type of side data to be queried
> + *
> + * @return a pointer to the side data of a given type on success, NULL if there
> + * is no side data with such type in this set.
> + */
> +const AVFrameSideData *av_frame_side_data_get(const AVFrameSideData **sd,
> + const int nb_sd,
> + enum AVFrameSideDataType type);
> +
> /**
> * @}
> */
LGTM.
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 09/14] avcodec: add frame side data array to AVCodecContext
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
` (7 preceding siblings ...)
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 08/14] avutil/frame: add helper for getting side data from array Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-12 21:26 ` James Almer
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 10/14] avcodec: add helper for configuring AVCodecContext's frame side data Jan Ekström
` (4 subsequent siblings)
13 siblings, 1 reply; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
This allows configuring an encoder by using AVFrameSideData.
---
libavcodec/avcodec.h | 8 ++++++++
libavcodec/options.c | 2 ++
2 files changed, 10 insertions(+)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 21fc74707f..432a3fd153 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2062,6 +2062,14 @@ typedef struct AVCodecContext {
* Number of entries in side_data_prefer_packet.
*/
unsigned nb_side_data_prefer_packet;
+
+ /**
+ * Set containing static side data, such as HDR10 CLL / MDCV structures.
+ * - encoding: set by user
+ * - decoding: unused
+ */
+ AVFrameSideData **frame_side_data;
+ int nb_frame_side_data;
} AVCodecContext;
/**
diff --git a/libavcodec/options.c b/libavcodec/options.c
index dcc67e497a..29b961411e 100644
--- a/libavcodec/options.c
+++ b/libavcodec/options.c
@@ -176,6 +176,8 @@ void avcodec_free_context(AVCodecContext **pavctx)
av_freep(&avctx->inter_matrix);
av_freep(&avctx->rc_override);
av_channel_layout_uninit(&avctx->ch_layout);
+ av_frame_side_data_free(
+ &avctx->frame_side_data, &avctx->nb_frame_side_data);
av_freep(pavctx);
}
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* Re: [FFmpeg-devel] [PATCH v8 09/14] avcodec: add frame side data array to AVCodecContext
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 09/14] avcodec: add frame side data array to AVCodecContext Jan Ekström
@ 2024-03-12 21:26 ` James Almer
0 siblings, 0 replies; 19+ messages in thread
From: James Almer @ 2024-03-12 21:26 UTC (permalink / raw)
To: ffmpeg-devel
On 3/11/2024 5:58 PM, Jan Ekström wrote:
> This allows configuring an encoder by using AVFrameSideData.
> ---
> libavcodec/avcodec.h | 8 ++++++++
> libavcodec/options.c | 2 ++
> 2 files changed, 10 insertions(+)
>
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index 21fc74707f..432a3fd153 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -2062,6 +2062,14 @@ typedef struct AVCodecContext {
> * Number of entries in side_data_prefer_packet.
> */
> unsigned nb_side_data_prefer_packet;
> +
> + /**
> + * Set containing static side data, such as HDR10 CLL / MDCV structures.
> + * - encoding: set by user
> + * - decoding: unused
This is not taking into account the requests from the last review round.
> + */
> + AVFrameSideData **frame_side_data;
> + int nb_frame_side_data;
> } AVCodecContext;
>
> /**
> diff --git a/libavcodec/options.c b/libavcodec/options.c
> index dcc67e497a..29b961411e 100644
> --- a/libavcodec/options.c
> +++ b/libavcodec/options.c
> @@ -176,6 +176,8 @@ void avcodec_free_context(AVCodecContext **pavctx)
> av_freep(&avctx->inter_matrix);
> av_freep(&avctx->rc_override);
> av_channel_layout_uninit(&avctx->ch_layout);
> + av_frame_side_data_free(
> + &avctx->frame_side_data, &avctx->nb_frame_side_data);
>
> av_freep(pavctx);
> }
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 10/14] avcodec: add helper for configuring AVCodecContext's frame side data
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
` (8 preceding siblings ...)
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 09/14] avcodec: add frame side data array to AVCodecContext Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 11/14] ffmpeg: pass first video AVFrame's side data to encoder Jan Ekström
` (3 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
This allows API clients that wish to configure multiple entries
at a time to do so without writing the looping code themselves.
---
libavcodec/avcodec.c | 30 ++++++++++++++++++++++++++++++
libavcodec/avcodec.h | 21 +++++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c
index a9a87bb58c..0ced87b946 100644
--- a/libavcodec/avcodec.c
+++ b/libavcodec/avcodec.c
@@ -686,3 +686,33 @@ int attribute_align_arg avcodec_receive_frame(AVCodecContext *avctx, AVFrame *fr
return ff_decode_receive_frame(avctx, frame);
return ff_encode_receive_frame(avctx, frame);
}
+
+int avcodec_configure_side_data(AVCodecContext *avctx,
+ const AVFrameSideData **sd, const int nb_sd,
+ unsigned int flags)
+{
+ if (!avctx)
+ return AVERROR(EINVAL);
+
+ if (!sd) {
+ av_frame_side_data_free(
+ &avctx->frame_side_data, &avctx->nb_frame_side_data);
+ return 0;
+ }
+
+ if (nb_sd > 0 && nb_sd == avctx->nb_frame_side_data &&
+ sd == (const AVFrameSideData **)avctx->frame_side_data)
+ return AVERROR(EINVAL);
+
+ for (int i = 0; i < nb_sd; i++) {
+ int ret = av_frame_side_data_clone(
+ &avctx->frame_side_data, &avctx->nb_frame_side_data, sd[i], flags);
+ if (ret < 0) {
+ av_frame_side_data_free(
+ &avctx->frame_side_data, &avctx->nb_frame_side_data);
+ return ret;
+ }
+ }
+
+ return 0;
+}
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 432a3fd153..6de4dc0f7b 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3075,6 +3075,27 @@ void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size);
*/
int avcodec_is_open(AVCodecContext *s);
+/**
+ * Add multiple side data entries to an AVCodecContext's array in one go, for
+ * example from an AVFrame.
+ *
+ * In case the function fails to add a side data entry, it will clear the
+ * whole side data set.
+ *
+ * @param avctx context to which the side data should be added
+ * @param sd array of side data to use as input.
+ * if null, clears out the side data for this context.
+ * @param nb_sd integer containing the number of entries in the array.
+ * @param flags Some combination of AV_FRAME_SIDE_DATA_SET_FLAG_* flags, or 0.
+ *
+ * @return negative error code on failure, >=0 on success.
+ *
+ * @see av_frame_side_data_new regarding the flags.
+ */
+int avcodec_configure_side_data(AVCodecContext *avctx,
+ const AVFrameSideData **sd, const int nb_sd,
+ unsigned int flags);
+
/**
* @}
*/
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 11/14] ffmpeg: pass first video AVFrame's side data to encoder
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
` (9 preceding siblings ...)
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 10/14] avcodec: add helper for configuring AVCodecContext's frame side data Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 12/14] avcodec/libsvtav1: add support for writing out CLL and MDCV Jan Ekström
` (2 subsequent siblings)
13 siblings, 0 replies; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
This enables further configuration of output based on the results
of input decoding and filtering in a similar manner as the color
information.
---
fftools/ffmpeg_enc.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/fftools/ffmpeg_enc.c b/fftools/ffmpeg_enc.c
index bdba50df03..5ec6ee17de 100644
--- a/fftools/ffmpeg_enc.c
+++ b/fftools/ffmpeg_enc.c
@@ -245,6 +245,16 @@ int enc_open(void *opaque, const AVFrame *frame)
enc_ctx->colorspace = frame->colorspace;
enc_ctx->chroma_sample_location = frame->chroma_location;
+ ret = avcodec_configure_side_data(
+ enc_ctx,
+ (const AVFrameSideData **)frame->side_data, frame->nb_side_data,
+ AV_FRAME_SIDE_DATA_FLAG_UNIQUE);
+ if (ret < 0) {
+ av_log(NULL, AV_LOG_ERROR, "failed to configure video encoder: %s!\n",
+ av_err2str(ret));
+ return ret;
+ }
+
if (enc_ctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) ||
(frame->flags & AV_FRAME_FLAG_INTERLACED)
#if FFMPEG_OPT_TOP
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 12/14] avcodec/libsvtav1: add support for writing out CLL and MDCV
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
` (10 preceding siblings ...)
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 11/14] ffmpeg: pass first video AVFrame's side data to encoder Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 13/14] avcodec/libx264: " Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 14/14] avcodec/libx265: " Jan Ekström
13 siblings, 0 replies; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
These two were added in 28e23d7f348c78d49a726c7469f9d4e38edec341
and 3558c1f2e97455e0b89edef31b9a72ab7fa30550 for version 0.9.0 of
SVT-AV1, which is also our minimum requirement right now.
In other words, no additional version limiting conditions seem
to be required.
Additionally, add a FATE test which verifies that pass-through of
the MDCV/CLL side data is working during encoding.
---
libavcodec/libsvtav1.c | 68 ++++++++++++++++++++++++++++++++++
tests/fate/enc_external.mak | 5 +++
tests/ref/fate/libsvtav1-hdr10 | 14 +++++++
3 files changed, 87 insertions(+)
create mode 100644 tests/ref/fate/libsvtav1-hdr10
diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c
index 7721e01677..66fa019aa0 100644
--- a/libavcodec/libsvtav1.c
+++ b/libavcodec/libsvtav1.c
@@ -27,6 +27,8 @@
#include "libavutil/common.h"
#include "libavutil/frame.h"
#include "libavutil/imgutils.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mastering_display_metadata.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/avassert.h"
@@ -136,6 +138,70 @@ static int alloc_buffer(EbSvtAv1EncConfiguration *config, SvtContext *svt_enc)
}
+static void handle_mdcv(struct EbSvtAv1MasteringDisplayInfo *dst,
+ const AVMasteringDisplayMetadata *mdcv)
+{
+ if (mdcv->has_primaries) {
+ const struct EbSvtAv1ChromaPoints *const points[] = {
+ &dst->r,
+ &dst->g,
+ &dst->b,
+ };
+
+ for (int i = 0; i < 3; i++) {
+ const struct EbSvtAv1ChromaPoints *dst = points[i];
+ const AVRational *src = mdcv->display_primaries[i];
+
+ AV_WB16(&dst->x,
+ av_rescale_q(1, src[0], (AVRational){ 1, (1 << 16) }));
+ AV_WB16(&dst->y,
+ av_rescale_q(1, src[1], (AVRational){ 1, (1 << 16) }));
+ }
+
+ AV_WB16(&dst->white_point.x,
+ av_rescale_q(1, mdcv->white_point[0],
+ (AVRational){ 1, (1 << 16) }));
+ AV_WB16(&dst->white_point.y,
+ av_rescale_q(1, mdcv->white_point[1],
+ (AVRational){ 1, (1 << 16) }));
+ }
+
+ if (mdcv->has_luminance) {
+ AV_WB32(&dst->max_luma,
+ av_rescale_q(1, mdcv->max_luminance,
+ (AVRational){ 1, (1 << 8) }));
+ AV_WB32(&dst->min_luma,
+ av_rescale_q(1, mdcv->min_luminance,
+ (AVRational){ 1, (1 << 14) }));
+ }
+}
+
+static void handle_side_data(AVCodecContext *avctx,
+ EbSvtAv1EncConfiguration *param)
+{
+ const AVFrameSideData *cll_sd =
+ av_frame_side_data_get(
+ (const AVFrameSideData **)avctx->frame_side_data,
+ avctx->nb_frame_side_data, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
+ const AVFrameSideData *mdcv_sd =
+ av_frame_side_data_get(
+ (const AVFrameSideData **)avctx->frame_side_data,
+ avctx->nb_frame_side_data, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
+
+ if (cll_sd) {
+ const AVContentLightMetadata *cll =
+ (AVContentLightMetadata *)cll_sd->data;
+
+ AV_WB16(¶m->content_light_level.max_cll, cll->MaxCLL);
+ AV_WB16(¶m->content_light_level.max_fall, cll->MaxFALL);
+ }
+
+ if (mdcv_sd) {
+ handle_mdcv(¶m->mastering_display,
+ (AVMasteringDisplayMetadata *)mdcv_sd->data);
+ }
+}
+
static int config_enc_params(EbSvtAv1EncConfiguration *param,
AVCodecContext *avctx)
{
@@ -254,6 +320,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
/* 2 = IDR, closed GOP, 1 = CRA, open GOP */
param->intra_refresh_type = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ? 2 : 1;
+ handle_side_data(avctx, param);
+
#if SVT_AV1_CHECK_VERSION(0, 9, 1)
while ((en = av_dict_get(svt_enc->svtav1_opts, "", en, AV_DICT_IGNORE_SUFFIX))) {
EbErrorType ret = svt_av1_enc_parse_parameter(param, en->key, en->value);
diff --git a/tests/fate/enc_external.mak b/tests/fate/enc_external.mak
index 7eabebcc51..d787941c16 100644
--- a/tests/fate/enc_external.mak
+++ b/tests/fate/enc_external.mak
@@ -2,5 +2,10 @@ FATE_ENC_EXTERNAL-$(call ENCDEC, LIBX264 H264, MOV, H264_DEMUXER) += fate-libx26
fate-libx264-simple: CMD = enc_external $(TARGET_SAMPLES)/h264-conformance/BA1_Sony_D.jsv \
mp4 "-c:v libx264" "-show_entries frame=width,height,pix_fmt,pts,pkt_dts -of flat"
+# test for SVT-AV1 MDCV and CLL passthrough during encoding
+FATE_ENC_EXTERNAL-$(call ENCDEC, LIBSVTAV1 HEVC, MOV, HEVC_DEMUXER LIBDAV1D_DECODER) += fate-libsvtav1-hdr10
+fate-libsvtav1-hdr10: CMD = enc_external $(TARGET_SAMPLES)/hevc/hdr10_plus_h265_sample.hevc \
+ mp4 "-c:v libsvtav1" "-show_frames -show_entries frame=side_data_list -of flat"
+
FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_ENC_EXTERNAL-yes)
fate-enc-external: $(FATE_ENC_EXTERNAL-yes)
diff --git a/tests/ref/fate/libsvtav1-hdr10 b/tests/ref/fate/libsvtav1-hdr10
new file mode 100644
index 0000000000..6f0d34903b
--- /dev/null
+++ b/tests/ref/fate/libsvtav1-hdr10
@@ -0,0 +1,14 @@
+frames.frame.0.side_data_list.side_data.0.side_data_type="Mastering display metadata"
+frames.frame.0.side_data_list.side_data.0.red_x="17367/65536"
+frames.frame.0.side_data_list.side_data.0.red_y="45220/65536"
+frames.frame.0.side_data_list.side_data.0.green_x="9830/65536"
+frames.frame.0.side_data_list.side_data.0.green_y="3932/65536"
+frames.frame.0.side_data_list.side_data.0.blue_x="44564/65536"
+frames.frame.0.side_data_list.side_data.0.blue_y="20972/65536"
+frames.frame.0.side_data_list.side_data.0.white_point_x="20493/65536"
+frames.frame.0.side_data_list.side_data.0.white_point_y="21561/65536"
+frames.frame.0.side_data_list.side_data.0.min_luminance="82/16384"
+frames.frame.0.side_data_list.side_data.0.max_luminance="256000/256"
+frames.frame.0.side_data_list.side_data.1.side_data_type="Content light level metadata"
+frames.frame.0.side_data_list.side_data.1.max_content=1000
+frames.frame.0.side_data_list.side_data.1.max_average=200
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 13/14] avcodec/libx264: add support for writing out CLL and MDCV
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
` (11 preceding siblings ...)
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 12/14] avcodec/libsvtav1: add support for writing out CLL and MDCV Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 14/14] avcodec/libx265: " Jan Ekström
13 siblings, 0 replies; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
Both of these two structures were first available with X264_BUILD
163, so make relevant functionality conditional on the version
being at least such.
Keep handle_side_data available in all cases as this way X264_init
does not require additional version based conditions within it.
Finally, add a FATE test which verifies that pass-through of the
MDCV/CLL side data is working during encoding.
---
configure | 2 +
libavcodec/libx264.c | 79 ++++++++++++++++++++++++++++++++++++
tests/fate/enc_external.mak | 5 +++
tests/ref/fate/libx264-hdr10 | 15 +++++++
4 files changed, 101 insertions(+)
create mode 100644 tests/ref/fate/libx264-hdr10
diff --git a/configure b/configure
index 05f8283af9..fe883cff5f 100755
--- a/configure
+++ b/configure
@@ -2531,6 +2531,7 @@ CONFIG_EXTRA="
jpegtables
lgplv3
libx262
+ libx264_hdr10
llauddsp
llviddsp
llvidencdsp
@@ -6927,6 +6928,7 @@ enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x
require_cpp_condition libx264 x264.h "X264_BUILD >= 122" && {
[ "$toolchain" != "msvc" ] ||
require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } &&
+ check_cpp_condition libx264_hdr10 x264.h "X264_BUILD >= 163" &&
check_cpp_condition libx262 x264.h "X264_MPEG2"
enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get &&
require_cpp_condition libx265 x265.h "X265_BUILD >= 89"
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c
index 0997c4e134..afeb285487 100644
--- a/libavcodec/libx264.c
+++ b/libavcodec/libx264.c
@@ -25,6 +25,7 @@
#include "libavutil/eval.h"
#include "libavutil/internal.h"
#include "libavutil/opt.h"
+#include "libavutil/mastering_display_metadata.h"
#include "libavutil/mem.h"
#include "libavutil/pixdesc.h"
#include "libavutil/stereo3d.h"
@@ -853,6 +854,82 @@ static int convert_pix_fmt(enum AVPixelFormat pix_fmt)
return AVERROR(EINVAL);\
}
+#if CONFIG_LIBX264_HDR10
+static void handle_mdcv(x264_param_t *params,
+ const AVMasteringDisplayMetadata *mdcv)
+{
+ if (!mdcv->has_primaries && !mdcv->has_luminance)
+ return;
+
+ params->mastering_display.b_mastering_display = 1;
+
+ if (mdcv->has_primaries) {
+ int *const points[][2] = {
+ {
+ ¶ms->mastering_display.i_red_x,
+ ¶ms->mastering_display.i_red_y
+ },
+ {
+ ¶ms->mastering_display.i_green_x,
+ ¶ms->mastering_display.i_green_y
+ },
+ {
+ ¶ms->mastering_display.i_blue_x,
+ ¶ms->mastering_display.i_blue_y
+ },
+ };
+
+ for (int i = 0; i < 3; i++) {
+ const AVRational *src = mdcv->display_primaries[i];
+ int *dst[2] = { points[i][0], points[i][1] };
+
+ *dst[0] = av_rescale_q(1, src[0], (AVRational){ 1, 50000 });
+ *dst[1] = av_rescale_q(1, src[1], (AVRational){ 1, 50000 });
+ }
+
+ params->mastering_display.i_white_x =
+ av_rescale_q(1, mdcv->white_point[0], (AVRational){ 1, 50000 });
+ params->mastering_display.i_white_y =
+ av_rescale_q(1, mdcv->white_point[1], (AVRational){ 1, 50000 });
+ }
+
+ if (mdcv->has_luminance) {
+ params->mastering_display.i_display_max =
+ av_rescale_q(1, mdcv->max_luminance, (AVRational){ 1, 10000 });
+ params->mastering_display.i_display_min =
+ av_rescale_q(1, mdcv->min_luminance, (AVRational){ 1, 10000 });
+ }
+}
+#endif // CONFIG_LIBX264_HDR10
+
+static void handle_side_data(AVCodecContext *avctx, x264_param_t *params)
+{
+#if CONFIG_LIBX264_HDR10
+ const AVFrameSideData *cll_sd =
+ av_frame_side_data_get(
+ (const AVFrameSideData **)avctx->frame_side_data,
+ avctx->nb_frame_side_data, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
+ const AVFrameSideData *mdcv_sd =
+ av_frame_side_data_get(
+ (const AVFrameSideData **)avctx->frame_side_data,
+ avctx->nb_frame_side_data, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
+
+ if (cll_sd) {
+ const AVContentLightMetadata *cll =
+ (AVContentLightMetadata *)cll_sd->data;
+
+ params->content_light_level.i_max_cll = cll->MaxCLL;
+ params->content_light_level.i_max_fall = cll->MaxFALL;
+
+ params->content_light_level.b_cll = 1;
+ }
+
+ if (mdcv_sd) {
+ handle_mdcv(params, (AVMasteringDisplayMetadata *)mdcv_sd->data);
+ }
+#endif // CONFIG_LIBX264_HDR10
+}
+
static av_cold int X264_init(AVCodecContext *avctx)
{
X264Context *x4 = avctx->priv_data;
@@ -1153,6 +1230,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED)
x4->params.vui.i_chroma_loc = avctx->chroma_sample_location - 1;
+ handle_side_data(avctx, &x4->params);
+
if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER)
x4->params.b_repeat_headers = 0;
diff --git a/tests/fate/enc_external.mak b/tests/fate/enc_external.mak
index d787941c16..4095a4b51a 100644
--- a/tests/fate/enc_external.mak
+++ b/tests/fate/enc_external.mak
@@ -7,5 +7,10 @@ FATE_ENC_EXTERNAL-$(call ENCDEC, LIBSVTAV1 HEVC, MOV, HEVC_DEMUXER LIBDAV1D_DECO
fate-libsvtav1-hdr10: CMD = enc_external $(TARGET_SAMPLES)/hevc/hdr10_plus_h265_sample.hevc \
mp4 "-c:v libsvtav1" "-show_frames -show_entries frame=side_data_list -of flat"
+# test for x264 MDCV and CLL passthrough during encoding
+FATE_ENC_EXTERNAL-$(call ENCDEC, LIBX264 HEVC, MOV, LIBX264_HDR10 HEVC_DEMUXER H264_DECODER) += fate-libx264-hdr10
+fate-libx264-hdr10: CMD = enc_external $(TARGET_SAMPLES)/hevc/hdr10_plus_h265_sample.hevc \
+ mp4 "-c:v libx264" "-show_frames -show_entries frame=side_data_list -of flat"
+
FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_ENC_EXTERNAL-yes)
fate-enc-external: $(FATE_ENC_EXTERNAL-yes)
diff --git a/tests/ref/fate/libx264-hdr10 b/tests/ref/fate/libx264-hdr10
new file mode 100644
index 0000000000..99c11677f0
--- /dev/null
+++ b/tests/ref/fate/libx264-hdr10
@@ -0,0 +1,15 @@
+frames.frame.0.side_data_list.side_data.0.side_data_type="H.26[45] User Data Unregistered SEI message"
+frames.frame.0.side_data_list.side_data.1.side_data_type="Mastering display metadata"
+frames.frame.0.side_data_list.side_data.1.red_x="13250/50000"
+frames.frame.0.side_data_list.side_data.1.red_y="34500/50000"
+frames.frame.0.side_data_list.side_data.1.green_x="7500/50000"
+frames.frame.0.side_data_list.side_data.1.green_y="3000/50000"
+frames.frame.0.side_data_list.side_data.1.blue_x="34000/50000"
+frames.frame.0.side_data_list.side_data.1.blue_y="16000/50000"
+frames.frame.0.side_data_list.side_data.1.white_point_x="15635/50000"
+frames.frame.0.side_data_list.side_data.1.white_point_y="16450/50000"
+frames.frame.0.side_data_list.side_data.1.min_luminance="50/10000"
+frames.frame.0.side_data_list.side_data.1.max_luminance="10000000/10000"
+frames.frame.0.side_data_list.side_data.2.side_data_type="Content light level metadata"
+frames.frame.0.side_data_list.side_data.2.max_content=1000
+frames.frame.0.side_data_list.side_data.2.max_average=200
--
2.44.0
_______________________________________________
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] 19+ messages in thread
* [FFmpeg-devel] [PATCH v8 14/14] avcodec/libx265: add support for writing out CLL and MDCV
2024-03-11 20:58 [FFmpeg-devel] [PATCH v8 00/14] encoder AVCodecContext configuration side data Jan Ekström
` (12 preceding siblings ...)
2024-03-11 20:58 ` [FFmpeg-devel] [PATCH v8 13/14] avcodec/libx264: " Jan Ekström
@ 2024-03-11 20:58 ` Jan Ekström
13 siblings, 0 replies; 19+ messages in thread
From: Jan Ekström @ 2024-03-11 20:58 UTC (permalink / raw)
To: ffmpeg-devel
The newer of these two are the separate integers for content light
level, introduced in 3952bf3e98c76c31594529a3fe34e056d3e3e2ea ,
with X265_BUILD 75. As we already require X265_BUILD of at least
89, no further conditions are required.
---
libavcodec/libx265.c | 88 ++++++++++++++++++++++++++++++++++++
tests/fate/enc_external.mak | 5 ++
tests/ref/fate/libx265-hdr10 | 16 +++++++
3 files changed, 109 insertions(+)
create mode 100644 tests/ref/fate/libx265-hdr10
diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c
index 92183b9ca2..b77da1c2f1 100644
--- a/libavcodec/libx265.c
+++ b/libavcodec/libx265.c
@@ -28,9 +28,11 @@
#include <float.h>
#include "libavutil/avassert.h"
+#include "libavutil/bprint.h"
#include "libavutil/buffer.h"
#include "libavutil/internal.h"
#include "libavutil/common.h"
+#include "libavutil/mastering_display_metadata.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "avcodec.h"
@@ -176,6 +178,85 @@ static av_cold int libx265_param_parse_int(AVCodecContext *avctx,
return 0;
}
+static int handle_mdcv(const AVClass **avcl, const x265_api *api,
+ x265_param *params,
+ const AVMasteringDisplayMetadata *mdcv)
+{
+ int ret = AVERROR_BUG;
+ AVBPrint buf;
+ av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC);
+
+ // G(%hu,%hu)B(%hu,%hu)R(%hu,%hu)WP(%hu,%hu)L(%u,%u)
+ av_bprintf(
+ &buf,
+ "G(%"PRId64",%"PRId64")B(%"PRId64",%"PRId64")R(%"PRId64",%"PRId64")"
+ "WP(%"PRId64",%"PRId64")L(%"PRId64",%"PRId64")",
+ av_rescale_q(1, mdcv->display_primaries[1][0], (AVRational){ 1, 50000 }),
+ av_rescale_q(1, mdcv->display_primaries[1][1], (AVRational){ 1, 50000 }),
+ av_rescale_q(1, mdcv->display_primaries[2][0], (AVRational){ 1, 50000 }),
+ av_rescale_q(1, mdcv->display_primaries[2][1], (AVRational){ 1, 50000 }),
+ av_rescale_q(1, mdcv->display_primaries[0][0], (AVRational){ 1, 50000 }),
+ av_rescale_q(1, mdcv->display_primaries[0][1], (AVRational){ 1, 50000 }),
+ av_rescale_q(1, mdcv->white_point[0], (AVRational){ 1, 50000 }),
+ av_rescale_q(1, mdcv->white_point[1], (AVRational){ 1, 50000 }),
+ av_rescale_q(1, mdcv->max_luminance, (AVRational){ 1, 10000 }),
+ av_rescale_q(1, mdcv->min_luminance, (AVRational){ 1, 10000 }));
+
+ if (!av_bprint_is_complete(&buf)) {
+ av_log(avcl, AV_LOG_ERROR,
+ "MDCV string too long for its available space!\n");
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+
+ if (api->param_parse(params, "master-display", buf.str) ==
+ X265_PARAM_BAD_VALUE) {
+ av_log(avcl, AV_LOG_ERROR,
+ "Invalid value \"%s\" for param \"master-display\".\n",
+ buf.str);
+ ret = AVERROR(EINVAL);
+ goto end;
+ }
+
+ ret = 0;
+
+end:
+ av_bprint_finalize(&buf, NULL);
+
+ return ret;
+}
+
+static int handle_side_data(AVCodecContext *avctx, const x265_api *api,
+ x265_param *params)
+{
+ const AVFrameSideData *cll_sd =
+ av_frame_side_data_get(
+ (const AVFrameSideData **)avctx->frame_side_data,
+ avctx->nb_frame_side_data, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
+ const AVFrameSideData *mdcv_sd =
+ av_frame_side_data_get(
+ (const AVFrameSideData **)avctx->frame_side_data,
+ avctx->nb_frame_side_data, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
+
+ if (cll_sd) {
+ const AVContentLightMetadata *cll =
+ (AVContentLightMetadata *)cll_sd->data;
+
+ params->maxCLL = cll->MaxCLL;
+ params->maxFALL = cll->MaxFALL;
+ }
+
+ if (mdcv_sd) {
+ int ret = handle_mdcv(
+ &avctx->av_class, api, params,
+ (AVMasteringDisplayMetadata *)mdcv_sd->data);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
static av_cold int libx265_encode_init(AVCodecContext *avctx)
{
libx265Context *ctx = avctx->priv_data;
@@ -336,6 +417,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
return AVERROR_BUG;
}
+ ret = handle_side_data(avctx, ctx->api, ctx->params);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Failed handling side data! (%s)\n",
+ av_err2str(ret));
+ return ret;
+ }
+
if (ctx->crf >= 0) {
char crf[6];
diff --git a/tests/fate/enc_external.mak b/tests/fate/enc_external.mak
index 4095a4b51a..30021efbcd 100644
--- a/tests/fate/enc_external.mak
+++ b/tests/fate/enc_external.mak
@@ -12,5 +12,10 @@ FATE_ENC_EXTERNAL-$(call ENCDEC, LIBX264 HEVC, MOV, LIBX264_HDR10 HEVC_DEMUXER H
fate-libx264-hdr10: CMD = enc_external $(TARGET_SAMPLES)/hevc/hdr10_plus_h265_sample.hevc \
mp4 "-c:v libx264" "-show_frames -show_entries frame=side_data_list -of flat"
+# test for x265 MDCV and CLL passthrough during encoding
+FATE_ENC_EXTERNAL-$(call ENCDEC, LIBX265 HEVC, MOV, HEVC_DEMUXER) += fate-libx265-hdr10
+fate-libx265-hdr10: CMD = enc_external $(TARGET_SAMPLES)/hevc/hdr10_plus_h265_sample.hevc \
+ mp4 "-c:v libx265" "-show_frames -show_entries frame=side_data_list -of flat"
+
FATE_SAMPLES_FFMPEG_FFPROBE += $(FATE_ENC_EXTERNAL-yes)
fate-enc-external: $(FATE_ENC_EXTERNAL-yes)
diff --git a/tests/ref/fate/libx265-hdr10 b/tests/ref/fate/libx265-hdr10
new file mode 100644
index 0000000000..571c837cac
--- /dev/null
+++ b/tests/ref/fate/libx265-hdr10
@@ -0,0 +1,16 @@
+frames.frame.0.side_data_list.side_data.0.side_data_type="H.26[45] User Data Unregistered SEI message"
+frames.frame.0.side_data_list.side_data.1.side_data_type="H.26[45] User Data Unregistered SEI message"
+frames.frame.0.side_data_list.side_data.2.side_data_type="Mastering display metadata"
+frames.frame.0.side_data_list.side_data.2.red_x="13250/50000"
+frames.frame.0.side_data_list.side_data.2.red_y="34500/50000"
+frames.frame.0.side_data_list.side_data.2.green_x="7500/50000"
+frames.frame.0.side_data_list.side_data.2.green_y="3000/50000"
+frames.frame.0.side_data_list.side_data.2.blue_x="34000/50000"
+frames.frame.0.side_data_list.side_data.2.blue_y="16000/50000"
+frames.frame.0.side_data_list.side_data.2.white_point_x="15635/50000"
+frames.frame.0.side_data_list.side_data.2.white_point_y="16450/50000"
+frames.frame.0.side_data_list.side_data.2.min_luminance="50/10000"
+frames.frame.0.side_data_list.side_data.2.max_luminance="10000000/10000"
+frames.frame.0.side_data_list.side_data.3.side_data_type="Content light level metadata"
+frames.frame.0.side_data_list.side_data.3.max_content=1000
+frames.frame.0.side_data_list.side_data.3.max_average=200
--
2.44.0
_______________________________________________
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] 19+ messages in thread