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


>From 808053b373b1209bc4a56a5630ee9cbc71413ff6 Mon Sep 17 00:00:00 2001
From: Bela Bodecs <bode...@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 <bode...@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).
 
+@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.
 
+@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.
+
+@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

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to