vo_sdl.c

来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,734 行 · 第 1/4 页

C
1,734
字号
/* *  vo_sdl.c * *  (was video_out_sdl.c from OMS project/mpeg2dec -> http://linuxvideo.org) * *  Copyright (C) Ryan C. Gordon <icculus@lokigames.com> - April 22, 2000. * *  Copyright (C) Felix Buenemann <atmosfear@users.sourceforge.net> - 2001 * *  (for extensive code enhancements) * *  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/), *  to be used with MPlayer [The Movie Player for Linux] project, further info *  from http://www.mplayerhq.hu * *  -- old disclaimer -- * *  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 *  the Free Software Foundation. * *  -- end old disclaimer --  * *  Changes: *    Dominik Schnitzer <dominik@schnitzer.at> - November 08, 2000. *    - Added resizing support, fullscreen: changed the sdlmodes selection *       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 *    Felix Buenemann <Atmosfear@users.sourceforge.net> - March 11, 2001 *    - Added aspect-ratio awareness for fullscreen *    Felix Buenemann <Atmosfear@users.sourceforge.net> - March 11, 2001 *    - 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 *    - Minor bugfix to aspect-ratio for non-4:3-resolutions (like 1280x1024) *    - Bugfix to check_events() to reveal mouse cursor after 'q'-quit in *       fullscreen-mode *    Felix Buenemann <Atmosfear@users.sourceforge.net> - April 10, 2001 *    - 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) *    Felix Buenemann <Atmosfear@users.sourceforge.net> - April 11, 2001 *    - OSD and subtitle support added *    - some minor code-changes *    - added code to comply with new fullscreen meaning *    - changed fullscreen-mode-cycling from '+' to 'c' (interferred with audiosync *       adjustment) *    Felix Buenemann <Atmosfear@users.sourceforge.net> - April 13, 2001 *    - added keymapping to toggle OSD ('o' key)  *    - added some defines to modify some sdl-out internas (see comments) * *    Felix Buenemann: further changes will be visible through cvs log, don't want *     to update this all the time (CVS info on http://mplayer.sourceforge.net) * *//* define to force software-surface (video surface stored in system memory)*/#undef SDL_NOHWSURFACE/* define to enable surface locks, this might be needed on SMP machines */#undef SDL_ENABLE_LOCKS//#define BUGGY_SDL //defined by configure/* MONITOR_ASPECT MUST BE FLOAT */#define MONITOR_ASPECT 4.0/3.0#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <inttypes.h>#include "mp_msg.h"#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include "video_out.h"#include "video_out_internal.h"#include "fastmemcpy.h"#include "sub.h"#include "aspect.h"#include "libmpcodecs/vfcap.h"#ifdef HAVE_X11#include <X11/Xlib.h>#include "x11_common.h"#endif#include "input/input.h"#include "input/mouse.h"#include "subopt-helper.h"#include "mp_fifo.h"static vo_info_t info = {	"SDL YUV/RGB/BGR renderer (SDL v1.1.7+ only!)",	"sdl",	"Ryan C. Gordon <icculus@lokigames.com>, Felix Buenemann <atmosfear@users.sourceforge.net>",	""};LIBVO_EXTERN(sdl)#include <SDL.h>//#include <SDL/SDL_syswm.h>#ifdef SDL_ENABLE_LOCKS#define	SDL_OVR_LOCK(x)        if (SDL_LockYUVOverlay (priv->overlay)) { \				if( mp_msg_test(MSGT_VO,MSGL_V) ) { \ 				  mp_msg(MSGT_VO,MSGL_V, "SDL: Couldn't lock YUV overlay\n"); } \				return x; \	    		    }#define SDL_OVR_UNLOCK      SDL_UnlockYUVOverlay (priv->overlay);#define SDL_SRF_LOCK(srf, x)   if(SDL_MUSTLOCK(srf)) { \				if(SDL_LockSurface (srf)) { \					if( mp_msg_test(MSGT_VO,MSGL_V) ) { \ 					  mp_msg(MSGT_VO,MSGL_V, "SDL: Couldn't lock RGB surface\n"); } \					return x; \				} \			    }#define SDL_SRF_UNLOCK(srf) if(SDL_MUSTLOCK(srf)) \				SDL_UnlockSurface (srf);#else#define SDL_OVR_LOCK(x)#define SDL_OVR_UNLOCK#define SDL_SRF_LOCK(srf, x)#define SDL_SRF_UNLOCK(srf)#endif/** Private SDL Data structure **/static struct sdl_priv_s {	/* output driver used by sdl */	char driver[8];		/* SDL display surface */	SDL_Surface *surface;		/* SDL RGB surface */	SDL_Surface *rgbsurface;		/* SDL YUV overlay */	SDL_Overlay *overlay;	/* 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;	/* RGB or YUV? */	Uint8 mode;	#define YUV 0	#define RGB 1	#define BGR 2	/* use direct blitting to surface */	int dblit;	/* current fullscreen mode, 0 = highest available fullscreen mode */	int fullmode;	/* YUV ints */	int framePlaneY, framePlaneUV, framePlaneYUY;	int stridePlaneY, stridePlaneUV, stridePlaneYUY;		/* RGB ints */	int framePlaneRGB;	int stridePlaneRGB;	/* Flip image */	int flip;	/* fullscreen behaviour; see init */	int fulltype;	/* is X running (0/1) */	int X;	/* X11 Resolution */	int XWidth, XHeight;	        /* original image dimensions */	int width, height;	/* destination dimensions */	int dstwidth, dstheight;    /* Draw image at coordinate y on the SDL surfaces */    int y;    /* The image is displayed between those y coordinates in priv->surface */    int y_screen_top, y_screen_bottom;    /* 1 if the OSD has changed otherwise 0 */    int osd_has_changed;    	/* source image format (YUV/RGB/...) */    uint32_t format;    /* dirty_off_frame[0] contains a bounding box around the osd contents drawn above the image       dirty_off_frame[1] is the corresponding thing for OSD contents drawn below the image    */    SDL_Rect dirty_off_frame[2];} sdl_priv;static void erase_area_4(int x_start, int width, int height, int pitch, uint32_t color, uint8_t* pixels);static void erase_area_1(int x_start, int width, int height, int pitch, uint8_t color, uint8_t* pixels);static int setup_surfaces(void);static void set_video_mode(int width, int height, int bpp, uint32_t sdlflags);static void erase_rectangle(int x, int y, int w, int h);/* Expand 'rect' to contain the rectangle specified by x, y, w and h */static void expand_rect(SDL_Rect* rect, int x, int y, int w, int h){    if(rect->x < 0 || rect->y < 0) {        rect->x = x;        rect->y = y;        rect->w = w;        rect->h = h;        return;    }        if(rect->x > x)        rect->x = x;    if(rect->y > y)        rect->y = y;    if(rect->x + rect->w < x + w)        rect->w = x + w - rect->x;    if(rect->y + rect->h < y + h)        rect->h = y + h - rect->y;}/** 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){	struct sdl_priv_s *priv = &sdl_priv;	    if(priv->osd_has_changed) {        /* OSD did change. Store a bounding box of everything drawn into the OSD */        if(priv->y >= y0) {            /* Make sure we don't mark part of the frame area dirty */            if(h + y0 > priv->y)                 expand_rect(&priv->dirty_off_frame[0], x0, y0, w, priv->y - y0);            else                expand_rect(&priv->dirty_off_frame[0], x0, y0, w, h);        }        else if(priv->y + priv->height <= y0 + h) {            /* Make sure we don't mark part of the frame area dirty */            if(y0 < priv->y + priv->height)                 expand_rect(&priv->dirty_off_frame[1], x0,                            priv->y + priv->height,                            w, h - ((priv->y + priv->height) - y0));            else                expand_rect(&priv->dirty_off_frame[1], x0, y0, w, h);        }    }    else { /* OSD contents didn't change only draw parts that was erased by the frame */        if(priv->y >= y0) {           src = src + (priv->y - y0) * stride;           srca = srca + (priv->y - y0) * stride;           h -= priv->y - y0;           y0 = priv->y;        }        if(priv->y + priv->height <= y0 + h)            h = priv->y + priv->height - y0;        if(h <= 0)            return;    }	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->overlay->pitches[0]*y0+x0,priv->overlay->pitches[0]);		break;		case IMGFMT_YUY2:        	case IMGFMT_YVYU:                x0 *= 2;    			vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) *(priv->overlay->pixels))+priv->overlay->pitches[0]*y0+x0,priv->overlay->pitches[0]);		break;	        	case IMGFMT_UYVY:                x0 *= 2;    			vo_draw_alpha_yuy2(w,h,src,srca,stride,((uint8_t *) *(priv->overlay->pixels))+priv->overlay->pitches[0]*y0+x0,priv->overlay->pitches[0]);		break;		default:        if(priv->dblit) {            x0 *= priv->surface->format->BytesPerPixel;		switch(priv->format) {		case IMGFMT_RGB15:		case IMGFMT_BGR15:    			vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) priv->surface->pixels)+y0*priv->surface->pitch+x0,priv->surface->pitch);		break;		case IMGFMT_RGB16:		case IMGFMT_BGR16:    			vo_draw_alpha_rgb16(w,h,src,srca,stride,((uint8_t *) priv->surface->pixels)+y0*priv->surface->pitch+x0,priv->surface->pitch);		break;		case IMGFMT_RGB24:		case IMGFMT_BGR24:    			vo_draw_alpha_rgb24(w,h,src,srca,stride,((uint8_t *) priv->surface->pixels)+y0*priv->surface->pitch+x0,priv->surface->pitch);		break;		case IMGFMT_RGB32:		case IMGFMT_BGR32:    			vo_draw_alpha_rgb32(w,h,src,srca,stride,((uint8_t *) priv->surface->pixels)+y0*priv->surface->pitch+x0,priv->surface->pitch);		break;		}        }		else {            x0 *= priv->rgbsurface->format->BytesPerPixel;		switch(priv->format) {		case IMGFMT_RGB15:		case IMGFMT_BGR15:    			vo_draw_alpha_rgb15(w,h,src,srca,stride,((uint8_t *) priv->rgbsurface->pixels)+y0*priv->rgbsurface->pitch+x0,priv->rgbsurface->pitch);		break;		case IMGFMT_RGB16:		case IMGFMT_BGR16:    			vo_draw_alpha_rgb16(w,h,src,srca,stride,((uint8_t *) priv->rgbsurface->pixels)+y0*priv->rgbsurface->pitch+x0,priv->rgbsurface->pitch);		break;		case IMGFMT_RGB24:		case IMGFMT_BGR24:    			vo_draw_alpha_rgb24(w,h,src,srca,stride,((uint8_t *) priv->rgbsurface->pixels)+y0*priv->rgbsurface->pitch+x0,priv->rgbsurface->pitch);		break;		case IMGFMT_RGB32:		case IMGFMT_BGR32:    			vo_draw_alpha_rgb32(w,h,src,srca,stride,((uint8_t *) priv->rgbsurface->pixels)+y0*priv->rgbsurface->pitch+x0,priv->rgbsurface->pitch);		break;		}        }          	}	}/** * 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 **/  static int sdl_open (void *plugin, void *name){	struct sdl_priv_s *priv = &sdl_priv;	const SDL_VideoInfo *vidInfo = NULL;	/*static int opened = 0;		if (opened)	    return 0;	opened = 1;*/	/* other default values */	#ifdef SDL_NOHWSURFACE		if( mp_msg_test(MSGT_VO,MSGL_V) ) {			mp_msg(MSGT_VO,MSGL_V, "SDL: using software-surface\n"); }		priv->sdlflags = SDL_SWSURFACE|SDL_RESIZABLE|SDL_ANYFORMAT;		priv->sdlfullflags = SDL_SWSURFACE|SDL_FULLSCREEN|SDL_ANYFORMAT;		// XXX:FIXME: ASYNCBLIT should be enabled for SMP systems	#else	

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?