vf_frei0r: switch to an AVOptions-based system.

This commit is contained in:
Anton Khirnov 2013-02-25 21:21:29 +01:00
parent f13ab29925
commit 5aa1a668cf
3 changed files with 108 additions and 53 deletions

View File

@ -1118,20 +1118,22 @@ Apply a frei0r effect to the input video.
To enable compilation of this filter you need to install the frei0r To enable compilation of this filter you need to install the frei0r
header and configure Libav with --enable-frei0r. header and configure Libav with --enable-frei0r.
The filter supports the syntax: This filter accepts the following options:
@example
@var{filter_name}[@{:|=@}@var{param1}:@var{param2}:...:@var{paramN}]
@end example
@var{filter_name} is the name to the frei0r effect to load. If the @table @option
environment variable @env{FREI0R_PATH} is defined, the frei0r effect
is searched in each one of the directories specified by the colon
separated list in @env{FREIOR_PATH}, otherwise in the standard frei0r
paths, which are in this order: @file{HOME/.frei0r-1/lib/},
@file{/usr/local/lib/frei0r-1/}, @file{/usr/lib/frei0r-1/}.
@var{param1}, @var{param2}, ... , @var{paramN} specify the parameters @item filter_name
for the frei0r effect. The name to the frei0r effect to load. If the environment variable
@env{FREI0R_PATH} is defined, the frei0r effect is searched in each one of the
directories specified by the colon separated list in @env{FREIOR_PATH},
otherwise in the standard frei0r paths, which are in this order:
@file{HOME/.frei0r-1/lib/}, @file{/usr/local/lib/frei0r-1/},
@file{/usr/lib/frei0r-1/}.
@item filter_params
A '|'-separated list of parameters to pass to the frei0r effect.
@end table
A frei0r effect parameter can be a boolean (whose values are specified A frei0r effect parameter can be a boolean (whose values are specified
with "y" and "n"), a double, a color (specified by the syntax with "y" and "n"), a double, a color (specified by the syntax
@ -1146,7 +1148,7 @@ effect parameter is not specified the default value is set.
Some examples follow: Some examples follow:
@example @example
# apply the distort0r effect, set the first two double parameters # apply the distort0r effect, set the first two double parameters
frei0r=distort0r:0.5:0.01 frei0r=filter_name=distort0r:filter_params=0.5|0.01
# apply the colordistance effect, takes a color as first parameter # apply the colordistance effect, takes a color as first parameter
frei0r=colordistance:0.2/0.3/0.4 frei0r=colordistance:0.2/0.3/0.4
@ -1155,7 +1157,7 @@ frei0r=colordistance:0x112233
# apply the perspective effect, specify the top left and top right # apply the perspective effect, specify the top left and top right
# image positions # image positions
frei0r=perspective:0.2/0.2:0.8/0.2 frei0r=perspective:0.2/0.2|0.8/0.2
@end example @end example
For more information see: For more information see:
@ -2375,24 +2377,33 @@ Provide a frei0r source.
To enable compilation of this filter you need to install the frei0r To enable compilation of this filter you need to install the frei0r
header and configure Libav with --enable-frei0r. header and configure Libav with --enable-frei0r.
The source supports the syntax: This source accepts the following options:
@example
@var{size}:@var{rate}:@var{src_name}[@{=|:@}@var{param1}:@var{param2}:...:@var{paramN}]
@end example
@var{size} is the size of the video to generate, may be a string of the @table @option
form @var{width}x@var{height} or a frame size abbreviation.
@var{rate} is the rate of the video to generate, may be a string of @item size
the form @var{num}/@var{den} or a frame rate abbreviation. The size of the video to generate, may be a string of the form
@var{src_name} is the name to the frei0r source to load. For more @var{width}x@var{height} or a frame size abbreviation.
information regarding frei0r and how to set the parameters read the
section @ref{frei0r} in the description of the video filters. @item framerate
Framerate of the generated video, may be a string of the form
@var{num}/@var{den} or a frame rate abbreviation.
@item filter_name
The name to the frei0r source to load. For more information regarding frei0r and
how to set the parameters read the section @ref{frei0r} in the description of
the video filters.
@item filter_params
A '|'-separated list of parameters to pass to the frei0r source.
@end table
Some examples follow: Some examples follow:
@example @example
# generate a frei0r partik0l source with size 200x200 and framerate 10 # generate a frei0r partik0l source with size 200x200 and framerate 10
# which is overlayed on the overlay filter main input # which is overlayed on the overlay filter main input
frei0r_src=200x200:10:partik0l=1234 [overlay]; [in][overlay] overlay frei0r_src=size=200x200:framerate=10:filter_name=partik0l:filter_params=1234 [overlay]; [in][overlay] overlay
@end example @end example
@section rgbtestsrc, testsrc @section rgbtestsrc, testsrc

View File

@ -487,19 +487,36 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque
if (ret < 0) if (ret < 0)
goto fail; goto fail;
#if FF_API_OLD_FILTER_OPTS #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_src")) {
/* a hack for compatibility with the old syntax /* a hack for compatibility with the old syntax
* replace colons with |s */ * replace colons with |s */
char *copy = av_strdup(args); char *copy = av_strdup(args);
char *p = copy; char *p = copy;
int nb_leading = 0; // number of leading colons to skip
if (!copy) { if (!copy) {
ret = AVERROR(ENOMEM); ret = AVERROR(ENOMEM);
goto fail; goto fail;
} }
if (strchr(copy, ':')) { if (!strcmp(filter->filter->name, "frei0r"))
nb_leading = 1;
else if (!strcmp(filter->filter->name, "frei0r_src"))
nb_leading = 3;
while (nb_leading--) {
p = strchr(p, ':');
if (!p) {
p = copy + strlen(copy);
break;
}
p++;
}
if (strchr(p, ':')) {
av_log(filter, AV_LOG_WARNING, "This syntax is deprecated. Use " av_log(filter, AV_LOG_WARNING, "This syntax is deprecated. Use "
"'|' to separate the list items.\n"); "'|' to separate the list items.\n");
} }

View File

@ -35,6 +35,7 @@
#include "libavutil/internal.h" #include "libavutil/internal.h"
#include "libavutil/mathematics.h" #include "libavutil/mathematics.h"
#include "libavutil/mem.h" #include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "libavutil/parseutils.h" #include "libavutil/parseutils.h"
#include "avfilter.h" #include "avfilter.h"
#include "formats.h" #include "formats.h"
@ -53,6 +54,7 @@ typedef void (*f0r_set_param_value_f)(f0r_instance_t instance, f0r_param_t param
typedef void (*f0r_get_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index); typedef void (*f0r_get_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index);
typedef struct Frei0rContext { typedef struct Frei0rContext {
const AVClass *class;
f0r_update_f update; f0r_update_f update;
void *dl_handle; /* dynamic library handle */ void *dl_handle; /* dynamic library handle */
f0r_instance_t instance; f0r_instance_t instance;
@ -64,7 +66,11 @@ typedef struct Frei0rContext {
f0r_construct_f construct; f0r_construct_f construct;
f0r_destruct_f destruct; f0r_destruct_f destruct;
f0r_deinit_f deinit; f0r_deinit_f deinit;
char params[256];
char *dl_name;
char *params;
char *size;
char *framerate;
/* only used by the source */ /* only used by the source */
int w, h; int w, h;
@ -143,7 +149,7 @@ static int set_params(AVFilterContext *ctx, const char *params)
frei0r->get_param_info(&info, i); frei0r->get_param_info(&info, i);
if (*params) { if (*params) {
if (!(param = av_get_token(&params, ":"))) if (!(param = av_get_token(&params, "|")))
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
params++; /* skip ':' */ params++; /* skip ':' */
ret = set_param(ctx, info, i, param); ret = set_param(ctx, info, i, param);
@ -222,6 +228,11 @@ static av_cold int frei0r_init(AVFilterContext *ctx,
f0r_plugin_info_t *pi; f0r_plugin_info_t *pi;
char *path; char *path;
if (!dl_name) {
av_log(ctx, AV_LOG_ERROR, "No filter name provided.\n");
return AVERROR(EINVAL);
}
/* see: http://piksel.org/frei0r/1.2/spec/1.2/spec/group__pluglocations.html */ /* see: http://piksel.org/frei0r/1.2/spec/1.2/spec/group__pluglocations.html */
if ((path = av_strdup(getenv("FREI0R_PATH")))) { if ((path = av_strdup(getenv("FREI0R_PATH")))) {
char *p, *ptr = NULL; char *p, *ptr = NULL;
@ -287,13 +298,8 @@ static av_cold int frei0r_init(AVFilterContext *ctx,
static av_cold int filter_init(AVFilterContext *ctx, const char *args) static av_cold int filter_init(AVFilterContext *ctx, const char *args)
{ {
Frei0rContext *frei0r = ctx->priv; Frei0rContext *frei0r = ctx->priv;
char dl_name[1024], c;
*frei0r->params = 0;
if (args) return frei0r_init(ctx, frei0r->dl_name, F0R_PLUGIN_TYPE_FILTER);
sscanf(args, "%1023[^:=]%c%255c", dl_name, &c, frei0r->params);
return frei0r_init(ctx, dl_name, F0R_PLUGIN_TYPE_FILTER);
} }
static av_cold void uninit(AVFilterContext *ctx) static av_cold void uninit(AVFilterContext *ctx)
@ -306,8 +312,6 @@ static av_cold void uninit(AVFilterContext *ctx)
frei0r->deinit(); frei0r->deinit();
if (frei0r->dl_handle) if (frei0r->dl_handle)
dlclose(frei0r->dl_handle); dlclose(frei0r->dl_handle);
memset(frei0r, 0, sizeof(*frei0r));
} }
static int config_input_props(AVFilterLink *inlink) static int config_input_props(AVFilterLink *inlink)
@ -368,6 +372,21 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
return ff_filter_frame(outlink, out); return ff_filter_frame(outlink, out);
} }
#define OFFSET(x) offsetof(Frei0rContext, x)
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM
static const AVOption filter_options[] = {
{ "filter_name", NULL, OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS },
{ "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS },
{ NULL },
};
static const AVClass filter_class = {
.class_name = "frei0r",
.item_name = av_default_item_name,
.option = filter_options,
.version = LIBAVUTIL_VERSION_INT,
};
static const AVFilterPad avfilter_vf_frei0r_inputs[] = { static const AVFilterPad avfilter_vf_frei0r_inputs[] = {
{ {
.name = "default", .name = "default",
@ -395,6 +414,7 @@ AVFilter avfilter_vf_frei0r = {
.uninit = uninit, .uninit = uninit,
.priv_size = sizeof(Frei0rContext), .priv_size = sizeof(Frei0rContext),
.priv_class = &filter_class,
.inputs = avfilter_vf_frei0r_inputs, .inputs = avfilter_vf_frei0r_inputs,
@ -404,31 +424,22 @@ AVFilter avfilter_vf_frei0r = {
static av_cold int source_init(AVFilterContext *ctx, const char *args) static av_cold int source_init(AVFilterContext *ctx, const char *args)
{ {
Frei0rContext *frei0r = ctx->priv; Frei0rContext *frei0r = ctx->priv;
char dl_name[1024], c;
char frame_size[128] = "";
char frame_rate[128] = "";
AVRational frame_rate_q; AVRational frame_rate_q;
memset(frei0r->params, 0, sizeof(frei0r->params)); if (av_parse_video_size(&frei0r->w, &frei0r->h, frei0r->size) < 0) {
av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", frei0r->size);
if (args)
sscanf(args, "%127[^:]:%127[^:]:%1023[^:=]%c%255c",
frame_size, frame_rate, dl_name, &c, frei0r->params);
if (av_parse_video_size(&frei0r->w, &frei0r->h, frame_size) < 0) {
av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", frame_size);
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
if (av_parse_video_rate(&frame_rate_q, frame_rate) < 0 || if (av_parse_video_rate(&frame_rate_q, frei0r->framerate) < 0 ||
frame_rate_q.den <= 0 || frame_rate_q.num <= 0) { frame_rate_q.den <= 0 || frame_rate_q.num <= 0) {
av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", frame_rate); av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", frei0r->framerate);
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
frei0r->time_base.num = frame_rate_q.den; frei0r->time_base.num = frame_rate_q.den;
frei0r->time_base.den = frame_rate_q.num; frei0r->time_base.den = frame_rate_q.num;
return frei0r_init(ctx, dl_name, F0R_PLUGIN_TYPE_SOURCE); return frei0r_init(ctx, frei0r->dl_name, F0R_PLUGIN_TYPE_SOURCE);
} }
static int source_config_props(AVFilterLink *outlink) static int source_config_props(AVFilterLink *outlink)
@ -467,6 +478,21 @@ static int source_request_frame(AVFilterLink *outlink)
return ff_filter_frame(outlink, frame); return ff_filter_frame(outlink, frame);
} }
static const AVOption src_options[] = {
{ "size", "Dimensions of the generated video.", OFFSET(size), AV_OPT_TYPE_STRING, { .str = "" }, .flags = FLAGS },
{ "framerate", NULL, OFFSET(framerate), AV_OPT_TYPE_STRING, { .str = "25" }, .flags = FLAGS },
{ "filter_name", NULL, OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS },
{ "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS },
{ NULL },
};
static const AVClass src_class = {
.class_name = "frei0r_src",
.item_name = av_default_item_name,
.option = src_options,
.version = LIBAVUTIL_VERSION_INT,
};
static const AVFilterPad avfilter_vsrc_frei0r_src_outputs[] = { static const AVFilterPad avfilter_vsrc_frei0r_src_outputs[] = {
{ {
.name = "default", .name = "default",
@ -482,6 +508,7 @@ AVFilter avfilter_vsrc_frei0r_src = {
.description = NULL_IF_CONFIG_SMALL("Generate a frei0r source."), .description = NULL_IF_CONFIG_SMALL("Generate a frei0r source."),
.priv_size = sizeof(Frei0rContext), .priv_size = sizeof(Frei0rContext),
.priv_class = &src_class,
.init = source_init, .init = source_init,
.uninit = uninit, .uninit = uninit,