The frame side-data could be created before the actual frame is
decoded/created.
---

version bump and apichange dance once the actual code and api are fine
for everybody.

 libavutil/frame.c | 60 +++++++++++++++++++++++++++++++++++++------------------
 libavutil/frame.h | 22 ++++++++++++++++++++
 2 files changed, 63 insertions(+), 19 deletions(-)

diff --git a/libavutil/frame.c b/libavutil/frame.c
index 32ec470..53c9d83 100644
--- a/libavutil/frame.c
+++ b/libavutil/frame.c
@@ -447,37 +447,59 @@ AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, 
int plane)
     return NULL;
 }

-AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
-                                        enum AVFrameSideDataType type,
-                                        int size)
+
+AVFrameSideData *av_frame_side_data_alloc(enum AVFrameSideDataType type,
+                                          int size)
 {
-    AVFrameSideData *ret, **tmp;
+    AVFrameSideData *sd = av_mallocz(sizeof(*sd));
+    if (!sd)
+        return sd;

-    if (frame->nb_side_data > INT_MAX / sizeof(*frame->side_data) - 1)
+    sd->data = av_malloc(size);
+    if (!sd->data) {
+        av_free(sd);
         return NULL;
+    }
+
+    sd->size = size;
+    sd->type = type;

-    tmp = av_realloc(frame->side_data,
-                     (frame->nb_side_data + 1) * sizeof(*frame->side_data));
+    return sd;
+}
+
+int av_frame_append_side_data(AVFrame *frame,
+                              AVFrameSideData *side_data)
+{
+    AVFrameSideData **tmp;
+
+    tmp = av_realloc_array(frame->side_data,
+                           frame->nb_side_data + 1,
+                           sizeof(*frame->side_data));
     if (!tmp)
-        return NULL;
+        return AVERROR(ENOMEM);
+
     frame->side_data = tmp;

-    ret = av_mallocz(sizeof(*ret));
-    if (!ret)
+    frame->side_data[frame->nb_side_data++] = side_data;
+
+    return 0;
+}
+
+AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
+                                        enum AVFrameSideDataType type,
+                                        int size)
+{
+    AVFrameSideData *sd = av_frame_side_data_alloc(type, size);
+
+    if (!sd)
         return NULL;

-    ret->data = av_malloc(size);
-    if (!ret->data) {
-        av_freep(&ret);
+    if (av_frame_append_side_data(frame, sd) < 0) {
+        free_side_data(sd);
         return NULL;
     }

-    ret->size = size;
-    ret->type = type;
-
-    frame->side_data[frame->nb_side_data++] = ret;
-
-    return ret;
+    return sd;
 }

 AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 2bd70ef..9e907dc 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -597,6 +597,28 @@ int av_frame_copy_props(AVFrame *dst, const AVFrame *src);
 AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane);

 /**
+ * Allocate a side data
+ *
+ * @param type type of the added side data
+ * @param size size of the side data
+ *
+ * @return newly added side data on success, NULL on error
+ */
+AVFrameSideData *av_frame_side_data_alloc(enum AVFrameSideDataType type,
+                                          int size);
+
+/**
+ * Add an already allocated side data to a frame.
+ *
+ * @param frame a frame to which the side data should be added
+ * @param side_data the already populated side_data.
+ *
+ * @return 0 on success, AVERROR(ENOMEM) on failure.
+ */
+int av_frame_append_side_data(AVFrame *frame,
+                              AVFrameSideData *side_data);
+
+/**
  * Add a new side data to a frame.
  *
  * @param frame a frame to which the side data should be added
--
1.9.0

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to