From: lilo_booter Date: Fri, 9 Apr 2004 13:31:27 +0000 (+0000) Subject: Memory leaks and resample rework X-Git-Url: http://research.m1stereo.tv/gitweb?a=commitdiff_plain;h=021ef038007bbde4d3a54a37c3e614f74c68bdb3;p=melted Memory leaks and resample rework git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@272 d19143bc-622f-0410-bfdd-b5b2a6649095 --- diff --git a/src/framework/mlt_consumer.c b/src/framework/mlt_consumer.c index b03f078..0b3f1dd 100644 --- a/src/framework/mlt_consumer.c +++ b/src/framework/mlt_consumer.c @@ -367,6 +367,9 @@ static void consumer_read_ahead_stop( mlt_consumer this ) // Wipe the queue while ( mlt_deque_count( this->queue ) ) mlt_frame_close( mlt_deque_pop_back( this->queue ) ); + + // Close the queue + mlt_deque_close( this->queue ); } } diff --git a/src/framework/mlt_filter.c b/src/framework/mlt_filter.c index 11f4db7..6e82f5e 100644 --- a/src/framework/mlt_filter.c +++ b/src/framework/mlt_filter.c @@ -194,4 +194,5 @@ void mlt_filter_close( mlt_filter this ) this->close( this ); else mlt_service_close( &this->parent ); + free( this ); } diff --git a/src/framework/mlt_playlist.c b/src/framework/mlt_playlist.c index 8e332e5..acf0fd2 100644 --- a/src/framework/mlt_playlist.c +++ b/src/framework/mlt_playlist.c @@ -85,6 +85,9 @@ mlt_playlist mlt_playlist_init( ) mlt_properties_set( mlt_playlist_properties( this ), "eof", "pause" ); mlt_properties_set( mlt_playlist_properties( this ), "resource", "" ); mlt_properties_set( mlt_playlist_properties( this ), "mlt_type", "mlt_producer" ); + + this->size = 10; + this->list = malloc( this->size * sizeof( playlist_entry * ) ); } return this; @@ -168,8 +171,7 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer { int i; this->list = realloc( this->list, ( this->size + 10 ) * sizeof( playlist_entry * ) ); - for ( i = this->size; i < this->size + 10; i ++ ) - this->list[ i ] = NULL; + for ( i = this->size; i < this->size + 10; i ++ ) this->list[ i ] = NULL; this->size += 10; } @@ -643,7 +645,11 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i void mlt_playlist_close( mlt_playlist this ) { + int i = 0; mlt_producer_close( &this->parent ); mlt_producer_close( &this->blank ); + for ( i = 0; i < this->count; i ++ ) + free( this->list[ i ] ); + free( this->list ); free( this ); } diff --git a/src/framework/mlt_properties.c b/src/framework/mlt_properties.c index 4b0f76b..eb437f3 100644 --- a/src/framework/mlt_properties.c +++ b/src/framework/mlt_properties.c @@ -360,24 +360,29 @@ int mlt_properties_count( mlt_properties this ) int mlt_properties_parse( mlt_properties this, char *namevalue ) { char *name = strdup( namevalue ); - char *value = strdup( namevalue ); + char *value = NULL; int error = 0; + char *ptr = strchr( name, '=' ); - if ( strchr( name, '=' ) ) + if ( ptr ) { - *( strchr( name, '=' ) ) = '\0'; - strcpy( value, strchr( value, '=' ) + 1 ); + *( ptr ++ ) = '\0'; + + if ( *ptr != '\"' ) + { + value = strdup( ptr ); + } + else + { + ptr ++; + value = strdup( ptr ); + if ( value != NULL && value[ strlen( value ) - 1 ] == '\"' ) + value[ strlen( value ) - 1 ] = '\0'; + } } else { - strcpy( value, "" ); - } - - if ( strlen( value ) > 1 && value[ 0 ] == '\"' ) - { - strcpy( value, value + 1 ); - if ( value[ strlen( value ) - 1 ] == '\"' ) - value[ strlen( value ) - 1 ] = '\0'; + value = strdup( "" ); } error = mlt_properties_set( this, name, value ); diff --git a/src/framework/mlt_repository.c b/src/framework/mlt_repository.c index 9e0b1a8..f121511 100644 --- a/src/framework/mlt_repository.c +++ b/src/framework/mlt_repository.c @@ -90,12 +90,16 @@ static void *construct_instance( mlt_properties service_properties, char *symbol construct_full_file( full_file, prefix, file ); // Open the shared object - object = dlopen( full_file, RTLD_NOW | RTLD_GLOBAL ); - if ( object == NULL ) + object = dlopen( full_file, RTLD_NOW ); + if ( object != NULL ) + { + // Set it on the properties + mlt_properties_set_data( object_properties, "dlopen", object, 0, ( mlt_destructor )dlclose, NULL ); + } + else + { fprintf( stderr, "Failed to load plugin: %s\n", dlerror() ); - - // Set it on the properties - mlt_properties_set_data( object_properties, "dlopen", object, 0, ( mlt_destructor )dlclose, NULL ); + } } // Now check if we have this symbol pointer diff --git a/src/inigo/inigo.c b/src/inigo/inigo.c index 563371a..41a0341 100644 --- a/src/inigo/inigo.c +++ b/src/inigo/inigo.c @@ -183,7 +183,7 @@ int main( int argc, char **argv ) char *name = NULL; // Construct the factory - mlt_factory_init( getenv( "MLT_REPOSITORY" ) ); + mlt_factory_init( NULL ); // Check for serialisation switch first for ( i = 1; i < argc; i ++ ) diff --git a/src/modules/dv/consumer_libdv.c b/src/modules/dv/consumer_libdv.c index d82d32b..da86a03 100644 --- a/src/modules/dv/consumer_libdv.c +++ b/src/modules/dv/consumer_libdv.c @@ -275,7 +275,7 @@ static void consumer_encode_audio( mlt_consumer this, uint8_t *dv_frame, mlt_fra // Default audio args mlt_audio_format fmt = mlt_audio_pcm; int channels = 2; - int frequency = 48000; + int frequency = mlt_properties_get_int( this_properties, "frequency" ); int samples = mlt_sample_calculator( mlt_properties_get_double( this_properties, "fps" ), frequency, count ); int16_t *pcm = NULL; @@ -305,6 +305,11 @@ static void consumer_encode_audio( mlt_consumer this, uint8_t *dv_frame, mlt_fra for ( j = 0; j < channels; j++ ) audio_buffers[ j ][ i ] = *pcm ++; } + else + { + for ( j = 0; j < channels; j++ ) + memset( audio_buffers[ j ], 0, 2 * DV_AUDIO_MAX_SAMPLES ); + } // Encode audio on frame dv_encode_full_audio( encoder, audio_buffers, channels, frequency, dv_frame ); diff --git a/src/modules/resample/filter_resample.c b/src/modules/resample/filter_resample.c index 2c848a8..c2f8144 100644 --- a/src/modules/resample/filter_resample.c +++ b/src/modules/resample/filter_resample.c @@ -36,21 +36,30 @@ static int resample_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) { - // Get the properties of the a frame + // Get the properties of the frame mlt_properties properties = mlt_frame_properties( frame ); - int output_rate = mlt_properties_get_int( properties, "resample.frequency" ); - SRC_STATE *state = mlt_properties_get_data( properties, "resample.state", NULL ); - SRC_DATA data; - float *input_buffer = mlt_properties_get_data( properties, "resample.input_buffer", NULL ); - float *output_buffer = mlt_properties_get_data( properties, "resample.output_buffer", NULL ); + + // Get the filter service + mlt_filter filter = mlt_frame_pop_audio( frame ); + + // Get the filter properties + mlt_properties filter_properties = mlt_filter_properties( filter ); + + // Get the resample information + int output_rate = mlt_properties_get_int( filter_properties, "frequency" ); + SRC_STATE *state = mlt_properties_get_data( filter_properties, "state", NULL ); + float *input_buffer = mlt_properties_get_data( filter_properties, "input_buffer", NULL ); + float *output_buffer = mlt_properties_get_data( filter_properties, "output_buffer", NULL ); int channels_avail = *channels; + SRC_DATA data; int i; + // If no resample frequency is specified, default to requested value if ( output_rate == 0 ) output_rate = *frequency; // Restore the original get_audio - frame->get_audio = mlt_properties_get_data( properties, "resample.get_audio", NULL ); + frame->get_audio = mlt_frame_pop_audio( frame ); // Get the producer's audio mlt_frame_get_audio( frame, buffer, format, frequency, &channels_avail, samples ); @@ -60,11 +69,11 @@ static int resample_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form { int size = *channels * *samples * sizeof( int16_t ); int16_t *new_buffer = mlt_pool_alloc( size ); + int j, k = 0; // Duplicate the existing channels for ( i = 0; i < *samples; i++ ) { - int j, k = 0; for ( j = 0; j < *channels; j++ ) { new_buffer[ ( i * *channels ) + j ] = (*buffer)[ ( i * channels_avail ) + k ]; @@ -77,7 +86,7 @@ static int resample_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form *buffer = new_buffer; } - else if ( channels_avail > *channels ) + else if ( channels_avail == 6 && *channels == 2 ) { // Nasty hack for ac3 5.1 audio - may be a cause of failure? int size = *channels * *samples * sizeof( int16_t ); @@ -97,50 +106,56 @@ static int resample_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_form } // Return now if no work to do - if ( output_rate == *frequency ) - return 0; - - //fprintf( stderr, "resample_get_audio: input_rate %d output_rate %d\n", *frequency, output_rate ); - - // Convert to floating point - for ( i = 0; i < *samples * *channels; ++i ) - input_buffer[ i ] = ( float )( (*buffer)[ i ] ) / 32768; - - // Resample - data.data_in = input_buffer; - data.data_out = output_buffer; - data.src_ratio = ( float ) output_rate / ( float ) *frequency; - data.input_frames = *samples; - data.output_frames = BUFFER_LEN / *channels; - data.end_of_input = 0; - i = src_process( state, &data ); - if ( i == 0 ) + if ( output_rate != *frequency ) { - if ( data.output_frames_gen > *samples ) - { - *buffer = mlt_pool_alloc( data.output_frames_gen * *channels * sizeof( int16_t ) ); - mlt_properties_set_data( properties, "audio", *buffer, *channels * data.output_frames_gen * 2, mlt_pool_release, NULL ); - } - *samples = data.output_frames_gen; - *frequency = output_rate; - - // Convert from floating back to signed 16bit - for ( i = 0; i < *samples * *channels; ++i ) + float *p = input_buffer; + float *end = p + *samples * *channels; + int16_t *q = *buffer; + + // Convert to floating point + while( p != end ) + *p ++ = ( float )( *q ++ ) / 32768.0; + + // Resample + data.data_in = input_buffer; + data.data_out = output_buffer; + data.src_ratio = ( float ) output_rate / ( float ) *frequency; + data.input_frames = *samples; + data.output_frames = BUFFER_LEN / *channels; + data.end_of_input = 0; + i = src_process( state, &data ); + if ( i == 0 ) { - float sample = output_buffer[ i ]; - if ( sample > 1.0 ) - sample = 1.0; - if ( sample < -1.0 ) - sample = -1.0; - if ( sample >= 0 ) - (*buffer)[ i ] = lrint( 32767.0 * sample ); - else - (*buffer)[ i ] = lrint( 32768.0 * sample ); + if ( data.output_frames_gen > *samples ) + { + *buffer = mlt_pool_realloc( *buffer, data.output_frames_gen * *channels * sizeof( int16_t ) ); + mlt_properties_set_data( properties, "audio", *buffer, *channels * data.output_frames_gen * 2, mlt_pool_release, NULL ); + } + + *samples = data.output_frames_gen; + *frequency = output_rate; + + p = output_buffer; + q = *buffer; + end = p + *samples * *channels; + + // Convert from floating back to signed 16bit + while( p != end ) + { + if ( *p > 1.0 ) + *p = 1.0; + if ( *p < -1.0 ) + *p = -1.0; + if ( *p > 0 ) + *q ++ = 32767 * *p ++; + else + *q ++ = 32768 * *p ++; + } } + else + fprintf( stderr, "resample_get_audio: %s %d,%d,%d\n", src_strerror( i ), *frequency, *samples, output_rate ); } - else - fprintf( stderr, "resample_get_audio: %s %d,%d,%d\n", src_strerror( i ), *frequency, *samples, output_rate ); - + return 0; } @@ -151,23 +166,8 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) { if ( frame->get_audio != NULL ) { - mlt_properties properties = mlt_filter_properties( this ); - mlt_properties frame_props = mlt_frame_properties( frame ); - - // Propogate the frequency property if supplied - if ( mlt_properties_get( properties, "frequency" ) != NULL ) - mlt_properties_set_int( frame_props, "resample.frequency", mlt_properties_get_int( properties, "frequency" ) ); - - // Propogate the other properties - mlt_properties_set_int( frame_props, "resample.channels", mlt_properties_get_int( properties, "channels" ) ); - mlt_properties_set_data( frame_props, "resample.state", mlt_properties_get_data( properties, "state", NULL ), 0, NULL, NULL ); - mlt_properties_set_data( frame_props, "resample.input_buffer", mlt_properties_get_data( properties, "input_buffer", NULL ), 0, NULL, NULL ); - mlt_properties_set_data( frame_props, "resample.output_buffer", mlt_properties_get_data( properties, "output_buffer", NULL ), 0, NULL, NULL ); - - // Backup the original get_audio (it's still needed) - mlt_properties_set_data( frame_props, "resample.get_audio", frame->get_audio, 0, NULL, NULL ); - - // Override the get_audio method + mlt_frame_push_audio( frame, frame->get_audio ); + mlt_frame_push_audio( frame, this ); frame->get_audio = resample_get_audio; } diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c index 0d17499..0873118 100644 --- a/src/modules/sdl/consumer_sdl.c +++ b/src/modules/sdl/consumer_sdl.c @@ -665,6 +665,9 @@ static void consumer_close( mlt_consumer parent ) // Stop the consumer mlt_consumer_stop( parent ); + // Close the queue + mlt_deque_close( this->queue ); + // Destroy mutexes pthread_mutex_destroy( &this->audio_mutex ); pthread_cond_destroy( &this->audio_cond );