@ -26,16 +26,11 @@
# include "mem.h"
# include "thread.h"
AVBufferRef * av_ buffer_create( uint8_t * data , size_t size ,
void ( * free ) ( void * opaque , uint8_t * data ) ,
void * opaque , int flags )
static AVBufferRef * buffer_create ( AVBuffer * buf , uint8_t * data , size_t size ,
void ( * free ) ( void * opaque , uint8_t * data ) ,
void * opaque , int flags )
{
AVBufferRef * ref = NULL ;
AVBuffer * buf = NULL ;
buf = av_mallocz ( sizeof ( * buf ) ) ;
if ( ! buf )
return NULL ;
buf - > data = data ;
buf - > size = size ;
@ -47,10 +42,8 @@ AVBufferRef *av_buffer_create(uint8_t *data, size_t size,
buf - > flags = flags ;
ref = av_mallocz ( sizeof ( * ref ) ) ;
if ( ! ref ) {
av_freep ( & buf ) ;
if ( ! ref )
return NULL ;
}
ref - > buffer = buf ;
ref - > data = data ;
@ -59,6 +52,23 @@ AVBufferRef *av_buffer_create(uint8_t *data, size_t size,
return ref ;
}
AVBufferRef * av_buffer_create ( uint8_t * data , size_t size ,
void ( * free ) ( void * opaque , uint8_t * data ) ,
void * opaque , int flags )
{
AVBufferRef * ret ;
AVBuffer * buf = av_mallocz ( sizeof ( * buf ) ) ;
if ( ! buf )
return NULL ;
ret = buffer_create ( buf , data , size , free , opaque , flags ) ;
if ( ! ret ) {
av_free ( buf ) ;
return NULL ;
}
return ret ;
}
void av_buffer_default_free ( void * opaque , uint8_t * data )
{
av_free ( data ) ;
@ -117,8 +127,12 @@ static void buffer_replace(AVBufferRef **dst, AVBufferRef **src)
av_freep ( dst ) ;
if ( atomic_fetch_sub_explicit ( & b - > refcount , 1 , memory_order_acq_rel ) = = 1 ) {
/* b->free below might already free the structure containing *b,
* so we have to read the flag now to avoid use - after - free . */
int free_avbuffer = ! ( b - > flags_internal & BUFFER_FLAG_NO_FREE ) ;
b - > free ( b - > opaque , b - > data ) ;
av_freep ( & b ) ;
if ( free_avbuffer )
av_free ( b ) ;
}
}
@ -378,11 +392,13 @@ AVBufferRef *av_buffer_pool_get(AVBufferPool *pool)
ff_mutex_lock ( & pool - > mutex ) ;
buf = pool - > pool ;
if ( buf ) {
ret = av_buffer_create ( buf - > data , pool - > size , pool_release_buffer ,
buf , 0 ) ;
memset ( & buf - > buffer , 0 , sizeof ( buf - > buffer ) ) ;
ret = buffer_create ( & buf - > buffer , buf - > data , pool - > size ,
pool_release_buffer , buf , 0 ) ;
if ( ret ) {
pool - > pool = buf - > next ;
buf - > next = NULL ;
buf - > buffer . flags_internal | = BUFFER_FLAG_NO_FREE ;
}
} else {
ret = pool_alloc_buffer ( pool ) ;