[FFmpeg-devel] [PATCH] lavfi/crop: add support for x/y commands

Stefano Sabatini stefasab at gmail.com
Wed Jul 10 17:51:08 CEST 2013


TODO: bump micro
---
 doc/filters.texi      | 14 ++++++++++++++
 libavfilter/vf_crop.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 67 insertions(+)

diff --git a/doc/filters.texi b/doc/filters.texi
index 92f8612..9e95f2c 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -2503,6 +2503,20 @@ is approximated to the nearest valid value.
 The expression for @var{x} may depend on @var{y}, and the expression
 for @var{y} may depend on @var{x}.
 
+ at subsection Commands
+
+This filter supports the following commands:
+ at table @option
+ at item x
+ at item y
+ at item H
+Modify the x and/or the y position of the cropped area.
+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 end table
+
 @subsection Examples
 
 @itemize
diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c
index 832e6cf..4c63107 100644
--- a/libavfilter/vf_crop.c
+++ b/libavfilter/vf_crop.c
@@ -292,6 +292,58 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame)
     return ff_filter_frame(link->dst->outputs[0], frame);
 }
 
+static int set_expr(AVExpr **pexpr_ptr, char **expr_ptr,
+                    const char *expr, const char *option, void *log_ctx)
+{
+    int ret;
+    AVExpr *new_pexpr;
+    char *new_expr;
+
+    new_expr = av_strdup(expr);
+    if (!new_expr)
+        return AVERROR(ENOMEM);
+    ret = av_expr_parse(&new_pexpr, expr, var_names,
+                        NULL, NULL, NULL, NULL, 0, log_ctx);
+    if (ret < 0) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "Error when evaluating the expression '%s' for %s\n",
+               expr, option);
+        av_free(new_expr);
+        return ret;
+    }
+
+    if (*pexpr_ptr)
+        av_expr_free(*pexpr_ptr);
+    *pexpr_ptr = new_pexpr;
+    av_freep(expr_ptr);
+    *expr_ptr = new_expr;
+
+    return 0;
+}
+
+static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
+                           char *res, int res_len, int flags)
+{
+    CropContext *crop = ctx->priv;
+
+#define SET_EXPR(expr, option)                                          \
+    do {                                                                \
+        int ret = set_expr(&crop->expr##_pexpr, &crop->expr##_expr,     \
+                           args, option, ctx);                          \
+        if (ret < 0)                                                    \
+            return ret;                                                 \
+    } while (0)
+
+    if (!strcmp(cmd, "x")) {
+        SET_EXPR(x, "x");
+    } else if (!strcmp(cmd, "y")) {
+        SET_EXPR(y, "y");
+    } else
+        return AVERROR(ENOSYS);
+
+    return 0;
+}
+
 #define OFFSET(x) offsetof(CropContext, x)
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
 
@@ -340,4 +392,5 @@ AVFilter avfilter_vf_crop = {
 
     .inputs    = avfilter_vf_crop_inputs,
     .outputs   = avfilter_vf_crop_outputs,
+    .process_command = process_command,
 };
-- 
1.8.1.2



More information about the ffmpeg-devel mailing list