buffer: add support for pools using caller data in allocation

This should allow using more complex allocators than simple malloc
wrappers.
This commit is contained in:
Anton Khirnov 2016-01-09 09:25:32 +01:00
parent c084d6d2cf
commit 721a4efc05
5 changed files with 50 additions and 2 deletions

View File

@ -13,6 +13,9 @@ libavutil: 2015-08-28
API changes, most recent first:
2016-xx-xx - lavu 55.6.0
xxxxxxx buffer.h - Add av_buffer_pool_init2().
2016-xx-xx - xxxxxxx - lavf 57.3.0 - avformat.h
Add AVFormatContext.opaque, io_open and io_close, allowing custom IO
for muxers and demuxers that open additional files.

View File

@ -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;

View File

@ -241,6 +241,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

View File

@ -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 */

View File

@ -54,7 +54,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 55
#define LIBAVUTIL_VERSION_MINOR 5
#define LIBAVUTIL_VERSION_MINOR 6
#define LIBAVUTIL_VERSION_MICRO 0
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \