* [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array
@ 2024-03-28 16:52 James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 2/7 v5] avutil/frame: add a flag to allow overwritting existing entries James Almer
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: James Almer @ 2024-03-28 16:52 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/frame.c | 19 +++++++++++++++++++
libavutil/frame.h | 24 ++++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index ef1613c344..87cc8450c8 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -812,6 +812,25 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
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_UNIQUE)
+ remove_side_data(sd, nb_sd, type);
+
+ sd_dst = add_side_data_from_buf(sd, nb_sd, type, buf);
+ if (!sd_dst)
+ return NULL;
+
+ *pbuf = NULL;
+ return sd_dst;
+}
+
int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
const AVFrameSideData *src, unsigned int flags)
{
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 3b6d746a16..8d16924432 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -1062,6 +1062,30 @@ 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 Pointer to AVBufferRef to add to the array. On success,
+ * the function takes ownership of the AVBufferRef and *buf is
+ * set to NULL, unless AV_FRAME_SIDE_DATA_FLAG_NEW_REF is set
+ * in which case the ownership will remain with the caller.
+ * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0.
+ *
+ * @return newly added side data on success, NULL on error.
+ * @note 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,
+ 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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 2/7 v5] avutil/frame: add a flag to allow overwritting existing entries
2024-03-28 16:52 [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
@ 2024-03-28 16:52 ` James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 3/7 v5] avutil/frame: use the same data information as the source entry when cloning side data James Almer
` (5 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: James Almer @ 2024-03-28 16:52 UTC (permalink / raw)
To: ffmpeg-devel
Enable it only for side data types that don't allow more than one entry.
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/frame.c | 59 +++++++++++++++++++++++++++++--
libavutil/frame.h | 30 +++++++++++-----
libavutil/tests/side_data_array.c | 52 +++++++++++++++------------
tests/ref/fate/side_data_array | 22 ++++++------
4 files changed, 119 insertions(+), 44 deletions(-)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 87cc8450c8..9c3569db0e 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -795,15 +795,36 @@ 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);
+ 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)
@@ -822,6 +843,13 @@ AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
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);
+ if (sd_dst)
+ *pbuf = NULL;
+ return sd_dst;
+ }
sd_dst = add_side_data_from_buf(sd, nb_sd, type, buf);
if (!sd_dst)
@@ -834,6 +862,7 @@ 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)
{
+ const AVSideDataDescriptor *desc;
AVBufferRef *buf = NULL;
AVFrameSideData *sd_dst = NULL;
int ret = AVERROR_BUG;
@@ -841,13 +870,37 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
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);
- if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
- remove_side_data(sd, nb_sd, src->type);
-
sd_dst = add_side_data_from_buf(sd, nb_sd, src->type, buf);
if (!sd_dst) {
av_buffer_unref(&buf);
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 8d16924432..4885600dce 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -1040,7 +1040,15 @@ const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType typ
*/
void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd);
+/**
+ * Remove existing entries before adding new ones.
+ */
#define AV_FRAME_SIDE_DATA_FLAG_UNIQUE (1 << 0)
+/**
+ * Don't add a new entry if another of the same type exists.
+ * Applies only for side data types without the AV_SIDE_DATA_PROP_MULTI prop.
+ */
+#define AV_FRAME_SIDE_DATA_FLAG_REPLACE (1 << 1)
/**
* Add new side data entry to an array.
@@ -1053,10 +1061,12 @@ void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd);
* @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.
+ * @return newly added side data on success, NULL on error.
+ * @note In case of AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of
+ * matching AVFrameSideDataType will be removed before the addition
+ * is attempted.
+ * @note In case of AV_FRAME_SIDE_DATA_FLAG_REPLACE being set, if an
+ * entry of the same type already exists, it will be replaced instead.
*/
AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
enum AVFrameSideDataType type,
@@ -1080,6 +1090,8 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
* @note In case of AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of
* matching AVFrameSideDataType will be removed before the addition
* is attempted.
+ * @note In case of AV_FRAME_SIDE_DATA_FLAG_REPLACE being set, if an
+ * entry of the same type already exists, it will be replaced instead.
*
*/
AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
@@ -1098,10 +1110,12 @@ AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
* 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.
+ * @return negative error code on failure, >=0 on success.
+ * @note In case of AV_FRAME_SIDE_DATA_FLAG_UNIQUE being set, entries of
+ * matching AVFrameSideDataType will be removed before the addition
+ * is attempted.
+ * @note In case of AV_FRAME_SIDE_DATA_FLAG_REPLACE being set, if an
+ * entry of the same type already exists, it will be replaced instead.
*/
int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
const AVFrameSideData *src, unsigned int flags);
diff --git a/libavutil/tests/side_data_array.c b/libavutil/tests/side_data_array.c
index 793a62c009..633e9ee681 100644
--- a/libavutil/tests/side_data_array.c
+++ b/libavutil/tests/side_data_array.c
@@ -20,23 +20,22 @@
#include <stdio.h>
#include "libavutil/frame.c"
-#include "libavutil/mastering_display_metadata.h"
+#include "libavutil/internal.h"
-static void print_clls(const AVFrameSideData **sd, const int nb_sd)
+static void print_entries(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));
+ printf("sd %d (size %"SIZE_SPECIFIER"), %s",
+ i, entry->size, av_frame_side_data_name(entry->type));
- if (entry->type != AV_FRAME_DATA_CONTENT_LIGHT_LEVEL) {
+ if (entry->type != AV_FRAME_DATA_SEI_UNREGISTERED) {
putchar('\n');
continue;
}
- printf(": MaxCLL: %u\n",
- ((AVContentLightMetadata *)entry->data)->MaxCLL);
+ printf(": %d\n", *(int32_t *)entry->data);
}
}
@@ -51,51 +50,60 @@ int main(void)
av_assert0(
av_frame_side_data_new(&set.sd, &set.nb_sd,
- AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT,
- 0, 0));
+ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
+ sizeof(int64_t), 0));
+ av_assert0(
+ av_frame_side_data_new(&set.sd, &set.nb_sd,
+ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
+ sizeof(int32_t), AV_FRAME_SIDE_DATA_FLAG_REPLACE));
// 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);
+ &set.sd, &set.nb_sd, AV_FRAME_DATA_SEI_UNREGISTERED,
+ sizeof(int32_t), 0);
av_assert0(sd);
- ((AVContentLightMetadata *)sd->data)->MaxCLL = value;
+ *(int32_t *)sd->data = value;
}
av_assert0(
av_frame_side_data_new(
- &set.sd, &set.nb_sd, AV_FRAME_DATA_SPHERICAL, 0, 0));
+ &set.sd, &set.nb_sd, AV_FRAME_DATA_SPHERICAL,
+ sizeof(int64_t), 0));
+
+ av_assert0(
+ av_frame_side_data_new(
+ &set.sd, &set.nb_sd, AV_FRAME_DATA_SPHERICAL,
+ sizeof(int32_t), AV_FRAME_SIDE_DATA_FLAG_REPLACE));
// 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);
+ &set.sd, &set.nb_sd, AV_FRAME_DATA_SEI_UNREGISTERED,
+ sizeof(int32_t), 0);
av_assert0(sd);
- ((AVContentLightMetadata *)sd->data)->MaxCLL = value + 3;
+ *(int32_t *)sd->data = value + 3;
}
puts("Initial addition results with duplicates:");
- print_clls((const AVFrameSideData **)set.sd, set.nb_sd);
+ print_entries((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);
+ &set.sd, &set.nb_sd, AV_FRAME_DATA_SEI_UNREGISTERED,
+ sizeof(int32_t), AV_FRAME_SIDE_DATA_FLAG_UNIQUE);
av_assert0(sd);
- ((AVContentLightMetadata *)sd->data)->MaxCLL = 1337;
+ *(int32_t *)sd->data = 1337;
}
puts("\nFinal state after a single 'no-duplicates' addition:");
- print_clls((const AVFrameSideData **)set.sd, set.nb_sd);
+ print_entries((const AVFrameSideData **)set.sd, set.nb_sd);
av_frame_side_data_free(&set.sd, &set.nb_sd);
diff --git a/tests/ref/fate/side_data_array b/tests/ref/fate/side_data_array
index 7d8c684d8f..c1d77b0445 100644
--- a/tests/ref/fate/side_data_array
+++ b/tests/ref/fate/side_data_array
@@ -1,14 +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
+sd 0 (size 4), Content light level metadata
+sd 1 (size 4), H.26[45] User Data Unregistered SEI message: 1
+sd 2 (size 4), H.26[45] User Data Unregistered SEI message: 2
+sd 3 (size 4), H.26[45] User Data Unregistered SEI message: 3
+sd 4 (size 4), Spherical Mapping
+sd 5 (size 4), H.26[45] User Data Unregistered SEI message: 4
+sd 6 (size 4), H.26[45] User Data Unregistered SEI message: 5
+sd 7 (size 4), H.26[45] User Data Unregistered SEI message: 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
+sd 0 (size 4), Content light level metadata
+sd 1 (size 4), Spherical Mapping
+sd 2 (size 4), H.26[45] User Data Unregistered SEI message: 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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 3/7 v5] avutil/frame: use the same data information as the source entry when cloning side data
2024-03-28 16:52 [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 2/7 v5] avutil/frame: add a flag to allow overwritting existing entries James Almer
@ 2024-03-28 16:52 ` James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 4/7 v5] avutil/frame: add helper to remove side data of a given type from an array James Almer
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: James Almer @ 2024-03-28 16:52 UTC (permalink / raw)
To: ffmpeg-devel
src->{data,size} does not need to match src->buf->{data,size}.
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/frame.c | 30 ++++++++++++++++++++----------
1 file changed, 20 insertions(+), 10 deletions(-)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index 9c3569db0e..d37f1511e8 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -741,16 +741,14 @@ AVBufferRef *av_frame_get_plane_buffer(const AVFrame *frame, int plane)
return NULL;
}
-static AVFrameSideData *add_side_data_from_buf(AVFrameSideData ***sd,
- int *nb_sd,
- enum AVFrameSideDataType type,
- AVBufferRef *buf)
+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;
- if (!buf)
- return NULL;
-
// *nb_sd + 1 needs to fit into an int and a size_t.
if ((unsigned)*nb_sd >= FFMIN(INT_MAX, SIZE_MAX))
return NULL;
@@ -765,8 +763,8 @@ static AVFrameSideData *add_side_data_from_buf(AVFrameSideData ***sd,
return NULL;
ret->buf = buf;
- ret->data = ret->buf->data;
- ret->size = buf->size;
+ ret->data = data;
+ ret->size = size;
ret->type = type;
(*sd)[(*nb_sd)++] = ret;
@@ -774,6 +772,17 @@ static AVFrameSideData *add_side_data_from_buf(AVFrameSideData ***sd,
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)
@@ -901,7 +910,8 @@ int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
if (!buf)
return AVERROR(ENOMEM);
- sd_dst = add_side_data_from_buf(sd, nb_sd, src->type, buf);
+ 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);
--
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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 4/7 v5] avutil/frame: add helper to remove side data of a given type from an array
2024-03-28 16:52 [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 2/7 v5] avutil/frame: add a flag to allow overwritting existing entries James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 3/7 v5] avutil/frame: use the same data information as the source entry when cloning side data James Almer
@ 2024-03-28 16:52 ` James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 5/7 v5] avutil/mastering_display_metadata: add a new allocator function that returns a size James Almer
` (3 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: James Almer @ 2024-03-28 16:52 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/frame.c | 6 ++++++
libavutil/frame.h | 5 +++++
2 files changed, 11 insertions(+)
diff --git a/libavutil/frame.c b/libavutil/frame.c
index d37f1511e8..10b9f7fa94 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -937,6 +937,12 @@ const AVFrameSideData *av_frame_side_data_get_c(const AVFrameSideData * const *s
return NULL;
}
+void av_frame_side_data_remove(AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type)
+{
+ remove_side_data(sd, nb_sd, type);
+}
+
AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
enum AVFrameSideDataType type)
{
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 4885600dce..68a2ad1555 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -1149,6 +1149,11 @@ const AVFrameSideData *av_frame_side_data_get(AVFrameSideData * const *sd,
nb_sd, type);
}
+/**
+ * Remove and free all side data instances of the given type from an array.
+ */
+void av_frame_side_data_remove(AVFrameSideData ***sd, 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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 5/7 v5] avutil/mastering_display_metadata: add a new allocator function that returns a size
2024-03-28 16:52 [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
` (2 preceding siblings ...)
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 4/7 v5] avutil/frame: add helper to remove side data of a given type from an array James Almer
@ 2024-03-28 16:52 ` James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 6/7 v5] avcodec/decode: add AVFrameSideData helper wrappers that don't depend on frames James Almer
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: James Almer @ 2024-03-28 16:52 UTC (permalink / raw)
To: ffmpeg-devel
av_mastering_display_metadata_alloc() is not useful in scenarios where you need to
know the runtime size of AVMasteringDisplayMetadata.
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavutil/mastering_display_metadata.c | 13 +++++++++++++
libavutil/mastering_display_metadata.h | 9 +++++++++
2 files changed, 22 insertions(+)
diff --git a/libavutil/mastering_display_metadata.c b/libavutil/mastering_display_metadata.c
index 6069347617..ea41f13f9d 100644
--- a/libavutil/mastering_display_metadata.c
+++ b/libavutil/mastering_display_metadata.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <stddef.h>
#include <stdint.h>
#include <string.h>
@@ -29,6 +30,18 @@ AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc(void)
return av_mallocz(sizeof(AVMasteringDisplayMetadata));
}
+AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc_size(size_t *size)
+{
+ AVMasteringDisplayMetadata *mastering = av_mallocz(sizeof(AVMasteringDisplayMetadata));
+ if (!mastering)
+ return NULL;
+
+ if (size)
+ *size = sizeof(*mastering);
+
+ return mastering;
+}
+
AVMasteringDisplayMetadata *av_mastering_display_metadata_create_side_data(AVFrame *frame)
{
AVFrameSideData *side_data = av_frame_new_side_data(frame,
diff --git a/libavutil/mastering_display_metadata.h b/libavutil/mastering_display_metadata.h
index c23b07c3cd..52fcef9e37 100644
--- a/libavutil/mastering_display_metadata.h
+++ b/libavutil/mastering_display_metadata.h
@@ -77,6 +77,15 @@ typedef struct AVMasteringDisplayMetadata {
*/
AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc(void);
+/**
+ * Allocate an AVMasteringDisplayMetadata structure and set its fields to
+ * default values. The resulting struct can be freed using av_freep().
+ *
+ * @return An AVMasteringDisplayMetadata filled with default values or NULL
+ * on failure.
+ */
+AVMasteringDisplayMetadata *av_mastering_display_metadata_alloc_size(size_t *size);
+
/**
* Allocate a complete AVMasteringDisplayMetadata and add it to the frame.
*
--
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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 6/7 v5] avcodec/decode: add AVFrameSideData helper wrappers that don't depend on frames
2024-03-28 16:52 [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
` (3 preceding siblings ...)
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 5/7 v5] avutil/mastering_display_metadata: add a new allocator function that returns a size James Almer
@ 2024-03-28 16:52 ` James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 7/7 v5] avcodec/hevcdec: export global side data in AVCodecContext James Almer
2024-03-30 17:39 ` [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
6 siblings, 0 replies; 12+ messages in thread
From: James Almer @ 2024-03-28 16:52 UTC (permalink / raw)
To: ffmpeg-devel
They will be useful to fill arrays stored in other structs.
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavcodec/decode.c | 106 ++++++++++++++++++++++++++++++++++++--------
libavcodec/decode.h | 24 ++++++++++
2 files changed, 112 insertions(+), 18 deletions(-)
diff --git a/libavcodec/decode.c b/libavcodec/decode.c
index 34bcb7cc64..1f6c2a8dde 100644
--- a/libavcodec/decode.c
+++ b/libavcodec/decode.c
@@ -1799,16 +1799,16 @@ int ff_decode_preinit(AVCodecContext *avctx)
* @retval 0 side data of this type can be added to frame
* @retval 1 side data of this type should not be added to frame
*/
-static int side_data_pref(const AVCodecContext *avctx, AVFrame *frame,
- enum AVFrameSideDataType type)
+static int side_data_pref(const AVCodecContext *avctx, AVFrameSideData ***sd,
+ int *nb_sd, enum AVFrameSideDataType type)
{
DecodeContext *dc = decode_ctx(avctx->internal);
// Note: could be skipped for `type` without corresponding packet sd
- if (av_frame_get_side_data(frame, type)) {
+ if (av_frame_side_data_get(*sd, *nb_sd, type)) {
if (dc->side_data_pref_mask & (1ULL << type))
return 1;
- av_frame_remove_side_data(frame, type);
+ av_frame_side_data_remove(sd, nb_sd, type);
}
return 0;
@@ -1821,7 +1821,7 @@ int ff_frame_new_side_data(const AVCodecContext *avctx, AVFrame *frame,
{
AVFrameSideData *sd;
- if (side_data_pref(avctx, frame, type)) {
+ if (side_data_pref(avctx, &frame->side_data, &frame->nb_side_data, type)) {
if (psd)
*psd = NULL;
return 0;
@@ -1834,34 +1834,71 @@ int ff_frame_new_side_data(const AVCodecContext *avctx, AVFrame *frame,
return sd ? 0 : AVERROR(ENOMEM);
}
-int ff_frame_new_side_data_from_buf(const AVCodecContext *avctx,
- AVFrame *frame, enum AVFrameSideDataType type,
- AVBufferRef **buf, AVFrameSideData **psd)
+int ff_frame_new_side_data_from_buf_ext(const AVCodecContext *avctx,
+ AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ AVBufferRef **buf)
{
- AVFrameSideData *sd = NULL;
int ret = 0;
- if (side_data_pref(avctx, frame, type))
+ if (side_data_pref(avctx, sd, nb_sd, type))
goto finish;
- sd = av_frame_new_side_data_from_buf(frame, type, *buf);
- if (sd)
- *buf = NULL;
- else
+ if (!av_frame_side_data_add(sd, nb_sd, type, buf, 0))
ret = AVERROR(ENOMEM);
finish:
av_buffer_unref(buf);
- if (psd)
- *psd = sd;
return ret;
}
+int ff_frame_new_side_data_from_buf(const AVCodecContext *avctx,
+ AVFrame *frame, enum AVFrameSideDataType type,
+ AVBufferRef **buf, AVFrameSideData **psd)
+{
+ return ff_frame_new_side_data_from_buf_ext(avctx,
+ &frame->side_data, &frame->nb_side_data,
+ type, buf);
+}
+
+int ff_decode_mastering_display_new_ext(const AVCodecContext *avctx,
+ AVFrameSideData ***sd, int *nb_sd,
+ struct AVMasteringDisplayMetadata **mdm)
+{
+ AVBufferRef *buf;
+ size_t size;
+
+ if (side_data_pref(avctx, sd, nb_sd, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA)) {
+ *mdm = NULL;
+ return 0;
+ }
+
+ *mdm = av_mastering_display_metadata_alloc_size(&size);
+ if (!*mdm)
+ return AVERROR(ENOMEM);
+
+ buf = av_buffer_create((uint8_t *)*mdm, size, NULL, NULL, 0);
+ if (!buf) {
+ av_freep(mdm);
+ return AVERROR(ENOMEM);
+ }
+
+ if (!av_frame_side_data_add(sd, nb_sd, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA,
+ &buf, 0)) {
+ *mdm = NULL;
+ av_buffer_unref(&buf);
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+
int ff_decode_mastering_display_new(const AVCodecContext *avctx, AVFrame *frame,
AVMasteringDisplayMetadata **mdm)
{
- if (side_data_pref(avctx, frame, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA)) {
+ if (side_data_pref(avctx, &frame->side_data, &frame->nb_side_data,
+ AV_FRAME_DATA_MASTERING_DISPLAY_METADATA)) {
*mdm = NULL;
return 0;
}
@@ -1870,10 +1907,43 @@ int ff_decode_mastering_display_new(const AVCodecContext *avctx, AVFrame *frame,
return *mdm ? 0 : AVERROR(ENOMEM);
}
+int ff_decode_content_light_new_ext(const AVCodecContext *avctx,
+ AVFrameSideData ***sd, int *nb_sd,
+ AVContentLightMetadata **clm)
+{
+ AVBufferRef *buf;
+ size_t size;
+
+ if (side_data_pref(avctx, sd, nb_sd, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL)) {
+ *clm = NULL;
+ return 0;
+ }
+
+ *clm = av_content_light_metadata_alloc(&size);
+ if (!*clm)
+ return AVERROR(ENOMEM);
+
+ buf = av_buffer_create((uint8_t *)*clm, size, NULL, NULL, 0);
+ if (!buf) {
+ av_freep(clm);
+ return AVERROR(ENOMEM);
+ }
+
+ if (!av_frame_side_data_add(sd, nb_sd, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL,
+ &buf, 0)) {
+ *clm = NULL;
+ av_buffer_unref(&buf);
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+
int ff_decode_content_light_new(const AVCodecContext *avctx, AVFrame *frame,
AVContentLightMetadata **clm)
{
- if (side_data_pref(avctx, frame, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL)) {
+ if (side_data_pref(avctx, &frame->side_data, &frame->nb_side_data,
+ AV_FRAME_DATA_CONTENT_LIGHT_LEVEL)) {
*clm = NULL;
return 0;
}
diff --git a/libavcodec/decode.h b/libavcodec/decode.h
index 4ffbd9db8e..72a775ff9d 100644
--- a/libavcodec/decode.h
+++ b/libavcodec/decode.h
@@ -175,6 +175,15 @@ int ff_frame_new_side_data_from_buf(const AVCodecContext *avctx,
AVFrame *frame, enum AVFrameSideDataType type,
AVBufferRef **buf, AVFrameSideData **sd);
+/**
+ * Same as `ff_frame_new_side_data_from_buf`, but taking a AVFrameSideData
+ * array directly instead of an AVFrame.
+ */
+int ff_frame_new_side_data_from_buf_ext(const AVCodecContext *avctx,
+ AVFrameSideData ***sd, int *nb_sd,
+ enum AVFrameSideDataType type,
+ AVBufferRef **buf);
+
struct AVMasteringDisplayMetadata;
struct AVContentLightMetadata;
@@ -187,6 +196,14 @@ struct AVContentLightMetadata;
int ff_decode_mastering_display_new(const AVCodecContext *avctx, AVFrame *frame,
struct AVMasteringDisplayMetadata **mdm);
+/**
+ * Same as `ff_decode_mastering_display_new`, but taking a AVFrameSideData
+ * array directly instead of an AVFrame.
+ */
+int ff_decode_mastering_display_new_ext(const AVCodecContext *avctx,
+ AVFrameSideData ***sd, int *nb_sd,
+ struct AVMasteringDisplayMetadata **mdm);
+
/**
* Wrapper around av_content_light_metadata_create_side_data(), which
* rejects side data overridden by the demuxer. Returns 0 on success, and a
@@ -196,4 +213,11 @@ int ff_decode_mastering_display_new(const AVCodecContext *avctx, AVFrame *frame,
int ff_decode_content_light_new(const AVCodecContext *avctx, AVFrame *frame,
struct AVContentLightMetadata **clm);
+/**
+ * Same as `ff_decode_content_light_new`, but taking a AVFrameSideData
+ * array directly instead of an AVFrame.
+ */
+int ff_decode_content_light_new_ext(const AVCodecContext *avctx,
+ AVFrameSideData ***sd, int *nb_sd,
+ struct AVContentLightMetadata **clm);
#endif /* AVCODEC_DECODE_H */
--
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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 7/7 v5] avcodec/hevcdec: export global side data in AVCodecContext
2024-03-28 16:52 [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
` (4 preceding siblings ...)
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 6/7 v5] avcodec/decode: add AVFrameSideData helper wrappers that don't depend on frames James Almer
@ 2024-03-28 16:52 ` James Almer
2024-04-03 8:32 ` Anton Khirnov
2024-03-30 17:39 ` [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
6 siblings, 1 reply; 12+ messages in thread
From: James Almer @ 2024-03-28 16:52 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavcodec/avcodec.h | 2 +-
libavcodec/h2645_sei.c | 215 +++++++++++++++++++++----------------
libavcodec/h2645_sei.h | 2 +
libavcodec/hevcdec.c | 4 +
libavcodec/pthread_frame.c | 11 ++
5 files changed, 141 insertions(+), 93 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 83dc487251..968009a192 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2071,7 +2071,7 @@ typedef struct AVCodecContext {
* - encoding: may be set by user before calling avcodec_open2() for
* encoder configuration. Afterwards owned and freed by the
* encoder.
- * - decoding: unused
+ * - decoding: may be set by libavcodec in avcodec_open2().
*/
AVFrameSideData **decoded_side_data;
int nb_decoded_side_data;
diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c
index afc103b69c..14a01c64d2 100644
--- a/libavcodec/h2645_sei.c
+++ b/libavcodec/h2645_sei.c
@@ -529,6 +529,120 @@ static int is_frame_packing_type_valid(SEIFpaType type, enum AVCodecID codec_id)
type >= SEI_FPA_TYPE_SIDE_BY_SIDE;
}
+static int h2645_sei_to_side_data(AVCodecContext *avctx, H2645SEI *sei,
+ AVFrameSideData ***sd, int *nb_sd)
+{
+ int ret;
+
+ for (unsigned i = 0; i < sei->unregistered.nb_buf_ref; i++) {
+ H2645SEIUnregistered *unreg = &sei->unregistered;
+
+ if (unreg->buf_ref[i]) {
+ AVFrameSideData *entry = av_frame_side_data_add(sd, nb_sd,
+ AV_FRAME_DATA_SEI_UNREGISTERED,
+ &unreg->buf_ref[i], 0);
+ if (!entry)
+ av_buffer_unref(&unreg->buf_ref[i]);
+ }
+ }
+ sei->unregistered.nb_buf_ref = 0;
+
+ if (sei->ambient_viewing_environment.present) {
+ H2645SEIAmbientViewingEnvironment *env =
+ &sei->ambient_viewing_environment;
+ AVBufferRef *buf;
+ size_t size;
+
+ AVAmbientViewingEnvironment *dst_env =
+ av_ambient_viewing_environment_alloc(&size);
+ if (!dst_env)
+ return AVERROR(ENOMEM);
+
+ buf = av_buffer_create((uint8_t *)dst_env, size, NULL, NULL, 0);
+ if (!buf) {
+ av_free(dst_env);
+ return AVERROR(ENOMEM);
+ }
+
+ ret = ff_frame_new_side_data_from_buf_ext(avctx, sd, nb_sd,
+ AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT, &buf);
+
+ if (ret < 0)
+ return ret;
+
+ dst_env->ambient_illuminance = av_make_q(env->ambient_illuminance, 10000);
+ dst_env->ambient_light_x = av_make_q(env->ambient_light_x, 50000);
+ dst_env->ambient_light_y = av_make_q(env->ambient_light_y, 50000);
+ }
+
+ if (sei->mastering_display.present) {
+ // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b
+ const int mapping[3] = {2, 0, 1};
+ const int chroma_den = 50000;
+ const int luma_den = 10000;
+ int i;
+ AVMasteringDisplayMetadata *metadata;
+
+ ret = ff_decode_mastering_display_new_ext(avctx, sd, nb_sd, &metadata);
+ if (ret < 0)
+ return ret;
+
+ if (metadata) {
+ for (i = 0; i < 3; i++) {
+ const int j = mapping[i];
+ metadata->display_primaries[i][0].num = sei->mastering_display.display_primaries[j][0];
+ metadata->display_primaries[i][0].den = chroma_den;
+ metadata->display_primaries[i][1].num = sei->mastering_display.display_primaries[j][1];
+ metadata->display_primaries[i][1].den = chroma_den;
+ }
+ metadata->white_point[0].num = sei->mastering_display.white_point[0];
+ metadata->white_point[0].den = chroma_den;
+ metadata->white_point[1].num = sei->mastering_display.white_point[1];
+ metadata->white_point[1].den = chroma_den;
+
+ metadata->max_luminance.num = sei->mastering_display.max_luminance;
+ metadata->max_luminance.den = luma_den;
+ metadata->min_luminance.num = sei->mastering_display.min_luminance;
+ metadata->min_luminance.den = luma_den;
+ metadata->has_luminance = 1;
+ metadata->has_primaries = 1;
+
+ av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n");
+ av_log(avctx, AV_LOG_DEBUG,
+ "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f)\n",
+ av_q2d(metadata->display_primaries[0][0]),
+ av_q2d(metadata->display_primaries[0][1]),
+ av_q2d(metadata->display_primaries[1][0]),
+ av_q2d(metadata->display_primaries[1][1]),
+ av_q2d(metadata->display_primaries[2][0]),
+ av_q2d(metadata->display_primaries[2][1]),
+ av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1]));
+ av_log(avctx, AV_LOG_DEBUG,
+ "min_luminance=%f, max_luminance=%f\n",
+ av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance));
+ }
+ }
+
+ if (sei->content_light.present) {
+ AVContentLightMetadata *metadata;
+
+ ret = ff_decode_content_light_new_ext(avctx, sd, nb_sd, &metadata);
+ if (ret < 0)
+ return ret;
+
+ if (metadata) {
+ metadata->MaxCLL = sei->content_light.max_content_light_level;
+ metadata->MaxFALL = sei->content_light.max_pic_average_light_level;
+
+ av_log(avctx, AV_LOG_DEBUG, "Content Light Level Metadata:\n");
+ av_log(avctx, AV_LOG_DEBUG, "MaxCLL=%d, MaxFALL=%d\n",
+ metadata->MaxCLL, metadata->MaxFALL);
+ }
+ }
+
+ return 0;
+}
+
int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
enum AVCodecID codec_id,
AVCodecContext *avctx, const H2645VUI *vui,
@@ -625,19 +739,9 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
}
- for (unsigned i = 0; i < sei->unregistered.nb_buf_ref; i++) {
- H2645SEIUnregistered *unreg = &sei->unregistered;
-
- if (unreg->buf_ref[i]) {
- AVFrameSideData *sd = av_frame_new_side_data_from_buf(frame,
- AV_FRAME_DATA_SEI_UNREGISTERED,
- unreg->buf_ref[i]);
- if (!sd)
- av_buffer_unref(&unreg->buf_ref[i]);
- unreg->buf_ref[i] = NULL;
- }
- }
- sei->unregistered.nb_buf_ref = 0;
+ ret = h2645_sei_to_side_data(avctx, sei, &frame->side_data, &frame->nb_side_data);
+ if (ret < 0)
+ return ret;
if (sei->afd.present) {
AVFrameSideData *sd = av_frame_new_side_data(frame, AV_FRAME_DATA_AFD,
@@ -728,88 +832,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
return ret;
#endif
- if (sei->ambient_viewing_environment.present) {
- H2645SEIAmbientViewingEnvironment *env =
- &sei->ambient_viewing_environment;
-
- AVAmbientViewingEnvironment *dst_env =
- av_ambient_viewing_environment_create_side_data(frame);
- if (!dst_env)
- return AVERROR(ENOMEM);
-
- dst_env->ambient_illuminance = av_make_q(env->ambient_illuminance, 10000);
- dst_env->ambient_light_x = av_make_q(env->ambient_light_x, 50000);
- dst_env->ambient_light_y = av_make_q(env->ambient_light_y, 50000);
- }
-
- if (sei->mastering_display.present) {
- // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b
- const int mapping[3] = {2, 0, 1};
- const int chroma_den = 50000;
- const int luma_den = 10000;
- int i;
- AVMasteringDisplayMetadata *metadata;
-
- ret = ff_decode_mastering_display_new(avctx, frame, &metadata);
- if (ret < 0)
- return ret;
-
- if (metadata) {
- for (i = 0; i < 3; i++) {
- const int j = mapping[i];
- metadata->display_primaries[i][0].num = sei->mastering_display.display_primaries[j][0];
- metadata->display_primaries[i][0].den = chroma_den;
- metadata->display_primaries[i][1].num = sei->mastering_display.display_primaries[j][1];
- metadata->display_primaries[i][1].den = chroma_den;
- }
- metadata->white_point[0].num = sei->mastering_display.white_point[0];
- metadata->white_point[0].den = chroma_den;
- metadata->white_point[1].num = sei->mastering_display.white_point[1];
- metadata->white_point[1].den = chroma_den;
-
- metadata->max_luminance.num = sei->mastering_display.max_luminance;
- metadata->max_luminance.den = luma_den;
- metadata->min_luminance.num = sei->mastering_display.min_luminance;
- metadata->min_luminance.den = luma_den;
- metadata->has_luminance = 1;
- metadata->has_primaries = 1;
-
- av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n");
- av_log(avctx, AV_LOG_DEBUG,
- "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f)\n",
- av_q2d(metadata->display_primaries[0][0]),
- av_q2d(metadata->display_primaries[0][1]),
- av_q2d(metadata->display_primaries[1][0]),
- av_q2d(metadata->display_primaries[1][1]),
- av_q2d(metadata->display_primaries[2][0]),
- av_q2d(metadata->display_primaries[2][1]),
- av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1]));
- av_log(avctx, AV_LOG_DEBUG,
- "min_luminance=%f, max_luminance=%f\n",
- av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance));
- }
- }
-
- if (sei->content_light.present) {
- AVContentLightMetadata *metadata;
-
- ret = ff_decode_content_light_new(avctx, frame, &metadata);
- if (ret < 0)
- return ret;
-
- if (metadata) {
- metadata->MaxCLL = sei->content_light.max_content_light_level;
- metadata->MaxFALL = sei->content_light.max_pic_average_light_level;
-
- av_log(avctx, AV_LOG_DEBUG, "Content Light Level Metadata:\n");
- av_log(avctx, AV_LOG_DEBUG, "MaxCLL=%d, MaxFALL=%d\n",
- metadata->MaxCLL, metadata->MaxFALL);
- }
- }
-
return 0;
}
+int ff_h2645_sei_to_context(AVCodecContext *avctx, H2645SEI *sei)
+{
+ return h2645_sei_to_side_data(avctx, sei, &avctx->decoded_side_data,
+ &avctx->nb_decoded_side_data);
+}
+
void ff_h2645_sei_reset(H2645SEI *s)
{
av_buffer_unref(&s->a53_caption.buf_ref);
diff --git a/libavcodec/h2645_sei.h b/libavcodec/h2645_sei.h
index b9a6c7587b..488dbcad7e 100644
--- a/libavcodec/h2645_sei.h
+++ b/libavcodec/h2645_sei.h
@@ -168,4 +168,6 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
unsigned bit_depth_luma, unsigned bit_depth_chroma,
int seed);
+int ff_h2645_sei_to_context(AVCodecContext *avctx, H2645SEI *sei);
+
#endif /* AVCODEC_H2645_SEI_H */
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 575836e340..3d98d51249 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -3656,6 +3656,10 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx)
if (ret < 0) {
return ret;
}
+
+ ret = ff_h2645_sei_to_context(avctx, &s->sei.common);
+ if (ret < 0)
+ return ret;
}
sd = ff_get_coded_side_data(avctx, AV_PKT_DATA_DOVI_CONF);
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index fd356bd190..a693e12670 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -334,6 +334,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
if (for_user) {
if (codec->update_thread_context_for_user)
err = codec->update_thread_context_for_user(dst, src);
+
+ av_frame_side_data_free(&dst->decoded_side_data, &dst->nb_decoded_side_data);
+ for (int i = 0; i < src->nb_decoded_side_data; i++) {
+ int ret = av_frame_side_data_clone(&dst->decoded_side_data,
+ &dst->nb_decoded_side_data,
+ src->decoded_side_data[i], 0);
+ if (ret < 0)
+ return ret;
+ }
} else {
const PerThreadContext *p_src = src->internal->thread_ctx;
PerThreadContext *p_dst = dst->internal->thread_ctx;
@@ -767,6 +776,8 @@ static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
if (!copy)
return AVERROR(ENOMEM);
copy->priv_data = NULL;
+ copy->decoded_side_data = NULL;
+ copy->nb_decoded_side_data = 0;
/* From now on, this PerThreadContext will be cleaned up by
* ff_frame_thread_free in case of errors. */
--
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] 12+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array
2024-03-28 16:52 [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
` (5 preceding siblings ...)
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 7/7 v5] avcodec/hevcdec: export global side data in AVCodecContext James Almer
@ 2024-03-30 17:39 ` James Almer
2024-04-11 2:35 ` James Almer
6 siblings, 1 reply; 12+ messages in thread
From: James Almer @ 2024-03-30 17:39 UTC (permalink / raw)
To: ffmpeg-devel
On 3/28/2024 1:52 PM, James Almer wrote:
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
> libavutil/frame.c | 19 +++++++++++++++++++
> libavutil/frame.h | 24 ++++++++++++++++++++++++
> 2 files changed, 43 insertions(+)
>
> diff --git a/libavutil/frame.c b/libavutil/frame.c
> index ef1613c344..87cc8450c8 100644
> --- a/libavutil/frame.c
> +++ b/libavutil/frame.c
> @@ -812,6 +812,25 @@ AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
> 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_UNIQUE)
> + remove_side_data(sd, nb_sd, type);
> +
> + sd_dst = add_side_data_from_buf(sd, nb_sd, type, buf);
> + if (!sd_dst)
> + return NULL;
> +
> + *pbuf = NULL;
> + return sd_dst;
> +}
> +
> int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
> const AVFrameSideData *src, unsigned int flags)
> {
> diff --git a/libavutil/frame.h b/libavutil/frame.h
> index 3b6d746a16..8d16924432 100644
> --- a/libavutil/frame.h
> +++ b/libavutil/frame.h
> @@ -1062,6 +1062,30 @@ 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 Pointer to AVBufferRef to add to the array. On success,
> + * the function takes ownership of the AVBufferRef and *buf is
> + * set to NULL, unless AV_FRAME_SIDE_DATA_FLAG_NEW_REF is set
> + * in which case the ownership will remain with the caller.
> + * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags, or 0.
> + *
> + * @return newly added side data on success, NULL on error.
> + * @note 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,
> + 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.
Ping for the set.
_______________________________________________
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] 12+ messages in thread
* Re: [FFmpeg-devel] [PATCH 7/7 v5] avcodec/hevcdec: export global side data in AVCodecContext
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 7/7 v5] avcodec/hevcdec: export global side data in AVCodecContext James Almer
@ 2024-04-03 8:32 ` Anton Khirnov
2024-04-03 11:31 ` James Almer
2024-04-03 11:55 ` [FFmpeg-devel] [PATCH 7/7 v6] " James Almer
0 siblings, 2 replies; 12+ messages in thread
From: Anton Khirnov @ 2024-04-03 8:32 UTC (permalink / raw)
To: FFmpeg development discussions and patches
Quoting James Almer (2024-03-28 17:52:50)
> diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
> index fd356bd190..a693e12670 100644
> --- a/libavcodec/pthread_frame.c
> +++ b/libavcodec/pthread_frame.c
> @@ -334,6 +334,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
> if (for_user) {
> if (codec->update_thread_context_for_user)
> err = codec->update_thread_context_for_user(dst, src);
> +
> + av_frame_side_data_free(&dst->decoded_side_data, &dst->nb_decoded_side_data);
> + for (int i = 0; i < src->nb_decoded_side_data; i++) {
> + int ret = av_frame_side_data_clone(&dst->decoded_side_data,
> + &dst->nb_decoded_side_data,
> + src->decoded_side_data[i], 0);
> + if (ret < 0)
> + return ret;
> + }
Seems wasteful to do this for every frame, when it only needs to be done
once. Is there a reason not to put this code in init_thread()?
--
Anton Khirnov
_______________________________________________
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] 12+ messages in thread
* Re: [FFmpeg-devel] [PATCH 7/7 v5] avcodec/hevcdec: export global side data in AVCodecContext
2024-04-03 8:32 ` Anton Khirnov
@ 2024-04-03 11:31 ` James Almer
2024-04-03 11:55 ` [FFmpeg-devel] [PATCH 7/7 v6] " James Almer
1 sibling, 0 replies; 12+ messages in thread
From: James Almer @ 2024-04-03 11:31 UTC (permalink / raw)
To: ffmpeg-devel
On 4/3/2024 5:32 AM, Anton Khirnov wrote:
> Quoting James Almer (2024-03-28 17:52:50)
>> diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
>> index fd356bd190..a693e12670 100644
>> --- a/libavcodec/pthread_frame.c
>> +++ b/libavcodec/pthread_frame.c
>> @@ -334,6 +334,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
>> if (for_user) {
>> if (codec->update_thread_context_for_user)
>> err = codec->update_thread_context_for_user(dst, src);
>> +
>> + av_frame_side_data_free(&dst->decoded_side_data, &dst->nb_decoded_side_data);
>> + for (int i = 0; i < src->nb_decoded_side_data; i++) {
>> + int ret = av_frame_side_data_clone(&dst->decoded_side_data,
>> + &dst->nb_decoded_side_data,
>> + src->decoded_side_data[i], 0);
>> + if (ret < 0)
>> + return ret;
>> + }
>
> Seems wasteful to do this for every frame, when it only needs to be done
> once. Is there a reason not to put this code in init_thread()?
Hadn't thought about it. Will try that.
_______________________________________________
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] 12+ messages in thread
* [FFmpeg-devel] [PATCH 7/7 v6] avcodec/hevcdec: export global side data in AVCodecContext
2024-04-03 8:32 ` Anton Khirnov
2024-04-03 11:31 ` James Almer
@ 2024-04-03 11:55 ` James Almer
1 sibling, 0 replies; 12+ messages in thread
From: James Almer @ 2024-04-03 11:55 UTC (permalink / raw)
To: ffmpeg-devel
Signed-off-by: James Almer <jamrial@gmail.com>
---
libavcodec/avcodec.h | 2 +-
libavcodec/h2645_sei.c | 215 +++++++++++++++++++++----------------
libavcodec/h2645_sei.h | 2 +
libavcodec/hevcdec.c | 4 +
libavcodec/pthread_frame.c | 14 ++-
5 files changed, 143 insertions(+), 94 deletions(-)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 83dc487251..968009a192 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -2071,7 +2071,7 @@ typedef struct AVCodecContext {
* - encoding: may be set by user before calling avcodec_open2() for
* encoder configuration. Afterwards owned and freed by the
* encoder.
- * - decoding: unused
+ * - decoding: may be set by libavcodec in avcodec_open2().
*/
AVFrameSideData **decoded_side_data;
int nb_decoded_side_data;
diff --git a/libavcodec/h2645_sei.c b/libavcodec/h2645_sei.c
index f0f107f73b..1dcdbe7ffb 100644
--- a/libavcodec/h2645_sei.c
+++ b/libavcodec/h2645_sei.c
@@ -529,6 +529,120 @@ static int is_frame_packing_type_valid(SEIFpaType type, enum AVCodecID codec_id)
type >= SEI_FPA_TYPE_SIDE_BY_SIDE;
}
+static int h2645_sei_to_side_data(AVCodecContext *avctx, H2645SEI *sei,
+ AVFrameSideData ***sd, int *nb_sd)
+{
+ int ret;
+
+ for (unsigned i = 0; i < sei->unregistered.nb_buf_ref; i++) {
+ H2645SEIUnregistered *unreg = &sei->unregistered;
+
+ if (unreg->buf_ref[i]) {
+ AVFrameSideData *entry = av_frame_side_data_add(sd, nb_sd,
+ AV_FRAME_DATA_SEI_UNREGISTERED,
+ &unreg->buf_ref[i], 0);
+ if (!entry)
+ av_buffer_unref(&unreg->buf_ref[i]);
+ }
+ }
+ sei->unregistered.nb_buf_ref = 0;
+
+ if (sei->ambient_viewing_environment.present) {
+ H2645SEIAmbientViewingEnvironment *env =
+ &sei->ambient_viewing_environment;
+ AVBufferRef *buf;
+ size_t size;
+
+ AVAmbientViewingEnvironment *dst_env =
+ av_ambient_viewing_environment_alloc(&size);
+ if (!dst_env)
+ return AVERROR(ENOMEM);
+
+ buf = av_buffer_create((uint8_t *)dst_env, size, NULL, NULL, 0);
+ if (!buf) {
+ av_free(dst_env);
+ return AVERROR(ENOMEM);
+ }
+
+ ret = ff_frame_new_side_data_from_buf_ext(avctx, sd, nb_sd,
+ AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT, &buf);
+
+ if (ret < 0)
+ return ret;
+
+ dst_env->ambient_illuminance = av_make_q(env->ambient_illuminance, 10000);
+ dst_env->ambient_light_x = av_make_q(env->ambient_light_x, 50000);
+ dst_env->ambient_light_y = av_make_q(env->ambient_light_y, 50000);
+ }
+
+ if (sei->mastering_display.present) {
+ // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b
+ const int mapping[3] = {2, 0, 1};
+ const int chroma_den = 50000;
+ const int luma_den = 10000;
+ int i;
+ AVMasteringDisplayMetadata *metadata;
+
+ ret = ff_decode_mastering_display_new_ext(avctx, sd, nb_sd, &metadata);
+ if (ret < 0)
+ return ret;
+
+ if (metadata) {
+ for (i = 0; i < 3; i++) {
+ const int j = mapping[i];
+ metadata->display_primaries[i][0].num = sei->mastering_display.display_primaries[j][0];
+ metadata->display_primaries[i][0].den = chroma_den;
+ metadata->display_primaries[i][1].num = sei->mastering_display.display_primaries[j][1];
+ metadata->display_primaries[i][1].den = chroma_den;
+ }
+ metadata->white_point[0].num = sei->mastering_display.white_point[0];
+ metadata->white_point[0].den = chroma_den;
+ metadata->white_point[1].num = sei->mastering_display.white_point[1];
+ metadata->white_point[1].den = chroma_den;
+
+ metadata->max_luminance.num = sei->mastering_display.max_luminance;
+ metadata->max_luminance.den = luma_den;
+ metadata->min_luminance.num = sei->mastering_display.min_luminance;
+ metadata->min_luminance.den = luma_den;
+ metadata->has_luminance = 1;
+ metadata->has_primaries = 1;
+
+ av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n");
+ av_log(avctx, AV_LOG_DEBUG,
+ "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f)\n",
+ av_q2d(metadata->display_primaries[0][0]),
+ av_q2d(metadata->display_primaries[0][1]),
+ av_q2d(metadata->display_primaries[1][0]),
+ av_q2d(metadata->display_primaries[1][1]),
+ av_q2d(metadata->display_primaries[2][0]),
+ av_q2d(metadata->display_primaries[2][1]),
+ av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1]));
+ av_log(avctx, AV_LOG_DEBUG,
+ "min_luminance=%f, max_luminance=%f\n",
+ av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance));
+ }
+ }
+
+ if (sei->content_light.present) {
+ AVContentLightMetadata *metadata;
+
+ ret = ff_decode_content_light_new_ext(avctx, sd, nb_sd, &metadata);
+ if (ret < 0)
+ return ret;
+
+ if (metadata) {
+ metadata->MaxCLL = sei->content_light.max_content_light_level;
+ metadata->MaxFALL = sei->content_light.max_pic_average_light_level;
+
+ av_log(avctx, AV_LOG_DEBUG, "Content Light Level Metadata:\n");
+ av_log(avctx, AV_LOG_DEBUG, "MaxCLL=%d, MaxFALL=%d\n",
+ metadata->MaxCLL, metadata->MaxFALL);
+ }
+ }
+
+ return 0;
+}
+
int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
enum AVCodecID codec_id,
AVCodecContext *avctx, const H2645VUI *vui,
@@ -625,19 +739,9 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
}
- for (unsigned i = 0; i < sei->unregistered.nb_buf_ref; i++) {
- H2645SEIUnregistered *unreg = &sei->unregistered;
-
- if (unreg->buf_ref[i]) {
- AVFrameSideData *sd = av_frame_new_side_data_from_buf(frame,
- AV_FRAME_DATA_SEI_UNREGISTERED,
- unreg->buf_ref[i]);
- if (!sd)
- av_buffer_unref(&unreg->buf_ref[i]);
- unreg->buf_ref[i] = NULL;
- }
- }
- sei->unregistered.nb_buf_ref = 0;
+ ret = h2645_sei_to_side_data(avctx, sei, &frame->side_data, &frame->nb_side_data);
+ if (ret < 0)
+ return ret;
if (sei->afd.present) {
AVFrameSideData *sd = av_frame_new_side_data(frame, AV_FRAME_DATA_AFD,
@@ -728,88 +832,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
return ret;
#endif
- if (sei->ambient_viewing_environment.present) {
- H2645SEIAmbientViewingEnvironment *env =
- &sei->ambient_viewing_environment;
-
- AVAmbientViewingEnvironment *dst_env =
- av_ambient_viewing_environment_create_side_data(frame);
- if (!dst_env)
- return AVERROR(ENOMEM);
-
- dst_env->ambient_illuminance = av_make_q(env->ambient_illuminance, 10000);
- dst_env->ambient_light_x = av_make_q(env->ambient_light_x, 50000);
- dst_env->ambient_light_y = av_make_q(env->ambient_light_y, 50000);
- }
-
- if (sei->mastering_display.present) {
- // HEVC uses a g,b,r ordering, which we convert to a more natural r,g,b
- const int mapping[3] = {2, 0, 1};
- const int chroma_den = 50000;
- const int luma_den = 10000;
- int i;
- AVMasteringDisplayMetadata *metadata;
-
- ret = ff_decode_mastering_display_new(avctx, frame, &metadata);
- if (ret < 0)
- return ret;
-
- if (metadata) {
- for (i = 0; i < 3; i++) {
- const int j = mapping[i];
- metadata->display_primaries[i][0].num = sei->mastering_display.display_primaries[j][0];
- metadata->display_primaries[i][0].den = chroma_den;
- metadata->display_primaries[i][1].num = sei->mastering_display.display_primaries[j][1];
- metadata->display_primaries[i][1].den = chroma_den;
- }
- metadata->white_point[0].num = sei->mastering_display.white_point[0];
- metadata->white_point[0].den = chroma_den;
- metadata->white_point[1].num = sei->mastering_display.white_point[1];
- metadata->white_point[1].den = chroma_den;
-
- metadata->max_luminance.num = sei->mastering_display.max_luminance;
- metadata->max_luminance.den = luma_den;
- metadata->min_luminance.num = sei->mastering_display.min_luminance;
- metadata->min_luminance.den = luma_den;
- metadata->has_luminance = 1;
- metadata->has_primaries = 1;
-
- av_log(avctx, AV_LOG_DEBUG, "Mastering Display Metadata:\n");
- av_log(avctx, AV_LOG_DEBUG,
- "r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f)\n",
- av_q2d(metadata->display_primaries[0][0]),
- av_q2d(metadata->display_primaries[0][1]),
- av_q2d(metadata->display_primaries[1][0]),
- av_q2d(metadata->display_primaries[1][1]),
- av_q2d(metadata->display_primaries[2][0]),
- av_q2d(metadata->display_primaries[2][1]),
- av_q2d(metadata->white_point[0]), av_q2d(metadata->white_point[1]));
- av_log(avctx, AV_LOG_DEBUG,
- "min_luminance=%f, max_luminance=%f\n",
- av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance));
- }
- }
-
- if (sei->content_light.present) {
- AVContentLightMetadata *metadata;
-
- ret = ff_decode_content_light_new(avctx, frame, &metadata);
- if (ret < 0)
- return ret;
-
- if (metadata) {
- metadata->MaxCLL = sei->content_light.max_content_light_level;
- metadata->MaxFALL = sei->content_light.max_pic_average_light_level;
-
- av_log(avctx, AV_LOG_DEBUG, "Content Light Level Metadata:\n");
- av_log(avctx, AV_LOG_DEBUG, "MaxCLL=%d, MaxFALL=%d\n",
- metadata->MaxCLL, metadata->MaxFALL);
- }
- }
-
return 0;
}
+int ff_h2645_sei_to_context(AVCodecContext *avctx, H2645SEI *sei)
+{
+ return h2645_sei_to_side_data(avctx, sei, &avctx->decoded_side_data,
+ &avctx->nb_decoded_side_data);
+}
+
void ff_h2645_sei_reset(H2645SEI *s)
{
av_buffer_unref(&s->a53_caption.buf_ref);
diff --git a/libavcodec/h2645_sei.h b/libavcodec/h2645_sei.h
index b9a6c7587b..488dbcad7e 100644
--- a/libavcodec/h2645_sei.h
+++ b/libavcodec/h2645_sei.h
@@ -168,4 +168,6 @@ int ff_h2645_sei_to_frame(AVFrame *frame, H2645SEI *sei,
unsigned bit_depth_luma, unsigned bit_depth_chroma,
int seed);
+int ff_h2645_sei_to_context(AVCodecContext *avctx, H2645SEI *sei);
+
#endif /* AVCODEC_H2645_SEI_H */
diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c
index 752459af2d..7419381ce2 100644
--- a/libavcodec/hevcdec.c
+++ b/libavcodec/hevcdec.c
@@ -3657,6 +3657,10 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx)
if (ret < 0) {
return ret;
}
+
+ ret = ff_h2645_sei_to_context(avctx, &s->sei.common);
+ if (ret < 0)
+ return ret;
}
sd = ff_get_coded_side_data(avctx, AV_PKT_DATA_DOVI_CONF);
diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c
index fd356bd190..f19571f6f8 100644
--- a/libavcodec/pthread_frame.c
+++ b/libavcodec/pthread_frame.c
@@ -767,6 +767,8 @@ static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
if (!copy)
return AVERROR(ENOMEM);
copy->priv_data = NULL;
+ copy->decoded_side_data = NULL;
+ copy->nb_decoded_side_data = 0;
/* From now on, this PerThreadContext will be cleaned up by
* ff_frame_thread_free in case of errors. */
@@ -820,9 +822,19 @@ static av_cold int init_thread(PerThreadContext *p, int *threads_to_free,
}
p->thread_init = NEEDS_CLOSE;
- if (first)
+ if (first) {
update_context_from_thread(avctx, copy, 1);
+ av_frame_side_data_free(&avctx->decoded_side_data, &avctx->nb_decoded_side_data);
+ for (int i = 0; i < copy->nb_decoded_side_data; i++) {
+ err = av_frame_side_data_clone(&avctx->decoded_side_data,
+ &avctx->nb_decoded_side_data,
+ copy->decoded_side_data[i], 0);
+ if (err < 0)
+ return err;
+ }
+ }
+
atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0);
err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p));
--
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] 12+ messages in thread
* Re: [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array
2024-03-30 17:39 ` [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
@ 2024-04-11 2:35 ` James Almer
0 siblings, 0 replies; 12+ messages in thread
From: James Almer @ 2024-04-11 2:35 UTC (permalink / raw)
To: ffmpeg-devel
On 3/30/2024 2:39 PM, James Almer wrote:
> On 3/28/2024 1:52 PM, James Almer wrote:
>> Signed-off-by: James Almer <jamrial@gmail.com>
>> ---
>> libavutil/frame.c | 19 +++++++++++++++++++
>> libavutil/frame.h | 24 ++++++++++++++++++++++++
>> 2 files changed, 43 insertions(+)
>>
>> diff --git a/libavutil/frame.c b/libavutil/frame.c
>> index ef1613c344..87cc8450c8 100644
>> --- a/libavutil/frame.c
>> +++ b/libavutil/frame.c
>> @@ -812,6 +812,25 @@ AVFrameSideData
>> *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
>> 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_UNIQUE)
>> + remove_side_data(sd, nb_sd, type);
>> +
>> + sd_dst = add_side_data_from_buf(sd, nb_sd, type, buf);
>> + if (!sd_dst)
>> + return NULL;
>> +
>> + *pbuf = NULL;
>> + return sd_dst;
>> +}
>> +
>> int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
>> const AVFrameSideData *src, unsigned
>> int flags)
>> {
>> diff --git a/libavutil/frame.h b/libavutil/frame.h
>> index 3b6d746a16..8d16924432 100644
>> --- a/libavutil/frame.h
>> +++ b/libavutil/frame.h
>> @@ -1062,6 +1062,30 @@ 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 Pointer to AVBufferRef to add to the array. On success,
>> + * the function takes ownership of the AVBufferRef and
>> *buf is
>> + * set to NULL, unless AV_FRAME_SIDE_DATA_FLAG_NEW_REF
>> is set
>> + * in which case the ownership will remain with the caller.
>> + * @param flags Some combination of AV_FRAME_SIDE_DATA_FLAG_* flags,
>> or 0.
>> + *
>> + * @return newly added side data on success, NULL on error.
>> + * @note 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,
>> + 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.
>
> Ping for the set.
Will apply the set soon.
_______________________________________________
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] 12+ messages in thread
end of thread, other threads:[~2024-04-11 2:36 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-28 16:52 [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 2/7 v5] avutil/frame: add a flag to allow overwritting existing entries James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 3/7 v5] avutil/frame: use the same data information as the source entry when cloning side data James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 4/7 v5] avutil/frame: add helper to remove side data of a given type from an array James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 5/7 v5] avutil/mastering_display_metadata: add a new allocator function that returns a size James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 6/7 v5] avcodec/decode: add AVFrameSideData helper wrappers that don't depend on frames James Almer
2024-03-28 16:52 ` [FFmpeg-devel] [PATCH 7/7 v5] avcodec/hevcdec: export global side data in AVCodecContext James Almer
2024-04-03 8:32 ` Anton Khirnov
2024-04-03 11:31 ` James Almer
2024-04-03 11:55 ` [FFmpeg-devel] [PATCH 7/7 v6] " James Almer
2024-03-30 17:39 ` [FFmpeg-devel] [PATCH 1/7 v5] avutil/frame: add helper for adding side data w/ AVBufferRef to array James Almer
2024-04-11 2:35 ` 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