avfilter/vf_floodfill: finish early if source and destination fill matches

Fixes #8236
This commit is contained in:
Paul B Mahol 2019-10-10 21:50:03 +02:00
parent b67af536be
commit 1331e00179
1 changed files with 34 additions and 24 deletions

View File

@ -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 }
};