[FFmpeg-devel] [PATCH] lavfi: add smptehdbars source
Stefano Sabatini
stefasab at gmail.com
Sat Apr 13 00:13:04 CEST 2013
On date Thursday 2013-04-11 22:44:15 +0000, Paul B Mahol encoded:
> Signed-off-by: Paul B Mahol <onemda at gmail.com>
> ---
> doc/filters.texi | 5 +-
> libavfilter/Makefile | 1 +
> libavfilter/allfilters.c | 1 +
> libavfilter/vsrc_testsrc.c | 172 ++++++++++++++++++++++++++++++++++++++-------
> 4 files changed, 151 insertions(+), 28 deletions(-)
Reminder: minor bump, Changelog entry
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 3438308..f732cf4 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -6231,7 +6231,7 @@ ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_c
> @end example
> @end itemize
>
> - at section color, nullsrc, rgbtestsrc, smptebars, testsrc
> + at section color, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc
>
> The @code{color} source provides an uniformly colored input.
>
> @@ -6246,6 +6246,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 c736ad1..6ac98d4 100644
> --- a/libavfilter/Makefile
> +++ b/libavfilter/Makefile
> @@ -182,6 +182,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 721db2e..a2f12d2 100644
> --- a/libavfilter/allfilters.c
> +++ b/libavfilter/allfilters.c
> @@ -177,6 +177,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/vsrc_testsrc.c b/libavfilter/vsrc_testsrc.c
> index 7ae256d..0240f08 100644
> --- a/libavfilter/vsrc_testsrc.c
> +++ b/libavfilter/vsrc_testsrc.c
> @@ -662,10 +662,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 */
> @@ -698,6 +695,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)
> @@ -717,6 +725,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;
> @@ -763,37 +802,115 @@ static av_cold int smptebars_init(AVFilterContext *ctx, const char *args)
> return init(ctx);
> }
>
> -static int smptebars_query_formats(AVFilterContext *ctx)
> -{
> - ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0));
> - return 0;
> -}
> +AVFilter avfilter_vsrc_smptebars = {
> + .name = "smptebars",
> + .description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."),
> + .priv_size = sizeof(TestSourceContext),
> + .init = smptebars_init,
> + .uninit = uninit,
>
> -static int smptebars_config_props(AVFilterLink *outlink)
> + .query_formats = smptebars_query_formats,
> + .inputs = NULL,
> + .outputs = smptebars_outputs,
> + .priv_class = &smptebars_class,
> +};
> +
> +#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)
> {
> - AVFilterContext *ctx = outlink->src;
> TestSourceContext *test = ctx->priv;
> + int d_w, r_w, r_h, l_w, i, tmp, x = 0, y = 0;
Nit: better names or a comment may help here (same for regular smptebars)
> + const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(picref->format);
>
> - ff_draw_init(&test->draw, outlink->format, 0);
> + 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;
>
> - return config_props(outlink);
> + 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 const AVFilterPad smptebars_outputs[] = {
> - {
> - .name = "default",
> - .type = AVMEDIA_TYPE_VIDEO,
> - .request_frame = request_frame,
> - .config_props = smptebars_config_props,
> - },
> - { NULL }
> -};
> +static av_cold int smptehdbars_init(AVFilterContext *ctx, const char *args)
> +{
> + TestSourceContext *test = ctx->priv;
>
> -AVFilter avfilter_vsrc_smptebars = {
> - .name = "smptebars",
> - .description = NULL_IF_CONFIG_SMALL("Generate SMPTE color bars."),
> + 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 = smptebars_init,
> + .init = smptehdbars_init,
> .uninit = uninit,
Looks good to me assuming it has been tested, adding a test for it may
be useful (although possibly overkill), thanks.
--
FFmpeg = Fierce and Fast Murdering Philosophical Extroverse Gladiator
More information about the ffmpeg-devel
mailing list