From 13c506918729c8a75d1012ba485fe25755c8221a Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 20 Jun 2012 01:54:58 +0000 Subject: [PATCH] lavfi: add smptebars source Patch readapted by Stefano Sabatini, color values proposed by Tim Nicholson . Address trac ticket #1462. See thread: Subject: [FFmpeg-devel] [PATCH] smptebars filter Date: Wed, 20 Jun 2012 01:54:58 +0000 Signed-off-by: Paul B Mahol Signed-off-by: Stefano Sabatini --- Changelog | 1 + doc/filters.texi | 5 +- libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 4 +- libavfilter/vsrc_testsrc.c | 131 +++++++++++++++++++++++++++++++++++++ 6 files changed, 140 insertions(+), 3 deletions(-) diff --git a/Changelog b/Changelog index ce0d53c4e8..fd8e175e80 100644 --- a/Changelog +++ b/Changelog @@ -42,6 +42,7 @@ version next: - bitmap subtitles in filters (experimental and temporary) - MP2 encoding via TwoLAME - bmp parser +- smptebars source version 0.11: diff --git a/doc/filters.texi b/doc/filters.texi index c712f50ea6..e73fc09431 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -3918,7 +3918,7 @@ ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_c @end example @end itemize -@section color, nullsrc, rgbtestsrc, testsrc +@section color, nullsrc, rgbtestsrc, smptebars, testsrc The @code{color} source provides an uniformly colored input. @@ -3930,6 +3930,9 @@ The @code{rgbtestsrc} source generates an RGB test pattern useful for detecting RGB vs BGR issues. You should see a red, green and blue stripe from top to bottom. +The @code{smptebars} source generates a color bars pattern, based on +the SMPTE Engineering Guideline EG 1-1990. + The @code{testsrc} source generates a test video pattern, showing a color pattern, a scrolling gradient and a timestamp. This is mainly intended for testing purposes. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 727ab4e219..b6bd37f148 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -139,6 +139,7 @@ OBJS-$(CONFIG_MANDELBROT_FILTER) += vsrc_mandelbrot.o OBJS-$(CONFIG_MPTESTSRC_FILTER) += vsrc_mptestsrc.o OBJS-$(CONFIG_NULLSRC_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_RGBTESTSRC_FILTER) += vsrc_testsrc.o +OBJS-$(CONFIG_SMPTEBARS_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_BUFFERSINK_FILTER) += sink_buffer.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 403383da93..da1c8e62ae 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -129,6 +129,7 @@ void avfilter_register_all(void) REGISTER_FILTER (MPTESTSRC, mptestsrc, vsrc); REGISTER_FILTER (NULLSRC, nullsrc, vsrc); REGISTER_FILTER (RGBTESTSRC, rgbtestsrc, vsrc); + REGISTER_FILTER (SMPTEBARS, smptebars, vsrc); REGISTER_FILTER (TESTSRC, testsrc, vsrc); REGISTER_FILTER (BUFFERSINK, buffersink, vsink); diff --git a/libavfilter/version.h b/libavfilter/version.h index a3230b79b5..60660d8090 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -29,8 +29,8 @@ #include "libavutil/avutil.h" #define LIBAVFILTER_VERSION_MAJOR 3 -#define LIBAVFILTER_VERSION_MINOR 5 -#define LIBAVFILTER_VERSION_MICRO 102 +#define LIBAVFILTER_VERSION_MINOR 6 +#define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/libavfilter/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c index a2124ba3ba..30605789f8 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2007 Nicolas George * Copyright (c) 2011 Stefano Sabatini + * Copyright (c) 2012 Paul B Mahol * * This file is part of FFmpeg. * @@ -28,6 +29,8 @@ * * rgbtestsrc is ported from MPlayer libmpcodecs/vf_rgbtest.c by * Michael Niedermayer. + * + * smptebars is by Paul B Mahol. */ #include @@ -646,3 +649,131 @@ AVFilter avfilter_vsrc_rgbtestsrc = { }; #endif /* CONFIG_RGBTESTSRC_FILTER */ + +#if CONFIG_SMPTEBARS_FILTER + +#define smptebars_options options +AVFILTER_DEFINE_CLASS(smptebars); + +static const uint8_t rainbow[7][4] = { + { 191, 191, 191, 255 }, /* gray */ + { 191, 191, 0, 255 }, /* yellow */ + { 0, 191, 191, 255 }, /* cyan */ + { 0, 191, 0, 255 }, /* green */ + { 191, 0, 191, 255 }, /* magenta */ + { 191, 0, 0, 255 }, /* red */ + { 0, 0, 191, 255 }, /* blue */ +}; + +static const uint8_t wobnair[7][4] = { + { 0, 0, 191, 255 }, /* blue */ + { 19, 19, 19, 255 }, /* 7.5% intensity black */ + { 191, 0, 191, 255 }, /* magenta */ + { 19, 19, 19, 255 }, /* 7.5% intensity black */ + { 0, 191, 191, 255 }, /* cyan */ + { 19, 19, 19, 255 }, /* 7.5% intensity black */ + { 191, 191, 191, 255 }, /* gray */ +}; + +static const uint8_t white[4] = { 255, 255, 255, 255 }; +static const uint8_t black[4] = { 19, 19, 19, 255 }; /* 7.5% intensity black */ + +/* pluge pulses */ +static const uint8_t neg4ire[4] = { 9, 9, 9, 255 }; /* 3.5% intensity black */ +static const uint8_t pos4ire[4] = { 29, 29, 29, 255 }; /* 11.5% intensity black */ + +/* fudged Q/-I */ +static const uint8_t i_pixel[4] = { 0, 68, 130, 255 }; +static const uint8_t q_pixel[4] = { 67, 0, 130, 255 }; + +static void smptebars_fill_picture(AVFilterContext *ctx, AVFilterBufferRef *picref) +{ + TestSourceContext *test = ctx->priv; + FFDrawColor color; + int r_w, r_h, w_h, p_w, p_h, i, x = 0; + + r_w = (test->w + 6) / 7; + r_h = test->h * 2 / 3; + w_h = test->h * 3 / 4 - r_h; + p_w = r_w * 5 / 4; + p_h = test->h - w_h - r_h; + +#define DRAW_COLOR(rgba, x, y, w, h) \ + ff_draw_color(&test->draw, &color, rgba); \ + ff_fill_rectangle(&test->draw, &color, \ + picref->data, picref->linesize, x, y, w, h) \ + + for (i = 0; i < 7; i++) { + DRAW_COLOR(rainbow[i], x, 0, FFMIN(r_w, test->w - x), r_h); + DRAW_COLOR(wobnair[i], x, r_h, FFMIN(r_w, test->w - x), w_h); + x += r_w; + } + x = 0; + DRAW_COLOR(i_pixel, x, r_h + w_h, p_w, p_h); + x += p_w; + DRAW_COLOR(white, x, r_h + w_h, p_w, p_h); + x += p_w; + DRAW_COLOR(q_pixel, x, r_h + w_h, p_w, p_h); + x += p_w; + DRAW_COLOR(black, x, r_h + w_h, 5 * r_w - x, p_h); + x += 5 * r_w - x; + DRAW_COLOR(neg4ire, x, r_h + w_h, r_w / 3, p_h); + x += r_w / 3; + DRAW_COLOR(black, x, r_h + w_h, r_w / 3, p_h); + x += r_w / 3; + DRAW_COLOR(pos4ire, x, r_h + w_h, r_w / 3, p_h); + x += r_w / 3; + DRAW_COLOR(black, x, r_h + w_h, test->w - x, p_h); +} + +static av_cold int smptebars_init(AVFilterContext *ctx, const char *args) +{ + TestSourceContext *test = ctx->priv; + + test->class = &smptebars_class; + test->fill_picture_fn = smptebars_fill_picture; + test->draw_once = 1; + return init(ctx, args); +} + +static int smptebars_query_formats(AVFilterContext *ctx) +{ + ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); + return 0; +} + +static int smptebars_config_props(AVFilterLink *outlink) +{ + AVFilterContext *ctx = outlink->src; + TestSourceContext *test = ctx->priv; + + ff_draw_init(&test->draw, outlink->format, 0); + + return config_props(outlink); +} + +AVFilter avfilter_vsrc_smptebars = { + .name = "smptebars", + .description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."), + .priv_size = sizeof(TestSourceContext), + .init = smptebars_init, + .uninit = uninit, + + .query_formats = smptebars_query_formats, + + .inputs = (const AVFilterPad[]) { + { .name = NULL } + }, + + .outputs = (const AVFilterPad[]) { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .request_frame = request_frame, + .config_props = smptebars_config_props, + }, + { .name = NULL } + }, +}; + +#endif /* CONFIG_SMPTEBARS_FILTER */