mlt_properties properties;
mlt_deque queue;
pthread_t thread;
+ int joined;
int running;
uint8_t audio_buffer[ 4096 * 10 ];
int audio_avail;
static void consumer_close( mlt_consumer parent );
static void *consumer_thread( void * );
static int consumer_get_dimensions( int *width, int *height );
+static void consumer_sdl_event( mlt_listener listener, mlt_properties owner, mlt_service this, void **args );
/** This is what will be called by the factory - anything can be passed in
via the argument, but keep it simple.
// Get sample aspect ratio
this->aspect_ratio = mlt_properties_get_double( this->properties, "aspect_ratio" );
+
+ // Ensure we don't join on a non-running object
+ this->joined = 1;
// Default display aspect ratio
this->display_aspect = 4.0 / 3.0;
{
this->width = mlt_properties_get_int( this->properties, "width" );
this->height = mlt_properties_get_int( this->properties, "height" );
-
- // Default window size
- this->window_width = ( float )this->height * this->display_aspect;
- this->window_height = this->height;
- }
- else
- {
- if ( (int)( ( float )this->width / this->height * 1000 ) !=
- (int)( this->display_aspect * 1000 ) )
- {
- // Override these
- this->display_aspect = ( float )this->width / this->height;
- this->aspect_ratio = 1.0;
- mlt_properties_set_double( this->properties, "aspect_ratio", this->aspect_ratio );
- }
-
- // Set window size
- this->window_width = this->width;
- this->window_height = this->height;
}
+ // Default window size
+ this->window_width = ( float )this->height * this->display_aspect;
+ this->window_height = this->height;
+
// Set the sdl flags
this->sdl_flags = SDL_HWSURFACE | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_RESIZABLE | SDL_DOUBLEBUF;
parent->stop = consumer_stop;
parent->is_stopped = consumer_is_stopped;
+ // Register specific events
+ mlt_events_register( this->properties, "consumer-sdl-event", ( mlt_transmitter )consumer_sdl_event );
+
// Return the consumer produced
return parent;
}
return NULL;
}
+static void consumer_sdl_event( mlt_listener listener, mlt_properties owner, mlt_service this, void **args )
+{
+ if ( listener != NULL )
+ listener( owner, this, ( SDL_Event * )args[ 0 ] );
+}
+
int consumer_start( mlt_consumer parent )
{
consumer_sdl this = parent->child;
{
pthread_attr_t thread_attributes;
+ consumer_stop( parent );
+
this->running = 1;
+ this->joined = 0;
// Allow the user to force resizing to window size
if ( mlt_properties_get_int( this->properties, "resize" ) )
// Inherit the scheduling priority
pthread_attr_init( &thread_attributes );
pthread_attr_setinheritsched( &thread_attributes, PTHREAD_INHERIT_SCHED );
-
+
pthread_create( &this->thread, &thread_attributes, consumer_thread, this );
}
// Get the actual object
consumer_sdl this = parent->child;
- if ( this->running )
+ if ( this->joined == 0 )
{
// Kill the thread and clean up
this->running = 0;
pthread_mutex_unlock( &this->audio_mutex );
pthread_join( this->thread, NULL );
+ this->joined = 1;
}
return 0;
if ( mlt_properties_get_int( properties, "video_off" ) == 0 )
{
// Get the image, width and height
+ mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 );
// Handle events
while ( SDL_PollEvent( &event ) )
{
+ mlt_events_fire( this->properties, "consumer-sdl-event", &event, NULL );
+
switch( event.type )
{
case SDL_VIDEORESIZE:
}
}
- if ( width != this->width || height != this->height || this->last_frame_aspect != mlt_frame_get_aspect_ratio( frame ) )
+ if ( width != this->width || height != this->height ||
+ ( ( int )( this->last_frame_aspect * 1000 ) != ( int )( mlt_frame_get_aspect_ratio( frame ) * 1000 ) &&
+ ( mlt_frame_get_aspect_ratio( frame ) != 1.0 || this->last_frame_aspect == 0.0 ) ) )
+
{
this->width = width;
this->height = height;
mlt_properties_set_int( this->properties, "rect_y", this->rect.y );
mlt_properties_set_int( this->properties, "rect_w", this->rect.w );
mlt_properties_set_int( this->properties, "rect_h", this->rect.h );
-
+
// Force an overlay recreation
if ( this->sdl_overlay != NULL )
SDL_FreeYUVOverlay( this->sdl_overlay );
sdl_lock_display();
this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
sdl_unlock_display();
-
+ if ( consumer_get_dimensions( &this->window_width, &this->window_height ) )
+ this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
+ SDL_Flip( this->sdl_screen );
+ mlt_properties_set_int( properties, "changed", 0 );
+
if ( this->sdl_screen != NULL )
{
SDL_SetClipRect( this->sdl_screen, &this->rect );
sdl_lock_display();
this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
SDL_SetClipRect( this->sdl_screen, &this->rect );
- SDL_Flip( this->sdl_screen );
sdl_unlock_display();
mlt_properties_set_int( properties, "changed", 0 );
}
int64_t playtime = 0;
struct timespec tm = { 0, 100000 };
- if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE ) < 0 )
+ if ( mlt_properties_get_int( mlt_consumer_properties( consumer ), "sdl_started" ) == 0 )
{
- fprintf( stderr, "Failed to initialize SDL: %s\n", SDL_GetError() );
- return NULL;
+ if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) < 0 )
+ {
+ fprintf( stderr, "Failed to initialize SDL: %s\n", SDL_GetError() );
+ return NULL;
+ }
+
+ SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
+ SDL_EnableUNICODE( 1 );
+ }
+ else
+ {
+ if ( SDL_GetVideoSurface( ) != NULL )
+ consumer_get_dimensions( &this->window_width, &this->window_height );
+ mlt_properties_set_int( mlt_consumer_properties( consumer ), "changed", 1 );
}
- SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
- SDL_EnableUNICODE( 1 );
+ SDL_InitSubSystem( SDL_INIT_AUDIO );
// Loop until told not to
while( this->running )
// internal cleanup
if ( this->sdl_overlay != NULL )
SDL_FreeYUVOverlay( this->sdl_overlay );
- SDL_Quit( );
+
+ SDL_QuitSubSystem( SDL_INIT_AUDIO );
+
+ 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 ) );