From 501d815ec45d38aed403e4db576d2439a6c61127 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 4 Oct 2026 02:50:51 +0200 Subject: [PATCH] avutil/frame: let libavutil allocate a video frame's buffer with its own allocator ff_frame_get_video_buffer() lays a video frame out like av_frame_get_buffer() does, but takes the buffer from a callback, so that the memory can come from a pool or from a device specific allocator. Assisted-by: Claude --- libavutil/frame.c | 9 ++++++--- libavutil/frame_internal.h | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 libavutil/frame_internal.h diff --git a/libavutil/frame.c b/libavutil/frame.c index ca8e8486a3..185adbef68 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -21,6 +21,7 @@ #include "buffer.h" #include "dict.h" #include "frame.h" +#include "frame_internal.h" #include "imgutils.h" #include "mem.h" #include "refstruct.h" @@ -72,7 +73,9 @@ void av_frame_free(AVFrame **frame) #define ALIGN (HAVE_SIMD_ALIGN_64 ? 64 : 32) -static int get_video_buffer(AVFrame *frame, int align) +int ff_frame_get_video_buffer(AVFrame *frame, int align, + AVBufferRef *(*alloc)(void *opaque, size_t size), + void *opaque) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); int ret, padded_height; @@ -119,7 +122,7 @@ static int get_video_buffer(AVFrame *frame, int align) total_size += sizes[i]; } - frame->buf[0] = av_buffer_alloc(total_size); + frame->buf[0] = alloc ? alloc(opaque, total_size) : av_buffer_alloc(total_size); if (!frame->buf[0]) { ret = AVERROR(ENOMEM); goto fail; @@ -209,7 +212,7 @@ int av_frame_get_buffer(AVFrame *frame, int align) return AVERROR(EINVAL); if (frame->width > 0 && frame->height > 0) - return get_video_buffer(frame, align); + return ff_frame_get_video_buffer(frame, align, NULL, NULL); else if (frame->nb_samples > 0 && (av_channel_layout_check(&frame->ch_layout))) return get_audio_buffer(frame, align); diff --git a/libavutil/frame_internal.h b/libavutil/frame_internal.h new file mode 100644 index 0000000000..a9f1c61805 --- /dev/null +++ b/libavutil/frame_internal.h @@ -0,0 +1,37 @@ +/* + * 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 + */ + +#ifndef AVUTIL_FRAME_INTERNAL_H +#define AVUTIL_FRAME_INTERNAL_H + +#include + +#include "buffer.h" +#include "frame.h" + +/** + * Allocate the buffer of a video frame like av_frame_get_buffer(). + * + * @param alloc allocates the buffer, av_buffer_alloc() is used if NULL + * @param opaque passed to alloc + */ +int ff_frame_get_video_buffer(AVFrame *frame, int align, + AVBufferRef *(*alloc)(void *opaque, size_t size), + void *opaque); + +#endif /* AVUTIL_FRAME_INTERNAL_H */