The licence was changed from GPL to LGPL with explicit approval from
the original author.
See thread:
Subject: [FFmpeg-devel] [PATCH] lavfi: add rgbtestsrc source,
ported from MPlayer libmpcodecs
Date: Mon, 11 Jul 2011 16:32:41 +0200
... | ... |
@@ -2045,13 +2045,17 @@ Some examples follow: |
2045 | 2045 |
frei0r_src=200x200:10:partik0l=1234 [overlay]; [in][overlay] overlay |
2046 | 2046 |
@end example |
2047 | 2047 |
|
2048 |
-@section testsrc |
|
2048 |
+@section rgbtestsrc, testsrc |
|
2049 | 2049 |
|
2050 |
-Generate a test video pattern, showing a color pattern, a scrolling |
|
2051 |
-gradient and a timestamp. This is mainly intended for testing |
|
2052 |
-purposes. |
|
2050 |
+The @code{rgbtestsrc} source generates an RGB test pattern useful for |
|
2051 |
+detecting RGB vs BGR issues. You should see a red, green and blue |
|
2052 |
+stripe from top to bottom. |
|
2053 | 2053 |
|
2054 |
-It accepts an optional sequence of @var{key}=@var{value} pairs, |
|
2054 |
+The @code{testsrc} source generates a test video pattern, showing a |
|
2055 |
+color pattern, a scrolling gradient and a timestamp. This is mainly |
|
2056 |
+intended for testing purposes. |
|
2057 |
+ |
|
2058 |
+Both sources accept an optional sequence of @var{key}=@var{value} pairs, |
|
2055 | 2059 |
separated by ":". The description of the accepted options follows. |
2056 | 2060 |
|
2057 | 2061 |
@table @option |
... | ... |
@@ -69,6 +69,7 @@ OBJS-$(CONFIG_COLOR_FILTER) += vsrc_color.o |
69 | 69 |
OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o |
70 | 70 |
OBJS-$(CONFIG_MOVIE_FILTER) += vsrc_movie.o |
71 | 71 |
OBJS-$(CONFIG_NULLSRC_FILTER) += vsrc_nullsrc.o |
72 |
+OBJS-$(CONFIG_RGBTESTSRC_FILTER) += vsrc_testsrc.o |
|
72 | 73 |
OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o |
73 | 74 |
|
74 | 75 |
OBJS-$(CONFIG_BUFFERSINK_FILTER) += vsink_buffer.o |
... | ... |
@@ -85,6 +85,7 @@ void avfilter_register_all(void) |
85 | 85 |
REGISTER_FILTER (FREI0R, frei0r_src, vsrc); |
86 | 86 |
REGISTER_FILTER (MOVIE, movie, vsrc); |
87 | 87 |
REGISTER_FILTER (NULLSRC, nullsrc, vsrc); |
88 |
+ REGISTER_FILTER (RGBTESTSRC, rgbtestsrc, vsrc); |
|
88 | 89 |
REGISTER_FILTER (TESTSRC, testsrc, vsrc); |
89 | 90 |
|
90 | 91 |
REGISTER_FILTER (BUFFER, buffersink, vsink); |
... | ... |
@@ -29,8 +29,8 @@ |
29 | 29 |
#include "libavutil/rational.h" |
30 | 30 |
|
31 | 31 |
#define LIBAVFILTER_VERSION_MAJOR 2 |
32 |
-#define LIBAVFILTER_VERSION_MINOR 25 |
|
33 |
-#define LIBAVFILTER_VERSION_MICRO 1 |
|
32 |
+#define LIBAVFILTER_VERSION_MINOR 26 |
|
33 |
+#define LIBAVFILTER_VERSION_MICRO 0 |
|
34 | 34 |
|
35 | 35 |
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ |
36 | 36 |
LIBAVFILTER_VERSION_MINOR, \ |
... | ... |
@@ -21,13 +21,19 @@ |
21 | 21 |
|
22 | 22 |
/** |
23 | 23 |
* @file |
24 |
- * Based on the test pattern generator demuxer by Nicolas George: |
|
24 |
+ * Misc test sources. |
|
25 |
+ * |
|
26 |
+ * testsrc is based on the test pattern generator demuxer by Nicolas George: |
|
25 | 27 |
* http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/2007-October/037845.html |
28 |
+ * |
|
29 |
+ * rgbtestsrc is ported from MPlayer libmpcodecs/vf_rgbtest.c by |
|
30 |
+ * Michael Niedermayer. |
|
26 | 31 |
*/ |
27 | 32 |
|
28 | 33 |
#include <float.h> |
29 | 34 |
|
30 | 35 |
#include "libavutil/opt.h" |
36 |
+#include "libavutil/intreadwrite.h" |
|
31 | 37 |
#include "libavutil/parseutils.h" |
32 | 38 |
#include "avfilter.h" |
33 | 39 |
|
... | ... |
@@ -41,6 +47,9 @@ typedef struct { |
41 | 41 |
char *rate; ///< video frame rate |
42 | 42 |
char *duration; ///< total duration of the generated video |
43 | 43 |
void (* fill_picture_fn)(AVFilterContext *ctx, AVFilterBufferRef *picref); |
44 |
+ |
|
45 |
+ /* only used by rgbtest */ |
|
46 |
+ int rgba_map[4]; |
|
44 | 47 |
} TestSourceContext; |
45 | 48 |
|
46 | 49 |
#define OFFSET(x) offsetof(TestSourceContext, x) |
... | ... |
@@ -350,3 +359,130 @@ AVFilter avfilter_vsrc_testsrc = { |
350 | 350 |
}; |
351 | 351 |
|
352 | 352 |
#endif /* CONFIG_TESTSRC_FILTER */ |
353 |
+ |
|
354 |
+#if CONFIG_RGBTESTSRC_FILTER |
|
355 |
+ |
|
356 |
+static const char *rgbtestsrc_get_name(void *ctx) |
|
357 |
+{ |
|
358 |
+ return "rgbtestsrc"; |
|
359 |
+} |
|
360 |
+ |
|
361 |
+static const AVClass rgbtestsrc_class = { |
|
362 |
+ "RGBTestSourceContext", |
|
363 |
+ rgbtestsrc_get_name, |
|
364 |
+ testsrc_options |
|
365 |
+}; |
|
366 |
+ |
|
367 |
+#define R 0 |
|
368 |
+#define G 1 |
|
369 |
+#define B 2 |
|
370 |
+#define A 3 |
|
371 |
+ |
|
372 |
+static void rgbtest_put_pixel(uint8_t *dst, int dst_linesize, |
|
373 |
+ int x, int y, int r, int g, int b, enum PixelFormat fmt, |
|
374 |
+ int rgba_map[4]) |
|
375 |
+{ |
|
376 |
+ int32_t v; |
|
377 |
+ uint8_t *p; |
|
378 |
+ |
|
379 |
+ switch (fmt) { |
|
380 |
+ case PIX_FMT_BGR444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r >> 4) << 8) | ((g >> 4) << 4) | (b >> 4); break; |
|
381 |
+ case PIX_FMT_RGB444: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b >> 4) << 8) | ((g >> 4) << 4) | (r >> 4); break; |
|
382 |
+ case PIX_FMT_BGR555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<10) | ((g>>3)<<5) | (b>>3); break; |
|
383 |
+ case PIX_FMT_RGB555: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<10) | ((g>>3)<<5) | (r>>3); break; |
|
384 |
+ case PIX_FMT_BGR565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((r>>3)<<11) | ((g>>2)<<5) | (b>>3); break; |
|
385 |
+ case PIX_FMT_RGB565: ((uint16_t*)(dst + y*dst_linesize))[x] = ((b>>3)<<11) | ((g>>2)<<5) | (r>>3); break; |
|
386 |
+ case PIX_FMT_RGB24: |
|
387 |
+ case PIX_FMT_BGR24: |
|
388 |
+ v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8)); |
|
389 |
+ p = dst + 3*x + y*dst_linesize; |
|
390 |
+ AV_WL24(p, v); |
|
391 |
+ break; |
|
392 |
+ case PIX_FMT_RGBA: |
|
393 |
+ case PIX_FMT_BGRA: |
|
394 |
+ case PIX_FMT_ARGB: |
|
395 |
+ case PIX_FMT_ABGR: |
|
396 |
+ v = (r << (rgba_map[R]*8)) + (g << (rgba_map[G]*8)) + (b << (rgba_map[B]*8)); |
|
397 |
+ p = dst + 4*x + y*dst_linesize; |
|
398 |
+ AV_WL32(p, v); |
|
399 |
+ break; |
|
400 |
+ } |
|
401 |
+} |
|
402 |
+ |
|
403 |
+static void rgbtest_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref) |
|
404 |
+{ |
|
405 |
+ TestSourceContext *test = ctx->priv; |
|
406 |
+ int x, y, w = picref->video->w, h = picref->video->h; |
|
407 |
+ |
|
408 |
+ for (y = 0; y < h; y++) { |
|
409 |
+ for (x = 0; x < picref->video->w; x++) { |
|
410 |
+ int c = 256*x/w; |
|
411 |
+ int r = 0, g = 0, b = 0; |
|
412 |
+ |
|
413 |
+ if (3*y < h ) r = c; |
|
414 |
+ else if (3*y < 2*h) g = c; |
|
415 |
+ else b = c; |
|
416 |
+ |
|
417 |
+ rgbtest_put_pixel(picref->data[0], picref->linesize[0], x, y, r, g, b, |
|
418 |
+ ctx->outputs[0]->format, test->rgba_map); |
|
419 |
+ } |
|
420 |
+ } |
|
421 |
+} |
|
422 |
+ |
|
423 |
+static av_cold int rgbtest_init(AVFilterContext *ctx, const char *args, void *opaque) |
|
424 |
+{ |
|
425 |
+ TestSourceContext *test = ctx->priv; |
|
426 |
+ |
|
427 |
+ test->class = &rgbtestsrc_class; |
|
428 |
+ test->fill_picture_fn = rgbtest_fill_picture; |
|
429 |
+ return init(ctx, args, opaque); |
|
430 |
+} |
|
431 |
+ |
|
432 |
+static int rgbtest_query_formats(AVFilterContext *ctx) |
|
433 |
+{ |
|
434 |
+ static const enum PixelFormat pix_fmts[] = { |
|
435 |
+ PIX_FMT_RGBA, PIX_FMT_ARGB, PIX_FMT_BGRA, PIX_FMT_ABGR, |
|
436 |
+ PIX_FMT_BGR24, PIX_FMT_RGB24, |
|
437 |
+ PIX_FMT_RGB444, PIX_FMT_BGR444, |
|
438 |
+ PIX_FMT_RGB565, PIX_FMT_BGR565, |
|
439 |
+ PIX_FMT_RGB555, PIX_FMT_BGR555, |
|
440 |
+ PIX_FMT_NONE |
|
441 |
+ }; |
|
442 |
+ avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); |
|
443 |
+ return 0; |
|
444 |
+} |
|
445 |
+ |
|
446 |
+static int rgbtest_config_props(AVFilterLink *outlink) |
|
447 |
+{ |
|
448 |
+ TestSourceContext *test = outlink->src->priv; |
|
449 |
+ |
|
450 |
+ switch (outlink->format) { |
|
451 |
+ case PIX_FMT_ARGB: test->rgba_map[A] = 0; test->rgba_map[R] = 1; test->rgba_map[G] = 2; test->rgba_map[B] = 3; break; |
|
452 |
+ case PIX_FMT_ABGR: test->rgba_map[A] = 0; test->rgba_map[B] = 1; test->rgba_map[G] = 2; test->rgba_map[R] = 3; break; |
|
453 |
+ case PIX_FMT_RGBA: |
|
454 |
+ case PIX_FMT_RGB24: test->rgba_map[R] = 0; test->rgba_map[G] = 1; test->rgba_map[B] = 2; test->rgba_map[A] = 3; break; |
|
455 |
+ case PIX_FMT_BGRA: |
|
456 |
+ case PIX_FMT_BGR24: test->rgba_map[B] = 0; test->rgba_map[G] = 1; test->rgba_map[R] = 2; test->rgba_map[A] = 3; break; |
|
457 |
+ } |
|
458 |
+ |
|
459 |
+ return config_props(outlink); |
|
460 |
+} |
|
461 |
+ |
|
462 |
+AVFilter avfilter_vsrc_rgbtestsrc = { |
|
463 |
+ .name = "rgbtestsrc", |
|
464 |
+ .description = NULL_IF_CONFIG_SMALL("Generate RGB test pattern."), |
|
465 |
+ .priv_size = sizeof(TestSourceContext), |
|
466 |
+ .init = rgbtest_init, |
|
467 |
+ |
|
468 |
+ .query_formats = rgbtest_query_formats, |
|
469 |
+ |
|
470 |
+ .inputs = (AVFilterPad[]) {{ .name = NULL}}, |
|
471 |
+ |
|
472 |
+ .outputs = (AVFilterPad[]) {{ .name = "default", |
|
473 |
+ .type = AVMEDIA_TYPE_VIDEO, |
|
474 |
+ .request_frame = request_frame, |
|
475 |
+ .config_props = rgbtest_config_props, }, |
|
476 |
+ { .name = NULL }}, |
|
477 |
+}; |
|
478 |
+ |
|
479 |
+#endif /* CONFIG_RGBTESTSRC_FILTER */ |