diff options
author | Ben Boeckel <mathstuf@gmail.com> | 2013-11-17 20:36:26 -0500 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-11-20 16:48:51 +0100 |
commit | 51a84a6bca611759c237aefe4408dbea8e153c04 (patch) | |
tree | feceb7d01db5b8f3356cc3840017d4166be62c94 | |
parent | 1e506a2cc586935b9548870295dcbd680422e180 (diff) | |
download | ffmpeg-51a84a6bca611759c237aefe4408dbea8e153c04.tar.gz |
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@gmail.com>
Reviewed-by: wm4
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/avcodec.h | 18 | ||||
-rw-r--r-- | libavcodec/avpacket.c | 58 |
2 files changed, 76 insertions, 0 deletions
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 5239bd76f9..68bb1154ae 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 bce3a5890b..e30845c0c0 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) { |