summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjstebbins <[email protected]>2013-10-23 20:33:32 +0000
committerjstebbins <[email protected]>2013-10-23 20:33:32 +0000
commit32a56184a88817091950a94335dbf1036677eaf1 (patch)
tree1a6a466ab1851d5f673707ca9cdf43a0fe5b8010
parent1ce5a64075d60ba43c63366710816539d37cd1b8 (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.c62
-rw-r--r--libhb/encavcodec.c1
-rw-r--r--libhb/encavcodecaudio.c1
-rw-r--r--libhb/fifo.c26
-rw-r--r--libhb/scan.c2
-rw-r--r--libhb/sync.c14
-rw-r--r--libhb/work.c6
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 )