From 1331e001796c656a4a3c770a16121c15ec1db2ac Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Thu, 10 Oct 2019 21:50:03 +0200 Subject: avfilter/vf_floodfill: finish early if source and destination fill matches Fixes #8236 --- libavfilter/vf_floodfill.c | 58 +++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 24 deletions(-) (limited to 'libavfilter/vf_floodfill.c') diff --git a/libavfilter/vf_floodfill.c b/libavfilter/vf_floodfill.c index 323dd0e2fa..cf8f689559 100644 --- a/libavfilter/vf_floodfill.c +++ b/libavfilter/vf_floodfill.c @@ -34,9 +34,10 @@ typedef struct FloodfillContext { const AVClass *class; int x, y; - int s0, s1, s2, s3; - int d0, d1, d2, d3; + int s[4]; + int d[4]; + int nb_planes; int back, front; Points *points; @@ -238,12 +239,12 @@ static int config_input(AVFilterLink *inlink) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); AVFilterContext *ctx = inlink->dst; FloodfillContext *s = ctx->priv; - int nb_planes = av_pix_fmt_count_planes(inlink->format); int depth; + s->nb_planes = av_pix_fmt_count_planes(inlink->format); depth = desc->comp[0].depth; if (depth == 8) { - switch (nb_planes) { + switch (s->nb_planes) { case 1: s->set_pixel = set_pixel1; s->is_same = is_same1; s->pick_pixel = pick_pixel1; break; @@ -255,7 +256,7 @@ static int config_input(AVFilterLink *inlink) s->pick_pixel = pick_pixel4; break; } } else { - switch (nb_planes) { + switch (s->nb_planes) { case 1: s->set_pixel = set_pixel1_16; s->is_same = is_same1_16; s->pick_pixel = pick_pixel1_16; break; @@ -280,17 +281,25 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) { AVFilterContext *ctx = link->dst; FloodfillContext *s = ctx->priv; - const unsigned d0 = s->d0; - const unsigned d1 = s->d1; - const unsigned d2 = s->d2; - const unsigned d3 = s->d3; - int s0 = s->s0; - int s1 = s->s1; - int s2 = s->s2; - int s3 = s->s3; + const unsigned d0 = s->d[0]; + const unsigned d1 = s->d[1]; + const unsigned d2 = s->d[2]; + const unsigned d3 = s->d[3]; + int s0 = s->s[0]; + int s1 = s->s[1]; + int s2 = s->s[2]; + int s3 = s->s[3]; const int w = frame->width; const int h = frame->height; - int ret; + int i, ret; + + for (i = 0; i < s->nb_planes; i++) { + if (s->s[i] != s->d[i]) + break; + } + + if (i == s->nb_planes) + goto end; if (ret = av_frame_make_writable(frame)) return ret; @@ -337,6 +346,7 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) } } +end: return ff_filter_frame(ctx->outputs[0], frame); } @@ -405,16 +415,16 @@ static const AVFilterPad floodfill_outputs[] = { #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM static const AVOption floodfill_options[] = { - { "x", "set pixel x coordinate", OFFSET(x), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, - { "y", "set pixel y coordinate", OFFSET(y), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, - { "s0", "set source #0 component value", OFFSET(s0), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, - { "s1", "set source #1 component value", OFFSET(s1), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, - { "s2", "set source #2 component value", OFFSET(s2), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, - { "s3", "set source #3 component value", OFFSET(s3), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, - { "d0", "set destination #0 component value", OFFSET(d0), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, - { "d1", "set destination #1 component value", OFFSET(d1), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, - { "d2", "set destination #2 component value", OFFSET(d2), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, - { "d3", "set destination #3 component value", OFFSET(d3), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { "x", "set pixel x coordinate", OFFSET(x), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { "y", "set pixel y coordinate", OFFSET(y), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { "s0", "set source #0 component value", OFFSET(s[0]), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, + { "s1", "set source #1 component value", OFFSET(s[1]), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, + { "s2", "set source #2 component value", OFFSET(s[2]), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, + { "s3", "set source #3 component value", OFFSET(s[3]), AV_OPT_TYPE_INT, {.i64=0},-1, UINT16_MAX, FLAGS }, + { "d0", "set destination #0 component value", OFFSET(d[0]), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { "d1", "set destination #1 component value", OFFSET(d[1]), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { "d2", "set destination #2 component value", OFFSET(d[2]), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, + { "d3", "set destination #3 component value", OFFSET(d[3]), AV_OPT_TYPE_INT, {.i64=0}, 0, UINT16_MAX, FLAGS }, { NULL } }; -- cgit v1.2.3