lavfi/hue: add named options support
authorJérémy Tran <tran.jeremy.av@gmail.com>
Thu, 16 Aug 2012 07:15:58 +0000 (09:15 +0200)
committerStefano Sabatini <stefasab@gmail.com>
Thu, 16 Aug 2012 13:01:05 +0000 (15:01 +0200)
Old syntax has been kept for compatibility reasons.

Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
doc/filters.texi
libavfilter/version.h
libavfilter/vf_hue.c

index dff3cc2..f4c895a 100644 (file)
@@ -2191,12 +2191,53 @@ a float number which specifies chroma temporal strength, defaults to
 
 Modify the hue and/or the saturation of the input.
 
-This filter accepts the optional parameters: @var{hue}:@var{saturation}.
+This filter accepts the following optional named options:
 
-@var{hue} must be a float number that specifies the hue angle as a
-number of degrees, and defaults to 0.0.
-@var{saturation} must be a float number that specifies the saturation
-in the [-10,10] range, and defaults to 1.0.
+@table @option
+@item h
+Specify the hue angle as a number of degrees. It accepts a float
+number or an expression, and defaults to 0.0.
+
+@item H
+Specify the hue angle as a number of degrees. It accepts a float
+number or an expression, and defaults to 0.0.
+
+@item s
+Specify the saturation in the [-10,10] range. It accepts a float number and
+defaults to 1.0.
+@end table
+
+The options can also be set using the syntax: @var{hue}:@var{saturation}
+
+In this case @var{hue} is expressed in degrees.
+
+Some examples follow:
+@itemize
+@item
+Set the hue to 90 degrees and the saturation to 1.0:
+@example
+hue=h=90:s=1
+@end example
+
+@item
+Same command but expressing the hue in radians:
+@example
+hue=H=PI/2:s=1
+@end example
+
+@item
+Same command without named options, hue must be expressed in degrees:
+@example
+hue=90:1
+@end example
+
+@item
+Note that "h:s" syntax does not support expressions for the values of
+h and s, so the following example will issue an error:
+@example
+hue=PI/2:1
+@end example
+@end itemize
 
 @section idet
 
index 85a839f..b2ef311 100644 (file)
@@ -30,7 +30,7 @@
 
 #define LIBAVFILTER_VERSION_MAJOR  3
 #define LIBAVFILTER_VERSION_MINOR  9
-#define LIBAVFILTER_VERSION_MICRO 101
+#define LIBAVFILTER_VERSION_MICRO 102
 
 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
                                                LIBAVFILTER_VERSION_MINOR, \
index 16fa4f4..0bc4d92 100644 (file)
@@ -25,7 +25,9 @@
  * Ported from MPlayer libmpcodecs/vf_hue.c.
  */
 
+#include <float.h>
 #include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
 #include "libavutil/pixdesc.h"
 
 #include "avfilter.h"
 #include "internal.h"
 #include "video.h"
 
+#define HUE_DEFAULT_VAL 0
+#define SAT_DEFAULT_VAL 1
+
 typedef struct {
-    float    hue;
+    const    AVClass *class;
+    float    hue_deg; /* hue expressed in degrees */
+    float    hue; /* hue expressed in radians */
     float    saturation;
     int      hsub;
     int      vsub;
@@ -42,13 +49,44 @@ typedef struct {
     int32_t hue_cos;
 } HueContext;
 
+#define OFFSET(x) offsetof(HueContext, x)
+static const AVOption hue_options[] = {
+    { "h", "set the hue angle degrees", OFFSET(hue_deg), AV_OPT_TYPE_FLOAT,
+      { -FLT_MAX }, -FLT_MAX, FLT_MAX, AV_OPT_FLAG_VIDEO_PARAM },
+    { "H", "set the hue angle radians", OFFSET(hue), AV_OPT_TYPE_FLOAT,
+      { -FLT_MAX }, -FLT_MAX, FLT_MAX, AV_OPT_FLAG_VIDEO_PARAM },
+    { "s", "set the saturation value", OFFSET(saturation), AV_OPT_TYPE_FLOAT,
+      { SAT_DEFAULT_VAL }, -10, 10, AV_OPT_FLAG_VIDEO_PARAM },
+    { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(hue);
+
 static av_cold int init(AVFilterContext *ctx, const char *args)
 {
     HueContext *hue = ctx->priv;
-    float h = 0, s = 1;
-    int n;
+    float h = HUE_DEFAULT_VAL, s = SAT_DEFAULT_VAL;
+    int n, ret;
     char c1 = 0, c2 = 0;
+    char *equal;
+
+    hue->class = &hue_class;
 
+    /* named options syntax */
+    if (equal = strchr(args, '=')) {
+        av_opt_set_defaults(hue);
+        if ((ret = av_set_options_string(hue, args, "=", ":")) < 0)
+            return ret;
+        if (hue->hue != -FLT_MAX && hue->hue_deg != -FLT_MAX) {
+            av_log(ctx, AV_LOG_ERROR,
+                   "H and h options are incompatible and cannot be specified "
+                   "at the same time\n");
+            return AVERROR(EINVAL);
+        }
+        if (hue->hue == -FLT_MAX)
+            hue->hue = HUE_DEFAULT_VAL;
+    /* compatibility syntax */
+    } else {
     if (args) {
         n = sscanf(args, "%f%c%f%c", &h, &c1, &s, &c2);
         if (n != 0 && n != 1 && (n != 3 || c1 != ':')) {
@@ -57,7 +95,6 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
                    "must be in the form 'hue[:saturation]'\n", args);
             return AVERROR(EINVAL);
         }
-    }
 
     if (s < -10 || s > 10) {
         av_log(ctx, AV_LOG_ERROR,
@@ -65,14 +102,25 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
                "must be included between range -10 and +10\n", s);
         return AVERROR(EINVAL);
     }
-
-    /* Convert angle from degree to radian */
-    hue->hue = h * M_PI / 180;
+    }
+    hue->hue_deg = h;
     hue->saturation = s;
+    }
+
+    if (hue->hue_deg != -FLT_MAX)
+        /* Convert angle from degrees to radians */
+        hue->hue = hue->hue_deg * M_PI / 180;
 
     return 0;
 }
 
+static av_cold void uninit(AVFilterContext *ctx)
+{
+    HueContext *hue = ctx->priv;
+
+    av_opt_free(hue);
+}
+
 static int query_formats(AVFilterContext *ctx)
 {
     static const enum PixelFormat pix_fmts[] = {
@@ -180,6 +228,7 @@ AVFilter avfilter_vf_hue = {
     .priv_size = sizeof(HueContext),
 
     .init          = init,
+    .uninit        = uninit,
     .query_formats = query_formats,
 
     .inputs = (const AVFilterPad[]) {