[FFmpeg-devel] [PATCH] lavfi/overlay: add enable option

Stefano Sabatini stefasab at gmail.com
Tue Feb 19 23:32:00 CET 2013


TODO: bump micro
---
 doc/filters.texi         |   10 ++++++++--
 libavfilter/vf_overlay.c |   20 +++++++++++++++-----
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index da03a69..8ddbac4 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -3862,6 +3862,12 @@ frame. 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).
 
+ at item enable
+Set the expression which enables the overlay. The expression is
+evaluated for each new output frame, if the evaluation is different
+from 0, the overlay is displayed on top of the input frame. By default
+it is "1".
+
 @item format
 Set the format for the output video.
 
@@ -3889,8 +3895,8 @@ If set to 1, force the output to terminate when the shortest input
 terminates. Default value is 0.
 @end table
 
-The @var{x} and @var{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
 @item main_h, H
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index 0bfb5f4..c9dedb5 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -108,8 +108,8 @@ typedef struct {
     int shortest;               ///< terminate stream when the shortest input terminates
     enum OverlayFormat { OVERLAY_FORMAT_YUV420, OVERLAY_FORMAT_YUV444, OVERLAY_FORMAT_RGB, OVERLAY_FORMAT_NB} format;
     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)
@@ -118,6 +118,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 },
     { "rgb", "force packed RGB in input and output (deprecated)", OFFSET(allow_packed_rgb), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS },
 
     { "format", "set output format", OFFSET(format), AV_OPT_TYPE_INT, {.i64=OVERLAY_FORMAT_YUV420}, 0, OVERLAY_FORMAT_NB-1, FLAGS, "format" },
@@ -160,6 +161,7 @@ static av_cold void uninit(AVFilterContext *ctx)
 
     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;
 
     avfilter_unref_bufferp(&over->overpicref);
     ff_bufqueue_discard_all(&over->queue_main);
@@ -276,6 +278,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;
@@ -526,12 +532,14 @@ static int try_filter_frame(AVFilterContext *ctx, AVFilterBufferRef *mainpic)
     av_dlog(ctx, "\n");
 
     if (over->overpicref) {
+        double enable;
         over->var_values[VAR_T] = mainpic->pts == AV_NOPTS_VALUE ?
             NAN : mainpic->pts * av_q2d(inlink->time_base);
         over->var_values[VAR_POS] = mainpic->pos == -1 ? NAN : mainpic->pos;
         over->var_values[VAR_X] = av_expr_eval(over->x_pexpr, over->var_values, NULL);
         over->var_values[VAR_Y] = av_expr_eval(over->y_pexpr, over->var_values, NULL);
         over->var_values[VAR_X] = av_expr_eval(over->x_pexpr, over->var_values, NULL);
+        enable = av_expr_eval(over->enable_pexpr, over->var_values, NULL);
 
         if (isnan(over->var_values[VAR_X])) {
             over->x = INT_MAX;
@@ -545,12 +553,14 @@ static int try_filter_frame(AVFilterContext *ctx, AVFilterBufferRef *mainpic)
             over->y = over->var_values[VAR_Y];
             over->y &= ~((1 << over->vsub) - 1);
         }
-        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,
+               enable);
 
-        blend_image(ctx, mainpic, over->overpicref, over->x, over->y);
+        if (enable)
+            blend_image(ctx, mainpic, over->overpicref, over->x, over->y);
         over->var_values[VAR_N] += 1.0;
     }
     ret = ff_filter_frame(ctx->outputs[0], mainpic);
-- 
1.7.9.5



More information about the ffmpeg-devel mailing list