Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
* [FFmpeg-devel] [PATCH] avfilter/vf_alphamerge: add slice threading
@ 2025-12-21  9:17 Raja Rathour via ffmpeg-devel
  0 siblings, 0 replies; only message in thread
From: Raja Rathour via ffmpeg-devel @ 2025-12-21  9:17 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Raja Rathour

[-- Attachment #1: Type: text/plain, Size: 221 bytes --]

Hi,

This patch adds slice threading support to the alphamerge filter.

Benchmarks with *4K *video show a performance improvement:
Single-Threaded: *2.41s
*Multi-Threaded: *2.25s*

Please review.

Thanks,

*Raja Rathour*

[-- Attachment #2: 0001-Signed-off-by-Raja-Rathour-imraja729-gmail.com.patch --]
[-- Type: text/x-patch, Size: 4467 bytes --]

From c5e3efa9824b85a3ff0db72c12d78fd1d1b74ac1 Mon Sep 17 00:00:00 2001
From: Raja Rathour <imraja729@gmail.com>
Date: Sun, 21 Dec 2025 14:28:25 +0530
Subject: [PATCH] Signed-off-by: Raja Rathour <imraja729@gmail.com>

avfilter/vf_alphamerge: add slice threading

Move the main rendering logic into a slice function to enable
multi-threading support.

Benchmark (4K Video):
Single-Threaded: 2.41s
Multi-Threaded:  2.25s
---
 libavfilter/vf_alphamerge.c | 67 +++++++++++++++++++++++++------------
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/libavfilter/vf_alphamerge.c b/libavfilter/vf_alphamerge.c
index c17a647dbe..cf959a5eec 100644
--- a/libavfilter/vf_alphamerge.c
+++ b/libavfilter/vf_alphamerge.c
@@ -37,6 +37,11 @@
 
 enum { Y, U, V, A };
 
+typedef struct ThreadData {
+    AVFrame *main_buf;
+    AVFrame *alpha_buf;
+} ThreadData;
+
 typedef struct AlphaMergeContext {
     const AVClass *class;
 
@@ -46,12 +51,47 @@ typedef struct AlphaMergeContext {
     FFFrameSync fs;
 } AlphaMergeContext;
 
+static int alphamerge_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
+{
+    AlphaMergeContext *s = ctx->priv;  // <--- THIS WAS MISSING
+    ThreadData *td = arg;
+    AVFrame *main_buf = td->main_buf;
+    AVFrame *alpha_buf = td->alpha_buf;
+    int slice_start = (main_buf->height * jobnr) / nb_jobs;
+    int slice_end   = (main_buf->height * (jobnr+1)) / nb_jobs;
+    int y;
+
+    if (s->is_packed_rgb) {
+        int x;
+        uint8_t *pin, *pout;
+        for (y = slice_start; y < slice_end; y++) {
+            pin = alpha_buf->data[0] + y * alpha_buf->linesize[0];
+            pout = main_buf->data[0] + y * main_buf->linesize[0] + s->rgba_map[A];
+            for (x = 0; x < main_buf->width; x++) {
+                *pout = *pin;
+                pin += 1;
+                pout += 4;
+            }
+        }
+    } else {
+        const int main_linesize = main_buf->linesize[A];
+        const int alpha_linesize = alpha_buf->linesize[Y];
+        av_image_copy_plane(main_buf->data[A] + slice_start * main_linesize,
+                            main_linesize,
+                            alpha_buf->data[Y] + slice_start * alpha_linesize,
+                            alpha_linesize,
+                            FFMIN(main_linesize, alpha_linesize),
+                            slice_end - slice_start);
+    }
+    return 0;
+}
+
 static int do_alphamerge(FFFrameSync *fs)
 {
     AVFilterContext *ctx = fs->parent;
     AVFilterLink *outlink = ctx->outputs[0];
-    AlphaMergeContext *s = ctx->priv;
     AVFrame *main_buf, *alpha_buf;
+    ThreadData td;
     int ret;
 
     ret = ff_framesync_dualinput_get_writable(fs, &main_buf, &alpha_buf);
@@ -67,25 +107,10 @@ static int do_alphamerge(FFFrameSync *fs)
                av_color_range_name(alpha_buf->color_range));
     }
 
-    if (s->is_packed_rgb) {
-        int x, y;
-        uint8_t *pin, *pout;
-        for (y = 0; y < main_buf->height; y++) {
-            pin = alpha_buf->data[0] + y * alpha_buf->linesize[0];
-            pout = main_buf->data[0] + y * main_buf->linesize[0] + s->rgba_map[A];
-            for (x = 0; x < main_buf->width; x++) {
-                *pout = *pin;
-                pin += 1;
-                pout += 4;
-            }
-        }
-    } else {
-        const int main_linesize = main_buf->linesize[A];
-        const int alpha_linesize = alpha_buf->linesize[Y];
-        av_image_copy_plane(main_buf->data[A], main_linesize,
-                            alpha_buf->data[Y], alpha_linesize,
-                            FFMIN(main_linesize, alpha_linesize), alpha_buf->height);
-    }
+    td.main_buf = main_buf;
+    td.alpha_buf = alpha_buf;
+    ff_filter_execute(ctx, alphamerge_slice, &td, NULL,
+                      FFMIN(main_buf->height, ff_filter_get_nb_threads(ctx)));
 
     return ff_filter_frame(ctx->outputs[0], main_buf);
 }
@@ -210,7 +235,7 @@ const FFFilter ff_vf_alphamerge = {
     .p.description  = NULL_IF_CONFIG_SMALL("Copy the luma value of the second "
                       "input into the alpha channel of the first input."),
     .p.priv_class   = &alphamerge_class,
-    .p.flags        = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
+    .p.flags        = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL | AVFILTER_FLAG_SLICE_THREADS,
     .preinit        = alphamerge_framesync_preinit,
     .priv_size      = sizeof(AlphaMergeContext),
     .init           = init,
-- 
2.48.1


[-- Attachment #3: Type: text/plain, Size: 163 bytes --]

_______________________________________________
ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org
To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2025-12-21  9:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-12-21  9:17 [FFmpeg-devel] [PATCH] avfilter/vf_alphamerge: add slice threading Raja Rathour via ffmpeg-devel

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