[FFmpeg-cvslog] avfilter/vf_maskfun: add support for commands

Paul B Mahol git at videolan.org
Tue Feb 9 12:24:56 EET 2021


ffmpeg | branch: master | Paul B Mahol <onemda at gmail.com> | Tue Feb  9 11:23:19 2021 +0100| [ca042675eebe2c29f052eb2fa07db15fd702a943] | committer: Paul B Mahol

avfilter/vf_maskfun: add support for commands

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ca042675eebe2c29f052eb2fa07db15fd702a943
---

 doc/filters.texi         |  4 ++
 libavfilter/vf_maskfun.c | 98 +++++++++++++++++++++++++++++++++---------------
 2 files changed, 71 insertions(+), 31 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 891e8c4544..0db014c922 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -14403,6 +14403,10 @@ average, output frame will be completely filled with value set by @var{fill} opt
 Typically useful for scene changes when used in combination with @code{tblend} filter.
 @end table
 
+ at subsection Commands
+
+This filter supports the all above options as @ref{commands}.
+
 @section mcdeint
 
 Apply motion-compensation deinterlacing.
diff --git a/libavfilter/vf_maskfun.c b/libavfilter/vf_maskfun.c
index 4ceb21b943..55a4c57c9d 100644
--- a/libavfilter/vf_maskfun.c
+++ b/libavfilter/vf_maskfun.c
@@ -47,14 +47,14 @@ typedef struct MaskFunContext {
 } MaskFunContext;
 
 #define OFFSET(x) offsetof(MaskFunContext, x)
-#define VF AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+#define VFT AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_RUNTIME_PARAM
 
 static const AVOption maskfun_options[] = {
-    { "low",    "set low threshold",  OFFSET(low),    AV_OPT_TYPE_INT, {.i64=10},  0, UINT16_MAX, VF },
-    { "high",   "set high threshold", OFFSET(high),   AV_OPT_TYPE_INT, {.i64=10},  0, UINT16_MAX, VF },
-    { "planes", "set planes",         OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0, 0xF,        VF },
-    { "fill",   "set fill value",     OFFSET(fill),   AV_OPT_TYPE_INT, {.i64=0},   0, UINT16_MAX, VF },
-    { "sum",    "set sum value",      OFFSET(sum),    AV_OPT_TYPE_INT, {.i64=10},  0, UINT16_MAX, VF },
+    { "low",    "set low threshold",  OFFSET(low),    AV_OPT_TYPE_INT, {.i64=10},  0, UINT16_MAX, VFT },
+    { "high",   "set high threshold", OFFSET(high),   AV_OPT_TYPE_INT, {.i64=10},  0, UINT16_MAX, VFT },
+    { "planes", "set planes",         OFFSET(planes), AV_OPT_TYPE_INT, {.i64=0xF}, 0, 0xF,        VFT },
+    { "fill",   "set fill value",     OFFSET(fill),   AV_OPT_TYPE_INT, {.i64=0},   0, UINT16_MAX, VFT },
+    { "sum",    "set sum value",      OFFSET(sum),    AV_OPT_TYPE_INT, {.i64=10},  0, UINT16_MAX, VFT },
     { NULL }
 };
 
@@ -182,6 +182,45 @@ static int maskfun##name(AVFilterContext *ctx, void *arg,    \
 MASKFUN(8, uint8_t, 1)
 MASKFUN(16, uint16_t, 2)
 
+static void fill_frame(AVFilterContext *ctx)
+{
+    MaskFunContext *s = ctx->priv;
+
+    s->fill = FFMIN(s->fill, s->max);
+    if (s->depth == 8) {
+        for (int p = 0; p < s->nb_planes; p++) {
+            uint8_t *dst = s->empty->data[p];
+
+            for (int y = 0; y < s->height[p]; y++) {
+                memset(dst, s->fill, s->width[p]);
+                dst += s->empty->linesize[p];
+            }
+        }
+    } else {
+        for (int p = 0; p < s->nb_planes; p++) {
+            uint16_t *dst = (uint16_t *)s->empty->data[p];
+
+            for (int y = 0; y < s->height[p]; y++) {
+                for (int x = 0; x < s->width[p]; x++)
+                    dst[x] = s->fill;
+                dst += s->empty->linesize[p] / 2;
+            }
+        }
+    }
+}
+
+static void set_max_sum(AVFilterContext *ctx)
+{
+    MaskFunContext *s = ctx->priv;
+
+    s->max_sum = 0;
+    for (int p = 0; p < s->nb_planes; p++) {
+        if (!((1 << p) & s->planes))
+            continue;
+        s->max_sum += (uint64_t)s->sum * s->width[p] * s->height[p];
+    }
+}
+
 static int config_input(AVFilterLink *inlink)
 {
     AVFilterContext *ctx = inlink->dst;
@@ -203,7 +242,6 @@ static int config_input(AVFilterLink *inlink)
 
     s->depth = desc->comp[0].depth;
     s->max = (1 << s->depth) - 1;
-    s->fill = FFMIN(s->fill, s->max);
 
     if (s->depth == 8) {
         s->maskfun = maskfun8;
@@ -217,33 +255,30 @@ static int config_input(AVFilterLink *inlink)
     if (!s->empty)
         return AVERROR(ENOMEM);
 
-    if (s->depth == 8) {
-        for (int p = 0; p < s->nb_planes; p++) {
-            uint8_t *dst = s->empty->data[p];
+    fill_frame(ctx);
 
-            for (int y = 0; y < s->height[p]; y++) {
-                memset(dst, s->fill, s->width[p]);
-                dst += s->empty->linesize[p];
-            }
-        }
-    } else {
-        for (int p = 0; p < s->nb_planes; p++) {
-            uint16_t *dst = (uint16_t *)s->empty->data[p];
+    set_max_sum(ctx);
 
-            for (int y = 0; y < s->height[p]; y++) {
-                for (int x = 0; x < s->width[p]; x++)
-                    dst[x] = s->fill;
-                dst += s->empty->linesize[p] / 2;
-            }
-        }
-    }
+    return 0;
+}
 
-    s->max_sum = 0;
-    for (int p = 0; p < s->nb_planes; p++) {
-        if (!((1 << p) & s->planes))
-            continue;
-        s->max_sum += (uint64_t)s->sum * s->width[p] * s->height[p];
-    }
+static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+                           char *res, int res_len, int flags)
+{
+    MaskFunContext *s = ctx->priv;
+    int fill = s->fill;
+    int sum = s->sum;
+    int ret;
+
+    ret = ff_filter_process_command(ctx, cmd, args, res, res_len, flags);
+    if (ret < 0)
+        return ret;
+
+    if (sum != s->sum)
+        set_max_sum(ctx);
+
+    if (fill != s->fill)
+        fill_frame(ctx);
 
     return 0;
 }
@@ -284,4 +319,5 @@ AVFilter ff_vf_maskfun = {
     .outputs       = maskfun_outputs,
     .priv_class    = &maskfun_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
+    .process_command = process_command,
 };



More information about the ffmpeg-cvslog mailing list