Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [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