vo_sdl.c

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

C
1,734
字号
 		    mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SDL_InfoPleaseUseVmOrZoom);		priv->fulltype = VOFLAG_FULLSCREEN;		set_fullmode(priv->fullmode);          	/*if((priv->surface = SDL_SetVideoMode (d_width, d_height, priv->bpp, priv->sdlfullflags)))			SDL_ShowCursor(0);*/	} else		if(flags&VOFLAG_MODESWITCHING) {	 	if( mp_msg_test(MSGT_VO,MSGL_V) ) { 	 		mp_msg(MSGT_VO,MSGL_V, "SDL: setting zoomed fullscreen with modeswitching\n"); }		priv->fulltype = VOFLAG_MODESWITCHING;		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);*/	} else	if(flags&VOFLAG_SWSCALE) {	 	if( mp_msg_test(MSGT_VO,MSGL_V) ) {			mp_msg(MSGT_VO,MSGL_V, "SDL: setting zoomed fullscreen with modeswitching\n"); }		priv->fulltype = VOFLAG_SWSCALE;		set_fullmode(priv->fullmode);	}         else {		if((strcmp(priv->driver, "x11") == 0)		||(strcmp(priv->driver, "windib") == 0)		||(strcmp(priv->driver, "directx") == 0)		||(strcmp(priv->driver, "Quartz") == 0)		||(strcmp(priv->driver, "cgx") == 0)		||(strcmp(priv->driver, "os4video") == 0)		||((strcmp(priv->driver, "aalib") == 0) && priv->X)){			if( mp_msg_test(MSGT_VO,MSGL_V) ) { 				mp_msg(MSGT_VO,MSGL_V, "SDL: setting windowed mode\n"); }            set_video_mode(priv->dstwidth, priv->dstheight, priv->bpp, priv->sdlflags);		}		else {			if( mp_msg_test(MSGT_VO,MSGL_V) ) { 				mp_msg(MSGT_VO,MSGL_V, "SDL: setting zoomed fullscreen with modeswitching\n"); }			priv->fulltype = VOFLAG_SWSCALE;			set_fullmode(priv->fullmode);		}		}        if(!priv->surface) { // cannot SetVideoMode 		mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SDL_FailedToSetVideoMode, SDL_GetError());		return -1;	}		return 0;}/* Free priv->rgbsurface or priv->overlay if they are != NULL. * Setup priv->rgbsurface or priv->overlay depending on source format. * The size of the created surface or overlay depends on the size of * priv->surface, priv->width, priv->height, priv->dstwidth and priv->dstheight. */static int setup_surfaces(void){    struct sdl_priv_s *priv = &sdl_priv;    float v_scale = ((float) priv->dstheight) / priv->height;    int surfwidth, surfheight;    surfwidth = priv->width;    surfheight = priv->height + (priv->surface->h - priv->dstheight) / v_scale;    surfheight&= ~1;    /* Place the image in the middle of the screen */    priv->y = (surfheight - priv->height) / 2;    priv->y_screen_top = priv->y * v_scale;    priv->y_screen_bottom = priv->y_screen_top + priv->dstheight;    priv->dirty_off_frame[0].x = -1;    priv->dirty_off_frame[0].y = -1;    priv->dirty_off_frame[1].x = -1;    priv->dirty_off_frame[1].y = -1;    /* Make sure the entire screen is updated */    vo_osd_changed(1);    if(priv->rgbsurface)        SDL_FreeSurface(priv->rgbsurface);    else if(priv->overlay)        SDL_FreeYUVOverlay(priv->overlay);    priv->rgbsurface = NULL;    priv->overlay = NULL;        if(priv->mode != YUV && (priv->format&0xFF) == priv->bpp) {		if(strcmp(priv->driver, "x11") == 0) {            priv->dblit = 1;            priv->framePlaneRGB = priv->width * priv->height * priv->surface->format->BytesPerPixel;            priv->stridePlaneRGB = priv->width * priv->surface->format->BytesPerPixel;            erase_rectangle(0, 0, priv->surface->w, priv->surface->h);            return 0;        }	}	switch(priv->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:            priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, surfwidth, surfheight, 15, 31, 992, 31744, 0);	    break;		    case IMGFMT_BGR15:            priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, surfwidth, surfheight, 15, 31744, 992, 31, 0);	    break;		    case IMGFMT_RGB16:            priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, surfwidth, surfheight, 16, 31, 2016, 63488, 0);	    break;		    case IMGFMT_BGR16:            priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, surfwidth, surfheight, 16, 63488, 2016, 31, 0);	    break;		    case IMGFMT_RGB24:            priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, surfwidth, surfheight, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);	    break;		    case IMGFMT_BGR24:            priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, surfwidth, surfheight, 24, 0xFF0000, 0x00FF00, 0x0000FF, 0);	    break;		    case IMGFMT_RGB32:            priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, surfwidth, surfheight, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0/*0xFF000000*/);	    break;		    case IMGFMT_BGR32:            priv->rgbsurface = SDL_CreateRGBSurface (SDL_SRCCOLORKEY, surfwidth, surfheight, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0/*0xFF000000*/);	    break;		    default:		/* Initialize and create the YUV Overlay used for video out */		if (!(priv->overlay = SDL_CreateYUVOverlay (surfwidth, surfheight, priv->format, priv->surface))) {			mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SDL_CouldntCreateAYUVOverlay, SDL_GetError());			return -1;		}		priv->framePlaneY = priv->width * priv->height;		priv->framePlaneUV = (priv->width * priv->height) >> 2;		priv->framePlaneYUY = priv->width * priv->height * 2;		priv->stridePlaneY = priv->width;		priv->stridePlaneUV = priv->width/2;		priv->stridePlaneYUY = priv->width * 2;	}	    if(priv->mode != YUV) {        if(!priv->rgbsurface) {            mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SDL_CouldntCreateARGBSurface, SDL_GetError());            return -1;        }        priv->dblit = 0;        if((priv->format&0xFF) != priv->bpp)            mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SDL_UsingDepthColorspaceConversion, priv->format&0xFF, priv->bpp);        priv->framePlaneRGB = priv->width * priv->height * priv->rgbsurface->format->BytesPerPixel;        priv->stridePlaneRGB = priv->width * priv->rgbsurface->format->BytesPerPixel;    }        erase_rectangle(0, 0, surfwidth, surfheight);	return 0;}/** * 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 int draw_frame(uint8_t *src[]){	struct sdl_priv_s *priv = &sdl_priv;	uint8_t *dst;	int i;	uint8_t *mysrc = src[0];    switch(priv->format){        case IMGFMT_YUY2:        case IMGFMT_UYVY:        case IMGFMT_YVYU:        SDL_OVR_LOCK(-1)        dst = (uint8_t *) *(priv->overlay->pixels) + priv->overlay->pitches[0]*priv->y;	    if(priv->flip) {	    	mysrc+=priv->framePlaneYUY;		for(i = 0; i < priv->height; i++) {			mysrc-=priv->stridePlaneYUY;			fast_memcpy (dst, mysrc, priv->stridePlaneYUY);                dst+=priv->overlay->pitches[0];		}	    }	    else fast_memcpy (dst, src[0], priv->framePlaneYUY);	    SDL_OVR_UNLOCK            break;		case IMGFMT_RGB15:	case IMGFMT_BGR15:		case IMGFMT_RGB16:	case IMGFMT_BGR16:		case IMGFMT_RGB24:	case IMGFMT_BGR24:		case IMGFMT_RGB32:	case IMGFMT_BGR32:		if(priv->dblit) {			SDL_SRF_LOCK(priv->surface, -1)			dst = (uint8_t *) priv->surface->pixels + priv->y*priv->surface->pitch;			if(priv->flip) {				mysrc+=priv->framePlaneRGB;				for(i = 0; i < priv->height; i++) {					mysrc-=priv->stridePlaneRGB;					fast_memcpy (dst, mysrc, priv->stridePlaneRGB);					dst += priv->surface->pitch;				}			}			else fast_memcpy (dst, src[0], priv->framePlaneRGB);			SDL_SRF_UNLOCK(priv->surface)		} else {			SDL_SRF_LOCK(priv->rgbsurface, -1)			dst = (uint8_t *) priv->rgbsurface->pixels + priv->y*priv->rgbsurface->pitch;			if(priv->flip) {				mysrc+=priv->framePlaneRGB;				for(i = 0; i < priv->height; i++) {					mysrc-=priv->stridePlaneRGB;					fast_memcpy (dst, mysrc, priv->stridePlaneRGB);					dst += priv->rgbsurface->pitch;				}			}			else fast_memcpy (dst, src[0], priv->framePlaneRGB);			SDL_SRF_UNLOCK(priv->rgbsurface)		}		break;        }        		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 int 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;    SDL_OVR_LOCK(-1)    y += priv->y;        dst = priv->overlay->pixels[0] + priv->overlay->pitches[0]*y + x;    memcpy_pic(dst, image[0], w, h, priv->overlay->pitches[0], stride[0]);    x/=2;y/=2;w/=2;h/=2;    switch(priv->format) {    case IMGFMT_YV12:        dst = priv->overlay->pixels[2] + priv->overlay->pitches[2]*y + x;	memcpy_pic(dst, image[1], w, h, priv->overlay->pitches[2], stride[1]);        dst = priv->overlay->pixels[1] + priv->overlay->pitches[1]*y + x;	memcpy_pic(dst, image[2], w, h, priv->overlay->pitches[1], stride[2]);    break;    case IMGFMT_I420:    case IMGFMT_IYUV:        dst = priv->overlay->pixels[1] + priv->overlay->pitches[1]*y + x;	memcpy_pic(dst, image[1], w, h, priv->overlay->pitches[1], stride[1]);        dst = priv->overlay->pixels[2] + priv->overlay->pitches[2]*y + x;	memcpy_pic(dst, image[2], w, h, priv->overlay->pitches[2], stride[2]);    break;    default:	mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SDL_UnsupportedImageFormatInDrawslice);    }	SDL_OVR_UNLOCK	return 0;}/** * Checks for SDL keypress and window resize events * *   params : none *  returns : doesn't return **/#include "osdep/keycodes.h"#define shift_key (event.key.keysym.mod==(KMOD_LSHIFT||KMOD_RSHIFT)) static void check_events (void){	struct sdl_priv_s *priv = &sdl_priv;	SDL_Event event;	SDLKey keypressed = 0;		/* Poll the waiting SDL Events */	while ( SDL_PollEvent(&event) ) {		switch (event.type) {			/* capture window resize events */			case SDL_VIDEORESIZE:				if(!priv->dblit)                    set_video_mode(event.resize.w, event.resize.h, priv->bpp, priv->sdlflags);				/* 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;				//}				if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { 					mp_msg(MSGT_VO,MSGL_DBG3, "SDL: Window resize\n"); }			break;						case SDL_MOUSEBUTTONDOWN:				if(vo_nomouse_input)				    break;					mplayer_put_key((MOUSE_BTN0+event.button.button-1) | MP_KEY_DOWN);				break;			    					case SDL_MOUSEBUTTONUP:				if(vo_nomouse_input)				    break;				mplayer_put_key(MOUSE_BTN0+event.button.button-1);				break;				/* graphics mode selection shortcuts */#ifdef BUGGY_SDL			case SDL_KEYDOWN:				switch(event.key.keysym.sym) {                                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;                                case SDLK_LESS: mplayer_put_key(shift_key?'>':'<'); break;                                case SDLK_GREATER: mplayer_put_key('>'); break;                                case SDLK_ASTERISK:				case SDLK_KP_MULTIPLY:				case SDLK_SLASH:				case SDLK_KP_DIVIDE:				default: break;				}			break;			case SDL_KEYUP:#else						case SDL_KEYDOWN:#endif							keypressed = event.key.keysym.sym;				if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { 					mp_msg(MSGT_VO,MSGL_DBG2, "SDL: Key pressed: '%i'\n", keypressed); }				/* c key pressed. c cycles through available fullscreenmodes, if we have some */				if ( ((keypressed == SDLK_c)) && (priv->fullmodes) ) {					/* select next fullscreen mode */					priv->fullmode++;					if (priv->fullmode > (findArrayEnd(priv->fullmodes) - 1)) priv->fullmode = 0;					set_fullmode(priv->fullmode);						if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { 						mp_msg(MSGT_VO,MSGL_DBG2, "SDL: Set next available fullscreen mode.\n"); }				}				else if ( keypressed == SDLK_n ) {#ifdef HAVE_X11										aspect(&priv->dstwidth, &priv->dstheight,A_NOZOOM);#endif										if (priv->surface->w != priv->dstwidth || priv->surface->h != priv->dstheight) {                        set_video_mode(priv->dstwidth, priv->dstheight, priv->bpp, priv->sdlflags);					    	priv->windowsize.w = priv->surface->w;						priv->windowsize.h = priv->surface->h;						if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { 							mp_msg(MSGT_VO,MSGL_DBG2, "SDL: Normal size\n"); }					} else					if (priv->surface->w != priv->dstwidth * 2 || priv->surface->h != priv->dstheight * 2) {                        set_video_mode(priv->dstwidth * 2, priv->dstheight * 2, priv->bpp, priv->sdlflags);					    	priv->windowsize.w = priv->surface->w;						priv->windowsize.h = priv->surface->h;						if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { 							mp_msg(MSGT_VO,MSGL_DBG2, "SDL: Double size\n"); }					}				}	                                else switch(keypressed){				case SDLK_RETURN: mplayer_put_key(KEY_ENTER);break;                                case SDLK_ESCAPE: mplayer_put_key(KEY_ESC);break;				case SDLK_q: mplayer_put_key('q');break; 				case SDLK_F1: mplayer_put_key(KEY_F+1);break; 				case SDLK_F2: mplayer_put_key(KEY_F+2);break; 				case SDLK_F3: mplayer_put_key(KEY_F+3);break; 				case SDLK_F4: mplayer_put_key(KEY_F+4);break; 				case SDLK_F5: mplayer_put_key(KEY_F+5);break; 				case SDLK_F6: mplayer_put_key(KEY_F+6);break; 				case SDLK_F7: mplayer_put_key(KEY_F+7);break; 				case SDLK_F8: mplayer_put_key(KEY_F+8);break; 				case SDLK_F9: mplayer_put_key(KEY_F+9);break; 				case SDLK_F10: mplayer_put_key(KEY_F+10);break; 				case SDLK_F11: mplayer_put_key(KEY_F+11);break; 				case SDLK_F12: mplayer_put_key(KEY_F+12);break;                                /*case SDLK_o: mplayer_put_key('o');break;                                case SDLK_SPACE: mplayer_put_key(' ');break;                                case SDLK_p: mplayer_put_key('p');break;*/				case SDLK_7: mplayer_put_key(shift_key?'/':'7');                                case SDLK_PLUS: mplayer_put_key(shift_key?'*':'+');                                case SDLK_KP_PLUS: mplayer_put_key('+');break;                                case SDLK_MINUS:                                case SDLK_KP_MINUS: mplayer_put_key('-');break;				case SDLK_TAB: mplayer_put_key('\t');break;				case SDLK_PAGEUP: mplayer_put_key(KEY_PAGE_UP);break;				case SDLK_PAGEDOWN: mplayer_put_key(KEY_PAGE_DOWN);break;  #ifdef BUGGY_SDL                                case SDLK_UP:                                case SDLK_DOWN:                                case SDLK_LEFT:                                case SDLK_RIGHT:                                case SDLK_ASTERISK:				case SDLK_KP_MULTIPLY:				case SDLK_SLASH:				case SDLK_KP_DIVIDE:				break;#else				                                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;                                case SDLK_LESS: mplayer_put_key(shift_key?'>':'<'); break;                                case SDLK_GREATER: mplayer_put_key('>'); break;                                case SDLK_ASTERISK:

⌨️ 快捷键说明

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