comparison libvo/vo_sdl.c @ 635:b9735f811d7d

15,16,24,32Bit rgb/bgr support added, aalib fixed, performance optimizations, code cleanup and so much more...
author atmosfear
date Wed, 25 Apr 2001 20:43:45 +0000
parents 41d6eec69b60
children 19d941a8b46f
comparison
equal deleted inserted replaced
634:12d884de4ea1 635:b9735f811d7d
2 * vo_sdl.c 2 * vo_sdl.c
3 * 3 *
4 * (was video_out_sdl.c from OMS project/mpeg2dec -> http://linuxvideo.org) 4 * (was video_out_sdl.c from OMS project/mpeg2dec -> http://linuxvideo.org)
5 * 5 *
6 * Copyright (C) Ryan C. Gordon <icculus@lokigames.com> - April 22, 2000. 6 * Copyright (C) Ryan C. Gordon <icculus@lokigames.com> - April 22, 2000.
7 *
8 * Copyright (C) Felix Buenemann <atmosfear@users.sourceforge.net> - 2001
9 *
10 * (for extensive code enhancements)
7 * 11 *
8 * Current maintainer for MPlayer project (report bugs to that address): 12 * Current maintainer for MPlayer project (report bugs to that address):
9 * Felix Buenemann <atmosfear@users.sourceforge.net> 13 * Felix Buenemann <atmosfear@users.sourceforge.net>
10 * 14 *
11 * This file is a video out driver using the SDL library (http://libsdl.org/), 15 * This file is a video out driver using the SDL library (http://libsdl.org/),
84 * 88 *
85 * Felix Buenemann: further changes will be visible through cvs log, don't want 89 * Felix Buenemann: further changes will be visible through cvs log, don't want
86 * to update this all the time (CVS info on http://mplayer.sourceforge.net) 90 * to update this all the time (CVS info on http://mplayer.sourceforge.net)
87 * 91 *
88 * KNOWN BUGS: 92 * KNOWN BUGS:
89 * - Crashes with aalib (not resolved yet) 93 * - Crashes with aalib (fixed, but have to find cause!)
90 */ 94 */
91 95
92 /* define if you want to force Xv SDL output? */
93 #undef SDL_FORCEXV
94 /* define to force software-surface (video surface stored in system memory)*/ 96 /* define to force software-surface (video surface stored in system memory)*/
95 #undef SDL_NOHWSURFACE 97 #undef SDL_NOHWSURFACE
96 /* define to disable usage of the xvideo extension */
97 #undef SDL_NOXV
98 98
99 #include <stdio.h> 99 #include <stdio.h>
100 #include <stdlib.h> 100 #include <stdlib.h>
101 #include <string.h> 101 #include <string.h>
102 #include <inttypes.h> 102 #include <inttypes.h>
108 #include "fastmemcpy.h" 108 #include "fastmemcpy.h"
109 #include "sub.h" 109 #include "sub.h"
110 110
111 LIBVO_EXTERN(sdl) 111 LIBVO_EXTERN(sdl)
112 112
113 //#include "log.h"
114 //#define LOG if(0)printf
115
116 extern int verbose; 113 extern int verbose;
114 char *sdl_driver;
115 int sdl_noxv;
116 int sdl_forcexv;
117 117
118 static vo_info_t vo_info = 118 static vo_info_t vo_info =
119 { 119 {
120 "SDL YUV overlay (SDL v1.1.7+ only!)", 120 "SDL YUV/RGB/BGR renderer (SDL v1.1.7+ only!)",
121 "sdl", 121 "sdl",
122 "Ryan C. Gordon <icculus@lokigames.com>", 122 "Ryan C. Gordon <icculus@lokigames.com>, Felix Buenemann <atmosfear@users.sourceforge.net>",
123 "" 123 ""
124 }; 124 };
125 125
126 #include <SDL/SDL.h> 126 #include <SDL/SDL.h>
127 127
128 /** Private SDL Data structure **/ 128 /** Private SDL Data structure **/
129 129
130 static struct sdl_priv_s { 130 static struct sdl_priv_s {
131 131
132 /* SDL YUV surface & overlay */ 132 /* output driver used by sdl */
133 char driver[8];
134
135 /* SDL display surface */
133 SDL_Surface *surface; 136 SDL_Surface *surface;
137
138 /* SDL RGB surface */
139 SDL_Surface *rgbsurface;
140
141 /* SDL YUV overlay */
134 SDL_Overlay *overlay; 142 SDL_Overlay *overlay;
135 // SDL_Overlay *current_frame; 143
144 /* x,y video position for centering */
145 SDL_Rect vidpos;
136 146
137 /* available fullscreen modes */ 147 /* available fullscreen modes */
138 SDL_Rect **fullmodes; 148 SDL_Rect **fullmodes;
139 149
140 /* surface attributes for fullscreen and windowed mode */ 150 /* surface attributes for fullscreen and windowed mode */
143 /* save the windowed output extents */ 153 /* save the windowed output extents */
144 SDL_Rect windowsize; 154 SDL_Rect windowsize;
145 155
146 /* Bits per Pixel */ 156 /* Bits per Pixel */
147 Uint8 bpp; 157 Uint8 bpp;
158
159 /* RGB or YUV? */
160 Uint8 mode;
161 #define YUV 0
162 #define RGB 1
163 #define BGR 2
148 164
149 /* current fullscreen mode, 0 = highest available fullscreen mode */ 165 /* current fullscreen mode, 0 = highest available fullscreen mode */
150 int fullmode; 166 int fullmode;
151 167
152 /* YUV ints */ 168 /* YUV ints */
153 int framePlaneY, framePlaneUV; 169 int framePlaneY, framePlaneUV;
154 int stridePlaneY, stridePlaneUV; 170 int stridePlaneY, stridePlaneUV;
171
172 /* RGB ints */
173 int framePlaneRGB;
174
155 int width,height; 175 int width,height;
156 int format; 176 int format;
157 } sdl_priv; 177 } sdl_priv;
158 178
159 179
164 * 184 *
165 **/ 185 **/
166 186
167 static void draw_alpha(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){ 187 static void draw_alpha(int x0,int y0, int w,int h, unsigned char* src, unsigned char *srca, int stride){
168 struct sdl_priv_s *priv = &sdl_priv; 188 struct sdl_priv_s *priv = &sdl_priv;
169 int x,y;
170 189
171 switch(priv->format) { 190 switch(priv->format) {
172 case IMGFMT_YV12: 191 case IMGFMT_YV12:
173 case IMGFMT_I420: 192 case IMGFMT_I420:
174 case IMGFMT_IYUV: 193 case IMGFMT_IYUV:
178 case IMGFMT_YVYU: 197 case IMGFMT_YVYU:
179 vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) *(priv->overlay->pixels))+2*(priv->width*y0+x0),2*priv->width); 198 vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) *(priv->overlay->pixels))+2*(priv->width*y0+x0),2*priv->width);
180 break; 199 break;
181 case IMGFMT_UYVY: 200 case IMGFMT_UYVY:
182 vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) *(priv->overlay->pixels))+2*(priv->width*y0+x0)+1,2*priv->width); 201 vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) *(priv->overlay->pixels))+2*(priv->width*y0+x0)+1,2*priv->width);
183 break; 202 break;
203 case IMGFMT_RGB15:
204 case IMGFMT_BGR15:
205 vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) priv->rgbsurface->pixels)+2*(y0*priv->width+x0),2*priv->width);
206 break;
207 case IMGFMT_RGB16:
208 case IMGFMT_BGR16:
209 vo_draw_alpha_rgb16(w,h,src,srca,stride,((uint8_t *) priv->rgbsurface->pixels)+2*(y0*priv->width+x0),2*priv->width);
210 break;
211 case IMGFMT_RGB24:
212 case IMGFMT_BGR24:
213 vo_draw_alpha_rgb24(w,h,src,srca,stride,((uint8_t *) priv->rgbsurface->pixels)+3*(y0*priv->width+x0),3*priv->width);
214 break;
215 case IMGFMT_RGB32:
216 case IMGFMT_BGR32:
217 vo_draw_alpha_rgb32(w,h,src,srca,stride,((uint8_t *) priv->rgbsurface->pixels)+4*(y0*priv->width+x0),4*priv->width);
218 break;
184 } 219 }
185 } 220 }
186 221
187 222
188 /** 223 /**
218 253
219 if (opened) 254 if (opened)
220 return 0; 255 return 0;
221 opened = 1; 256 opened = 1;
222 257
223 // LOG (LOG_DEBUG, "SDL video out: Opened Plugin"); 258 if(verbose > 2) printf("SDL: Opening Plugin\n");
259
260 if(sdl_driver) setenv("SDL_VIDEODRIVER", sdl_driver, 1);
224 261
225 /* does the user want SDL to try and force Xv */ 262 /* does the user want SDL to try and force Xv */
226 #ifdef SDL_FORCEXV 263 if(sdl_forcexv) setenv("SDL_VIDEO_X11_NODIRECTCOLOR", "1", 1);
227 setenv("SDL_VIDEO_X11_NODIRECTCOLOR", "1", 1); 264
228 #endif 265 /* does the user want to disable Xv and use software scaling instead */
229 #ifdef SDL_NOXV 266 if(sdl_noxv) setenv("SDL_VIDEO_YUV_HWACCEL", "0", 1);
230 setenv("SDL_VIDEO_YUV_HWACCEL", "0", 1); 267
231 #endif
232 268
233 /* default to no fullscreen mode, we'll set this as soon we have the avail. modes */ 269 /* default to no fullscreen mode, we'll set this as soon we have the avail. modes */
234 priv->fullmode = -2; 270 priv->fullmode = -2;
271
272 priv->surface = NULL;
273 priv->rgbsurface = NULL;
274 priv->overlay = NULL;
275 priv->fullmodes = NULL;
276 priv->bpp = 0;
277
278 /* initialize the SDL Video system */
279 if (SDL_Init (SDL_INIT_VIDEO/*|SDL_INIT_NOPARACHUTE*/)) {
280 if(verbose > 2) printf("SDL: Initializing of SDL failed: %s.\n", SDL_GetError());
281 return -1;
282 }
283
284 SDL_VideoDriverName(priv->driver, 8);
285 if(verbose) printf("SDL: Using driver: %s\n", priv->driver);
235 /* other default values */ 286 /* other default values */
236 #ifdef SDL_NOHWSURFACE 287 #ifdef SDL_NOHWSURFACE
237 if(verbose) printf("SDL: using software-surface\n"); 288 if(verbose) printf("SDL: using software-surface\n");
238 priv->sdlflags = SDL_SWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT; 289 priv->sdlflags = SDL_SWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT;
239 priv->sdlfullflags = SDL_SWSURFACE|SDL_FULLSCREEN|SDL_DOUBLEBUF|SDL_ASYNCBLIT; 290 priv->sdlfullflags = SDL_SWSURFACE|SDL_FULLSCREEN|SDL_DOUBLEBUF|SDL_ASYNCBLIT;
240 #else 291 #else
241 if(verbose) printf("SDL: using hardware-surface\n"); 292 if((strcmp(priv->driver, "dga") == 0) && (priv->mode)) {
242 priv->sdlflags = SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT; //SDL_HWACCEL 293 if(verbose) printf("SDL: using software-surface\n");
243 priv->sdlfullflags = SDL_HWSURFACE|SDL_FULLSCREEN|SDL_DOUBLEBUF|SDL_ASYNCBLIT; //SDL_HWACCEL 294 priv->sdlflags = SDL_SWSURFACE|SDL_FULLSCREEN|SDL_ASYNCBLIT|SDL_HWACCEL;
295 priv->sdlfullflags = SDL_SWSURFACE|SDL_FULLSCREEN|SDL_ASYNCBLIT|SDL_HWACCEL;
296 }
297 else {
298 if(verbose) printf("SDL: using hardware-surface\n");
299 priv->sdlflags = SDL_HWSURFACE|SDL_RESIZABLE|SDL_ASYNCBLIT|SDL_HWACCEL;
300 priv->sdlfullflags = SDL_HWSURFACE|SDL_FULLSCREEN|SDL_DOUBLEBUF|SDL_ASYNCBLIT|SDL_HWACCEL;
301 }
244 #endif 302 #endif
245 priv->surface = NULL; 303
246 priv->overlay = NULL; 304 /* Setup Keyrepeats */
247 priv->fullmodes = NULL; 305 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
248 priv->bpp = 0; //added atmos
249
250 /* initialize the SDL Video system */
251 if (SDL_Init (SDL_INIT_VIDEO)) {
252 // LOG (LOG_ERROR, "SDL video out: Initializing of SDL failed (SDL_Init). Please use the latest version of SDL.");
253 return -1;
254 }
255
256 /* No Keyrepeats! */
257 SDL_EnableKeyRepeat(0,0);
258 306
259 /* get information about the graphics adapter */ 307 /* get information about the graphics adapter */
260 vidInfo = SDL_GetVideoInfo (); 308 vidInfo = SDL_GetVideoInfo ();
261 309
262 /* collect all fullscreen & hardware modes available */ 310 /* collect all fullscreen & hardware modes available */
274 * That's all we have. If this fails there's nothing left. 322 * That's all we have. If this fails there's nothing left.
275 * Theoretically there could be Fullscreenmodes left - we ignore this for now. 323 * Theoretically there could be Fullscreenmodes left - we ignore this for now.
276 */ 324 */
277 priv->sdlflags &= ~SDL_HWSURFACE; 325 priv->sdlflags &= ~SDL_HWSURFACE;
278 if ((!SDL_ListModes (vidInfo->vfmt, priv->sdlflags)) && (!priv->fullmodes)) { 326 if ((!SDL_ListModes (vidInfo->vfmt, priv->sdlflags)) && (!priv->fullmodes)) {
279 // LOG (LOG_ERROR, "SDL video out: Couldn't get any acceptable SDL Mode for output. (SDL_ListModes failed)"); 327 printf("SDL: Couldn't get any acceptable SDL Mode for output.\n");
280 return -1; 328 return -1;
281 } 329 }
282 } 330 }
283 331
284 332
285 /* YUV overlays need at least 16-bit color depth, but the 333 /* YUV overlays need at least 16-bit color depth, but the
286 * display might less. The SDL AAlib target says it can only do 334 * display might less. The SDL AAlib target says it can only do
287 * 8-bits, for example. So, if the display is less than 16-bits, 335 * 8-bits, for example. So, if the display is less than 16-bits,
288 * we'll force the BPP to 16, and pray that SDL can emulate for us. 336 * we'll force the BPP to 16, and pray that SDL can emulate for us.
289 */ 337 */
338 //commented out for RGB test reasons
290 priv->bpp = vidInfo->vfmt->BitsPerPixel; 339 priv->bpp = vidInfo->vfmt->BitsPerPixel;
291 if (priv->bpp < 16) { 340 //FIXME: DO NOT ADD ANY CODE BELOW THIS OR SDL WILL CRASH WITH AALIB!
292 /* 341 if (!priv->mode && priv->bpp < 16) {
293 LOG (LOG_WARNING, "SDL video out: Your SDL display target wants to be at a color depth of (%d), but we need it to be at\ 342
343 if(verbose) printf("SDL: Your SDL display target wants to be at a color depth of (%d), but we need it to be at\
294 least 16 bits, so we need to emulate 16-bit color. This is going to slow things down; you might want to\ 344 least 16 bits, so we need to emulate 16-bit color. This is going to slow things down; you might want to\
295 increase your display's color depth, if possible", priv->bpp); 345 increase your display's color depth, if possible.\n", priv->bpp);
296 */ 346
297 priv->bpp = 16; 347 priv->bpp = 16;
298 } 348 }
299 349
300 /* We dont want those in out event queue */ 350 /* We don't want those in our event queue.
301 SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE); 351 * We use SDL_KEYUP cause SDL_KEYDOWN seems to cause problems
352 * with keys need to be pressed twice, to be recognized.
353 */
354 /*SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
302 SDL_EventState(SDL_KEYDOWN, SDL_IGNORE); 355 SDL_EventState(SDL_KEYDOWN, SDL_IGNORE);
303 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); 356 SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE);
304 SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE); 357 SDL_EventState(SDL_MOUSEBUTTONDOWN, SDL_IGNORE);
305 SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE); 358 SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE);
306 SDL_EventState(SDL_QUIT, SDL_IGNORE); 359 SDL_EventState(SDL_QUIT, SDL_IGNORE);
307 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); 360 SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE);
308 SDL_EventState(SDL_USEREVENT, SDL_IGNORE); 361 SDL_EventState(SDL_USEREVENT, SDL_IGNORE);*/
362
309 363
310 /* Success! */ 364 /* Success! */
311 return 0; 365 return 0;
312 } 366 }
313 367
325 379
326 /* Cleanup YUV Overlay structure */ 380 /* Cleanup YUV Overlay structure */
327 if (priv->overlay) 381 if (priv->overlay)
328 SDL_FreeYUVOverlay(priv->overlay); 382 SDL_FreeYUVOverlay(priv->overlay);
329 383
384 /* Free RGB Surface */
385 if (priv->rgbsurface)
386 SDL_FreeSurface(priv->rgbsurface);
387
330 /* Free our blitting surface */ 388 /* Free our blitting surface */
331 if (priv->surface) 389 if (priv->surface)
332 SDL_FreeSurface(priv->surface); 390 SDL_FreeSurface(priv->surface);
333 391
334 /* DONT attempt to free the fullscreen modes array. SDL_Quit* does this for us */ 392 /* DONT attempt to free the fullscreen modes array. SDL_Quit* does this for us */
335 393
336 /* Cleanup SDL */ 394 /* Cleanup SDL */
337 SDL_Quit(); /* might have to be changed to quitsubsystem only, if plugins become 395 SDL_Quit();
338 changeable on the fly */ 396 //SDL_QuitSubSystem(SDL_INIT_VIDEO);
339 397 /* might have to be changed to quitsubsystem only, if plugins become
340 // LOG (LOG_DEBUG, "SDL video out: Closed Plugin"); 398 * changeable on the fly */
399
400 if(verbose > 2) printf("SDL: Closed Plugin\n");
341 401
342 return 0; 402 return 0;
343 } 403 }
344 404
345 405
376 /* if we were successfull hide the mouse cursor and save the mode */ 436 /* if we were successfull hide the mouse cursor and save the mode */
377 if (newsurface) { 437 if (newsurface) {
378 priv->surface = newsurface; 438 priv->surface = newsurface;
379 SDL_ShowCursor(0); 439 SDL_ShowCursor(0);
380 } 440 }
441 //TODO: check if this produces memhole! (no surface freeing)
442 priv->vidpos.x = (priv->surface->w - priv->width) / 2;
443 priv->vidpos.y = (priv->surface->h - priv->height) / 2;
381 } 444 }
382 445
383 446
384 /** 447 /**
385 * Initialize an SDL surface and an SDL YUV overlay. 448 * Initialize an SDL surface and an SDL YUV overlay.
412 if(verbose) printf("SDL: Using 0x%X (YVYU) image format\n", format); break; 475 if(verbose) printf("SDL: Using 0x%X (YVYU) image format\n", format); break;
413 case IMGFMT_I420: 476 case IMGFMT_I420:
414 if(verbose) printf("SDL: Using 0x%X (I420) image format\n", format); 477 if(verbose) printf("SDL: Using 0x%X (I420) image format\n", format);
415 printf("SDL: Mapping I420 to IYUV\n"); 478 printf("SDL: Mapping I420 to IYUV\n");
416 sdl_format = SDL_IYUV_OVERLAY; 479 sdl_format = SDL_IYUV_OVERLAY;
417 break; 480 break;
481 case IMGFMT_BGR15:
482 if(verbose) printf("SDL: Using 0x%X (BGR15) image format\n", format);
483 priv->mode = BGR;
484 break;
485 case IMGFMT_RGB15:
486 if(verbose) printf("SDL: Using 0x%X (RGB15) image format\n", format);
487 priv->mode = RGB;
488 break;
489 case IMGFMT_BGR16:
490 if(verbose) printf("SDL: Using 0x%X (BGR16) image format\n", format);
491 priv->mode = BGR;
492 break;
493 case IMGFMT_RGB16:
494 if(verbose) printf("SDL: Using 0x%X (RGB16) image format\n", format);
495 priv->mode = RGB;
496 break;
497 case IMGFMT_BGR24:
498 if(verbose) printf("SDL: Using 0x%X (BGR24) image format\n", format);
499 priv->mode = BGR;
500 break;
501 case IMGFMT_RGB24:
502 if(verbose) printf("SDL: Using 0x%X (RGB24) image format\n", format);
503 priv->mode = RGB;
504 break;
505 case IMGFMT_BGR32:
506 if(verbose) printf("SDL: Using 0x%X (BGR32) image format\n", format);
507 priv->mode = BGR;
508 break;
509 case IMGFMT_RGB32:
510 if(verbose) printf("SDL: Using 0x%X (RGB32) image format\n", format);
511 priv->mode = RGB;
512 break;
418 default: 513 default:
419 printf("SDL: Unsupported image format (0x%X)\n",format); 514 printf("SDL: Unsupported image format (0x%X)\n",format);
420 return -1; 515 return -1;
421 } 516 }
422 517
423 sdl_open (NULL, NULL); 518 sdl_open (NULL, NULL);
424 519
425 /* Set output window title */ 520 /* Set output window title */
426 SDL_WM_SetCaption (".: MPlayer : F = Fullscreen/Windowed : C = Cycle Fullscreen Resolutions :.", "SDL Video Out"); 521 SDL_WM_SetCaption (".: MPlayer : F = Fullscreen/Windowed : C = Cycle Fullscreen Resolutions :.", "SDL Video Out");
522 //SDL_WM_SetCaption (title, title);
427 523
428 /* Save the original Image size */ 524 /* Save the original Image size */
429 525
430 priv->width = width; 526 priv->width = d_width ? d_width : width;
431 priv->height = height; 527 priv->height = d_height ? d_height : height;
432 priv->format = format; 528 priv->format = format;
529 priv->windowsize.w = d_width ? d_width : width;
530 priv->windowsize.h = d_height ? d_height : height;
433 531
434 /* bit 0 (0x01) means fullscreen (-fs) 532 /* bit 0 (0x01) means fullscreen (-fs)
435 * bit 1 (0x02) means mode switching (-vm) 533 * bit 1 (0x02) means mode switching (-vm)
436 * bit 2 (0x04) enables software scaling (-zoom) 534 * bit 2 (0x04) enables software scaling (-zoom)
437 */ 535 */
438 // printf("SDL: fullscreenflag is set to: %i\n", fullscreen); 536 // printf("SDL: fullscreenflag is set to: %i\n", fullscreen);
439 // printf("SDL: Width: %i Height: %i D_Width %i D_Height: %i\n", width, height, d_width, d_height); 537 // printf("SDL: Width: %i Height: %i D_Width %i D_Height: %i\n", width, height, d_width, d_height);
440 switch(fullscreen){ 538 switch(fullscreen){
441 case 0x01: 539 case 0x01:
442 case 0x05: 540 case 0x05:
541 priv->width = width;
542 priv->height = height;
443 if(verbose) printf("SDL: setting zoomed fullscreen without modeswitching\n"); 543 if(verbose) printf("SDL: setting zoomed fullscreen without modeswitching\n");
444 priv->windowsize.w = d_width; 544 printf("SDL: Info - please use -vm (unscaled) or -zoom (scaled) for best fullscreen experience\n");
445 priv->windowsize.h = d_height;
446 if((priv->surface = SDL_SetVideoMode (d_width, d_height, priv->bpp, priv->sdlfullflags))) 545 if((priv->surface = SDL_SetVideoMode (d_width, d_height, priv->bpp, priv->sdlfullflags)))
447 SDL_ShowCursor(0); 546 SDL_ShowCursor(0);
448 break; 547 break;
449 case 0x02: 548 case 0x02:
450 case 0x03:
451 priv->windowsize.w = width;
452 priv->windowsize.h = height;
453 #ifdef SDL_NOXV
454 if(verbose) printf("SDL: setting nonzoomed fullscreen with modeswitching\n"); 549 if(verbose) printf("SDL: setting nonzoomed fullscreen with modeswitching\n");
455 if(priv->surface = SDL_SetVideoMode (width, height, priv->bpp, priv->sdlfullflags)) 550 printf("SDL: Info - please use -zoom switch to scale video\n");
551 if((priv->surface = SDL_SetVideoMode (d_width ? d_width : width, d_height ? d_height : height, priv->bpp, priv->sdlfullflags)))
456 SDL_ShowCursor(0); 552 SDL_ShowCursor(0);
457 #else 553 break;
554 case 0x04:
555 case 0x06:
458 if(verbose) printf("SDL: setting zoomed fullscreen with modeswitching\n"); 556 if(verbose) printf("SDL: setting zoomed fullscreen with modeswitching\n");
459 priv->surface=NULL; 557 printf("SDL: Info - please use -vm switch instead if you don't want scaled video\n");
460 set_fullmode(priv->fullmode);
461 #endif
462 break;
463 case 0x06:
464 case 0x07:
465 if(verbose) printf("SDL: setting zoomed fullscreen with modeswitching\n");
466 priv->windowsize.w = width;
467 priv->windowsize.h = height;
468 priv->surface=NULL; 558 priv->surface=NULL;
469 set_fullmode(priv->fullmode); 559 set_fullmode(priv->fullmode);
470 break; 560 break;
471 default: 561 default:
472 if(verbose) printf("SDL: setting windowed mode\n"); 562 if(verbose) printf("SDL: setting windowed mode\n");
473 priv->windowsize.w = d_width; 563 if((priv->surface = SDL_SetVideoMode (d_width, d_height, priv->bpp, priv->sdlflags))
474 priv->windowsize.h = d_height; 564 && (strcmp(priv->driver, "dga") == 0)) SDL_ShowCursor(0); //TODO: other sdl drivers that are fullscreen only?
475 priv->surface = SDL_SetVideoMode (d_width, d_height, priv->bpp, priv->sdlflags);
476 } 565 }
477 if(!priv->surface) return -1; // cannot SetVideoMode 566 if(!priv->surface) { // cannot SetVideoMode
478 567 printf("SDL: failed to set video mode: %s\n", SDL_GetError());
479 /* Initialize and create the YUV Overlay used for video out */
480 if (!(priv->overlay = SDL_CreateYUVOverlay (width, height, sdl_format, priv->surface))) {
481 printf ("SDL video out: Couldn't create an SDL-based YUV overlay\n");
482 return -1; 568 return -1;
569 }
570
571 switch(format) {
572 /* Initialize and create the RGB Surface used for video out in BGR/RGB mode */
573 //SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
574 // SDL_SWSURFACE,SDL_HWSURFACE,SDL_SRCCOLORKEY, priv->flags? guess: exchange Rmask and Bmask for BGR<->RGB
575 // 32 bit: a:ff000000 r:ff000 g:ff00 b:ff
576 // 24 bit: r:ff0000 g:ff00 b:ff
577 // 16 bit: r:1111100000000000b g:0000011111100000b b:0000000000011111b
578 // 15 bit: r:111110000000000b g:000001111100000b b:000000000011111b
579 // FIXME: colorkey detect based on bpp, FIXME static bpp value, FIXME alpha value correct?
580 case IMGFMT_RGB15:
581 if (!(priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, width, height, 15, 31, 992, 31744, 0))) {
582 printf ("SDL: Couldn't create a RGB surface: %s\n", SDL_GetError());
583 return -1;
584 }
585 break;
586 case IMGFMT_BGR15:
587 if (!(priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, width, height, 15, 31744, 992, 31, 0))) {
588 printf ("SDL: Couldn't create a RGB surface: %s\n", SDL_GetError());
589 return -1;
590 }
591 break;
592 case IMGFMT_RGB16:
593 if (!(priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, width, height, 16, 31, 2016, 63488, 0))) {
594 printf ("SDL: Couldn't create a RGB surface: %s\n", SDL_GetError());
595 return -1;
596 }
597 break;
598 case IMGFMT_BGR16:
599 if (!(priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, width, height, 16, 63488, 2016, 31, 0))) {
600 printf ("SDL: Couldn't create a RGB surface: %s\n", SDL_GetError());
601 return -1;
602 }
603 break;
604 case IMGFMT_RGB24:
605 if (!(priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, width, height, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0))) {
606 printf ("SDL: Couldn't create a RGB surface: %s\n", SDL_GetError());
607 return -1;
608 }
609 break;
610 case IMGFMT_BGR24:
611 if (!(priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, width, height, 24, 0xFF0000, 0x00FF00, 0x0000FF, 0))) {
612 printf ("SDL: Couldn't create a RGB surface: %s\n", SDL_GetError());
613 return -1;
614 }
615 break;
616 case IMGFMT_RGB32:
617 if (!(priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, width, height, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000))) {
618 printf ("SDL: Couldn't create a RGB surface: %s\n", SDL_GetError());
619 return -1;
620 }
621 break;
622 case IMGFMT_BGR32:
623 if (!(priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, width, height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000))) {
624 printf ("SDL: Couldn't create a RGB surface: %s\n", SDL_GetError());
625 return -1;
626 }
627 break;
628 default:
629 /* Initialize and create the YUV Overlay used for video out */
630 if (!(priv->overlay = SDL_CreateYUVOverlay (width, height, sdl_format, priv->surface))) {
631 printf ("SDL: Couldn't create a YUV overlay: %s\n", SDL_GetError());
632 return -1;
633 }
634 priv->framePlaneY = width * height;
635 priv->framePlaneUV = (width * height) >> 2;
636 priv->stridePlaneY = width;
637 priv->stridePlaneUV = width/2;
483 } 638 }
484 priv->framePlaneY = width * height; 639
485 priv->framePlaneUV = (width * height) >> 2; 640 if(priv->mode) {
486 priv->stridePlaneY = width; 641 priv->framePlaneRGB = width * height * priv->rgbsurface->format->BytesPerPixel;
487 priv->stridePlaneUV = width/2; 642 }
488
489 return 0; 643 return 0;
490 } 644 }
491 645
492 646
493 /** 647 /**
500 //static int sdl_draw_frame (frame_t *frame) 654 //static int sdl_draw_frame (frame_t *frame)
501 static uint32_t draw_frame(uint8_t *src[]) 655 static uint32_t draw_frame(uint8_t *src[])
502 { 656 {
503 struct sdl_priv_s *priv = &sdl_priv; 657 struct sdl_priv_s *priv = &sdl_priv;
504 uint8_t *dst; 658 uint8_t *dst;
505 659
506 // priv->current_frame = (SDL_Overlay*) frame->private;
507 // SDL_UnlockYUVOverlay (priv->current_frame);
508
509 if (SDL_LockYUVOverlay (priv->overlay)) {
510 // LOG (LOG_ERROR, "SDL video out: Couldn't lock SDL-based YUV overlay");
511 return -1;
512 }
513
514 switch(priv->format){ 660 switch(priv->format){
515 case IMGFMT_YV12: 661 case IMGFMT_YV12:
516 case IMGFMT_I420: 662 case IMGFMT_I420:
517 case IMGFMT_IYUV: 663 case IMGFMT_IYUV:
664 /*if (SDL_LockYUVOverlay (priv->overlay)) {
665 if(verbose) printf("SDL: Couldn't lock YUV overlay\n");
666 return -1;
667 }*/
518 dst = (uint8_t *) *(priv->overlay->pixels); 668 dst = (uint8_t *) *(priv->overlay->pixels);
519 memcpy (dst, src[0], priv->framePlaneY); 669 memcpy (dst, src[0], priv->framePlaneY);
520 dst += priv->framePlaneY; 670 dst += priv->framePlaneY;
521 memcpy (dst, src[2], priv->framePlaneUV); 671 memcpy (dst, src[2], priv->framePlaneUV);
522 dst += priv->framePlaneUV; 672 dst += priv->framePlaneUV;
523 memcpy (dst, src[1], priv->framePlaneUV); 673 memcpy (dst, src[1], priv->framePlaneUV);
674 /*SDL_UnlockYUVOverlay (priv->overlay);*/
524 break; 675 break;
525 676
526 case IMGFMT_YUY2: 677 case IMGFMT_YUY2:
527 case IMGFMT_UYVY: 678 case IMGFMT_UYVY:
528 case IMGFMT_YVYU: 679 case IMGFMT_YVYU:
680 /*if (SDL_LockYUVOverlay (priv->overlay)) {
681 if(verbose) printf("SDL: Couldn't lock YUV overlay\n");
682 return -1;
683 }*/
529 dst = (uint8_t *) *(priv->overlay->pixels); 684 dst = (uint8_t *) *(priv->overlay->pixels);
530 memcpy (dst, src[0], priv->width*priv->height*2); 685 memcpy (dst, src[0], priv->width*priv->height*2);
686 /*SDL_UnlockYUVOverlay (priv->overlay);*/
531 break; 687 break;
688
689 case IMGFMT_RGB15:
690 case IMGFMT_BGR15:
691 case IMGFMT_RGB16:
692 case IMGFMT_BGR16:
693 case IMGFMT_RGB24:
694 case IMGFMT_BGR24:
695 case IMGFMT_RGB32:
696 case IMGFMT_BGR32:
697 /*if(SDL_MUSTLOCK(priv->rgbsurface)) {
698 if (SDL_LockSurface (priv->rgbsurface)) {
699 if(verbose) printf("SDL: Couldn't lock RGB surface\n");
700 return -1;
701 }
702 }*/
703 dst = (uint8_t *) priv->rgbsurface->pixels;
704 memcpy (dst, src[0], priv->framePlaneRGB);
705 /*if(SDL_MUSTLOCK(priv->rgbsurface))
706 SDL_UnlockSurface (priv->rgbsurface);*/
707 break;
708
532 } 709 }
533 710
534 SDL_UnlockYUVOverlay (priv->overlay);
535 return 0; 711 return 0;
536 } 712 }
537 713
538 714
539 /** 715 /**
549 struct sdl_priv_s *priv = &sdl_priv; 725 struct sdl_priv_s *priv = &sdl_priv;
550 uint8_t *dst; 726 uint8_t *dst;
551 uint8_t *src; 727 uint8_t *src;
552 int i; 728 int i;
553 729
554 //priv->current_frame = priv->overlay; 730 /*if (SDL_LockYUVOverlay (priv->overlay)) {
555 731 if(verbose) printf("SDL: Couldn't lock YUV overlay");
556 if (SDL_LockYUVOverlay (priv->overlay)) {
557 // LOG (LOG_ERROR, "SDL video out: Couldn't lock SDL-based YUV overlay");
558 return -1; 732 return -1;
559 } 733 }*/
560 734
561 dst = (uint8_t *) *(priv->overlay->pixels) 735 dst = (uint8_t *) *(priv->overlay->pixels)
562 + (priv->stridePlaneY * y + x); 736 + (priv->stridePlaneY * y + x);
563 src = image[0]; 737 src = image[0];
564 for(i=0;i<h;i++){ 738 for(i=0;i<h;i++){
585 memcpy(dst,src,w); 759 memcpy(dst,src,w);
586 src+=stride[1]; 760 src+=stride[1];
587 dst+=priv->stridePlaneUV; 761 dst+=priv->stridePlaneUV;
588 } 762 }
589 763
590 #if 0 764 /*SDL_UnlockYUVOverlay (priv->overlay);*/
591 dst = (uint8_t *) *(priv->overlay->pixels) + (priv->slicePlaneY * slice_num);
592 memcpy (dst, src[0], priv->slicePlaneY);
593 dst = (uint8_t *) *(priv->overlay->pixels) + priv->framePlaneY + (priv->slicePlaneUV * slice_num);
594 memcpy (dst, src[2], priv->slicePlaneUV);
595 dst += priv->framePlaneUV;
596 memcpy (dst, src[1], priv->slicePlaneUV);
597 #endif
598
599 SDL_UnlockYUVOverlay (priv->overlay);
600 765
601 return 0; 766 return 0;
602 } 767 }
603 768
604 769
631 /* save video extents, to restore them after going fullscreen */ 796 /* save video extents, to restore them after going fullscreen */
632 //if(!(priv->surface->flags & SDL_FULLSCREEN)) { 797 //if(!(priv->surface->flags & SDL_FULLSCREEN)) {
633 priv->windowsize.w = priv->surface->w; 798 priv->windowsize.w = priv->surface->w;
634 priv->windowsize.h = priv->surface->h; 799 priv->windowsize.h = priv->surface->h;
635 //} 800 //}
636 // LOG (LOG_DEBUG, "SDL video out: Window resize"); 801 if(verbose > 2) printf("SDL: Window resize\n");
637 break; 802 break;
638 803
639 804
640 /* graphics mode selection shortcuts */ 805 /* graphics mode selection shortcuts */
641 case SDL_KEYUP: 806 case SDL_KEYDOWN:
807 switch(event.key.keysym.sym) {
808 case SDLK_UP: mplayer_put_key(KEY_UP);break;
809 case SDLK_DOWN: mplayer_put_key(KEY_DOWN);break;
810 case SDLK_LEFT: mplayer_put_key(KEY_LEFT);break;
811 case SDLK_RIGHT: mplayer_put_key(KEY_RIGHT);break;
812 }
813 break;
814 case SDL_KEYUP:
642 keypressed = event.key.keysym.sym; 815 keypressed = event.key.keysym.sym;
643 816
644 /* c key pressed. c cycles through available fullscreenmodes, if we have some */ 817 /* c key pressed. c cycles through available fullscreenmodes, if we have some */
645 if ( ((keypressed == SDLK_c)) && (priv->fullmodes) ) { 818 if ( ((keypressed == SDLK_c)) && (priv->fullmodes) ) {
646 /* select next fullscreen mode */ 819 /* select next fullscreen mode */
647 priv->fullmode++; 820 priv->fullmode++;
648 if (priv->fullmode > (findArrayEnd(priv->fullmodes) - 1)) priv->fullmode = 0; 821 if (priv->fullmode > (findArrayEnd(priv->fullmodes) - 1)) priv->fullmode = 0;
649 set_fullmode(priv->fullmode); 822 set_fullmode(priv->fullmode);
650 823
651 // LOG (LOG_DEBUG, "SDL video out: Set next available fullscreen mode."); 824 if(verbose > 1) printf("SDL: Set next available fullscreen mode.\n");
652 } 825 }
653 826
654 /* f key pressed toggles/exits fullscreenmode */ 827 /* f key pressed toggles/exits fullscreenmode */
655 else if ( keypressed == SDLK_f ) { 828 else if ( keypressed == SDLK_f ) {
656 if (priv->surface->flags & SDL_FULLSCREEN) { 829 if (priv->surface->flags & SDL_FULLSCREEN) {
657 priv->surface = SDL_SetVideoMode(priv->windowsize.w, priv->windowsize.h, priv->bpp, priv->sdlflags); 830 priv->surface = SDL_SetVideoMode(priv->windowsize.w, priv->windowsize.h, priv->bpp, priv->sdlflags);
658 SDL_ShowCursor(1); 831 SDL_ShowCursor(1);
659 // LOG (LOG_DEBUG, "SDL video out: Windowed mode"); 832 if(verbose > 1) printf("SDL: Windowed mode\n");
660 } 833 }
661 else if (priv->fullmodes){ 834 else if (priv->fullmodes){
662 set_fullmode(priv->fullmode); 835 set_fullmode(priv->fullmode);
663 836
664 // LOG (LOG_DEBUG, "SDL video out: Set fullscreen mode."); 837 if(verbose > 1) printf("SDL: Set fullscreen mode\n");
665 } 838 }
666 } 839 }
667 840
668 else switch(keypressed){ 841 else switch(keypressed){
669 // case SDLK_q: if(!(priv->surface->flags & SDL_FULLSCREEN))mplayer_put_key('q');break;
670 case SDLK_RETURN: 842 case SDLK_RETURN:
671 if (!firstcheck) { firstcheck = 1; break; } 843 if (!firstcheck) { firstcheck = 1; break; }
672 case SDLK_ESCAPE: 844 case SDLK_ESCAPE:
673 case SDLK_q: 845 case SDLK_q:
674 SDL_ShowCursor(1); 846 SDL_ShowCursor(1);
675 mplayer_put_key('q'); 847 mplayer_put_key('q');
676 break; 848 break;
677 /*case SDLK_o: mplayer_put_key('o');break; 849 /*case SDLK_o: mplayer_put_key('o');break;
678 case SDLK_SPACE: mplayer_put_key(' ');break; 850 case SDLK_SPACE: mplayer_put_key(' ');break;
679 case SDLK_p: mplayer_put_key('p');break;*/ 851 case SDLK_p: mplayer_put_key('p');break;*/
680 case SDLK_UP: mplayer_put_key(KEY_UP);break;
681 case SDLK_DOWN: mplayer_put_key(KEY_DOWN);break;
682 case SDLK_LEFT: mplayer_put_key(KEY_LEFT);break;
683 case SDLK_RIGHT: mplayer_put_key(KEY_RIGHT);break;
684 case SDLK_PLUS: 852 case SDLK_PLUS:
685 case SDLK_KP_PLUS: mplayer_put_key('+');break; 853 case SDLK_KP_PLUS: mplayer_put_key('+');break;
686 case SDLK_MINUS: 854 case SDLK_MINUS:
687 case SDLK_KP_MINUS: mplayer_put_key('-');break; 855 case SDLK_KP_MINUS: mplayer_put_key('-');break;
688 case SDLK_ASTERISK: 856 case SDLK_ASTERISK:
709 **/ 877 **/
710 878
711 static void flip_page (void) 879 static void flip_page (void)
712 { 880 {
713 struct sdl_priv_s *priv = &sdl_priv; 881 struct sdl_priv_s *priv = &sdl_priv;
714 882 SDL_Surface *blitconv; // temporary conversion surface
715 //vo_draw_alpha_yuy2(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride) 883
884 /* update osd/subtitles */
716 vo_draw_text(priv->width,priv->height,draw_alpha); 885 vo_draw_text(priv->width,priv->height,draw_alpha);
717 886
718 /* check and react on keypresses and window resizes */ 887 /* check and react on keypresses and window resizes */
719 check_events(); 888 check_events();
720 889
721 /* blit to the YUV overlay */ 890 switch(priv->format) {
722 SDL_DisplayYUVOverlay (priv->overlay, &priv->surface->clip_rect); 891 case IMGFMT_RGB15:
723 892 case IMGFMT_BGR15:
724 /* check if we have a double buffered surface and flip() if we do. */ 893 case IMGFMT_RGB16:
725 if ( priv->surface->flags & SDL_DOUBLEBUF ) 894 case IMGFMT_BGR16:
726 SDL_Flip(priv->surface); 895 case IMGFMT_RGB24:
727 896 case IMGFMT_BGR24:
728 SDL_LockYUVOverlay (priv->overlay); 897 case IMGFMT_RGB32:
729 } 898 case IMGFMT_BGR32:
730 899 /* blit to the RGB surface */
731 #if 0 900 blitconv = SDL_DisplayFormat(priv->rgbsurface);
732 static frame_t* sdl_allocate_image_buffer(int width, int height) 901 if(SDL_BlitSurface (blitconv, NULL, priv->surface, &priv->vidpos))
733 { 902 printf("SDL: Blit failed: %s\n", SDL_GetError());
734 struct sdl_priv_s *priv = &sdl_priv; 903 SDL_FreeSurface(blitconv);
735 frame_t *frame; 904
736 905 /*if(SDL_MUSTLOCK(priv->surface)) {
737 if (!(frame = malloc (sizeof (frame_t)))) 906 if (SDL_LockSurface (priv->surface)) {
738 return NULL; 907 if(verbose) printf("SDL: Couldn't lock RGB surface\n");
739 908 return;
740 if (!(frame->private = (void*) SDL_CreateYUVOverlay (width, height, 909 }
741 SDL_IYUV_OVERLAY, priv->surface))) 910 }*/
742 { 911 /* update screen */
743 // LOG (LOG_ERROR, "SDL video out: Couldn't create an SDL-based YUV overlay"); 912 SDL_UpdateRect(priv->surface, priv->vidpos.x, priv->vidpos.y, priv->width, priv->height);
744 return NULL; 913 /*if(SDL_MUSTLOCK(priv->surface))
745 } 914 SDL_UnlockSurface (priv->surface);*/
746 915
747 frame->base[0] = (uint8_t*) ((SDL_Overlay*) (frame->private))->pixels[0]; 916 /* check if we have a double buffered surface and flip() if we do. */
748 frame->base[1] = (uint8_t*) ((SDL_Overlay*) (frame->private))->pixels[1]; 917 if ( priv->surface->flags & SDL_DOUBLEBUF )
749 frame->base[2] = (uint8_t*) ((SDL_Overlay*) (frame->private))->pixels[2]; 918 SDL_Flip(priv->surface);
750 919
751 SDL_LockYUVOverlay ((SDL_Overlay*) frame->private); 920 break;
752 return frame; 921 default:
753 } 922 /* blit to the YUV overlay */
754 923 SDL_DisplayYUVOverlay (priv->overlay, &priv->surface->clip_rect);
755 static void sdl_free_image_buffer(frame_t* frame) 924
756 { 925 /* check if we have a double buffered surface and flip() if we do. */
757 SDL_FreeYUVOverlay((SDL_Overlay*) frame->private); 926 if ( priv->surface->flags & SDL_DOUBLEBUF )
758 free(frame); 927 SDL_Flip(priv->surface);
759 } 928
760 #endif 929 //SDL_LockYUVOverlay (priv->overlay); // removed because unused!?
930 }
931 }
761 932
762 static uint32_t 933 static uint32_t
763 query_format(uint32_t format) 934 query_format(uint32_t format)
764 { 935 {
765 switch(format){ 936 switch(format){
767 case IMGFMT_I420: 938 case IMGFMT_I420:
768 case IMGFMT_IYUV: 939 case IMGFMT_IYUV:
769 case IMGFMT_YUY2: 940 case IMGFMT_YUY2:
770 case IMGFMT_UYVY: 941 case IMGFMT_UYVY:
771 case IMGFMT_YVYU: 942 case IMGFMT_YVYU:
772 // case IMGFMT_RGB|24: 943 return 0x6; // hw supported & osd
773 // case IMGFMT_BGR|24: 944 case IMGFMT_RGB15:
774 return 1; 945 case IMGFMT_BGR15:
946 case IMGFMT_RGB16:
947 case IMGFMT_BGR16:
948 case IMGFMT_RGB24:
949 case IMGFMT_BGR24:
950 case IMGFMT_RGB32:
951 case IMGFMT_BGR32:
952 return 0x5; // hw supported w/conversion & osd
775 } 953 }
776 return 0; 954 return 0;
777 } 955 }
778 956
779 static const vo_info_t* 957 static const vo_info_t*