mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-24 12:09:55 +00:00
avfilter/vf_fftfilt: make it possible to evaluate expressions per frame
Signed-off-by: Paul B Mahol <onemda@gmail.com>
This commit is contained in:
parent
4705a80fb0
commit
b43cd67862
@ -7926,6 +7926,20 @@ Set the frequency domain weight expression for the 1st chroma plane.
|
|||||||
@item weight_V
|
@item weight_V
|
||||||
Set the frequency domain weight expression for the 2nd chroma plane.
|
Set the frequency domain weight expression for the 2nd chroma plane.
|
||||||
|
|
||||||
|
@item eval
|
||||||
|
Set when the expressions are evaluated.
|
||||||
|
|
||||||
|
It accepts the following values:
|
||||||
|
@table @samp
|
||||||
|
@item init
|
||||||
|
Only evaluate expressions once during the filter initialization.
|
||||||
|
|
||||||
|
@item frame
|
||||||
|
Evaluate expressions for each incoming frame.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
Default value is @samp{init}.
|
||||||
|
|
||||||
The filter accepts the following variables:
|
The filter accepts the following variables:
|
||||||
@item X
|
@item X
|
||||||
@item Y
|
@item Y
|
||||||
@ -7934,6 +7948,9 @@ The coordinates of the current sample.
|
|||||||
@item W
|
@item W
|
||||||
@item H
|
@item H
|
||||||
The width and height of the image.
|
The width and height of the image.
|
||||||
|
|
||||||
|
@item N
|
||||||
|
The number of input frame, starting from 0.
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@subsection Examples
|
@subsection Examples
|
||||||
|
@ -33,9 +33,16 @@
|
|||||||
|
|
||||||
#define MAX_PLANES 4
|
#define MAX_PLANES 4
|
||||||
|
|
||||||
|
enum EvalMode {
|
||||||
|
EVAL_MODE_INIT,
|
||||||
|
EVAL_MODE_FRAME,
|
||||||
|
EVAL_MODE_NB
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct FFTFILTContext {
|
typedef struct FFTFILTContext {
|
||||||
const AVClass *class;
|
const AVClass *class;
|
||||||
|
|
||||||
|
int eval_mode;
|
||||||
int depth;
|
int depth;
|
||||||
int nb_planes;
|
int nb_planes;
|
||||||
int planewidth[MAX_PLANES];
|
int planewidth[MAX_PLANES];
|
||||||
@ -59,8 +66,8 @@ typedef struct FFTFILTContext {
|
|||||||
|
|
||||||
} FFTFILTContext;
|
} FFTFILTContext;
|
||||||
|
|
||||||
static const char *const var_names[] = { "X", "Y", "W", "H", NULL };
|
static const char *const var_names[] = { "X", "Y", "W", "H", "N", NULL };
|
||||||
enum { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_VARS_NB };
|
enum { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_N, VAR_VARS_NB };
|
||||||
|
|
||||||
enum { Y = 0, U, V };
|
enum { Y = 0, U, V };
|
||||||
|
|
||||||
@ -74,6 +81,9 @@ static const AVOption fftfilt_options[] = {
|
|||||||
{ "weight_Y", "set luminance expression in Y plane", OFFSET(weight_str[Y]), AV_OPT_TYPE_STRING, {.str = "1"}, CHAR_MIN, CHAR_MAX, FLAGS },
|
{ "weight_Y", "set luminance expression in Y plane", OFFSET(weight_str[Y]), AV_OPT_TYPE_STRING, {.str = "1"}, CHAR_MIN, CHAR_MAX, FLAGS },
|
||||||
{ "weight_U", "set chrominance expression in U plane", OFFSET(weight_str[U]), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
|
{ "weight_U", "set chrominance expression in U plane", OFFSET(weight_str[U]), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
|
||||||
{ "weight_V", "set chrominance expression in V plane", OFFSET(weight_str[V]), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, FLAGS },
|
{ "weight_V", "set chrominance expression in V plane", OFFSET(weight_str[V]), AV_OPT_TYPE_STRING, {.str = NULL}, 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},
|
{NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -195,12 +205,30 @@ static av_cold int initialize(AVFilterContext *ctx)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void do_eval(FFTFILTContext *s, AVFilterLink *inlink, int plane)
|
||||||
|
{
|
||||||
|
double values[VAR_VARS_NB];
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
values[VAR_N] = inlink->frame_count_out;
|
||||||
|
values[VAR_W] = s->planewidth[plane];
|
||||||
|
values[VAR_H] = s->planeheight[plane];
|
||||||
|
|
||||||
|
for (i = 0; i < s->rdft_hlen[plane]; i++) {
|
||||||
|
values[VAR_X] = i;
|
||||||
|
for (j = 0; j < s->rdft_vlen[plane]; j++) {
|
||||||
|
values[VAR_Y] = j;
|
||||||
|
s->weight[plane][i * s->rdft_vlen[plane] + j] =
|
||||||
|
av_expr_eval(s->weight_expr[plane], values, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int config_props(AVFilterLink *inlink)
|
static int config_props(AVFilterLink *inlink)
|
||||||
{
|
{
|
||||||
FFTFILTContext *s = inlink->dst->priv;
|
FFTFILTContext *s = inlink->dst->priv;
|
||||||
const AVPixFmtDescriptor *desc;
|
const AVPixFmtDescriptor *desc;
|
||||||
int rdft_hbits, rdft_vbits, i, j, plane;
|
int rdft_hbits, rdft_vbits, i, plane;
|
||||||
double values[VAR_VARS_NB];
|
|
||||||
|
|
||||||
desc = av_pix_fmt_desc_get(inlink->format);
|
desc = av_pix_fmt_desc_get(inlink->format);
|
||||||
s->depth = desc->comp[0].depth;
|
s->depth = desc->comp[0].depth;
|
||||||
@ -242,21 +270,11 @@ static int config_props(AVFilterLink *inlink)
|
|||||||
|
|
||||||
/*Luminance value - Array initialization*/
|
/*Luminance value - Array initialization*/
|
||||||
for (plane = 0; plane < 3; plane++) {
|
for (plane = 0; plane < 3; plane++) {
|
||||||
values[VAR_W] = s->planewidth[plane];
|
|
||||||
values[VAR_H] = s->planeheight[plane];
|
|
||||||
|
|
||||||
if(!(s->weight[plane] = av_malloc_array(s->rdft_hlen[plane], s->rdft_vlen[plane] * sizeof(double))))
|
if(!(s->weight[plane] = av_malloc_array(s->rdft_hlen[plane], s->rdft_vlen[plane] * sizeof(double))))
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
for (i = 0; i < s->rdft_hlen[plane]; i++)
|
|
||||||
{
|
if (s->eval_mode == EVAL_MODE_INIT)
|
||||||
values[VAR_X] = i;
|
do_eval(s, inlink, plane);
|
||||||
for (j = 0; j < s->rdft_vlen[plane]; j++)
|
|
||||||
{
|
|
||||||
values[VAR_Y] = j;
|
|
||||||
s->weight[plane][i * s->rdft_vlen[plane] + j] =
|
|
||||||
av_expr_eval(s->weight_expr[plane], values, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -281,6 +299,9 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
|
|||||||
int w = s->planewidth[plane];
|
int w = s->planewidth[plane];
|
||||||
int h = s->planeheight[plane];
|
int h = s->planeheight[plane];
|
||||||
|
|
||||||
|
if (s->eval_mode == EVAL_MODE_FRAME)
|
||||||
|
do_eval(s, inlink, plane);
|
||||||
|
|
||||||
rdft_horizontal(s, in, w, h, plane);
|
rdft_horizontal(s, in, w, h, plane);
|
||||||
rdft_vertical(s, h, plane);
|
rdft_vertical(s, h, plane);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user