From cab7cd53c3a4d9c4355751088fec61860dcabbce Mon Sep 17 00:00:00 2001 From: lilo_booter Date: Wed, 2 Feb 2005 12:30:09 +0000 Subject: [PATCH] SMP/HT fixes git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@655 d19143bc-622f-0410-bfdd-b5b2a6649095 --- src/framework/mlt_consumer.c | 53 ++++++++++++++++++++++--------- src/framework/mlt_consumer.h | 1 + src/framework/mlt_frame.c | 5 +-- src/framework/mlt_tractor.c | 1 + src/modules/sdl/consumer_sdl.c | 39 +++++++++++++---------- src/modules/sdl/consumer_sdl_preview.c | 18 ++++++---- src/modules/sdl/consumer_sdl_still.c | 4 ++ 7 files changed, 78 insertions(+), 43 deletions(-) diff --git a/src/framework/mlt_consumer.c b/src/framework/mlt_consumer.c index bcc65ac..1819a0f 100644 --- a/src/framework/mlt_consumer.c +++ b/src/framework/mlt_consumer.c @@ -157,6 +157,7 @@ int mlt_consumer_start( mlt_consumer this ) // Just to make sure nothing is hanging around... mlt_frame_close( this->put ); this->put = NULL; + this->put_active = 1; // Deal with it now. if ( test_card != NULL ) @@ -215,14 +216,14 @@ int mlt_consumer_put_frame( mlt_consumer this, mlt_frame frame ) struct timeval now; struct timespec tm; pthread_mutex_lock( &this->put_mutex ); - while ( !mlt_consumer_is_stopped( this ) && this->put != NULL ) + while ( this->put_active && this->put != NULL ) { gettimeofday( &now, NULL ); tm.tv_sec = now.tv_sec + 1; tm.tv_nsec = now.tv_usec * 1000; pthread_cond_timedwait( &this->put_cond, &this->put_mutex, &tm ); } - if ( !mlt_consumer_is_stopped( this ) && this->put == NULL ) + if ( this->put_active && this->put == NULL ) this->put = frame; else mlt_frame_close( frame ); @@ -257,7 +258,7 @@ mlt_frame mlt_consumer_get_frame( mlt_consumer this ) struct timeval now; struct timespec tm; pthread_mutex_lock( &this->put_mutex ); - while ( !mlt_consumer_is_stopped( this ) && this->put == NULL ) + while ( this->put_active && this->put == NULL ) { gettimeofday( &now, NULL ); tm.tv_sec = now.tv_sec + 1; @@ -353,10 +354,17 @@ static void *consumer_read_ahead_thread( void *arg ) int64_t time_frame = 0; int64_t time_process = 0; int skip_next = 0; + mlt_service lock_object = NULL; // Get the first frame frame = mlt_consumer_get_frame( this ); + // Get the lock object + lock_object = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "consumer_lock_service", NULL ); + + // Lock it + if ( lock_object ) mlt_service_lock( lock_object ); + // Get the image of the first frame if ( !video_off ) mlt_frame_get_image( frame, &image, &this->format, &width, &height, 0 ); @@ -367,6 +375,10 @@ static void *consumer_read_ahead_thread( void *arg ) mlt_frame_get_audio( frame, &pcm, &afmt, &frequency, &channels, &samples ); } + // Unlock the lock object + if ( lock_object ) mlt_service_unlock( lock_object ); + + // Mark as rendered mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "rendered", 1 ); // Get the starting time (can ignore the times above) @@ -393,9 +405,15 @@ static void *consumer_read_ahead_thread( void *arg ) if ( frame == NULL ) continue; + // Attempt to fetch the lock object + lock_object = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "consumer_lock_service", NULL ); + // Increment the count count ++; + // Lock if there's a lock object + if ( lock_object ) mlt_service_lock( lock_object ); + // All non normal playback frames should be shown if ( mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "_speed" ) != 1 ) { @@ -445,6 +463,9 @@ static void *consumer_read_ahead_thread( void *arg ) // Determine if the next frame should be skipped if ( mlt_deque_count( this->queue ) <= 5 && ( ( time_wait + time_frame + time_process ) / count ) > 40000 ) skip_next = 1; + + // Unlock if there's a lock object + if ( lock_object ) mlt_service_unlock( lock_object ); } // Remove the last frame @@ -585,25 +606,25 @@ int mlt_consumer_stop( mlt_consumer this ) { // Get the properies mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); + char *debug = mlt_properties_get( MLT_CONSUMER_PROPERTIES( this ), "debug" ); + + // Just in case... + if ( debug ) fprintf( stderr, "%s: stopping put waiting\n", debug ); + pthread_mutex_lock( &this->put_mutex ); + this->put_active = 0; + pthread_cond_broadcast( &this->put_cond ); + pthread_mutex_unlock( &this->put_mutex ); // Stop the consumer + if ( debug ) fprintf( stderr, "%s: stopping consumer\n", debug ); if ( this->stop != NULL ) this->stop( this ); // Check if the user has requested real time or not and stop if necessary + if ( debug ) fprintf( stderr, "%s: stopping read_ahead\n", debug ); if ( mlt_properties_get_int( properties, "real_time" ) ) consumer_read_ahead_stop( this ); - // Just in case... - pthread_mutex_lock( &this->put_mutex ); - if ( this->put != NULL ) - { - mlt_frame_close( this->put ); - this->put = NULL; - } - pthread_cond_broadcast( &this->put_cond ); - pthread_mutex_unlock( &this->put_mutex ); - // Kill the test card mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL ); @@ -611,6 +632,8 @@ int mlt_consumer_stop( mlt_consumer this ) if ( mlt_properties_get( properties, "post" ) ) system( mlt_properties_get( properties, "post" ) ); + if ( debug ) fprintf( stderr, "%s: stopped\n", debug ); + return 0; } @@ -639,19 +662,17 @@ void mlt_consumer_close( mlt_consumer this ) if ( consumer_close ) { // Just in case... - mlt_consumer_stop( this ); + //mlt_consumer_stop( this ); this->close = NULL; consumer_close( this ); } else { - // Make sure it only gets called once this->parent.close = NULL; // Destroy the push mutex and condition - pthread_cond_broadcast( &this->put_cond ); pthread_mutex_destroy( &this->put_mutex ); pthread_cond_destroy( &this->put_cond ); diff --git a/src/framework/mlt_consumer.h b/src/framework/mlt_consumer.h index d68ff56..873f421 100644 --- a/src/framework/mlt_consumer.h +++ b/src/framework/mlt_consumer.h @@ -52,6 +52,7 @@ struct mlt_consumer_s pthread_mutex_t put_mutex; pthread_cond_t put_cond; mlt_frame put; + int put_active; }; /** Public final methods diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 1637dad..53472db 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -262,16 +262,15 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for mlt_properties properties = MLT_FRAME_PROPERTIES( this ); mlt_get_image get_image = mlt_frame_pop_get_image( this ); mlt_producer producer = mlt_properties_get_data( properties, "test_card_producer", NULL ); + int error = 0; *width = *width >> 1 << 1; if ( get_image != NULL ) { - int error = 0; mlt_position position = mlt_frame_get_position( this ); error = get_image( this, buffer, format, width, height, writable ); mlt_frame_set_position( this, position ); - return error; } else if ( mlt_properties_get_data( properties, "image", NULL ) != NULL ) { @@ -360,7 +359,7 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for mlt_properties_set_int( properties, "test_image", 1 ); } - return 0; + return error; } uint8_t *mlt_frame_get_alpha_mask( mlt_frame this ) diff --git a/src/framework/mlt_tractor.c b/src/framework/mlt_tractor.c index b1bdab2..ffc4779 100644 --- a/src/framework/mlt_tractor.c +++ b/src/framework/mlt_tractor.c @@ -393,6 +393,7 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra mlt_frame_set_position( *frame, mlt_producer_frame( parent ) ); mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_audio", audio == NULL ); mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_image", video == NULL ); + mlt_properties_set_data( MLT_FRAME_PROPERTIES( *frame ), "consumer_lock_service", this, 0, NULL, NULL ); } else if ( producer != NULL ) { diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c index 71dbade..50e08d8 100644 --- a/src/modules/sdl/consumer_sdl.c +++ b/src/modules/sdl/consumer_sdl.c @@ -207,14 +207,9 @@ int consumer_stop( mlt_consumer parent ) if ( this->joined == 0 ) { // Kill the thread and clean up + this->joined = 1; this->running = 0; - - pthread_mutex_lock( &this->audio_mutex ); - pthread_cond_broadcast( &this->audio_cond ); - pthread_mutex_unlock( &this->audio_mutex ); - pthread_join( this->thread, NULL ); - this->joined = 1; } return 0; @@ -375,7 +370,7 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame ) uint8_t *image; int changed = 0; - if ( mlt_properties_get_int( properties, "video_off" ) == 0 ) + if ( this->running && mlt_properties_get_int( properties, "video_off" ) == 0 ) { // Get the image, width and height mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); @@ -450,7 +445,7 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame ) mlt_properties_set_int( properties, "changed", 0 ); } - if ( 1 ) + if ( this->running ) { // Determine window's new display aspect ratio float this_aspect = ( float )this->window_width / this->window_height; @@ -514,7 +509,7 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame ) SDL_SetClipRect( this->sdl_screen, &this->rect ); } - if ( this->sdl_screen != NULL && this->sdl_overlay == NULL ) + if ( this->running && this->sdl_screen != NULL && this->sdl_overlay == NULL ) { SDL_SetClipRect( this->sdl_screen, &this->rect ); SDL_Flip( this->sdl_screen ); @@ -523,7 +518,7 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame ) sdl_unlock_display(); } - if ( this->sdl_screen != NULL && this->sdl_overlay != NULL ) + if ( this->running && this->sdl_screen != NULL && this->sdl_overlay != NULL ) { this->buffer = this->sdl_overlay->pixels[ 0 ]; sdl_lock_display(); @@ -568,10 +563,16 @@ static void *video_thread( void *arg ) { // Pop the next frame pthread_mutex_lock( &this->video_mutex ); - while ( ( next = mlt_deque_pop_front( this->queue ) ) == NULL && this->running ) + next = mlt_deque_pop_front( this->queue ); + while ( next == NULL && this->running ) + { pthread_cond_wait( &this->video_cond, &this->video_mutex ); + next = mlt_deque_pop_front( this->queue ); + } pthread_mutex_unlock( &this->video_mutex ); + if ( !this->running || next == NULL ) break; + // Get the properties properties = MLT_FRAME_PROPERTIES( next ); @@ -615,8 +616,12 @@ static void *video_thread( void *arg ) // This frame can now be closed mlt_frame_close( next ); + next = NULL; } + if ( next != NULL ) + mlt_frame_close( next ); + mlt_consumer_stopped( &this->parent ); return NULL; @@ -729,8 +734,8 @@ static void *consumer_thread( void *arg ) if ( !mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "audio_off" ) ) SDL_QuitSubSystem( SDL_INIT_AUDIO ); - if ( mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "sdl_started" ) == 0 ) - SDL_Quit( ); + //if ( mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "sdl_started" ) == 0 ) + //SDL_Quit( ); while( mlt_deque_count( this->queue ) ) mlt_frame_close( mlt_deque_pop_back( this->queue ) ); @@ -795,7 +800,10 @@ static void consumer_close( mlt_consumer parent ) consumer_sdl this = parent->child; // Stop the consumer - mlt_consumer_stop( parent ); + ///mlt_consumer_stop( parent ); + + // Now clean up the rest + mlt_consumer_close( parent ); // Close the queue mlt_deque_close( this->queue ); @@ -804,9 +812,6 @@ static void consumer_close( mlt_consumer parent ) pthread_mutex_destroy( &this->audio_mutex ); pthread_cond_destroy( &this->audio_cond ); - // Now clean up the rest - mlt_consumer_close( parent ); - // Finally clean up this free( this ); } diff --git a/src/modules/sdl/consumer_sdl_preview.c b/src/modules/sdl/consumer_sdl_preview.c index f1a7c50..ec383ab 100644 --- a/src/modules/sdl/consumer_sdl_preview.c +++ b/src/modules/sdl/consumer_sdl_preview.c @@ -295,7 +295,7 @@ static void *consumer_thread( void *arg ) } else { - mlt_consumer_purge( this->play ); + //mlt_consumer_purge( this->play ); last_position = -1; } @@ -363,12 +363,16 @@ static void *consumer_thread( void *arg ) // We are definitely not waiting on the first frame any more first = 0; } + else + { + this->running = 0; + } } - mlt_consumer_stop( this->play ); - mlt_consumer_stop( this->still ); + //mlt_consumer_stop( this->play ); + //mlt_consumer_stop( this->still ); - SDL_Quit( ); + //SDL_Quit( ); return NULL; } @@ -384,13 +388,13 @@ static void consumer_close( mlt_consumer parent ) // Stop the consumer mlt_consumer_stop( parent ); - // Now clean up the rest - mlt_consumer_close( parent ); - // Close the child consumers mlt_consumer_close( this->play ); mlt_consumer_close( this->still ); + // Now clean up the rest + mlt_consumer_close( parent ); + // Finally clean up this free( this ); } diff --git a/src/modules/sdl/consumer_sdl_still.c b/src/modules/sdl/consumer_sdl_still.c index f9e3aa7..a5ede1a 100644 --- a/src/modules/sdl/consumer_sdl_still.c +++ b/src/modules/sdl/consumer_sdl_still.c @@ -569,6 +569,10 @@ static void *consumer_thread( void *arg ) consumer_play_video( this, frame ); mlt_frame_close( frame ); } + else + { + this->running = 0; + } } if ( mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "sdl_started" ) == 0 ) -- 1.7.4.4