lavfi/hue: add named options support

Old syntax has been kept for compatibility reasons.

Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
This commit is contained in:
Jérémy Tran 2012-08-16 09:15:58 +02:00 committed by Stefano Sabatini
parent 6efce3a894
commit 191b77eb01
3 changed files with 103 additions and 13 deletions

View 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

View 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, \

View 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"
@ -33,8 +35,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 +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[]) {