mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2025-02-17 18:38:13 +00:00
lavfi: switch to an AVOptions-based system.
This commit is contained in:
parent
56c1b92576
commit
b439c992c2
@ -41,8 +41,25 @@ The name of the filter class is optionally followed by a string
|
|||||||
"=@var{arguments}".
|
"=@var{arguments}".
|
||||||
|
|
||||||
@var{arguments} is a string which contains the parameters used to
|
@var{arguments} is a string which contains the parameters used to
|
||||||
initialize the filter instance, and are described in the filter
|
initialize the filter instance. It may have one of the two allowed forms:
|
||||||
descriptions below.
|
@itemize
|
||||||
|
|
||||||
|
@item
|
||||||
|
A ':'-separated list of @var{key=value} pairs.
|
||||||
|
|
||||||
|
@item
|
||||||
|
A ':'-separated list of @var{value}. In this case, the keys are assumed to be
|
||||||
|
the option names in the order they are declared. E.g. the @code{fade} filter
|
||||||
|
declares three options in this order -- @option{type}, @option{start_frame} and
|
||||||
|
@option{nb_frames}. Then the parameter list @var{in:0:30} means that the value
|
||||||
|
@var{in} is assigned to the option @option{type}, @var{0} to
|
||||||
|
@option{start_frame} and @var{30} to @option{nb_frames}.
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
If the option value itself is a list of items (e.g. the @code{format} filter
|
||||||
|
takes a list of pixel formats), the items in the list are usually separated by
|
||||||
|
'|'.
|
||||||
|
|
||||||
The list of arguments can be quoted using the character "'" as initial
|
The list of arguments can be quoted using the character "'" as initial
|
||||||
and ending mark, and the character '\' for escaping the characters
|
and ending mark, and the character '\' for escaping the characters
|
||||||
|
@ -21,9 +21,11 @@
|
|||||||
|
|
||||||
/* #define DEBUG */
|
/* #define DEBUG */
|
||||||
|
|
||||||
|
#include "libavutil/avstring.h"
|
||||||
#include "libavutil/channel_layout.h"
|
#include "libavutil/channel_layout.h"
|
||||||
#include "libavutil/common.h"
|
#include "libavutil/common.h"
|
||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
#include "libavutil/rational.h"
|
#include "libavutil/rational.h"
|
||||||
#include "libavutil/samplefmt.h"
|
#include "libavutil/samplefmt.h"
|
||||||
@ -346,6 +348,11 @@ int avfilter_open(AVFilterContext **filter_ctx, AVFilter *filter, const char *in
|
|||||||
goto err;
|
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);
|
ret->nb_inputs = pad_count(filter->inputs);
|
||||||
if (ret->nb_inputs ) {
|
if (ret->nb_inputs ) {
|
||||||
ret->input_pads = av_malloc(sizeof(AVFilterPad) * 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);
|
av_freep(&link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter->filter->priv_class)
|
||||||
|
av_opt_free(filter->priv);
|
||||||
|
|
||||||
av_freep(&filter->name);
|
av_freep(&filter->name);
|
||||||
av_freep(&filter->input_pads);
|
av_freep(&filter->input_pads);
|
||||||
av_freep(&filter->output_pads);
|
av_freep(&filter->output_pads);
|
||||||
@ -431,12 +441,81 @@ void avfilter_free(AVFilterContext *filter)
|
|||||||
av_free(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)
|
int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
|
||||||
{
|
{
|
||||||
|
AVDictionary *options = NULL;
|
||||||
|
AVDictionaryEntry *e;
|
||||||
int ret=0;
|
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);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,6 +388,12 @@ typedef struct AVFilter {
|
|||||||
const AVFilterPad *inputs; ///< NULL terminated list of inputs. NULL if none
|
const AVFilterPad *inputs; ///< NULL terminated list of inputs. NULL if none
|
||||||
const AVFilterPad *outputs; ///< NULL terminated list of outputs. NULL if none
|
const AVFilterPad *outputs; ///< NULL terminated list of outputs. NULL if none
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class for the private data, used to access filter private
|
||||||
|
* AVOptions.
|
||||||
|
*/
|
||||||
|
const AVClass *priv_class;
|
||||||
|
|
||||||
/*****************************************************************
|
/*****************************************************************
|
||||||
* All fields below this line are not part of the public API. They
|
* All fields below this line are not part of the public API. They
|
||||||
* may not be used outside of libavfilter and can be changed and
|
* may not be used outside of libavfilter and can be changed and
|
||||||
|
@ -55,5 +55,8 @@
|
|||||||
#ifndef FF_API_AVFILTERBUFFER
|
#ifndef FF_API_AVFILTERBUFFER
|
||||||
#define FF_API_AVFILTERBUFFER (LIBAVFILTER_VERSION_MAJOR < 4)
|
#define FF_API_AVFILTERBUFFER (LIBAVFILTER_VERSION_MAJOR < 4)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FF_API_OLD_FILTER_OPTS
|
||||||
|
#define FF_API_OLD_FILTER_OPTS (LIBAVFILTER_VERSION_MAJOR < 4)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* AVFILTER_VERSION_H */
|
#endif /* AVFILTER_VERSION_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user