af_resample: switch to an AVOptions-based system.
authorAnton Khirnov <anton@khirnov.net>
Mon, 25 Feb 2013 20:21:29 +0000 (21:21 +0100)
committerAnton Khirnov <anton@khirnov.net>
Tue, 9 Apr 2013 16:45:50 +0000 (18:45 +0200)
libavfilter/af_resample.c
libavfilter/avfilter.c
libavfilter/avfilter.h

index f82a970..7e86684 100644 (file)
@@ -37,6 +37,7 @@
 #include "internal.h"
 
 typedef struct ResampleContext {
+    const AVClass *class;
     AVAudioResampleContext *avr;
     AVDictionary *options;
 
@@ -46,26 +47,30 @@ typedef struct ResampleContext {
     int got_output;
 } ResampleContext;
 
-static av_cold int init(AVFilterContext *ctx, const char *args)
+static av_cold int init(AVFilterContext *ctx, AVDictionary **opts)
 {
     ResampleContext *s = ctx->priv;
+    const AVClass *avr_class = avresample_get_class();
+    AVDictionaryEntry *e = NULL;
 
-    if (args) {
-        int ret = av_dict_parse_string(&s->options, args, "=", ":", 0);
-        if (ret < 0) {
-            av_log(ctx, AV_LOG_ERROR, "error setting option string: %s\n", args);
-            return ret;
-        }
-
-        /* do not allow the user to override basic format options */
-        av_dict_set(&s->options,  "in_channel_layout", NULL, 0);
-        av_dict_set(&s->options, "out_channel_layout", NULL, 0);
-        av_dict_set(&s->options,  "in_sample_fmt",     NULL, 0);
-        av_dict_set(&s->options, "out_sample_fmt",     NULL, 0);
-        av_dict_set(&s->options,  "in_sample_rate",    NULL, 0);
-        av_dict_set(&s->options, "out_sample_rate",    NULL, 0);
+    while ((e = av_dict_get(*opts, "", e, AV_DICT_IGNORE_SUFFIX))) {
+        if (av_opt_find(&avr_class, e->key, NULL, 0,
+                        AV_OPT_SEARCH_FAKE_OBJ | AV_OPT_SEARCH_CHILDREN))
+            av_dict_set(&s->options, e->key, e->value, 0);
     }
 
+    e = NULL;
+    while ((e = av_dict_get(s->options, "", e, AV_DICT_IGNORE_SUFFIX)))
+        av_dict_set(opts, e->key, NULL, 0);
+
+    /* do not allow the user to override basic format options */
+    av_dict_set(&s->options,  "in_channel_layout", NULL, 0);
+    av_dict_set(&s->options, "out_channel_layout", NULL, 0);
+    av_dict_set(&s->options,  "in_sample_fmt",     NULL, 0);
+    av_dict_set(&s->options, "out_sample_fmt",     NULL, 0);
+    av_dict_set(&s->options,  "in_sample_rate",    NULL, 0);
+    av_dict_set(&s->options, "out_sample_rate",    NULL, 0);
+
     return 0;
 }
 
@@ -272,6 +277,25 @@ fail:
     return ret;
 }
 
+static const AVClass *resample_child_class_next(const AVClass *prev)
+{
+    return prev ? NULL : avresample_get_class();
+}
+
+static void *resample_child_next(void *obj, void *prev)
+{
+    ResampleContext *s = obj;
+    return prev ? NULL : s->avr;
+}
+
+static const AVClass resample_class = {
+    .class_name       = "resample",
+    .item_name        = av_default_item_name,
+    .version          = LIBAVUTIL_VERSION_INT,
+    .child_class_next = resample_child_class_next,
+    .child_next       = resample_child_next,
+};
+
 static const AVFilterPad avfilter_af_resample_inputs[] = {
     {
         .name           = "default",
@@ -295,8 +319,9 @@ AVFilter avfilter_af_resample = {
     .name          = "resample",
     .description   = NULL_IF_CONFIG_SMALL("Audio resampling and conversion."),
     .priv_size     = sizeof(ResampleContext),
+    .priv_class    = &resample_class,
 
-    .init           = init,
+    .init_dict      = init,
     .uninit         = uninit,
     .query_formats  = query_formats,
 
index 93d1855..a8429aa 100644 (file)
@@ -501,11 +501,12 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
         }
     }
 
-    if (filter->filter->init) {
+    if (filter->filter->init)
         ret = filter->filter->init(filter, args);
-        if (ret < 0)
-            goto fail;
-    }
+    else if (filter->filter->init_dict)
+        ret = filter->filter->init_dict(filter, &options);
+    if (ret < 0)
+        goto fail;
 
     if ((e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
         av_log(filter, AV_LOG_ERROR, "No such option: %s.\n", e->key);
index 66f57df..5208c2a 100644 (file)
@@ -409,6 +409,13 @@ typedef struct AVFilter {
     int (*init)(AVFilterContext *ctx, const char *args);
 
     /**
+     * Should be set instead of init by the filters that want to pass a
+     * dictionary of AVOptions to nested contexts that are allocated in
+     * init.
+     */
+    int (*init_dict)(AVFilterContext *ctx, AVDictionary **options);
+
+    /**
      * Filter uninitialization function. Should deallocate any memory held
      * by the filter, release any buffer references, etc. This does not need
      * to deallocate the AVFilterContext->priv memory itself.