예제 #1
0
GF_Err SDLVid_SetFullScreen(GF_VideoOutput *dr, u32 bFullScreenOn, u32 *screen_width, u32 *screen_height)
{
	u32 bpp, pref_bpp;
	SDLVID();

	if (ctx->fullscreen==bFullScreenOn) return GF_OK;

	/*lock to get sure the event queue is not processed under X*/
	gf_mx_p(ctx->evt_mx);
	ctx->fullscreen = bFullScreenOn;

	pref_bpp = bpp = ctx->screen->format->BitsPerPixel;

	if (ctx->fullscreen) {
		u32 flags;
		Bool switch_res = 0;
		const char *sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "SwitchResolution");
		if (sOpt && !stricmp(sOpt, "yes")) switch_res = 1;
		if (!dr->max_screen_width || !dr->max_screen_height) switch_res = 1;

		flags = (ctx->output_3d_type==1) ? SDL_GL_FULLSCREEN_FLAGS : SDL_FULLSCREEN_FLAGS;
		ctx->store_width = *screen_width;
		ctx->store_height = *screen_height;
		if (switch_res) {
			u32 i;
			ctx->fs_width = *screen_width;
			ctx->fs_height = *screen_height;
			for(i=0; i<nb_video_modes; i++) {
				if (ctx->fs_width<=video_modes[2*i] && ctx->fs_height<=video_modes[2*i + 1]) {
					if ((pref_bpp = SDL_VideoModeOK(video_modes[2*i], video_modes[2*i+1], bpp, flags))) {
						ctx->fs_width = video_modes[2*i];
						ctx->fs_height = video_modes[2*i + 1];
						break;
					}
				}
			}
		} else {
			ctx->fs_width = dr->max_screen_width;
			ctx->fs_height = dr->max_screen_height;
		}
		ctx->screen = SDL_SetVideoMode(ctx->fs_width, ctx->fs_height, pref_bpp, flags);
		/*we switched bpp, clean all objects*/
		if (bpp != pref_bpp) SDLVid_DestroyObjects(ctx);
		*screen_width = ctx->fs_width;
		*screen_height = ctx->fs_height;
		/*GL has changed*/
		if (ctx->output_3d_type==1) {
			GF_Event evt;
			evt.type = GF_EVENT_VIDEO_SETUP;
			dr->on_event(dr->evt_cbk_hdl, &evt);
		}
	} else {
		SDLVid_ResizeWindow(dr, ctx->store_width, ctx->store_height);
		*screen_width = ctx->store_width;
		*screen_height = ctx->store_height;
	}
	gf_mx_v(ctx->evt_mx);
	if (!ctx->screen) return GF_IO_ERR;
	return GF_OK;
}
예제 #2
0
GF_Err SDLVid_SetBackbufferSize(GF_VideoOutput *dr, u32 newWidth, u32 newHeight, Bool system_mem)
{
	u32 col;
	const char *opt;
	SDLVID();
	
	if (ctx->output_3d_type==1) return GF_BAD_PARAM;

	opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "HardwareMemory");
	if (system_mem) {
		if (opt && !strcmp(opt, "Always")) system_mem = 0;
	} else {
		if (opt && !strcmp(opt, "Never")) system_mem = 1;
	}
	ctx->use_systems_memory = system_mem;


	/*clear screen*/
	col = SDL_MapRGB(ctx->screen->format, 0, 0, 0);
	SDL_FillRect(ctx->screen, NULL, col);
	SDL_Flip(ctx->screen);

	if (ctx->back_buffer && ((u32) ctx->back_buffer->w==newWidth) && ((u32) ctx->back_buffer->h==newHeight)) {
		return GF_OK;
	}
	if (ctx->back_buffer) SDL_FreeSurface(ctx->back_buffer);
	ctx->back_buffer = SDL_CreateRGBSurface(ctx->use_systems_memory ? SDL_SWSURFACE : SDL_HWSURFACE, newWidth, newHeight, ctx->screen->format->BitsPerPixel, ctx->screen->format->Rmask, ctx->screen->format->Gmask, ctx->screen->format->Bmask, 0);
	ctx->width = newWidth;
	ctx->height = newHeight;
	if (!ctx->back_buffer) return GF_IO_ERR;

	return GF_OK;
}
예제 #3
0
GF_Err SDLVid_Setup(struct _video_out *dr, void *os_handle, void *os_display, u32 init_flags)
{
	SDLVID();
	/*we don't allow SDL hack, not stable enough*/
	//if (os_handle) SDLVid_SetHack(os_handle, 1);

	ctx->os_handle = os_handle;
	ctx->is_init = 0;
	ctx->output_3d_type = 0;
	ctx->force_alpha = (init_flags & GF_TERM_WINDOW_TRANSPARENT) ? 1 : 0;

	if (!SDLOUT_InitSDL()) return GF_IO_ERR;

#ifdef	SDL_WINDOW_THREAD
	ctx->sdl_th_state = SDL_STATE_STOPPED;
	gf_th_run(ctx->sdl_th, SDLVid_EventProc, dr);

	while (!ctx->sdl_th_state)
		gf_sleep(10);

	if (ctx->sdl_th_state==SDL_STATE_STOP_REQ) {
		SDLOUT_CloseSDL();
		ctx->sdl_th_state = SDL_STATE_STOPPED;
		return GF_IO_ERR;
	}
#else
	if (!SDLVid_InitializeWindow(ctx, dr)) {
		SDLOUT_CloseSDL();
		return GF_IO_ERR;
	}
#endif

	ctx->is_init = 1;
	return GF_OK;
}
예제 #4
0
u32 SDLVid_EventProc(void *par)
{
#if 0
	u32 last_mouse_move;
#endif
	Bool ret;
	GF_VideoOutput *dr = (GF_VideoOutput *)par;
	SDLVID();

	if (!SDLVid_InitializeWindow(ctx, dr)) {
		ctx->sdl_th_state = SDL_STATE_STOP_REQ;
	}

	ctx->sdl_th_state = SDL_STATE_RUNNING;
	while (ctx->sdl_th_state==SDL_STATE_RUNNING) {
		/*after much testing: we must ensure nothing is using the event queue when resizing window.
		-- under X, it throws Xlib "unexpected async reply" under linux, therefore we don't wait events,
		we check for events and execute them if any
		-- under Win32, the SDL_SetVideoMode deadlocks, so we don't force exclusive access to events
		*/
#ifndef WIN32
		gf_mx_p(ctx->evt_mx);
#endif

		ret = SDLVid_ProcessMessageQueue(ctx, dr);

#ifndef WIN32
		gf_mx_v(ctx->evt_mx);
#endif

		/*looks like this hides the cursor for ever when switching back from FS*/
#if 0
		if (ctx->fullscreen && (last_mouse_move + 2000 < SDL_GetTicks()) ) {
			if (cursor_on) SDL_ShowCursor(0);
			cursor_on = 0;
		} else if (!cursor_on) {
			SDL_ShowCursor(1);
			cursor_on = 1;
		}
#endif
	
		/*QUIT message has been processed*/
		if (!ret) {
			ctx->sdl_th_state = SDL_STATE_STOP_REQ;
			break;
		}

		gf_sleep(2);
	}

	while (ctx->sdl_th_state == SDL_STATE_STOP_REQ)
		gf_sleep(10);

	SDLVid_ShutdownWindow(ctx);
	ctx->sdl_th_state = SDL_STATE_STOPPED;

	return 0;
}
예제 #5
0
파일: video.c 프로젝트: noelove/GPAC-old
GF_Err SDLVid_ResizeWindow(GF_VideoOutput *dr, u32 width, u32 height) 
{
	SDLVID();
	GF_Event evt;

	/*lock X mutex to make sure the event queue is not being processed*/
	gf_mx_p(ctx->evt_mx);

	if (ctx->output_3d_type==1) {
		u32 flags, nb_bits;
		const char *opt;
		if ((ctx->width==width) && (ctx->height==height) ) {
			gf_mx_v(ctx->evt_mx);
			return GF_OK;
		}
		flags = SDL_GL_WINDOW_FLAGS;
		if (ctx->os_handle) flags &= ~SDL_RESIZABLE;
		if (ctx->fullscreen) flags |= SDL_FULLSCREEN_FLAGS;
		if (!ctx->screen) ctx->screen = SDL_SetVideoMode(width, height, 0, flags);
		SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

		opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "GLNbBitsDepth");
		nb_bits = opt ? atoi(opt) : 16;
		SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, nb_bits);
		SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 0);
		opt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "GLNbBitsPerComponent");
		nb_bits = opt ? atoi(opt) : 5;
		SDL_GL_SetAttribute(SDL_GL_RED_SIZE, nb_bits);
		SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, nb_bits);
		SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, nb_bits);

		assert(width);
		assert(height);
		ctx->screen = SDL_SetVideoMode(width, height, 0, flags);
		assert(ctx->screen);
		ctx->width = width;
		ctx->height = height;
		memset(&evt, 0, sizeof(GF_Event));
		evt.type = GF_EVENT_VIDEO_SETUP;
		dr->on_event(dr->evt_cbk_hdl, &evt);		
	} else {
		u32 flags;
#ifdef GPAC_IPHONE
		flags = SDL_FULLSCREEN_FLAGS;
		//SDL readme says it would make us faster
		SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
		SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 1);
#else
		flags = SDL_WINDOW_FLAGS;
#endif
		if (ctx->os_handle) flags &= ~SDL_RESIZABLE;
		ctx->screen = SDL_SetVideoMode(width, height, 0, flags);
	}
	gf_mx_v(ctx->evt_mx);
	return ctx->screen ? GF_OK : GF_IO_ERR;
}
예제 #6
0
void SDL_DeleteVideo(void *ifce)
{
	GF_VideoOutput *dr = (GF_VideoOutput *)ifce;
	SDLVID();
#ifdef	SDL_WINDOW_THREAD
	gf_th_del(ctx->sdl_th);
#endif
	gf_mx_del(ctx->evt_mx);
	gf_free(ctx);
	gf_free(dr);
}
예제 #7
0
static GF_Err SDLVid_Flush(GF_VideoOutput *dr, GF_Window *dest)
{
	SDL_Rect rc;
	SDLVID();
	/*if resizing don't process otherwise we may deadlock*/
	if (!ctx->screen) return GF_OK;

	if (ctx->output_3d_type==1) {
		SDL_GL_SwapBuffers();
		return GF_OK;
	}
	if (!ctx->back_buffer) return GF_BAD_PARAM;

	if ((dest->w != (u32) ctx->back_buffer->w) || (dest->h != (u32) ctx->back_buffer->h)) {
		GF_VideoSurface src, dst;

		SDL_LockSurface(ctx->back_buffer);
		SDL_LockSurface(ctx->screen);

		src.height = ctx->back_buffer->h;
		src.width = ctx->back_buffer->w;
		src.pitch_x = 0;
		src.pitch_y = ctx->back_buffer->pitch;
		src.pixel_format = SDLVid_MapPixelFormat(ctx->back_buffer->format, ctx->force_alpha);
		src.video_buffer = ctx->back_buffer->pixels;

		dst.height = ctx->screen->h;
		dst.width = ctx->screen->w;
		dst.pitch_x = 0;
		dst.pitch_y = ctx->screen->pitch;
		dst.pixel_format = SDLVid_MapPixelFormat(ctx->screen->format, 0);
		dst.video_buffer = ctx->screen->pixels;

		gf_stretch_bits(&dst, &src, dest, NULL, 0xFF, 0, NULL, NULL);

		SDL_UnlockSurface(ctx->back_buffer);
		SDL_UnlockSurface(ctx->screen);
	} else {
		rc.x = dest->x; rc.y = dest->y; rc.w = dest->w; rc.h = dest->h;
		SDL_BlitSurface(ctx->back_buffer, NULL, ctx->screen, &rc);
	}
	SDL_Flip(ctx->screen);
	return GF_OK;
}
예제 #8
0
static void SDLVid_SetCursor(GF_VideoOutput *dr, u32 cursor_type)
{
	SDLVID();
	switch (cursor_type) {
	case GF_CURSOR_ANCHOR:
	case GF_CURSOR_TOUCH:
	case GF_CURSOR_ROTATE:
	case GF_CURSOR_PROXIMITY:
	case GF_CURSOR_PLANE:
		SDL_SetCursor(ctx->curs_hand);
		break;
	case GF_CURSOR_COLLIDE:
		SDL_SetCursor(ctx->curs_collide);
		break;
	default:
		SDL_SetCursor(ctx->curs_def);
		break;
	}
}
예제 #9
0
static GF_Err SDLVid_LockBackBuffer(GF_VideoOutput *dr, GF_VideoSurface *video_info, u32 do_lock)
{
	SDLVID();
	if (!ctx->back_buffer) return GF_BAD_PARAM;
	if (do_lock) {
		if (!video_info) return GF_BAD_PARAM;
		if (SDL_LockSurface(ctx->back_buffer)<0) return GF_IO_ERR;
		video_info->width = ctx->back_buffer->w;
		video_info->height = ctx->back_buffer->h;
		video_info->pitch_x = 0;
		video_info->pitch_y = ctx->back_buffer->pitch;
		video_info->video_buffer = ctx->back_buffer->pixels;
		video_info->pixel_format = SDLVid_MapPixelFormat(ctx->back_buffer->format, ctx->force_alpha);
		video_info->is_hardware_memory = !ctx->use_systems_memory;
	} else {
		SDL_UnlockSurface(ctx->back_buffer);
	}
	return GF_OK;
}
예제 #10
0
static void SDLVid_Shutdown(GF_VideoOutput *dr)
{
	SDLVID();
	/*remove all surfaces*/

	if (!ctx->is_init) return;
#ifdef	SDL_WINDOW_THREAD
	if (ctx->sdl_th_state==SDL_STATE_RUNNING) {
		SDL_Event evt;
		evt.type = SDL_QUIT;
		SDL_PushEvent(&evt);
	}
	/*wait until thread say it is stopped*/
	ctx->sdl_th_state = SDL_STATE_WAIT_FOR_THREAD_TERMINATION;
	while (ctx->sdl_th_state != SDL_STATE_STOPPED)
		gf_sleep(10);

#else
	SDLVid_ShutdownWindow(ctx);
#endif

	SDLOUT_CloseSDL();
	ctx->is_init = 0;
}
예제 #11
0
static GF_Err SDL_Blit(GF_VideoOutput *dr, GF_VideoSurface *video_src, GF_Window *src_wnd, GF_Window *dst_wnd, u32 overlay_type)
{
	SDLVID();
	u32 amask = 0;
	u32 bpp, i;
	u8 *dst, *src;
	SDL_Rect srcrc, dstrc;
	SDL_Surface **pool;

	if (overlay_type) {
		if (!video_src) {
			if (ctx->yuv_overlay) {
				SDL_FreeYUVOverlay(ctx->yuv_overlay);
				ctx->yuv_overlay=NULL;
			}
			return GF_OK;
		}
		if (!ctx->yuv_overlay || (ctx->yuv_overlay->w != src_wnd->w) || (ctx->yuv_overlay->h != src_wnd->h) ) {
			if (ctx->yuv_overlay) SDL_FreeYUVOverlay(ctx->yuv_overlay);

			ctx->yuv_overlay = SDL_CreateYUVOverlay(src_wnd->w, src_wnd->h, SDL_YV12_OVERLAY, ctx->screen);
			if (!ctx->yuv_overlay) return GF_NOT_SUPPORTED;
		}
		/*copy pixels*/
		SDL_LockYUVOverlay(ctx->yuv_overlay);

		copy_yuv(ctx->yuv_overlay->pixels[0], ctx->yuv_overlay->pixels[1], ctx->yuv_overlay->pixels[2], GF_PIXEL_YV12, ctx->yuv_overlay->pitches[0], 
			video_src->video_buffer, video_src->pitch_y, video_src->pixel_format,
			video_src->width, video_src->height, src_wnd);

		SDL_UnlockYUVOverlay(ctx->yuv_overlay);

		dstrc.w = dst_wnd->w;
		dstrc.h = dst_wnd->h;
		dstrc.x = dst_wnd->x;
		dstrc.y = dst_wnd->y;
		SDL_DisplayYUVOverlay(ctx->yuv_overlay, &dstrc);
		return GF_OK;
	}

	/*SDL doesn't support stretching ...*/
	if ((src_wnd->w != dst_wnd->w) || (src_wnd->h!=dst_wnd->h)) return GF_NOT_SUPPORTED;

	switch (video_src->pixel_format) {
	case GF_PIXEL_RGB_24:
		pool = &ctx->pool_rgb;
		bpp = 3;
		break;
	case GF_PIXEL_RGBA:
		pool = &ctx->pool_rgba;
		amask = 0xFF000000;
		bpp = 4;
		break;
	default:
		return GF_NOT_SUPPORTED;
	}

	if (! *pool || ((*pool)->w < (int) src_wnd->w) || ((*pool)->h < (int) src_wnd->h) ) {
		if ((*pool)) SDL_FreeSurface((*pool));
		(*pool) = SDL_CreateRGBSurface(ctx->use_systems_memory ? SDL_SWSURFACE : SDL_HWSURFACE, 
						src_wnd->w, src_wnd->h, 8*bpp, 
						0x000000FF, 0x0000FF00, 0x00FF0000, amask);
		if (! (*pool) ) return GF_IO_ERR;
	}

	SDL_LockSurface(*pool);

	dst = (u8 *) ( (*pool)->pixels);
	src = video_src->video_buffer + video_src->pitch_y*src_wnd->y + src_wnd->x*bpp;
	for (i=0; i<src_wnd->h; i++) {
		memcpy(dst, src, bpp * src_wnd->w);
		src += video_src->pitch_y;
		dst += (*pool)->pitch;
	}
	SDL_UnlockSurface(*pool);

	srcrc.w = src_wnd->w;
	srcrc.h = src_wnd->h;
	srcrc.x = 0;
	srcrc.y = 0;

	dstrc.w = dst_wnd->w;
	dstrc.h = dst_wnd->h;
	dstrc.x = dst_wnd->x;
	dstrc.y = dst_wnd->y;

	SDL_BlitSurface(*pool, &srcrc, ctx->back_buffer, &dstrc);
	return GF_OK;
}
예제 #12
0
static GF_Err SDLVid_ProcessEvent(GF_VideoOutput *dr, GF_Event *evt)
{
	if (!evt) {
#ifndef	SDL_WINDOW_THREAD
		SDLVID();
		SDLVid_ProcessMessageQueue(ctx, dr);
#endif		
		return GF_OK;
	}
	switch (evt->type) {
	case GF_EVENT_SET_CURSOR:
		SDLVid_SetCursor(dr, evt->cursor.cursor_type);
		break;
	case GF_EVENT_SET_CAPTION:
#ifdef SDL_WINDOW_THREAD
	{
		SDLVID();
		if (ctx->sdl_th_state != SDL_STATE_RUNNING)
			break;
	}
#endif
		SDL_WM_SetCaption(evt->caption.caption, NULL);
		break;
	case GF_EVENT_SHOWHIDE:
		/*the only way to have proper show/hide with SDL is to shutdown the video system and reset it up
		which we don't want to do since the setup MUST occur in the rendering thread for some configs (openGL)*/
		return GF_NOT_SUPPORTED;
	case GF_EVENT_SIZE:
		SDLVid_ResizeWindow(dr, evt->size.width, evt->size.height);
		break;
	case GF_EVENT_MOVE:
		break;
	case GF_EVENT_VIDEO_SETUP:
	{
		SDLVID();
		switch (evt->setup.opengl_mode) {
		case 0:
			/*force a resetup of the window*/
			if (ctx->output_3d_type) {
				ctx->width = ctx->height = 0;
			}
			ctx->output_3d_type = 0;
			return SDLVid_SetBackbufferSize(dr, evt->setup.width, evt->setup.height, evt->setup.system_memory);
		case 1:
			/*force a resetup of the window*/
			if (!ctx->output_3d_type) {
				ctx->width = ctx->height = 0;
			}
			ctx->output_3d_type = 1;
			return SDLVid_ResizeWindow(dr, evt->setup.width, evt->setup.height);
		case 2:
			/*find a way to do that in SDL*/
			ctx->output_3d_type = 2;
			GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[SDL] 3D not supported with SDL.\n"));
			return GF_NOT_SUPPORTED;
		}
		default:
			GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[SDL] Trying to set an Unknown Mode %d !\n", evt->setup.opengl_mode));
			return GF_NOT_SUPPORTED;
	}
		break;
	case GF_EVENT_SYS_COLORS:
#ifdef WIN32
		evt->sys_cols.sys_colors[0] = get_sys_col(COLOR_ACTIVEBORDER);
		evt->sys_cols.sys_colors[1] = get_sys_col(COLOR_ACTIVECAPTION);
		evt->sys_cols.sys_colors[2] = get_sys_col(COLOR_APPWORKSPACE);
		evt->sys_cols.sys_colors[3] = get_sys_col(COLOR_BACKGROUND);
		evt->sys_cols.sys_colors[4] = get_sys_col(COLOR_BTNFACE);
		evt->sys_cols.sys_colors[5] = get_sys_col(COLOR_BTNHIGHLIGHT);
		evt->sys_cols.sys_colors[6] = get_sys_col(COLOR_BTNSHADOW);
		evt->sys_cols.sys_colors[7] = get_sys_col(COLOR_BTNTEXT);
		evt->sys_cols.sys_colors[8] = get_sys_col(COLOR_CAPTIONTEXT);
		evt->sys_cols.sys_colors[9] = get_sys_col(COLOR_GRAYTEXT);
		evt->sys_cols.sys_colors[10] = get_sys_col(COLOR_HIGHLIGHT);
		evt->sys_cols.sys_colors[11] = get_sys_col(COLOR_HIGHLIGHTTEXT);
		evt->sys_cols.sys_colors[12] = get_sys_col(COLOR_INACTIVEBORDER);
		evt->sys_cols.sys_colors[13] = get_sys_col(COLOR_INACTIVECAPTION);
		evt->sys_cols.sys_colors[14] = get_sys_col(COLOR_INACTIVECAPTIONTEXT);
		evt->sys_cols.sys_colors[15] = get_sys_col(COLOR_INFOBK);
		evt->sys_cols.sys_colors[16] = get_sys_col(COLOR_INFOTEXT);
		evt->sys_cols.sys_colors[17] = get_sys_col(COLOR_MENU);
		evt->sys_cols.sys_colors[18] = get_sys_col(COLOR_MENUTEXT);
		evt->sys_cols.sys_colors[19] = get_sys_col(COLOR_SCROLLBAR);
		evt->sys_cols.sys_colors[20] = get_sys_col(COLOR_3DDKSHADOW);
		evt->sys_cols.sys_colors[21] = get_sys_col(COLOR_3DFACE);
		evt->sys_cols.sys_colors[22] = get_sys_col(COLOR_3DHIGHLIGHT);
		evt->sys_cols.sys_colors[23] = get_sys_col(COLOR_3DLIGHT);
		evt->sys_cols.sys_colors[24] = get_sys_col(COLOR_3DSHADOW);
		evt->sys_cols.sys_colors[25] = get_sys_col(COLOR_WINDOW);
		evt->sys_cols.sys_colors[26] = get_sys_col(COLOR_WINDOWFRAME);
		evt->sys_cols.sys_colors[27] = get_sys_col(COLOR_WINDOWTEXT);
		return GF_OK;
#else
		return GF_NOT_SUPPORTED;
#endif
	}
	return GF_OK;
}