This is an automated email from the git hooks/post-receive script. Git pushed a commit to branch master in repository ffmpeg.
commit 51d4406e075a99eb7fdec8b96dac9b91a34e900f Author: Lynne <[email protected]> AuthorDate: Sun Apr 26 15:47:17 2026 +0200 Commit: Lynne <[email protected]> CommitDate: Fri May 22 14:05:21 2026 +0900 swscale/graph: support allocating hardware intermediate frames Sponsored-by: Sovereign Tech Fund --- libswscale/graph.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++-- libswscale/vulkan/ops.c | 7 +++++++ libswscale/vulkan/ops.h | 6 ++++++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/libswscale/graph.c b/libswscale/graph.c index a5209b5058..2ee1bd84a2 100644 --- a/libswscale/graph.c +++ b/libswscale/graph.c @@ -21,6 +21,7 @@ #include "libavutil/avassert.h" #include "libavutil/cpu.h" #include "libavutil/error.h" +#include "libavutil/hwcontext.h" #include "libavutil/imgutils.h" #include "libavutil/macros.h" #include "libavutil/mem.h" @@ -38,6 +39,9 @@ #include "graph.h" #include "ops.h" #include "ops_dispatch.h" +#if CONFIG_VULKAN +#include "vulkan/ops.h" +#endif int ff_sws_pass_aligned_width(const SwsPass *pass, int width) { @@ -86,6 +90,31 @@ static int frame_alloc_planes(AVFrame *dst) return 0; } +#if CONFIG_VULKAN +static int pass_alloc_output_hw(SwsPass *pass, AVFrame *avframe, + AVBufferRef *dev_ref) +{ + SwsPassBuffer *buffer = pass->output; + AVBufferRef *frames_ref = av_hwframe_ctx_alloc(dev_ref); + if (!frames_ref) + return AVERROR(ENOMEM); + + AVHWFramesContext *hwfc = (AVHWFramesContext *)frames_ref->data; + hwfc->format = AV_PIX_FMT_VULKAN; + hwfc->sw_format = pass->format; + hwfc->width = buffer->width; + hwfc->height = buffer->height; + + int ret = av_hwframe_ctx_init(frames_ref); + if (ret >= 0) { + avframe->format = AV_PIX_FMT_VULKAN; + ret = av_hwframe_get_buffer(frames_ref, avframe, 0); + } + av_buffer_unref(&frames_ref); + return ret; +} +#endif + static int pass_alloc_output(SwsPass *pass) { if (!pass || pass->output->avframe) @@ -95,16 +124,35 @@ static int pass_alloc_output(SwsPass *pass) AVFrame *avframe = av_frame_alloc(); if (!avframe) return AVERROR(ENOMEM); - avframe->format = pass->format; avframe->width = buffer->width; avframe->height = buffer->height; - int ret = frame_alloc_planes(avframe); + int ret; + +#if CONFIG_VULKAN + const SwsGraph *graph = pass->graph; + if (graph->src.hw_format == AV_PIX_FMT_VULKAN && + graph->dst.hw_format == AV_PIX_FMT_VULKAN) { + AVBufferRef *dev_ref = ff_sws_vk_device_ref(graph->ctx); + if (dev_ref) { + ret = pass_alloc_output_hw(pass, avframe, dev_ref); + if (ret >= 0) + goto done; + av_frame_unref(avframe); + } + } +#endif + + avframe->format = pass->format; + ret = frame_alloc_planes(avframe); if (ret < 0) { av_frame_free(&avframe); return ret; } +#if CONFIG_VULKAN +done: +#endif buffer->avframe = avframe; ff_sws_frame_from_avframe(&buffer->frame, avframe); return 0; diff --git a/libswscale/vulkan/ops.c b/libswscale/vulkan/ops.c index a2ef13918e..abd9f2d5c9 100644 --- a/libswscale/vulkan/ops.c +++ b/libswscale/vulkan/ops.c @@ -82,6 +82,13 @@ int ff_sws_vk_init(SwsContext *sws, AVBufferRef *dev_ref) return 0; } +AVBufferRef *ff_sws_vk_device_ref(SwsContext *sws) +{ + SwsInternal *c = sws_internal(sws); + FFVulkanOpsCtx *s = c->hw_priv; + return s ? s->vkctx.device_ref : NULL; +} + #define MAX_DITHER_BUFS 4 typedef struct VulkanPriv { diff --git a/libswscale/vulkan/ops.h b/libswscale/vulkan/ops.h index 0421dba446..6c9ae6c7fd 100644 --- a/libswscale/vulkan/ops.h +++ b/libswscale/vulkan/ops.h @@ -38,4 +38,10 @@ typedef struct FFVulkanOpsCtx { int ff_sws_vk_init(SwsContext *sws, AVBufferRef *dev_ref); +/** + * Returns the Vulkan device reference associated with `sws`, or NULL if + * Vulkan has not been initialized for this context. + */ +AVBufferRef *ff_sws_vk_device_ref(SwsContext *sws); + #endif /* SWSCALE_VULKAN_OPS_H */ _______________________________________________ ffmpeg-cvslog mailing list -- [email protected] To unsubscribe send an email to [email protected]
