[FFmpeg-devel] [PATCH] vf_hue: add named options support

Stefano Sabatini stefasab at gmail.com
Thu Aug 16 01:09:29 CEST 2012


On date Wednesday 2012-08-15 21:50:25 +0200, Jérémy Tran encoded:
> Old syntax has been kept for compatibility reasons.
> ---
>  doc/filters.texi     | 44 +++++++++++++++++++++++++++++++++-----
>  libavfilter/vf_hue.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++------
>  2 files changed, 93 insertions(+), 11 deletions(-)
> 
> diff --git a/doc/filters.texi b/doc/filters.texi
> index 763085c..8783697 100644
> --- a/doc/filters.texi
> +++ b/doc/filters.texi
> @@ -2191,12 +2191,46 @@ 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:
>  
> - at var{hue} must be a float number that specifies the hue angle as a
> -number of degrees, and defaults to 0.0.
> - at var{saturation} must be a float number that specifies the saturation
> -in the [-10,10] range, and defaults to 1.0.
> + at table @option

> + at item h
> +a float number that specifies the hue angle as a
> +number of degrees, and defaults to 0.0

Nit: options *do* something, so this should be:

@item h
Specify the hue angle as a number of degrees. It accepts a float
number or an expression, and defaults to 0.0.

> + at item H
> +a float number that specifies the hue angle as a
> +number of radians, and defaults to 0.0
> + at item s
> +a float number that specifies the saturation
> +in the [-10,10] range, and defaults to 1.0

Ditto.

> + at 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:
> + at itemize
> + at item Set the hue to 90 degrees and the saturation to 1.0:
> + at example
> +hue=h=90:s=1
> + at end example
> +
> + at item Same command but expressing the hue in radians:
> + at example
> +hue=H=PI/2:s=1
> + at end example
> +
> + at item Same command without named options, hue must be expressed in degrees:
> + at example
> +hue=90:1
> + at end example
> +
> + at item This is wrong:

More explicative:

Note that "h:s" syntax does not support expressions for the values of
h and s, so the following example will issue an error:

> + at example
> +hue=PI/2:1
> + at end example
> + at end itemize
>  
>  @section idet
>  
> diff --git a/libavfilter/vf_hue.c b/libavfilter/vf_hue.c
> index 16fa4f4..4ee09c5 100644
> --- a/libavfilter/vf_hue.c
> +++ b/libavfilter/vf_hue.c
> @@ -25,7 +25,10 @@
>   * Ported from MPlayer libmpcodecs/vf_hue.c.
>   */
>  
> +#include <float.h>
> +#include "libavutil/eval.h"
>  #include "libavutil/imgutils.h"
> +#include "libavutil/opt.h"
>  #include "libavutil/pixdesc.h"
>  
>  #include "avfilter.h"
> @@ -33,8 +36,13 @@
>  #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 +50,42 @@ 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;
> +    float h = HUE_DEFAULT_VAL, s = SAT_DEFAULT_VAL;
>      int n;
>      char c1 = 0, c2 = 0;
> +    char *equal;
> +
> +    hue->class = &hue_class;
>  
> +    /* named options syntax */
> +    if (equal = strchr(args, '=')) {
> +        av_opt_set_defaults(hue);
> +        av_set_options_string(hue, args, "=", ":");
> +        if (hue->hue != -FLT_MAX && hue->hue_deg != -FLT_MAX) {
> +            av_log(ctx, AV_LOG_ERROR,

> +                   "H and h options have been both defined at the same time\n");

This is stating a true fact, but is not providing any hint to the user
that there is a problem and how to fix it (heck, what the hell should
I do now?).

More useful:
"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 +94,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 +101,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 +227,7 @@ AVFilter avfilter_vf_hue = {
>      .priv_size = sizeof(HueContext),
>  
>      .init          = init,
> +    .uninit        = uninit,
>      .query_formats = query_formats,

Should be fine otherwise, thanks and nice patch.
-- 
FFmpeg = Fostering and Fancy MultiPurpose Erratic Gnome


More information about the ffmpeg-devel mailing list