mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-24 13:56:33 +02:00
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:
parent
6efce3a894
commit
191b77eb01
@ -2191,12 +2191,53 @@ a float number which specifies chroma temporal strength, defaults to
|
|||||||
|
|
||||||
Modify the hue and/or the saturation of the input.
|
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
|
@table @option
|
||||||
number of degrees, and defaults to 0.0.
|
@item h
|
||||||
@var{saturation} must be a float number that specifies the saturation
|
Specify the hue angle as a number of degrees. It accepts a float
|
||||||
in the [-10,10] range, and defaults to 1.0.
|
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
|
@section idet
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#define LIBAVFILTER_VERSION_MAJOR 3
|
#define LIBAVFILTER_VERSION_MAJOR 3
|
||||||
#define LIBAVFILTER_VERSION_MINOR 9
|
#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, \
|
#define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \
|
||||||
LIBAVFILTER_VERSION_MINOR, \
|
LIBAVFILTER_VERSION_MINOR, \
|
||||||
|
@ -25,7 +25,9 @@
|
|||||||
* Ported from MPlayer libmpcodecs/vf_hue.c.
|
* Ported from MPlayer libmpcodecs/vf_hue.c.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
#include "libavutil/imgutils.h"
|
#include "libavutil/imgutils.h"
|
||||||
|
#include "libavutil/opt.h"
|
||||||
#include "libavutil/pixdesc.h"
|
#include "libavutil/pixdesc.h"
|
||||||
|
|
||||||
#include "avfilter.h"
|
#include "avfilter.h"
|
||||||
@ -33,8 +35,13 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
|
||||||
|
#define HUE_DEFAULT_VAL 0
|
||||||
|
#define SAT_DEFAULT_VAL 1
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
float hue;
|
const AVClass *class;
|
||||||
|
float hue_deg; /* hue expressed in degrees */
|
||||||
|
float hue; /* hue expressed in radians */
|
||||||
float saturation;
|
float saturation;
|
||||||
int hsub;
|
int hsub;
|
||||||
int vsub;
|
int vsub;
|
||||||
@ -42,13 +49,44 @@ typedef struct {
|
|||||||
int32_t hue_cos;
|
int32_t hue_cos;
|
||||||
} HueContext;
|
} 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)
|
static av_cold int init(AVFilterContext *ctx, const char *args)
|
||||||
{
|
{
|
||||||
HueContext *hue = ctx->priv;
|
HueContext *hue = ctx->priv;
|
||||||
float h = 0, s = 1;
|
float h = HUE_DEFAULT_VAL, s = SAT_DEFAULT_VAL;
|
||||||
int n;
|
int n, ret;
|
||||||
char c1 = 0, c2 = 0;
|
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) {
|
if (args) {
|
||||||
n = sscanf(args, "%f%c%f%c", &h, &c1, &s, &c2);
|
n = sscanf(args, "%f%c%f%c", &h, &c1, &s, &c2);
|
||||||
if (n != 0 && n != 1 && (n != 3 || c1 != ':')) {
|
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);
|
"must be in the form 'hue[:saturation]'\n", args);
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (s < -10 || s > 10) {
|
if (s < -10 || s > 10) {
|
||||||
av_log(ctx, AV_LOG_ERROR,
|
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);
|
"must be included between range -10 and +10\n", s);
|
||||||
return AVERROR(EINVAL);
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* Convert angle from degree to radian */
|
hue->hue_deg = h;
|
||||||
hue->hue = h * M_PI / 180;
|
|
||||||
hue->saturation = s;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static av_cold void uninit(AVFilterContext *ctx)
|
||||||
|
{
|
||||||
|
HueContext *hue = ctx->priv;
|
||||||
|
|
||||||
|
av_opt_free(hue);
|
||||||
|
}
|
||||||
|
|
||||||
static int query_formats(AVFilterContext *ctx)
|
static int query_formats(AVFilterContext *ctx)
|
||||||
{
|
{
|
||||||
static const enum PixelFormat pix_fmts[] = {
|
static const enum PixelFormat pix_fmts[] = {
|
||||||
@ -180,6 +228,7 @@ AVFilter avfilter_vf_hue = {
|
|||||||
.priv_size = sizeof(HueContext),
|
.priv_size = sizeof(HueContext),
|
||||||
|
|
||||||
.init = init,
|
.init = init,
|
||||||
|
.uninit = uninit,
|
||||||
.query_formats = query_formats,
|
.query_formats = query_formats,
|
||||||
|
|
||||||
.inputs = (const AVFilterPad[]) {
|
.inputs = (const AVFilterPad[]) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user