[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