summaryrefslogtreecommitdiff
path: root/libavfilter/vf_geq.c
diff options
context:
space:
mode:
authorMarton Balint <cus@passwd.hu>2019-12-28 14:50:12 +0100
committerMarton Balint <cus@passwd.hu>2020-01-31 22:47:49 +0100
commitc044ac2071fd1ba2b184a35427c98fc5338a9d27 (patch)
tree03e3bcf5067a0995f6317ae9480b720ae0b9d378 /libavfilter/vf_geq.c
parentb82825eba837f7cbb24c1d66e93285d029307417 (diff)
avfilter/vf_geq: use per-thread AVExpr for expression evaluation
There was no consensus about separating AVExprState from AVExpr so here is a minimal patch using the existing AVExpr to fix ticket #7528. Signed-off-by: Marton Balint <cus@passwd.hu>
Diffstat (limited to 'libavfilter/vf_geq.c')
-rw-r--r--libavfilter/vf_geq.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/libavfilter/vf_geq.c b/libavfilter/vf_geq.c
index 23c989b248..c6f76a6963 100644
--- a/libavfilter/vf_geq.c
+++ b/libavfilter/vf_geq.c
@@ -33,6 +33,7 @@
#include "libavutil/pixdesc.h"
#include "internal.h"
+#define MAX_NB_THREADS 32
#define NB_PLANES 4
enum InterpolationMethods {
@@ -46,7 +47,7 @@ enum { VAR_X, VAR_Y, VAR_W, VAR_H, VAR_N, VAR_
typedef struct GEQContext {
const AVClass *class;
- AVExpr *e[NB_PLANES]; ///< expressions for each plane
+ AVExpr *e[NB_PLANES][MAX_NB_THREADS]; ///< expressions for each plane and thread
char *expr_str[4+3]; ///< expression strings for each plane
AVFrame *picref; ///< current input buffer
uint8_t *dst; ///< reference pointer to the 8bits output
@@ -288,12 +289,14 @@ static av_cold int geq_init(AVFilterContext *ctx)
NULL };
int counter[10] = {0};
- ret = av_expr_parse(&geq->e[plane], geq->expr_str[plane < 3 && geq->is_rgb ? plane+4 : plane], var_names,
- NULL, NULL, func2_names, func2, 0, ctx);
- if (ret < 0)
- break;
+ for (int i = 0; i < MAX_NB_THREADS; i++) {
+ ret = av_expr_parse(&geq->e[plane][i], geq->expr_str[plane < 3 && geq->is_rgb ? plane+4 : plane], var_names,
+ NULL, NULL, func2_names, func2, 0, ctx);
+ if (ret < 0)
+ goto end;
+ }
- av_expr_count_func(geq->e[plane], counter, FF_ARRAY_ELEMS(counter), 2);
+ av_expr_count_func(geq->e[plane][0], counter, FF_ARRAY_ELEMS(counter), 2);
geq->needs_sum[plane] = counter[5] + counter[6] + counter[7] + counter[8] + counter[9];
}
@@ -391,7 +394,7 @@ static int slice_geq_filter(AVFilterContext *ctx, void *arg, int jobnr, int nb_j
for (x = 0; x < width; x++) {
values[VAR_X] = x;
- ptr[x] = av_expr_eval(geq->e[plane], values, geq);
+ ptr[x] = av_expr_eval(geq->e[plane][jobnr], values, geq);
}
ptr += linesize;
}
@@ -401,7 +404,7 @@ static int slice_geq_filter(AVFilterContext *ctx, void *arg, int jobnr, int nb_j
values[VAR_Y] = y;
for (x = 0; x < width; x++) {
values[VAR_X] = x;
- ptr16[x] = av_expr_eval(geq->e[plane], values, geq);
+ ptr16[x] = av_expr_eval(geq->e[plane][jobnr], values, geq);
}
ptr16 += linesize/2;
}
@@ -414,7 +417,7 @@ static int geq_filter_frame(AVFilterLink *inlink, AVFrame *in)
{
int plane;
AVFilterContext *ctx = inlink->dst;
- const int nb_threads = ff_filter_get_nb_threads(ctx);
+ const int nb_threads = FFMIN(MAX_NB_THREADS, ff_filter_get_nb_threads(ctx));
GEQContext *geq = ctx->priv;
AVFilterLink *outlink = inlink->dst->outputs[0];
AVFrame *out;
@@ -464,8 +467,9 @@ static av_cold void geq_uninit(AVFilterContext *ctx)
int i;
GEQContext *geq = ctx->priv;
- for (i = 0; i < FF_ARRAY_ELEMS(geq->e); i++)
- av_expr_free(geq->e[i]);
+ for (i = 0; i < NB_PLANES; i++)
+ for (int j = 0; j < MAX_NB_THREADS; j++)
+ av_expr_free(geq->e[i][j]);
for (i = 0; i < NB_PLANES; i++)
av_freep(&geq->pixel_sums);
}