From 006e20bd3655443e2d709dfbee468af2805a994a Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Mon, 8 Apr 2013 12:22:48 +0200 Subject: [PATCH] lavfi/overlay: add enable expression This expression is useful to enable/disable overlaying on the fly. Note that this can't be easily done relying on the filtergraph structure, since this implies caching issues or a null frame overlaying in the best case, which is better avoided for performance and convenience reasons. --- doc/filters.texi | 12 +++++++++--- libavfilter/version.h | 2 +- libavfilter/vf_overlay.c | 25 ++++++++++++++++++------- 3 files changed, 28 insertions(+), 11 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index 4668b7fc53..215e4387a2 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -4267,8 +4267,14 @@ on the main video. Default value is "0" for both expressions. In case the expression is invalid, it is set to a huge value (meaning that the overlay will not be displayed within the output visible area). +@item enable +Set the expression which enables the overlay. If the evaluation is +different from 0, the overlay is displayed on top of the input +frame. By default it is "1". + @item eval -Set when the expressions for @option{x} and @option{y} are evaluated. +Set when the expressions for @option{x}, @option{y}, and +@option{enable} are evaluated. It accepts the following values: @table @samp @@ -4308,8 +4314,8 @@ color space. Default value is 0. This option is deprecated, use @option{format} instead. @end table -The @option{x}, and @option{y} expressions can contain the following -parameters. +The @option{x}, @option{y}, and @option{enable} expressions can +contain the following parameters. @table @option @item main_w, W diff --git a/libavfilter/version.h b/libavfilter/version.h index 7e9784e4e3..e2fec54961 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -30,7 +30,7 @@ #define LIBAVFILTER_VERSION_MAJOR 3 #define LIBAVFILTER_VERSION_MINOR 50 -#define LIBAVFILTER_VERSION_MICRO 101 +#define LIBAVFILTER_VERSION_MICRO 102 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c index 62bdd4e92b..57a0bcd268 100644 --- a/libavfilter/vf_overlay.c +++ b/libavfilter/vf_overlay.c @@ -87,6 +87,7 @@ enum var_name { typedef struct { const AVClass *class; int x, y; ///< position of overlayed picture + double enable; ///< tells if blending is enabled int allow_packed_rgb; uint8_t frame_requested; @@ -110,8 +111,8 @@ typedef struct { int shortest; ///< terminate stream when the shortest input terminates double var_values[VAR_VARS_NB]; - char *x_expr, *y_expr; - AVExpr *x_pexpr, *y_pexpr; + char *x_expr, *y_expr, *enable_expr; + AVExpr *x_pexpr, *y_pexpr, *enable_pexpr; } OverlayContext; #define OFFSET(x) offsetof(OverlayContext, x) @@ -120,6 +121,7 @@ typedef struct { static const AVOption overlay_options[] = { { "x", "set the x expression", OFFSET(x_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS }, { "y", "set the y expression", OFFSET(y_expr), AV_OPT_TYPE_STRING, {.str = "0"}, CHAR_MIN, CHAR_MAX, FLAGS }, + { "enable", "set expression which enables overlay", OFFSET(enable_expr), AV_OPT_TYPE_STRING, {.str = "1"}, .flags = FLAGS }, { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_FRAME}, 0, EVAL_MODE_NB-1, FLAGS, "eval" }, { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, @@ -159,6 +161,7 @@ static av_cold void uninit(AVFilterContext *ctx) ff_bufqueue_discard_all(&over->queue_over); av_expr_free(over->x_pexpr); over->x_pexpr = NULL; av_expr_free(over->y_pexpr); over->y_pexpr = NULL; + av_expr_free(over->enable_pexpr); over->enable_pexpr = NULL; } static int query_formats(AVFilterContext *ctx) @@ -257,6 +260,7 @@ static void eval_expr(AVFilterContext *ctx) over->var_values[VAR_X] = av_expr_eval(over->x_pexpr, over->var_values, NULL); over->x = normalize_xy(over->var_values[VAR_X], over->hsub); over->y = normalize_xy(over->var_values[VAR_Y], over->vsub); + over->enable = av_expr_eval(over->enable_pexpr, over->var_values, NULL); } static int config_input_overlay(AVFilterLink *inlink) @@ -291,6 +295,10 @@ static int config_input_overlay(AVFilterLink *inlink) if ((ret = av_expr_parse(&over->y_pexpr, expr, var_names, NULL, NULL, NULL, NULL, 0, ctx)) < 0) goto fail; + expr = over->enable_expr; + if ((ret = av_expr_parse(&over->enable_pexpr, expr, var_names, + NULL, NULL, NULL, NULL, 0, ctx)) < 0) + goto fail; over->overlay_is_packed_rgb = ff_fill_rgba_map(over->overlay_rgba_map, inlink->format) >= 0; @@ -298,9 +306,10 @@ static int config_input_overlay(AVFilterLink *inlink) if (over->eval_mode == EVAL_MODE_INIT) { eval_expr(ctx); - av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d\n", + av_log(ctx, AV_LOG_VERBOSE, "x:%f xi:%d y:%f yi:%d enable:%f\n", over->var_values[VAR_X], over->x, - over->var_values[VAR_Y], over->y); + over->var_values[VAR_Y], over->y, + over->enable); } av_log(ctx, AV_LOG_VERBOSE, @@ -573,12 +582,14 @@ static int try_filter_frame(AVFilterContext *ctx, AVFrame *mainpic) over->var_values[VAR_POS] = pos == -1 ? NAN : pos; eval_expr(ctx); - av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f pos:%f x:%f xi:%d y:%f yi:%d\n", + av_log(ctx, AV_LOG_DEBUG, "n:%f t:%f pos:%f x:%f xi:%d y:%f yi:%d enable:%f\n", over->var_values[VAR_N], over->var_values[VAR_T], over->var_values[VAR_POS], over->var_values[VAR_X], over->x, - over->var_values[VAR_Y], over->y); + over->var_values[VAR_Y], over->y, + over->enable); } - blend_image(ctx, mainpic, over->overpicref, over->x, over->y); + if (over->enable) + blend_image(ctx, mainpic, over->overpicref, over->x, over->y); over->var_values[VAR_N] += 1.0; }