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 A2C2F49207 for ; Fri, 26 Sep 2025 14:13:28 +0000 (UTC) Authentication-Results: ffbox; dkim=fail (body hash mismatch (got b'5FsGrnYBAv0aNKn7sgFtuBYXQ5zZrjYvHUgNNIm1Y6c=', expected b'g5cUV4A4rfdN5UOLuv5jdnIweDMXJ8UucuUKmA9NjI0=')) 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=1758895988; 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=5FsGrnYBAv0aNKn7sgFtuBYXQ5zZrjYvHUgNNIm1Y6c=; b=c5kLUSLnk4PRU5La3WdFrkNw6UqVK5pkB0Gir3as6+nGBtBHTRSYk9CBG5zNGh8H3bmZb MDrPE+eq/m7gXBNg6O7dXEjqTQTTftcAB9pzEr82hVcdftRI/SoAbqz+/56p2XUzAwjl0HK /9Urs+TsjWcirQUX2syNV+4KFt3icacSegFGp+DF0QPai3Nz9r0b5U7mh5//8iN8BHU6OEt Rn2/jC0vQ3m0QatzR+5ar/VqvGpoxBJCHBp8zAOO0q4tPH4nIK2VjezqVeocXg9qBhbgFjX JcSK632R2hRqZPaUCqMePgyNudPQjI/R+ZHWbVnY9U0TdNGrV1YV4+VzoDXg== Received: from [172.19.0.4] (unknown [172.19.0.4]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 11C5768ED5C; Fri, 26 Sep 2025 17:13:08 +0300 (EEST) ARC-Seal: i=1; cv=none; a=rsa-sha256; d=ffmpeg.org; s=arc; t=1758895983; b=Gn3CTNyiTyPvO4ebz7HiqGg5pq1OSq3rI6fnek9n9dhUDcl9QJ27px16viwo0zmnHccAR /TbfmzhDRqcZWHzlZ0ZsAB/+2Nl5xcUsEG8KnI/7gsCDwhpbCPj/owZ7X0k4bk2sEVQWPrf oApw6CIEtK0V/To8sMg2W5JRe+liPVA0bQKE7rqKyhQz0SNJ67O5lFb3cWRTbgAIv4NjYbm MmN7gyPpP5dUDpQeQTWLkv0r3qzOJSPHz5WQbS2FbnYmpoItK7p4jPdkF4XGmCbHuC3gIEN SNaXyq2UdXmqlkyYielBMIWluKijqyUbI5LmiQBdFEvmfROaJZmmZAm5hvuQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=ffmpeg.org; s=arc; t=1758895983; 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=G+85zgOPdnAIegVfp7BuJL/lCZ0+cSmNGDYXSbA1FBY=; b=moax+3yrpa4NW1KHFtuoQGddZd0UUwVlSBtu02uqKsEqWBMGr/6SuStpcDoa8yPpZD272 0owTzKq6U6s3aERCGK1LAvNqeQbb5d2BJBGd2nynobHOruUjsCsdbFPKv0d4HdK+/szz71V aeb0aS9k7GrQfumZ6q1lch0h6llO0H4GB8+6v1HYg4vppdcU/w92E2AonXGU/HTiKhlraIc scowhrhQ77D8n7IjUQFNKC1yG7c/knFl0I/csxd6NEfz2i/j1gjgY34DF08Ld3YFASoYhxs AkMS8bN0x+fUU1Yc6Mct9PvkSkuXGYX7DSTDAKMn+oY6pov9skN5sQQwRKbQ== 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=1758895975; h=content-type : mime-version : content-transfer-encoding : from : to : reply-to : subject : date : from; bh=g5cUV4A4rfdN5UOLuv5jdnIweDMXJ8UucuUKmA9NjI0=; b=28EUkUPPQqm4LbQkEzVpAbXjYL6P9Gp1kwsUXDnHSTcCdiT1YxHGvBtoCxtmswS4OQyrU 2Zl8QvU+2QbuVou06oOiNLKVJruJxccthqnk9E4dju+ta3mn1+K4zXjlXcyWtEB0Qd0ziaq 9ek/7KlVTZR7c1tlF7uPO0+ocYmvlbOZxBnlgC9DtTc5dXS6VfXuHokc7HeQZUGqsy311FT ck79CsmBPCvTdlzxFldiIABnKg3UsVO48/oi0qDkcuaInKgVuvuuzZ1WP7jjStKxfOIBgA7 zKEG0Sbv9fbuDuaJ1spwlW37Zt08HhCApVBuHFuFUU8xeIzlknkI5B4RKKQw== Received: from ed19c606a818 (code.ffmpeg.org [188.245.149.3]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id E7B1668ED2D for ; Fri, 26 Sep 2025 17:12:54 +0300 (EEST) MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Date: Fri, 26 Sep 2025 14:12:54 -0000 Message-ID: <175889597514.25.4258383455586422316@bf249f23a2c8> Message-ID-Hash: KREHSHMCWUADHSVNV4H3BI3TAHH5ACPZ X-Message-ID-Hash: KREHSHMCWUADHSVNV4H3BI3TAHH5ACPZ X-MailFrom: code@ffmpeg.org 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; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list Reply-To: FFmpeg development discussions and patches Subject: [FFmpeg-devel] [PATCH] libavfilter: cuda and alpha mode (PR #20615) 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: Zhao Zhili via ffmpeg-devel Cc: Zhao Zhili Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Archived-At: List-Archive: List-Post: PR #20615 opened by Zhao Zhili (quink) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20615 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/20615.patch >>From 38c142874ed506922c3b0452c1078f4c752352d0 Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 26 Sep 2025 16:06:50 +0800 Subject: [PATCH 1/9] avfilter/vf_bilateral_cuda: remove write only variable --- libavfilter/vf_bilateral_cuda.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libavfilter/vf_bilateral_cuda.c b/libavfilter/vf_bilateral_cuda.c index 7115fa9e05..8f58be63e4 100644 --- a/libavfilter/vf_bilateral_cuda.c +++ b/libavfilter/vf_bilateral_cuda.c @@ -53,8 +53,7 @@ typedef struct CUDABilateralContext { enum AVPixelFormat in_fmt, out_fmt; const AVPixFmtDescriptor *in_desc, *out_desc; - int in_planes, out_planes; - int in_plane_depths[4]; + int in_planes; int in_plane_channels[4]; int window_size; @@ -161,7 +160,6 @@ static av_cold void set_format_info(AVFilterContext *ctx, enum AVPixelFormat in_ s->in_desc = av_pix_fmt_desc_get(s->in_fmt); s->out_desc = av_pix_fmt_desc_get(s->out_fmt); s->in_planes = av_pix_fmt_count_planes(s->in_fmt); - s->out_planes = av_pix_fmt_count_planes(s->out_fmt); // find maximum step of each component of each plane // For our subset of formats, this should accurately tell us how many channels CUDA needs @@ -171,8 +169,6 @@ static av_cold void set_format_info(AVFilterContext *ctx, enum AVPixelFormat in_ d = (s->in_desc->comp[i].depth + 7) / 8; p = s->in_desc->comp[i].plane; s->in_plane_channels[p] = FFMAX(s->in_plane_channels[p], s->in_desc->comp[i].step / d); - - s->in_plane_depths[p] = s->in_desc->comp[i].depth; } } -- 2.49.1 >>From e65b056d237c9d50deec5c601cb425de70fd4a54 Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 26 Sep 2025 16:28:27 +0800 Subject: [PATCH 2/9] avfilter/vf_bilateral_cuda: simplify the checking of window_size --- libavfilter/vf_bilateral_cuda.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_bilateral_cuda.c b/libavfilter/vf_bilateral_cuda.c index 8f58be63e4..8c07b10a72 100644 --- a/libavfilter/vf_bilateral_cuda.c +++ b/libavfilter/vf_bilateral_cuda.c @@ -265,7 +265,7 @@ static av_cold int cuda_bilateral_config_props(AVFilterLink *outlink) outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; // the window_size makes more sense when it is odd, so add 1 if even - s->window_size= (s->window_size%2) ? s->window_size : s->window_size+1; + s->window_size |= 1; ret = cuda_bilateral_load_functions(ctx); if (ret < 0) -- 2.49.1 >>From f2976aab4832ca11c227989152610e0b86689dbb Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 26 Sep 2025 17:08:00 +0800 Subject: [PATCH 3/9] avfilter/vf_bilateral_cuda: simplify frame management --- libavfilter/vf_bilateral_cuda.c | 73 ++++++--------------------------- 1 file changed, 12 insertions(+), 61 deletions(-) diff --git a/libavfilter/vf_bilateral_cuda.c b/libavfilter/vf_bilateral_cuda.c index 8c07b10a72..f6b80c199a 100644 --- a/libavfilter/vf_bilateral_cuda.c +++ b/libavfilter/vf_bilateral_cuda.c @@ -31,6 +31,7 @@ #include "avfilter.h" #include "filters.h" +#include "video.h" #include "cuda/load_helper.h" @@ -61,8 +62,6 @@ typedef struct CUDABilateralContext { float sigmaR; AVBufferRef *frames_ctx; - AVFrame *frame; - AVFrame *tmp_frame; CUcontext cu_ctx; CUmodule cu_module; @@ -71,21 +70,6 @@ typedef struct CUDABilateralContext { CUstream cu_stream; } CUDABilateralContext; -static av_cold int cudabilateral_init(AVFilterContext *ctx) -{ - CUDABilateralContext *s = ctx->priv; - - s->frame = av_frame_alloc(); - if (!s->frame) - return AVERROR(ENOMEM); - - s->tmp_frame = av_frame_alloc(); - if (!s->tmp_frame) - return AVERROR(ENOMEM); - - return 0; -} - static av_cold void cudabilateral_uninit(AVFilterContext *ctx) { CUDABilateralContext *s = ctx->priv; @@ -100,9 +84,7 @@ static av_cold void cudabilateral_uninit(AVFilterContext *ctx) CHECK_CU(cu->cuCtxPopCurrent(&bilateral)); } - av_frame_free(&s->frame); av_buffer_unref(&s->frames_ctx); - av_frame_free(&s->tmp_frame); } static av_cold int init_hwframe_ctx(CUDABilateralContext *s, AVBufferRef *device_ctx, int width, int height) @@ -125,11 +107,6 @@ static av_cold int init_hwframe_ctx(CUDABilateralContext *s, AVBufferRef *device if (ret < 0) goto fail; - av_frame_unref(s->frame); - ret = av_hwframe_get_buffer(out_ref, s->frame, 0); - if (ret < 0) - goto fail; - av_buffer_unref(&s->frames_ctx); s->frames_ctx = out_ref; @@ -366,31 +343,6 @@ exit: return ret; } -static int cuda_bilateral_process(AVFilterContext *ctx, AVFrame *out, AVFrame *in) -{ - CUDABilateralContext *s = ctx->priv; - AVFrame *src = in; - int ret; - - ret = cuda_bilateral_process_internal(ctx, s->frame, src); - if (ret < 0) - return ret; - - src = s->frame; - ret = av_hwframe_get_buffer(src->hw_frames_ctx, s->tmp_frame, 0); - if (ret < 0) - return ret; - - av_frame_move_ref(out, s->frame); - av_frame_move_ref(s->frame, s->tmp_frame); - - ret = av_frame_copy_props(out, in); - if (ret < 0) - return ret; - - return 0; -} - static int cuda_bilateral_filter_frame(AVFilterLink *link, AVFrame *in) { AVFilterContext *ctx = link->dst; @@ -398,11 +350,11 @@ static int cuda_bilateral_filter_frame(AVFilterLink *link, AVFrame *in) AVFilterLink *outlink = ctx->outputs[0]; CudaFunctions *cu = s->hwctx->internal->cuda_dl; - AVFrame *out = NULL; + AVFrame *out; CUcontext bilateral; int ret = 0; - out = av_frame_alloc(); + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!out) { ret = AVERROR(ENOMEM); goto fail; @@ -412,9 +364,15 @@ static int cuda_bilateral_filter_frame(AVFilterLink *link, AVFrame *in) if (ret < 0) goto fail; - ret = cuda_bilateral_process(ctx, out, in); + ret = cuda_bilateral_process_internal(ctx, out, in); + if (ret < 0) + goto fail; - CHECK_CU(cu->cuCtxPopCurrent(&bilateral)); + ret = av_frame_copy_props(out, in); + if (ret < 0) + goto fail; + + ret = CHECK_CU(cu->cuCtxPopCurrent(&bilateral)); if (ret < 0) goto fail; @@ -461,18 +419,11 @@ static const AVFilterPad cuda_bilateral_outputs[] = { const FFFilter ff_vf_bilateral_cuda = { .p.name = "bilateral_cuda", .p.description = NULL_IF_CONFIG_SMALL("GPU accelerated bilateral filter"), - .p.priv_class = &cuda_bilateral_class, - - .init = cudabilateral_init, .uninit = cudabilateral_uninit, - - .priv_size = sizeof(CUDABilateralContext), - + .priv_size = sizeof(CUDABilateralContext), FILTER_INPUTS(cuda_bilateral_inputs), FILTER_OUTPUTS(cuda_bilateral_outputs), - FILTER_SINGLE_PIXFMT(AV_PIX_FMT_CUDA), - .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE, }; -- 2.49.1 >>From cf5ecc7e4d0b2b0a1893effdd46311ace87ca9f8 Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 26 Sep 2025 17:49:33 +0800 Subject: [PATCH 4/9] avfilter/vf_bilateral_cuda: don't create a new hwframe_ctx There is no change on properties, so just reference the input link's hwframe ctx. --- libavfilter/vf_bilateral_cuda.c | 41 +-------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/libavfilter/vf_bilateral_cuda.c b/libavfilter/vf_bilateral_cuda.c index f6b80c199a..a55f021374 100644 --- a/libavfilter/vf_bilateral_cuda.c +++ b/libavfilter/vf_bilateral_cuda.c @@ -61,8 +61,6 @@ typedef struct CUDABilateralContext { float sigmaS; float sigmaR; - AVBufferRef *frames_ctx; - CUcontext cu_ctx; CUmodule cu_module; CUfunction cu_func; @@ -83,37 +81,6 @@ static av_cold void cudabilateral_uninit(AVFilterContext *ctx) s->cu_module = NULL; CHECK_CU(cu->cuCtxPopCurrent(&bilateral)); } - - av_buffer_unref(&s->frames_ctx); -} - -static av_cold int init_hwframe_ctx(CUDABilateralContext *s, AVBufferRef *device_ctx, int width, int height) -{ - AVBufferRef *out_ref = NULL; - AVHWFramesContext *out_ctx; - int ret; - - out_ref = av_hwframe_ctx_alloc(device_ctx); - if (!out_ref) - return AVERROR(ENOMEM); - out_ctx = (AVHWFramesContext*)out_ref->data; - - out_ctx->format = AV_PIX_FMT_CUDA; - out_ctx->sw_format = s->out_fmt; - out_ctx->width = width; - out_ctx->height = height; - - ret = av_hwframe_ctx_init(out_ref); - if (ret < 0) - goto fail; - - av_buffer_unref(&s->frames_ctx); - s->frames_ctx = out_ref; - - return 0; -fail: - av_buffer_unref(&out_ref); - return ret; } static int format_is_supported(enum AVPixelFormat fmt) @@ -153,9 +120,7 @@ static av_cold int init_processing_chain(AVFilterContext *ctx, int width, int he { FilterLink *inl = ff_filter_link(ctx->inputs[0]); FilterLink *outl = ff_filter_link(ctx->outputs[0]); - CUDABilateralContext *s = ctx->priv; AVHWFramesContext *in_frames_ctx; - int ret; /* check that we have a hw context */ if (!inl->hw_frames_ctx) { @@ -171,11 +136,7 @@ static av_cold int init_processing_chain(AVFilterContext *ctx, int width, int he set_format_info(ctx, in_frames_ctx->sw_format, in_frames_ctx->sw_format); - ret = init_hwframe_ctx(s, in_frames_ctx->device_ref, width, height); - if (ret < 0) - return ret; - - outl->hw_frames_ctx = av_buffer_ref(s->frames_ctx); + outl->hw_frames_ctx = av_buffer_ref(inl->hw_frames_ctx); if (!outl->hw_frames_ctx) return AVERROR(ENOMEM); -- 2.49.1 >>From af5671b90bb2d151a13b9342736f0883822ae7fa Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 26 Sep 2025 18:01:11 +0800 Subject: [PATCH 5/9] avfilter/vf_bilateral_cuda: remove some variables and redundant operations Since output format is equal to input format, there is no point to save two groups of fmt and desc. --- libavfilter/vf_bilateral_cuda.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/libavfilter/vf_bilateral_cuda.c b/libavfilter/vf_bilateral_cuda.c index a55f021374..acc8736f80 100644 --- a/libavfilter/vf_bilateral_cuda.c +++ b/libavfilter/vf_bilateral_cuda.c @@ -52,8 +52,7 @@ typedef struct CUDABilateralContext { const AVClass *class; AVCUDADeviceContext *hwctx; - enum AVPixelFormat in_fmt, out_fmt; - const AVPixFmtDescriptor *in_desc, *out_desc; + const AVPixFmtDescriptor *in_desc; int in_planes; int in_plane_channels[4]; @@ -93,17 +92,13 @@ static int format_is_supported(enum AVPixelFormat fmt) return 0; } -static av_cold void set_format_info(AVFilterContext *ctx, enum AVPixelFormat in_format, enum AVPixelFormat out_format) +static av_cold void set_format_info(AVFilterContext *ctx, enum AVPixelFormat format) { CUDABilateralContext *s = ctx->priv; int i, p, d; - s->in_fmt = in_format; - s->out_fmt = out_format; - - s->in_desc = av_pix_fmt_desc_get(s->in_fmt); - s->out_desc = av_pix_fmt_desc_get(s->out_fmt); - s->in_planes = av_pix_fmt_count_planes(s->in_fmt); + s->in_desc = av_pix_fmt_desc_get(format); + s->in_planes = av_pix_fmt_count_planes(format); // find maximum step of each component of each plane // For our subset of formats, this should accurately tell us how many channels CUDA needs @@ -134,7 +129,7 @@ static av_cold int init_processing_chain(AVFilterContext *ctx, int width, int he return AVERROR(ENOSYS); } - set_format_info(ctx, in_frames_ctx->sw_format, in_frames_ctx->sw_format); + set_format_info(ctx, in_frames_ctx->sw_format); outl->hw_frames_ctx = av_buffer_ref(inl->hw_frames_ctx); if (!outl->hw_frames_ctx) @@ -287,8 +282,8 @@ static int cuda_bilateral_process_internal(AVFilterContext *ctx, ret = call_cuda_kernel(ctx, (s->in_plane_channels[1] > 1) ? s->cu_func_uv : s->cu_func, tex, out, out->width, out->height, out->linesize[0], - AV_CEIL_RSHIFT(out->width, s->out_desc->log2_chroma_w), - AV_CEIL_RSHIFT(out->height, s->out_desc->log2_chroma_h), + AV_CEIL_RSHIFT(out->width, s->in_desc->log2_chroma_w), + AV_CEIL_RSHIFT(out->height, s->in_desc->log2_chroma_h), out->linesize[1] >> ((s->in_plane_channels[1] > 1) ? 1 : 0), s->window_size, s->sigmaS, s->sigmaR); if (ret < 0) -- 2.49.1 >>From f70edf234a017266599b73f146e741ae9242bcd0 Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 26 Sep 2025 19:44:09 +0800 Subject: [PATCH 6/9] avfilter/vf_bilateral_cuda: remove a goto which has no effect --- libavfilter/vf_bilateral_cuda.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/libavfilter/vf_bilateral_cuda.c b/libavfilter/vf_bilateral_cuda.c index acc8736f80..4cb6d2e641 100644 --- a/libavfilter/vf_bilateral_cuda.c +++ b/libavfilter/vf_bilateral_cuda.c @@ -286,8 +286,6 @@ static int cuda_bilateral_process_internal(AVFilterContext *ctx, AV_CEIL_RSHIFT(out->height, s->in_desc->log2_chroma_h), out->linesize[1] >> ((s->in_plane_channels[1] > 1) ? 1 : 0), s->window_size, s->sigmaS, s->sigmaR); - if (ret < 0) - goto exit; exit: for (i = 0; i < s->in_planes; i++) -- 2.49.1 >>From 20dbfc8bfe1661115f84e4a4c4d87233276922ef Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 26 Sep 2025 20:08:36 +0800 Subject: [PATCH 7/9] avfilter/vf_chromakey_cuda: simplify frame management --- libavfilter/vf_chromakey_cuda.c | 98 +++++++++------------------------ 1 file changed, 25 insertions(+), 73 deletions(-) diff --git a/libavfilter/vf_chromakey_cuda.c b/libavfilter/vf_chromakey_cuda.c index 43f50c5a9a..6595e5317b 100644 --- a/libavfilter/vf_chromakey_cuda.c +++ b/libavfilter/vf_chromakey_cuda.c @@ -32,6 +32,7 @@ #include "avfilter.h" #include "filters.h" #include "cuda/load_helper.h" +#include "video.h" static const enum AVPixelFormat supported_formats[] = { AV_PIX_FMT_YUV420P, @@ -61,10 +62,6 @@ typedef struct ChromakeyCUDAContext { float similarity; float blend; - AVBufferRef *frames_ctx; - AVFrame *frame; - AVFrame *tmp_frame; - CUcontext cu_ctx; CUmodule cu_module; CUfunction cu_func; @@ -72,21 +69,6 @@ typedef struct ChromakeyCUDAContext { CUstream cu_stream; } ChromakeyCUDAContext; -static av_cold int cudachromakey_init(AVFilterContext *ctx) -{ - ChromakeyCUDAContext *s = ctx->priv; - - s->frame = av_frame_alloc(); - if (!s->frame) - return AVERROR(ENOMEM); - - s->tmp_frame = av_frame_alloc(); - if (!s->tmp_frame) - return AVERROR(ENOMEM); - - return 0; -} - static av_cold void cudachromakey_uninit(AVFilterContext *ctx) { ChromakeyCUDAContext *s = ctx->priv; @@ -101,14 +83,12 @@ static av_cold void cudachromakey_uninit(AVFilterContext *ctx) s->cu_module = NULL; CHECK_CU(cu->cuCtxPopCurrent(&context)); } - - av_frame_free(&s->frame); - av_buffer_unref(&s->frames_ctx); - av_frame_free(&s->tmp_frame); } -static av_cold int init_hwframe_ctx(ChromakeyCUDAContext *s, AVBufferRef *device_ctx, int width, int height) +static av_cold int init_hwframe_ctx(AVFilterContext *ctx, AVBufferRef *device_ctx, int width, int height) { + FilterLink *outl = ff_filter_link(ctx->outputs[0]); + ChromakeyCUDAContext *s = ctx->priv; AVBufferRef *out_ref = NULL; AVHWFramesContext *out_ctx; int ret; @@ -127,13 +107,7 @@ static av_cold int init_hwframe_ctx(ChromakeyCUDAContext *s, AVBufferRef *device if (ret < 0) goto fail; - av_frame_unref(s->frame); - ret = av_hwframe_get_buffer(out_ref, s->frame, 0); - if (ret < 0) - goto fail; - - av_buffer_unref(&s->frames_ctx); - s->frames_ctx = out_ref; + outl->hw_frames_ctx = out_ref; return 0; fail: @@ -181,7 +155,6 @@ static av_cold void set_format_info(AVFilterContext *ctx, enum AVPixelFormat in_ static av_cold int init_processing_chain(AVFilterContext *ctx, int width, int height) { FilterLink *inl = ff_filter_link(ctx->inputs[0]); - FilterLink *outl = ff_filter_link(ctx->outputs[0]); ChromakeyCUDAContext *s = ctx->priv; AVHWFramesContext *in_frames_ctx; int ret; @@ -201,13 +174,15 @@ static av_cold int init_processing_chain(AVFilterContext *ctx, int width, int he set_format_info(ctx, in_frames_ctx->sw_format, AV_PIX_FMT_YUVA420P); - ret = init_hwframe_ctx(s, in_frames_ctx->device_ref, width, height); - if (ret < 0) - return ret; - - outl->hw_frames_ctx = av_buffer_ref(s->frames_ctx); - if (!outl->hw_frames_ctx) - return AVERROR(ENOMEM); + if (in_frames_ctx->sw_format == s->out_fmt) { + ff_filter_link(ctx->outputs[0])->hw_frames_ctx = av_buffer_ref(inl->hw_frames_ctx); + if (!ff_filter_link(ctx->outputs[0])->hw_frames_ctx) + return AVERROR(ENOMEM); + } else { + ret = init_hwframe_ctx(ctx, in_frames_ctx->device_ref, width, height); + if (ret < 0) + return ret; + } return 0; } @@ -386,31 +361,6 @@ exit: return ret; } -static int cudachromakey_process(AVFilterContext *ctx, AVFrame *out, AVFrame *in) -{ - ChromakeyCUDAContext *s = ctx->priv; - AVFrame *src = in; - int ret; - - ret = cudachromakey_process_internal(ctx, s->frame, src); - if (ret < 0) - return ret; - - src = s->frame; - ret = av_hwframe_get_buffer(src->hw_frames_ctx, s->tmp_frame, 0); - if (ret < 0) - return ret; - - av_frame_move_ref(out, s->frame); - av_frame_move_ref(s->frame, s->tmp_frame); - - ret = av_frame_copy_props(out, in); - if (ret < 0) - return ret; - - return 0; -} - static int cudachromakey_filter_frame(AVFilterLink *link, AVFrame *in) { AVFilterContext *ctx = link->dst; @@ -418,13 +368,12 @@ static int cudachromakey_filter_frame(AVFilterLink *link, AVFrame *in) AVFilterLink *outlink = ctx->outputs[0]; CudaFunctions *cu = s->hwctx->internal->cuda_dl; - AVFrame *out = NULL; + AVFrame *out; CUcontext context; int ret = 0; - out = av_frame_alloc(); - if (!out) - { + out = ff_get_video_buffer(outlink, outlink->w, outlink->h); + if (!out) { ret = AVERROR(ENOMEM); goto fail; } @@ -433,9 +382,15 @@ static int cudachromakey_filter_frame(AVFilterLink *link, AVFrame *in) if (ret < 0) goto fail; - ret = cudachromakey_process(ctx, out, in); + ret = cudachromakey_process_internal(ctx, out, in); + if (ret < 0) + goto fail; - CHECK_CU(cu->cuCtxPopCurrent(&context)); + ret = av_frame_copy_props(out, in); + if (ret < 0) + goto fail; + + ret = CHECK_CU(cu->cuCtxPopCurrent(&context)); if (ret < 0) goto fail; @@ -485,10 +440,7 @@ const FFFilter ff_vf_chromakey_cuda = { .p.description = NULL_IF_CONFIG_SMALL("GPU accelerated chromakey filter"), .p.priv_class = &cudachromakey_class, - - .init = cudachromakey_init, .uninit = cudachromakey_uninit, - .priv_size = sizeof(ChromakeyCUDAContext), FILTER_INPUTS(cudachromakey_inputs), -- 2.49.1 >>From fa1a8c64b0a6f8e1fbd35e1c9a84663a17430996 Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 26 Sep 2025 21:06:24 +0800 Subject: [PATCH 8/9] avfilter/vf_chromakey_cuda: specify alpha_mode of output Fix assert failure with: ffmpeg -init_hw_device cuda=gpu -filter_hw_device gpu \ -i input.mp4 -an \ -vf hwupload,format=cuda,chromakey_cuda=color=black,hwdownload,format=yuva420p,alphaextract \ -f null - Assertion frame->alpha_mode == link->alpha_mode failed at src/libavfilter/avfilter.c:1085 --- libavfilter/vf_chromakey_cuda.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavfilter/vf_chromakey_cuda.c b/libavfilter/vf_chromakey_cuda.c index 6595e5317b..4ffc5cd77e 100644 --- a/libavfilter/vf_chromakey_cuda.c +++ b/libavfilter/vf_chromakey_cuda.c @@ -259,6 +259,7 @@ static av_cold int cudachromakey_config_props(AVFilterLink *outlink) s->cu_stream = s->hwctx->stream; outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; + outlink->alpha_mode = AVALPHA_MODE_STRAIGHT; ret = cudachromakey_load_functions(ctx); if (ret < 0) @@ -389,6 +390,7 @@ static int cudachromakey_filter_frame(AVFilterLink *link, AVFrame *in) ret = av_frame_copy_props(out, in); if (ret < 0) goto fail; + out->alpha_mode = outlink->alpha_mode; ret = CHECK_CU(cu->cuCtxPopCurrent(&context)); if (ret < 0) -- 2.49.1 >>From e9e3d078264d2d6d8657e00e94f66779117364be Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Fri, 26 Sep 2025 21:33:57 +0800 Subject: [PATCH 9/9] avfilter/vf_chromakey: specify alphamode of chromakey filter Fix assert failure with: ffmpeg -i input.mp4 \ -vf chromakey=similarity=0.1,format=yuva420p,alphaextract \ -f null - Assertion frame->alpha_mode == link->alpha_mode failed at src/libavfilter/avfilter.c:1085 --- libavfilter/vf_chromakey.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavfilter/vf_chromakey.c b/libavfilter/vf_chromakey.c index f6f6314615..e5a7ac15b5 100644 --- a/libavfilter/vf_chromakey.c +++ b/libavfilter/vf_chromakey.c @@ -262,6 +262,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *frame) FFMIN(frame->height, ff_filter_get_nb_threads(avctx)))) return res; + if (!strcmp(avctx->filter->name, "chromakey")) + frame->alpha_mode = avctx->outputs[0]->alpha_mode; return ff_filter_frame(avctx->outputs[0], frame); } @@ -291,6 +293,7 @@ static av_cold int config_output(AVFilterLink *outlink) } if (!strcmp(avctx->filter->name, "chromakey")) { + outlink->alpha_mode = AVALPHA_MODE_STRAIGHT; ctx->do_slice = ctx->depth <= 8 ? do_chromakey_slice : do_chromakey16_slice; } else { ctx->do_slice = ctx->depth <= 8 ? do_chromahold_slice: do_chromahold16_slice; -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- ffmpeg-devel@ffmpeg.org To unsubscribe send an email to ffmpeg-devel-leave@ffmpeg.org