| @@ -35,6 +35,7 @@ · 34 unmodified lines |
| 35 | #include "libavutil/internal.h" | 35 | #include "libavutil/internal.h" |
| 36 | #include "libavutil/mathematics.h" | 36 | #include "libavutil/mathematics.h" |
| 37 | #include "libavutil/mem.h" | 37 | #include "libavutil/mem.h" |
| | 38 | #include "libavutil/opt.h" |
| 38 | #include "libavutil/parseutils.h" | 39 | #include "libavutil/parseutils.h" |
| 39 | #include "avfilter.h" | 40 | #include "avfilter.h" |
| 40 | #include "formats.h" | 41 | #include "formats.h" |
| @@ -53,6 +54,7 @@ typedef void (*f0r_set_param_value_f)(f0r_instance_t instance, f0r_param_t param · 12 unmodified lines |
| 53 | typedef void (*f0r_get_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index); | 54 | typedef void (*f0r_get_param_value_f)(f0r_instance_t instance, f0r_param_t param, int param_index); |
| 54 | | 55 | |
| 55 | typedef struct Frei0rContext { | 56 | typedef struct Frei0rContext { |
| | 57 | const AVClass *class; |
| 56 | f0r_update_f update; | 58 | f0r_update_f update; |
| 57 | void *dl_handle; /* dynamic library handle */ | 59 | void *dl_handle; /* dynamic library handle */ |
| 58 | f0r_instance_t instance; | 60 | f0r_instance_t instance; |
| @@ -64,7 +66,11 @@ typedef struct Frei0rContext { · 5 unmodified lines |
| 64 | f0r_construct_f construct; | 66 | f0r_construct_f construct; |
| 65 | f0r_destruct_f destruct; | 67 | f0r_destruct_f destruct; |
| 66 | f0r_deinit_f deinit; | 68 | f0r_deinit_f deinit; |
| 67 | char params[256]; | 69 | |
| | 70 | char *dl_name; |
| | 71 | char *params; |
| | 72 | char *size; |
| | 73 | char *framerate; |
| 68 | | 74 | |
| 69 | /* only used by the source */ | 75 | /* only used by the source */ |
| 70 | int w, h; | 76 | int w, h; |
| @@ -143,7 +149,7 @@ static int set_params(AVFilterContext *ctx, const char *params) · 72 unmodified lines |
| 143 | frei0r->get_param_info(&info, i); | 149 | frei0r->get_param_info(&info, i); |
| 144 | | 150 | |
| 145 | if (*params) { | 151 | if (*params) { |
| 146 | if (!(param = av_get_token(¶ms, ":"))) | 152 | if (!(param = av_get_token(¶ms, "|"))) |
| 147 | return AVERROR(ENOMEM); | 153 | return AVERROR(ENOMEM); |
| 148 | params++; /* skip ':' */ | 154 | params++; /* skip ':' */ |
| 149 | ret = set_param(ctx, info, i, param); | 155 | ret = set_param(ctx, info, i, param); |
| @@ -222,6 +228,11 @@ static av_cold int frei0r_init(AVFilterContext *ctx, · 72 unmodified lines |
| 222 | f0r_plugin_info_t *pi; | 228 | f0r_plugin_info_t *pi; |
| 223 | char *path; | 229 | char *path; |
| 224 | | 230 | |
| | 231 | if (!dl_name) { |
| | 232 | av_log(ctx, AV_LOG_ERROR, "No filter name provided.\n"); |
| | 233 | return AVERROR(EINVAL); |
| | 234 | } |
| | 235 | |
| 225 | /* see: http://piksel.org/frei0r/1.2/spec/1.2/spec/group__pluglocations.html */ | 236 | /* see: http://piksel.org/frei0r/1.2/spec/1.2/spec/group__pluglocations.html */ |
| 226 | if ((path = av_strdup(getenv("FREI0R_PATH")))) { | 237 | if ((path = av_strdup(getenv("FREI0R_PATH")))) { |
| 227 | char *p, *ptr = NULL; | 238 | char *p, *ptr = NULL; |
| @@ -287,13 +298,8 @@ static av_cold int frei0r_init(AVFilterContext *ctx, · 59 unmodified lines |
| 287 | static av_cold int filter_init(AVFilterContext *ctx, const char *args) | 298 | static av_cold int filter_init(AVFilterContext *ctx, const char *args) |
| 288 | { | 299 | { |
| 289 | Frei0rContext *frei0r = ctx->priv; | 300 | Frei0rContext *frei0r = ctx->priv; |
| 290 | char dl_name[1024], c; | | |
| 291 | *frei0r->params = 0; | | |
| 292 | | 301 | |
| 293 | if (args) | 302 | return frei0r_init(ctx, frei0r->dl_name, F0R_PLUGIN_TYPE_FILTER); |
| 294 | sscanf(args, "%1023[^:=]%c%255c", dl_name, &c, frei0r->params); | | |
| 295 | | | |
| 296 | return frei0r_init(ctx, dl_name, F0R_PLUGIN_TYPE_FILTER); | | |
| 297 | } | 303 | } |
| 298 | | 304 | |
| 299 | static av_cold void uninit(AVFilterContext *ctx) | 305 | static av_cold void uninit(AVFilterContext *ctx) |
| @@ -306,8 +312,6 @@ static av_cold void uninit(AVFilterContext *ctx) · 6 unmodified lines |
| 306 | frei0r->deinit(); | 312 | frei0r->deinit(); |
| 307 | if (frei0r->dl_handle) | 313 | if (frei0r->dl_handle) |
| 308 | dlclose(frei0r->dl_handle); | 314 | dlclose(frei0r->dl_handle); |
| 309 | | | |
| 310 | memset(frei0r, 0, sizeof(*frei0r)); | | |
| 311 | } | 315 | } |
| 312 | | 316 | |
| 313 | static int config_input_props(AVFilterLink *inlink) | 317 | static int config_input_props(AVFilterLink *inlink) |
| @@ -368,6 +372,21 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 54 unmodified lines |
| 368 | return ff_filter_frame(outlink, out); | 372 | return ff_filter_frame(outlink, out); |
| 369 | } | 373 | } |
| 370 | | 374 | |
| | 375 | #define OFFSET(x) offsetof(Frei0rContext, x) |
| | 376 | #define FLAGS AV_OPT_FLAG_VIDEO_PARAM |
| | 377 | static const AVOption filter_options[] = { |
| | 378 | { "filter_name", NULL, OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS }, |
| | 379 | { "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS }, |
| | 380 | { NULL }, |
| | 381 | }; |
| | 382 | |
| | 383 | static const AVClass filter_class = { |
| | 384 | .class_name = "frei0r", |
| | 385 | .item_name = av_default_item_name, |
| | 386 | .option = filter_options, |
| | 387 | .version = LIBAVUTIL_VERSION_INT, |
| | 388 | }; |
| | 389 | |
| 371 | static const AVFilterPad avfilter_vf_frei0r_inputs[] = { | 390 | static const AVFilterPad avfilter_vf_frei0r_inputs[] = { |
| 372 | { | 391 | { |
| 373 | .name = "default", | 392 | .name = "default", |
| @@ -395,6 +414,7 @@ AVFilter avfilter_vf_frei0r = { · 21 unmodified lines |
| 395 | .uninit = uninit, | 414 | .uninit = uninit, |
| 396 | | 415 | |
| 397 | .priv_size = sizeof(Frei0rContext), | 416 | .priv_size = sizeof(Frei0rContext), |
| | 417 | .priv_class = &filter_class, |
| 398 | | 418 | |
| 399 | .inputs = avfilter_vf_frei0r_inputs, | 419 | .inputs = avfilter_vf_frei0r_inputs, |
| 400 | | 420 | |
| @@ -404,31 +424,22 @@ AVFilter avfilter_vf_frei0r = { · 3 unmodified lines |
| 404 | static av_cold int source_init(AVFilterContext *ctx, const char *args) | 424 | static av_cold int source_init(AVFilterContext *ctx, const char *args) |
| 405 | { | 425 | { |
| 406 | Frei0rContext *frei0r = ctx->priv; | 426 | Frei0rContext *frei0r = ctx->priv; |
| 407 | char dl_name[1024], c; | | |
| 408 | char frame_size[128] = ""; | | |
| 409 | char frame_rate[128] = ""; | | |
| 410 | AVRational frame_rate_q; | 427 | AVRational frame_rate_q; |
| 411 | | 428 | |
| 412 | memset(frei0r->params, 0, sizeof(frei0r->params)); | 429 | if (av_parse_video_size(&frei0r->w, &frei0r->h, frei0r->size) < 0) { |
| 413 | | 430 | av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", frei0r->size); |
| 414 | if (args) | | |
| 415 | sscanf(args, "%127[^:]:%127[^:]:%1023[^:=]%c%255c", | | |
| 416 | frame_size, frame_rate, dl_name, &c, frei0r->params); | | |
| 417 | | | |
| 418 | if (av_parse_video_size(&frei0r->w, &frei0r->h, frame_size) < 0) { | | |
| 419 | av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", frame_size); | | |
| 420 | return AVERROR(EINVAL); | 431 | return AVERROR(EINVAL); |
| 421 | } | 432 | } |
| 422 | | 433 | |
| 423 | if (av_parse_video_rate(&frame_rate_q, frame_rate) < 0 || | 434 | if (av_parse_video_rate(&frame_rate_q, frei0r->framerate) < 0 || |
| 424 | frame_rate_q.den <= 0 || frame_rate_q.num <= 0) { | 435 | frame_rate_q.den <= 0 || frame_rate_q.num <= 0) { |
| 425 | av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", frame_rate); | 436 | av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", frei0r->framerate); |
| 426 | return AVERROR(EINVAL); | 437 | return AVERROR(EINVAL); |
| 427 | } | 438 | } |
| 428 | frei0r->time_base.num = frame_rate_q.den; | 439 | frei0r->time_base.num = frame_rate_q.den; |
| 429 | frei0r->time_base.den = frame_rate_q.num; | 440 | frei0r->time_base.den = frame_rate_q.num; |
| 430 | | 441 | |
| 431 | return frei0r_init(ctx, dl_name, F0R_PLUGIN_TYPE_SOURCE); | 442 | return frei0r_init(ctx, frei0r->dl_name, F0R_PLUGIN_TYPE_SOURCE); |
| 432 | } | 443 | } |
| 433 | | 444 | |
| 434 | static int source_config_props(AVFilterLink *outlink) | 445 | static int source_config_props(AVFilterLink *outlink) |
| @@ -467,6 +478,21 @@ static int source_request_frame(AVFilterLink *outlink) · 32 unmodified lines |
| 467 | return ff_filter_frame(outlink, frame); | 478 | return ff_filter_frame(outlink, frame); |
| 468 | } | 479 | } |
| 469 | | 480 | |
| | 481 | static const AVOption src_options[] = { |
| | 482 | { "size", "Dimensions of the generated video.", OFFSET(size), AV_OPT_TYPE_STRING, { .str = "" }, .flags = FLAGS }, |
| | 483 | { "framerate", NULL, OFFSET(framerate), AV_OPT_TYPE_STRING, { .str = "25" }, .flags = FLAGS }, |
| | 484 | { "filter_name", NULL, OFFSET(dl_name), AV_OPT_TYPE_STRING, .flags = FLAGS }, |
| | 485 | { "filter_params", NULL, OFFSET(params), AV_OPT_TYPE_STRING, .flags = FLAGS }, |
| | 486 | { NULL }, |
| | 487 | }; |
| | 488 | |
| | 489 | static const AVClass src_class = { |
| | 490 | .class_name = "frei0r_src", |
| | 491 | .item_name = av_default_item_name, |
| | 492 | .option = src_options, |
| | 493 | .version = LIBAVUTIL_VERSION_INT, |
| | 494 | }; |
| | 495 | |
| 470 | static const AVFilterPad avfilter_vsrc_frei0r_src_outputs[] = { | 496 | static const AVFilterPad avfilter_vsrc_frei0r_src_outputs[] = { |
| 471 | { | 497 | { |
| 472 | .name = "default", | 498 | .name = "default", |
| @@ -482,6 +508,7 @@ AVFilter avfilter_vsrc_frei0r_src = { · 9 unmodified lines |
| 482 | .description = NULL_IF_CONFIG_SMALL("Generate a frei0r source."), | 508 | .description = NULL_IF_CONFIG_SMALL("Generate a frei0r source."), |
| 483 | | 509 | |
| 484 | .priv_size = sizeof(Frei0rContext), | 510 | .priv_size = sizeof(Frei0rContext), |
| | 511 | .priv_class = &src_class, |
| 485 | .init = source_init, | 512 | .init = source_init, |
| 486 | .uninit = uninit, | 513 | .uninit = uninit, |
| 487 | | 514 | |