Dan,
Here is a patch for the SDL_Preview consumer, that increases the speed when
switching between the STILL and SDL consumers.  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.  I have tested this patch against
OpenShot when using the regular SDL consumer and the SDL Preview consumer.
 I can't make it break, so I feel pretty good about it.

Please let me know if you see any potential issues with the patch.

Thanks!
-Jonathan
diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c
index f58e73d..50bad71 100644
--- a/src/modules/sdl/consumer_sdl.c
+++ b/src/modules/sdl/consumer_sdl.c
@@ -214,8 +214,14 @@ 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 == 0 )
+				// 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,6 +264,9 @@ int consumer_stop( mlt_consumer parent )
 {
 	// Get the actual object
 	consumer_sdl this = parent->child;
+	int sdl_started = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" );
+	int audio_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "audio_off" );
+	int quit_audio_subsystem = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "quit_audio_subsystem" );
 
 	if ( this->joined == 0 )
 	{
@@ -272,15 +281,23 @@ 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" ) )
-		{
-			pthread_mutex_lock( &this->audio_mutex );
-			pthread_cond_broadcast( &this->audio_cond );
-			pthread_mutex_unlock( &this->audio_mutex );
-			SDL_QuitSubSystem( SDL_INIT_AUDIO );
-		}
+		if ( !audio_off )
+			if (sdl_started == 0 || quit_audio_subsystem == 1)
+			{
+				// 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 == 0 )
 		{
 			pthread_mutex_lock( &mlt_sdl_mutex );
 			SDL_Quit( );
@@ -407,13 +424,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 == 0 && SDL_OpenAudio( &request, &got ) != 0 )
 		{
 			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;
 		}
diff --git a/src/modules/sdl/consumer_sdl_preview.c b/src/modules/sdl/consumer_sdl_preview.c
index f6f08b9..6e883e1 100644
--- a/src/modules/sdl/consumer_sdl_preview.c
+++ b/src/modules/sdl/consumer_sdl_preview.c
@@ -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( 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 );
------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
Mlt-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mlt-devel

Reply via email to