vo_sdl.c
来自「君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图」· C语言 代码 · 共 1,734 行 · 第 1/4 页
C
1,734 行
case SDLK_KP_MULTIPLY: mplayer_put_key('*'); break; case SDLK_SLASH: case SDLK_KP_DIVIDE: mplayer_put_key('/'); break;#endif case SDLK_KP0: mplayer_put_key(KEY_KP0); break; case SDLK_KP1: mplayer_put_key(KEY_KP1); break; case SDLK_KP2: mplayer_put_key(KEY_KP2); break; case SDLK_KP3: mplayer_put_key(KEY_KP3); break; case SDLK_KP4: mplayer_put_key(KEY_KP4); break; case SDLK_KP5: mplayer_put_key(KEY_KP5); break; case SDLK_KP6: mplayer_put_key(KEY_KP6); break; case SDLK_KP7: mplayer_put_key(KEY_KP7); break; case SDLK_KP8: mplayer_put_key(KEY_KP8); break; case SDLK_KP9: mplayer_put_key(KEY_KP9); break; case SDLK_KP_PERIOD: mplayer_put_key(KEY_KPDEC); break; case SDLK_KP_ENTER: mplayer_put_key(KEY_KPENTER); break; default: //printf("got scancode: %d keysym: %d mod: %d %d\n", event.key.keysym.scancode, keypressed, event.key.keysym.mod); mplayer_put_key(keypressed); } break; case SDL_QUIT: mplayer_put_key(KEY_CLOSE_WIN);break; } }}#undef shift_key/* Erase (paint it black) the rectangle specified by x, y, w and h in the surface or overlay which is used for OSD*/static void erase_rectangle(int x, int y, int w, int h){ struct sdl_priv_s *priv = &sdl_priv; switch(priv->format) { case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: { SDL_OVR_LOCK((void) 0) /* Erase Y plane */ erase_area_1(x, w, h, priv->overlay->pitches[0], 0, priv->overlay->pixels[0] + priv->overlay->pitches[0]*y); /* Erase U and V planes */ w /= 2; x /= 2; h /= 2; y /= 2; erase_area_1(x, w, h, priv->overlay->pitches[1], 128, priv->overlay->pixels[1] + priv->overlay->pitches[1]*y); erase_area_1(x, w, h, priv->overlay->pitches[2], 128, priv->overlay->pixels[2] + priv->overlay->pitches[2]*y); SDL_OVR_UNLOCK break; } case IMGFMT_YUY2: case IMGFMT_YVYU: { /* yuy2 and yvyu represent black the same way */ uint8_t yuy2_black[] = {0, 128, 0, 128}; SDL_OVR_LOCK((void) 0) erase_area_4(x*2, w*2, h, priv->overlay->pitches[0], *((uint32_t*) yuy2_black), priv->overlay->pixels[0] + priv->overlay->pitches[0]*y); SDL_OVR_UNLOCK break; } case IMGFMT_UYVY: { uint8_t uyvy_black[] = {128, 0, 128, 0}; SDL_OVR_LOCK((void) 0) erase_area_4(x*2, w*2, h, priv->overlay->pitches[0], *((uint32_t*) uyvy_black), priv->overlay->pixels[0] + priv->overlay->pitches[0]*y); 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: { SDL_Rect rect; rect.w = w; rect.h = h; rect.x = x; rect.y = y; if(priv->dblit) { SDL_SRF_LOCK(priv->surface, (void) 0) SDL_FillRect(priv->surface, &rect, 0); SDL_SRF_UNLOCK(priv->surface) } else { SDL_SRF_LOCK(priv->rgbsurface, (void) 0) SDL_FillRect(priv->rgbsurface, &rect, 0); SDL_SRF_UNLOCK(priv->rgbsurface) } break; } }}static void draw_osd(void){ struct sdl_priv_s *priv = &sdl_priv; priv->osd_has_changed = vo_osd_changed(0); if(priv->osd_has_changed) { int i; for(i = 0; i < 2; i++) { if(priv->dirty_off_frame[i].x < 0 || priv->dirty_off_frame[i].y < 0) continue; erase_rectangle(priv->dirty_off_frame[i].x, priv->dirty_off_frame[i].y, priv->dirty_off_frame[i].w, priv->dirty_off_frame[i].h); priv->dirty_off_frame[i].x = -1; priv->dirty_off_frame[i].y = -1; } } /* update osd/subtitles */ if(priv->mode == YUV) vo_draw_text(priv->overlay->w, priv->overlay->h, draw_alpha); else { if(priv->dblit) vo_draw_text(priv->surface->w, priv->surface->h, draw_alpha); else vo_draw_text(priv->rgbsurface->w, priv->rgbsurface->h, draw_alpha); }}/* Fill area beginning at 'pixels' with 'color'. 'x_start', 'width' and 'pitch' * are given in bytes. 4 bytes at a time. */static void erase_area_4(int x_start, int width, int height, int pitch, uint32_t color, uint8_t* pixels){ int x_end = x_start/4 + width/4; int x, y; uint32_t* data = (uint32_t*) pixels; x_start /= 4; pitch /= 4; for(y = 0; y < height; y++) { for(x = x_start; x < x_end; x++) data[y*pitch + x] = color; }}/* Fill area beginning at 'pixels' with 'color'. 'x_start', 'width' and 'pitch' * are given in bytes. 1 byte at a time. */static void erase_area_1(int x_start, int width, int height, int pitch, uint8_t color, uint8_t* pixels){ int y; for(y = 0; y < height; y++) { memset(&pixels[y*pitch + x_start], color, width); }}/** * Display the surface we have written our data to * * params : mode == index of the desired fullscreen mode * returns : doesn't return **/static void flip_page (void){ struct sdl_priv_s *priv = &sdl_priv; 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: if(!priv->dblit) { /* blit to the RGB surface */ if(SDL_BlitSurface (priv->rgbsurface, NULL, priv->surface, NULL)) mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_SDL_BlitFailed, SDL_GetError()); } /* update screen */ //SDL_UpdateRect(priv->surface, 0, 0, priv->surface->clip_rect.w, priv->surface->clip_rect.h); if(priv->osd_has_changed) { priv->osd_has_changed = 0; SDL_UpdateRects(priv->surface, 1, &priv->surface->clip_rect); } else SDL_UpdateRect(priv->surface, 0, priv->y_screen_top, priv->surface->clip_rect.w, priv->y_screen_bottom); /* 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!? } }static intquery_format(uint32_t format){ switch(format){ case IMGFMT_YV12:// it seems buggy (not hw accelerated), so just use YV12 instead!// case IMGFMT_I420:// case IMGFMT_IYUV: case IMGFMT_YUY2: case IMGFMT_UYVY: case IMGFMT_YVYU: return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_OSD | VFCAP_HWSCALE_UP | VFCAP_HWSCALE_DOWN; 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 VFCAP_CSP_SUPPORTED | VFCAP_OSD | VFCAP_FLIP; } return 0;}static voiduninit(void){#ifdef HAVE_X11 struct sdl_priv_s *priv = &sdl_priv; if(priv->X) { if( mp_msg_test(MSGT_VO,MSGL_V) ) { mp_msg(MSGT_VO,MSGL_V, "SDL: activating XScreensaver/DPMS\n"); } vo_x11_uninit(); }#endif sdl_close(); /* Cleanup SDL */ if(SDL_WasInit(SDL_INIT_VIDEO)) SDL_QuitSubSystem(SDL_INIT_VIDEO); if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { mp_msg(MSGT_VO,MSGL_DBG3, "SDL: Closed Plugin\n"); }}static int preinit(const char *arg){ struct sdl_priv_s *priv = &sdl_priv; char * sdl_driver = NULL; int sdl_hwaccel; int sdl_forcexv; opt_t subopts[] = { {"forcexv", OPT_ARG_BOOL, &sdl_forcexv, NULL, 0}, {"hwaccel", OPT_ARG_BOOL, &sdl_hwaccel, NULL, 0}, {"driver", OPT_ARG_MSTRZ, &sdl_driver, NULL, 0}, {NULL, 0, NULL, NULL, 0} }; sdl_forcexv = 1; sdl_hwaccel = 1; if (subopt_parse(arg, subopts) != 0) return -1; priv->rgbsurface = NULL; priv->overlay = NULL; priv->surface = NULL; if( mp_msg_test(MSGT_VO,MSGL_DBG3) ) { mp_msg(MSGT_VO,MSGL_DBG3, "SDL: Opening Plugin\n"); } if(sdl_driver) { setenv("SDL_VIDEODRIVER", sdl_driver, 1); free(sdl_driver); } /* does the user want SDL to try and force Xv */ if(sdl_forcexv) setenv("SDL_VIDEO_X11_NODIRECTCOLOR", "1", 1); else setenv("SDL_VIDEO_X11_NODIRECTCOLOR", "0", 1); /* does the user want to disable Xv and use software scaling instead */ if(sdl_hwaccel) setenv("SDL_VIDEO_YUV_HWACCEL", "1", 1); else setenv("SDL_VIDEO_YUV_HWACCEL", "0", 1); /* default to no fullscreen mode, we'll set this as soon we have the avail. modes */ priv->fullmode = -2; priv->fullmodes = NULL; priv->bpp = 0; /* initialize the SDL Video system */ if (!SDL_WasInit(SDL_INIT_VIDEO)) { if (SDL_Init (SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE)) { mp_msg(MSGT_VO,MSGL_ERR, MSGTR_LIBVO_SDL_InitializationFailed, SDL_GetError()); return -1; } } SDL_VideoDriverName(priv->driver, 8); mp_msg(MSGT_VO,MSGL_INFO, MSGTR_LIBVO_SDL_UsingDriver, priv->driver); priv->X = 0;#ifdef HAVE_X11 if(vo_init()) { if( mp_msg_test(MSGT_VO,MSGL_V) ) { mp_msg(MSGT_VO,MSGL_V, "SDL: deactivating XScreensaver/DPMS\n"); } priv->XWidth = vo_screenwidth; priv->XHeight = vo_screenheight; priv->X = 1; if( mp_msg_test(MSGT_VO,MSGL_V) ) { mp_msg(MSGT_VO,MSGL_V, "SDL: X11 Resolution %ix%i\n", priv->XWidth, priv->XHeight); } }#endif return 0;}static uint32_t get_image(mp_image_t *mpi){ struct sdl_priv_s *priv = &sdl_priv; if(priv->format != mpi->imgfmt) return VO_FALSE; if(mpi->type == MP_IMGTYPE_STATIC || mpi->type == MP_IMGTYPE_TEMP) { if(mpi->flags&MP_IMGFLAG_PLANAR) { mpi->planes[0] = priv->overlay->pixels[0] + priv->y*priv->overlay->pitches[0]; mpi->stride[0] = priv->overlay->pitches[0]; if(mpi->flags&MP_IMGFLAG_SWAPPED) { mpi->planes[1] = priv->overlay->pixels[1] + priv->y*priv->overlay->pitches[1]/2; mpi->stride[1] = priv->overlay->pitches[1]; mpi->planes[2] = priv->overlay->pixels[2] + priv->y*priv->overlay->pitches[2]/2; mpi->stride[2] = priv->overlay->pitches[2]; } else { mpi->planes[2] = priv->overlay->pixels[1] + priv->y*priv->overlay->pitches[1]/2; mpi->stride[2] = priv->overlay->pitches[1]; mpi->planes[1] = priv->overlay->pixels[2] + priv->y*priv->overlay->pitches[2]/2; mpi->stride[1] = priv->overlay->pitches[2]; } } else if(IMGFMT_IS_RGB(priv->format) || IMGFMT_IS_BGR(priv->format)) { if(priv->dblit) { if(mpi->type == MP_IMGTYPE_STATIC && (priv->surface->flags & SDL_DOUBLEBUF)) return VO_FALSE; mpi->planes[0] = (uint8_t *)priv->surface->pixels + priv->y*priv->surface->pitch; mpi->stride[0] = priv->surface->pitch; } else { mpi->planes[0] = (uint8_t *)priv->rgbsurface->pixels + priv->y*priv->rgbsurface->pitch; mpi->stride[0] = priv->rgbsurface->pitch; } } else { mpi->planes[0] = priv->overlay->pixels[0] + priv->y*priv->overlay->pitches[0]; mpi->stride[0] = priv->overlay->pitches[0]; } mpi->flags|=MP_IMGFLAG_DIRECT; return VO_TRUE; } return VO_FALSE;}static int control(uint32_t request, void *data, ...){ struct sdl_priv_s *priv = &sdl_priv; switch (request) { case VOCTRL_GET_IMAGE: return get_image(data); case VOCTRL_QUERY_FORMAT: return query_format(*((uint32_t*)data)); case VOCTRL_FULLSCREEN: if (priv->surface->flags & SDL_FULLSCREEN) { set_video_mode(priv->windowsize.w, priv->windowsize.h, priv->bpp, priv->sdlflags); SDL_ShowCursor(1); if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "SDL: Windowed mode\n"); } } else if (priv->fullmodes) { set_fullmode(priv->fullmode); if( mp_msg_test(MSGT_VO,MSGL_DBG2) ) { mp_msg(MSGT_VO,MSGL_DBG2, "SDL: Set fullscreen mode\n"); } } return VO_TRUE; } return VO_NOTIMPL;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?