]> git.sesse.net Git - mlt/commitdiff
Increase the speed of switching between sdl_still and sdl.
authorDan Dennedy <dan@dennedy.org>
Mon, 20 Dec 2010 03:43:47 +0000 (19:43 -0800)
committerDan Dennedy <dan@dennedy.org>
Mon, 20 Dec 2010 03:43:47 +0000 (19:43 -0800)
Based on patch from Jonathan Thomas.

It does this by not calling the SDL_InitSubSystem( SDL_INIT_AUDIO ) and
SDL_QuitSubSystem( SDL_INIT_AUDIO ) methods every time it switches, but
rather when the SDL Preview consumer is started and stopped.

src/modules/sdl/consumer_sdl.c
src/modules/sdl/consumer_sdl_preview.c

index f58e73de84b937bfa81340cf15aa9cef47fded9f..85cdd6c70708612f7d2954e9a3cdb4c55925a562 100644 (file)
@@ -214,8 +214,16 @@ int consumer_start( mlt_consumer parent )
                        pthread_mutex_unlock( &mlt_sdl_mutex );
                }
 
-               if ( audio_off == 0 )
-                       SDL_InitSubSystem( SDL_INIT_AUDIO );
+               if ( !audio_off )
+               {
+                       if ( !sdl_started )
+                               // Init the audio sub-system
+                               SDL_InitSubSystem( SDL_INIT_AUDIO );
+                       else
+                               // write silence to the audio buffer, since the sdl_preview consumer is
+                               // in charge of initializing the audio sub-system
+                               SDL_PauseAudio( 0 );
+               }
 
                // Default window size
                if ( mlt_properties_get_int( this->properties, "_arg_size" ) )
@@ -258,9 +266,14 @@ int consumer_stop( mlt_consumer parent )
 {
        // Get the actual object
        consumer_sdl this = parent->child;
-
+       
        if ( this->joined == 0 )
        {
+               mlt_properties properties = MLT_CONSUMER_PROPERTIES( parent );
+               int sdl_started = mlt_properties_get_int( properties, "sdl_started" );
+               int audio_off = mlt_properties_get_int( properties, "audio_off" );
+               int quit_audio_subsystem = mlt_properties_get_int( properties, "quit_audio_subsystem" );
+       
                // Kill the thread and clean up
                this->joined = 1;
                this->running = 0;
@@ -272,15 +285,25 @@ int consumer_stop( mlt_consumer parent )
                        SDL_FreeYUVOverlay( this->sdl_overlay );
                this->sdl_overlay = NULL;
 
-               if ( !mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "audio_off" ) )
+               if ( !audio_off )
                {
-                       pthread_mutex_lock( &this->audio_mutex );
-                       pthread_cond_broadcast( &this->audio_cond );
-                       pthread_mutex_unlock( &this->audio_mutex );
-                       SDL_QuitSubSystem( SDL_INIT_AUDIO );
+                       if ( !sdl_started || quit_audio_subsystem )
+                       {
+                               // quit the audio sub-system, if this is a normal sdl consumer,
+                               // or if the 'quit_audio_subsystem' property is set to 1
+                               pthread_mutex_lock( &this->audio_mutex );
+                               pthread_cond_broadcast( &this->audio_cond );
+                               pthread_mutex_unlock( &this->audio_mutex );
+                               SDL_QuitSubSystem( SDL_INIT_AUDIO );
+                       }
+                       else
+                               // Write silence to the audio buffer.  This is used when the sdl_preview
+                               // consumer is in charge of the audio sub-system.
+                               SDL_PauseAudio( 1 );
                }
 
-               if ( mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" ) == 0 )
+               // Shutdown SDL if this consumer is not controlled by the SDL preview consumer
+               if ( !sdl_started )
                {
                        pthread_mutex_lock( &mlt_sdl_mutex );
                        SDL_Quit( );
@@ -407,13 +430,22 @@ static int consumer_play_audio( consumer_sdl this, mlt_frame frame, int init_aud
                request.samples = audio_buffer;
                request.callback = sdl_fill_audio;
                request.userdata = (void *)this;
-               if ( SDL_OpenAudio( &request, &got ) != 0 )
+
+               // determine if we should open the audio
+               int audio_opened = mlt_properties_get_int( properties, "audio_opened" );
+
+               // open the audio device once
+               if ( !audio_opened && SDL_OpenAudio( &request, &got ) )
                {
                        mlt_log_error( MLT_CONSUMER_SERVICE( this ), "SDL failed to open audio: %s\n", SDL_GetError() );
                        init_audio = 2;
                }
-               else if ( got.size != 0 )
+               else
                {
+                       // do not open the audio again for this consumer
+                       mlt_properties_set_int( properties, "audio_opened", 1 );
+
+                       // write silence to the audio buffer
                        SDL_PauseAudio( 0 );
                        init_audio = 0;
                }
index f6f08b929075fb1d99c36f44625a143035d35022..dc9361156a9a2a2a2b10a3f1c270540cd8ab67b6 100644 (file)
@@ -46,7 +46,6 @@ struct consumer_sdl_s
        int sdl_flags;
        double last_speed;
        mlt_position last_position;
-
        pthread_cond_t refresh_cond;
        pthread_mutex_t refresh_mutex;
        int refresh_count;
@@ -153,6 +152,7 @@ static int consumer_start( mlt_consumer parent )
                char *audio_device = mlt_properties_get( properties, "audio_device" );
                char *output_display = mlt_properties_get( properties, "output_display" );
                int progressive = mlt_properties_get_int( properties, "progressive" ) | mlt_properties_get_int( properties, "deinterlace" );
+               int audio_off = mlt_properties_get_int( properties, "audio_off" );
 
                consumer_stop( parent );
 
@@ -187,6 +187,10 @@ static int consumer_start( mlt_consumer parent )
                SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
                SDL_EnableUNICODE( 1 );
 
+               // init audio sub-system (if enabled)
+               if ( !audio_off )
+                       SDL_InitSubSystem( SDL_INIT_AUDIO );
+
                // Pass properties down
                mlt_properties_set_data( play, "transport_producer", mlt_properties_get_data( properties, "transport_producer", NULL ), 0, NULL, NULL );
                mlt_properties_set_data( still, "transport_producer", mlt_properties_get_data( properties, "transport_producer", NULL ), 0, NULL, NULL );
@@ -223,6 +227,9 @@ static int consumer_start( mlt_consumer parent )
                mlt_properties_set_int( play, "sdl_started", 1 );
                mlt_properties_set_int( still, "sdl_started", 1 );
 
+               // Inform the sdl child consumer to not quit the audio sub-system
+               mlt_properties_set_int( play, "quit_audio_subsystem", 0 );
+
                pthread_create( &this->thread, NULL, consumer_thread, this );
        }
 
@@ -236,6 +243,9 @@ static int consumer_stop( mlt_consumer parent )
 
        if ( this->joined == 0 )
        {
+               // inform child sdl consumer to quit the audio sub-system
+               mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( this->play ), "quit_audio_subsystem", 1 );
+
                mlt_properties properties = MLT_CONSUMER_PROPERTIES( parent );
                int app_locked = mlt_properties_get_int( properties, "app_locked" );
                void ( *lock )( void ) = mlt_properties_get_data( properties, "app_lock", NULL );
@@ -254,7 +264,6 @@ static int consumer_stop( mlt_consumer parent )
                this->joined = 1;
 
                if ( app_locked && lock ) lock( );
-               
                pthread_mutex_lock( &mlt_sdl_mutex );
                SDL_Quit( );
                pthread_mutex_unlock( &mlt_sdl_mutex );