[FFmpeg-devel] [PATCH 2/9] lavu/opt: introduce av_opt_serialize()

Stefano Sabatini stefasab at gmail.com
Tue Nov 11 17:19:43 CET 2014


On date Tuesday 2014-11-11 08:31:24 +0100, Lukasz Marek encoded:
> TODO: bump minor version, update doc/APIchanges
> 
> Function allows to create string containing object's serialized options.
> Such string may be passed back to av_set_options_string() in order to restore options.
> 
> Signed-off-by: Lukasz Marek <lukasz.m.luki2 at gmail.com>
> ---
>  libavutil/opt.c    | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++
>  libavutil/opt.h    |  17 +++++++
>  tests/ref/fate/opt |   8 ++++
>  3 files changed, 160 insertions(+)
> 
> diff --git a/libavutil/opt.c b/libavutil/opt.c
> index 85c9379..a490583 100644
> --- a/libavutil/opt.c
> +++ b/libavutil/opt.c
> @@ -37,6 +37,7 @@
>  #include "pixdesc.h"
>  #include "mathematics.h"
>  #include "samplefmt.h"
> +#include "bprint.h"
>  
>  #include <float.h>
>  
> @@ -69,6 +70,7 @@ static int read_number(const AVOption *o, void *dst, double *num, int *den, int6
>      case AV_OPT_TYPE_INT64:     *intnum = *(int64_t     *)dst;return 0;
>      case AV_OPT_TYPE_FLOAT:     *num    = *(float       *)dst;return 0;
>      case AV_OPT_TYPE_DOUBLE:    *num    = *(double      *)dst;return 0;
> +    case AV_OPT_TYPE_VIDEO_RATE:
>      case AV_OPT_TYPE_RATIONAL:  *intnum = ((AVRational*)dst)->num;
>                                  *den    = ((AVRational*)dst)->den;
>                                                          return 0;
> @@ -1830,6 +1832,110 @@ int av_opt_is_set_to_default_by_name(void *obj, const char *name, int search_fla
>      return av_opt_is_set_to_default(target, o);
>  }
>  
> +static int opt_serialize_option(void *obj, const AVOption *o, char *buffer, size_t size,
> +                                const char key_val_sep)

probably also a const char *pairs_sep?

> +{
> +    void *dst;
> +    int64_t i64;
> +    double d;
> +    int i, ret, ret2;
> +
> +    dst = ((uint8_t*)obj) + o->offset;
> +    ret = snprintf(buffer, size, "%s%c", o->name, key_val_sep);
> +    if (ret >= size || ret < 0)
> +        return AVERROR(ENOMEM);
> +    switch (o->type) {
> +    case AV_OPT_TYPE_FLAGS:
> +    case AV_OPT_TYPE_PIXEL_FMT:
> +    case AV_OPT_TYPE_SAMPLE_FMT:
> +    case AV_OPT_TYPE_INT:
> +    case AV_OPT_TYPE_CHANNEL_LAYOUT:
> +    case AV_OPT_TYPE_INT64:
> +        read_number(o, dst, NULL, NULL, &i64);
> +        ret2 = snprintf(buffer + ret, size - ret, "%"PRId64, i64);
> +        break;
> +    case AV_OPT_TYPE_DURATION:
> +        read_number(o, dst, NULL, NULL, &i64);
> +        ret2 = snprintf(buffer + ret, size - ret, "%f", i64 / 1000000.0);
> +        break;

> +    case AV_OPT_TYPE_STRING:
> +        ret2 = snprintf(buffer + ret, size - ret, "%s", *(char **)dst);
> +        break;

what if the string is NULL?

> +    case AV_OPT_TYPE_DOUBLE:
> +    case AV_OPT_TYPE_FLOAT:
> +        read_number(o, dst, &d, NULL, NULL);
> +        ret2 = snprintf(buffer + ret, size - ret, "%.10f", d);
> +        break;
> +    case AV_OPT_TYPE_VIDEO_RATE:
> +    case AV_OPT_TYPE_RATIONAL:
> +        read_number(o, dst, NULL, &i, &i64);
> +        if (i == 1)
> +            ret2 = snprintf(buffer + ret, size - ret, "%"PRId64, i64);
> +        else
> +            ret2 = snprintf(buffer + ret, size - ret, "%"PRId64"/%d", i64, i);
> +        break;
> +    case AV_OPT_TYPE_IMAGE_SIZE:
> +        ret2 = snprintf(buffer + ret, size - ret, "%dx%d", ((int *)dst)[0], ((int *)dst)[1]);
> +        break;
> +    case AV_OPT_TYPE_COLOR:
> +        ret2 = snprintf(buffer + ret, size - ret, "0x%.2x%.2x%.2x%.2x",
> +                        ((uint8_t *)dst)[0], ((uint8_t *)dst)[1], ((uint8_t *)dst)[2], ((uint8_t *)dst)[3]);
> +        break;
> +    case AV_OPT_TYPE_BINARY: {
> +        int opt_size = *(int *)((void **)dst + 1);
> +        uint8_t *opt_ptr = *(uint8_t **)dst;
> +        ret2 = opt_size * 2;
> +        if (ret2 >= size - ret)
> +            break;
> +        i = -1;
> +        while(++i < opt_size)
> +            snprintf(buffer + ret + i * 2, size - ret - i * 2, "%.2x", opt_ptr[i]);
> +        break;
> +    }
> +    case AV_OPT_TYPE_DICT:
> +        av_log(NULL, AV_LOG_WARNING, "Dictionary option is not serialized.\n");
> +        return AVERROR_PATCHWELCOME;
> +    default:
> +        return AVERROR_PATCHWELCOME;
> +    }
> +    if (ret2 >= size - ret || ret2 < 0)
> +        return AVERROR(ENOMEM);
> +    return ret + ret2;
> +}

We have already av_get_opt() which serializes the value. Also we should
probably escape the values.

[...]
-- 
FFmpeg = Fantastic & Fiendish Mythic Practical Extreme God


More information about the ffmpeg-devel mailing list