On date Friday 2015-03-13 11:46:42 +0530, Arwa Arif encoded: > I have added the variable options. I have not done the refactoring part yet.
> From 00052c1bbe5fe87d86fcff6f5e810290468d0251 Mon Sep 17 00:00:00 2001 > From: Arwa Arif <arwaarif1...@gmail.com> > Date: Fri, 13 Mar 2015 11:37:40 +0530 > Subject: [PATCH] Add variables to process_command in vf_eq > > --- > doc/filters.texi | 16 +++++++++++++-- > libavfilter/vf_eq.c | 55 > ++++++++++++++++++++++++++++++--------------------- > libavfilter/vf_eq.h | 36 ++++++++++++++++----------------- > 3 files changed, 64 insertions(+), 43 deletions(-) Check attached modified patch. -- FFmpeg = Formidable & Free Murdering Problematic Enhanced Gem
>From bca3c330b3ab60c84ab69f4da2fe04caa848f6e5 Mon Sep 17 00:00:00 2001 From: arwa arif <arwaarif1...@gmail.com> Date: Fri, 13 Mar 2015 11:46:42 +0530 Subject: [PATCH] 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 <stefa...@gmail.com> --- doc/filters.texi | 70 ++++++++++++++++++++++++++++++++++++++--------------- libavfilter/vf_eq.c | 70 +++++++++++++++++++++++++++++++++++------------------ libavfilter/vf_eq.h | 39 ++++++++++++++--------------- 3 files changed, 118 insertions(+), 61 deletions(-) diff --git a/doc/filters.texi b/doc/filters.texi index dbcd391..653b985 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -4366,40 +4366,72 @@ The filter accepts the following options: @table @option @item contrast -Set the contrast value. It accepts a float value in range @code{-2.0} to -@code{2.0}. The default value is @code{0.0}. +Set the contrast expression. The value must be a float value in range +@code{-2.0} to @code{2.0}. The default value is "0". @item brightness -Set the brightness value. It accepts a float value in range @code{-1.0} to -@code{1.0}. The default value is @code{0.0}. +Set the brightness expression. The value must be a float value in +range @code{-1.0} to @code{1.0}. The default value is "0". @item saturation -Set the saturation value. It accepts a float value in range @code{0.0} to -@code{3.0}. The default value is @code{1.0}. +Set the saturation expression. The value must be a float in +range @code{0.0} to @code{3.0}. The default value is "1". @item gamma -Set the gamma value. It accepts a float value in range @code{0.1} to @code{10.0}. -The default value is @code{1.0}. +Set the gamma expression. The value must be a float in range +@code{0.1} to @code{10.0}. The default value is "1". @item gamma_r -Set the gamma value for red. It accepts a float value in range -@code{0.1} to @code{10.0}. The default value is @code{1.0}. +Set the gamma expression for red. The value must be a float in +range @code{0.1} to @code{10.0}. The default value is "1". @item gamma_g -Set the gamma value for green. It accepts a float value in range -@code{0.1} to @code{10.0}. The default value is @code{1.0}. +Set the gamma expression for green. The value must be a float in range +@code{0.1} to @code{10.0}. The default value is "1". @item gamma_b -Set the gamma value for blue. It accepts a float value in range -@code{0.1} to @code{10.0}. The default value is @code{1.0}. +Set the gamma expression for blue. The value must be a float in range +@code{0.1} to @code{10.0}. The default value is "1". @item gamma_weight -Can be used to reduce the effect of a high gamma value on bright image areas, -e.g. keep them from getting overamplified and just plain white. It accepts a -float value in range @code{0.0} to @code{1.0}.A value of @code{0.0} turns the -gamma correction all the way down while @code{1.0} leaves it at its full strength. -Default is @code{1.0}. +Set the gamma weight expression. It can be used to reduce the effect +of a high gamma value on bright image areas, e.g. keep them from +getting overamplified and just plain white. The value must be a float +in range @code{0.0} to @code{1.0}. A value of @code{0.0} turns the +gamma correction all the way down while @code{1.0} leaves it at its +full strength. Default is "1". +@item eval +Set when the expressions for brightness, contrast, saturation and +gamma expressions are evaluated. + +It accepts the following values: +@table @samp +@item init +only evaluate expressions once during the filter initialization or +when a command is processed + +@item frame +evaluate expressions for each incoming frame +@end table + +Default value is @samp{init}. +@end table + +The expressions accept the following parameters: +@table @option +@item n +frame count of the input frame starting from 0 + +@item pos +byte position of the corresponding packet in the input file, NAN if +unspecified + +@item r +frame rate of the input video, NAN if the input frame rate is unknown + +@item t +timestamp expressed in seconds, NAN if the input timestamp is unknown @end table @subsection Commands diff --git a/libavfilter/vf_eq.c b/libavfilter/vf_eq.c index e1aa206..a6fd27a 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 evaluating the expression '%s' for %s\n", @@ -222,6 +216,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 +244,15 @@ static int query_formats(AVFilterContext *ctx) return 0; } +#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 +263,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; @@ -285,7 +304,8 @@ static int process_command(AVFilterContext *ctx, const char *cmd, const char *ar #define SET_PARAM(param_name, set_name) \ if (!strcmp(cmd, #param_name)) { \ ret = set_expr(&eq->param_name##_pexpr, args, cmd, ctx); \ - set_##set_name(eq); \ + if (eq->eval_mode == EVAL_MODE_INIT) \ + set_##set_name(eq); \ return ret; \ } @@ -305,6 +325,7 @@ static const AVFilterPad eq_inputs[] = { .name = "default", .type = AVMEDIA_TYPE_VIDEO, .filter_frame = filter_frame, + .config_props = config_props, }, { NULL } }; @@ -337,6 +358,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 fe9c09c..8525048 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); -- 1.8.3.2
_______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel