*****************************************************************************/
typedef struct vout_sys_s
{
+ int i_width;
+ int i_height;
SDL_Surface * p_display; /* display device */
SDL_Overlay * p_overlay; /* overlay device */
boolean_t b_fullscreen;
boolean_t b_reopen_display;
+ boolean_t b_toggle_fullscreen;
Uint8 * p_buffer[2];
/* Buffers informations */
- boolean_t b_must_acquire; /* must be acquired before writing */
} vout_sys_t;
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-static int SDLOpenDisplay ( vout_thread_t *p_vout );
-static void SDLCloseDisplay ( vout_thread_t *p_vout );
+static int SDLOpenDisplay ( vout_thread_t *p_vout );
+static void SDLCloseDisplay ( vout_thread_t *p_vout );
+static void SDLToggleFullScreen ( vout_thread_t *p_vout );
/*****************************************************************************
* vout_SDLCreate: allocate SDL video thread output method
p_vout->p_sys->p_display = NULL;
p_vout->p_sys->p_overlay = NULL;
- p_vout->p_sys->b_must_acquire = 0;
/* Initialize library */
- if( SDL_Init(SDL_INIT_VIDEO) < 0 )
+ if( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTTHREAD) < 0 )
{
intf_ErrMsg( "error: can't initialize SDL library: %s",
SDL_GetError() );
p_vout->p_sys->b_fullscreen = 0;
}
- p_vout->p_sys->b_reopen_display = 1;
+ p_vout->p_sys->i_width = VOUT_WIDTH_DEFAULT;
+ p_vout->p_sys->i_height = VOUT_HEIGHT_DEFAULT;
if( SDLOpenDisplay(p_vout) )
{
- intf_ErrMsg( "error: can't initialize SDL library: %s",
- SDL_GetError() );
- free( p_vout->p_sys );
- return( 1 );
+ intf_ErrMsg( "error: can't initialize SDL library: %s",
+ SDL_GetError() );
+ return( 1 );
}
+ p_vout->p_sys->b_toggle_fullscreen = 0;
+
return( 0 );
}
*****************************************************************************/
int vout_SDLInit( vout_thread_t *p_vout )
{
- /* Acquire first buffer */
- if( p_vout->p_sys->b_must_acquire )
- {
- SDL_LockSurface(p_vout->p_sys->p_display);
- }
-
return( 0 );
}
*****************************************************************************/
void vout_SDLEnd( vout_thread_t *p_vout )
{
- /* Release buffer */
- if( p_vout->p_sys->b_must_acquire )
- {
- SDL_UnlockSurface ( p_vout->p_sys->p_display );
- }
- free( p_vout->p_sys );
+ SDLCloseDisplay( p_vout );
+ SDL_Quit();
}
/*****************************************************************************
*****************************************************************************/
void vout_SDLDestroy( vout_thread_t *p_vout )
{
- SDLCloseDisplay( p_vout );
free( p_vout->p_sys );
}
/* If the display has to be reopened we do so */
if( p_vout->p_sys->b_reopen_display )
{
- p_vout->p_sys->b_must_acquire = 0;
- if( p_vout->p_sys->p_display )
- {
- if( p_vout->p_sys->p_overlay )
- {
- SDL_FreeYUVOverlay(p_vout->p_sys->p_overlay);
- p_vout->p_sys->p_overlay = NULL;
- }
- SDL_FreeSurface( p_vout->p_sys->p_display );
- p_vout->p_sys->p_display = NULL;
- }
+ SDLCloseDisplay(p_vout);
if( SDLOpenDisplay(p_vout) )
{
intf_ErrMsg( "error: can't open DISPLAY default display" );
return( 1 );
}
- p_vout->p_sys->b_reopen_display = 0;
}
+
+ /* if fullscreen has to be toggled we do so */
+ if( p_vout->p_sys->b_toggle_fullscreen )
+ {
+ SDLToggleFullScreen(p_vout);
+ }
+
return( 0 );
}
+/*****************************************************************************
+ * vout_SDLSetPalette: sets an 8 bpp palette
+ *****************************************************************************
+ * This function sets the palette given as an argument. It does not return
+ * anything, but could later send information on which colors it was unable
+ * to set.
+ *****************************************************************************/
+void vout_SDLSetPalette( p_vout_thread_t p_vout, u16 *red, u16 *green, u16 *blue, u16 *transp)
+{
+ /* Create a display surface with a grayscale palette */
+ SDL_Color colors[256];
+ int i;
+
+ /* Fill colors with color information */
+ for( i = 0; i < 256; i++ )
+ {
+ colors[ i ].r = red[ i ] >> 8;
+ colors[ i ].g = green[ i ] >> 8;
+ colors[ i ].b = blue[ i ] >> 8;
+ }
+
+ /* Set palette */
+ if( SDL_SetColors(p_vout->p_sys->p_display, colors, 0, 256) == 0 )
+ {
+ intf_ErrMsg( "vout error: failed setting palette\n" );
+ }
+
+}
+
/*****************************************************************************
* vout_SDLDisplay: displays previously rendered output
*****************************************************************************
void vout_SDLDisplay( vout_thread_t *p_vout )
{
SDL_Rect disp;
- if(p_vout->b_need_render)
- {
- /* Change display frame */
- if( p_vout->p_sys->b_must_acquire )
- {
-
+ if((p_vout->p_sys->p_display != NULL) && !p_vout->p_sys->b_reopen_display)
+ {
+ if(p_vout->b_need_render)
+ {
+ /* Change display frame */
SDL_Flip( p_vout->p_sys->p_display );
-
- /* Swap buffers and change write frame */
- SDL_LockSurface ( p_vout->p_sys->p_display );
}
- }
- else
- {
-
- /*
- * p_vout->p_rendered_pic->p_y/u/v contains the YUV buffers to render
- */
- if( p_vout->p_sys->b_must_acquire )
+ else
{
+
+ /*
+ * p_vout->p_rendered_pic->p_y/u/v contains the YUV buffers to
+ * render
+ */
/* TODO: support for streams other than 4:2:0 */
/* create the overlay if necessary */
- if( !p_vout->p_sys->p_overlay )
+ if( p_vout->p_sys->p_overlay == NULL )
{
p_vout->p_sys->p_overlay = SDL_CreateYUVOverlay(
p_vout->p_rendered_pic->i_width,
- p_vout->p_rendered_pic->i_height,
+ p_vout->p_rendered_pic->i_height,
SDL_YV12_OVERLAY,
p_vout->p_sys->p_display
);
p_vout->p_rendered_pic->p_u,
p_vout->p_sys->p_overlay->h *
p_vout->p_sys->p_overlay->pitches[2] / 2);
-
+
disp.w = (&p_vout->p_buffer[p_vout->i_buffer_index])->i_pic_width;
disp.h = (&p_vout->p_buffer[p_vout->i_buffer_index])->i_pic_height;
disp.x = (p_vout->i_width - disp.w)/2;
disp.y = (p_vout->i_height - disp.h)/2;
-
+
SDL_DisplayYUVOverlay( p_vout->p_sys->p_overlay , &disp );
SDL_UnlockYUVOverlay(p_vout->p_sys->p_overlay);
}
static int SDLOpenDisplay( vout_thread_t *p_vout )
{
SDL_Rect clipping_rect;
-
+ Uint32 flags;
+ int bpp;
/* Open display
* TODO: Check that we can request for a DOUBLEBUF HWSURFACE display
*/
+
+ /* init flags and cursor */
+ flags = SDL_ANYFORMAT | SDL_HWPALETTE;
+
if( p_vout->p_sys->b_fullscreen )
+ flags |= SDL_FULLSCREEN;
+ else
+ flags |= SDL_RESIZABLE;
+
+ if( p_vout->b_need_render )
+ flags |= SDL_HWSURFACE | SDL_DOUBLEBUF;
+ else
+ flags |= SDL_SWSURFACE; /* save video memory */
+
+ bpp = SDL_VideoModeOK(p_vout->p_sys->i_width,
+ p_vout->p_sys->i_height,
+ p_vout->i_screen_depth, flags);
+
+ if(bpp == 0)
{
- p_vout->p_sys->p_display = SDL_SetVideoMode(p_vout->i_width,
- p_vout->i_height,
- 0,
- SDL_ANYFORMAT | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN );
- SDL_ShowCursor( 0 );
- } else {
- p_vout->p_sys->p_display = SDL_SetVideoMode(p_vout->i_width,
- p_vout->i_height,
- 0,
- SDL_ANYFORMAT | SDL_HWSURFACE | SDL_DOUBLEBUF );
- SDL_ShowCursor( 1 );
+ intf_ErrMsg( "error: can't open DISPLAY default display" );
+ return( 1 );
}
-
+
+ p_vout->p_sys->p_display = SDL_SetVideoMode(p_vout->p_sys->i_width,
+ p_vout->p_sys->i_height,
+ bpp, flags);
+
if( p_vout->p_sys->p_display == NULL )
{
intf_ErrMsg( "error: can't open DISPLAY default display" );
return( 1 );
}
+
+ SDL_LockSurface(p_vout->p_sys->p_display);
+
+ if( p_vout->p_sys->b_fullscreen )
+ SDL_ShowCursor( 0 );
+ else
+ SDL_ShowCursor( 1 );
+
SDL_WM_SetCaption( VOUT_TITLE , VOUT_TITLE );
- SDL_EventState(SDL_KEYUP , SDL_IGNORE); /* ignore keys up */
-
- /* Check buffers properties */
- p_vout->p_sys->b_must_acquire = 1; /* always acquire */
- p_vout->p_sys->p_buffer[ 0 ] =
- p_vout->p_sys->p_display->pixels;
-
- SDL_Flip(p_vout->p_sys->p_display);
- p_vout->p_sys->p_buffer[ 1 ] =
- p_vout->p_sys->p_display->pixels;
- SDL_Flip(p_vout->p_sys->p_display);
-
- /* Set graphic context colors */
-
-/*
- col_fg.r = col_fg.g = col_fg.b = -1;
- col_bg.r = col_bg.g = col_bg.b = 0;
- if( ggiSetGCForeground(p_vout->p_sys->p_display,
- ggiMapColor(p_vout->p_sys->p_display,&col_fg)) ||
- ggiSetGCBackground(p_vout->p_sys->p_display,
- ggiMapColor(p_vout->p_sys->p_display,&col_bg)) )
+ SDL_EventState(SDL_KEYUP , SDL_IGNORE); /* ignore keys up */
+
+ if( p_vout->b_need_render )
{
- intf_ErrMsg("error: can't set colors");
- ggiClose( p_vout->p_sys->p_display );
- ggiExit();
- return( 1 );
+ p_vout->p_sys->p_buffer[ 0 ] = p_vout->p_sys->p_display->pixels;
+ SDL_Flip(p_vout->p_sys->p_display);
+ p_vout->p_sys->p_buffer[ 1 ] = p_vout->p_sys->p_display->pixels;
+ SDL_Flip(p_vout->p_sys->p_display);
+
+ /* Set clipping for text */
+ clipping_rect.x = 0;
+ clipping_rect.y = 0;
+ clipping_rect.w = p_vout->p_sys->p_display->w;
+ clipping_rect.h = p_vout->p_sys->p_display->h;
+ SDL_SetClipRect(p_vout->p_sys->p_display, &clipping_rect);
+
+ /* Set thread information */
+ p_vout->i_width = p_vout->p_sys->p_display->w;
+ p_vout->i_height = p_vout->p_sys->p_display->h;
+ p_vout->i_bytes_per_line = p_vout->p_sys->p_display->pitch;
+
+ p_vout->i_screen_depth =
+ p_vout->p_sys->p_display->format->BitsPerPixel;
+ p_vout->i_bytes_per_pixel =
+ p_vout->p_sys->p_display->format->BytesPerPixel;
+
+ p_vout->i_red_mask = p_vout->p_sys->p_display->format->Rmask;
+ p_vout->i_green_mask = p_vout->p_sys->p_display->format->Gmask;
+ p_vout->i_blue_mask = p_vout->p_sys->p_display->format->Bmask;
+
+ /* FIXME: palette in 8bpp ?? */
+ /* Set and initialize buffers */
+ vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer[ 0 ],
+ p_vout->p_sys->p_buffer[ 1 ] );
}
-*/
-
- /* Set clipping for text */
- clipping_rect.x = 0;
- clipping_rect.y = 0;
- clipping_rect.w = p_vout->p_sys->p_display->w;
- clipping_rect.h = p_vout->p_sys->p_display->h;
- SDL_SetClipRect(p_vout->p_sys->p_display, &clipping_rect);
-
-
-
- /* Set thread information */
- p_vout->i_width = p_vout->p_sys->p_display->w;
- p_vout->i_height = p_vout->p_sys->p_display->h;
-
- p_vout->i_bytes_per_line = p_vout->p_sys->p_display->format->BytesPerPixel *
- p_vout->p_sys->p_display->w ;
-
- p_vout->i_screen_depth = p_vout->p_sys->p_display->format->BitsPerPixel;
- p_vout->i_bytes_per_pixel = p_vout->p_sys->p_display->format->BytesPerPixel;
- p_vout->i_red_mask = p_vout->p_sys->p_display->format->Rmask;
- p_vout->i_green_mask = p_vout->p_sys->p_display->format->Gmask;
- p_vout->i_blue_mask = p_vout->p_sys->p_display->format->Bmask;
-
- /* FIXME: palette in 8bpp ?? */
- /* Set and initialize buffers */
- vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer[ 0 ],
- p_vout->p_sys->p_buffer[ 1 ] );
+ else
+ {
+ p_vout->p_sys->p_buffer[ 0 ] = p_vout->p_sys->p_display->pixels;
+ p_vout->p_sys->p_buffer[ 1 ] = p_vout->p_sys->p_display->pixels;
+
+ /* Set thread information */
+ p_vout->i_width = p_vout->p_sys->p_display->w;
+ p_vout->i_height = p_vout->p_sys->p_display->h;
+ p_vout->i_bytes_per_line = p_vout->p_sys->p_display->pitch;
+
+ vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer[ 0 ],
+ p_vout->p_sys->p_buffer[ 1 ] );
+ }
+
+ p_vout->i_changes |= VOUT_YUV_CHANGE;
+
+ p_vout->p_sys->b_reopen_display = 0;
return( 0 );
}
*****************************************************************************/
static void SDLCloseDisplay( vout_thread_t *p_vout )
{
- if( p_vout->p_sys->p_display )
+ if( p_vout->p_sys->p_display != NULL )
{
- p_vout->p_sys->b_must_acquire = 0;
- if( p_vout->p_sys->p_overlay )
- {
+ if( p_vout->p_sys->p_overlay != NULL )
+ {
SDL_FreeYUVOverlay(p_vout->p_sys->p_overlay);
p_vout->p_sys->p_overlay = NULL;
}
+ SDL_UnlockSurface ( p_vout->p_sys->p_display );
SDL_FreeSurface( p_vout->p_sys->p_display );
p_vout->p_sys->p_display = NULL;
}
+}
- SDL_Quit();
+/*****************************************************************************
+ * SDLToggleFullScreen: toggle fullscreen
+ *****************************************************************************
+ * This function toggles the fullscreen state of the surface.
+ *****************************************************************************/
+static void SDLToggleFullScreen( vout_thread_t *p_vout )
+{
+ SDL_WM_ToggleFullScreen(p_vout->p_sys->p_display);
+
+ if( p_vout->p_sys->b_fullscreen )
+ SDL_ShowCursor( 0 );
+ else
+ SDL_ShowCursor( 1 );
+
+ p_vout->p_sys->b_toggle_fullscreen = 0;
}