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: add alphamerge_cuda filter
@ 2025-08-07  2:53 Jorge Estrada
  2025-08-07 10:15 ` Nicolas George
  0 siblings, 1 reply; 2+ messages in thread
From: Jorge Estrada @ 2025-08-07  2:53 UTC (permalink / raw)
  To: ffmpeg-devel; +Cc: Jorge Estrada

This patch adds the alphamerge_cuda video filter

Example usage:
ffmpeg -f lavfi -i "color=c=red:s=1280x720:d=5,format=yuva420p" \
-f lavfi -i "color=c=black:s=1280x720:d=5,geq=lum='255*gt(W/4,hypot(X-W/2,Y-H/2))'" \
-f lavfi -i "color=c=blue:s=1280x720:d=5" \
-filter_complex \
"[0:v]hwupload_cuda[base]; \
 [1:v]hwupload_cuda[mask]; \
 [2:v]hwupload_cuda[bkgd]; \
 [base][mask]alphamerge_cuda[merged]; \
 [bkgd][merged]overlay_cuda" \
-c:v h264_nvenc -y out.mp4
---
 configure                         |   2 +
 doc/filters.texi                  |  21 ++
 libavfilter/Makefile              |   2 +
 libavfilter/allfilters.c          |   1 +
 libavfilter/version.h             |   2 +-
 libavfilter/vf_alphamerge_cuda.c  | 345 ++++++++++++++++++++++++++++++
 libavfilter/vf_alphamerge_cuda.cu |  44 ++++
 7 files changed, 416 insertions(+), 1 deletion(-)
 create mode 100644 libavfilter/vf_alphamerge_cuda.c
 create mode 100644 libavfilter/vf_alphamerge_cuda.cu

diff --git a/configure b/configure
index 30e61c5bb5..268e3c3e28 100755
--- a/configure
+++ b/configure
@@ -3349,6 +3349,8 @@ vaapi_encode_deps="vaapi"
 vulkan_encode_deps="vulkan"
 v4l2_m2m_deps="linux_videodev2_h sem_timedwait"
 
+alphamerge_cuda_filter_deps="ffnvcodec"
+alphamerge_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
 bilateral_cuda_filter_deps="ffnvcodec"
 bilateral_cuda_filter_deps_any="cuda_nvcc cuda_llvm"
 chromakey_cuda_filter_deps="ffnvcodec"
diff --git a/doc/filters.texi b/doc/filters.texi
index 61ece1d000..e51e11eb28 100644
--- a/doc/filters.texi
+++ b/doc/filters.texi
@@ -26500,6 +26500,27 @@ Note: If FFmpeg detects the Nvidia CUDA Toolkit during configuration, it will en
 @item Configure FFmpeg with @code{--enable-cuda-llvm}. Additional requirement: @code{llvm} lib must be installed.
 @end itemize
 
+@subsection alphamerge_cuda
+Add or replace the alpha component of the primary input stream with the luma plane of a second input stream, using CUDA hardware acceleration.
+
+@subsubsection Examples
+@itemize
+@item
+Apply a circular alpha mask to a red video before overlaying it onto a blue background.
+@example
+ffmpeg -f lavfi -i "color=c=red:s=1280x720:d=5,format=yuva420p" \
+-f lavfi -i "color=c=black:s=1280x720:d=5,geq=lum='255*gt(W/4,hypot(X-W/2,Y-H/2))'" \
+-f lavfi -i "color=c=blue:s=1280x720:d=5" \
+-filter_complex \
+"[0:v]hwupload_cuda[base]; \
+ [1:v]hwupload_cuda[mask]; \
+ [2:v]hwupload_cuda[bkgd]; \
+ [base][mask]alphamerge_cuda[merged]; \
+ [bkgd][merged]overlay_cuda" \
+-c:v h264_nvenc -y out.mp4
+@end example
+@end itemize
+
 @subsection bilateral_cuda
 CUDA accelerated bilateral filter, an edge preserving filter.
 This filter is mathematically accurate thanks to the use of GPU acceleration.
diff --git a/libavfilter/Makefile b/libavfilter/Makefile
index 9a906bd342..3df6444f83 100644
--- a/libavfilter/Makefile
+++ b/libavfilter/Makefile
@@ -194,6 +194,8 @@ OBJS-$(CONFIG_ANULLSINK_FILTER)              += asink_anullsink.o
 OBJS-$(CONFIG_ADDROI_FILTER)                 += vf_addroi.o
 OBJS-$(CONFIG_ALPHAEXTRACT_FILTER)           += vf_extractplanes.o
 OBJS-$(CONFIG_ALPHAMERGE_FILTER)             += vf_alphamerge.o framesync.o
+OBJS-$(CONFIG_ALPHAMERGE_CUDA_FILTER)        += vf_alphamerge_cuda.o framesync.o vf_alphamerge_cuda.ptx.o \
+                                                cuda/load_helper.o
 OBJS-$(CONFIG_AMPLIFY_FILTER)                += vf_amplify.o
 OBJS-$(CONFIG_ASS_FILTER)                    += vf_subtitles.o
 OBJS-$(CONFIG_ATADENOISE_FILTER)             += vf_atadenoise.o
diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c
index 44b4de2a14..87e9f2bdd4 100644
--- a/libavfilter/allfilters.c
+++ b/libavfilter/allfilters.c
@@ -179,6 +179,7 @@ extern const FFFilter ff_asink_anullsink;
 extern const FFFilter ff_vf_addroi;
 extern const FFFilter ff_vf_alphaextract;
 extern const FFFilter ff_vf_alphamerge;
+extern const FFFilter ff_vf_alphamerge_cuda;
 extern const FFFilter ff_vf_amplify;
 extern const FFFilter ff_vf_ass;
 extern const FFFilter ff_vf_atadenoise;
diff --git a/libavfilter/version.h b/libavfilter/version.h
index 7e0eb9af97..4d8f28e512 100644
--- a/libavfilter/version.h
+++ b/libavfilter/version.h
@@ -31,7 +31,7 @@
 
 #include "version_major.h"
 
-#define LIBAVFILTER_VERSION_MINOR   3
+#define LIBAVFILTER_VERSION_MINOR   4
 #define LIBAVFILTER_VERSION_MICRO 100
 
 
diff --git a/libavfilter/vf_alphamerge_cuda.c b/libavfilter/vf_alphamerge_cuda.c
new file mode 100644
index 0000000000..b8ab78cb2e
--- /dev/null
+++ b/libavfilter/vf_alphamerge_cuda.c
@@ -0,0 +1,345 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Copy the luma value of the second input into the alpha channel of the first input using CUDA.
+ */
+
+#include "libavutil/internal.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/hwcontext.h"
+#include "libavutil/hwcontext_cuda_internal.h"
+#include "libavutil/cuda_check.h"
+#include "libavutil/mem.h"
+
+#include "avfilter.h"
+#include "filters.h"
+#include "formats.h"
+#include "framesync.h"
+
+#include "cuda/load_helper.h"
+
+#define CHECK_CU(call) FF_CUDA_CHECK_DL(ctx, s->hwctx->internal->cuda_dl, call)
+#define DIV_UP(a, b) ( ((a) + (b) - 1) / (b) )
+
+#define BLOCK_X 32
+#define BLOCK_Y 16
+
+#define MAIN_INPUT 0
+#define ALPHA_INPUT 1
+
+#define ALPHA_PLANE_INDEX 3
+
+static const enum AVPixelFormat supported_main_formats[] = {
+    AV_PIX_FMT_YUVA444P,
+    AV_PIX_FMT_YUVA420P,
+    AV_PIX_FMT_NONE,
+};
+
+static const enum AVPixelFormat supported_alpha_mask_formats[] = {
+    AV_PIX_FMT_YUV420P,
+    AV_PIX_FMT_YUV444P,
+    AV_PIX_FMT_YUVA420P,
+    AV_PIX_FMT_YUVA444P,
+    AV_PIX_FMT_NV12,
+    AV_PIX_FMT_NONE,
+};
+
+typedef struct AlphaMergeCUDAContext {
+    const AVClass *class;
+
+    enum AVPixelFormat sw_format_main;
+    enum AVPixelFormat sw_format_alpha_mask;
+
+    AVBufferRef *hw_device_ctx;
+    AVCUDADeviceContext *hwctx;
+
+    CUcontext cu_ctx;
+    CUmodule cu_module;
+    CUfunction cu_func_alphamerge_planar;
+    CUstream cu_stream;
+
+    FFFrameSync fs;
+
+    int alpha_plane_idx;
+
+} AlphaMergeCUDAContext;
+
+
+static int format_is_supported(const enum AVPixelFormat supported_formats[], enum AVPixelFormat fmt)
+{
+    for (int i = 0; supported_formats[i] != AV_PIX_FMT_NONE; i++)
+        if (supported_formats[i] == fmt)
+            return 1;
+    return 0;
+}
+
+static int query_formats(const AVFilterContext *ctx,
+                         AVFilterFormatsConfig **cfg_in,
+                         AVFilterFormatsConfig **cfg_out)
+{
+    static const int pix_fmts[] = { AV_PIX_FMT_CUDA, AV_PIX_FMT_NONE };
+    static const int alpha_mask_ranges[] = { AVCOL_RANGE_JPEG };
+    AVFilterFormats *formats = NULL;
+    int ret = 0;
+
+    formats = ff_make_format_list(pix_fmts);
+    if (!formats)
+        return AVERROR(ENOMEM);
+
+    if ((ret = ff_set_common_formats2(ctx, cfg_in, cfg_out, ff_make_format_list(pix_fmts))) < 0)
+        return ret;
+
+    formats = ff_make_format_list(alpha_mask_ranges);
+    if (!formats)
+        return AVERROR(ENOMEM);
+
+    ret = ff_formats_ref(formats, &cfg_in[ALPHA_INPUT]->color_ranges);
+    ff_formats_unref(&formats);
+    if (ret < 0)
+        return ret;
+
+    return 0;
+}
+
+static int do_alphamerge_cuda(FFFrameSync *fs)
+{
+    AVFilterContext *ctx = fs->parent;
+    AlphaMergeCUDAContext *s = ctx->priv;
+    AVFilterLink *outlink = ctx->outputs[0];
+    AVFrame *main_frame = NULL;
+    AVFrame *alpha_mask_frame = NULL;
+    CudaFunctions *cu = s->hwctx->internal->cuda_dl;
+    CUcontext dummy_cu_ctx;
+    int ret;
+
+    ret = ff_framesync_dualinput_get_writable(fs, &main_frame, &alpha_mask_frame);
+    if (ret < 0)
+        return ret;
+
+    if (!alpha_mask_frame)
+        return ff_filter_frame(outlink, main_frame);
+
+    ret = CHECK_CU(cu->cuCtxPushCurrent(s->cu_ctx));
+    if (ret < 0)
+        return ret;
+
+    void *kernel_args[] = {
+        &main_frame->data[s->alpha_plane_idx],
+        &main_frame->linesize[s->alpha_plane_idx],
+        &alpha_mask_frame->data[0],
+        &alpha_mask_frame->linesize[0],
+        &main_frame->width,
+        &main_frame->height
+    };
+    unsigned int grid_x = DIV_UP(main_frame->width, BLOCK_X);
+    unsigned int grid_y = DIV_UP(main_frame->height, BLOCK_Y);
+
+    ret = CHECK_CU(cu->cuLaunchKernel(s->cu_func_alphamerge_planar, grid_x, grid_y, 1,
+                                      BLOCK_X, BLOCK_Y, 1,
+                                      0, s->cu_stream, kernel_args, NULL));
+
+    CHECK_CU(cu->cuCtxPopCurrent(&dummy_cu_ctx));
+
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Failed to launch CUDA kernel\n");
+        return ret;
+    }
+
+    return ff_filter_frame(outlink, main_frame);
+}
+
+
+static int alphamerge_cuda_config_output(AVFilterLink *outlink)
+{
+    AVFilterContext *ctx = outlink->src;
+    AlphaMergeCUDAContext *s = ctx->priv;
+
+    AVFilterLink *main_inlink = ctx->inputs[MAIN_INPUT];
+    AVFilterLink *alpha_inlink = ctx->inputs[ALPHA_INPUT];
+
+    FilterLink *main_inl = ff_filter_link(main_inlink);
+    FilterLink *alpha_inl = ff_filter_link(alpha_inlink);
+
+    AVHWFramesContext *main_frames_ctx = (AVHWFramesContext*)main_inl->hw_frames_ctx->data;
+    AVHWFramesContext *alpha_frames_ctx = (AVHWFramesContext*)alpha_inl->hw_frames_ctx->data;
+
+    const AVPixFmtDescriptor *main_desc;
+    CUcontext dummy_cu_ctx;
+    CudaFunctions *cu;
+    int ret = 0;
+
+    extern const unsigned char ff_vf_alphamerge_cuda_ptx_data[];
+    extern const unsigned int ff_vf_alphamerge_cuda_ptx_len;
+
+    s->sw_format_main = main_frames_ctx->sw_format;
+    if (!format_is_supported(supported_main_formats, s->sw_format_main)) {
+        av_log(ctx, AV_LOG_ERROR, "Unsupported main input software pixel format: %s\n",
+               av_get_pix_fmt_name(s->sw_format_main));
+        return AVERROR(ENOSYS);
+    }
+
+    s->sw_format_alpha_mask = alpha_frames_ctx->sw_format;
+    if (!format_is_supported(supported_alpha_mask_formats, s->sw_format_alpha_mask)) {
+        av_log(ctx, AV_LOG_ERROR, "Unsupported alpha mask input software pixel format: %s.\n",
+               av_get_pix_fmt_name(s->sw_format_alpha_mask));
+        return AVERROR(ENOSYS);
+    }
+
+    if (main_inlink->w != alpha_inlink->w || main_inlink->h != alpha_inlink->h) {
+        av_log(ctx, AV_LOG_ERROR, "Input frame sizes do not match (%dx%d vs %dx%d).\n",
+               main_inlink->w, main_inlink->h, alpha_inlink->w, alpha_inlink->h);
+        return AVERROR(EINVAL);
+    }
+
+    s->hw_device_ctx = av_buffer_ref(main_frames_ctx->device_ref);
+    if (!s->hw_device_ctx)
+        return AVERROR(ENOMEM);
+
+    s->hwctx = ((AVHWDeviceContext*)s->hw_device_ctx->data)->hwctx;
+    s->cu_ctx = s->hwctx->cuda_ctx;
+    s->cu_stream = s->hwctx->stream;
+    cu = s->hwctx->internal->cuda_dl;
+
+    ret = CHECK_CU(cu->cuCtxPushCurrent(s->cu_ctx));
+    if (ret < 0)
+        return ret;
+
+    ret = ff_cuda_load_module(ctx, s->hwctx, &s->cu_module,
+                              ff_vf_alphamerge_cuda_ptx_data, ff_vf_alphamerge_cuda_ptx_len);
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Failed to load CUDA module.\n");
+        goto end;
+    }
+
+    ret = CHECK_CU(cu->cuModuleGetFunction(&s->cu_func_alphamerge_planar, s->cu_module, "alphamerge_planar"));
+    if (ret < 0) {
+        av_log(ctx, AV_LOG_ERROR, "Failed to get kernel function 'alphamerge_planar'.\n");
+        goto end;
+    }
+
+    main_desc = av_pix_fmt_desc_get(s->sw_format_main);
+    if (!main_desc || !(main_desc->flags & AV_PIX_FMT_FLAG_ALPHA)) {
+        av_log(ctx, AV_LOG_ERROR, "Main input sw_format %s is not a supported format with an alpha channel.\n",
+               av_get_pix_fmt_name(s->sw_format_main));
+        ret = AVERROR(EINVAL);
+        goto end;
+    }
+    s->alpha_plane_idx = main_desc->comp[ALPHA_PLANE_INDEX].plane;
+
+    ff_filter_link(outlink)->hw_frames_ctx = av_buffer_ref(main_inl->hw_frames_ctx);
+    if (!ff_filter_link(outlink)->hw_frames_ctx) {
+        ret = AVERROR(ENOMEM);
+        goto end;
+    }
+
+    s->fs.time_base = main_inlink->time_base;
+    if ((ret = ff_framesync_init_dualinput(&s->fs, ctx)) < 0)
+        goto end;
+
+    outlink->w = main_inlink->w;
+    outlink->h = main_inlink->h;
+    outlink->time_base = main_inlink->time_base;
+    outlink->sample_aspect_ratio = main_inlink->sample_aspect_ratio;
+    ff_filter_link(outlink)->frame_rate = ff_filter_link(main_inlink)->frame_rate;
+
+    ret = ff_framesync_configure(&s->fs);
+
+end:
+    CHECK_CU(cu->cuCtxPopCurrent(&dummy_cu_ctx));
+    return ret;
+}
+
+static av_cold int alphamerge_cuda_init(AVFilterContext *ctx)
+{
+    AlphaMergeCUDAContext *s = ctx->priv;
+    s->fs.on_event = &do_alphamerge_cuda;
+    return 0;
+}
+
+static av_cold void alphamerge_cuda_uninit(AVFilterContext *ctx)
+{
+    AlphaMergeCUDAContext *s = ctx->priv;
+    CUcontext dummy;
+
+    ff_framesync_uninit(&s->fs);
+
+    if (s->cu_module) {
+        CudaFunctions *cu = s->hwctx->internal->cuda_dl;
+        CHECK_CU(cu->cuCtxPushCurrent(s->cu_ctx));
+
+        if (s->cu_stream)
+            CHECK_CU(cu->cuStreamSynchronize(s->cu_stream));
+
+        CHECK_CU(cu->cuModuleUnload(s->cu_module));
+        CHECK_CU(cu->cuCtxPopCurrent(&dummy));
+    }
+
+    av_buffer_unref(&s->hw_device_ctx);
+}
+
+static int alphamerge_cuda_activate(AVFilterContext *ctx)
+{
+    AlphaMergeCUDAContext *s = ctx->priv;
+    return ff_framesync_activate(&s->fs);
+}
+
+static const AVFilterPad alphamerge_cuda_inputs[] = {
+    {
+        .name = "main",
+        .type = AVMEDIA_TYPE_VIDEO,
+    },
+    {
+        .name = "alpha",
+        .type = AVMEDIA_TYPE_VIDEO,
+    }
+};
+
+static const AVFilterPad alphamerge_cuda_outputs[] = {
+    {
+        .name = "default",
+        .type = AVMEDIA_TYPE_VIDEO,
+        .config_props = &alphamerge_cuda_config_output,
+    }
+};
+
+static const AVOption alphamerge_cuda_options[] = {
+    { NULL },
+};
+
+FRAMESYNC_DEFINE_CLASS(alphamerge_cuda, AlphaMergeCUDAContext, fs);
+
+const FFFilter ff_vf_alphamerge_cuda = {
+    .p.name          = "alphamerge_cuda",
+    .p.description   = NULL_IF_CONFIG_SMALL("Copy the luma value of the second input into the alpha channel of the first input using CUDA."),
+
+    .priv_size     = sizeof(AlphaMergeCUDAContext),
+    .p.priv_class    = &alphamerge_cuda_class,
+
+    .init          = &alphamerge_cuda_init,
+    .uninit        = &alphamerge_cuda_uninit,
+
+    .activate      = &alphamerge_cuda_activate,
+    FILTER_INPUTS(alphamerge_cuda_inputs),
+    FILTER_OUTPUTS(alphamerge_cuda_outputs),
+    FILTER_QUERY_FUNC2(query_formats),
+    .preinit       = alphamerge_cuda_framesync_preinit,
+    .flags_internal = FF_FILTER_FLAG_HWFRAME_AWARE,
+};
\ No newline at end of file
diff --git a/libavfilter/vf_alphamerge_cuda.cu b/libavfilter/vf_alphamerge_cuda.cu
new file mode 100644
index 0000000000..99a9dc91ec
--- /dev/null
+++ b/libavfilter/vf_alphamerge_cuda.cu
@@ -0,0 +1,44 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+template <typename T>
+__device__ void alphamerge_impl(T *dst, int dst_pitch,
+                                const T *src, int src_pitch,
+                                int width, int height)
+{
+    const int x = blockIdx.x * blockDim.x + threadIdx.x;
+    const int y = blockIdx.y * blockDim.y + threadIdx.y;
+
+    if (x < width && y < height) {
+        dst[y * dst_pitch + x] = src[y * src_pitch + x];
+    }
+}
+
+extern "C" {
+    __global__ void alphamerge_planar(unsigned char* main_alpha_plane,
+                                      int main_alpha_linesize,
+                                      const unsigned char* alpha_mask_luma_plane,
+                                      int alpha_mask_luma_linesize,
+                                      int width, int height)
+    {
+        alphamerge_impl<unsigned char>(main_alpha_plane, main_alpha_linesize,
+                                       alpha_mask_luma_plane, alpha_mask_luma_linesize,
+                                       width, height);
+    }
+}
\ No newline at end of file
-- 
2.34.1

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [FFmpeg-devel] [PATCH] avfilter: add alphamerge_cuda filter
  2025-08-07  2:53 [FFmpeg-devel] [PATCH] avfilter: add alphamerge_cuda filter Jorge Estrada
@ 2025-08-07 10:15 ` Nicolas George
  0 siblings, 0 replies; 2+ messages in thread
From: Nicolas George @ 2025-08-07 10:15 UTC (permalink / raw)
  To: FFmpeg development discussions and patches

Jorge Estrada (HE12025-08-06):
> This patch adds the alphamerge_cuda video filter

Thanks, but sorry, no: this is wrong, although not by your fault.

Your filter supports only planar formats. Changing a whole plane in a
planar format should involve a little reference counting gymnastics and
updating a pointer, no data copy.

See <https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/20153>:

# `vf_alphamerge` was added in July 2012 (82ecae8a70), it used memcpy() to
# replace the alpha plane of the frame, that was later (d6b9f2b7da)
# updated to use av_image_copy_plane().
# 
# But in March 2013 (c4e8821732), we gained the ability to share plane
# data between multiple frames, thanks to refcounted buffers.
# `vf_alphamerge` could have used that ability, but it was never done,
# probably because `vf_alphamerge` came from the FFmpeg side while the
# refcounting came from the libav side.
# 
# `vf_alphamerge` needs to be updated to only create a new reference to
# the alpha plane of the input frame and use it in the output frame. No
# data copy involved at all.

The same probably applies to vf_extractplanes.c, although the excuse of
having been added before refcounting is not valid for this one.

These are rather low-hanging fruits.

Regards,

-- 
  Nicolas George
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-08-07 10:15 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-08-07  2:53 [FFmpeg-devel] [PATCH] avfilter: add alphamerge_cuda filter Jorge Estrada
2025-08-07 10:15 ` Nicolas George

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