[FFmpeg-devel] [PATCHv4 2/7] avpacket: add pack/unpack functions for AVDictionary
Ben Boeckel
mathstuf at gmail.com
Mon Nov 18 02:36:26 CET 2013
These functions are intended for use with side_data which comes in an
AVPacket.
Signed-off-by: Ben Boeckel <mathstuf at gmail.com>
---
libavcodec/avcodec.h | 18 ++++++++++++++++
libavcodec/avpacket.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 76 insertions(+)
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index b761edf..6f00b19 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -3586,6 +3586,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 d9cfb38..9419eb4 100644
--- a/libavcodec/avpacket.c
+++ b/libavcodec/avpacket.c
@@ -426,6 +426,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)
{
--
1.8.4.2
More information about the ffmpeg-devel
mailing list