Commit e9d2baffa4 for ffmpeg
commit e9d2baffa48b4d7e91d99d5a20c0b67dd4a25b3f
Author: Michael Niedermayer <michael@niedermayer.cc>
Date: Sun Oct 4 03:34:47 2026 +0200
avutil/hwcontext: let the hardware context type allocate transfer buffers
A device may transfer faster to or from memory it allocated itself
than ordinary memory.
Assisted-by: Claude
diff --git a/libavutil/hwcontext.c b/libavutil/hwcontext.c
index d5cf6dc012..297cc5dd85 100644
--- a/libavutil/hwcontext.c
+++ b/libavutil/hwcontext.c
@@ -405,6 +405,12 @@ int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ref,
return ctxi->hw_type->transfer_get_formats(&ctxi->p, dir, formats);
}
+static void transfer_pool_free(void *opaque)
+{
+ AVBufferRef *device_ref = opaque;
+ av_buffer_unref(&device_ref);
+}
+
static AVBufferRef *transfer_buffer_alloc(void *opaque, size_t size)
{
FFHWFramesContext *ctxi = opaque;
@@ -412,15 +418,25 @@ static AVBufferRef *transfer_buffer_alloc(void *opaque, size_t size)
ff_mutex_lock(&ctxi->transfer_pool_lock);
if (ctxi->transfer_pool_size != size) {
+ /* buffers of the hardware context type need the device to be freed */
+ AVBufferRef *device_ref = ctxi->hw_type->transfer_buffer_alloc ?
+ av_buffer_ref(ctxi->p.device_ref) : NULL;
+
av_buffer_pool_uninit(&ctxi->transfer_pool);
- ctxi->transfer_pool = av_buffer_pool_init(size, NULL);
+ ctxi->transfer_pool = device_ref ?
+ av_buffer_pool_init2(size, device_ref,
+ ctxi->hw_type->transfer_buffer_alloc,
+ transfer_pool_free) :
+ av_buffer_pool_init(size, NULL);
ctxi->transfer_pool_size = ctxi->transfer_pool ? size : 0;
+ if (!ctxi->transfer_pool)
+ av_buffer_unref(&device_ref);
}
if (ctxi->transfer_pool)
buf = av_buffer_pool_get(ctxi->transfer_pool);
ff_mutex_unlock(&ctxi->transfer_pool_lock);
- return buf;
+ return buf ? buf : av_buffer_alloc(size);
}
int av_hwframe_get_transfer_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame)
diff --git a/libavutil/hwcontext_internal.h b/libavutil/hwcontext_internal.h
index 33e34b9d65..e100233e35 100644
--- a/libavutil/hwcontext_internal.h
+++ b/libavutil/hwcontext_internal.h
@@ -72,6 +72,14 @@ typedef struct HWContextType {
void (*frames_uninit)(AVHWFramesContext *ctx);
int (*frames_get_buffer)(AVHWFramesContext *ctx, AVFrame *frame);
+
+ /**
+ * Allocate a buffer of size bytes for av_hwframe_get_transfer_buffer(),
+ * av_buffer_alloc() is used if this is not set or returns NULL.
+ *
+ * @param device_ref the AVBufferRef of the AVHWDeviceContext
+ */
+ AVBufferRef *(*transfer_buffer_alloc)(void *device_ref, size_t size);
int (*transfer_get_formats)(AVHWFramesContext *ctx,
enum AVHWFrameTransferDirection dir,
enum AVPixelFormat **formats);