Commit 5aa1a668 authored by Anton Khirnov's avatar Anton Khirnov

vf_frei0r: switch to an AVOptions-based system.

parent f13ab299
...@@ -1118,20 +1118,22 @@ Apply a frei0r effect to the input video. ...@@ -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}] @table @option
@end example
@item filter_name
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/}.
@var{filter_name} is the name to the frei0r effect to load. If the @item filter_params
environment variable @env{FREI0R_PATH} is defined, the frei0r effect A '|'-separated list of parameters to pass to 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 @end table
for the frei0r effect.
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. ...@@ -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 ...@@ -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. ...@@ -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}] @table @option
@end example
@item size
The size of the video to generate, may be a string of the form
@var{width}x@var{height} or a frame size abbreviation.
@var{size} is the size of the video to generate, may be a string of the @item framerate
form @var{width}x@var{height} or a frame size abbreviation. Framerate of the generated video, may be a string of the form
@var{rate} is the rate of the video to generate, may be a string of @var{num}/@var{den} or a frame rate abbreviation.
the form @var{num}/@var{den} or a frame rate abbreviation.
@var{src_name} is the name to the frei0r source to load. For more @item filter_name
information regarding frei0r and how to set the parameters read the The name to the frei0r source to load. For more information regarding frei0r and
section @ref{frei0r} in the description of the video filters. 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
......
...@@ -487,19 +487,36 @@ int avfilter_init_filter(AVFilterContext *filter, const char *args, void *opaque ...@@ -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");
} }
......
...@@ -35,6 +35,7 @@ ...@@ -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 ...@@ -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 { ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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 = { ...@@ -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 = { ...@@ -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) ...@@ -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 = { ...@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment