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 + -
显示快捷键?