[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