aboutsummaryrefslogtreecommitdiffstats
path: root/libavfilter/avfilter.c
diff options
context:
space:
mode:
authorAnton Khirnov <anton@khirnov.net>2013-02-25 21:21:29 +0100
committerAnton Khirnov <anton@khirnov.net>2013-04-09 18:45:37 +0200
commitb439c992c23f3e0f3832fffd2a34a664b236c525 (patch)
treeb2c5c664c5458925bac0ba3e2f61de0df0609608 /libavfilter/avfilter.c
parent56c1b9257698719bca9e87df843e7933434d6efa (diff)
downloadffmpeg-b439c992c23f3e0f3832fffd2a34a664b236c525.tar.gz
lavfi: switch to an AVOptions-based system.
Diffstat (limited to 'libavfilter/avfilter.c')
-rw-r--r--libavfilter/avfilter.c81
1 files changed, 80 insertions, 1 deletions
diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c
index 4985ce9579..93d1855ce3 100644
--- a/libavfilter/avfilter.c
+++ b/libavfilter/avfilter.c
@@ -21,9 +21,11 @@
/* #define DEBUG */
+#include "libavutil/avstring.h"
#include "libavutil/channel_layout.h"
#include "libavutil/common.h"
#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
#include "libavutil/rational.h"
#include "libavutil/samplefmt.h"
@@ -346,6 +348,11 @@ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *in
goto err;
}
+ if (filter->priv_class) {
+ *(const AVClass**)ret->priv = filter->priv_class;
+ av_opt_set_defaults(ret->priv);
+ }
+
ret->nb_inputs = pad_count(filter->inputs);
if (ret->nb_inputs ) {
ret->input_pads = av_malloc(sizeof(AVFilterPad) * ret->nb_inputs);
@@ -422,6 +429,9 @@ void avfilter_free(AVFilterContext *filter)
av_freep(&link);
}
+ if (filter->filter->priv_class)
+ av_opt_free(filter->priv);
+
av_freep(&filter->name);
av_freep(&filter->input_pads);
av_freep(&filter->output_pads);
@@ -431,12 +441,81 @@ void avfilter_free(AVFilterContext *filter)
av_free(filter);
}
+/* process a list of value1:value2:..., each value corresponding
+ * to subsequent AVOption, in the order they are declared */
+static int process_unnamed_options(AVFilterContext *ctx, AVDictionary **options,
+ const char *args)
+{
+ const AVOption *o = NULL;
+ const char *p = args;
+ char *val;
+
+ while (*p) {
+ o = av_opt_next(ctx->priv, o);
+ if (!o) {
+ av_log(ctx, AV_LOG_ERROR, "More options provided than "
+ "this filter supports.\n");
+ return AVERROR(EINVAL);
+ }
+ if (o->type == AV_OPT_TYPE_CONST)
+ continue;
+
+ val = av_get_token(&p, ":");
+ if (!val)
+ return AVERROR(ENOMEM);
+
+ av_dict_set(options, o->name, val, 0);
+
+ av_freep(&val);
+ if (*p)
+ p++;
+ }
+
+ return 0;
+}
+
int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
{
+ AVDictionary *options = NULL;
+ AVDictionaryEntry *e;
int ret=0;
- if (filter->filter->init)
+ if (args && *args && filter->filter->priv_class) {
+ if (strchr(args, '=')) {
+ /* assume a list of key1=value1:key2=value2:... */
+ ret = av_dict_parse_string(&options, args, "=", ":", 0);
+ if (ret < 0)
+ goto fail;
+ } else {
+ ret = process_unnamed_options(filter, &options, args);
+ if (ret < 0)
+ goto fail;
+ }
+ }
+
+ if (filter->filter->priv_class) {
+ ret = av_opt_set_dict(filter->priv, &options);
+ if (ret < 0) {
+ av_log(filter, AV_LOG_ERROR, "Error applying options to the filter.\n");
+ goto fail;
+ }
+ }
+
+ if (filter->filter->init) {
ret = filter->filter->init(filter, args);
+ 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);
+ ret = AVERROR_OPTION_NOT_FOUND;
+ goto fail;
+ }
+
+fail:
+ av_dict_free(&options);
+
return ret;
}