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] libavfilter: cuda and alpha mode (PR #20615)
@ 2025-09-26 14:12 Zhao Zhili via ffmpeg-devel
  0 siblings, 0 replies; only message in thread
From: Zhao Zhili via ffmpeg-devel @ 2025-09-26 14:12 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Zhao Zhili

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 <zhilizhao@tencent.com>
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 <zhilizhao@tencent.com>
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 <zhilizhao@tencent.com>
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 <zhilizhao@tencent.com>
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 <zhilizhao@tencent.com>
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 <zhilizhao@tencent.com>
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 <zhilizhao@tencent.com>
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 <zhilizhao@tencent.com>
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 <zhilizhao@tencent.com>
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

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

only message in thread, other threads:[~2025-09-26 14:13 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-09-26 14:12 [FFmpeg-devel] [PATCH] libavfilter: cuda and alpha mode (PR #20615) Zhao Zhili 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 http://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/ http://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