diff options
author | jstebbins <[email protected]> | 2013-10-23 20:33:32 +0000 |
---|---|---|
committer | jstebbins <[email protected]> | 2013-10-23 20:33:32 +0000 |
commit | 32a56184a88817091950a94335dbf1036677eaf1 (patch) | |
tree | 1a6a466ab1851d5f673707ca9cdf43a0fe5b8010 | |
parent | 1ce5a64075d60ba43c63366710816539d37cd1b8 (diff) |
libhb: Plug some leaks and clean up the buffer pool code a little.
Filters were leaking buffers when a job is cancelled.
decavcodec could leak when job cancelled.
decavcodec leaked audio extradata in BSInfo
encavcodec and encavcodecaudio leaked AVCodecContext
sync leaked subtitle_sanitizer_t data
git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@5853 b64f7644-9d1e-0410-96f1-a4d463321fa5
-rw-r--r-- | libhb/decavcodec.c | 62 | ||||
-rw-r--r-- | libhb/encavcodec.c | 1 | ||||
-rw-r--r-- | libhb/encavcodecaudio.c | 1 | ||||
-rw-r--r-- | libhb/fifo.c | 26 | ||||
-rw-r--r-- | libhb/scan.c | 2 | ||||
-rw-r--r-- | libhb/sync.c | 14 | ||||
-rw-r--r-- | libhb/work.c | 6 |
7 files changed, 62 insertions, 50 deletions
diff --git a/libhb/decavcodec.c b/libhb/decavcodec.c index 15a14dcec..0ade0da27 100644 --- a/libhb/decavcodec.c +++ b/libhb/decavcodec.c @@ -347,6 +347,8 @@ static void closePrivData( hb_work_private_t ** ppv ) if ( pv ) { flushDelayQueue( pv ); + hb_buffer_t *buf = link_buf_list( pv ); + hb_buffer_close( &buf ); if ( pv->job && pv->context && pv->context->codec ) { @@ -659,6 +661,7 @@ static int decavcodecaBSInfo( hb_work_object_t *w, const hb_buffer_t *buf, if ( parser != NULL ) av_parser_close( parser ); hb_avcodec_close( context ); + av_freep( &context->extradata ); av_free( context ); return ret; } @@ -1327,28 +1330,28 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job ) pv->threads = HB_FFMPEG_THREADS_AUTO; } - if ( pv->title->opaque_priv ) - { - AVFormatContext *ic = (AVFormatContext*)pv->title->opaque_priv; - - AVCodec *codec = NULL; + AVCodec *codec = NULL; #ifdef USE_QSV - if (pv->qsv.decode) - { - codec = avcodec_find_decoder_by_name(pv->qsv.codec_name); - } - else + if (pv->qsv.decode) + { + codec = avcodec_find_decoder_by_name(pv->qsv.codec_name); + } + else #endif - { - codec = avcodec_find_decoder(w->codec_param); - } + { + codec = avcodec_find_decoder(w->codec_param); + } + if ( codec == NULL ) + { + hb_log( "decavcodecvInit: failed to find codec for id (%d)", w->codec_param ); + return 1; + } + + if ( pv->title->opaque_priv ) + { + AVFormatContext *ic = (AVFormatContext*)pv->title->opaque_priv; - if ( codec == NULL ) - { - hb_log( "decavcodecvInit: failed to find codec for id (%d)", w->codec_param ); - return 1; - } pv->context = avcodec_alloc_context3(codec); avcodec_copy_context( pv->context, ic->streams[pv->title->video_id]->codec); pv->context->workaround_bugs = FF_BUG_AUTODETECT; @@ -1401,20 +1404,6 @@ static int decavcodecvInit( hb_work_object_t * w, hb_job_t * job ) } else { - AVCodec *codec = NULL; - -#ifdef USE_QSV - if (pv->qsv.decode) - { - codec = avcodec_find_decoder_by_name(pv->qsv.codec_name); - } - else -#endif - { - codec = avcodec_find_decoder(w->codec_param); - } - - pv->parser = av_parser_init( w->codec_param ); pv->context = avcodec_alloc_context3( codec ); pv->context->workaround_bugs = FF_BUG_AUTODETECT; @@ -1560,15 +1549,6 @@ static int decavcodecvWork( hb_work_object_t * w, hb_buffer_t ** buf_in, *buf_out = hb_buffer_init( 0 );; return HB_WORK_DONE; } - // Note that there is currently a small memory leak in libav at this - // point. pv->context->priv_data gets allocated by - // avcodec_alloc_context3(), then avcodec_get_context_defaults3() - // memsets the context and looses the pointer. - // - // avcodec_get_context_defaults3() looks as if they intended for - // it to preserve any existing priv_data because they test the pointer - // before allocating new memory, but the memset has already cleared it. - avcodec_get_context_defaults3( pv->context, codec ); if ( setup_extradata( w, in ) ) { // we didn't find the headers needed to set up extradata. diff --git a/libhb/encavcodec.c b/libhb/encavcodec.c index 04125301c..a695fa443 100644 --- a/libhb/encavcodec.c +++ b/libhb/encavcodec.c @@ -291,6 +291,7 @@ void encavcodecClose( hb_work_object_t * w ) hb_deep_log( 2, "encavcodec: closing libavcodec" ); avcodec_flush_buffers( pv->context ); hb_avcodec_close( pv->context ); + av_free( pv->context ); } if( pv->file ) { diff --git a/libhb/encavcodecaudio.c b/libhb/encavcodecaudio.c index 44c3be75d..e0c81e507 100644 --- a/libhb/encavcodecaudio.c +++ b/libhb/encavcodecaudio.c @@ -296,6 +296,7 @@ static void encavcodecaClose(hb_work_object_t * w) if (pv->context->codec != NULL) avcodec_flush_buffers(pv->context); hb_avcodec_close(pv->context); + av_free( pv->context ); } if (pv->output_buf != NULL) diff --git a/libhb/fifo.c b/libhb/fifo.c index bd1a45e40..fbfcefd02 100644 --- a/libhb/fifo.c +++ b/libhb/fifo.c @@ -48,6 +48,8 @@ static hb_fifo_t fifo_list = * be at most 32 possible pools when the size is a 32 bit int. To avoid a lot * of slow & error-prone run-time checking we allow for all 32. */ #define MAX_BUFFER_POOLS 32 +#define BUFFER_POOL_FIRST 10 +#define BUFFER_POOL_LAST 25 /* the buffer pool only exists to avoid the two malloc and two free calls that * it would otherwise take to allocate & free a buffer. but we don't want to * tie up a lot of memory in the pool because this allocator isn't as general @@ -72,15 +74,21 @@ void hb_buffer_pool_init( void ) /* we allocate pools for sizes 2^10 through 2^25. requests larger than * 2^25 will get passed through to malloc. */ int i; - for ( i = 10; i < 26; ++i ) + + // Create larger queue for 2^10 bucket since all allocations smaller than + // 2^10 come from here. + buffers.pool[BUFFER_POOL_FIRST] = hb_fifo_init(BUFFER_POOL_MAX_ELEMENTS*10, 1); + buffers.pool[BUFFER_POOL_FIRST]->buffer_size = 1 << 10; + + /* requests smaller than 2^10 are satisfied from the 2^10 pool. */ + for ( i = 1; i < BUFFER_POOL_FIRST; ++i ) { - buffers.pool[i] = hb_fifo_init(BUFFER_POOL_MAX_ELEMENTS, 1); - buffers.pool[i]->buffer_size = 1 << i; + buffers.pool[i] = buffers.pool[BUFFER_POOL_FIRST]; } - /* requests smaller than 2^10 are satisfied from the 2^10 pool. */ - for ( i = 1; i < 10; ++i ) + for ( i = BUFFER_POOL_FIRST + 1; i <= BUFFER_POOL_LAST; ++i ) { - buffers.pool[i] = buffers.pool[10]; + buffers.pool[i] = hb_fifo_init(BUFFER_POOL_MAX_ELEMENTS, 1); + buffers.pool[i]->buffer_size = 1 << i; } } @@ -152,7 +160,7 @@ static void buffer_pool_validate( hb_fifo_t * f ) static void buffer_pools_validate( void ) { int ii; - for ( ii = 10; ii < 26; ++ii ) + for ( ii = BUFFER_POOL_FIRST; ii <= BUFFER_POOL_LAST; ++ii ) { buffer_pool_validate( buffers.pool[ii] ); } @@ -234,7 +242,7 @@ void hb_buffer_pool_free( void ) hb_lock(buffers.lock); - for( i = 10; i < 26; ++i) + for( i = BUFFER_POOL_FIRST; i <= BUFFER_POOL_LAST; ++i) { count = 0; while( ( b = hb_fifo_get(buffers.pool[i]) ) ) @@ -270,7 +278,7 @@ void hb_buffer_pool_free( void ) static hb_fifo_t *size_to_pool( int size ) { int i; - for ( i = 0; i < 30; ++i ) + for ( i = BUFFER_POOL_FIRST; i <= BUFFER_POOL_LAST; ++i ) { if ( size <= (1 << i) ) { diff --git a/libhb/scan.c b/libhb/scan.c index ec35eb916..535baea39 100644 --- a/libhb/scan.c +++ b/libhb/scan.c @@ -538,6 +538,7 @@ static int DecodePreviews( hb_scan_t * data, hb_title_t * title ) { free( info_list ); crop_record_free( crops ); + hb_buffer_pool_free(); return 0; } if (data->bd) @@ -940,6 +941,7 @@ skip_preview: if (data->dvd) hb_dvd_stop( data->dvd ); + hb_buffer_pool_free(); return npreviews; } diff --git a/libhb/sync.c b/libhb/sync.c index c14d96166..f002434ce 100644 --- a/libhb/sync.c +++ b/libhb/sync.c @@ -227,6 +227,12 @@ static void InitSubtitle( hb_job_t * job, hb_sync_video_t * sync, int i ) } } +static void CloseSubtitle(hb_sync_video_t * sync, int ii) +{ + hb_buffer_close(&sync->subtitle_sanitizer[ii].list_current); + hb_buffer_close(&sync->subtitle_sanitizer[ii].last); +} + /*********************************************************************** * Close Video *********************************************************************** @@ -237,6 +243,7 @@ void syncVideoClose( hb_work_object_t * w ) hb_work_private_t * pv = w->private_data; hb_job_t * job = pv->job; hb_sync_video_t * sync = &pv->type.video; + int ii; // Wake up audio sync if it's still waiting on condition. pv->common->pts_offset = 0; @@ -266,6 +273,13 @@ void syncVideoClose( hb_work_object_t * w ) sync->drops, sync->dups ); } + int count = hb_list_count(job->list_subtitle); + for( ii = 0; ii < count; ii++ ) + { + CloseSubtitle(sync, ii); + } + free(sync->subtitle_sanitizer); + hb_lock( pv->common->mutex ); if ( --pv->common->ref == 0 ) { diff --git a/libhb/work.c b/libhb/work.c index 6ed374a3c..bdf2191ea 100644 --- a/libhb/work.c +++ b/libhb/work.c @@ -1773,11 +1773,17 @@ static void filter_loop( void * _f ) if ( hb_fifo_full_wait( f->fifo_out ) ) { hb_fifo_push( f->fifo_out, buf_out ); + buf_out = NULL; break; } } } } + if ( buf_out ) + { + hb_buffer_close( &buf_out ); + } + // Consume data in incoming fifo till job complete so that // residual data does not stall the pipeline while( !*f->done ) |