From 03e2ec32b88f410f90e696ec9ab3b744cc43de13 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 11 Apr 2013 15:49:44 +0000 Subject: [PATCH] lavfi: add smptehdbars source Signed-off-by: Paul B Mahol --- Changelog | 1 + doc/filters.texi | 5 +- libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/version.h | 4 +- libavfilter/vsrc_testsrc.c | 180 ++++++++++++++++++++++++++++++------- 6 files changed, 158 insertions(+), 34 deletions(-) diff --git a/Changelog b/Changelog index 22a216bec7..d6fdbee45b 100644 --- a/Changelog +++ b/Changelog @@ -21,6 +21,7 @@ version : - uniform options syntax across all filters - telecine filter - new interlace filter +- smptehdbars source version 1.2: diff --git a/doc/filters.texi b/doc/filters.texi index 0ff8da0ccb..391faff1b6 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -6194,7 +6194,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, smptebars, testsrc +@section color, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc The @code{color} source provides an uniformly colored input. @@ -6209,6 +6209,9 @@ 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{smptehdbars} source generates a color bars pattern, based on +the SMPTE RP 219-2002. + 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 c3cd753557..dd6e8af94d 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -183,6 +183,7 @@ 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_SMPTEHDBARS_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 7e875f68e5..19cf1c8d83 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -180,6 +180,7 @@ void avfilter_register_all(void) REGISTER_FILTER(NULLSRC, nullsrc, vsrc); REGISTER_FILTER(RGBTESTSRC, rgbtestsrc, vsrc); REGISTER_FILTER(SMPTEBARS, smptebars, vsrc); + REGISTER_FILTER(SMPTEHDBARS, smptehdbars, vsrc); REGISTER_FILTER(TESTSRC, testsrc, vsrc); REGISTER_FILTER(NULLSINK, nullsink, vsink); diff --git a/libavfilter/version.h b/libavfilter/version.h index 3112dd5cd0..2e71970c93 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 53 -#define LIBAVFILTER_VERSION_MICRO 101 +#define LIBAVFILTER_VERSION_MINOR 54 +#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 7b594678a5..3d2f93683f 100644 --- a/libavfilter/vsrc_testsrc.c +++ b/libavfilter/vsrc_testsrc.c @@ -30,7 +30,7 @@ * rgbtestsrc is ported from MPlayer libmpcodecs/vf_rgbtest.c by * Michael Niedermayer. * - * smptebars is by Paul B Mahol. + * smptebars and smptehdbars is by Paul B Mahol. */ #include @@ -654,10 +654,7 @@ AVFilter avfilter_vsrc_rgbtestsrc = { #endif /* CONFIG_RGBTESTSRC_FILTER */ -#if CONFIG_SMPTEBARS_FILTER - -#define smptebars_options options -AVFILTER_DEFINE_CLASS(smptebars); +#if CONFIG_SMPTEBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER static const uint8_t rainbow[7][4] = { { 191, 191, 191, 255 }, /* gray */ @@ -690,6 +687,17 @@ static const uint8_t pos4ire[4] = { 29, 29, 29, 255 }; /* 11.5% intensity bla static const uint8_t i_pixel[4] = { 0, 68, 130, 255 }; static const uint8_t q_pixel[4] = { 67, 0, 130, 255 }; +static const uint8_t gray40[4] = { 102, 102, 102, 255 }; +static const uint8_t gray15[4] = { 38, 38, 38, 255 }; +static const uint8_t cyan[4] = { 0, 255, 255, 255 }; +static const uint8_t yellow[4] = { 255, 255, 0, 255 }; +static const uint8_t blue[4] = { 0, 0, 255, 255 }; +static const uint8_t red[4] = { 255, 0, 0, 255 }; +static const uint8_t black0[4] = { 5, 5, 5, 255 }; +static const uint8_t black2[4] = { 10, 10, 10, 255 }; +static const uint8_t black4[4] = { 15, 15, 15, 255 }; +static const uint8_t neg2[4] = { 0, 0, 0, 255 }; + static void inline draw_bar(TestSourceContext *test, const uint8_t *color, unsigned x, unsigned y, unsigned w, unsigned h, AVFrame *frame) @@ -709,6 +717,37 @@ static void inline draw_bar(TestSourceContext *test, const uint8_t *color, frame->data, frame->linesize, x, y, w, h); } +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); +} + +static const AVFilterPad smptebars_outputs[] = { + { + .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .request_frame = request_frame, + .config_props = smptebars_config_props, + }, + { NULL } +}; + +#if CONFIG_SMPTEHDBARS_FILTER + +#define smptebars_options options +AVFILTER_DEFINE_CLASS(smptebars); + static void smptebars_fill_picture(AVFilterContext *ctx, AVFrame *picref) { TestSourceContext *test = ctx->priv; @@ -755,32 +794,6 @@ static av_cold int smptebars_init(AVFilterContext *ctx) return init(ctx); } -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); -} - -static const AVFilterPad smptebars_outputs[] = { - { - .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .request_frame = request_frame, - .config_props = smptebars_config_props, - }, - { NULL } -}; - AVFilter avfilter_vsrc_smptebars = { .name = "smptebars", .description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."), @@ -795,3 +808,108 @@ AVFilter avfilter_vsrc_smptebars = { }; #endif /* CONFIG_SMPTEBARS_FILTER */ + +#if CONFIG_SMPTEHDBARS_FILTER + +#define smptehdbars_options options +AVFILTER_DEFINE_CLASS(smptehdbars); + +static void smptehdbars_fill_picture(AVFilterContext *ctx, AVFrame *picref) +{ + TestSourceContext *test = ctx->priv; + int d_w, r_w, r_h, l_w, i, tmp, x = 0, y = 0; + const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format); + + d_w = FFALIGN(test->w / 8, 1 << pixdesc->log2_chroma_w); + r_h = FFALIGN(test->h * 7 / 12, 1 << pixdesc->log2_chroma_h); + draw_bar(test, gray40, x, 0, d_w, r_h, picref); + x += d_w; + + r_w = FFALIGN((((test->w + 3) / 4) * 3) / 7, 1 << pixdesc->log2_chroma_w); + for (i = 0; i < 7; i++) { + draw_bar(test, rainbow[i], x, 0, r_w, r_h, picref); + x += r_w; + } + draw_bar(test, gray40, x, 0, test->w - x, r_h, picref); + y = r_h; + r_h = FFALIGN(test->h / 12, 1 << pixdesc->log2_chroma_h); + draw_bar(test, cyan, 0, y, d_w, r_h, picref); + x = d_w; + draw_bar(test, i_pixel, x, y, r_w, r_h, picref); + x += r_w; + tmp = r_w * 6; + draw_bar(test, rainbow[0], x, y, tmp, r_h, picref); + x += tmp; + l_w = x; + draw_bar(test, blue, x, y, test->w - x, r_h, picref); + y += r_h; + draw_bar(test, yellow, 0, y, d_w, r_h, picref); + x = d_w; + draw_bar(test, q_pixel, x, y, r_w, r_h, picref); + x += r_w; + + for (i = 0; i < tmp; i += 1 << pixdesc->log2_chroma_w) { + uint8_t yramp[4] = {0}; + + yramp[0] = + yramp[1] = + yramp[2] = i * 255 / tmp; + yramp[3] = 255; + + draw_bar(test, yramp, x, y, 1 << pixdesc->log2_chroma_w, r_h, picref); + x += 1 << pixdesc->log2_chroma_w; + } + draw_bar(test, red, x, y, test->w - x, r_h, picref); + y += r_h; + draw_bar(test, gray15, 0, y, d_w, test->h - y, picref); + x = d_w; + tmp = FFALIGN(r_w * 3 / 2, 1 << pixdesc->log2_chroma_w); + draw_bar(test, black0, x, y, tmp, test->h - y, picref); + x += tmp; + tmp = FFALIGN(r_w * 2, 1 << pixdesc->log2_chroma_w); + draw_bar(test, white, x, y, tmp, test->h - y, picref); + x += tmp; + tmp = FFALIGN(r_w * 5 / 6, 1 << pixdesc->log2_chroma_w); + draw_bar(test, black0, x, y, tmp, test->h - y, picref); + x += tmp; + tmp = FFALIGN(r_w / 3, 1 << pixdesc->log2_chroma_w); + draw_bar(test, neg2, x, y, tmp, test->h - y, picref); + x += tmp; + draw_bar(test, black0, x, y, tmp, test->h - y, picref); + x += tmp; + draw_bar(test, black2, x, y, tmp, test->h - y, picref); + x += tmp; + draw_bar(test, black0, x, y, tmp, test->h - y, picref); + x += tmp; + draw_bar(test, black4, x, y, tmp, test->h - y, picref); + x += tmp; + r_w = l_w - x; + draw_bar(test, black0, x, y, r_w, test->h - y, picref); + x += r_w; + draw_bar(test, gray15, x, y, test->w - x, test->h - y, picref); +} + +static av_cold int smptehdbars_init(AVFilterContext *ctx) +{ + TestSourceContext *test = ctx->priv; + + test->fill_picture_fn = smptehdbars_fill_picture; + test->draw_once = 1; + return init(ctx); +} + +AVFilter avfilter_vsrc_smptehdbars = { + .name = "smptehdbars", + .description = NULL_IF_CONFIG_SMALL("Generate SMPTE HD color bars."), + .priv_size = sizeof(TestSourceContext), + .init = smptehdbars_init, + .uninit = uninit, + + .query_formats = smptebars_query_formats, + .inputs = NULL, + .outputs = smptebars_outputs, + .priv_class = &smptebars_class, +}; + +#endif /* CONFIG_SMPTEHDBARS_FILTER */ +#endif /* CONFIG_SMPTEHDBARS_FILTER || CONFIG_SMPTEHDBARS_FILTER */