From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id 78A9C4D044 for ; Wed, 7 Jan 2026 14:22:39 +0000 (UTC) Authentication-Results: ffbox; dkim=fail (body hash mismatch (got b'cQLhU0ERVVRKxMOp9ZcZACENwaDnJgLW7qocxMun8IA=', expected b'VyODFeaWSjj0Ty6VMZgS+KctDLqa8Vh3ZFizAU7183g=')) header.d=ffmpeg.org header.i=@ffmpeg.org header.a=rsa-sha256 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1767795729; h=mime-version : to : date : message-id : reply-to : subject : list-id : list-archive : list-archive : list-help : list-owner : list-post : list-subscribe : list-unsubscribe : from : cc : content-type : content-transfer-encoding : from; bh=cQLhU0ERVVRKxMOp9ZcZACENwaDnJgLW7qocxMun8IA=; b=U+sLYJBF2bzHV+MnoPGle8wphtc66vzlY7WJbA5uxlk3nGkZqk6WGJEV8Go43D1xLLRW9 jnmc9YcI0x+Z7HMB8K12u4i9AYRrOhdhxMR+BqZlT8vl8gzGd1oeXr7oqgxWLrn2rlMVS/W qlZoXDnceAPXkkVPVxGtBFE1adBJUSCYVHIDXt6T8k2mpRIP8Q7baNYdVRZUGMlZNXugOiV HXNENOOfJW98biBLGkagRKKoMiFXn/IIQGfvzUB2reGoL/lnJmVLsj//a1at+tGSl/iHafP 1e4UW7jSqRBurFGmzzpO4QbMxtne/KDScX9Q5v3vZeXWRdTi7TPi6vnsjIVg== Received: from [172.20.0.4] (unknown [172.20.0.4]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 63D60690D8E; Wed, 7 Jan 2026 16:22:09 +0200 (EET) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=ffmpeg.org; s=arc; t=1767795714; b=sMz0pRRrhIielzjCgvxskdpqr8fka8tzxF6XJXI9cqlIyIMLtZ32jU5lIlvfTGNFWLQfl DSc2TDcOd94c9hb36ntzDoms0kZ0Nl6G9KQ5z4MFQLQpdA3tXcAnzUvRub5oxoSjZnd5lyd DMhb8OV/s81dQpeSRUyUESEvzCv5unQRBqdSK9OrvLxqhfbV1NJWBfTzpTDYfgGAugExfwL GckAQ/UGBOmuUodCV6s501k15gDpEWiMYeXDS9lk3IKKQz2wSh9h5NyJ8aJ3HVPjqHLqmWq fWID0UWIA4fIoHL+MnxEV3wTjXt4kcJlFlei3iewWhf1vvc6EVA4+T/Joj8A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=ffmpeg.org; s=arc; t=1767795714; h=from : sender : reply-to : subject : date : message-id : to : cc : mime-version : content-type : content-transfer-encoding : content-id : content-description : resent-date : resent-from : resent-sender : resent-to : resent-cc : resent-message-id : in-reply-to : references : list-id : list-help : list-unsubscribe : list-subscribe : list-post : list-owner : list-archive; bh=AbJzFEa/3q9N+lPKywN4Ws1flvwg1Fi1XPza0L1ZYzw=; b=lQNu059Vr5ZyypgQncbwyRJLOqhxUv2DXwWchqTtIfc10v0t/bL4NSWeGP3GOKe1psPn+ 9S4mTD/yu/iYDEIzbnlEizvlUTRUqoWHlm5xnQOYutiWU7/eV5GG8MoMpBZXaXNQS1LJ/7C WVoRzqp5d1xGquILkSSWfZNvGm2vB8Y/Zj70qDtxWDklIV+VzHYdP0t3Y1HD7j/U6iBN31s SdnWnm6iKhgan5XHh1sIpUgM3ek4KYVnjBDCRdRdphodXE9HM8TI9pjDXkGZ8uzqxjJwl19 kX7oqdZjUiZBh/Su1jcEZAFySLGIXQsXlkEhVuDHR5ReTeevzLRhmifGtlEw== ARC-Authentication-Results: i=1; ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none; dmarc=pass header.from=ffmpeg.org policy.dmarc=quarantine Authentication-Results: ffmpeg.org; dkim=pass header.d=ffmpeg.org header.i=@ffmpeg.org; arc=none (Message is not ARC signed); dmarc=pass (Used From Domain Record) header.from=ffmpeg.org policy.dmarc=quarantine DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ffmpeg.org; i=@ffmpeg.org; q=dns/txt; s=mail; t=1767795706; h=content-type : mime-version : content-transfer-encoding : from : to : reply-to : subject : date : from; bh=VyODFeaWSjj0Ty6VMZgS+KctDLqa8Vh3ZFizAU7183g=; b=VKZrRIE7cqg9SYdYAqXTVVDopGz9T4ZeYyqROcWfRhFI0EbgYGV2TTiDUbltu8Lt8Uv7G HgRfTnZogh5UH3VnOrzOgkOC+RCl4QoZ31bndygwGYd043g8uTaU2vs/sUhnBCclPrNoTJ1 Ls1Q70c6BDGhZX3VGiH2dOzxaJPEWf1ikxRTsjBTn8UpOeNWYBG1vz9pqHq/MNDHGGf0pwi WryA2jNqhVHjvV88DtgYl/EJP0j4lmqUAcV1DwxV6PubyJ/twGsYXx3F1PmMFWhblfA2n81 UEmR0lJV0BEaId3JjnbFvDXns/huYBfQvszbm1FWkmpdWiP+zIRyUpGw0RfA== Received: from de3a2b3407a2 (code.ffmpeg.org [188.245.149.3]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 7B5A468FEDD for ; Wed, 7 Jan 2026 16:21:46 +0200 (EET) MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Date: Wed, 07 Jan 2026 14:21:46 -0000 Message-ID: <176779570667.25.14493060368576644874@4457048688e7> Message-ID-Hash: FK4FYDCR4PK2J3ESXA44AFXHU72NJPDW X-Message-ID-Hash: FK4FYDCR4PK2J3ESXA44AFXHU72NJPDW X-MailFrom: code@ffmpeg.org X-Mailman-Rule-Hits: nonmember-moderation X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-ffmpeg-devel.ffmpeg.org-0; header-match-ffmpeg-devel.ffmpeg.org-1; header-match-ffmpeg-devel.ffmpeg.org-2; header-match-ffmpeg-devel.ffmpeg.org-3; emergency; member-moderation X-Mailman-Version: 3.3.10 Precedence: list Reply-To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PR] avfilter/vf_blackframe: add slice threading using stdatomic (PR #21407) List-Id: FFmpeg development discussions and patches Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Raja-89 via ffmpeg-devel Cc: Raja-89 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Archived-At: List-Archive: List-Post: PR #21407 opened by Raja-89 URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21407 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21407.patch This patch implements slice threading for the blackframe filter to improve processing performance. To avoid unnecessary memory allocation and reduce overhead, the implementation uses a single stdatomic atomic integer for the global black pixel count across all threads, as requested during review. Changes in v9: - Implemented slice threading using ff_filter_execute. - Replaced heap allocation (av_calloc) with stdatomic (atomic_uint) for the pixel counter. - Enabled AVFILTER_FLAG_SLICE_THREADS. - Updated height comment to Doxygen style (///<) and restored original struct comments. Signed-off-by: Raja Rathour >>From 87328a4c047ad3dd803208f823c14758c0bb83bb Mon Sep 17 00:00:00 2001 From: Raja Rathour Date: Wed, 7 Jan 2026 19:46:56 +0530 Subject: [PATCH] avfilter/vf_blackframe: add slice threading using stdatomic Signed-off-by: Raja Rathour --- libavfilter/vf_blackframe.c | 58 ++++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c index f0aa53e133..d45fef5d14 100644 --- a/libavfilter/vf_blackframe.c +++ b/libavfilter/vf_blackframe.c @@ -29,6 +29,7 @@ #include #include +#include #include "libavutil/internal.h" #include "libavutil/opt.h" @@ -41,10 +42,19 @@ typedef struct BlackFrameContext { int bamount; ///< black amount int bthresh; ///< black threshold unsigned int frame; ///< frame number - unsigned int nblack; ///< number of black pixels counted so far + atomic_uint nblack; ///< number of black pixels counted so far unsigned int last_keyframe; ///< frame number of the last received key-frame } BlackFrameContext; +typedef struct ThreadData { + const uint8_t *data; + int linesize; + int bthresh; + int width; + int height; + BlackFrameContext *s; +} ThreadData; + static const enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV410P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_GRAY8, AV_PIX_FMT_NV12, AV_PIX_FMT_NV21, AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV411P, @@ -55,26 +65,53 @@ static const enum AVPixelFormat pix_fmts[] = { snprintf(buf, sizeof(buf), format, value); \ av_dict_set(metadata, key, buf, 0) +static int blackframe_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) +{ + ThreadData *td = arg; + int slice_start = (td->height * jobnr) / nb_jobs; + int slice_end = (td->height * (jobnr+1)) / nb_jobs; + int x, y; + const uint8_t *p; + unsigned int black_pixels_count = 0; + + p = td->data + slice_start * td->linesize; + + for (y = slice_start; y < slice_end; y++) { + for (x = 0; x < td->width; x++) + black_pixels_count += p[x] < td->bthresh; + p += td->linesize; + } + + atomic_fetch_add(&td->s->nblack, black_pixels_count); + return 0; +} + static int filter_frame(AVFilterLink *inlink, AVFrame *frame) { AVFilterContext *ctx = inlink->dst; BlackFrameContext *s = ctx->priv; - int x, i; + ThreadData td; int pblack = 0; - uint8_t *p = frame->data[0]; + int nb_threads = ff_filter_get_nb_threads(ctx); + int nb_jobs = FFMIN(inlink->h, nb_threads); AVDictionary **metadata; char buf[32]; - for (i = 0; i < frame->height; i++) { - for (x = 0; x < inlink->w; x++) - s->nblack += p[x] < s->bthresh; - p += frame->linesize[0]; - } + atomic_init(&s->nblack, 0); + + td.data = frame->data[0]; + td.linesize = frame->linesize[0]; + td.width = inlink->w; + td.height = inlink->h; + td.bthresh = s->bthresh; + td.s = s; + + ff_filter_execute(ctx, blackframe_slice, &td, NULL, nb_jobs); if (frame->flags & AV_FRAME_FLAG_KEY) s->last_keyframe = s->frame; - pblack = s->nblack * 100 / (inlink->w * inlink->h); + pblack = atomic_load(&s->nblack) * 100 / (inlink->w * inlink->h); if (pblack >= s->bamount) { metadata = &frame->metadata; @@ -88,7 +125,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) } s->frame++; - s->nblack = 0; return ff_filter_frame(inlink->dst->outputs[0], frame); } @@ -118,7 +154,7 @@ const FFFilter ff_vf_blackframe = { .p.name = "blackframe", .p.description = NULL_IF_CONFIG_SMALL("Detect frames that are (almost) black."), .p.priv_class = &blackframe_class, - .p.flags = AVFILTER_FLAG_METADATA_ONLY, + .p.flags = AVFILTER_FLAG_METADATA_ONLY | AVFILTER_FLAG_SLICE_THREADS, .priv_size = sizeof(BlackFrameContext), FILTER_INPUTS(avfilter_vf_blackframe_inputs), FILTER_OUTPUTS(ff_video_default_filterpad), -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org