History

lavfi/hue: apply major simplifications, and switch to AVOption-based system

This also drops support for "flat syntax" and "reinit" command. "reinit" command is not very robust and complicates the logic more than necessary, since requires to reset all the options in the command. *This is a syntax break*.

Stefano Sabatini committed 13 years ago

Commit e4fd58f1 parent c36ab014 files · +66 −116Browse files

Unified · Split

4 files
  1. doc/filters.texi +20 −31
  2. libavfilter/avfilter.c +0 −1
  3. libavfilter/version.h +1 −1
  4. libavfilter/vf_hue.c +45 −83
doc/filters.texi+20−31
@@ -3653,24 +3653,27 @@ a float number which specifies chroma temporal strength, defaults to · 3652 unmodified lines
3653 3653
3654Modify the hue and/or the saturation of the input.3654Modify the hue and/or the saturation of the input.
3655 3655
3656This filter accepts the following optional named options:3656This filter accepts the following options:
3657 3657
3658@table @option3658@table @option
3659@item h3659@item h
3660Specify the hue angle as a number of degrees. It accepts a float3660Specify the hue angle as a number of degrees. It accepts an expression,
3661number or an expression, and defaults to 0.0.3661and defaults to "0".
3662
3663@item H
3664Specify the hue angle as a number of radians. It accepts a float
3665number or an expression, and defaults to 0.0.
3666 3662
3667@item s3663@item s
3668Specify the saturation in the [-10,10] range. It accepts a float number and3664Specify the saturation in the [-10,10] range. It accepts a float number and
3669defaults to 1.0.3665defaults to "1".
3666
3667@item H
3668Specify the hue angle as a number of radians. It accepts a float
3669number or an expression, and defaults to "0".
3670@end table3670@end table
3671 3671
3672The @var{h}, @var{H} and @var{s} parameters are expressions containing the3672@option{h} and @option{H} are mutually exclusive, and can't be
3673following constants:3673specified at the same time.
3674
3675The @option{h}, @option{H} and @option{s} option values are
3676expressions containing the following constants:
3674 3677
3675@table @option3678@table @option
3676@item n3679@item n
@@ -3689,10 +3692,6 @@ timestamp expressed in seconds, NAN if the input timestamp is unknown · 12 unmodified lines
3689time base of the input video3692time base of the input video
3690@end table3693@end table
3691 3694
3692The options can also be set using the syntax: @var{hue}:@var{saturation}
3693
3694In this case @var{hue} is expressed in degrees.
3695
3696@subsection Examples3695@subsection Examples
3697 3696
3698@itemize3697@itemize
@@ -3708,19 +3707,6 @@ Same command but expressing the hue in radians: · 9 unmodified lines
3708hue=H=PI/2:s=13707hue=H=PI/2:s=1
3709@end example3708@end example
3710 3709
3711@item
3712Same command without named options, hue must be expressed in degrees:
3713@example
3714hue=90:1
3715@end example
3716
3717@item
3718Note that "h:s" syntax does not support expressions for the values of
3719h and s, so the following example will issue an error:
3720@example
3721hue=PI/2:1
3722@end example
3723
3724@item3710@item
3725Rotate hue and make the saturation swing between 03711Rotate hue and make the saturation swing between 0
3726and 2 over a period of 1 second:3712and 2 over a period of 1 second:
@@ -3756,12 +3742,15 @@ hue="s=max(0\, min(1\, (START+DURATION-t)/DURATION))" · 29 unmodified lines
3756 3742
3757This filter supports the following command:3743This filter supports the following command:
3758@table @option3744@table @option
3759@item reinit3745@item s
3746@item h
3747@item H
3760Modify the hue and/or the saturation of the input video.3748Modify the hue and/or the saturation of the input video.
3761The command accepts the same named options and syntax than when calling the3749The command accepts the same options and syntax of the corresponding
3762filter from the command-line.3750options.
3763 3751
3764If a parameter is omitted, it is kept at its current value.3752If the specified expression is not valid, it is kept at its current
3753value.
3765@end table3754@end table
3766 3755
3767@section idet3756@section idet
libavfilter/avfilter.c+0−1
@@ -679,7 +679,6 @@ static const char *const filters_left_to_update[] = { · 678 unmodified lines
679 "atempo",679 "atempo",
680 "buffer",680 "buffer",
681 "flite",681 "flite",
682 "hue",
683 "mp",682 "mp",
684 "pan",683 "pan",
685 "scale",684 "scale",
libavfilter/version.h+1−1
@@ -30,7 +30,7 @@ · 29 unmodified lines
30 30
31#define LIBAVFILTER_VERSION_MAJOR 331#define LIBAVFILTER_VERSION_MAJOR 3
32#define LIBAVFILTER_VERSION_MINOR 5232#define LIBAVFILTER_VERSION_MINOR 52
33#define LIBAVFILTER_VERSION_MICRO 10133#define LIBAVFILTER_VERSION_MICRO 102
34 34
35#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \35#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
36 LIBAVFILTER_VERSION_MINOR, \36 LIBAVFILTER_VERSION_MINOR, \
libavfilter/vf_hue.c+45−83
@@ -36,12 +36,6 @@ · 35 unmodified lines
36#include "internal.h"36#include "internal.h"
37#include "video.h"37#include "video.h"
38 38
39#define HUE_DEFAULT_VAL 0
40#define SAT_DEFAULT_VAL 1
41
42#define HUE_DEFAULT_VAL_STRING AV_STRINGIFY(HUE_DEFAULT_VAL)
43#define SAT_DEFAULT_VAL_STRING AV_STRINGIFY(SAT_DEFAULT_VAL)
44
45#define SAT_MIN_VAL -1039#define SAT_MIN_VAL -10
46#define SAT_MAX_VAL 1040#define SAT_MAX_VAL 10
47 41
@@ -78,7 +72,6 @@ typedef struct { · 30 unmodified lines
78 int vsub;72 int vsub;
79 int32_t hue_sin;73 int32_t hue_sin;
80 int32_t hue_cos;74 int32_t hue_cos;
81 int flat_syntax;
82 double var_values[VAR_NB];75 double var_values[VAR_NB];
83} HueContext;76} HueContext;
84 77
@@ -87,9 +80,9 @@ typedef struct { · 2 unmodified lines
87static const AVOption hue_options[] = {80static const AVOption hue_options[] = {
88 { "h", "set the hue angle degrees expression", OFFSET(hue_deg_expr), AV_OPT_TYPE_STRING,81 { "h", "set the hue angle degrees expression", OFFSET(hue_deg_expr), AV_OPT_TYPE_STRING,
89 { .str = NULL }, .flags = FLAGS },82 { .str = NULL }, .flags = FLAGS },
90 { "H", "set the hue angle radians expression", OFFSET(hue_expr), AV_OPT_TYPE_STRING,
91 { .str = NULL }, .flags = FLAGS },
92 { "s", "set the saturation expression", OFFSET(saturation_expr), AV_OPT_TYPE_STRING,83 { "s", "set the saturation expression", OFFSET(saturation_expr), AV_OPT_TYPE_STRING,
84 { .str = "1" }, .flags = FLAGS },
85 { "H", "set the hue angle radians expression", OFFSET(hue_expr), AV_OPT_TYPE_STRING,
93 { .str = NULL }, .flags = FLAGS },86 { .str = NULL }, .flags = FLAGS },
94 { NULL }87 { NULL }
95};88};
@@ -107,99 +100,62 @@ static inline void compute_sin_and_cos(HueContext *hue) · 11 unmodified lines
107 hue->hue_cos = rint(cos(hue->hue) * (1 << 16) * hue->saturation);100 hue->hue_cos = rint(cos(hue->hue) * (1 << 16) * hue->saturation);
108}101}
109 102
110#define SET_EXPRESSION(attr, name) do { \103static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *log_ctx)
111 if (hue->attr##_expr) { \
112 if ((ret = av_expr_parse(&hue->attr##_pexpr, hue->attr##_expr, var_names, \
113 NULL, NULL, NULL, NULL, 0, ctx)) < 0) { \
114 av_log(ctx, AV_LOG_ERROR, \
115 "Parsing failed for expression " #name "='%s'", \
116 hue->attr##_expr); \
117 hue->attr##_expr = old_##attr##_expr; \
118 hue->attr##_pexpr = old_##attr##_pexpr; \
119 return AVERROR(EINVAL); \
120 } else if (old_##attr##_pexpr) { \
121 av_freep(&old_##attr##_expr); \
122 av_expr_free(old_##attr##_pexpr); \
123 old_##attr##_pexpr = NULL; \
124 } \
125 } else { \
126 hue->attr##_expr = old_##attr##_expr; \
127 } \
128} while (0)
129
130static inline int set_options(AVFilterContext *ctx, const char *args)
131{104{
132 HueContext *hue = ctx->priv;
133 int ret;105 int ret;
134 char *old_hue_expr, *old_hue_deg_expr, *old_saturation_expr;106 AVExpr *old = NULL;
135 AVExpr *old_hue_pexpr, *old_hue_deg_pexpr, *old_saturation_pexpr;107
136 static const char *shorthand[] = { "h", "s", NULL };108 if (*pexpr)
137 old_hue_expr = hue->hue_expr;109 old = *pexpr;
138 old_hue_deg_expr = hue->hue_deg_expr;110 ret = av_expr_parse(pexpr, expr, var_names,
139 old_saturation_expr = hue->saturation_expr;111 NULL, NULL, NULL, NULL, 0, log_ctx);
140 112 if (ret < 0) {
141 old_hue_pexpr = hue->hue_pexpr;113 av_log(log_ctx, AV_LOG_ERROR,
142 old_hue_deg_pexpr = hue->hue_deg_pexpr;114 "Error when evaluating the expression '%s' for %s\n",
143 old_saturation_pexpr = hue->saturation_pexpr;115 expr, option);
144 116 *pexpr = old;
145 hue->hue_expr = NULL;
146 hue->hue_deg_expr = NULL;
147 hue->saturation_expr = NULL;
148
149 if ((ret = av_opt_set_from_string(hue, args, shorthand, "=", ":")) < 0)
150 return ret;117 return ret;
118 }
119 av_expr_free(old);
120 return 0;
121}
122
123static av_cold int init(AVFilterContext *ctx, const char *args)
124{
125 HueContext *hue = ctx->priv;
126 int ret;
127
151 if (hue->hue_expr && hue->hue_deg_expr) {128 if (hue->hue_expr && hue->hue_deg_expr) {
152 av_log(ctx, AV_LOG_ERROR,129 av_log(ctx, AV_LOG_ERROR,
153 "H and h options are incompatible and cannot be specified "130 "H and h options are incompatible and cannot be specified "
154 "at the same time\n");131 "at the same time\n");
155 hue->hue_expr = old_hue_expr;
156 hue->hue_deg_expr = old_hue_deg_expr;
157
158 return AVERROR(EINVAL);132 return AVERROR(EINVAL);
159 }133 }
160 134
161 SET_EXPRESSION(hue_deg, h);135#define SET_EXPR(expr, option) \
162 SET_EXPRESSION(hue, H);136 if (hue->expr##_expr) do { \
163 SET_EXPRESSION(saturation, s);137 ret = set_expr(&hue->expr##_pexpr, hue->expr##_expr, option, ctx); \
164 138 if (ret < 0) \
165 hue->flat_syntax = 0;139 return ret; \
140 } while (0)
141 SET_EXPR(saturation, "s");
142 SET_EXPR(hue_deg, "h");
143 SET_EXPR(hue, "H");
166 144
167 av_log(ctx, AV_LOG_VERBOSE,145 av_log(ctx, AV_LOG_VERBOSE,
168 "H_expr:%s h_deg_expr:%s s_expr:%s\n",146 "H_expr:%s h_deg_expr:%s s_expr:%s\n",
169 hue->hue_expr, hue->hue_deg_expr, hue->saturation_expr);147 hue->hue_expr, hue->hue_deg_expr, hue->saturation_expr);
170
171 compute_sin_and_cos(hue);148 compute_sin_and_cos(hue);
172 149
173 return 0;150 return 0;
174}151}
175 152
176static av_cold int init(AVFilterContext *ctx, const char *args)
177{
178 HueContext *hue = ctx->priv;
179
180 hue->class = &hue_class;
181 av_opt_set_defaults(hue);
182
183 hue->saturation = SAT_DEFAULT_VAL;
184 hue->hue = HUE_DEFAULT_VAL;
185 hue->hue_deg_pexpr = NULL;
186 hue->hue_pexpr = NULL;
187 hue->flat_syntax = 1;
188
189 return set_options(ctx, args);
190}
191
192static av_cold void uninit(AVFilterContext *ctx)153static av_cold void uninit(AVFilterContext *ctx)
193{154{
194 HueContext *hue = ctx->priv;155 HueContext *hue = ctx->priv;
195 156
196 av_opt_free(hue);
197
198 av_free(hue->hue_deg_expr);
199 av_expr_free(hue->hue_deg_pexpr);157 av_expr_free(hue->hue_deg_pexpr);
200 av_free(hue->hue_expr);
201 av_expr_free(hue->hue_pexpr);158 av_expr_free(hue->hue_pexpr);
202 av_free(hue->saturation_expr);
203 av_expr_free(hue->saturation_pexpr);159 av_expr_free(hue->saturation_pexpr);
204}160}
205 161
@@ -295,7 +251,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) · 89 unmodified lines
295 av_frame_copy_props(outpic, inpic);251 av_frame_copy_props(outpic, inpic);
296 }252 }
297 253
298 if (!hue->flat_syntax) {254 /* todo: reindent */
299 hue->var_values[VAR_T] = TS2T(inpic->pts, inlink->time_base);255 hue->var_values[VAR_T] = TS2T(inpic->pts, inlink->time_base);
300 hue->var_values[VAR_PTS] = TS2D(inpic->pts);256 hue->var_values[VAR_PTS] = TS2D(inpic->pts);
301 257
@@ -323,7 +279,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) · 21 unmodified lines
323 hue->var_values[VAR_T], (int)hue->var_values[VAR_N]);279 hue->var_values[VAR_T], (int)hue->var_values[VAR_N]);
324 280
325 compute_sin_and_cos(hue);281 compute_sin_and_cos(hue);
326 }
327 282
328 hue->var_values[VAR_N] += 1;283 hue->var_values[VAR_N] += 1;
329 284
@@ -345,10 +300,17 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *inpic) · 15 unmodified lines
345static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,300static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
346 char *res, int res_len, int flags)301 char *res, int res_len, int flags)
347{302{
348 if (!strcmp(cmd, "reinit"))303 HueContext *hue = ctx->priv;
349 return set_options(ctx, args);304
350 else305#define SET_CMD(expr, option) \
351 return AVERROR(ENOSYS);306 if (!strcmp(cmd, option)) do { \
307 return set_expr(&hue->expr##_pexpr, args, cmd, ctx); \
308 } while (0)
309 SET_CMD(hue_deg, "h");
310 SET_CMD(hue, "H");
311 SET_CMD(saturation, "s");
312
313 return AVERROR(ENOSYS);
352}314}
353 315
354static const AVFilterPad hue_inputs[] = {316static const AVFilterPad hue_inputs[] = {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t