History

Implement frei0r source.

Originally committed as revision 25855 to svn://svn.ffmpeg.org/ffmpeg/trunk

Stefano Sabatini committed 15 years ago

Commit f8608dc1 parent 60445a06 files · +144 −11Browse files

Unified · Split

6 files
  1. Changelog +1 −0
  2. doc/filters.texi +29 −0
  3. libavfilter/Makefile +1 −0
  4. libavfilter/allfilters.c +1 −0
  5. libavfilter/avfilter.h +1 −1
  6. libavfilter/vf_frei0r.c +111 −10
Changelog+1−0
@@ -60,6 +60,7 @@ version <next>: · 59 unmodified lines
60- rename aspect filter to setdar, and pixelaspect to setsar60- rename aspect filter to setdar, and pixelaspect to setsar
61- IEC 61937 demuxer61- IEC 61937 demuxer
62- Mobotix .mxg demuxer62- Mobotix .mxg demuxer
63- frei0r source added
63 64
64 65
65version 0.6:66version 0.6:
doc/filters.texi+29−0
@@ -283,6 +283,7 @@ The following command: · 282 unmodified lines
283 283
284will convert the input video to the format "yuv420p".284will convert the input video to the format "yuv420p".
285 285
286@anchor{frei0r}
286@section frei0r287@section frei0r
287 288
288Apply a frei0r effect to the input video.289Apply a frei0r effect to the input video.
@@ -869,6 +870,34 @@ respectively 352 and 288 (corresponding to the CIF size format). · 580 unmodified lines
869timebase. The expression can contain the constants "PI", "E", "PHI",870timebase. The expression can contain the constants "PI", "E", "PHI",
870"AVTB" (the default timebase), and defaults to the value "AVTB".871"AVTB" (the default timebase), and defaults to the value "AVTB".
871 872
873@section frei0r_src
874
875Provide a frei0r source.
876
877To enable compilation of this filter you need to install the frei0r
878header and configure FFmpeg with --enable-frei0r.
879
880The source supports the syntax:
881@example
882@var{size}:@var{rate}:@var{src_name}[@{=|:@}@var{param1}:@var{param2}:...:@var{paramN}]
883@end example
884
885@var{size} is the size of the video to generate, may be a string of the
886form @var{width}x@var{height} or a frame size abbreviation.
887@var{rate} is the rate of the video to generate, may be a string of
888the form @var{num}/@var{den} or a frame rate abbreviation.
889@var{src_name} is the name to the frei0r source to load. For more
890information regarding frei0r and how to set the parameters read the
891section "frei0r" (@pxref{frei0r}) in the description of the video
892filters.
893
894Some examples follow:
895@example
896# generate a frei0r partik0l source with size 200x200 and framerate 10
897# which is overlayed on the overlay filter main input
898frei0r_src=200x200:10:partik0l=1234 [overlay]; [in][overlay] overlay
899@end example
900
872@c man end VIDEO SOURCES901@c man end VIDEO SOURCES
873 902
874@chapter Video Sinks903@chapter Video Sinks
libavfilter/Makefile+1−0
@@ -46,6 +46,7 @@ OBJS-$(CONFIG_YADIF_FILTER) += vf_yadif.o · 45 unmodified lines
46 46
47OBJS-$(CONFIG_BUFFER_FILTER) += vsrc_buffer.o47OBJS-$(CONFIG_BUFFER_FILTER) += vsrc_buffer.o
48OBJS-$(CONFIG_COLOR_FILTER) += vf_pad.o48OBJS-$(CONFIG_COLOR_FILTER) += vf_pad.o
49OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o
49OBJS-$(CONFIG_NULLSRC_FILTER) += vsrc_nullsrc.o50OBJS-$(CONFIG_NULLSRC_FILTER) += vsrc_nullsrc.o
50 51
51OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o52OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o
libavfilter/allfilters.c+1−0
@@ -67,6 +67,7 @@ void avfilter_register_all(void) · 66 unmodified lines
67 67
68 REGISTER_FILTER (BUFFER, buffer, vsrc);68 REGISTER_FILTER (BUFFER, buffer, vsrc);
69 REGISTER_FILTER (COLOR, color, vsrc);69 REGISTER_FILTER (COLOR, color, vsrc);
70 REGISTER_FILTER (FREI0R, frei0r_src, vsrc);
70 REGISTER_FILTER (NULLSRC, nullsrc, vsrc);71 REGISTER_FILTER (NULLSRC, nullsrc, vsrc);
71 72
72 REGISTER_FILTER (NULLSINK, nullsink, vsink);73 REGISTER_FILTER (NULLSINK, nullsink, vsink);
libavfilter/avfilter.h+1−1
@@ -25,7 +25,7 @@ · 24 unmodified lines
25#include "libavutil/avutil.h"25#include "libavutil/avutil.h"
26 26
27#define LIBAVFILTER_VERSION_MAJOR 127#define LIBAVFILTER_VERSION_MAJOR 1
28#define LIBAVFILTER_VERSION_MINOR 6528#define LIBAVFILTER_VERSION_MINOR 66
29#define LIBAVFILTER_VERSION_MICRO 029#define LIBAVFILTER_VERSION_MICRO 0
30 30
31#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \31#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
libavfilter/vf_frei0r.c+111−10
@@ -27,6 +27,7 @@ · 26 unmodified lines
27#include <dlfcn.h>27#include <dlfcn.h>
28#include <frei0r.h>28#include <frei0r.h>
29#include "libavutil/avstring.h"29#include "libavutil/avstring.h"
30#include "libavcore/imgutils.h"
30#include "libavcore/parseutils.h"31#include "libavcore/parseutils.h"
31#include "avfilter.h"32#include "avfilter.h"
32 33
@@ -54,6 +55,11 @@ typedef struct Frei0rContext { · 21 unmodified lines
54 f0r_destruct_f destruct;55 f0r_destruct_f destruct;
55 f0r_deinit_f deinit;56 f0r_deinit_f deinit;
56 char params[256];57 char params[256];
58
59 /* only used by the source */
60 int w, h;
61 AVRational time_base;
62 uint64_t pts;
57} Frei0rContext;63} Frei0rContext;
58 64
59static void *load_sym(AVFilterContext *ctx, const char *sym_name)65static void *load_sym(AVFilterContext *ctx, const char *sym_name)
@@ -197,18 +203,14 @@ static void *load_path(AVFilterContext *ctx, const char *prefix, const char *nam · 137 unmodified lines
197 return dlopen(path, RTLD_NOW|RTLD_LOCAL);203 return dlopen(path, RTLD_NOW|RTLD_LOCAL);
198}204}
199 205
200static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)206static av_cold int frei0r_init(AVFilterContext *ctx,
207 const char *dl_name, int type)
201{208{
202 Frei0rContext *frei0r = ctx->priv;209 Frei0rContext *frei0r = ctx->priv;
203 f0r_init_f f0r_init;210 f0r_init_f f0r_init;
204 f0r_get_plugin_info_f f0r_get_plugin_info;211 f0r_get_plugin_info_f f0r_get_plugin_info;
205 f0r_plugin_info_t *pi;212 f0r_plugin_info_t *pi;
206 char dl_name[1024], *path;213 char *path;
207
208 *frei0r->params = 0;
209
210 if (args)
211 sscanf(args, "%1023[^:]:%255c", dl_name, frei0r->params);
212 214
213 /* see: http://piksel.org/frei0r/1.2/spec/1.2/spec/group__pluglocations.html */215 /* see: http://piksel.org/frei0r/1.2/spec/1.2/spec/group__pluglocations.html */
214 if ((path = av_strdup(getenv("FREI0R_PATH")))) {216 if ((path = av_strdup(getenv("FREI0R_PATH")))) {
@@ -250,9 +252,10 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) · 35 unmodified lines
250 252
251 f0r_get_plugin_info(&frei0r->plugin_info);253 f0r_get_plugin_info(&frei0r->plugin_info);
252 pi = &frei0r->plugin_info;254 pi = &frei0r->plugin_info;
253 if (pi->plugin_type != F0R_PLUGIN_TYPE_FILTER) {255 if (pi->plugin_type != type) {
254 av_log(ctx, AV_LOG_ERROR,256 av_log(ctx, AV_LOG_ERROR,
255 "Invalid type '%s' for the plugin, a filter plugin was expected\n",257 "Invalid type '%s' for the plugin\n",
258 pi->plugin_type == F0R_PLUGIN_TYPE_FILTER ? "filter" :
256 pi->plugin_type == F0R_PLUGIN_TYPE_SOURCE ? "source" :259 pi->plugin_type == F0R_PLUGIN_TYPE_SOURCE ? "source" :
257 pi->plugin_type == F0R_PLUGIN_TYPE_MIXER2 ? "mixer2" :260 pi->plugin_type == F0R_PLUGIN_TYPE_MIXER2 ? "mixer2" :
258 pi->plugin_type == F0R_PLUGIN_TYPE_MIXER3 ? "mixer3" : "unknown");261 pi->plugin_type == F0R_PLUGIN_TYPE_MIXER3 ? "mixer3" : "unknown");
@@ -271,6 +274,18 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) · 12 unmodified lines
271 return 0;274 return 0;
272}275}
273 276
277static av_cold int filter_init(AVFilterContext *ctx, const char *args, void *opaque)
278{
279 Frei0rContext *frei0r = ctx->priv;
280 char dl_name[1024];
281 *frei0r->params = 0;
282
283 if (args)
284 sscanf(args, "%1023[^:]:%255c", dl_name, frei0r->params);
285
286 return frei0r_init(ctx, dl_name, F0R_PLUGIN_TYPE_FILTER);
287}
288
274static av_cold void uninit(AVFilterContext *ctx)289static av_cold void uninit(AVFilterContext *ctx)
275{290{
276 Frei0rContext *frei0r = ctx->priv;291 Frei0rContext *frei0r = ctx->priv;
@@ -344,7 +359,7 @@ AVFilter avfilter_vf_frei0r = { · 67 unmodified lines
344 .description = NULL_IF_CONFIG_SMALL("Apply a frei0r effect."),359 .description = NULL_IF_CONFIG_SMALL("Apply a frei0r effect."),
345 360
346 .query_formats = query_formats,361 .query_formats = query_formats,
347 .init = init,362 .init = filter_init,
348 .uninit = uninit,363 .uninit = uninit,
349 364
350 .priv_size = sizeof(Frei0rContext),365 .priv_size = sizeof(Frei0rContext),
@@ -361,3 +376,89 @@ AVFilter avfilter_vf_frei0r = { · 10 unmodified lines
361 .type = AVMEDIA_TYPE_VIDEO, },376 .type = AVMEDIA_TYPE_VIDEO, },
362 { .name = NULL}},377 { .name = NULL}},
363};378};
379
380static av_cold int source_init(AVFilterContext *ctx, const char *args, void *opaque)
381{
382 Frei0rContext *frei0r = ctx->priv;
383 char dl_name[1024], c;
384 char frame_size[128] = "";
385 char frame_rate[128] = "";
386 AVRational frame_rate_q;
387
388 memset(frei0r->params, 0, sizeof(frei0r->params));
389
390 if (args)
391 sscanf(args, "%127[^:]:%127[^:]:%1023[^:=]%c%255c",
392 frame_size, frame_rate, dl_name, &c, frei0r->params);
393
394 if (av_parse_video_size(&frei0r->w, &frei0r->h, frame_size) < 0) {
395 av_log(ctx, AV_LOG_ERROR, "Invalid frame size: '%s'\n", frame_size);
396 return AVERROR(EINVAL);
397 }
398
399 if (av_parse_video_rate(&frame_rate_q, frame_rate) < 0 ||
400 frame_rate_q.den <= 0 || frame_rate_q.num <= 0) {
401 av_log(ctx, AV_LOG_ERROR, "Invalid frame rate: '%s'\n", frame_rate);
402 return AVERROR(EINVAL);
403 }
404 frei0r->time_base.num = frame_rate_q.den;
405 frei0r->time_base.den = frame_rate_q.num;
406
407 return frei0r_init(ctx, dl_name, F0R_PLUGIN_TYPE_SOURCE);
408}
409
410static int source_config_props(AVFilterLink *outlink)
411{
412 AVFilterContext *ctx = outlink->src;
413 Frei0rContext *frei0r = ctx->priv;
414
415 if (av_image_check_size(frei0r->w, frei0r->h, 0, ctx) < 0)
416 return AVERROR(EINVAL);
417 outlink->w = frei0r->w;
418 outlink->h = frei0r->h;
419 outlink->time_base = frei0r->time_base;
420
421 if (!(frei0r->instance = frei0r->construct(outlink->w, outlink->h))) {
422 av_log(ctx, AV_LOG_ERROR, "Impossible to load frei0r instance");
423 return AVERROR(EINVAL);
424 }
425
426 return set_params(ctx, frei0r->params);
427}
428
429static int source_request_frame(AVFilterLink *outlink)
430{
431 Frei0rContext *frei0r = outlink->src->priv;
432 AVFilterBufferRef *picref = avfilter_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
433 picref->video->pixel_aspect = (AVRational) {1, 1};
434 picref->pts = frei0r->pts++;
435 picref->pos = -1;
436
437 avfilter_start_frame(outlink, avfilter_ref_buffer(picref, ~0));
438 frei0r->update(frei0r->instance, av_rescale_q(picref->pts, frei0r->time_base, (AVRational){1,1000}),
439 NULL, (uint32_t *)picref->data[0]);
440 avfilter_draw_slice(outlink, 0, outlink->h, 1);
441 avfilter_end_frame(outlink);
442 avfilter_unref_buffer(picref);
443
444 return 0;
445}
446
447AVFilter avfilter_vsrc_frei0r_src = {
448 .name = "frei0r_src",
449 .description = NULL_IF_CONFIG_SMALL("Generate a frei0r source."),
450
451 .priv_size = sizeof(Frei0rContext),
452 .init = source_init,
453 .uninit = uninit,
454
455 .query_formats = query_formats,
456
457 .inputs = (AVFilterPad[]) {{ .name = NULL}},
458
459 .outputs = (AVFilterPad[]) {{ .name = "default",
460 .type = AVMEDIA_TYPE_VIDEO,
461 .request_frame = source_request_frame,
462 .config_props = source_config_props },
463 { .name = NULL}},
464};

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t