X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavfilter%2Fvf_drawbox.c;h=2794fc252062a5babfbac1cfbd89ee822784e0b9;hb=a04ad248a05e7b613abe09b3bb067f555108d794;hp=c9cb63dbd13440662c01e0d1347f060b99a77bb5;hpb=22219a3ac46ac18f797c94e4619a34728556786c;p=ffmpeg diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c index c9cb63dbd13..2794fc25206 100644 --- a/libavfilter/vf_drawbox.c +++ b/libavfilter/vf_drawbox.c @@ -208,6 +208,12 @@ fail: return ret; } +static av_pure av_always_inline int pixel_belongs_to_box(DrawBoxContext *s, int x, int y) +{ + return (y - s->y < s->thickness) || (s->y + s->h - 1 - y < s->thickness) || + (x - s->x < s->thickness) || (s->x + s->w - 1 - x < s->thickness); +} + static int filter_frame(AVFilterLink *inlink, AVFrame *frame) { DrawBoxContext *s = inlink->dst->priv; @@ -225,13 +231,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) if (s->invert_color) { for (x = FFMAX(xb, 0); x < xb + s->w && x < frame->width; x++) - if ((y - yb < s->thickness) || (yb + s->h - 1 - y < s->thickness) || - (x - xb < s->thickness) || (xb + s->w - 1 - x < s->thickness)) + if (pixel_belongs_to_box(s, x, y)) row[0][x] = 0xff - row[0][x]; } else { for (x = FFMAX(xb, 0); x < xb + s->w && x < frame->width; x++) { - if ((y - yb < s->thickness) || (yb + s->h - 1 - y < s->thickness) || - (x - xb < s->thickness) || (xb + s->w - 1 - x < s->thickness)) { + if (pixel_belongs_to_box(s, x, y)) { row[0][x ] = s->yuv_color[Y]; row[1][x >> s->hsub] = s->yuv_color[U]; row[2][x >> s->hsub] = s->yuv_color[V]; @@ -250,15 +254,13 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) if (s->invert_color) { for (x = FFMAX(xb, 0); x < xb + s->w && x < frame->width; x++) - if ((y - yb < s->thickness) || (yb + s->h - 1 - y < s->thickness) || - (x - xb < s->thickness) || (xb + s->w - 1 - x < s->thickness)) + if (pixel_belongs_to_box(s, x, y)) row[0][x] = 0xff - row[0][x]; } else { for (x = FFMAX(xb, 0); x < xb + s->w && x < frame->width; x++) { double alpha = (double)s->yuv_color[A] / 255; - if ((y - yb < s->thickness) || (yb + s->h - 1 - y < s->thickness) || - (x - xb < s->thickness) || (xb + s->w - 1 - x < s->thickness)) { + if (pixel_belongs_to_box(s, x, y)) { row[0][x ] = (1 - alpha) * row[0][x ] + alpha * s->yuv_color[Y]; row[1][x >> s->hsub] = (1 - alpha) * row[1][x >> s->hsub] + alpha * s->yuv_color[U]; row[2][x >> s->hsub] = (1 - alpha) * row[2][x >> s->hsub] + alpha * s->yuv_color[V]; @@ -271,23 +273,56 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) return ff_filter_frame(inlink->dst->outputs[0], frame); } +static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags) +{ + AVFilterLink *inlink = ctx->inputs[0]; + DrawBoxContext *s = ctx->priv; + int old_x = s->x; + int old_y = s->y; + int old_w = s->w; + int old_h = s->h; + int old_t = s->thickness; + int old_r = s->replace; + int ret; + + ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags); + if (ret < 0) + return ret; + + ret = init(ctx); + if (ret < 0) + goto end; + ret = config_input(inlink); +end: + if (ret < 0) { + s->x = old_x; + s->y = old_y; + s->w = old_w; + s->h = old_h; + s->thickness = old_t; + s->replace = old_r; + } + + return ret; +} + #define OFFSET(x) offsetof(DrawBoxContext, x) -#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM +#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_RUNTIME_PARAM #if CONFIG_DRAWBOX_FILTER static const AVOption drawbox_options[] = { - { "x", "set horizontal position of the left box edge", OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "y", "set vertical position of the top box edge", OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "width", "set width of the box", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "w", "set width of the box", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "height", "set height of the box", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "h", "set height of the box", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "color", "set color of the box", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "c", "set color of the box", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "thickness", "set the box thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, { .str="3" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "t", "set the box thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, { .str="3" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "replace", "replace color & alpha", OFFSET(replace), AV_OPT_TYPE_BOOL, { .i64=0 }, 0, 1, FLAGS }, + { "x", "set horizontal position of the left box edge", OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "y", "set vertical position of the top box edge", OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "width", "set width of the box", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "w", "set width of the box", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "height", "set height of the box", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "h", "set height of the box", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "color", "set color of the box", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, 0, 0, FLAGS }, + { "c", "set color of the box", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, 0, 0, FLAGS }, + { "thickness", "set the box thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, { .str="3" }, 0, 0, FLAGS }, + { "t", "set the box thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, { .str="3" }, 0, 0, FLAGS }, + { "replace", "replace color & alpha", OFFSET(replace), AV_OPT_TYPE_BOOL, { .i64=0 }, 0, 1, FLAGS }, { NULL } }; @@ -312,7 +347,7 @@ static const AVFilterPad drawbox_outputs[] = { { NULL } }; -AVFilter ff_vf_drawbox = { +const AVFilter ff_vf_drawbox = { .name = "drawbox", .description = NULL_IF_CONFIG_SMALL("Draw a colored box on the input video."), .priv_size = sizeof(DrawBoxContext), @@ -321,6 +356,7 @@ AVFilter ff_vf_drawbox = { .query_formats = query_formats, .inputs = drawbox_inputs, .outputs = drawbox_outputs, + .process_command = process_command, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, }; #endif /* CONFIG_DRAWBOX_FILTER */ @@ -410,16 +446,16 @@ static int drawgrid_filter_frame(AVFilterLink *inlink, AVFrame *frame) } static const AVOption drawgrid_options[] = { - { "x", "set horizontal offset", OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "y", "set vertical offset", OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "width", "set width of grid cell", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "w", "set width of grid cell", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "height", "set height of grid cell", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "h", "set height of grid cell", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "color", "set color of the grid", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "c", "set color of the grid", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, CHAR_MIN, CHAR_MAX, FLAGS }, - { "thickness", "set grid line thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, {.str="1"}, CHAR_MIN, CHAR_MAX, FLAGS }, - { "t", "set grid line thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, {.str="1"}, CHAR_MIN, CHAR_MAX, FLAGS }, + { "x", "set horizontal offset", OFFSET(x_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "y", "set vertical offset", OFFSET(y_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "width", "set width of grid cell", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "w", "set width of grid cell", OFFSET(w_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "height", "set height of grid cell", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "h", "set height of grid cell", OFFSET(h_expr), AV_OPT_TYPE_STRING, { .str="0" }, 0, 0, FLAGS }, + { "color", "set color of the grid", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, 0, 0, FLAGS }, + { "c", "set color of the grid", OFFSET(color_str), AV_OPT_TYPE_STRING, { .str = "black" }, 0, 0, FLAGS }, + { "thickness", "set grid line thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, {.str="1"}, 0, 0, FLAGS }, + { "t", "set grid line thickness", OFFSET(t_expr), AV_OPT_TYPE_STRING, {.str="1"}, 0, 0, FLAGS }, { "replace", "replace color & alpha", OFFSET(replace), AV_OPT_TYPE_BOOL, { .i64=0 }, 0, 1, FLAGS }, { NULL } }; @@ -445,7 +481,7 @@ static const AVFilterPad drawgrid_outputs[] = { { NULL } }; -AVFilter ff_vf_drawgrid = { +const AVFilter ff_vf_drawgrid = { .name = "drawgrid", .description = NULL_IF_CONFIG_SMALL("Draw a colored grid on the input video."), .priv_size = sizeof(DrawBoxContext), @@ -455,6 +491,7 @@ AVFilter ff_vf_drawgrid = { .inputs = drawgrid_inputs, .outputs = drawgrid_outputs, .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, + .process_command = process_command, }; #endif /* CONFIG_DRAWGRID_FILTER */