avutil/hwcontext: add av_hwframe_get_transfer_buffer()

It allocates the buffers of a software frame used for a transfer to or
from a hardware frames context out of a pool kept by that context.

Assisted-by: Claude
This commit is contained in:
Michael Niedermayer authored and michaelni committed 2026-10-21 19:32:23 +00:00
1 parent 501d815ec4
commit b8249f73a7
5 files changed
+62 -1

No files matched your search

+3
View File
@@ -2,6 +2,9 @@ The last version increases of all libraries were on 2026-06-23.
API changes, most recent first:
2026-10-xx - xxxxxxxxxx - lavu 61.16.100 - hwcontext.h
Add av_hwframe_get_transfer_buffer().
2026-10-xx - xxxxxxxxxx - lavu 61.15.100 - encryption_info.h
Add av_encryption_init_info_append_side_data().
+34
View File
@@ -21,6 +21,7 @@
#include "avassert.h"
#include "buffer.h"
#include "common.h"
#include "frame_internal.h"
#include "hwcontext.h"
#include "hwcontext_internal.h"
#include "imgutils.h"
@@ -246,6 +247,9 @@ static void hwframe_ctx_free(void *opaque, uint8_t *data)
if (ctxi->pool_internal)
av_buffer_pool_uninit(&ctxi->pool_internal);
av_buffer_pool_uninit(&ctxi->transfer_pool);
ff_mutex_destroy(&ctxi->transfer_pool_lock);
if (ctxi->hw_type->frames_uninit)
ctxi->hw_type->frames_uninit(ctx);
@@ -273,6 +277,11 @@ AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
return NULL;
ctx = &ctxi->p;
if (ff_mutex_init(&ctxi->transfer_pool_lock, NULL)) {
av_free(ctxi);
return NULL;
}
if (hw_type->frames_hwctx_size) {
ctx->hwctx = av_mallocz(hw_type->frames_hwctx_size);
if (!ctx->hwctx)
@@ -301,6 +310,7 @@ AVBufferRef *av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
fail:
av_buffer_unref(&device_ref);
ff_mutex_destroy(&ctxi->transfer_pool_lock);
av_freep(&ctx->hwctx);
av_freep(&ctx);
return NULL;
@@ -395,6 +405,30 @@ int av_hwframe_transfer_get_formats(AVBufferRef *hwframe_ref,
return ctxi->hw_type->transfer_get_formats(&ctxi->p, dir, formats);
}
static AVBufferRef *transfer_buffer_alloc(void *opaque, size_t size)
{
FFHWFramesContext *ctxi = opaque;
AVBufferRef *buf = NULL;
ff_mutex_lock(&ctxi->transfer_pool_lock);
if (ctxi->transfer_pool_size != size) {
av_buffer_pool_uninit(&ctxi->transfer_pool);
ctxi->transfer_pool = av_buffer_pool_init(size, NULL);
ctxi->transfer_pool_size = ctxi->transfer_pool ? size : 0;
}
if (ctxi->transfer_pool)
buf = av_buffer_pool_get(ctxi->transfer_pool);
ff_mutex_unlock(&ctxi->transfer_pool_lock);
return buf;
}
int av_hwframe_get_transfer_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame)
{
return ff_frame_get_video_buffer(frame, 0, transfer_buffer_alloc,
hwframe_ctx->data);
}
static int transfer_data_alloc(AVFrame *dst, const AVFrame *src, int flags)
{
AVHWFramesContext *ctx;
+15
View File
@@ -372,6 +372,21 @@ int av_hwframe_ctx_init(AVBufferRef *ref);
*/
int av_hwframe_get_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame, int flags);
/**
* Allocate the buffers of a software frame that data is transferred to or
* from frames of the given AVHWFramesContext.
*
* Frames allocated otherwise can be transferred as well, as described for
* av_hwframe_transfer_data(). The buffers allocated here are pooled, and may be
* in memory that the device transfers faster.
*
* @param hwframe_ctx a reference to an AVHWFramesContext
* @param frame a video frame with format, width and height set and no
* data buffers
* @return 0 on success, a negative AVERROR code on failure
*/
int av_hwframe_get_transfer_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame);
/**
* Copy data to or from a hw surface. At least one of dst/src must have an
* AVHWFramesContext attached.
+9
View File
@@ -23,6 +23,7 @@
#include "buffer.h"
#include "hwcontext.h"
#include "thread.h"
#include "frame.h"
#include "pixfmt.h"
@@ -100,6 +101,14 @@ typedef struct FFHWFramesContext {
AVBufferPool *pool_internal;
/**
* Buffers of transfer_pool_size bytes for av_hwframe_get_transfer_buffer(),
* both guarded by transfer_pool_lock.
*/
AVBufferPool *transfer_pool;
size_t transfer_pool_size;
AVMutex transfer_pool_lock;
/**
* For a derived context, a reference to the original frames
* context it was derived from.
+1 -1
View File
@@ -79,7 +79,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 61
#define LIBAVUTIL_VERSION_MINOR 15
#define LIBAVUTIL_VERSION_MINOR 16
#define LIBAVUTIL_VERSION_MICRO 100
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \