You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-15 14:13:16 +02:00
lavfi/curves: add presets support.
Except for the vintage preset, the values are defined by Lou Logan based on the ones found in Adobe Photoshop CS6. Signed-off-by: Clément Bœsch <ubitux@gmail.com> Signed-off-by: Lou Logan <lou@lrcd.com>
This commit is contained in:
@@ -2340,6 +2340,22 @@ Set the key points for the red component.
|
|||||||
Set the key points for the green component.
|
Set the key points for the green component.
|
||||||
@item blue, b
|
@item blue, b
|
||||||
Set the key points for the blue component.
|
Set the key points for the blue component.
|
||||||
|
@item preset
|
||||||
|
Select one of the available color presets. This option can not be used in
|
||||||
|
addition to the @option{r}, @option{g}, @option{b} parameters.
|
||||||
|
Available presets are:
|
||||||
|
@table @samp
|
||||||
|
@item color_negative
|
||||||
|
@item cross_process
|
||||||
|
@item darker
|
||||||
|
@item increase_contrast
|
||||||
|
@item lighter
|
||||||
|
@item linear_contrast
|
||||||
|
@item medium_contrast
|
||||||
|
@item negative
|
||||||
|
@item vintage
|
||||||
|
@end table
|
||||||
|
Default is unset.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
To avoid some filtergraph syntax conflicts, each key points list need to be
|
To avoid some filtergraph syntax conflicts, each key points list need to be
|
||||||
@@ -2368,6 +2384,12 @@ Here we obtain the following coordinates for each components:
|
|||||||
@item blue
|
@item blue
|
||||||
@code{(0;0.22) (0.49;0.44) (1;0.80)}
|
@code{(0;0.22) (0.49;0.44) (1;0.80)}
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@item
|
||||||
|
The previous example can also be achieved with the associated built-in preset:
|
||||||
|
@example
|
||||||
|
curves=preset=vintage
|
||||||
|
@end example
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@section decimate
|
@section decimate
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#define LIBAVFILTER_VERSION_MAJOR 3
|
#define LIBAVFILTER_VERSION_MAJOR 3
|
||||||
#define LIBAVFILTER_VERSION_MINOR 48
|
#define LIBAVFILTER_VERSION_MINOR 48
|
||||||
#define LIBAVFILTER_VERSION_MICRO 102
|
#define LIBAVFILTER_VERSION_MICRO 103
|
||||||
|
|
||||||
#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, \
|
||||||
|
@@ -35,6 +35,7 @@ struct keypoint {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
|
char *preset;
|
||||||
char *comp_points_str[NB_COMP];
|
char *comp_points_str[NB_COMP];
|
||||||
uint8_t graph[NB_COMP][256];
|
uint8_t graph[NB_COMP][256];
|
||||||
} CurvesContext;
|
} CurvesContext;
|
||||||
@@ -48,11 +49,56 @@ static const AVOption curves_options[] = {
|
|||||||
{ "g", "set green points coordinates", OFFSET(comp_points_str[1]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
|
{ "g", "set green points coordinates", OFFSET(comp_points_str[1]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
|
||||||
{ "blue", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
|
{ "blue", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
|
||||||
{ "b", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
|
{ "b", "set blue points coordinates", OFFSET(comp_points_str[2]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
|
||||||
|
{ "preset", "select a color curves preset", OFFSET(preset), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
AVFILTER_DEFINE_CLASS(curves);
|
AVFILTER_DEFINE_CLASS(curves);
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char *name;
|
||||||
|
const char *r;
|
||||||
|
const char *g;
|
||||||
|
const char *b;
|
||||||
|
} curves_presets[] = { {
|
||||||
|
"color_negative",
|
||||||
|
"0/1 0.129/1 0.466/0.498 0.725/0 1/0",
|
||||||
|
"0/1 0.109/1 0.301/0.498 0.517/0 1/0",
|
||||||
|
"0/1 0.098/1 0.235/0.498 0.423/0 1/0",
|
||||||
|
},{
|
||||||
|
"cross_process",
|
||||||
|
"0.25/0.156 0.501/0.501 0.686/0.745",
|
||||||
|
"0.25/0.188 0.38/0.501 0.745/0.815 1/0.815",
|
||||||
|
"0.231/0.094 0.709/0.874",
|
||||||
|
},{
|
||||||
|
"darker", "0.5/0.4", "0.5/0.4", "0.5/0.4",
|
||||||
|
},{
|
||||||
|
"increase_contrast",
|
||||||
|
"0.149/0.066 0.831/0.905 0.905/0.98",
|
||||||
|
"0.149/0.066 0.831/0.905 0.905/0.98",
|
||||||
|
"0.149/0.066 0.831/0.905 0.905/0.98",
|
||||||
|
},{
|
||||||
|
"lighter", "0.4/0.5", "0.4/0.5", "0.4/0.5",
|
||||||
|
},{
|
||||||
|
"linear_contrast",
|
||||||
|
"0.305/0.286 0.694/0.713",
|
||||||
|
"0.305/0.286 0.694/0.713",
|
||||||
|
"0.305/0.286 0.694/0.713",
|
||||||
|
},{
|
||||||
|
"medium_contrast",
|
||||||
|
"0.286/0.219 0.639/0.643",
|
||||||
|
"0.286/0.219 0.639/0.643",
|
||||||
|
"0.286/0.219 0.639/0.643",
|
||||||
|
},{
|
||||||
|
"negative", "0/1 1/0", "0/1 1/0", "0/1 1/0",
|
||||||
|
},{
|
||||||
|
"vintage",
|
||||||
|
"0/0.11 0.42/0.51 1/0.95",
|
||||||
|
"0.50/0.48",
|
||||||
|
"0/0.22 0.49/0.44 1/0.8",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static struct keypoint *make_point(double x, double y, struct keypoint *next)
|
static struct keypoint *make_point(double x, double y, struct keypoint *next)
|
||||||
{
|
{
|
||||||
struct keypoint *point = av_mallocz(sizeof(*point));
|
struct keypoint *point = av_mallocz(sizeof(*point));
|
||||||
@@ -247,6 +293,33 @@ static av_cold int init(AVFilterContext *ctx, const char *args)
|
|||||||
if ((ret = av_set_options_string(curves, args, "=", ":")) < 0)
|
if ((ret = av_set_options_string(curves, args, "=", ":")) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
if (curves->preset) {
|
||||||
|
char **pts = curves->comp_points_str;
|
||||||
|
if (pts[0] || pts[1] || pts[2]) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "It is not possible to mix a preset "
|
||||||
|
"with explicit points placements\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
for (i = 0; i < FF_ARRAY_ELEMS(curves_presets); i++) {
|
||||||
|
if (!strcmp(curves->preset, curves_presets[i].name)) {
|
||||||
|
pts[0] = av_strdup(curves_presets[i].r);
|
||||||
|
pts[1] = av_strdup(curves_presets[i].g);
|
||||||
|
pts[2] = av_strdup(curves_presets[i].b);
|
||||||
|
if (!pts[0] || !pts[1] || !pts[2])
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == FF_ARRAY_ELEMS(curves_presets)) {
|
||||||
|
av_log(ctx, AV_LOG_ERROR, "Preset '%s' not found. Available presets:",
|
||||||
|
curves->preset);
|
||||||
|
for (i = 0; i < FF_ARRAY_ELEMS(curves_presets); i++)
|
||||||
|
av_log(ctx, AV_LOG_ERROR, " %s", curves_presets[i].name);
|
||||||
|
av_log(ctx, AV_LOG_ERROR, ".\n");
|
||||||
|
return AVERROR(EINVAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < NB_COMP; i++) {
|
for (i = 0; i < NB_COMP; i++) {
|
||||||
ret = parse_points_str(ctx, comp_points + i, curves->comp_points_str[i]);
|
ret = parse_points_str(ctx, comp_points + i, curves->comp_points_str[i]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@@ -48,7 +48,7 @@ FATE_HQDN3D += fate-filter-hqdn3d
|
|||||||
fate-filter-hqdn3d: CMD = framecrc -idct simple -i $(SAMPLES)/smjpeg/scenwin.mjpg -vf perms=random,hqdn3d -an
|
fate-filter-hqdn3d: CMD = framecrc -idct simple -i $(SAMPLES)/smjpeg/scenwin.mjpg -vf perms=random,hqdn3d -an
|
||||||
FATE_FILTER-$(call ALLYES, SMJPEG_DEMUXER MJPEG_DECODER PERMS_FILTER HQDN3D_FILTER) += $(FATE_HQDN3D)
|
FATE_FILTER-$(call ALLYES, SMJPEG_DEMUXER MJPEG_DECODER PERMS_FILTER HQDN3D_FILTER) += $(FATE_HQDN3D)
|
||||||
|
|
||||||
fate-filter-curves: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_median.avi -vf "perms=random,curves=r=0/0.11@.42/.51@1/0.95:g=0.50/0.48:b=0/0.22@.49/.44@1/0.8"
|
fate-filter-curves: CMD = framecrc -i $(SAMPLES)/utvideo/utvideo_rgb_median.avi -vf perms=random,curves=preset=vintage
|
||||||
FATE_FILTER-$(call ALLYES, UTVIDEO_DECODER AVI_DEMUXER PERMS_FILTER CURVES_FILTER) += fate-filter-curves
|
FATE_FILTER-$(call ALLYES, UTVIDEO_DECODER AVI_DEMUXER PERMS_FILTER CURVES_FILTER) += fate-filter-curves
|
||||||
|
|
||||||
FATE_GRADFUN += fate-filter-gradfun
|
FATE_GRADFUN += fate-filter-gradfun
|
||||||
|
Reference in New Issue
Block a user