summaryrefslogtreecommitdiff
path: root/libavfilter/vf_eq.c
diff options
context:
space:
mode:
authorarwa arif <arwaarif1994@gmail.com>2015-03-13 11:46:42 +0530
committerStefano Sabatini <stefasab@gmail.com>2015-03-20 09:41:32 +0100
commit9015ca359f271968edb16d19bad9fc340d8e3a3d (patch)
tree18a021dde0419880a033525f3bc1c1e4033a5e3f /libavfilter/vf_eq.c
parente6547cce72789d6e650ae3017dcf6370e24f6314 (diff)
downloadffmpeg-9015ca359f271968edb16d19bad9fc340d8e3a3d.tar.gz
lavfi/eq: rework expression evaluation
In particular, add support for t, pos, n, r parameters, and add an eval mode option. Also, partially reword option documentation. With several major edit by Stefano Sabatini. Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
Diffstat (limited to 'libavfilter/vf_eq.c')
-rw-r--r--libavfilter/vf_eq.c80
1 files changed, 53 insertions, 27 deletions
diff --git a/libavfilter/vf_eq.c b/libavfilter/vf_eq.c
index 520fd46188..f8b816038d 100644
--- a/libavfilter/vf_eq.c
+++ b/libavfilter/vf_eq.c
@@ -27,11 +27,6 @@
* very simple video equalizer
*/
-/**
- * TODO:
- * - Add support to process_command
- */
-
#include "libavfilter/internal.h"
#include "libavutil/common.h"
#include "libavutil/imgutils.h"
@@ -111,16 +106,16 @@ static void check_values(EQParameters *param, EQContext *eq)
static void set_contrast(EQContext *eq)
{
- eq->var_values[VAR_CONTRAST] = av_clipf(av_expr_eval(eq->contrast_pexpr, eq->var_values, eq),-2.0, 2.0);
- eq->param[0].contrast = eq->var_values[VAR_CONTRAST];
+ eq->contrast = av_clipf(av_expr_eval(eq->contrast_pexpr, eq->var_values, eq), -2.0, 2.0);
+ eq->param[0].contrast = eq->contrast;
eq->param[0].lut_clean = 0;
check_values(&eq->param[0], eq);
}
static void set_brightness(EQContext *eq)
{
- eq->var_values[VAR_BRIGHTNESS] = av_clipf(av_expr_eval(eq->brightness_pexpr, eq->var_values, eq), -1.0, 1.0);
- eq->param[0].brightness = eq->var_values[VAR_BRIGHTNESS];
+ eq->brightness = av_clipf(av_expr_eval(eq->brightness_pexpr, eq->var_values, eq), -1.0, 1.0);
+ eq->param[0].brightness = eq->brightness;
eq->param[0].lut_clean = 0;
check_values(&eq->param[0], eq);
}
@@ -129,18 +124,18 @@ static void set_gamma(EQContext *eq)
{
int i;
- eq->var_values[VAR_GAMMA] = av_clipf(av_expr_eval(eq->gamma_pexpr, eq->var_values, eq), 0.1, 10.0);
- eq->var_values[VAR_GAMMA_R] = av_clipf(av_expr_eval(eq->gamma_r_pexpr, eq->var_values, eq), 0.1, 10.0);
- eq->var_values[VAR_GAMMA_G] = av_clipf(av_expr_eval(eq->gamma_g_pexpr, eq->var_values, eq), 0.1, 10.0);
- eq->var_values[VAR_GAMMA_B] = av_clipf(av_expr_eval(eq->gamma_b_pexpr, eq->var_values, eq), 0.1, 10.0);
- eq->var_values[VAR_GAMMA_WEIGHT] = av_clipf(av_expr_eval(eq->gamma_weight_pexpr, eq->var_values, eq), 0.0, 1.0);
+ eq->gamma = av_clipf(av_expr_eval(eq->gamma_pexpr, eq->var_values, eq), 0.1, 10.0);
+ eq->gamma_r = av_clipf(av_expr_eval(eq->gamma_r_pexpr, eq->var_values, eq), 0.1, 10.0);
+ eq->gamma_g = av_clipf(av_expr_eval(eq->gamma_g_pexpr, eq->var_values, eq), 0.1, 10.0);
+ eq->gamma_b = av_clipf(av_expr_eval(eq->gamma_b_pexpr, eq->var_values, eq), 0.1, 10.0);
+ eq->gamma_weight = av_clipf(av_expr_eval(eq->gamma_weight_pexpr, eq->var_values, eq), 0.0, 1.0);
- eq->param[0].gamma = eq->var_values[VAR_GAMMA] * eq->var_values[VAR_GAMMA_G];
- eq->param[1].gamma = sqrt(eq->var_values[VAR_GAMMA_B] / eq->var_values[VAR_GAMMA_G]);
- eq->param[2].gamma = sqrt(eq->var_values[VAR_GAMMA_R] / eq->var_values[VAR_GAMMA_G]);
+ eq->param[0].gamma = eq->gamma * eq->gamma_g;
+ eq->param[1].gamma = sqrt(eq->gamma_b / eq->gamma_g);
+ eq->param[2].gamma = sqrt(eq->gamma_r / eq->gamma_g);
for (i = 0; i < 3; i++) {
- eq->param[i].gamma_weight = eq->var_values[VAR_GAMMA_WEIGHT];
+ eq->param[i].gamma_weight = eq->gamma_weight;
eq->param[i].lut_clean = 0;
check_values(&eq->param[i], eq);
}
@@ -150,10 +145,10 @@ static void set_saturation(EQContext *eq)
{
int i;
- eq->var_values[VAR_SATURATION] = av_clipf(av_expr_eval(eq->saturation_pexpr, eq->var_values, eq), 0.0, 3.0);
+ eq->saturation = av_clipf(av_expr_eval(eq->saturation_pexpr, eq->var_values, eq), 0.0, 3.0);
for (i = 1; i < 3; i++) {
- eq->param[i].contrast = eq->var_values[VAR_SATURATION];
+ eq->param[i].contrast = eq->saturation;
eq->param[i].lut_clean = 0;
check_values(&eq->param[i], eq);
}
@@ -166,8 +161,7 @@ static int set_expr(AVExpr **pexpr, const char *expr, const char *option, void *
if (*pexpr)
old = *pexpr;
- ret = av_expr_parse(pexpr, expr, var_names,
- NULL, NULL, NULL, NULL, 0, log_ctx);
+ ret = av_expr_parse(pexpr, expr, var_names, NULL, NULL, NULL, NULL, 0, log_ctx);
if (ret < 0) {
av_log(log_ctx, AV_LOG_ERROR,
"Error when parsing the expression '%s' for %s\n",
@@ -200,10 +194,12 @@ static int initialize(AVFilterContext *ctx)
if (ARCH_X86)
ff_eq_init_x86(eq);
- set_gamma(eq);
- set_contrast(eq);
- set_brightness(eq);
- set_saturation(eq);
+ if (eq->eval_mode == EVAL_MODE_INIT) {
+ set_gamma(eq);
+ set_contrast(eq);
+ set_brightness(eq);
+ set_saturation(eq);
+ }
return 0;
}
@@ -222,6 +218,17 @@ static void uninit(AVFilterContext *ctx)
av_expr_free(eq->gamma_b_pexpr); eq->gamma_b_pexpr = NULL;
}
+static int config_props(AVFilterLink *inlink)
+{
+ EQContext *eq = inlink->dst->priv;
+
+ eq->var_values[VAR_N] = 0;
+ eq->var_values[VAR_R] = inlink->frame_rate.num == 0 || inlink->frame_rate.den == 0 ?
+ NAN : av_q2d(inlink->frame_rate);
+
+ return 0;
+}
+
static int query_formats(AVFilterContext *ctx)
{
static const enum AVPixelFormat pixel_fmts_eq[] = {
@@ -239,12 +246,15 @@ static int query_formats(AVFilterContext *ctx)
return ff_set_common_formats(ctx, fmts_list);
}
+#define TS2T(ts, tb) ((ts) == AV_NOPTS_VALUE ? NAN : (double)(ts) * av_q2d(tb))
+
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
AVFilterContext *ctx = inlink->dst;
AVFilterLink *outlink = inlink->dst->outputs[0];
EQContext *eq = ctx->priv;
AVFrame *out;
+ int64_t pos = av_frame_get_pkt_pos(in);
const AVPixFmtDescriptor *desc;
int i;
@@ -255,6 +265,17 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
av_frame_copy_props(out, in);
desc = av_pix_fmt_desc_get(inlink->format);
+ eq->var_values[VAR_N] = inlink->frame_count;
+ eq->var_values[VAR_POS] = pos == -1 ? NAN : pos;
+ eq->var_values[VAR_T] = TS2T(in->pts, inlink->time_base);
+
+ if (eq->eval_mode == EVAL_MODE_FRAME) {
+ set_gamma(eq);
+ set_contrast(eq);
+ set_brightness(eq);
+ set_saturation(eq);
+ }
+
for (i = 0; i < desc->nb_components; i++) {
int w = inlink->w;
int h = inlink->h;
@@ -283,7 +304,8 @@ static inline int set_param(AVExpr **pexpr, const char *args, const char *cmd,
int ret;
if ((ret = set_expr(pexpr, args, cmd, ctx)) < 0)
return ret;
- set_fn(eq);
+ if (eq->eval_mode == EVAL_MODE_INIT)
+ set_fn(eq);
return 0;
}
@@ -311,6 +333,7 @@ static const AVFilterPad eq_inputs[] = {
.name = "default",
.type = AVMEDIA_TYPE_VIDEO,
.filter_frame = filter_frame,
+ .config_props = config_props,
},
{ NULL }
};
@@ -343,6 +366,9 @@ static const AVOption eq_options[] = {
OFFSET(gamma_b_expr), AV_OPT_TYPE_STRING, {.str = "1.0"}, CHAR_MIN, CHAR_MAX, FLAGS },
{ "gamma_weight", "set the gamma weight which reduces the effect of gamma on bright areas",
OFFSET(gamma_weight_expr), AV_OPT_TYPE_STRING, {.str = "1.0"}, CHAR_MIN, CHAR_MAX, FLAGS },
+ { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, "eval" },
+ { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" },
+ { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" },
{ NULL }
};