1 /*****************************************************************************
2 * vout_sdl.c: SDL video output display method
3 *****************************************************************************
4 * Copyright (C) 1998, 1999, 2000 VideoLAN
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
21 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
28 #include <errno.h> /* ENOMEM */
29 #include <stdlib.h> /* free() */
30 #include <string.h> /* strerror() */
41 #include "video_output.h"
45 /*****************************************************************************
46 * vout_sys_t: video output SDL method descriptor
47 *****************************************************************************
48 * This structure is part of the video output thread descriptor.
49 * It describes the SDL specific properties of an output thread.
50 *****************************************************************************/
51 typedef struct vout_sys_s
53 SDL_Surface * p_display; /* display device */
55 /* Buffers informations */
56 boolean_t b_must_acquire; /* must be acquired before writing */
59 /*****************************************************************************
61 *****************************************************************************/
62 static int SDLOpenDisplay ( vout_thread_t *p_vout,
63 char *psz_display, void *p_data );
64 static void SDLCloseDisplay ( vout_thread_t *p_vout );
66 /*****************************************************************************
67 * vout_SDLCreate: allocate SDL video thread output method
68 *****************************************************************************
69 * This function allocate and initialize a SDL vout method. It uses some of the
70 * vout properties to choose the correct mode, and change them according to the
72 *****************************************************************************/
73 int vout_SDLCreate( vout_thread_t *p_vout, char *psz_display,
74 int i_root_window, void *p_data )
77 /* Allocate structure */
78 p_vout->p_sys = malloc( sizeof( vout_sys_t ) );
79 if( p_vout->p_sys == NULL )
81 intf_ErrMsg( "error: %s\n", strerror(ENOMEM) );
85 /* Open and initialize device */
87 if( SDLOpenDisplay( p_vout, psz_display, p_data ) )
89 intf_ErrMsg( "error: can't initialize SDL display\n" );
90 free( p_vout->p_sys );
95 screen = SDL_CreateYUVOverlay(
99 p_vout->p_sys->p_display
101 intf_ErrMsg("[YUV acceleration] : %d",screen->hw_overlay);
102 if(screen->hw_overlay)
105 p_vout->b_need_render = 0;
110 /*****************************************************************************
111 * vout_SDLInit: initialize SDL video thread output method
112 *****************************************************************************
113 * This function initialize the SDL display device.
114 *****************************************************************************/
115 int vout_SDLInit( vout_thread_t *p_vout )
117 /* Acquire first buffer */
118 if( p_vout->p_sys->b_must_acquire )
120 SDL_LockSurface(p_vout->p_sys->p_display);
126 /*****************************************************************************
127 * vout_SDLEnd: terminate Sys video thread output method
128 *****************************************************************************
129 * Terminate an output method created by vout_SDLCreate
130 *****************************************************************************/
131 void vout_SDLEnd( vout_thread_t *p_vout )
134 if( p_vout->p_sys->b_must_acquire )
136 SDL_UnlockSurface ( p_vout->p_sys->p_display );
138 free( p_vout->p_sys );
141 /*****************************************************************************
142 * vout_SDLDestroy: destroy Sys video thread output method
143 *****************************************************************************
144 * Terminate an output method created by vout_SDLCreate
145 *****************************************************************************/
146 void vout_SDLDestroy( vout_thread_t *p_vout )
148 SDLCloseDisplay( p_vout );
149 free( p_vout->p_sys );
152 /*****************************************************************************
153 * vout_SDLManage: handle Sys events
154 *****************************************************************************
155 * This function should be called regularly by video output thread. It returns
156 * a non null value if an error occured.
157 *****************************************************************************/
158 int vout_SDLManage( vout_thread_t *p_vout )
160 /* FIXME: 8bpp: change palette ?? */
164 /*****************************************************************************
165 * vout_SDLDisplay: displays previously rendered output
166 *****************************************************************************
167 * This function send the currently rendered image to the display, wait until
168 * it is displayed and switch the two rendering buffer, preparing next frame.
169 *****************************************************************************/
170 void vout_SDLDisplay( vout_thread_t *p_vout )
172 SDL_Overlay * screen;
174 if(p_vout->b_need_render)
176 /* Change display frame */
177 if( p_vout->p_sys->b_must_acquire )
180 SDL_Flip( p_vout->p_sys->p_display );
182 //Swap buffers and change write frame
183 SDL_LockSurface ( p_vout->p_sys->p_display );
188 * p_vout->yuv.p_buffer contains the YUV buffer to render
191 screen = SDL_CreateYUVOverlay(
192 p_vout->p_rendered_pic->i_width,
193 p_vout->p_rendered_pic->i_height,
195 p_vout->p_sys->p_display
198 SDL_LockYUVOverlay(screen);
199 //* screen->pixels = calloc( p_vout->i_width * p_vout->i_height * 3, 1);
200 //*screen->pixels = p_vout->yuv.p_buffer;
201 /* *screen->pixels = malloc( p_vout->i_width * p_vout->i_height * 3 );
202 memcpy( *screen->pixels, p_vout->p_rendered_pic->p_y, p_vout->i_width * p_vout->i_height );
203 memcpy( *screen->pixels + p_vout->i_width * p_vout->i_height,
204 p_vout->p_rendered_pic->p_u,
205 p_vout->i_width * p_vout->i_height );
206 memcpy( *screen->pixels + p_vout->i_width * p_vout->i_height * 2,
207 p_vout->p_rendered_pic->p_v,
208 p_vout->i_width * p_vout->i_height ); */
211 // *screen->pixels = p_vout->p_rendered_pic->p_y;
212 *screen->pixels = p_vout->p_rendered_pic->p_data;
216 disp.w = p_vout->i_width;
217 disp.h = p_vout->i_height;
218 SDL_UnlockYUVOverlay(screen);
220 SDL_DisplayYUVOverlay( screen , &disp );
221 // free(* screen -> pixels);
222 SDL_FreeYUVOverlay(screen);
226 /* following functions are local */
228 /*****************************************************************************
229 * SDLOpenDisplay: open and initialize SDL device
230 *****************************************************************************
231 * Open and initialize display according to preferences specified in the vout
233 *****************************************************************************/
234 static int SDLOpenDisplay( vout_thread_t *p_vout, char *psz_display, void *p_data )
236 SDL_Rect clipping_rect;
238 /* Initialize library */
239 if( SDL_Init(SDL_INIT_VIDEO) < 0 )
241 intf_ErrMsg( "error: can't initialize SDL library: %s\n",
247 * TODO: Check that we can request for a DOUBLEBUF HWSURFACE display
249 if(psz_display != NULL && strcmp(psz_display,"fullscreen")==0)
251 p_vout->p_sys->p_display = SDL_SetVideoMode(p_vout->i_width,
254 SDL_ANYFORMAT | SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_FULLSCREEN );
257 p_vout->p_sys->p_display = SDL_SetVideoMode(p_vout->i_width,
260 SDL_ANYFORMAT | SDL_HWSURFACE | SDL_DOUBLEBUF );
264 if( p_vout->p_sys->p_display == NULL )
266 intf_ErrMsg( "error: can't open DISPLAY default display\n" );
269 SDL_WM_SetCaption( VOUT_TITLE , VOUT_TITLE );
270 SDL_EventState(SDL_KEYUP , SDL_IGNORE); /* ignore keys up */
272 /* Check buffers properties */
273 p_vout->p_sys->b_must_acquire = 1; /* always acquire */
274 p_vout->p_sys->p_buffer[ 0 ] =
275 p_vout->p_sys->p_display->pixels;
277 SDL_Flip(p_vout->p_sys->p_display);
278 p_vout->p_sys->p_buffer[ 1 ] =
279 p_vout->p_sys->p_display->pixels;
280 SDL_Flip(p_vout->p_sys->p_display);
282 /* Set graphic context colors */
285 col_fg.r = col_fg.g = col_fg.b = -1;
286 col_bg.r = col_bg.g = col_bg.b = 0;
287 if( ggiSetGCForeground(p_vout->p_sys->p_display,
288 ggiMapColor(p_vout->p_sys->p_display,&col_fg)) ||
289 ggiSetGCBackground(p_vout->p_sys->p_display,
290 ggiMapColor(p_vout->p_sys->p_display,&col_bg)) )
292 intf_ErrMsg("error: can't set colors\n");
293 ggiClose( p_vout->p_sys->p_display );
299 /* Set clipping for text */
302 clipping_rect.w = p_vout->p_sys->p_display->w;
303 clipping_rect.h = p_vout->p_sys->p_display->h;
304 SDL_SetClipRect(p_vout->p_sys->p_display, &clipping_rect);
308 /* Set thread information */
309 p_vout->i_width = p_vout->p_sys->p_display->w;
310 p_vout->i_height = p_vout->p_sys->p_display->h;
312 p_vout->i_bytes_per_line = p_vout->p_sys->p_display->format->BytesPerPixel *
313 p_vout->p_sys->p_display->w ;
315 p_vout->i_screen_depth = p_vout->p_sys->p_display->format->BitsPerPixel;
316 p_vout->i_bytes_per_pixel = p_vout->p_sys->p_display->format->BytesPerPixel;
317 p_vout->i_red_mask = p_vout->p_sys->p_display->format->Rmask;
318 p_vout->i_green_mask = p_vout->p_sys->p_display->format->Gmask;
319 p_vout->i_blue_mask = p_vout->p_sys->p_display->format->Bmask;
321 /* FIXME: palette in 8bpp ?? */
322 /* Set and initialize buffers */
323 vout_SetBuffers( p_vout, p_vout->p_sys->p_buffer[ 0 ],
324 p_vout->p_sys->p_buffer[ 1 ] );
329 /*****************************************************************************
330 * SDLCloseDisplay: close and reset SDL device
331 *****************************************************************************
332 * This function returns all resources allocated by SDLOpenDisplay and restore
333 * the original state of the device.
334 *****************************************************************************/
335 static void SDLCloseDisplay( vout_thread_t *p_vout )
337 SDL_FreeSurface( p_vout->p_sys->p_display );