mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-24 20:19:55 +00:00
Merge remote-tracking branch 'ubitux/lavfi-mixed-short-long'
* ubitux/lavfi-mixed-short-long: lavfi: restore mixed short/long option support with the new system. Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
d7e8b3d831
@ -137,7 +137,7 @@ The name of the filter class is optionally followed by a string
|
||||
"=@var{arguments}".
|
||||
|
||||
@var{arguments} is a string which contains the parameters used to
|
||||
initialize the filter instance. It may have one of the two allowed forms:
|
||||
initialize the filter instance. It may have one of the following forms:
|
||||
@itemize
|
||||
|
||||
@item
|
||||
@ -151,6 +151,12 @@ declares three options in this order -- @option{type}, @option{start_frame} and
|
||||
@var{in} is assigned to the option @option{type}, @var{0} to
|
||||
@option{start_frame} and @var{30} to @option{nb_frames}.
|
||||
|
||||
@item
|
||||
A ':'-separated list of mixed direct @var{value} and long @var{key=value}
|
||||
pairs. The direct @var{value} must precede the @var{key=value} pairs, and
|
||||
follow the same constraints order of the previous point. The following
|
||||
@var{key=value} pairs can be set in any preferred order.
|
||||
|
||||
@end itemize
|
||||
|
||||
If the option value itself is a list of items (e.g. the @code{format} filter
|
||||
|
@ -610,39 +610,64 @@ 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)
|
||||
static int process_options(AVFilterContext *ctx, AVDictionary **options,
|
||||
const char *args)
|
||||
{
|
||||
const AVOption *o = NULL;
|
||||
const char *p = args;
|
||||
char *val;
|
||||
int ret, count = 0;
|
||||
char *av_uninit(parsed_key), *av_uninit(value);
|
||||
const char *key;
|
||||
int offset= -1;
|
||||
|
||||
while (*p) {
|
||||
if (!args)
|
||||
return 0;
|
||||
|
||||
while (*args) {
|
||||
const char *shorthand = NULL;
|
||||
|
||||
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) {
|
||||
if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
|
||||
continue;
|
||||
offset = o->offset;
|
||||
shorthand = o->name;
|
||||
}
|
||||
if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
|
||||
continue;
|
||||
offset = o->offset;
|
||||
|
||||
val = av_get_token(&p, ":");
|
||||
if (!val)
|
||||
return AVERROR(ENOMEM);
|
||||
ret = av_opt_get_key_value(&args, "=", ":",
|
||||
shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
|
||||
&parsed_key, &value);
|
||||
if (ret < 0) {
|
||||
if (ret == AVERROR(EINVAL))
|
||||
av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", args);
|
||||
else
|
||||
av_log(ctx, AV_LOG_ERROR, "Unable to parse '%s': %s\n", args,
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
if (*args)
|
||||
args++;
|
||||
if (parsed_key) {
|
||||
key = parsed_key;
|
||||
while ((o = av_opt_next(ctx->priv, o))); /* discard all remaining shorthand */
|
||||
} else {
|
||||
key = shorthand;
|
||||
}
|
||||
|
||||
av_dict_set(options, o->name, val, 0);
|
||||
av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);
|
||||
av_dict_set(options, key, value, 0);
|
||||
if ((ret = av_opt_set(ctx->priv, key, value, 0)) < 0) {
|
||||
if (ret == AVERROR_OPTION_NOT_FOUND)
|
||||
av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);
|
||||
av_free(value);
|
||||
av_free(parsed_key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
av_freep(&val);
|
||||
if (*p)
|
||||
p++;
|
||||
av_free(value);
|
||||
av_free(parsed_key);
|
||||
count++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return count;
|
||||
}
|
||||
|
||||
int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
|
||||
@ -782,20 +807,11 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
|
||||
ret = av_dict_parse_string(&options, p, "=", ":", 0);
|
||||
}
|
||||
if (ret >= 0)
|
||||
ret = process_unnamed_options(filter, &options, copy);
|
||||
ret = process_options(filter, &options, copy);
|
||||
av_freep(©);
|
||||
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
} else
|
||||
#endif
|
||||
|
||||
if (strchr(args, '=')) {
|
||||
/* assume a list of key1=value1:key2=value2:... */
|
||||
ret = av_dict_parse_string(&options, args, "=", ":", 0);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
#if FF_API_OLD_FILTER_OPTS
|
||||
} else if (!strcmp(filter->filter->name, "format") ||
|
||||
!strcmp(filter->filter->name, "noformat") ||
|
||||
!strcmp(filter->filter->name, "frei0r") ||
|
||||
@ -835,14 +851,14 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
|
||||
while ((p = strchr(p, ':')))
|
||||
*p++ = '|';
|
||||
|
||||
ret = process_unnamed_options(filter, &options, copy);
|
||||
ret = process_options(filter, &options, copy);
|
||||
av_freep(©);
|
||||
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
#endif
|
||||
} else {
|
||||
ret = process_unnamed_options(filter, &options, args);
|
||||
ret = process_options(filter, &options, args);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user