Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Marton Balint <cus@passwd.hu>
To: ffmpeg-devel@ffmpeg.org
Cc: Marton Balint <cus@passwd.hu>
Subject: [FFmpeg-devel] [PATCH 3/4] avfilter/blend: use a per-thread AVExpr
Date: Thu,  9 May 2024 08:49:17 +0200
Message-ID: <20240509064918.6654-3-cus@passwd.hu> (raw)
In-Reply-To: <20240509064918.6654-1-cus@passwd.hu>

Otherwise expression state is accessed and changed from multiple threads.

Fixes ticket #10987.

Signed-off-by: Marton Balint <cus@passwd.hu>
---
 libavfilter/blend.h    |  3 ++-
 libavfilter/vf_blend.c | 35 ++++++++++++++++++++++++++---------
 2 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/libavfilter/blend.h b/libavfilter/blend.h
index 52c1b777c2..e6636839db 100644
--- a/libavfilter/blend.h
+++ b/libavfilter/blend.h
@@ -72,12 +72,13 @@ enum BlendMode {
 typedef struct SliceParams {
     double *values;
     int starty;
+    AVExpr *e;
 } SliceParams;
 
 typedef struct FilterParams {
     enum BlendMode mode;
     double opacity;
-    AVExpr *e;
+    AVExpr **e;
     char *expr_str;
     void (*blend)(const uint8_t *top, ptrdiff_t top_linesize,
                   const uint8_t *bottom, ptrdiff_t bottom_linesize,
diff --git a/libavfilter/vf_blend.c b/libavfilter/vf_blend.c
index 9ee8901e45..5ea6df2e75 100644
--- a/libavfilter/vf_blend.c
+++ b/libavfilter/vf_blend.c
@@ -47,6 +47,7 @@ typedef struct BlendContext {
     FilterParams params[4];
     int tblend;
     AVFrame *prev_frame;        /* only used with tblend */
+    int nb_threads;
 } BlendContext;
 
 static const char *const var_names[] = {   "X",   "Y",   "W",   "H",   "SW",   "SH",   "T",   "N",   "A",   "B",   "TOP",   "BOTTOM",        NULL };
@@ -139,7 +140,7 @@ static void blend_expr_## name(const uint8_t *_top, ptrdiff_t top_linesize,
     double *values = sliceparam->values;                                       \
     int starty = sliceparam->starty;                                           \
     type *dst = (type*)_dst;                                                   \
-    AVExpr *e = param->e;                                                      \
+    AVExpr *e = sliceparam->e;                                                 \
     int y, x;                                                                  \
     dst_linesize /= div;                                                       \
     top_linesize /= div;                                                       \
@@ -173,7 +174,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
     const uint8_t *bottom = td->bottom->data[td->plane];
     uint8_t *dst    = td->dst->data[td->plane];
     double values[VAR_VARS_NB];
-    SliceParams sliceparam = {.values = &values[0], .starty = slice_start};
+    SliceParams sliceparam = {.values = &values[0], .starty = slice_start, .e = td->param->e ? td->param->e[jobnr] : NULL};
 
     values[VAR_N]  = td->inlink->frame_count_out;
     values[VAR_T]  = td->dst->pts == AV_NOPTS_VALUE ? NAN : td->dst->pts * av_q2d(td->inlink->time_base);
@@ -221,7 +222,7 @@ static AVFrame *blend_frame(AVFilterContext *ctx, AVFrame *top_buf,
                           .inlink = inlink };
 
         ff_filter_execute(ctx, filter_slice, &td, NULL,
-                          FFMIN(outh, ff_filter_get_nb_threads(ctx)));
+                          FFMIN(outh, s->nb_threads));
     }
 
     if (!s->tblend)
@@ -250,6 +251,7 @@ static av_cold int init(AVFilterContext *ctx)
     BlendContext *s = ctx->priv;
 
     s->tblend = !strcmp(ctx->filter->name, "tblend");
+    s->nb_threads = ff_filter_get_nb_threads(ctx);
 
     s->fs.on_event = blend_frame_for_dualinput;
     return 0;
@@ -284,8 +286,14 @@ static av_cold void uninit(AVFilterContext *ctx)
     ff_framesync_uninit(&s->fs);
     av_frame_free(&s->prev_frame);
 
-    for (i = 0; i < FF_ARRAY_ELEMS(s->params); i++)
-        av_expr_free(s->params[i].e);
+    for (i = 0; i < FF_ARRAY_ELEMS(s->params); i++) {
+        if (s->params[i].e) {
+            for (int j = 0; j < s->nb_threads; j++)
+                av_expr_free(s->params[i].e[j]);
+            av_freep(&s->params[i].e);
+        }
+    }
+
 }
 
 static int config_params(AVFilterContext *ctx)
@@ -309,10 +317,19 @@ static int config_params(AVFilterContext *ctx)
                 return AVERROR(ENOMEM);
         }
         if (param->expr_str) {
-            ret = av_expr_parse(&param->e, param->expr_str, var_names,
-                                NULL, NULL, NULL, NULL, 0, ctx);
-            if (ret < 0)
-                return ret;
+            if (!param->e) {
+                param->e = av_calloc(s->nb_threads, sizeof(*param->e));
+                if (!param->e)
+                    return AVERROR(ENOMEM);
+            }
+            for (int i = 0; i < s->nb_threads; i++) {
+                av_expr_free(param->e[i]);
+                param->e[i] = NULL;
+                ret = av_expr_parse(&param->e[i], param->expr_str, var_names,
+                                    NULL, NULL, NULL, NULL, 0, ctx);
+                if (ret < 0)
+                    return ret;
+            }
             param->blend = s->depth > 8 ? s->depth > 16 ? blend_expr_32bit : blend_expr_16bit : blend_expr_8bit;
         }
     }
-- 
2.35.3

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  parent reply	other threads:[~2024-05-09  6:49 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-09  6:49 [FFmpeg-devel] [PATCH 1/4] avfilter/vsrc_testsrc: do not round down width and height for color src Marton Balint
2024-05-09  6:49 ` [FFmpeg-devel] [PATCH 2/4] avfilter/blend: put slice parameters to a single struct Marton Balint
2024-05-09  6:49 ` Marton Balint [this message]
2024-05-09  6:49 ` [FFmpeg-devel] [PATCH 4/4] avfilter/vf_geq: fix interpolation with 1 pixel width/height Marton Balint
2024-05-11  1:57   ` Michael Niedermayer
2024-05-13 19:43     ` Marton Balint

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240509064918.6654-3-cus@passwd.hu \
    --to=cus@passwd.hu \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git