On Tue, 2 Feb 2016 12:41:21 +0100
Anton Khirnov <[email protected]> wrote:
> This should allow using more complex allocators than simple malloc
> wrappers.
> ---
> libavutil/buffer.c | 27 ++++++++++++++++++++++++++-
> libavutil/buffer.h | 17 +++++++++++++++++
> libavutil/buffer_internal.h | 3 +++
> 3 files changed, 46 insertions(+), 1 deletion(-)
>
> diff --git a/libavutil/buffer.c b/libavutil/buffer.c
> index 1bc4a93..6681002 100644
> --- a/libavutil/buffer.c
> +++ b/libavutil/buffer.c
> @@ -194,6 +194,26 @@ int av_buffer_realloc(AVBufferRef **pbuf, int size)
> return 0;
> }
>
> +AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
> + AVBufferRef* (*alloc)(void *opaque, int
> size),
> + void (*pool_free)(void *opaque))
> +{
> + AVBufferPool *pool = av_mallocz(sizeof(*pool));
> + if (!pool)
> + return NULL;
> +
> + ff_mutex_init(&pool->mutex, NULL);
> +
> + pool->size = size;
> + pool->opaque = opaque;
> + pool->alloc2 = alloc;
> + pool->pool_free = pool_free;
> +
> + avpriv_atomic_int_set(&pool->refcount, 1);
> +
> + return pool;
> +}
> +
> AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size))
> {
> AVBufferPool *pool = av_mallocz(sizeof(*pool));
> @@ -224,6 +244,10 @@ static void buffer_pool_free(AVBufferPool *pool)
> av_freep(&buf);
> }
> ff_mutex_destroy(&pool->mutex);
> +
> + if (pool->pool_free)
> + pool->pool_free(pool->opaque);
> +
> av_freep(&pool);
> }
>
> @@ -261,7 +285,8 @@ static AVBufferRef *pool_alloc_buffer(AVBufferPool *pool)
> BufferPoolEntry *buf;
> AVBufferRef *ret;
>
> - ret = pool->alloc(pool->size);
> + ret = pool->alloc2 ? pool->alloc2(pool->opaque, pool->size) :
> + pool->alloc(pool->size);
> if (!ret)
> return NULL;
>
> diff --git a/libavutil/buffer.h b/libavutil/buffer.h
> index 56b4d02..7fc18e0 100644
> --- a/libavutil/buffer.h
> +++ b/libavutil/buffer.h
> @@ -242,6 +242,23 @@ typedef struct AVBufferPool AVBufferPool;
> AVBufferPool *av_buffer_pool_init(int size, AVBufferRef* (*alloc)(int size));
>
> /**
> + * Allocate and initialize a buffer pool with a more complex allocator.
> + *
> + * @param size size of each buffer in this pool
> + * @param opaque arbitrary user data used by the allocator
> + * @param alloc a function that will be used to allocate new buffers when the
> + * pool is empty.
> + * @param pool_free a function that will be called immediately before the
> pool
> + * is freed. I.e. after av_buffer_pool_can_uninit() is
> called
> + * by the pool and all the frames are returned to the pool
> and
> + * freed. It is intended to uninitialize the user opaque
> data.
> + * @return newly created buffer pool on success, NULL on error.
> + */
> +AVBufferPool *av_buffer_pool_init2(int size, void *opaque,
> + AVBufferRef* (*alloc)(void *opaque, int
> size),
> + void (*pool_free)(void *opaque));
> +
> +/**
> * Mark the pool as being available for freeing. It will actually be freed
> only
> * once all the allocated buffers associated with the pool are released.
> Thus it
> * is safe to call this function while some of the allocated buffers are
> still
> diff --git a/libavutil/buffer_internal.h b/libavutil/buffer_internal.h
> index 1032a54..64344d8 100644
> --- a/libavutil/buffer_internal.h
> +++ b/libavutil/buffer_internal.h
> @@ -88,7 +88,10 @@ struct AVBufferPool {
> volatile int refcount;
>
> int size;
> + void *opaque;
> AVBufferRef* (*alloc)(int size);
> + AVBufferRef* (*alloc2)(void *opaque, int size);
> + void (*pool_free)(void *opaque);
> };
>
> #endif /* AVUTIL_BUFFER_INTERNAL_H */
Seems ok. I'd like to suggest av_buffer_pool_init_with_free(). (Which
hints that the function provides a somewhat less commonly needed
feature, instead of being a replacement for av_buffer_pool_init().)
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel