libavfilter/vf_crop: implement process_command
authorBernd Bleßmann <bb@it-entwicklung.de>
Tue, 21 Jul 2015 10:48:33 +0000 (12:48 +0200)
committerMichael Niedermayer <michael@niedermayer.cc>
Tue, 21 Jul 2015 17:19:36 +0000 (19:19 +0200)
Signed-off-by: Bernd Bleßmann <bb@it-entwicklung.de>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
doc/filters.texi
libavfilter/vf_crop.c

index 28aaef3..348e8d7 100644 (file)
@@ -3481,12 +3481,12 @@ It accepts the following parameters:
 @item w, out_w
 The width of the output video. It defaults to @code{iw}.
 This expression is evaluated only once during the filter
-configuration.
+configuration, or when the @samp{w} or @samp{out_w} command is sent.
 
 @item h, out_h
 The height of the output video. It defaults to @code{ih}.
 This expression is evaluated only once during the filter
-configuration.
+configuration, or when the @samp{h} or @samp{out_h} command is sent.
 
 @item x
 The horizontal position, in the input video, of the left edge of the output
@@ -3646,6 +3646,22 @@ crop=in_w/2:in_h/2:y:10+10*sin(n/10)
 @end example
 @end itemize
 
+@subsection Commands
+
+This filter supports the following commands:
+@table @option
+@item w, out_w
+@item h, out_h
+@item x
+@item y
+Set width/height of the output video and the horizontal/vertical position
+in the input video.
+The command accepts the same syntax of the corresponding option.
+
+If the specified expression is not valid, it is kept at its current
+value.
+@end table
+
 @section cropdetect
 
 Auto-detect the crop size.
index f58a7ae..5679a44 100644 (file)
@@ -296,6 +296,42 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame)
     return ff_filter_frame(link->dst->outputs[0], frame);
 }
 
+static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+                           char *res, int res_len, int flags)
+{
+    CropContext *s = ctx->priv;
+    int ret;
+
+    if (   !strcmp(cmd, "out_w")  || !strcmp(cmd, "w")
+        || !strcmp(cmd, "out_h")  || !strcmp(cmd, "h")
+        || !strcmp(cmd, "x")      || !strcmp(cmd, "y")) {
+
+        int old_x = s->x;
+        int old_y = s->y;
+        int old_w = s->w;
+        int old_h = s->h;
+
+        AVFilterLink *outlink = ctx->outputs[0];
+        AVFilterLink *inlink  = ctx->inputs[0];
+
+        av_opt_set(s, cmd, args, 0);
+
+        if ((ret = config_input(inlink)) < 0) {
+            s->x = old_x;
+            s->y = old_y;
+            s->w = old_w;
+            s->h = old_h;
+            return ret;
+        }
+
+        ret = config_output(outlink);
+
+    } else
+        ret = AVERROR(ENOSYS);
+
+    return ret;
+}
+
 #define OFFSET(x) offsetof(CropContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 
@@ -332,12 +368,13 @@ static const AVFilterPad avfilter_vf_crop_outputs[] = {
 };
 
 AVFilter ff_vf_crop = {
-    .name          = "crop",
-    .description   = NULL_IF_CONFIG_SMALL("Crop the input video."),
-    .priv_size     = sizeof(CropContext),
-    .priv_class    = &crop_class,
-    .query_formats = query_formats,
-    .uninit        = uninit,
-    .inputs        = avfilter_vf_crop_inputs,
-    .outputs       = avfilter_vf_crop_outputs,
+    .name            = "crop",
+    .description     = NULL_IF_CONFIG_SMALL("Crop the input video."),
+    .priv_size       = sizeof(CropContext),
+    .priv_class      = &crop_class,
+    .query_formats   = query_formats,
+    .uninit          = uninit,
+    .inputs          = avfilter_vf_crop_inputs,
+    .outputs         = avfilter_vf_crop_outputs,
+    .process_command = process_command,
 };