From a3e67c2d2ff63254470a9bef673f98641ced639b Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 22 Jan 2020 19:11:38 +0100 Subject: [PATCH] avfilter/vf_stack: add fill option for xstack --- doc/filters.texi | 4 ++++ libavfilter/vf_stack.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/doc/filters.texi b/doc/filters.texi index fc900cf458..40db2e5c54 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -20062,6 +20062,10 @@ a layout must be set by the user. @item shortest If set to 1, force the output to terminate when the shortest input terminates. Default value is 0. + +@item fill +If set to valid color, all unused pixels will be filled with that color. +By default fill is set to none, so it is disabled. @end table @subsection Examples diff --git a/libavfilter/vf_stack.c b/libavfilter/vf_stack.c index 5bc4ccf6ed..35b7177e83 100644 --- a/libavfilter/vf_stack.c +++ b/libavfilter/vf_stack.c @@ -21,9 +21,11 @@ #include "libavutil/avstring.h" #include "libavutil/imgutils.h" #include "libavutil/opt.h" +#include "libavutil/parseutils.h" #include "libavutil/pixdesc.h" #include "avfilter.h" +#include "drawutils.h" #include "formats.h" #include "internal.h" #include "framesync.h" @@ -44,6 +46,12 @@ typedef struct StackContext { int is_vertical; int is_horizontal; int nb_planes; + uint8_t fillcolor[4]; + char *fillcolor_str; + int fillcolor_enable; + + FFDrawContext draw; + FFDrawColor color; StackItem *items; AVFrame **frames; @@ -53,8 +61,13 @@ typedef struct StackContext { static int query_formats(AVFilterContext *ctx) { AVFilterFormats *pix_fmts = NULL; + StackContext *s = ctx->priv; int fmt, ret; + if (s->fillcolor_enable) { + return ff_set_common_formats(ctx, ff_draw_supported_pixel_formats(0)); + } + for (fmt = 0; av_pix_fmt_desc_get(fmt); fmt++) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); if (!(desc->flags & AV_PIX_FMT_FLAG_PAL || @@ -87,6 +100,12 @@ static av_cold int init(AVFilterContext *ctx) return AVERROR(ENOMEM); if (!strcmp(ctx->filter->name, "xstack")) { + if (strcmp(s->fillcolor_str, "none") && + av_parse_color(s->fillcolor, s->fillcolor_str, -1, ctx) >= 0) { + s->fillcolor_enable = 1; + } else { + s->fillcolor_enable = 0; + } if (!s->layout) { if (s->nb_inputs == 2) { s->layout = av_strdup("0_0|w0_0"); @@ -159,6 +178,10 @@ static int process_frame(FFFrameSync *fs) out->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base); out->sample_aspect_ratio = outlink->sample_aspect_ratio; + if (s->fillcolor_enable) + ff_fill_rectangle(&s->draw, &s->color, out->data, out->linesize, + 0, 0, outlink->w, outlink->h); + ctx->internal->execute(ctx, process_slice, out, NULL, FFMIN(s->nb_inputs, ff_filter_get_nb_threads(ctx))); return ff_filter_frame(outlink, out); @@ -234,6 +257,11 @@ static int config_output(AVFilterLink *outlink) char *arg3, *p3, *saveptr3 = NULL; int inw, inh, size; + if (s->fillcolor_enable) { + ff_draw_init(&s->draw, ctx->inputs[0]->format, 0); + ff_draw_color(&s->draw, &s->color, s->fillcolor); + } + for (i = 0; i < s->nb_inputs; i++) { AVFilterLink *inlink = ctx->inputs[i]; StackItem *item = &s->items[i]; @@ -425,6 +453,7 @@ static const AVOption xstack_options[] = { { "inputs", "set number of inputs", OFFSET(nb_inputs), AV_OPT_TYPE_INT, {.i64=2}, 2, INT_MAX, .flags = FLAGS }, { "layout", "set custom layout", OFFSET(layout), AV_OPT_TYPE_STRING, {.str=NULL}, 0, 0, .flags = FLAGS }, { "shortest", "force termination when the shortest input terminates", OFFSET(shortest), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, .flags = FLAGS }, + { "fill", "set the color for unused pixels", OFFSET(fillcolor_str), AV_OPT_TYPE_STRING, {.str = "none"}, .flags = FLAGS }, { NULL }, };