[FFmpeg-devel] [PATCH] avfilter/vf_overlay: add show property/command

Bodecs Bela bodecsb at vivanet.hu
Sun Mar 11 23:44:07 EET 2018


Dear All,

I frequently use overlay video filter. Sometimes it is needed to 
dinamically hide/show the ovelaid video. (e.g during live streaming).
Currently the only possibility to hide the overlaid video is to position 
it to off site area of the visible region.
This patch creates a new, explicit property to controll hiding/showing 
the overlaid video.
'show' property may be an expression, similary to x and y.
The new 'show' property is controlable by command, also. So its value 
can be adjusted dinamically during live sessions by zmq filters.
To be compatible with existing stuff, its default value is "1".

Please review this patch and consider putting this patch into the 
official ffmpeg source tree.

Thank you in advance.


best regards,

Bela


-------------- next part --------------
>From 808053b373b1209bc4a56a5630ee9cbc71413ff6 Mon Sep 17 00:00:00 2001
From: Bela Bodecs <bodecsb at vivanet.hu>
Date: Sun, 11 Mar 2018 22:33:32 +0100
Subject: [PATCH] avfilter/vf_overlay: add show property/command

Currently the only possibility to hide the overlaid video is to position
it to off site area of the visible region. This patch creates a new,
explicit property to controll hiding/showing the overlaid video. 'show'
property may be an expression, similary to x and y. The new 'show'
property is controlable by command, also. To be compatible with existing
stuff, its default value is "1".

Signed-off-by: Bela Bodecs <bodecsb at vivanet.hu>
---
 doc/filters.texi         | 16 ++++++++++++++--
 libavfilter/vf_overlay.c | 37 ++++++++++++++++++++++++++-----------
 2 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index bd93e0a..f9b623c 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -11615,11 +11615,16 @@ 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).
 
+ at item show
+Set the expression for controlling to show or hide the overlaid video.
+Default value is "1". Expression evaluating to 0 means to hide,
+any other value means to show. Internally the result normalized to 0 or 1.
+
 @item eof_action
 See @ref{framesync}.
 
 @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{show} are evaluated.
 
 It accepts the following values:
 @table @samp
@@ -11670,7 +11675,7 @@ Set format of alpha of the overlaid video, it can be @var{straight} or
 @var{premultiplied}. Default is @var{straight}.
 @end table
 
-The @option{x}, and @option{y} expressions can contain the following
+The @option{x}, @option{y} and @option{show} expressions can contain the following
 parameters.
 
 @table @option
@@ -11702,6 +11707,9 @@ the position in the file of the input frame, NAN if unknown
 @item t
 The timestamp, expressed in seconds. It's NAN if the input timestamp is unknown.
 
+ at item show
+the computed value of @var{show} normalized to 0 or 1 according to wether overlaid video shown or hidden.
+
 @end table
 
 This filter also supports the @ref{framesync} options.
@@ -11730,6 +11738,10 @@ The command accepts the same syntax of the corresponding option.
 
 If the specified expression is not valid, it is kept at its current
 value.
+
+ at item show
+Modify the expression to show or to hide the overlaid video.
+
 @end table
 
 @subsection Examples
diff --git a/libavfilter/vf_overlay.c b/libavfilter/vf_overlay.c
index c6a6ac8..891db9e 100644
--- a/libavfilter/vf_overlay.c
+++ b/libavfilter/vf_overlay.c
@@ -52,6 +52,7 @@ static const char *const var_names[] = {
     "n",            ///< number of frame
     "pos",          ///< position in the file
     "t",            ///< timestamp expressed in seconds
+    "show",         ///< show/hide overlay
     NULL
 };
 
@@ -67,6 +68,7 @@ enum var_name {
     VAR_N,
     VAR_POS,
     VAR_T,
+    VAR_SHOW,
     VAR_VARS_NB
 };
 
@@ -111,6 +113,7 @@ typedef struct OverlayContext {
     int format;                 ///< OverlayFormat
     int alpha_format;
     int eval_mode;              ///< EvalMode
+    int show;                   ///< show or hide overlay
 
     FFFrameSync fs;
 
@@ -120,9 +123,9 @@ typedef struct OverlayContext {
     const AVPixFmtDescriptor *main_desc; ///< format descriptor for main input
 
     double var_values[VAR_VARS_NB];
-    char *x_expr, *y_expr;
+    char *x_expr, *y_expr, *show_expr;
 
-    AVExpr *x_pexpr, *y_pexpr;
+    AVExpr *x_pexpr, *y_pexpr, *show_pexpr;
 
     void (*blend_image)(AVFilterContext *ctx, AVFrame *dst, const AVFrame *src, int x, int y);
 } OverlayContext;
@@ -134,6 +137,7 @@ static av_cold void uninit(AVFilterContext *ctx)
     ff_framesync_uninit(&s->fs);
     av_expr_free(s->x_pexpr); s->x_pexpr = NULL;
     av_expr_free(s->y_pexpr); s->y_pexpr = NULL;
+    av_expr_free(s->show_pexpr); s->show_pexpr = NULL;
 }
 
 static inline int normalize_xy(double d, int chroma_sub)
@@ -153,6 +157,8 @@ static void eval_expr(AVFilterContext *ctx)
     s->var_values[VAR_X] = av_expr_eval(s->x_pexpr, s->var_values, NULL);
     s->x = normalize_xy(s->var_values[VAR_X], s->hsub);
     s->y = normalize_xy(s->var_values[VAR_Y], s->vsub);
+    s->var_values[VAR_SHOW] = av_expr_eval(s->show_pexpr, s->var_values, NULL);
+    s->show = s->var_values[VAR_SHOW]?1:0; // normalizing to fix value set
 }
 
 static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
@@ -186,6 +192,8 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar
         ret = set_expr(&s->x_pexpr, args, cmd, ctx);
     else if (!strcmp(cmd, "y"))
         ret = set_expr(&s->y_pexpr, args, cmd, ctx);
+    else if (!strcmp(cmd, "show"))
+        ret = set_expr(&s->show_pexpr, args, cmd, ctx);
     else
         ret = AVERROR(ENOSYS);
 
@@ -194,9 +202,11 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar
 
     if (s->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 show:%f showi:%d\n",
                s->var_values[VAR_X], s->x,
-               s->var_values[VAR_Y], s->y);
+               s->var_values[VAR_Y], s->y,
+               s->var_values[VAR_SHOW], s->show
+               );
     }
     return ret;
 }
@@ -348,9 +358,11 @@ static int config_input_overlay(AVFilterLink *inlink)
     s->var_values[VAR_N]     = 0;
     s->var_values[VAR_T]     = NAN;
     s->var_values[VAR_POS]   = NAN;
+    s->var_values[VAR_SHOW] = NAN;
 
     if ((ret = set_expr(&s->x_pexpr,      s->x_expr,      "x",      ctx)) < 0 ||
-        (ret = set_expr(&s->y_pexpr,      s->y_expr,      "y",      ctx)) < 0)
+        (ret = set_expr(&s->y_pexpr,      s->y_expr,      "y",      ctx)) < 0 ||
+        (ret = set_expr(&s->show_pexpr,   s->show_expr,   "show",   ctx)) < 0)
         return ret;
 
     s->overlay_is_packed_rgb =
@@ -359,9 +371,10 @@ static int config_input_overlay(AVFilterLink *inlink)
 
     if (s->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 show:%f showi:%d\n",
                s->var_values[VAR_X], s->x,
-               s->var_values[VAR_Y], s->y);
+               s->var_values[VAR_Y], s->y,
+               s->var_values[VAR_SHOW], s->show);
     }
 
     av_log(ctx, AV_LOG_VERBOSE,
@@ -898,14 +911,15 @@ static int do_blend(FFFrameSync *fs)
         s->var_values[VAR_MAIN_H   ] = s->var_values[VAR_MH] = mainpic->height;
 
         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 show:%f showi:%d\n",
                s->var_values[VAR_N], s->var_values[VAR_T], s->var_values[VAR_POS],
                s->var_values[VAR_X], s->x,
-               s->var_values[VAR_Y], s->y);
+               s->var_values[VAR_Y], s->y,
+               s->var_values[VAR_SHOW], s->show);
     }
 
-    if (s->x < mainpic->width  && s->x + second->width  >= 0 ||
-        s->y < mainpic->height && s->y + second->height >= 0)
+    if ((s->x < mainpic->width  && s->x + second->width  >= 0 ||
+        s->y < mainpic->height && s->y + second->height >= 0) && s->show)
         s->blend_image(ctx, mainpic, second, s->x, s->y);
     return ff_filter_frame(ctx->outputs[0], mainpic);
 }
@@ -951,6 +965,7 @@ static const AVOption overlay_options[] = {
     { "alpha", "alpha format", OFFSET(alpha_format), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, FLAGS, "alpha_format" },
         { "straight",      "", 0, AV_OPT_TYPE_CONST, {.i64=0}, .flags = FLAGS, .unit = "alpha_format" },
         { "premultiplied", "", 0, AV_OPT_TYPE_CONST, {.i64=1}, .flags = FLAGS, .unit = "alpha_format" },
+    { "show", "set the show/hide overlay expression", OFFSET(show_expr), AV_OPT_TYPE_STRING, {.str = "1"}, CHAR_MIN, CHAR_MAX, FLAGS },
     { NULL }
 };
 
-- 
2.5.3.windows.1



More information about the ffmpeg-devel mailing list