2001-02-24 20:28:24 +00:00
/*
2001-04-11 13:46:56 +00:00
* vo_sdl . c
*
2001-04-22 17:03:26 +00:00
* ( was video_out_sdl . c from OMS project / mpeg2dec - > http : //linuxvideo.org)
2001-02-24 20:28:24 +00:00
*
* Copyright ( C ) Ryan C . Gordon < icculus @ lokigames . com > - April 22 , 2000.
*
2001-04-25 20:43:45 +00:00
* Copyright ( C ) Felix Buenemann < atmosfear @ users . sourceforge . net > - 2001
*
* ( for extensive code enhancements )
*
2001-04-22 17:03:26 +00:00
* Current maintainer for MPlayer project ( report bugs to that address ) :
* Felix Buenemann < atmosfear @ users . sourceforge . net >
*
* This file is a video out driver using the SDL library ( http : //libsdl.org/),
2001-04-22 17:07:57 +00:00
* to be used with MPlayer [ The Movie Player for Linux ] project , further info
2001-04-22 17:03:26 +00:00
* from http : //mplayer.sourceforge.net.
*
* Current license is not decided yet , but we ' re heading for GPL .
*
* - - old disclaimer - -
*
2001-02-24 20:28:24 +00:00
* A mpeg2dec display driver that does output through the
* Simple DirectMedia Layer ( SDL ) library . This effectively gives us all
* sorts of output options : X11 , SVGAlib , fbcon , AAlib , GGI . Win32 , MacOS
* and BeOS support , too . Yay . SDL info , source , and binaries can be found
* at http : //slouken.devolution.com/SDL/
*
* This file is part of mpeg2dec , a free MPEG - 2 video stream decoder .
*
* mpeg2dec is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 , or ( at your option )
* any later version .
*
* mpeg2dec is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with GNU Make ; see the file COPYING . If not , write to
2001-04-22 17:03:26 +00:00
* the Free Software Foundation .
*
* - - end old disclaimer - -
2001-02-24 20:28:24 +00:00
*
* Changes :
* Dominik Schnitzer < dominik @ schnitzer . at > - November 08 , 2000.
2001-03-11 17:17:03 +00:00
* - Added resizing support , fullscreen : changed the sdlmodes selection
2001-02-24 20:28:24 +00:00
* routine .
* - SDL bugfixes : removed the atexit ( SLD_Quit ) , SDL_Quit now resides in
* the plugin_exit routine .
* - Commented the source : )
* - Shortcuts : for switching between Fullscreen / Windowed mode and for
* cycling between the different Fullscreen modes .
* - Small bugfixes : proper width / height of movie
* Dominik Schnitzer < dominik @ schnitzer . at > - November 11 , 2000.
* - Cleanup code , more comments
* - Better error handling
* Bruno Barreyra < barreyra @ ufl . edu > - December 10 , 2000.
* - Eliminated memcpy ' s for entire frames
2001-04-22 17:03:26 +00:00
* Felix Buenemann < Atmosfear @ users . sourceforge . net > - March 11 , 2001
2001-03-11 17:17:03 +00:00
* - Added aspect - ratio awareness for fullscreen
2001-04-22 17:03:26 +00:00
* Felix Buenemann < Atmosfear @ users . sourceforge . net > - March 11 , 2001
2001-03-12 17:20:48 +00:00
* - Fixed aspect - ratio awareness , did only vertical scaling ( black bars above
* and below ) , now also does horizontal scaling ( black bars left and right ) ,
* so you get the biggest possible picture with correct aspect - ratio .
* Felix Buenemann < Atmosfear @ users . sourceforge . net > - March 12 , 2001
2001-04-22 17:03:26 +00:00
* - Minor bugfix to aspect - ratio for non - 4 : 3 - resolutions ( like 1280 x1024 )
2001-03-12 17:20:48 +00:00
* - Bugfix to check_events ( ) to reveal mouse cursor after ' q ' - quit in
* fullscreen - mode
2001-04-11 13:46:56 +00:00
* Felix Buenemann < Atmosfear @ users . sourceforge . net > - April 10 , 2001
2001-04-10 21:41:31 +00:00
* - Changed keypress - detection from keydown to keyup , seems to fix keyrepeat
* bug ( key had to be pressed twice to be detected )
* - Changed key - handling : ' f ' cycles fullscreen / windowed , ESC / RETURN / ' q ' quits
* - Bugfix which avoids exit , because return is passed to sdl - output on startup ,
* which caused the player to exit ( keyboard - buffer problem ? better solution
* recommed )
2001-04-11 13:46:56 +00:00
* Felix Buenemann < Atmosfear @ users . sourceforge . net > - April 11 , 2001
* - OSD and subtitle support added
* - some minor code - changes
2001-04-11 20:00:55 +00:00
* - added code to comply with new fullscreen meaning
* - changed fullscreen - mode - cycling from ' + ' to ' c ' ( interferred with audiosync
* adjustment )
2001-04-13 13:00:07 +00:00
* Felix Buenemann < Atmosfear @ users . sourceforge . net > - April 13 , 2001
* - added keymapping to toggle OSD ( ' o ' key )
2001-04-13 21:04:13 +00:00
* - added some defines to modify some sdl - out internas ( see comments )
2001-04-16 17:19:28 +00:00
*
* Felix Buenemann : further changes will be visible through cvs log , don ' t want
2001-04-22 17:03:26 +00:00
* to update this all the time ( CVS info on http : //mplayer.sourceforge.net)
*
2001-02-24 20:28:24 +00:00
*/
2001-04-20 09:06:49 +00:00
/* define to force software-surface (video surface stored in system memory)*/
# undef SDL_NOHWSURFACE
2001-06-23 10:18:23 +00:00
/* define to enable surface locks, this might be needed on SMP machines */
# undef SDL_ENABLE_LOCKS
2001-05-05 21:38:33 +00:00
//#define BUGGY_SDL //defined by configure
2001-05-13 16:38:33 +00:00
/* MONITOR_ASPECT MUST BE FLOAT */
# define MONITOR_ASPECT 4.0 / 3.0
2001-02-24 20:28:24 +00:00
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <inttypes.h>
2001-06-11 17:41:21 +00:00
# include "../config.h"
2001-02-24 20:28:24 +00:00
# include "video_out.h"
# include "video_out_internal.h"
2001-04-11 19:41:38 +00:00
# include "fastmemcpy.h"
2001-04-24 11:42:04 +00:00
# include "sub.h"
2001-10-04 11:42:21 +00:00
# include "aspect.h"
2001-04-11 12:47:45 +00:00
2001-05-11 21:36:30 +00:00
# ifdef HAVE_X11
# include <X11/Xlib.h>
# include "x11_common.h"
# endif
2001-02-24 20:28:24 +00:00
LIBVO_EXTERN ( sdl )
2001-04-20 10:27:51 +00:00
extern int verbose ;
2001-04-25 20:43:45 +00:00
int sdl_noxv ;
int sdl_forcexv ;
2001-04-20 10:27:51 +00:00
2001-02-24 20:28:24 +00:00
static vo_info_t vo_info =
{
2001-04-25 20:43:45 +00:00
" SDL YUV/RGB/BGR renderer (SDL v1.1.7+ only!) " ,
2001-02-24 20:28:24 +00:00
" sdl " ,
2001-04-25 20:43:45 +00:00
" Ryan C. Gordon <icculus@lokigames.com>, Felix Buenemann <atmosfear@users.sourceforge.net> " ,
2001-02-24 20:28:24 +00:00
" "
} ;
2001-06-27 11:40:15 +00:00
# include <SDL.h>
2001-12-19 11:50:05 +00:00
//#include <SDL/SDL_syswm.h>
2001-06-05 18:40:44 +00:00
# if defined(sun) && defined(__svr4__)
/* setenv is missing on solaris */
static void setenv ( const char * name , const char * val , int _xx )
{
int len = strlen ( name ) + strlen ( val ) + 2 ;
char * env = malloc ( len ) ;
if ( env ! = NULL ) {
strcpy ( env , name ) ;
strcat ( env , " = " ) ;
strcat ( env , val ) ;
putenv ( env ) ;
}
}
# endif
2001-05-13 16:38:33 +00:00
# define FS 0x01
# define VM 0x02
# define ZOOM 0x04
# define FLIP 0x08
2001-02-24 20:28:24 +00:00
/** Private SDL Data structure **/
static struct sdl_priv_s {
2001-04-25 20:43:45 +00:00
/* output driver used by sdl */
char driver [ 8 ] ;
/* SDL display surface */
2001-02-24 20:28:24 +00:00
SDL_Surface * surface ;
2001-04-25 20:43:45 +00:00
/* SDL RGB surface */
SDL_Surface * rgbsurface ;
/* SDL YUV overlay */
2001-02-24 20:28:24 +00:00
SDL_Overlay * overlay ;
2001-04-25 20:43:45 +00:00
2001-02-24 20:28:24 +00:00
/* available fullscreen modes */
SDL_Rect * * fullmodes ;
/* surface attributes for fullscreen and windowed mode */
Uint32 sdlflags , sdlfullflags ;
/* save the windowed output extents */
SDL_Rect windowsize ;
/* Bits per Pixel */
Uint8 bpp ;
2001-04-25 20:43:45 +00:00
/* RGB or YUV? */
Uint8 mode ;
# define YUV 0
# define RGB 1
# define BGR 2
2001-06-24 19:20:19 +00:00
/* use direct blitting to surface */
int dblit ;
2001-02-24 20:28:24 +00:00
/* current fullscreen mode, 0 = highest available fullscreen mode */
int fullmode ;
/* YUV ints */
2001-05-13 16:38:33 +00:00
int framePlaneY , framePlaneUV , framePlaneYUY ;
int stridePlaneY , stridePlaneUV , stridePlaneYUY ;
2001-04-25 20:43:45 +00:00
/* RGB ints */
int framePlaneRGB ;
2001-05-11 21:36:30 +00:00
int stridePlaneRGB ;
/* Flip image */
int flip ;
2001-05-13 16:38:33 +00:00
/* fullscreen behaviour; see init */
int fulltype ;
2001-06-02 22:12:28 +00:00
/* is X running (0/1) */
int X ;
2001-05-13 16:38:33 +00:00
# ifdef HAVE_X11
/* X11 Resolution */
int XWidth , XHeight ;
# endif
2001-04-25 20:43:45 +00:00
2001-05-13 16:38:33 +00:00
/* original image dimensions */
int width , height ;
/* destination dimensions */
int dstwidth , dstheight ;
/* source image format (YUV/RGB/...) */
2001-02-24 20:28:24 +00:00
int format ;
} sdl_priv ;
2001-04-11 13:46:56 +00:00
/** libvo Plugin functions **/
/**
* draw_alpha is used for osd and subtitle display .
*
* */
static void draw_alpha ( int x0 , int y0 , int w , int h , unsigned char * src , unsigned char * srca , int stride ) {
2001-04-14 17:55:20 +00:00
struct sdl_priv_s * priv = & sdl_priv ;
2001-04-11 13:46:56 +00:00
2001-04-14 17:55:20 +00:00
switch ( priv - > format ) {
case IMGFMT_YV12 :
case IMGFMT_I420 :
case IMGFMT_IYUV :
vo_draw_alpha_yv12 ( w , h , src , srca , stride , ( ( uint8_t * ) * ( priv - > overlay - > pixels ) ) + priv - > width * y0 + x0 , priv - > width ) ;
break ;
case IMGFMT_YUY2 :
case IMGFMT_YVYU :
vo_draw_alpha_yuy2 ( w , h , src , srca , stride , ( ( uint8_t * ) * ( priv - > overlay - > pixels ) ) + 2 * ( priv - > width * y0 + x0 ) , 2 * priv - > width ) ;
break ;
2001-04-15 21:08:11 +00:00
case IMGFMT_UYVY :
vo_draw_alpha_yuy2 ( w , h , src , srca , stride , ( ( uint8_t * ) * ( priv - > overlay - > pixels ) ) + 2 * ( priv - > width * y0 + x0 ) + 1 , 2 * priv - > width ) ;
2001-04-25 20:43:45 +00:00
break ;
2001-06-22 19:56:41 +00:00
default :
2001-06-24 19:20:19 +00:00
if ( priv - > dblit )
2001-06-22 19:56:41 +00:00
switch ( priv - > format ) {
2001-05-17 15:11:58 +00:00
case IMGFMT_RGB15 :
case IMGFMT_BGR15 :
vo_draw_alpha_rgb15 ( w , h , src , srca , stride , ( ( uint8_t * ) priv - > surface - > pixels ) + 2 * ( y0 * priv - > width + x0 ) , 2 * priv - > width ) ;
break ;
case IMGFMT_RGB16 :
case IMGFMT_BGR16 :
vo_draw_alpha_rgb16 ( w , h , src , srca , stride , ( ( uint8_t * ) priv - > surface - > pixels ) + 2 * ( y0 * priv - > width + x0 ) , 2 * priv - > width ) ;
break ;
case IMGFMT_RGB24 :
case IMGFMT_BGR24 :
vo_draw_alpha_rgb24 ( w , h , src , srca , stride , ( ( uint8_t * ) priv - > surface - > pixels ) + 3 * ( y0 * priv - > width + x0 ) , 3 * priv - > width ) ;
break ;
case IMGFMT_RGB32 :
case IMGFMT_BGR32 :
vo_draw_alpha_rgb32 ( w , h , src , srca , stride , ( ( uint8_t * ) priv - > surface - > pixels ) + 4 * ( y0 * priv - > width + x0 ) , 4 * priv - > width ) ;
break ;
2001-06-22 19:56:41 +00:00
}
else
switch ( priv - > format ) {
2001-04-25 20:43:45 +00:00
case IMGFMT_RGB15 :
case IMGFMT_BGR15 :
vo_draw_alpha_rgb15 ( w , h , src , srca , stride , ( ( uint8_t * ) priv - > rgbsurface - > pixels ) + 2 * ( y0 * priv - > width + x0 ) , 2 * priv - > width ) ;
break ;
case IMGFMT_RGB16 :
case IMGFMT_BGR16 :
vo_draw_alpha_rgb16 ( w , h , src , srca , stride , ( ( uint8_t * ) priv - > rgbsurface - > pixels ) + 2 * ( y0 * priv - > width + x0 ) , 2 * priv - > width ) ;
break ;
case IMGFMT_RGB24 :
case IMGFMT_BGR24 :
vo_draw_alpha_rgb24 ( w , h , src , srca , stride , ( ( uint8_t * ) priv - > rgbsurface - > pixels ) + 3 * ( y0 * priv - > width + x0 ) , 3 * priv - > width ) ;
break ;
case IMGFMT_RGB32 :
case IMGFMT_BGR32 :
vo_draw_alpha_rgb32 ( w , h , src , srca , stride , ( ( uint8_t * ) priv - > rgbsurface - > pixels ) + 4 * ( y0 * priv - > width + x0 ) , 4 * priv - > width ) ;
break ;
2001-06-22 19:56:41 +00:00
}
2001-04-14 17:55:20 +00:00
}
2001-04-11 13:46:56 +00:00
}
2001-02-24 20:28:24 +00:00
/**
* Take a null - terminated array of pointers , and find the last element .
*
* params : array = = array of which we want to find the last element .
* returns : index of last NON - NULL element .
* */
static inline int findArrayEnd ( SDL_Rect * * array )
{
int i = 0 ;
while ( array [ i + + ] ) ; /* keep loopin' ... */
/* return the index of the last array element */
return i - 1 ;
}
/**
* Open and prepare SDL output .
*
* params : * plugin = =
* * name = =
* returns : 0 on success , - 1 on failure
* */
2001-04-10 21:41:31 +00:00
2001-02-24 20:28:24 +00:00
static int sdl_open ( void * plugin , void * name )
{
struct sdl_priv_s * priv = & sdl_priv ;
const SDL_VideoInfo * vidInfo = NULL ;
2002-02-04 19:14:40 +00:00
/*static int opened = 0;
2001-04-10 21:41:31 +00:00
2002-02-04 19:14:40 +00:00
if ( opened )
2001-02-24 20:28:24 +00:00
return 0 ;
2002-02-04 18:18:46 +00:00
opened = 1 ; */
2001-02-24 20:28:24 +00:00
2001-04-25 20:43:45 +00:00
if ( verbose > 2 ) printf ( " SDL: Opening Plugin \n " ) ;
2001-06-21 22:47:55 +00:00
if ( vo_subdevice ) setenv ( " SDL_VIDEODRIVER " , vo_subdevice , 1 ) ;
2001-04-11 13:46:56 +00:00
/* does the user want SDL to try and force Xv */
2001-04-25 20:43:45 +00:00
if ( sdl_forcexv ) setenv ( " SDL_VIDEO_X11_NODIRECTCOLOR " , " 1 " , 1 ) ;
/* does the user want to disable Xv and use software scaling instead */
if ( sdl_noxv ) setenv ( " SDL_VIDEO_YUV_HWACCEL " , " 0 " , 1 ) ;
2001-02-24 20:28:24 +00:00
2001-03-11 17:17:03 +00:00
/* default to no fullscreen mode, we'll set this as soon we have the avail. modes */
2001-02-24 20:28:24 +00:00
priv - > fullmode = - 2 ;
2001-04-25 20:43:45 +00:00
2001-02-24 20:28:24 +00:00
priv - > surface = NULL ;
2001-04-25 20:43:45 +00:00
priv - > rgbsurface = NULL ;
2001-02-24 20:28:24 +00:00
priv - > overlay = NULL ;
priv - > fullmodes = NULL ;
2001-04-25 20:43:45 +00:00
priv - > bpp = 0 ;
2001-02-24 20:28:24 +00:00
/* initialize the SDL Video system */
2002-01-24 21:46:57 +00:00
if ( SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) ) {
2001-06-09 18:42:36 +00:00
printf ( " SDL: Initializing of SDL failed: %s. \n " , SDL_GetError ( ) ) ;
2001-02-24 20:28:24 +00:00
return - 1 ;
}
2001-04-25 20:43:45 +00:00
SDL_VideoDriverName ( priv - > driver , 8 ) ;
2001-06-09 18:42:36 +00:00
printf ( " SDL: Using driver: %s \n " , priv - > driver ) ;
2001-04-25 20:43:45 +00:00
/* other default values */
# ifdef SDL_NOHWSURFACE
if ( verbose ) printf ( " SDL: using software-surface \n " ) ;
2001-06-22 19:56:41 +00:00
priv - > sdlflags = SDL_SWSURFACE | SDL_RESIZABLE | SDL_ASYNCBLIT | SDL_ANYFORMAT ;
priv - > sdlfullflags = SDL_SWSURFACE | SDL_FULLSCREEN | SDL_DOUBLEBUF | SDL_ASYNCBLIT | SDL_ANYFORMAT ;
2001-04-25 20:43:45 +00:00
# else
2001-06-22 19:56:41 +00:00
/*if((strcmp(priv->driver, "dga") == 0) && (priv->mode)) {
2001-04-25 20:43:45 +00:00
if ( verbose ) printf ( " SDL: using software-surface \n " ) ;
2001-06-22 19:56:41 +00:00
priv - > sdlflags = SDL_SWSURFACE | SDL_FULLSCREEN | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_ANYFORMAT ;
priv - > sdlfullflags = SDL_SWSURFACE | SDL_FULLSCREEN | SDL_ASYNCBLIT | SDL_HWACCEL | SDL_ANYFORMAT ;
2001-04-25 20:43:45 +00:00
}
2001-06-22 19:56:41 +00:00
else { */
2001-04-25 20:43:45 +00:00
if ( verbose ) printf ( " SDL: using hardware-surface \n " ) ;
2001-06-24 19:20:19 +00:00
priv - > sdlflags = SDL_HWSURFACE | SDL_RESIZABLE | SDL_ASYNCBLIT | SDL_HWACCEL /*|SDL_ANYFORMAT*/ ;
priv - > sdlfullflags = SDL_HWSURFACE | SDL_FULLSCREEN | SDL_DOUBLEBUF | SDL_ASYNCBLIT | SDL_HWACCEL /*|SDL_ANYFORMAT*/ ;
2001-06-22 19:56:41 +00:00
//}
2001-04-25 20:43:45 +00:00
# endif
2001-05-05 20:13:37 +00:00
/* Setup Keyrepeats (500/30 are defaults) */
SDL_EnableKeyRepeat ( SDL_DEFAULT_REPEAT_DELAY , 100 /*SDL_DEFAULT_REPEAT_INTERVAL*/ ) ;
2001-02-24 20:28:24 +00:00
/* get information about the graphics adapter */
vidInfo = SDL_GetVideoInfo ( ) ;
/* collect all fullscreen & hardware modes available */
if ( ! ( priv - > fullmodes = SDL_ListModes ( vidInfo - > vfmt , priv - > sdlfullflags ) ) ) {
/* non hardware accelerated fullscreen modes */
priv - > sdlfullflags & = ~ SDL_HWSURFACE ;
priv - > fullmodes = SDL_ListModes ( vidInfo - > vfmt , priv - > sdlfullflags ) ;
}
/* test for normal resizeable & windowed hardware accellerated surfaces */
if ( ! SDL_ListModes ( vidInfo - > vfmt , priv - > sdlflags ) ) {
/* test for NON hardware accelerated resizeable surfaces - poor you.
* That ' s all we have . If this fails there ' s nothing left .
* Theoretically there could be Fullscreenmodes left - we ignore this for now .
*/
priv - > sdlflags & = ~ SDL_HWSURFACE ;
if ( ( ! SDL_ListModes ( vidInfo - > vfmt , priv - > sdlflags ) ) & & ( ! priv - > fullmodes ) ) {
2001-04-25 20:43:45 +00:00
printf ( " SDL: Couldn't get any acceptable SDL Mode for output. \n " ) ;
2001-02-24 20:28:24 +00:00
return - 1 ;
}
}
2001-04-25 20:43:45 +00:00
2001-02-24 20:28:24 +00:00
/* YUV overlays need at least 16-bit color depth, but the
* display might less . The SDL AAlib target says it can only do
* 8 - bits , for example . So , if the display is less than 16 - bits ,
* we ' ll force the BPP to 16 , and pray that SDL can emulate for us .
2001-04-25 20:43:45 +00:00
*/
2001-02-24 20:28:24 +00:00
priv - > bpp = vidInfo - > vfmt - > BitsPerPixel ;
2001-04-25 20:43:45 +00:00
if ( ! priv - > mode & & priv - > bpp < 16 ) {
if ( verbose ) printf ( " SDL: Your SDL display target wants to be at a color depth of (%d), but we need it to be at \
2001-02-24 20:28:24 +00:00
least 16 bits , so we need to emulate 16 - bit color . This is going to slow things down ; you might want to \
2001-04-25 20:43:45 +00:00
increase your display ' s color depth , if possible . \ n " , priv->bpp);
2001-02-24 20:28:24 +00:00
priv - > bpp = 16 ;
}
2001-04-25 20:43:45 +00:00
/* We don't want those in our event queue.
* We use SDL_KEYUP cause SDL_KEYDOWN seems to cause problems
* with keys need to be pressed twice , to be recognized .
*/
2001-05-11 21:36:30 +00:00
# ifndef BUGGY_SDL
2001-05-11 17:21:15 +00:00
SDL_EventState ( SDL_ACTIVEEVENT , SDL_IGNORE ) ;
2001-02-24 20:28:24 +00:00
SDL_EventState ( SDL_MOUSEMOTION , SDL_IGNORE ) ;
SDL_EventState ( SDL_MOUSEBUTTONDOWN , SDL_IGNORE ) ;
SDL_EventState ( SDL_MOUSEBUTTONUP , SDL_IGNORE ) ;
2001-08-27 11:49:10 +00:00
// SDL_EventState(SDL_QUIT, SDL_IGNORE);
2001-02-24 20:28:24 +00:00
SDL_EventState ( SDL_SYSWMEVENT , SDL_IGNORE ) ;
2001-05-11 17:21:15 +00:00
SDL_EventState ( SDL_USEREVENT , SDL_IGNORE ) ;
2001-05-11 21:36:30 +00:00
# endif
2001-02-24 20:28:24 +00:00
/* Success! */
return 0 ;
}
/**
* Close SDL , Cleanups , Free Memory
*
* params : * plugin
* returns : non - zero on success , zero on error .
* */
static int sdl_close ( void )
{
struct sdl_priv_s * priv = & sdl_priv ;
/* Cleanup YUV Overlay structure */
if ( priv - > overlay )
SDL_FreeYUVOverlay ( priv - > overlay ) ;
2001-04-25 20:43:45 +00:00
/* Free RGB Surface */
if ( priv - > rgbsurface )
2001-06-14 12:42:56 +00:00
SDL_FreeSurface ( priv - > rgbsurface ) ;
2001-04-25 20:43:45 +00:00
2001-02-24 20:28:24 +00:00
/* Free our blitting surface */
if ( priv - > surface )
SDL_FreeSurface ( priv - > surface ) ;
2001-04-11 13:46:56 +00:00
/* DONT attempt to free the fullscreen modes array. SDL_Quit* does this for us */
2001-02-24 20:28:24 +00:00
/* Cleanup SDL */
2001-06-03 21:02:46 +00:00
//SDL_Quit();
SDL_QuitSubSystem ( SDL_INIT_VIDEO ) ;
2001-04-25 20:43:45 +00:00
/* might have to be changed to quitsubsystem only, if plugins become
* changeable on the fly */
2001-04-11 13:46:56 +00:00
2001-04-25 20:43:45 +00:00
if ( verbose > 2 ) printf ( " SDL: Closed Plugin \n " ) ;
2001-02-24 20:28:24 +00:00
return 0 ;
}
2001-05-13 16:38:33 +00:00
/**
* Do aspect ratio calculations
*
* params : srcw = = sourcewidth
* srch = = sourceheight
* dstw = = destinationwidth
* dsth = = destinationheight
*
* returns : SDL_Rect structure with new x and y , w and h
* */
2001-10-04 11:42:21 +00:00
#if 0
2001-05-13 16:38:33 +00:00
static SDL_Rect aspect ( int srcw , int srch , int dstw , int dsth ) {
SDL_Rect newres ;
if ( verbose > 1 ) printf ( " SDL Aspect: src: %ix%i dst: %ix%i \n " , srcw , srch , dstw , dsth ) ;
newres . h = ( ( float ) dstw / ( float ) srcw * ( float ) srch ) * ( ( float ) dsth / ( ( float ) dstw / ( MONITOR_ASPECT ) ) ) ;
if ( newres . h > dsth ) {
newres . w = ( ( float ) dsth / ( float ) newres . h ) * dstw ;
newres . h = dsth ;
newres . x = ( dstw - newres . w ) / 2 ;
newres . y = 0 ;
}
else {
newres . w = dstw ;
newres . x = 0 ;
newres . y = ( dsth - newres . h ) / 2 ;
}
if ( verbose ) printf ( " SDL Aspect-Destinationres: %ix%i (x: %i, y: %i) \n " , newres . w , newres . h , newres . x , newres . y ) ;
return newres ;
}
2001-10-04 11:42:21 +00:00
# endif
2001-02-24 20:28:24 +00:00
/**
* Sets the specified fullscreen mode .
*
* params : mode = = index of the desired fullscreen mode
* returns : doesn ' t return
* */
2001-05-13 16:38:33 +00:00
#if 0
2001-02-24 20:28:24 +00:00
static void set_fullmode ( int mode )
{
struct sdl_priv_s * priv = & sdl_priv ;
SDL_Surface * newsurface = NULL ;
2001-03-12 17:20:48 +00:00
int haspect , waspect = 0 ;
2001-02-24 20:28:24 +00:00
/* if we haven't set a fullmode yet, default to the lowest res fullmode first */
if ( mode < 0 )
mode = priv - > fullmode = findArrayEnd ( priv - > fullmodes ) - 1 ;
2001-03-12 17:20:48 +00:00
/* Calculate proper aspect ratio for fullscreen
* Height smaller than expected : add horizontal black bars ( haspect ) */
haspect = ( priv - > width * ( float ) ( ( float ) priv - > fullmodes [ mode ] - > h / ( float ) priv - > fullmodes [ mode ] - > w ) - priv - > height ) * ( float ) ( ( float ) priv - > fullmodes [ mode ] - > w / ( float ) priv - > width ) ;
/* Height bigger than expected: add vertical black bars (waspect)*/
if ( haspect < 0 ) {
haspect = 0 ; /* set haspect to zero because image will be scaled horizontal instead of vertical */
waspect = priv - > fullmodes [ mode ] - > w - ( ( float ) ( ( float ) priv - > fullmodes [ mode ] - > h / ( float ) priv - > height ) * ( float ) priv - > width ) ;
}
// printf ("W-Aspect: %i H-Aspect: %i\n", waspect, haspect);
2001-03-11 17:17:03 +00:00
2001-03-12 17:20:48 +00:00
/* change to given fullscreen mode and hide the mouse cursor */
newsurface = SDL_SetVideoMode ( priv - > fullmodes [ mode ] - > w - waspect , priv - > fullmodes [ mode ] - > h - haspect , priv - > bpp , priv - > sdlfullflags ) ;
2001-02-24 20:28:24 +00:00
/* if we were successfull hide the mouse cursor and save the mode */
if ( newsurface ) {
2001-06-14 12:42:56 +00:00
if ( priv - > surface )
SDL_FreeSurface ( priv - > surface ) ;
2001-02-24 20:28:24 +00:00
priv - > surface = newsurface ;
SDL_ShowCursor ( 0 ) ;
}
}
2001-05-13 16:38:33 +00:00
# endif
static void set_fullmode ( int mode ) {
struct sdl_priv_s * priv = & sdl_priv ;
SDL_Surface * newsurface = NULL ;
/* if we haven't set a fullmode yet, default to the lowest res fullmode first */
2001-12-19 11:50:05 +00:00
/* But select a mode where the full video enter */
if ( mode < 0 ) {
2002-02-04 18:18:46 +00:00
int i = 0 ;
2001-12-19 11:50:05 +00:00
mode = 0 ; // Default to the biggest mode avaible
for ( i = findArrayEnd ( priv - > fullmodes ) - 1 ; i > = 0 ; i - - ) {
if ( ( priv - > fullmodes [ i ] - > w > = priv - > width ) & &
( priv - > fullmodes [ i ] - > h > = priv - > height ) ) {
mode = i ;
break ;
}
}
priv - > fullmode = mode ;
}
2001-05-13 16:38:33 +00:00
2001-10-18 02:42:20 +00:00
aspect_save_screenres ( priv - > fullmodes [ mode ] - > w , priv - > fullmodes [ mode ] - > h ) ;
2001-05-13 16:38:33 +00:00
/* calculate new video size/aspect */
2001-10-04 11:42:21 +00:00
if ( ! priv - > mode ) {
2001-05-13 16:38:33 +00:00
if ( priv - > fulltype & FS ) {
2001-10-13 13:38:59 +00:00
# ifdef HAVE_X11
2001-10-18 02:42:20 +00:00
aspect_save_screenres ( priv - > XWidth , priv - > XHeight ) ;
2001-10-13 13:38:59 +00:00
# endif
2001-10-04 11:42:21 +00:00
}
2001-10-18 02:42:20 +00:00
aspect ( & priv - > dstwidth , & priv - > dstheight , A_ZOOM ) ;
2001-05-13 16:38:33 +00:00
}
2001-02-24 20:28:24 +00:00
2001-05-13 16:38:33 +00:00
/* try to change to given fullscreenmode */
2001-10-18 02:42:20 +00:00
newsurface = SDL_SetVideoMode ( priv - > dstwidth , priv - > dstheight , priv - > bpp , priv - > sdlfullflags ) ;
2001-05-13 16:38:33 +00:00
/* if creation of new surface was successfull, save it and hide mouse cursor */
if ( newsurface ) {
2001-06-14 12:42:56 +00:00
if ( priv - > surface )
SDL_FreeSurface ( priv - > surface ) ;
2001-05-13 16:38:33 +00:00
priv - > surface = newsurface ;
SDL_ShowCursor ( 0 ) ;
}
}
2001-06-14 12:42:56 +00:00
2001-02-24 20:28:24 +00:00
/**
* Initialize an SDL surface and an SDL YUV overlay .
*
* params : width = = width of video we ' ll be displaying .
* height = = height of video we ' ll be displaying .
* fullscreen = = want to be fullscreen ?
* title = = Title for window titlebar .
* returns : non - zero on success , zero on error .
* */
static uint32_t
2002-01-31 09:57:13 +00:00
config ( uint32_t width , uint32_t height , uint32_t d_width , uint32_t d_height , uint32_t flags , char * title , uint32_t format , const vo_tune_info_t * info )
2001-02-24 20:28:24 +00:00
//static int sdl_setup (int width, int height)
{
struct sdl_priv_s * priv = & sdl_priv ;
2001-04-11 20:11:21 +00:00
unsigned int sdl_format ;
2001-05-11 21:36:30 +00:00
# ifdef HAVE_X11
static Display * XDisplay ;
2001-05-13 16:38:33 +00:00
static int XScreen ;
2001-05-11 21:36:30 +00:00
# endif
2001-10-18 02:42:20 +00:00
aspect_save_orig ( width , height ) ;
aspect_save_prescale ( d_width , d_height ) ;
2001-05-11 21:36:30 +00:00
2001-04-15 21:08:11 +00:00
sdl_format = format ;
2001-02-24 20:28:24 +00:00
switch ( format ) {
2001-04-15 21:08:11 +00:00
case IMGFMT_YV12 :
2001-04-20 10:27:51 +00:00
if ( verbose ) printf ( " SDL: Using 0x%X (YV12) image format \n " , format ) ; break ;
2001-04-15 21:08:11 +00:00
case IMGFMT_IYUV :
2001-04-20 10:27:51 +00:00
if ( verbose ) printf ( " SDL: Using 0x%X (IYUV) image format \n " , format ) ; break ;
2001-04-15 21:08:11 +00:00
case IMGFMT_YUY2 :
2001-04-20 10:27:51 +00:00
if ( verbose ) printf ( " SDL: Using 0x%X (YUY2) image format \n " , format ) ; break ;
2001-04-15 21:08:11 +00:00
case IMGFMT_UYVY :
2001-04-20 10:27:51 +00:00
if ( verbose ) printf ( " SDL: Using 0x%X (UYVY) image format \n " , format ) ; break ;
2001-04-15 21:08:11 +00:00
case IMGFMT_YVYU :
2001-04-20 10:27:51 +00:00
if ( verbose ) printf ( " SDL: Using 0x%X (YVYU) image format \n " , format ) ; break ;
2001-04-15 21:08:11 +00:00
case IMGFMT_I420 :
2001-04-20 10:27:51 +00:00
if ( verbose ) printf ( " SDL: Using 0x%X (I420) image format \n " , format ) ;
2001-04-20 09:06:49 +00:00
printf ( " SDL: Mapping I420 to IYUV \n " ) ;
2001-04-15 21:08:11 +00:00
sdl_format = SDL_IYUV_OVERLAY ;
2001-04-25 20:43:45 +00:00
break ;
case IMGFMT_BGR15 :
if ( verbose ) printf ( " SDL: Using 0x%X (BGR15) image format \n " , format ) ;
priv - > mode = BGR ;
break ;
case IMGFMT_RGB15 :
if ( verbose ) printf ( " SDL: Using 0x%X (RGB15) image format \n " , format ) ;
priv - > mode = RGB ;
break ;
case IMGFMT_BGR16 :
if ( verbose ) printf ( " SDL: Using 0x%X (BGR16) image format \n " , format ) ;
priv - > mode = BGR ;
break ;
case IMGFMT_RGB16 :
if ( verbose ) printf ( " SDL: Using 0x%X (RGB16) image format \n " , format ) ;
priv - > mode = RGB ;
break ;
case IMGFMT_BGR24 :
if ( verbose ) printf ( " SDL: Using 0x%X (BGR24) image format \n " , format ) ;
priv - > mode = BGR ;
break ;
case IMGFMT_RGB24 :
if ( verbose ) printf ( " SDL: Using 0x%X (RGB24) image format \n " , format ) ;
priv - > mode = RGB ;
break ;
case IMGFMT_BGR32 :
if ( verbose ) printf ( " SDL: Using 0x%X (BGR32) image format \n " , format ) ;
priv - > mode = BGR ;
break ;
case IMGFMT_RGB32 :
if ( verbose ) printf ( " SDL: Using 0x%X (RGB32) image format \n " , format ) ;
priv - > mode = RGB ;
break ;
2001-04-15 21:08:11 +00:00
default :
2001-04-20 09:06:49 +00:00
printf ( " SDL: Unsupported image format (0x%X) \n " , format ) ;
2001-04-15 21:08:11 +00:00
return - 1 ;
}
2001-06-24 19:20:19 +00:00
if ( priv - > mode ) {
priv - > sdlflags | = SDL_ANYFORMAT ;
priv - > sdlfullflags | = SDL_ANYFORMAT ;
}
2001-02-24 20:28:24 +00:00
2001-05-11 21:36:30 +00:00
# ifdef HAVE_X11
if ( getenv ( " DISPLAY " ) ) {
if ( verbose ) printf ( " SDL: deactivating XScreensaver/DPMS \n " ) ;
XDisplay = XOpenDisplay ( getenv ( " DISPLAY " ) ) ;
2001-05-13 16:38:33 +00:00
XScreen = DefaultScreen ( XDisplay ) ;
priv - > XWidth = DisplayWidth ( XDisplay , XScreen ) ;
priv - > XHeight = DisplayHeight ( XDisplay , XScreen ) ;
2001-06-02 22:12:28 +00:00
priv - > X = 1 ;
2001-05-13 16:38:33 +00:00
if ( verbose ) printf ( " SDL: X11 Resolution %ix%i \n " , priv - > XWidth , priv - > XHeight ) ;
2001-05-11 21:36:30 +00:00
saver_off ( XDisplay ) ;
XCloseDisplay ( XDisplay ) ;
}
# endif
2001-06-09 18:42:36 +00:00
if ( sdl_open ( NULL , NULL ) ! = 0 )
return - 1 ;
2001-02-24 20:28:24 +00:00
2001-04-11 13:46:56 +00:00
/* Set output window title */
2001-10-04 11:42:21 +00:00
SDL_WM_SetCaption ( " .: MPlayer : F = Fullscreen/Windowed : C = Cycle Fullscreen Resolutions :. " , title ) ;
2001-04-25 20:43:45 +00:00
//SDL_WM_SetCaption (title, title);
2001-04-11 13:46:56 +00:00
2001-02-24 20:28:24 +00:00
/* Save the original Image size */
2001-03-11 17:17:03 +00:00
2001-04-26 21:28:02 +00:00
priv - > width = width ;
priv - > height = height ;
2001-05-13 16:38:33 +00:00
priv - > dstwidth = d_width ? d_width : width ;
priv - > dstheight = d_height ? d_height : height ;
/*priv->width = res.w;
priv - > height = res . h ; */
2001-02-24 20:28:24 +00:00
priv - > format = format ;
2001-05-13 16:38:33 +00:00
# ifdef HAVE_X11
2001-10-18 02:42:20 +00:00
aspect_save_screenres ( priv - > XWidth , priv - > XHeight ) ;
aspect ( & priv - > dstwidth , & priv - > dstheight , A_NOZOOM ) ;
2001-05-13 16:38:33 +00:00
# endif
2001-10-18 02:42:20 +00:00
priv - > windowsize . w = priv - > dstwidth ;
priv - > windowsize . h = priv - > dstheight ;
2001-02-24 20:28:24 +00:00
2001-04-11 20:00:55 +00:00
/* bit 0 (0x01) means fullscreen (-fs)
* bit 1 ( 0x02 ) means mode switching ( - vm )
* bit 2 ( 0x04 ) enables software scaling ( - zoom )
2001-05-11 21:36:30 +00:00
* bit 3 ( 0x08 ) enables flipping ( - flip )
*/
// printf("SDL: flags are set to: %i\n", flags);
2001-04-11 20:00:55 +00:00
// printf("SDL: Width: %i Height: %i D_Width %i D_Height: %i\n", width, height, d_width, d_height);
2001-05-13 16:38:33 +00:00
if ( flags & FLIP ) {
if ( verbose ) printf ( " SDL: using flipped video (only with RGB/BGR/packed YUV) \n " ) ;
2001-05-11 21:36:30 +00:00
priv - > flip = 1 ;
}
if ( flags & FS ) {
2001-04-20 10:27:51 +00:00
if ( verbose ) printf ( " SDL: setting zoomed fullscreen without modeswitching \n " ) ;
2001-10-18 02:42:20 +00:00
printf ( " SDL: Info - please use -vm or -zoom to switch to best resolution. \n " ) ;
2001-05-13 16:38:33 +00:00
priv - > fulltype = FS ;
set_fullmode ( priv - > fullmode ) ;
/*if((priv->surface = SDL_SetVideoMode (d_width, d_height, priv->bpp, priv->sdlfullflags)))
SDL_ShowCursor ( 0 ) ; */
2001-05-11 21:36:30 +00:00
} else
if ( flags & VM ) {
2001-10-18 02:42:20 +00:00
if ( verbose ) printf ( " SDL: setting zoomed fullscreen with modeswitching \n " ) ;
2001-05-13 16:38:33 +00:00
priv - > fulltype = VM ;
set_fullmode ( priv - > fullmode ) ;
/*if((priv->surface = SDL_SetVideoMode (d_width ? d_width : width, d_height ? d_height : height, priv->bpp, priv->sdlfullflags)))
SDL_ShowCursor ( 0 ) ; */
2001-05-11 21:36:30 +00:00
} else
if ( flags & ZOOM ) {
2001-04-20 10:27:51 +00:00
if ( verbose ) printf ( " SDL: setting zoomed fullscreen with modeswitching \n " ) ;
2001-05-13 16:38:33 +00:00
priv - > fulltype = ZOOM ;
set_fullmode ( priv - > fullmode ) ;
2001-05-11 21:36:30 +00:00
}
else {
2001-06-02 22:12:28 +00:00
if ( ( strcmp ( priv - > driver , " x11 " ) = = 0 ) | | ( ( strcmp ( priv - > driver , " aalib " ) = = 0 ) & & priv - > X ) ) {
2001-05-13 16:38:33 +00:00
if ( verbose ) printf ( " SDL: setting windowed mode \n " ) ;
2001-10-18 02:42:20 +00:00
priv - > surface = SDL_SetVideoMode ( priv - > dstwidth , priv - > dstheight , priv - > bpp , priv - > sdlflags ) ;
2001-05-13 16:38:33 +00:00
}
else {
2001-06-02 22:12:28 +00:00
if ( verbose ) printf ( " SDL: setting zoomed fullscreen with modeswitching \n " ) ;
priv - > fulltype = ZOOM ;
2001-05-13 16:38:33 +00:00
set_fullmode ( priv - > fullmode ) ;
}
2001-05-11 21:36:30 +00:00
}
2001-04-25 20:43:45 +00:00
if ( ! priv - > surface ) { // cannot SetVideoMode
printf ( " SDL: failed to set video mode: %s \n " , SDL_GetError ( ) ) ;
2001-02-24 20:28:24 +00:00
return - 1 ;
2001-04-25 20:43:45 +00:00
}
2001-02-24 20:28:24 +00:00
2001-04-25 20:43:45 +00:00
switch ( format ) {
/* Initialize and create the RGB Surface used for video out in BGR/RGB mode */
//SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);
// SDL_SWSURFACE,SDL_HWSURFACE,SDL_SRCCOLORKEY, priv->flags? guess: exchange Rmask and Bmask for BGR<->RGB
// 32 bit: a:ff000000 r:ff000 g:ff00 b:ff
// 24 bit: r:ff0000 g:ff00 b:ff
// 16 bit: r:1111100000000000b g:0000011111100000b b:0000000000011111b
// 15 bit: r:111110000000000b g:000001111100000b b:000000000011111b
// FIXME: colorkey detect based on bpp, FIXME static bpp value, FIXME alpha value correct?
case IMGFMT_RGB15 :
if ( ! ( priv - > rgbsurface = SDL_CreateRGBSurface ( SDL_SRCCOLORKEY , width , height , 15 , 31 , 992 , 31744 , 0 ) ) ) {
printf ( " SDL: Couldn't create a RGB surface: %s \n " , SDL_GetError ( ) ) ;
return - 1 ;
}
break ;
case IMGFMT_BGR15 :
if ( ! ( priv - > rgbsurface = SDL_CreateRGBSurface ( SDL_SRCCOLORKEY , width , height , 15 , 31744 , 992 , 31 , 0 ) ) ) {
printf ( " SDL: Couldn't create a RGB surface: %s \n " , SDL_GetError ( ) ) ;
return - 1 ;
}
break ;
case IMGFMT_RGB16 :
if ( ! ( priv - > rgbsurface = SDL_CreateRGBSurface ( SDL_SRCCOLORKEY , width , height , 16 , 31 , 2016 , 63488 , 0 ) ) ) {
printf ( " SDL: Couldn't create a RGB surface: %s \n " , SDL_GetError ( ) ) ;
return - 1 ;
}
break ;
case IMGFMT_BGR16 :
if ( ! ( priv - > rgbsurface = SDL_CreateRGBSurface ( SDL_SRCCOLORKEY , width , height , 16 , 63488 , 2016 , 31 , 0 ) ) ) {
printf ( " SDL: Couldn't create a RGB surface: %s \n " , SDL_GetError ( ) ) ;
return - 1 ;
}
break ;
case IMGFMT_RGB24 :
if ( ! ( priv - > rgbsurface = SDL_CreateRGBSurface ( SDL_SRCCOLORKEY , width , height , 24 , 0x0000FF , 0x00FF00 , 0xFF0000 , 0 ) ) ) {
printf ( " SDL: Couldn't create a RGB surface: %s \n " , SDL_GetError ( ) ) ;
return - 1 ;
}
break ;
case IMGFMT_BGR24 :
if ( ! ( priv - > rgbsurface = SDL_CreateRGBSurface ( SDL_SRCCOLORKEY , width , height , 24 , 0xFF0000 , 0x00FF00 , 0x0000FF , 0 ) ) ) {
printf ( " SDL: Couldn't create a RGB surface: %s \n " , SDL_GetError ( ) ) ;
return - 1 ;
}
break ;
case IMGFMT_RGB32 :
2001-06-24 19:20:19 +00:00
if ( ! ( priv - > rgbsurface = SDL_CreateRGBSurface ( SDL_SRCCOLORKEY , width , height , 32 , 0x000000FF , 0x0000FF00 , 0x00FF0000 , 0 /*0xFF000000*/ ) ) ) {
2001-04-25 20:43:45 +00:00
printf ( " SDL: Couldn't create a RGB surface: %s \n " , SDL_GetError ( ) ) ;
return - 1 ;
}
break ;
case IMGFMT_BGR32 :
2001-06-24 19:20:19 +00:00
if ( ! ( priv - > rgbsurface = SDL_CreateRGBSurface ( SDL_SRCCOLORKEY , width , height , 32 , 0x00FF0000 , 0x0000FF00 , 0x000000FF , 0 /*0xFF000000*/ ) ) ) {
2001-04-25 20:43:45 +00:00
printf ( " SDL: Couldn't create a RGB surface: %s \n " , SDL_GetError ( ) ) ;
return - 1 ;
}
break ;
default :
/* Initialize and create the YUV Overlay used for video out */
if ( ! ( priv - > overlay = SDL_CreateYUVOverlay ( width , height , sdl_format , priv - > surface ) ) ) {
printf ( " SDL: Couldn't create a YUV overlay: %s \n " , SDL_GetError ( ) ) ;
return - 1 ;
}
priv - > framePlaneY = width * height ;
priv - > framePlaneUV = ( width * height ) > > 2 ;
2001-05-13 16:38:33 +00:00
priv - > framePlaneYUY = width * height * 2 ;
2001-04-25 20:43:45 +00:00
priv - > stridePlaneY = width ;
priv - > stridePlaneUV = width / 2 ;
2001-05-13 16:38:33 +00:00
priv - > stridePlaneYUY = width * 2 ;
2001-04-25 20:43:45 +00:00
}
if ( priv - > mode ) {
2001-06-24 19:20:19 +00:00
if ( ( priv - > format & 0xFF ) ! = priv - > bpp ) { priv - > dblit = 0 ; printf ( " SDL: using depth/colorspace conversion, this will slow things down (%ibpp -> %ibpp). \n " , priv - > format & 0xFF , priv - > bpp ) ; }
else if ( strcmp ( priv - > driver , " x11 " ) = = 0 ) priv - > dblit = 1 ;
2001-04-25 20:43:45 +00:00
priv - > framePlaneRGB = width * height * priv - > rgbsurface - > format - > BytesPerPixel ;
2001-05-11 21:36:30 +00:00
priv - > stridePlaneRGB = width * priv - > rgbsurface - > format - > BytesPerPixel ;
2001-04-25 20:43:45 +00:00
}
2001-02-24 20:28:24 +00:00
return 0 ;
}
2001-06-23 10:18:23 +00:00
# ifdef SDL_ENABLE_LOCKS
# define SDL_OVR_LOCK if (SDL_LockYUVOverlay (priv->overlay)) { \
if ( verbose ) printf ( " SDL: Couldn't lock YUV overlay \n " ) ; \
return - 1 ; \
}
# define SDL_OVR_UNLOCK SDL_UnlockYUVOverlay (priv->overlay);
# define SDL_SRF_LOCK(srf) if(SDL_MUSTLOCK(srf)) { \
if ( SDL_LockSurface ( srf ) ) { \
if ( verbose ) printf ( " SDL: Couldn't lock RGB surface \n " ) ; \
return - 1 ; \
} \
}
# define SDL_SRF_UNLOCK(srf) if(SDL_MUSTLOCK(srf)) \
SDL_UnlockSurface ( srf ) ;
# else
# define SDL_OVR_LOCK
# define SDL_OVR_UNLOCK
# define SDL_SRF_LOCK(srf)
# define SDL_SRF_UNLOCK(srf)
# endif
2001-02-24 20:28:24 +00:00
/**
* Draw a frame to the SDL YUV overlay .
*
* params : * src [ ] = = the Y , U , and V planes that make up the frame .
* returns : non - zero on success , zero on error .
* */
//static int sdl_draw_frame (frame_t *frame)
static uint32_t draw_frame ( uint8_t * src [ ] )
{
struct sdl_priv_s * priv = & sdl_priv ;
uint8_t * dst ;
2001-05-11 21:36:30 +00:00
int i ;
uint8_t * mysrc = src [ 0 ] ;
2001-10-04 11:42:21 +00:00
2001-02-24 20:28:24 +00:00
switch ( priv - > format ) {
case IMGFMT_YV12 :
2001-04-14 17:55:20 +00:00
case IMGFMT_I420 :
case IMGFMT_IYUV :
2001-06-23 10:18:23 +00:00
SDL_OVR_LOCK
2001-02-24 20:28:24 +00:00
dst = ( uint8_t * ) * ( priv - > overlay - > pixels ) ;
memcpy ( dst , src [ 0 ] , priv - > framePlaneY ) ;
dst + = priv - > framePlaneY ;
memcpy ( dst , src [ 2 ] , priv - > framePlaneUV ) ;
dst + = priv - > framePlaneUV ;
memcpy ( dst , src [ 1 ] , priv - > framePlaneUV ) ;
2001-06-23 10:18:23 +00:00
SDL_OVR_UNLOCK
2001-02-24 20:28:24 +00:00
break ;
2001-04-14 17:55:20 +00:00
2001-02-24 20:28:24 +00:00
case IMGFMT_YUY2 :
2001-04-14 17:55:20 +00:00
case IMGFMT_UYVY :
case IMGFMT_YVYU :
2001-06-23 10:18:23 +00:00
SDL_OVR_LOCK
2001-02-24 20:28:24 +00:00
dst = ( uint8_t * ) * ( priv - > overlay - > pixels ) ;
2001-05-13 16:38:33 +00:00
if ( priv - > flip ) {
mysrc + = priv - > framePlaneYUY ;
for ( i = 0 ; i < priv - > height ; i + + ) {
mysrc - = priv - > stridePlaneYUY ;
memcpy ( dst , mysrc , priv - > stridePlaneYUY ) ;
dst + = priv - > stridePlaneYUY ;
}
}
else memcpy ( dst , src [ 0 ] , priv - > framePlaneYUY ) ;
2001-06-23 10:18:23 +00:00
SDL_OVR_UNLOCK
2001-02-24 20:28:24 +00:00
break ;
2001-04-25 20:43:45 +00:00
case IMGFMT_RGB15 :
case IMGFMT_BGR15 :
case IMGFMT_RGB16 :
case IMGFMT_BGR16 :
case IMGFMT_RGB24 :
case IMGFMT_BGR24 :
case IMGFMT_RGB32 :
case IMGFMT_BGR32 :
2001-06-24 19:20:19 +00:00
if ( priv - > dblit ) {
2001-06-23 10:18:23 +00:00
SDL_SRF_LOCK ( priv - > surface )
2001-06-22 19:56:41 +00:00
dst = ( uint8_t * ) priv - > surface - > pixels ;
if ( priv - > flip ) {
mysrc + = priv - > framePlaneRGB ;
for ( i = 0 ; i < priv - > height ; i + + ) {
mysrc - = priv - > stridePlaneRGB ;
memcpy ( dst , mysrc , priv - > stridePlaneRGB ) ;
dst + = priv - > stridePlaneRGB ;
}
2001-05-17 15:11:58 +00:00
}
2001-06-22 19:56:41 +00:00
else memcpy ( dst , src [ 0 ] , priv - > framePlaneRGB ) ;
2001-06-23 10:18:23 +00:00
SDL_SRF_UNLOCK ( priv - > surface )
2001-06-22 19:56:41 +00:00
} else {
2001-06-23 10:18:23 +00:00
SDL_SRF_LOCK ( priv - > rgbsurface )
2001-06-22 19:56:41 +00:00
dst = ( uint8_t * ) priv - > rgbsurface - > pixels ;
if ( priv - > flip ) {
mysrc + = priv - > framePlaneRGB ;
for ( i = 0 ; i < priv - > height ; i + + ) {
mysrc - = priv - > stridePlaneRGB ;
memcpy ( dst , mysrc , priv - > stridePlaneRGB ) ;
dst + = priv - > stridePlaneRGB ;
}
2001-05-11 21:36:30 +00:00
}
2001-06-22 19:56:41 +00:00
else memcpy ( dst , src [ 0 ] , priv - > framePlaneRGB ) ;
2001-06-23 10:18:23 +00:00
SDL_SRF_UNLOCK ( priv - > rgbsurface )
2001-05-11 21:36:30 +00:00
}
2001-04-25 20:43:45 +00:00
break ;
2001-02-24 20:28:24 +00:00
}
return 0 ;
}
/**
* Draw a slice ( 16 rows of image ) to the SDL YUV overlay .
*
* params : * src [ ] = = the Y , U , and V planes that make up the slice .
* returns : non - zero on error , zero on success .
* */
//static uint32_t draw_slice(uint8_t *src[], uint32_t slice_num)
static uint32_t draw_slice ( uint8_t * image [ ] , int stride [ ] , int w , int h , int x , int y )
{
struct sdl_priv_s * priv = & sdl_priv ;
uint8_t * dst ;
uint8_t * src ;
int i ;
2001-06-23 10:18:23 +00:00
SDL_OVR_LOCK
2001-02-24 20:28:24 +00:00
dst = ( uint8_t * ) * ( priv - > overlay - > pixels )
+ ( priv - > stridePlaneY * y + x ) ;
src = image [ 0 ] ;
for ( i = 0 ; i < h ; i + + ) {
memcpy ( dst , src , w ) ;
src + = stride [ 0 ] ;
dst + = priv - > stridePlaneY ;
}
x / = 2 ; y / = 2 ; w / = 2 ; h / = 2 ;
dst = ( uint8_t * ) * ( priv - > overlay - > pixels ) + priv - > framePlaneY
+ ( priv - > stridePlaneUV * y + x ) ;
src = image [ 2 ] ;
for ( i = 0 ; i < h ; i + + ) {
memcpy ( dst , src , w ) ;
src + = stride [ 2 ] ;
dst + = priv - > stridePlaneUV ;
}
dst = ( uint8_t * ) * ( priv - > overlay - > pixels ) + priv - > framePlaneY
+ priv - > framePlaneUV + ( priv - > stridePlaneUV * y + x ) ;
src = image [ 1 ] ;
for ( i = 0 ; i < h ; i + + ) {
memcpy ( dst , src , w ) ;
src + = stride [ 1 ] ;
dst + = priv - > stridePlaneUV ;
}
2001-06-23 10:18:23 +00:00
SDL_OVR_UNLOCK
2001-02-24 20:28:24 +00:00
return 0 ;
}
/**
* Checks for SDL keypress and window resize events
*
* params : none
* returns : doesn ' t return
* */
# include "../linux/keycodes.h"
extern void mplayer_put_key ( int code ) ;
2002-02-04 19:14:40 +00:00
# define shift_key (event.key.keysym.mod==(KMOD_LSHIFT||KMOD_RSHIFT))
2001-02-24 20:28:24 +00:00
static void check_events ( void )
{
struct sdl_priv_s * priv = & sdl_priv ;
SDL_Event event ;
2001-04-10 21:41:31 +00:00
SDLKey keypressed = 0 ;
static int firstcheck = 0 ;
2001-02-24 20:28:24 +00:00
/* Poll the waiting SDL Events */
while ( SDL_PollEvent ( & event ) ) {
switch ( event . type ) {
/* capture window resize events */
case SDL_VIDEORESIZE :
2001-10-04 11:42:21 +00:00
if ( ! priv - > dblit ) priv - > surface = SDL_SetVideoMode ( event . resize . w , event . resize . h , priv - > bpp , priv - > sdlflags ) ;
2001-02-24 20:28:24 +00:00
/* save video extents, to restore them after going fullscreen */
//if(!(priv->surface->flags & SDL_FULLSCREEN)) {
priv - > windowsize . w = priv - > surface - > w ;
priv - > windowsize . h = priv - > surface - > h ;
//}
2001-04-25 20:43:45 +00:00
if ( verbose > 2 ) printf ( " SDL: Window resize \n " ) ;
2001-02-24 20:28:24 +00:00
break ;
/* graphics mode selection shortcuts */
2001-05-05 21:38:33 +00:00
# ifdef BUGGY_SDL
2001-04-25 20:43:45 +00:00
case SDL_KEYDOWN :
2001-05-05 21:38:33 +00:00
switch ( event . key . keysym . sym ) {
2001-06-13 15:03:27 +00:00
case SDLK_UP : mplayer_put_key ( KEY_UP ) ; break ;
case SDLK_DOWN : mplayer_put_key ( KEY_DOWN ) ; break ;
case SDLK_LEFT : mplayer_put_key ( KEY_LEFT ) ; break ;
case SDLK_RIGHT : mplayer_put_key ( KEY_RIGHT ) ; break ;
2002-02-04 19:14:40 +00:00
case SDLK_LESS : mplayer_put_key ( shift_key ? ' > ' : ' < ' ) ; break ;
case SDLK_GREATER : mplayer_put_key ( ' > ' ) ; break ;
2001-05-05 21:38:33 +00:00
case SDLK_ASTERISK :
case SDLK_KP_MULTIPLY :
2001-06-13 15:03:27 +00:00
case SDLK_w : mplayer_put_key ( ' * ' ) ; break ;
2001-05-05 21:38:33 +00:00
case SDLK_SLASH :
case SDLK_KP_DIVIDE :
2001-06-13 15:03:27 +00:00
case SDLK_s : mplayer_put_key ( ' / ' ) ; break ;
default : break ;
2001-05-05 21:38:33 +00:00
}
break ;
case SDL_KEYUP :
# else
case SDL_KEYDOWN :
# endif
2001-02-24 20:28:24 +00:00
keypressed = event . key . keysym . sym ;
2001-05-05 20:13:37 +00:00
if ( verbose > 1 ) printf ( " SDL: Key pressed: '%i' \n " , keypressed ) ;
2001-04-01 00:08:26 +00:00
2001-04-11 20:11:21 +00:00
/* c key pressed. c cycles through available fullscreenmodes, if we have some */
2001-04-11 20:00:55 +00:00
if ( ( ( keypressed = = SDLK_c ) ) & & ( priv - > fullmodes ) ) {
2001-02-24 20:28:24 +00:00
/* select next fullscreen mode */
priv - > fullmode + + ;
if ( priv - > fullmode > ( findArrayEnd ( priv - > fullmodes ) - 1 ) ) priv - > fullmode = 0 ;
set_fullmode ( priv - > fullmode ) ;
2001-04-25 20:43:45 +00:00
if ( verbose > 1 ) printf ( " SDL: Set next available fullscreen mode. \n " ) ;
2001-02-24 20:28:24 +00:00
}
2001-04-10 21:41:31 +00:00
/* f key pressed toggles/exits fullscreenmode */
else if ( keypressed = = SDLK_f ) {
2001-04-01 00:08:26 +00:00
if ( priv - > surface - > flags & SDL_FULLSCREEN ) {
2001-02-24 20:28:24 +00:00
priv - > surface = SDL_SetVideoMode ( priv - > windowsize . w , priv - > windowsize . h , priv - > bpp , priv - > sdlflags ) ;
SDL_ShowCursor ( 1 ) ;
2001-04-25 20:43:45 +00:00
if ( verbose > 1 ) printf ( " SDL: Windowed mode \n " ) ;
2001-02-24 20:28:24 +00:00
}
else if ( priv - > fullmodes ) {
set_fullmode ( priv - > fullmode ) ;
2001-04-25 20:43:45 +00:00
if ( verbose > 1 ) printf ( " SDL: Set fullscreen mode \n " ) ;
2001-02-24 20:28:24 +00:00
}
}
2001-07-28 05:54:02 +00:00
else if ( keypressed = = SDLK_n ) {
2001-10-13 13:38:59 +00:00
# ifdef HAVE_X11
2001-10-18 02:42:20 +00:00
aspect ( & priv - > dstwidth , & priv - > dstheight , A_NOZOOM ) ;
2001-10-13 13:38:59 +00:00
# endif
2001-10-18 02:42:20 +00:00
if ( priv - > surface - > w ! = priv - > dstwidth | | priv - > surface - > h ! = priv - > dstheight ) {
priv - > surface = SDL_SetVideoMode ( priv - > dstwidth , priv - > dstheight , priv - > bpp , priv - > sdlflags ) ;
2001-07-28 05:54:02 +00:00
priv - > windowsize . w = priv - > surface - > w ;
priv - > windowsize . h = priv - > surface - > h ;
if ( verbose > 1 ) printf ( " SDL: Normal size \n " ) ;
2001-08-14 08:18:52 +00:00
} else
2001-10-18 02:42:20 +00:00
if ( priv - > surface - > w ! = priv - > dstwidth * 2 | | priv - > surface - > h ! = priv - > dstheight * 2 ) {
priv - > surface = SDL_SetVideoMode ( priv - > dstwidth * 2 , priv - > dstheight * 2 , priv - > bpp , priv - > sdlflags ) ;
2001-07-28 05:54:02 +00:00
priv - > windowsize . w = priv - > surface - > w ;
priv - > windowsize . h = priv - > surface - > h ;
if ( verbose > 1 ) printf ( " SDL: Double size \n " ) ;
}
}
2001-08-14 08:18:52 +00:00
2001-02-24 20:28:24 +00:00
else switch ( keypressed ) {
2001-04-10 21:41:31 +00:00
case SDLK_RETURN :
if ( ! firstcheck ) { firstcheck = 1 ; break ; }
case SDLK_ESCAPE :
case SDLK_q :
SDL_ShowCursor ( 1 ) ;
mplayer_put_key ( ' q ' ) ;
break ;
2001-04-16 17:19:28 +00:00
/*case SDLK_o: mplayer_put_key('o');break;
2001-04-22 10:45:01 +00:00
case SDLK_SPACE : mplayer_put_key ( ' ' ) ; break ;
case SDLK_p : mplayer_put_key ( ' p ' ) ; break ; */
2002-02-04 19:14:40 +00:00
case SDLK_7 : mplayer_put_key ( shift_key ? ' / ' : ' 7 ' ) ;
case SDLK_PLUS : mplayer_put_key ( shift_key ? ' * ' : ' + ' ) ;
2001-02-24 20:28:24 +00:00
case SDLK_KP_PLUS : mplayer_put_key ( ' + ' ) ; break ;
case SDLK_MINUS :
2001-04-22 10:45:01 +00:00
case SDLK_KP_MINUS : mplayer_put_key ( ' - ' ) ; break ;
2001-04-25 21:04:56 +00:00
case SDLK_TAB : mplayer_put_key ( ' \t ' ) ; break ;
2001-04-26 22:16:57 +00:00
case SDLK_PAGEUP : mplayer_put_key ( KEY_PAGE_UP ) ; break ;
case SDLK_PAGEDOWN : mplayer_put_key ( KEY_PAGE_DOWN ) ; break ;
2001-05-05 21:38:33 +00:00
# ifdef BUGGY_SDL
case SDLK_UP :
case SDLK_DOWN :
case SDLK_LEFT :
case SDLK_RIGHT :
case SDLK_ASTERISK :
case SDLK_KP_MULTIPLY :
case SDLK_w :
case SDLK_SLASH :
case SDLK_KP_DIVIDE :
case SDLK_s :
break ;
# else
2001-05-05 20:13:37 +00:00
case SDLK_UP : mplayer_put_key ( KEY_UP ) ; break ;
case SDLK_DOWN : mplayer_put_key ( KEY_DOWN ) ; break ;
case SDLK_LEFT : mplayer_put_key ( KEY_LEFT ) ; break ;
case SDLK_RIGHT : mplayer_put_key ( KEY_RIGHT ) ; break ;
2002-02-04 19:14:40 +00:00
case SDLK_LESS : mplayer_put_key ( shift_key ? ' > ' : ' < ' ) ; break ;
case SDLK_GREATER : mplayer_put_key ( ' > ' ) ; break ;
2001-05-05 20:13:37 +00:00
case SDLK_ASTERISK :
case SDLK_KP_MULTIPLY :
case SDLK_w : mplayer_put_key ( ' * ' ) ; break ;
case SDLK_SLASH :
case SDLK_KP_DIVIDE :
case SDLK_s : mplayer_put_key ( ' / ' ) ; break ;
2001-05-05 21:38:33 +00:00
# endif
2001-04-16 17:19:28 +00:00
default :
2002-02-04 19:14:40 +00:00
//printf("got scancode: %d keysym: %d mod: %d %d\n", event.key.keysym.scancode, keypressed, event.key.keysym.mod);
2001-04-16 17:19:28 +00:00
mplayer_put_key ( keypressed ) ;
2001-02-24 20:28:24 +00:00
}
break ;
2001-08-27 11:49:10 +00:00
case SDL_QUIT :
SDL_ShowCursor ( 1 ) ;
mplayer_put_key ( ' q ' ) ;
break ;
2001-02-24 20:28:24 +00:00
}
}
}
2002-02-04 19:14:40 +00:00
# undef shift_key
2001-02-24 20:28:24 +00:00
2001-08-13 11:08:18 +00:00
static void draw_osd ( void )
{ struct sdl_priv_s * priv = & sdl_priv ;
/* update osd/subtitles */
vo_draw_text ( priv - > width , priv - > height , draw_alpha ) ;
}
2001-02-24 20:28:24 +00:00
/**
2001-08-13 11:08:18 +00:00
* Display the surface we have written our data to
2001-02-24 20:28:24 +00:00
*
* params : mode = = index of the desired fullscreen mode
* returns : doesn ' t return
* */
static void flip_page ( void )
{
struct sdl_priv_s * priv = & sdl_priv ;
2001-04-25 20:43:45 +00:00
switch ( priv - > format ) {
case IMGFMT_RGB15 :
case IMGFMT_BGR15 :
case IMGFMT_RGB16 :
case IMGFMT_BGR16 :
case IMGFMT_RGB24 :
case IMGFMT_BGR24 :
case IMGFMT_RGB32 :
case IMGFMT_BGR32 :
2001-06-24 19:20:19 +00:00
if ( ! priv - > dblit ) {
2001-06-22 19:56:41 +00:00
/* blit to the RGB surface */
if ( SDL_BlitSurface ( priv - > rgbsurface , NULL , priv - > surface , NULL ) )
printf ( " SDL: Blit failed: %s \n " , SDL_GetError ( ) ) ;
}
2001-04-25 20:43:45 +00:00
/* update screen */
2001-05-13 16:38:33 +00:00
//SDL_UpdateRect(priv->surface, 0, 0, priv->surface->clip_rect.w, priv->surface->clip_rect.h);
SDL_UpdateRects ( priv - > surface , 1 , & priv - > surface - > clip_rect ) ;
2001-04-25 20:43:45 +00:00
/* check if we have a double buffered surface and flip() if we do. */
if ( priv - > surface - > flags & SDL_DOUBLEBUF )
SDL_Flip ( priv - > surface ) ;
break ;
default :
/* blit to the YUV overlay */
SDL_DisplayYUVOverlay ( priv - > overlay , & priv - > surface - > clip_rect ) ;
/* check if we have a double buffered surface and flip() if we do. */
if ( priv - > surface - > flags & SDL_DOUBLEBUF )
SDL_Flip ( priv - > surface ) ;
//SDL_LockYUVOverlay (priv->overlay); // removed because unused!?
}
2001-02-24 20:28:24 +00:00
}
static uint32_t
query_format ( uint32_t format )
{
switch ( format ) {
case IMGFMT_YV12 :
2001-04-14 17:55:20 +00:00
case IMGFMT_I420 :
case IMGFMT_IYUV :
2001-02-24 20:28:24 +00:00
case IMGFMT_YUY2 :
2001-04-14 17:55:20 +00:00
case IMGFMT_UYVY :
case IMGFMT_YVYU :
2001-04-25 20:43:45 +00:00
return 0x6 ; // hw supported & osd
case IMGFMT_RGB15 :
case IMGFMT_BGR15 :
case IMGFMT_RGB16 :
case IMGFMT_BGR16 :
case IMGFMT_RGB24 :
case IMGFMT_BGR24 :
case IMGFMT_RGB32 :
case IMGFMT_BGR32 :
return 0x5 ; // hw supported w/conversion & osd
2001-02-24 20:28:24 +00:00
}
return 0 ;
}
static const vo_info_t *
get_info ( void )
{
return & vo_info ;
}
static void
uninit ( void )
{
2001-05-11 21:36:30 +00:00
# ifdef HAVE_X11
static Display * XDisplay ;
if ( getenv ( " DISPLAY " ) ) {
if ( verbose ) printf ( " SDL: activating XScreensaver/DPMS \n " ) ;
XDisplay = XOpenDisplay ( getenv ( " DISPLAY " ) ) ;
saver_on ( XDisplay ) ;
XCloseDisplay ( XDisplay ) ;
}
# endif
2001-06-13 15:03:27 +00:00
sdl_close ( ) ;
2001-02-24 20:28:24 +00:00
}
2002-01-26 16:01:26 +00:00
static uint32_t preinit ( const char * arg )
{
return 0 ;
}
static void query_vaa ( vo_vaa_t * vaa )
{
memset ( vaa , 0 , sizeof ( vo_vaa_t ) ) ;
}