]> git.sesse.net Git - mlt/commitdiff
SMP/HT fixes
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Wed, 2 Feb 2005 12:30:09 +0000 (12:30 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Wed, 2 Feb 2005 12:30:09 +0000 (12:30 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@655 d19143bc-622f-0410-bfdd-b5b2a6649095

src/framework/mlt_consumer.c
src/framework/mlt_consumer.h
src/framework/mlt_frame.c
src/framework/mlt_tractor.c
src/modules/sdl/consumer_sdl.c
src/modules/sdl/consumer_sdl_preview.c
src/modules/sdl/consumer_sdl_still.c

index bcc65ac13d81b54cd823166cae075b0f55270767..1819a0ff7a0e586867febafc1f2bcaf4f7d03472 100644 (file)
@@ -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 );
 
index d68ff56d9e8bed0280a8a8c768a4d3eed4db1092..873f42165efb68dbf213c348f9d7dc3b5a905170 100644 (file)
@@ -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
index 1637dad3580094998cf02b6ecb0c19faff9b02de..53472dbfb6537ecdc839033ac9aa3f6e49d5a25b 100644 (file)
@@ -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 )
index b1bdab2b54f14dda46effbb4b1d732141b0ea5f8..ffc47797c1c9404cc88316dfbd3caaad88987a41 100644 (file)
@@ -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 )
                {
index 71dbade1aaddc836bb76ca0ee1d7173a4dec85f6..50e08d85611741f911b59ade2bf14d9ad3698c39 100644 (file)
@@ -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 );
 }
index f1a7c5051da7d26023e3284efedc79620d20b58f..ec383ab2e06c57eacc201770e83fcd520665113b 100644 (file)
@@ -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 );
 }
index f9e3aa750d2e5d0b99a3c7abe2e0f0574330fc60..a5ede1aff20642e355dbf7050686f3824cd7d58f 100644 (file)
@@ -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 )