]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/vf_maskfun.c
avfilter: Constify all AVFilters
[ffmpeg] / libavfilter / vf_maskfun.c
index a8c6466d221f08a018e699dfb180c4c6e0798e80..0f3e3545b3bd6f45ee996e9b35f3ef6c3339e63a 100644 (file)
@@ -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,37 +255,41 @@ 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;
 }
 
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    MaskFunContext *s = ctx->priv;
+
+    av_frame_free(&s->empty);
+}
+
 static const AVFilterPad maskfun_inputs[] = {
     {
         .name           = "default",
@@ -267,13 +309,15 @@ static const AVFilterPad maskfun_outputs[] = {
     { NULL }
 };
 
-AVFilter ff_vf_maskfun = {
+const AVFilter ff_vf_maskfun = {
     .name          = "maskfun",
     .description   = NULL_IF_CONFIG_SMALL("Create Mask."),
     .priv_size     = sizeof(MaskFunContext),
     .query_formats = query_formats,
+    .uninit        = uninit,
     .inputs        = maskfun_inputs,
     .outputs       = maskfun_outputs,
     .priv_class    = &maskfun_class,
     .flags         = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC | AVFILTER_FLAG_SLICE_THREADS,
+    .process_command = process_command,
 };