mirror of https://git.ffmpeg.org/ffmpeg.git
lavfi: restore mixed short/long option support with the new system.
process_unnamed_options() is renamed to process_options() and its code is heavily based on av_opt_set_from_string().
This commit is contained in:
parent
c7b0a84e1f
commit
b89ce54e74
|
@ -137,7 +137,7 @@ 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. It may have one of the two allowed forms:
|
initialize the filter instance. It may have one of the following forms:
|
||||||
@itemize
|
@itemize
|
||||||
|
|
||||||
@item
|
@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
|
@var{in} is assigned to the option @option{type}, @var{0} to
|
||||||
@option{start_frame} and @var{30} to @option{nb_frames}.
|
@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
|
@end itemize
|
||||||
|
|
||||||
If the option value itself is a list of items (e.g. the @code{format} filter
|
If the option value itself is a list of items (e.g. the @code{format} filter
|
||||||
|
|
|
@ -615,39 +615,64 @@ void avfilter_free(AVFilterContext *filter)
|
||||||
av_free(filter);
|
av_free(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* process a list of value1:value2:..., each value corresponding
|
static int process_options(AVFilterContext *ctx, AVDictionary **options,
|
||||||
* to subsequent AVOption, in the order they are declared */
|
const char *args)
|
||||||
static int process_unnamed_options(AVFilterContext *ctx, AVDictionary **options,
|
|
||||||
const char *args)
|
|
||||||
{
|
{
|
||||||
const AVOption *o = NULL;
|
const AVOption *o = NULL;
|
||||||
const char *p = args;
|
int ret, count = 0;
|
||||||
char *val;
|
char *av_uninit(parsed_key), *av_uninit(value);
|
||||||
|
const char *key;
|
||||||
int offset= -1;
|
int offset= -1;
|
||||||
|
|
||||||
while (*p) {
|
if (!args)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
while (*args) {
|
||||||
|
const char *shorthand = NULL;
|
||||||
|
|
||||||
o = av_opt_next(ctx->priv, o);
|
o = av_opt_next(ctx->priv, o);
|
||||||
if (!o) {
|
if (o) {
|
||||||
av_log(ctx, AV_LOG_ERROR, "More options provided than "
|
if (o->type == AV_OPT_TYPE_CONST || o->offset == offset)
|
||||||
"this filter supports.\n");
|
continue;
|
||||||
return AVERROR(EINVAL);
|
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, ":");
|
ret = av_opt_get_key_value(&args, "=", ":",
|
||||||
if (!val)
|
shorthand ? AV_OPT_FLAG_IMPLICIT_KEY : 0,
|
||||||
return AVERROR(ENOMEM);
|
&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);
|
av_free(value);
|
||||||
if (*p)
|
av_free(parsed_key);
|
||||||
p++;
|
count++;
|
||||||
}
|
}
|
||||||
|
return count;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
|
int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque)
|
||||||
|
@ -787,20 +812,11 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
|
||||||
ret = av_dict_parse_string(&options, p, "=", ":", 0);
|
ret = av_dict_parse_string(&options, p, "=", ":", 0);
|
||||||
}
|
}
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
ret = process_unnamed_options(filter, &options, copy);
|
ret = process_options(filter, &options, copy);
|
||||||
av_freep(©);
|
av_freep(©);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
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") ||
|
} else if (!strcmp(filter->filter->name, "format") ||
|
||||||
!strcmp(filter->filter->name, "noformat") ||
|
!strcmp(filter->filter->name, "noformat") ||
|
||||||
!strcmp(filter->filter->name, "frei0r") ||
|
!strcmp(filter->filter->name, "frei0r") ||
|
||||||
|
@ -840,14 +856,14 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
|
||||||
while ((p = strchr(p, ':')))
|
while ((p = strchr(p, ':')))
|
||||||
*p++ = '|';
|
*p++ = '|';
|
||||||
|
|
||||||
ret = process_unnamed_options(filter, &options, copy);
|
ret = process_options(filter, &options, copy);
|
||||||
av_freep(©);
|
av_freep(©);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
ret = process_unnamed_options(filter, &options, args);
|
ret = process_options(filter, &options, args);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue