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