[FFmpeg-devel] [PATCH] vf_unsharp: extend unsharp syntax, for supporting named options

Stefano Sabatini stefano.sabatini-lala at poste.it
Sat Aug 13 16:36:46 CEST 2011


Make setting params less awkward.

The old syntax is kept for backward compatibility.
---
 doc/filters.texi         |    7 +++++
 libavfilter/vf_unsharp.c |   59 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 0 deletions(-)

diff --git a/doc/filters.texi b/doc/filters.texi
index 191d8a4..32630f7 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -1776,6 +1776,11 @@ Sharpen or blur the input video.
 It accepts the following parameters:
 @var{luma_msize_x}:@var{luma_msize_y}:@var{luma_amount}:@var{chroma_msize_x}:@var{chroma_msize_y}:@var{chroma_amount}
 
+Alternatively it is possible to specify separately the luma or chroma
+component through a string of the form:
+"@var{msize_x}x at var{msize_y}[-+]@var{amount} using the :-separated
+ at opt{luma}/@opt{l} and @opt{chroma}/@opt{c} options.
+
 Negative values for the amount will blur the input video, while positive
 values will sharpen. All parameters are optional and default to the
 equivalent of the string '5:5:1.0:5:5:0.0'.
@@ -1811,9 +1816,11 @@ and 5.0, default value is 0.0.
 @example
 # Strong luma sharpen effect parameters
 unsharp=7:7:2.5
+unsharp=l=7x7+2.5
 
 # Strong blur of both luma and chroma parameters
 unsharp=7:7:-2:7:7:-2
+unsharp=l=7x7-2:c=7x7-2
 
 # Use the default values with @command{ffmpeg}
 ./ffmpeg -i in.avi -vf "unsharp" out.mp4
diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c
index ed8eef8..80859bd 100644
--- a/libavfilter/vf_unsharp.c
+++ b/libavfilter/vf_unsharp.c
@@ -39,6 +39,7 @@
 #include "avfilter.h"
 #include "libavutil/common.h"
 #include "libavutil/mem.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 
 #define MATRIX_MIN_LINE_SIZE 3
@@ -60,11 +61,34 @@ typedef struct FilterParam {
 } FilterParam;
 
 typedef struct {
+    const AVClass *class;
     FilterParam luma;   ///< luma parameters (width, height, amount)
     FilterParam chroma; ///< chroma parameters (width, height, amount)
     int hsub, vsub;
+    char *luma_str, *chroma_str;
 } UnsharpContext;
 
+#define OFFSET(x) offsetof(UnsharpContext, x)
+
+static const AVOption unsharp_options[] = {
+    {"luma",   "set luma parameters",        OFFSET(luma_str),   FF_OPT_TYPE_STRING, {.str="5x5+1"}, CHAR_MIN, CHAR_MAX },
+    {"l",      "set luma parameters",        OFFSET(luma_str),   FF_OPT_TYPE_STRING, {.str="5x5+1"}, CHAR_MIN, CHAR_MAX },
+    {"chroma", "set chroma parameters file", OFFSET(chroma_str), FF_OPT_TYPE_STRING, {.str="5x5+0"},    CHAR_MIN, CHAR_MAX },
+    {"c",      "set chroma parameters file", OFFSET(chroma_str), FF_OPT_TYPE_STRING, {.str="5x5+0"},    CHAR_MIN, CHAR_MAX },
+    {NULL}
+};
+
+static const char *unsharp_get_name(void *ctx)
+{
+    return "unsharp";
+}
+
+static const AVClass unsharp_class = {
+    "UnsharpContext",
+    unsharp_get_name,
+    unsharp_options
+};
+
 static void apply_unsharp(      uint8_t *dst, int dst_stride,
                           const uint8_t *src, int src_stride,
                           int width, int height, FilterParam *fp)
@@ -130,17 +154,49 @@ static void set_filter_param(FilterParam *fp, int msize_x, int msize_y, double a
     fp->halfscale = 1 << (fp->scalebits - 1);
 }
 
+static int parse_component_params(int *msize_x, int *msize_y, double *amount,
+                                 char *params, void *log_ctx)
+{
+    int n;
+    char sign;
+
+    n = sscanf(params, "%dx%d%c%lf", msize_x, msize_y, &sign, amount);
+    if (n != 4 || (sign != '+' && sign != '-')) {
+        av_log(log_ctx, AV_LOG_ERROR,
+               "Invalid component parameters '%s', must be of the form "
+               "'XxY[+-]A'\n", params);
+        return AVERROR(EINVAL);
+    }
+    if (sign == '-')
+        *amount *= -1;
+
+    return 0;
+}
+
 static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque)
 {
     UnsharpContext *unsharp = ctx->priv;
     int lmsize_x = 5, cmsize_x = 5;
     int lmsize_y = 5, cmsize_y = 5;
+    int ret, val;
     double lamount = 1.0f, camount = 0.0f;
     int val;
 
+    unsharp->class = &unsharp_class;
+    av_opt_set_defaults2(unsharp, 0, 0);
+
     if (args)
+        ret =
         sscanf(args, "%d:%d:%lf:%d:%d:%lf", &lmsize_x, &lmsize_y, &lamount,
                                             &cmsize_x, &cmsize_y, &camount);
+    if (!ret) {
+        if ((ret = av_set_options_string(unsharp, args, "=", ":")) < 0 ||
+            (ret = parse_component_params(&lmsize_x, &lmsize_y, &lamount,
+                                          unsharp->luma_str, ctx)) < 0  ||
+            (ret = parse_component_params(&cmsize_x, &cmsize_y, &camount,
+                                          unsharp->chroma_str, ctx)) < 0)
+            return ret;
+    }
 
 #define CHECK_SIZE(lc, xy, lc_str)                                      \
     val = lc##msize_##xy;                                               \
@@ -215,6 +271,9 @@ static av_cold void uninit(AVFilterContext *ctx)
 {
     UnsharpContext *unsharp = ctx->priv;
 
+    av_freep(&unsharp->luma_str);
+    av_freep(&unsharp->chroma_str);
+
     free_filter_param(&unsharp->luma);
     free_filter_param(&unsharp->chroma);
 }
-- 
1.7.2.5



More information about the ffmpeg-devel mailing list