aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClément Bœsch <ubitux@gmail.com>2013-04-15 10:53:54 +0200
committerClément Bœsch <ubitux@gmail.com>2013-04-15 11:35:06 +0200
commit99dac3933916507fb728b9c6d9aafb11c7d2f228 (patch)
tree68e1a6ab74d4213cc746f11e61255aa52250ef26
parent357da7ed42071ad79b03e1d6434bf177a58484f4 (diff)
downloadffmpeg-99dac3933916507fb728b9c6d9aafb11c7d2f228.tar.gz
lavfi/curves: add support for master component.
-rw-r--r--doc/filters.texi7
-rw-r--r--libavfilter/vf_curves.c52
2 files changed, 39 insertions, 20 deletions
diff --git a/doc/filters.texi b/doc/filters.texi
index b766985e3e..8df1a88611 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -2330,6 +2330,11 @@ Available presets are:
@item vintage
@end table
Default is @code{none}.
+@item master, m
+Set the master key points. These points will define a second pass mapping. It
+is sometimes called a "luminance" or "value" mapping. It can be used with
+@option{r}, @option{g}, @option{b} or @option{all} since it acts like a
+post-processing LUT.
@item red, r
Set the key points for the red component.
@item green, g
@@ -2337,7 +2342,7 @@ Set the key points for the green component.
@item blue, b
Set the key points for the blue component.
@item all
-Set the key points for all components.
+Set the key points for all components (not including master).
Can be used in addition to the other key points component
options. In this case, the unset component(s) will fallback on this
@option{all} setting.
diff --git a/libavfilter/vf_curves.c b/libavfilter/vf_curves.c
index 2bb1c5e65c..35a5af3946 100644
--- a/libavfilter/vf_curves.c
+++ b/libavfilter/vf_curves.c
@@ -51,9 +51,9 @@ enum preset {
typedef struct {
const AVClass *class;
enum preset preset;
- char *comp_points_str[NB_COMP];
+ char *comp_points_str[NB_COMP + 1];
char *comp_points_str_all;
- uint8_t graph[NB_COMP][256];
+ uint8_t graph[NB_COMP + 1][256];
} CurvesContext;
#define OFFSET(x) offsetof(CurvesContext, x)
@@ -71,6 +71,8 @@ static const AVOption curves_options[] = {
{ "negative", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_NEGATIVE}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
{ "strong_contrast", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_STRONG_CONTRAST}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
{ "vintage", NULL, 0, AV_OPT_TYPE_CONST, {.i64=PRESET_VINTAGE}, INT_MIN, INT_MAX, FLAGS, "preset_name" },
+ { "master","set master points coordinates",OFFSET(comp_points_str[NB_COMP]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
+ { "m", "set master points coordinates",OFFSET(comp_points_str[NB_COMP]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
{ "red", "set red points coordinates", OFFSET(comp_points_str[0]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
{ "r", "set red points coordinates", OFFSET(comp_points_str[0]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
{ "green", "set green points coordinates", OFFSET(comp_points_str[1]), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
@@ -87,7 +89,7 @@ static const struct {
const char *r;
const char *g;
const char *b;
- const char *all;
+ const char *master;
} curves_presets[] = {
[PRESET_COLOR_NEGATIVE] = {
"0/1 0.129/1 0.466/0.498 0.725/0 1/0",
@@ -99,13 +101,13 @@ static const struct {
"0.25/0.188 0.38/0.501 0.745/0.815 1/0.815",
"0.231/0.094 0.709/0.874",
},
- [PRESET_DARKER] = { .all = "0.5/0.4" },
- [PRESET_INCREASE_CONTRAST] = { .all = "0.149/0.066 0.831/0.905 0.905/0.98" },
- [PRESET_LIGHTER] = { .all = "0.4/0.5" },
- [PRESET_LINEAR_CONTRAST] = { .all = "0.305/0.286 0.694/0.713" },
- [PRESET_MEDIUM_CONTRAST] = { .all = "0.286/0.219 0.639/0.643" },
- [PRESET_NEGATIVE] = { .all = "0/1 1/0" },
- [PRESET_STRONG_CONTRAST] = { .all = "0.301/0.196 0.592/0.6 0.686/0.737" },
+ [PRESET_DARKER] = { .master = "0.5/0.4" },
+ [PRESET_INCREASE_CONTRAST] = { .master = "0.149/0.066 0.831/0.905 0.905/0.98" },
+ [PRESET_LIGHTER] = { .master = "0.4/0.5" },
+ [PRESET_LINEAR_CONTRAST] = { .master = "0.305/0.286 0.694/0.713" },
+ [PRESET_MEDIUM_CONTRAST] = { .master = "0.286/0.219 0.639/0.643" },
+ [PRESET_NEGATIVE] = { .master = "0/1 1/0" },
+ [PRESET_STRONG_CONTRAST] = { .master = "0.301/0.196 0.592/0.6 0.686/0.737" },
[PRESET_VINTAGE] = {
"0/0.11 0.42/0.51 1/0.95",
"0.50/0.48",
@@ -299,12 +301,12 @@ static av_cold int init(AVFilterContext *ctx)
{
int i, j, ret;
CurvesContext *curves = ctx->priv;
- struct keypoint *comp_points[NB_COMP] = {0};
+ struct keypoint *comp_points[NB_COMP + 1] = {0};
char **pts = curves->comp_points_str;
const char *allp = curves->comp_points_str_all;
- if (!allp && curves->preset != PRESET_NONE && curves_presets[curves->preset].all)
- allp = curves_presets[curves->preset].all;
+ //if (!allp && curves->preset != PRESET_NONE && curves_presets[curves->preset].all)
+ // allp = curves_presets[curves->preset].all;
if (allp) {
for (i = 0; i < NB_COMP; i++) {
@@ -316,14 +318,20 @@ static av_cold int init(AVFilterContext *ctx)
}
if (curves->preset != PRESET_NONE) {
- if (!pts[0]) pts[0] = av_strdup(curves_presets[curves->preset].r);
- if (!pts[1]) pts[1] = av_strdup(curves_presets[curves->preset].g);
- if (!pts[2]) pts[2] = av_strdup(curves_presets[curves->preset].b);
- if (!pts[0] || !pts[1] || !pts[2])
- return AVERROR(ENOMEM);
+#define SET_COMP_IF_NOT_SET(n, name) do { \
+ if (!pts[n] && curves_presets[curves->preset].name) { \
+ pts[n] = av_strdup(curves_presets[curves->preset].name); \
+ if (!pts[n]) \
+ return AVERROR(ENOMEM); \
+ } \
+} while (0)
+ SET_COMP_IF_NOT_SET(0, r);
+ SET_COMP_IF_NOT_SET(1, g);
+ SET_COMP_IF_NOT_SET(2, b);
+ SET_COMP_IF_NOT_SET(3, master);
}
- for (i = 0; i < NB_COMP; i++) {
+ for (i = 0; i < NB_COMP + 1; i++) {
ret = parse_points_str(ctx, comp_points + i, curves->comp_points_str[i]);
if (ret < 0)
return ret;
@@ -332,6 +340,12 @@ static av_cold int init(AVFilterContext *ctx)
return ret;
}
+ if (pts[NB_COMP]) {
+ for (i = 0; i < NB_COMP; i++)
+ for (j = 0; j < 256; j++)
+ curves->graph[i][j] = curves->graph[NB_COMP][curves->graph[i][j]];
+ }
+
if (av_log_get_level() >= AV_LOG_VERBOSE) {
for (i = 0; i < NB_COMP; i++) {
struct keypoint *point = comp_points[i];