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