Quoting wm4 (2016-02-02 13:23:01)
> 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().)

I dunno, the important difference is the opaque data, the free()
callback is just a consequence of that.
av_buffer_pool_init_with_opaque() is possible, but it's still not clear
what it's for just from the name.

-- 
Anton Khirnov
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to