| @@ -33,9 +33,16 @@ · 32 unmodified lines |
| 33 | | 33 | |
| 34 | #define MAX_PLANES 4 | 34 | #define MAX_PLANES 4 |
| 35 | | 35 | |
| | 36 | enum EvalMode { |
| | 37 | EVAL_MODE_INIT, |
| | 38 | EVAL_MODE_FRAME, |
| | 39 | EVAL_MODE_NB |
| | 40 | }; |
| | 41 | |
| 36 | typedef struct FFTFILTContext { | 42 | typedef struct FFTFILTContext { |
| 37 | const AVClass *class; | 43 | const AVClass *class; |
| 38 | | 44 | |
| | 45 | int eval_mode; |
| 39 | int depth; | 46 | int depth; |
| 40 | int nb_planes; | 47 | int nb_planes; |
| 41 | int planewidth[MAX_PLANES]; | 48 | int planewidth[MAX_PLANES]; |
| @@ -59,8 +66,8 @@ typedef struct FFTFILTContext { · 17 unmodified lines |
| 59 | | 66 | |
| 60 | } FFTFILTContext; | 67 | } FFTFILTContext; |
| 61 | | 68 | |
| 62 | static const char *const var_names[] = { "X", "Y", "W", "H", NULL }; | 69 | static const char *const var_names[] = { "X", "Y", "W", "H", "N", NULL }; |
| 63 | enum { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_VARS_NB }; | 70 | enum { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_N, VAR_VARS_NB }; |
| 64 | | 71 | |
| 65 | enum { Y = 0, U, V }; | 72 | enum { Y = 0, U, V }; |
| 66 | | 73 | |
| @@ -74,6 +81,9 @@ static const AVOption fftfilt_options[] = { · 7 unmodified lines |
| 74 | { "weight_Y", "set luminance expression in Y plane", OFFSET(weight_str[Y]), AV_OPT_TYPE_STRING, {.str = "1"}, CHAR_MIN, CHAR_MAX, FLAGS }, | 81 | { "weight_Y", "set luminance expression in Y plane", OFFSET(weight_str[Y]), AV_OPT_TYPE_STRING, {.str = "1"}, CHAR_MIN, CHAR_MAX, FLAGS }, |
| 75 | { "weight_U", "set chrominance expression in U plane", OFFSET(weight_str[U]), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, | 82 | { "weight_U", "set chrominance expression in U plane", OFFSET(weight_str[U]), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, |
| 76 | { "weight_V", "set chrominance expression in V plane", OFFSET(weight_str[V]), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, | 83 | { "weight_V", "set chrominance expression in V plane", OFFSET(weight_str[V]), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS }, |
| | 84 | { "eval", "specify when to evaluate expressions", OFFSET(eval_mode), AV_OPT_TYPE_INT, {.i64 = EVAL_MODE_INIT}, 0, EVAL_MODE_NB-1, FLAGS, "eval" }, |
| | 85 | { "init", "eval expressions once during initialization", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_INIT}, .flags = FLAGS, .unit = "eval" }, |
| | 86 | { "frame", "eval expressions per-frame", 0, AV_OPT_TYPE_CONST, {.i64=EVAL_MODE_FRAME}, .flags = FLAGS, .unit = "eval" }, |
| 77 | {NULL}, | 87 | {NULL}, |
| 78 | }; | 88 | }; |
| 79 | | 89 | |
| @@ -195,12 +205,30 @@ static av_cold int initialize(AVFilterContext *ctx) · 115 unmodified lines |
| 195 | return ret; | 205 | return ret; |
| 196 | } | 206 | } |
| 197 | | 207 | |
| | 208 | static void do_eval(FFTFILTContext *s, AVFilterLink *inlink, int plane) |
| | 209 | { |
| | 210 | double values[VAR_VARS_NB]; |
| | 211 | int i, j; |
| | 212 | |
| | 213 | values[VAR_N] = inlink->frame_count_out; |
| | 214 | values[VAR_W] = s->planewidth[plane]; |
| | 215 | values[VAR_H] = s->planeheight[plane]; |
| | 216 | |
| | 217 | for (i = 0; i < s->rdft_hlen[plane]; i++) { |
| | 218 | values[VAR_X] = i; |
| | 219 | for (j = 0; j < s->rdft_vlen[plane]; j++) { |
| | 220 | values[VAR_Y] = j; |
| | 221 | s->weight[plane][i * s->rdft_vlen[plane] + j] = |
| | 222 | av_expr_eval(s->weight_expr[plane], values, s); |
| | 223 | } |
| | 224 | } |
| | 225 | } |
| | 226 | |
| 198 | static int config_props(AVFilterLink *inlink) | 227 | static int config_props(AVFilterLink *inlink) |
| 199 | { | 228 | { |
| 200 | FFTFILTContext *s = inlink->dst->priv; | 229 | FFTFILTContext *s = inlink->dst->priv; |
| 201 | const AVPixFmtDescriptor *desc; | 230 | const AVPixFmtDescriptor *desc; |
| 202 | int rdft_hbits, rdft_vbits, i, j, plane; | 231 | int rdft_hbits, rdft_vbits, i, plane; |
| 203 | double values[VAR_VARS_NB]; | | |
| 204 | | 232 | |
| 205 | desc = av_pix_fmt_desc_get(inlink->format); | 233 | desc = av_pix_fmt_desc_get(inlink->format); |
| 206 | s->depth = desc->comp[0].depth; | 234 | s->depth = desc->comp[0].depth; |
| @@ -242,21 +270,11 @@ static int config_props(AVFilterLink *inlink) · 35 unmodified lines |
| 242 | | 270 | |
| 243 | /*Luminance value - Array initialization*/ | 271 | /*Luminance value - Array initialization*/ |
| 244 | for (plane = 0; plane < 3; plane++) { | 272 | for (plane = 0; plane < 3; plane++) { |
| 245 | values[VAR_W] = s->planewidth[plane]; | | |
| 246 | values[VAR_H] = s->planeheight[plane]; | | |
| 247 | | | |
| 248 | if(!(s->weight[plane] = av_malloc_array(s->rdft_hlen[plane], s->rdft_vlen[plane] * sizeof(double)))) | 273 | if(!(s->weight[plane] = av_malloc_array(s->rdft_hlen[plane], s->rdft_vlen[plane] * sizeof(double)))) |
| 249 | return AVERROR(ENOMEM); | 274 | return AVERROR(ENOMEM); |
| 250 | for (i = 0; i < s->rdft_hlen[plane]; i++) | 275 | |
| 251 | { | 276 | if (s->eval_mode == EVAL_MODE_INIT) |
| 252 | values[VAR_X] = i; | 277 | do_eval(s, inlink, plane); |
| 253 | for (j = 0; j < s->rdft_vlen[plane]; j++) | | |
| 254 | { | | |
| 255 | values[VAR_Y] = j; | | |
| 256 | s->weight[plane][i * s->rdft_vlen[plane] + j] = | | |
| 257 | av_expr_eval(s->weight_expr[plane], values, s); | | |
| 258 | } | | |
| 259 | } | | |
| 260 | } | 278 | } |
| 261 | return 0; | 279 | return 0; |
| 262 | } | 280 | } |
| @@ -281,6 +299,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) · 18 unmodified lines |
| 281 | int w = s->planewidth[plane]; | 299 | int w = s->planewidth[plane]; |
| 282 | int h = s->planeheight[plane]; | 300 | int h = s->planeheight[plane]; |
| 283 | | 301 | |
| | 302 | if (s->eval_mode == EVAL_MODE_FRAME) |
| | 303 | do_eval(s, inlink, plane); |
| | 304 | |
| 284 | rdft_horizontal(s, in, w, h, plane); | 305 | rdft_horizontal(s, in, w, h, plane); |
| 285 | rdft_vertical(s, h, plane); | 306 | rdft_vertical(s, h, plane); |
| 286 | | 307 | |