X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Fsdl%2Fconsumer_sdl.c;h=cf02c737e7c00317e71e2a0fca31e20f0d6fbcc4;hb=092636b85449e57fd33ffd4954a2de23c2a5f81c;hp=764cab36f556727edacec4af67f0105259dc649e;hpb=e4c9ccbcef39cadaccbad655bc6e36e825bf3dde;p=melted diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c index 764cab3..cf02c73 100644 --- a/src/modules/sdl/consumer_sdl.c +++ b/src/modules/sdl/consumer_sdl.c @@ -46,6 +46,8 @@ struct consumer_sdl_s pthread_cond_t audio_cond; int window_width; int window_height; + int width; + int height; }; /** Forward references to static functions. @@ -53,13 +55,13 @@ struct consumer_sdl_s static void consumer_close( mlt_consumer parent ); static void *consumer_thread( void * ); -static void consumer_get_dimensions( int *width, int *height ); +static int consumer_get_dimensions( int *width, int *height ); /** This is what will be called by the factory - anything can be passed in via the argument, but keep it simple. */ -mlt_consumer consumer_sdl_init( void *dummy ) +mlt_consumer consumer_sdl_init( char *arg ) { // Create the consumer object consumer_sdl this = calloc( sizeof( struct consumer_sdl_s ), 1 ); @@ -85,8 +87,24 @@ mlt_consumer consumer_sdl_init( void *dummy ) pthread_mutex_init( &this->audio_mutex, NULL ); pthread_cond_init( &this->audio_cond, NULL); - // TODO: process actual param - + // process actual param + if ( arg == NULL || !strcmp( arg, "PAL" ) ) + { + this->width = 720; + this->height = 576; + } + else if ( !strcmp( arg, "NTSC" ) ) + { + this->width = 720; + this->height = 480; + } + else if ( sscanf( arg, "%dx%d", &this->width, &this->height ) != 2 ) + { + this->width = 720; + this->height = 576; + } + + // Create the the thread pthread_create( &this->thread, NULL, consumer_thread, this ); @@ -170,6 +188,9 @@ static void *consumer_thread( void *arg ) // Get the service assoicated to the consumer mlt_service service = mlt_consumer_service( consumer ); + // Get the properties of this consumer + mlt_properties properties = this->properties; + // Define a frame pointer mlt_frame frame; @@ -194,7 +215,7 @@ static void *consumer_thread( void *arg ) if ( mlt_service_get_frame( service, &frame, 0 ) == 0 ) { mlt_image_format vfmt = mlt_image_yuv422; - int width, height; + int width = this->width, height = this->height; uint8_t *image; mlt_audio_format afmt = mlt_audio_pcm; @@ -202,6 +223,7 @@ static void *consumer_thread( void *arg ) int samples; int frequency; int16_t *pcm; + int changed = 0; mlt_frame_get_audio( frame, &pcm, &afmt, &frequency, &channels, &samples ); if ( init_audio == 1 ) @@ -212,7 +234,7 @@ static void *consumer_thread( void *arg ) request.freq = frequency; request.format = AUDIO_S16; request.channels = channels; - request.samples = 1024; + request.samples = 512; request.callback = sdl_fill_audio; request.userdata = (void *)this; if ( SDL_OpenAudio( &request, NULL ) < 0 ) @@ -234,40 +256,71 @@ static void *consumer_thread( void *arg ) // Get the image, width and height mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 ); - if ( width != this->window_width || height != this->window_height ) + + if ( sdl_screen != NULL ) { - SDL_Rect rect; - this->window_width = rect.w = width; - this->window_height = rect.h = height; + SDL_Event event; - // open SDL window with video overlay, if possible - if ( sdl_screen == NULL ) - sdl_screen = SDL_SetVideoMode( width, height, 0, sdl_flags ); - if ( sdl_screen != NULL ) + changed = consumer_get_dimensions( &this->window_width, &this->window_height ); + + while ( SDL_PollEvent( &event ) ) + { + switch( event.type ) + { + case SDL_VIDEORESIZE: + this->window_width = event.resize.w; + this->window_height = event.resize.h; + changed = 1; + break; + case SDL_KEYDOWN: + { + mlt_producer producer = mlt_properties_get_data( properties, "transport_producer", NULL ); + void (*callback)( mlt_producer, char * ) = mlt_properties_get_data( properties, "transport_callback", NULL ); + if ( callback != NULL && producer != NULL ) + callback( producer, SDL_GetKeyName(event.key.keysym.sym) ); + } + break; + } + } + } + + if ( sdl_screen == NULL || changed ) + { + double aspect_ratio = mlt_frame_get_aspect_ratio( frame ); + + if ( this->window_width == 0 || this->window_height == 0 ) { - rect.x = rect.y = 0; + this->window_width = width; + this->window_height = height; + } + // open SDL window with video overlay, if possible + sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, sdl_flags ); - // XXX: this is a little hack until we have some sort of aspect - // ratio property on images. - if ( rect.h <= 486 ) + if ( sdl_screen != NULL ) + { + SDL_Rect rect; + if ( this->window_width < this->window_height * aspect_ratio ) { - rect.w = 640; - rect.x = ( 720 - 640 ) / 2; + rect.w = this->window_width; + rect.h = this->window_width / aspect_ratio; } else { - rect.h = 540; - rect.y = ( 576 - 540 ) / 2; + rect.w = this->window_height * aspect_ratio; + rect.h = this->window_height; } + rect.x = ( this->window_width - rect.w ) / 2; + rect.y = ( this->window_height - rect.h ) / 2; + SDL_SetClipRect( sdl_screen, &rect ); // Force an overlay recreation if ( sdl_overlay != NULL ) SDL_FreeYUVOverlay( sdl_overlay ); sdl_lock_display(); - sdl_overlay = SDL_CreateYUVOverlay( width, height, SDL_YUY2_OVERLAY, sdl_screen ); + sdl_overlay = SDL_CreateYUVOverlay( this->width, this->height, SDL_YUY2_OVERLAY, sdl_screen ); sdl_unlock_display(); } } @@ -279,7 +332,7 @@ static void *consumer_thread( void *arg ) { if ( SDL_LockYUVOverlay( sdl_overlay ) >= 0 ) { - memcpy( buffer, image, width * height * 2 ); + mlt_resize_yuv422( buffer, this->width, this->height, image, width, height ); SDL_UnlockYUVOverlay( sdl_overlay ); SDL_DisplayYUVOverlay( sdl_overlay, &sdl_screen->clip_rect ); } @@ -310,8 +363,10 @@ static void *consumer_thread( void *arg ) return NULL; } -static void consumer_get_dimensions( int *width, int *height ) +static int consumer_get_dimensions( int *width, int *height ) { + int changed = 0; + // SDL windows manager structure SDL_SysWMinfo wm; @@ -334,11 +389,16 @@ static void consumer_get_dimensions( int *width, int *height ) XWindowAttributes attr; XGetWindowAttributes( display, window, &attr ); + // Determine whether window has changed + changed = *width != attr.width || *height != attr.height; + // Return width and height *width = attr.width; *height = attr.height; } } + + return changed; } /** Callback to allow override of the close method.