diff options
author | arwa arif <arwaarif1994@gmail.com> | 2015-03-13 11:46:42 +0530 |
---|---|---|
committer | Stefano Sabatini <stefasab@gmail.com> | 2015-03-20 09:41:32 +0100 |
commit | 9015ca359f271968edb16d19bad9fc340d8e3a3d (patch) | |
tree | 18a021dde0419880a033525f3bc1c1e4033a5e3f /libavfilter | |
parent | e6547cce72789d6e650ae3017dcf6370e24f6314 (diff) | |
download | ffmpeg-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')
-rw-r--r-- | libavfilter/version.h | 2 | ||||
-rw-r--r-- | libavfilter/vf_eq.c | 80 | ||||
-rw-r--r-- | libavfilter/vf_eq.h | 39 |
3 files changed, 74 insertions, 47 deletions
diff --git a/libavfilter/version.h b/libavfilter/version.h index b349aaf427..43b7ab9c03 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -31,7 +31,7 @@ #define LIBAVFILTER_VERSION_MAJOR 5 #define LIBAVFILTER_VERSION_MINOR 13 -#define LIBAVFILTER_VERSION_MICRO 100 +#define LIBAVFILTER_VERSION_MICRO 101 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ LIBAVFILTER_VERSION_MINOR, \ 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 } }; diff --git a/libavfilter/vf_eq.h b/libavfilter/vf_eq.h index fe9c09caca..8525048b3f 100644 --- a/libavfilter/vf_eq.h +++ b/libavfilter/vf_eq.h @@ -28,28 +28,20 @@ #include "avfilter.h" #include "libavutil/eval.h" -static const char * const var_names[] = { - "contrast", - "brightness", - "saturation", - "gamma", - "gamma_weight", - "gamma_r", - "gamma_g", - "gamma_b", +static const char *const var_names[] = { + "n", // frame count + "pos", // frame position + "r", // frame rate + "t", // timestamp expressed in seconds NULL }; enum var_name { - VAR_CONTRAST , - VAR_BRIGHTNESS , - VAR_SATURATION , - VAR_GAMMA , - VAR_GAMMA_WEIGHT , - VAR_GAMMA_R , - VAR_GAMMA_G , - VAR_GAMMA_B , - VAR_VARS_NB , + VAR_N, + VAR_POS, + VAR_R, + VAR_T, + VAR_NB }; typedef struct EQParameters { @@ -70,33 +62,42 @@ typedef struct { char *contrast_expr; AVExpr *contrast_pexpr; + double contrast; char *brightness_expr; AVExpr *brightness_pexpr; + double brightness; char *saturation_expr; AVExpr *saturation_pexpr; + double saturation; char *gamma_expr; AVExpr *gamma_pexpr; + double gamma; char *gamma_weight_expr; AVExpr *gamma_weight_pexpr; + double gamma_weight; char *gamma_r_expr; AVExpr *gamma_r_pexpr; + double gamma_r; char *gamma_g_expr; AVExpr *gamma_g_pexpr; + double gamma_g; char *gamma_b_expr; AVExpr *gamma_b_pexpr; + double gamma_b; - double var_values[VAR_VARS_NB]; + double var_values[VAR_NB]; void (*process)(struct EQParameters *par, uint8_t *dst, int dst_stride, const uint8_t *src, int src_stride, int w, int h); + enum EvalMode { EVAL_MODE_INIT, EVAL_MODE_FRAME, EVAL_MODE_NB } eval_mode; } EQContext; void ff_eq_init_x86(EQContext *eq); |