Same use case as av_fast_malloc(). If the buffer passed to it is writable and big enough it will be reused, otherwise a new one will be allocated instead.
Signed-off-by: James Almer <jamr...@gmail.com> --- TODO: Changelog and APIChanges entries, version bump. libavutil/buffer.c | 33 +++++++++++++++++++++++++++++++++ libavutil/buffer.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/libavutil/buffer.c b/libavutil/buffer.c index 8d1aa5fa84..26e015d7ee 100644 --- a/libavutil/buffer.c +++ b/libavutil/buffer.c @@ -215,6 +215,39 @@ int av_buffer_realloc(AVBufferRef **pbuf, int size) return 0; } +static inline int buffer_fast_alloc(AVBufferRef **pbuf, int size, + AVBufferRef* (*buffer_alloc)(int size)) +{ + AVBufferRef *buf = *pbuf; + + if (buf && av_buffer_is_writable(buf) + && buf->data == buf->buffer->data + && size <= buf->buffer->size) { + buf->size = FFMAX(0, size); + return 0; + } + + av_buffer_unref(pbuf); + + buf = buffer_alloc(size); + if (!buf) + return AVERROR(ENOMEM); + + *pbuf = buf; + + return 0; +} + +int av_buffer_fast_alloc(AVBufferRef **pbuf, int size) +{ + return buffer_fast_alloc(pbuf, size, av_buffer_alloc); +} + +int av_buffer_fast_allocz(AVBufferRef **pbuf, int size) +{ + return buffer_fast_alloc(pbuf, size, av_buffer_allocz); +} + AVBufferPool *av_buffer_pool_init2(int size, void *opaque, AVBufferRef* (*alloc)(void *opaque, int size), void (*pool_free)(void *opaque)) diff --git a/libavutil/buffer.h b/libavutil/buffer.h index 73b6bd0b14..1166017d22 100644 --- a/libavutil/buffer.h +++ b/libavutil/buffer.h @@ -197,6 +197,48 @@ int av_buffer_make_writable(AVBufferRef **buf); */ int av_buffer_realloc(AVBufferRef **buf, int size); +/** + * Allocate a buffer, reusing the given one if writable and large enough. + * + * @code{.c} + * AVBufferRef *buf = ...; + * int ret = av_buffer_fast_alloc(&buf, size); + * if (ret < 0) { + * // Allocation failed; buf already freed + * return ret; + * } + * @endcode + * + * @param buf A buffer reference. *buf may be NULL. On success, a new buffer + * reference will be written in its place. On failure, it will be + * unreferenced and set to NULL. + * @param size Required buffer size. + * + * @return 0 on success, a negative AVERROR on failure. + * + * @see av_buffer_realloc() + * @see av_buffer_fast_allocz() + */ +int av_buffer_fast_alloc(AVBufferRef **buf, int size); + +/** + * Allocate and clear a buffer, reusing the given one if writable and large + * enough. + * + * Like av_buffer_fast_alloc(), but all newly allocated space is initially + * cleared. Reused buffer is not cleared. + * + * @param buf A buffer reference. *buf may be NULL. On success, a new buffer + * reference will be written in its place. On failure, it will be + * unreferenced and set to NULL. + * @param size Required buffer size. + * + * @return 0 on success, a negative AVERROR on failure. + * + * @see av_buffer_fast_alloc() + */ +int av_buffer_fast_allocz(AVBufferRef **buf, int size); + /** * @} */ -- 2.16.2 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel