[FFmpeg-devel] [PATCHv3 2/7] avpacket: add pack/unpack functions for AVDictionary
wm4
nfxjfg at googlemail.com
Mon Oct 28 19:56:08 CET 2013
On Sun, 27 Oct 2013 22:47:30 -0400
Ben Boeckel <mathstuf at gmail.com> wrote:
> 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 | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 73 insertions(+)
>
> diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
> index ee2ba54..32ea394 100644
> --- a/libavcodec/avcodec.h
> +++ b/libavcodec/avcodec.h
> @@ -3582,6 +3582,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
Should this mention the need for input padding? (I'm not so familiar
with the conventions in the API, and whether input padding is
explicitly documented or not.)
> + * @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 bee159d..d65c27c 100644
> --- a/libavcodec/avpacket.c
> +++ b/libavcodec/avpacket.c
> @@ -426,6 +426,61 @@ 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;
> +
> + while (data < end) {
> + const uint8_t *key = data;
> + const uint8_t *val = data + strlen(key) + 1;
> + if (val >= end)
> + break;
Maybe this should 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)
> {
Rest looks good to me. Probably also needs an doc/APIchanges entry.
More information about the ffmpeg-devel
mailing list