[FFmpeg-devel] [PATCH/RFC] Per-codec option system

Stefano Sabatini stefano.sabatini-lala
Wed Sep 30 21:04:00 CEST 2009


On date Wednesday 2009-09-30 12:03:56 +0200, Michael Niedermayer encoded:
> On Wed, Sep 30, 2009 at 01:48:43AM -0700, Jason Garrett-Glaser wrote:
[...]
> >every codec will have to have a
> > help(), an option handler, and so forth.  How do you propose that we
> > implement this new system for only *some* codecs so that it can be
> > incrementally added?
> 
> i need to reread the mails from the past [someone got the $subs?]
> but without that i can think of an obvious solution to a few of the
> issues ...

I'm not sure if you refer to my last attempt to change AVOptions, in
the case check these:

http://thread.gmane.org/gmane.comp.video.ffmpeg.devel/79767/

http://thread.gmane.org/gmane.comp.video.ffmpeg.devel/93469/focus=94243

Also I believe per-codec options is somehow orthogonal to the changes
I proposed, also lavfi currently works exactly with *per-filter
options*, as there is not a global context shared by them as it is for
codecs.

Consider this example:

typedef struct
{
    const AVClass *class;
    char *out_w_expr, *out_h_expr;
    char *x_expr, *y_expr;
    char *color_str;
    int8_t yuva_color[4];

    double var_values[VARS_NB];
    int out_w, out_h, x, y;

    int hsub, vsub;         ///< chroma subsampling
} PadContext;

#define OFFSET(x) offsetof(PadContext, x)

static const AVOption pad_options[] = {
{"out_w", "set output width expression",  OFFSET(out_w_expr), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX},
{"out_h", "set output height expression", OFFSET(out_h_expr), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX},
{"x",     "set x offset expression",      OFFSET(x_expr),     FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX},
{"y",     "set y offset expression",      OFFSET(y_expr),     FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX},
{"color", "set the pad color",            OFFSET(color_str),  FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX},
{NULL},
};

static const char *pad_get_name(void *ctx)
{
    return "pad";
}

static const AVClass pad_class = {
    "PadContext",
    pad_get_name,
    pad_options
};

static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
{
    PadContext *pad = ctx->priv;
    uint8_t rgba_color[4];

    pad->class = &pad_class;
    av_opt_set_defaults2(pad, 0, 0);

    pad->var_values[PI] = M_PI;
    pad->var_values[E ] = M_E;

    pad->out_w_expr = av_strdup("in_w");
    pad->out_h_expr = av_strdup("in_h");
    pad->x_expr     = av_strdup("(out_w-in_w) / 2");
    pad->y_expr     = av_strdup("(out_h-in_h) / 2");
    pad->color_str  = av_strdup("black");

    if (args && av_set_options_string(pad, args, "=", ":") < 0)
        return -1;

    if (av_parse_color(rgba_color, pad->color_str, pad) < 0)
        return -1;
    pad->yuva_color[0] = RGB_TO_Y(rgba_color[0], rgba_color[1], rgba_color[2]);
    pad->yuva_color[1] = RGB_TO_U(rgba_color[0], rgba_color[1], rgba_color[2], 0);
    pad->yuva_color[2] = RGB_TO_V(rgba_color[0], rgba_color[1], rgba_color[2], 0);
    pad->yuva_color[3] = rgba_color[3];

    return 0;
}

The trick here is to find some way to tell av_set_option() to look for
an option in the private context of the codec, then eventually to
check then in the global shared context if the option is not found
there, maybe something like av_set_codec_option()?  But that's not a
good name if the same should be done for de-muxers or devices.

Note also how this does not require to change the current opt.[ch]
options system.

That is necessary if you need to deal with special option which are
not contemplated by the few types currently supported by opt.[hc].

> We currently have the AVCodecContext context and a private context
> (AVCodecContext->priv_data that being X264Context in x264s case)
> if we now add an AVOptions array for X264Context and make its first
> element an AVClass then av_set_string() could be called on priv_data
> and libx264.c would have full control over, help, default, min, max
> and type of each of these parameters.
> if we further could allocate priv_data in avcodec_get_context_defaults2()
> then we trivially could also initialize it to defaults with a single
> av_opt_set_defaults2() call
> that would look like
> 
> void avcodec_get_context_defaults2(AVCodecContext *s, enum CodecId codec_id){
>     ...
>     AVCodec codec= find_codec(codec_id);
>     s->codec= codec;
>     s->priv_data= av_mallocz(codec->priv_data_size);
>     if(codec->priv_class){
>         s->priv_data->av_class= codec->priv_class;
>         av_opt_set_defaults2(s->priv_data, flags, flags);
>     }
> }
> 
> (above would need a priv_class be addeded to AVCodec)

Regards.
-- 
FFmpeg = Foolish & Faboulous Magnificient Picky Erroneous Gem



More information about the ffmpeg-devel mailing list