[1/2] avpacket: add av_packet_copy_side_data()

Message ID 20170925032857.8324-1-jamrial@gmail.com
State New
Headers show

Commit Message

James Almer Sept. 25, 2017, 3:28 a.m.
This is meant for cases where av_packet_copy_props() can't be used as
only side data needs to be copied.

Signed-off-by: James Almer <jamrial@gmail.com>
---
 doc/APIchanges        |  3 +++
 libavcodec/avcodec.h  | 13 +++++++++++++
 libavcodec/avpacket.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/version.h  |  2 +-
 4 files changed, 62 insertions(+), 1 deletion(-)

Comments

James Almer Sept. 25, 2017, 6:52 p.m. | #1
On 9/25/2017 12:28 AM, James Almer wrote:
> This is meant for cases where av_packet_copy_props() can't be used as
> only side data needs to be copied.
> 
> Signed-off-by: James Almer <jamrial@gmail.com>
> ---
>  doc/APIchanges        |  3 +++
>  libavcodec/avcodec.h  | 13 +++++++++++++
>  libavcodec/avpacket.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  libavcodec/version.h  |  2 +-
>  4 files changed, 62 insertions(+), 1 deletion(-)

wm4 argued that av_packet_copy_props() should be used for this, even if
no other packet fields need to be copied. The caller can work around
that on their own code.

I'm fine with dropping the set if others agree with him.

Patch

diff --git a/doc/APIchanges b/doc/APIchanges
index fa27007f4..205aeaeff 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,9 @@  libavutil:     2017-03-23
 
 API changes, most recent first:
 
+2017-09-xx - xxxxxxx - lavc 58.5.0 - avcodec.h
+  Add av_packet_copy_side_data().
+
 2017-xx-xx - xxxxxxx - lavu 56.6.0 - pixdesc.h
   Add av_color_range_from_name(), av_color_primaries_from_name(),
   av_color_transfer_from_name(), av_color_space_from_name(), and
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 162f1abe4..6571d5d86 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3583,6 +3583,19 @@  uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
 int av_packet_add_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
                             uint8_t *data, size_t size);
 
+/**
+ * Copy packet side data from src to dst.
+ *
+ * @see av_packet_copy_props
+ * @see av_packet_free_side_data
+ *
+ * @param dst Destination packet
+ * @param src Source packet
+ *
+ * @return 0 on success, a negative AVERROR on error. On failure, dst is unchanged.
+ */
+int av_packet_copy_side_data(AVPacket *dst, const AVPacket *src);
+
 /**
  * Shrink the already allocated side data buffer
  *
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index 93e9eb6ae..f20c191c1 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -312,6 +312,51 @@  int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
     return AVERROR(ENOENT);
 }
 
+int av_packet_copy_side_data(AVPacket *dst, const AVPacket *src)
+{
+    AVPacketSideData *side_data;
+    int i, ret, side_data_elems = 0;
+
+    if (!src->side_data_elems)
+        return 0;
+
+    side_data = av_malloc_array(src->side_data_elems, sizeof(*src->side_data));
+    if (!side_data)
+        return AVERROR(ENOMEM);
+
+    for (i = 0; i < src->side_data_elems; i++) {
+        AVPacketSideData *sd_src = &src->side_data[i];
+        AVPacketSideData *sd_dst = &side_data[i];
+
+        if ((unsigned)sd_src->size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
+            ret = AVERROR(ERANGE);
+            goto fail;
+        }
+
+        sd_dst->data = av_mallocz(sd_src->size + AV_INPUT_BUFFER_PADDING_SIZE);
+        if (!sd_dst->data) {
+            ret = AVERROR(ENOMEM);
+            goto fail;
+        }
+
+        memcpy(sd_dst->data, sd_src->data, sd_src->size);
+        sd_dst->size = sd_src->size;
+        sd_dst->type = sd_src->type;
+        side_data_elems++;
+    }
+    dst->side_data = side_data;
+    dst->side_data_elems = side_data_elems;
+
+    return 0;
+
+fail:
+    for (i = 0; i < side_data_elems; i++)
+        av_free(side_data[i].data);
+    av_free(side_data);
+
+    return ret;
+}
+
 int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
 {
     int i;
diff --git a/libavcodec/version.h b/libavcodec/version.h
index bc5b8304b..aa6cdcd6b 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -28,7 +28,7 @@ 
 #include "libavutil/version.h"
 
 #define LIBAVCODEC_VERSION_MAJOR 58
-#define LIBAVCODEC_VERSION_MINOR  4
+#define LIBAVCODEC_VERSION_MINOR  5
 #define LIBAVCODEC_VERSION_MICRO  0
 
 #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \