* [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