lavfi/overlay: add enable expression
authorStefano Sabatini <stefasab@gmail.com>
Mon, 8 Apr 2013 10:22:48 +0000 (12:22 +0200)
committerStefano Sabatini <stefasab@gmail.com>
Wed, 10 Apr 2013 11:11:27 +0000 (13:11 +0200)
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
libavfilter/version.h
libavfilter/vf_overlay.c

index 4668b7f..215e438 100644 (file)
@@ -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
index 7e9784e..e2fec54 100644 (file)
@@ -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, \
index 62bdd4e..57a0bcd 100644 (file)
@@ -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;
     }