[FFmpeg-cvslog] avpacket: add pack/unpack functions for AVDictionary

Ben Boeckel git at videolan.org
Wed Nov 20 17:41:35 CET 2013


ffmpeg | branch: master | Ben Boeckel <mathstuf at gmail.com> | Sun Nov 17 20:36:26 2013 -0500| [51a84a6bca611759c237aefe4408dbea8e153c04] | committer: Michael Niedermayer

avpacket: add pack/unpack functions for AVDictionary

These functions are intended for use with side_data which comes in an
AVPacket.

Signed-off-by: Ben Boeckel <mathstuf at gmail.com>
Reviewed-by: wm4
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=51a84a6bca611759c237aefe4408dbea8e153c04
---

 libavcodec/avcodec.h  |   18 +++++++++++++++
 libavcodec/avpacket.c |   58 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 5239bd7..68bb115 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3587,6 +3587,24 @@ int av_packet_merge_side_data(AVPacket *pkt);
 
 int av_packet_split_side_data(AVPacket *pkt);
 
+/**
+ * Pack a dictionary for use in side_data.
+ *
+ * @param dict The dictionary to pack.
+ * @param size pointer to store the size of the returned data
+ * @return pointer to data if successful, NULL otherwise
+ */
+uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size);
+/**
+ * Unpack a dictionary from side_data.
+ *
+ * @param data data from side_data
+ * @param size size of the data
+ * @param dict the metadata storage dictionary
+ * @return 0 on success, < 0 on failure
+ */
+int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict);
+
 
 /**
  * Convenience function to free all the side data stored.
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c
index bce3a58..e30845c 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -427,6 +427,64 @@ int av_packet_split_side_data(AVPacket *pkt){
     return 0;
 }
 
+uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size)
+{
+    AVDictionaryEntry *t = NULL;
+    uint8_t *data = NULL;
+    *size = 0;
+
+    if (!dict)
+        return NULL;
+
+    while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) {
+        const int keylen = strlen(t->key);
+        const int valuelen = strlen(t->value);
+        const size_t new_size = *size + keylen + 1 + valuelen + 1;
+        uint8_t *const new_data = av_realloc(data, new_size);
+
+        if (!new_data)
+            goto fail;
+        data = new_data;
+
+        memcpy(data + *size, t->key, keylen + 1);
+        memcpy(data + *size + keylen + 1, t->value, valuelen + 1);
+
+        *size = new_size;
+    }
+
+    return data;
+
+fail:
+    av_freep(&data);
+    *size = 0;
+    return NULL;
+}
+
+int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict)
+{
+    const uint8_t *end = data + size;
+    int ret = 0;
+
+    if (!dict || !data || !size)
+        return ret;
+    if (size && end[-1])
+        return AVERROR_INVALIDDATA;
+    while (data < end) {
+        const uint8_t *key = data;
+        const uint8_t *val = data + strlen(key) + 1;
+
+        if (val >= end)
+            return AVERROR_INVALIDDATA;
+
+        ret = av_dict_set(dict, key, val, 0);
+        if (ret < 0)
+            break;
+        data = val + strlen(val) + 1;
+    }
+
+    return ret;
+}
+
 int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
                                int size)
 {



More information about the ffmpeg-cvslog mailing list