⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dx_video.c

📁 一个用于智能手机的多媒体库适合S60 WinCE的跨平台开发库
💻 C
字号:
/* *			GPAC - Multimedia Framework C SDK * *			Copyright (c) Jean Le Feuvre 2000-2005 *					All rights reserved * *  This file is part of GPAC / DirectX audio and video render module * *  GPAC is free software; you can redistribute it and/or modify *  it under the terms of the GNU Lesser General Public License as published by *  the Free Software Foundation; either version 2, or (at your option) *  any later version. *    *  GPAC is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU Lesser General Public License for more details. *    *  You should have received a copy of the GNU Lesser General Public *  License along with this library; see the file COPYING.  If not, write to *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  *		 */#include "dx_hw.h"#include <gpac/user.h>#define DDCONTEXT	DDContext *dd = (DDContext *)dr->opaque;static void RestoreWindow(DDContext *dd) {	if (!dd->NeedRestore) return;	dd->NeedRestore = 0;	if (dd->is_3D_out) {		ChangeDisplaySettings(NULL,0);		SetForegroundWindow(GetDesktopWindow());		SetForegroundWindow(dd->cur_hwnd);	} else {#ifdef USE_DX_3		IDirectDraw_SetCooperativeLevel(dd->pDD, dd->cur_hwnd, DDSCL_NORMAL);#else		IDirectDraw7_SetCooperativeLevel(dd->pDD, dd->cur_hwnd, DDSCL_NORMAL);#endif		dd->NeedRestore = 0;	}	SetForegroundWindow(dd->cur_hwnd);	SetFocus(dd->cur_hwnd);}void DestroyObjects(DDContext *dd){	RestoreWindow(dd);	SAFE_DD_RELEASE(dd->rgb_pool.pSurface);	memset(&dd->rgb_pool, 0, sizeof(DDSurface));	SAFE_DD_RELEASE(dd->yuv_pool.pSurface);	memset(&dd->yuv_pool, 0, sizeof(DDSurface));	SAFE_DD_RELEASE(dd->pPrimary);	SAFE_DD_RELEASE(dd->pBack);	SAFE_DD_RELEASE(dd->pDD);	dd->ddraw_init = 0;	/*delete openGL context*/#ifdef GPAC_USE_OGL_ES	if (dd->eglctx) eglDestroyContext(dd->egldpy, dd->eglctx);	dd->eglctx = NULL;	if (dd->surface) eglDestroySurface(dd->egldpy, dd->surface);	dd->surface = NULL;	if (dd->gl_HDC) {		if (dd->egldpy) eglTerminate(dd->egldpy);		ReleaseDC(dd->cur_hwnd, (HDC) dd->gl_HDC);		dd->gl_HDC = 0L;		dd->egldpy = NULL;	}#else	if (dd->gl_HRC) {		wglMakeCurrent(dd->gl_HDC, NULL);		wglDeleteContext(dd->gl_HRC);		dd->gl_HRC = NULL;	}	if (dd->gl_HDC) {		ReleaseDC(dd->cur_hwnd, dd->gl_HDC);		dd->gl_HDC = NULL;	}#endif}GF_Err DD_SetupOpenGL(GF_VideoOutput *dr) {	GF_Event evt;	DDCONTEXT#ifdef GPAC_USE_OGL_ES	EGLint major, minor;	EGLint n;	EGLConfig configs[1];	static int egl_atts[] = {EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 5, EGL_BLUE_SIZE, 5, 				/*alpha for compositeTexture*/				EGL_ALPHA_SIZE,     1,                EGL_DEPTH_SIZE,     16,                EGL_STENCIL_SIZE,   EGL_DONT_CARE,                EGL_NONE};	/*already setup*/	DestroyObjects(dd);	dd->gl_HDC = (NativeDisplayType) GetDC(dd->cur_hwnd);	dd->egldpy = eglGetDisplay(/*dd->gl_HDC*/ EGL_DEFAULT_DISPLAY);	if (!eglInitialize(dd->egldpy, &major, &minor)) return GF_IO_ERR;	if (!eglChooseConfig(dd->egldpy, egl_atts, configs, 1, &n)) return GF_IO_ERR;	dd->eglconfig = configs[0];	dd->surface = eglCreateWindowSurface(dd->egldpy, dd->eglconfig, dd->cur_hwnd, 0);	if (!dd->surface) return GF_IO_ERR; 	dd->eglctx = eglCreateContext(dd->egldpy, dd->eglconfig, NULL, NULL);	if (!dd->eglctx) {		eglDestroySurface(dd->egldpy, dd->surface);		dd->surface = 0L;		return GF_IO_ERR; 	}    if (!eglMakeCurrent(dd->egldpy, dd->surface, dd->surface, dd->eglctx)) {		eglDestroyContext(dd->egldpy, dd->eglctx);		dd->eglctx = 0L;		eglDestroySurface(dd->egldpy, dd->surface);		dd->surface = 0L;		return GF_IO_ERR;	}#else    PIXELFORMATDESCRIPTOR pfd;     s32 pixelformat; 	/*already setup*///	if (dd->gl_HRC) return GF_OK;	DestroyObjects(dd);	dd->gl_HDC = GetDC(dd->cur_hwnd);	if (!dd->gl_HDC) return GF_IO_ERR;    memset(&pfd, 0, sizeof(pfd));    pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);    pfd.nVersion = 1;    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;    pfd.dwLayerMask = PFD_MAIN_PLANE;    pfd.iPixelType = PFD_TYPE_RGBA;    pfd.cColorBits = 32;	pfd.cDepthBits = 32;	/*we need alpha support for composite textures...*/	pfd.cAlphaBits = 8;    if ( (pixelformat = ChoosePixelFormat(dd->gl_HDC, &pfd)) == FALSE ) return GF_IO_ERR;     if (SetPixelFormat(dd->gl_HDC, pixelformat, &pfd) == FALSE) 		return GF_IO_ERR; 	dd->gl_HRC = wglCreateContext(dd->gl_HDC);	if (!dd->gl_HRC) return GF_IO_ERR;	if (!wglMakeCurrent(dd->gl_HDC, dd->gl_HRC)) return GF_IO_ERR;#endif	evt.type = GF_EVENT_VIDEO_SETUP;	dr->on_event(dr->evt_cbk_hdl, &evt);		return GF_OK;}GF_Err DD_Setup(GF_VideoOutput *dr, void *os_handle, void *os_display, u32 init_flags, GF_GLConfig *cfg){	RECT rc;	DDCONTEXT	dd->os_hwnd = (HWND) os_handle;		if (init_flags & (GF_TERM_NO_VISUAL_THREAD | GF_TERM_NO_REGULATION) ) dd->systems_memory = 2;	DD_SetupWindow(dr, init_flags);	/*fatal error*/	if (!dd->os_hwnd) return GF_IO_ERR;	dd->cur_hwnd = dd->os_hwnd;	if (cfg) {		dd->is_3D_out = 1;		return GF_OK;	}	dd->is_3D_out = 0;	GetWindowRect(dd->cur_hwnd, &rc);	return InitDirectDraw(dr, rc.right - rc.left, rc.bottom - rc.top);}static void DD_Shutdown(GF_VideoOutput *dr){	DDCONTEXT	DestroyObjects(dd);	DD_ShutdownWindow(dr);}static GF_Err DD_SetFullScreen(GF_VideoOutput *dr, Bool bOn, u32 *outWidth, u32 *outHeight){	GF_Err e;	const char *sOpt;	u32 MaxWidth, MaxHeight;	DDCONTEXT;	if (!dd->width ||!dd->height) return GF_BAD_PARAM;	if (bOn == dd->fullscreen) return GF_OK;	if (!dd->fs_hwnd) return GF_NOT_SUPPORTED;	dd->fullscreen = bOn;		/*whenever changing card display mode relocate fastest YUV format for blit (since it depends	on the dest pixel format)*/	dd->yuv_init = 0;	if (dd->fullscreen) {		const char *sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "SwitchResolution");		if (sOpt && !stricmp(sOpt, "yes")) dd->switch_res = 1;		/*get current or best fitting mode*/		if (GetDisplayMode(dd) != GF_OK) return GF_IO_ERR;	}	MaxWidth = MaxHeight = 0;	sOpt = gf_modules_get_option((GF_BaseInterface *)dr, "Video", "MaxResolution");	if (sOpt) sscanf(sOpt, "%dx%d", &MaxWidth, &MaxHeight);	/*destroy all objects*/	DestroyObjects(dd);	if (dd->timer) KillTimer(dd->cur_hwnd, dd->timer);	dd->timer = 0;	ShowWindow(dd->cur_hwnd, SW_HIDE);	dd->cur_hwnd = dd->fullscreen ? dd->fs_hwnd : dd->os_hwnd;	ShowWindow(dd->cur_hwnd, SW_SHOWNORMAL);	SetForegroundWindow(dd->cur_hwnd);	if (dd->is_3D_out) {		DEVMODE settings;		e = GF_OK;		/*Setup FS*/		if (dd->fullscreen) {			/*change display mode*/			if ((MaxWidth && (dd->fs_width >= MaxWidth)) || (MaxHeight && (dd->fs_height >= MaxHeight)) ) {				dd->fs_width = MaxWidth;				dd->fs_height = MaxHeight;			}			/*force size change (we do it whether we own or not the window)*/			SetWindowPos(dd->cur_hwnd, NULL, 0, 0, dd->fs_width, dd->fs_height, SWP_NOZORDER | SWP_SHOWWINDOW);			SetForegroundWindow(dd->cur_hwnd);			memset(&settings, 0, sizeof(DEVMODE));			settings.dmSize = sizeof(DEVMODE);			settings.dmPelsWidth = dd->fs_width;			settings.dmPelsHeight = dd->fs_height;			settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;			if ( ChangeDisplaySettings(&settings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL ) {				GF_LOG(GF_LOG_ERROR, GF_LOG_MMIO, ("[DirectDraw] cannot change display settings\n"));				e = GF_IO_ERR;			} 			dd->NeedRestore = 1;			dd->fs_store_width = dd->fs_width;			dd->fs_store_height = dd->fs_height;		}		if (!e) e = DD_SetupOpenGL(dr);			} else {		e = InitDirectDraw(dr, dd->width, dd->height);	}	if (bOn) {		dd->store_width = *outWidth;		dd->store_height = *outHeight;		*outWidth = dd->fs_width;		*outHeight = dd->fs_height;	} else {		*outWidth = dd->store_width;		*outHeight = dd->store_height;	}	return e;}static GF_Err DD_Flush(GF_VideoOutput *dr, GF_Window *dest){	RECT rc;	HRESULT hr;	DDCONTEXT;	if (!dd) return GF_BAD_PARAM;	if (dd->is_3D_out) {#ifdef GPAC_USE_OGL_ES		if (dd->surface) eglSwapBuffers(dd->egldpy, dd->surface);#else		SwapBuffers(dd->gl_HDC);#endif		return GF_OK;	}	if (!dd->ddraw_init) return GF_BAD_PARAM;	if (!dd->fullscreen && dd->windowless) {		HDC hdc;		/*lock backbuffer HDC*/		dr->LockOSContext(dr, 1);		/*get window hdc and copy from backbuffer to window*/		hdc = GetDC(dd->os_hwnd);		BitBlt(hdc, 0, 0, dd->width, dd->height, dd->lock_hdc, 0, 0, SRCCOPY );		ReleaseDC(dd->os_hwnd, hdc);		/*unlock backbuffer HDC*/		dr->LockOSContext(dr, 0);		return GF_OK;	}	if (dest) {		POINT pt;		pt.x = dest->x;		pt.y = dest->y;		ClientToScreen(dd->cur_hwnd, &pt);		dest->x = pt.x;		dest->y = pt.y;		MAKERECT(rc, dest);		hr = IDirectDrawSurface_Blt(dd->pPrimary, &rc, dd->pBack, NULL, DDBLT_WAIT, NULL );	} else {		hr = IDirectDrawSurface_Blt(dd->pPrimary, NULL, dd->pBack, NULL, DDBLT_WAIT, NULL );	}	if (hr == DDERR_SURFACELOST) {		IDirectDrawSurface_Restore(dd->pPrimary);		IDirectDrawSurface_Restore(dd->pBack);	}	return FAILED(hr) ? GF_IO_ERR : GF_OK;}#ifdef USE_DX_3HRESULT WINAPI EnumDisplayModes( LPDDSURFACEDESC lpDDDesc, LPVOID lpContext)#elseHRESULT WINAPI EnumDisplayModes( LPDDSURFACEDESC2 lpDDDesc, LPVOID lpContext)#endif{	DDContext *dd = (DDContext *) lpContext;		//check W and H	if (dd->width <= lpDDDesc->dwWidth  && dd->height <= lpDDDesc->dwHeight		//check FSW and FSH		&& dd->fs_width > lpDDDesc->dwWidth && dd->fs_height > lpDDDesc->dwHeight) {		if (lpDDDesc->dwHeight == 200)			return DDENUMRET_OK;				dd->fs_width = lpDDDesc->dwWidth;		dd->fs_height = lpDDDesc->dwHeight;		return DDENUMRET_CANCEL;	}	return DDENUMRET_OK;}GF_Err GetDisplayMode(DDContext *dd){	if (dd->switch_res) {		HRESULT hr;		Bool temp_dd = 0;;		if (!dd->pDD) {			LPDIRECTDRAW ddraw;			DirectDrawCreate(NULL, &ddraw, NULL);#ifdef USE_DX_3			IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw, (LPVOID *)&dd->pDD);#else			IDirectDraw_QueryInterface(ddraw, &IID_IDirectDraw7, (LPVOID *)&dd->pDD);#endif					temp_dd = 1;		}		//we start with a hugde res and downscale		dd->fs_width = dd->fs_height = 50000;#ifdef USE_DX_3		hr = IDirectDraw_EnumDisplayModes(dd->pDD, 0L, NULL, dd,  (LPDDENUMMODESCALLBACK) EnumDisplayModes);#else		hr = IDirectDraw7_EnumDisplayModes(dd->pDD, 0L, NULL, dd,  (LPDDENUMMODESCALLBACK2) EnumDisplayModes);#endif		if (temp_dd) SAFE_DD_RELEASE(dd->pDD);		if (FAILED(hr)) return GF_IO_ERR;	} else {		dd->fs_width = GetSystemMetrics(SM_CXSCREEN);		dd->fs_height = GetSystemMetrics(SM_CYSCREEN);	}	return GF_OK;}static void *NewDXVideoOutput(){	DDContext *pCtx;	GF_VideoOutput *driv = (GF_VideoOutput *) malloc(sizeof(GF_VideoOutput));	memset(driv, 0, sizeof(GF_VideoOutput));	GF_REGISTER_MODULE_INTERFACE(driv, GF_VIDEO_OUTPUT_INTERFACE, "DirectX Video Output", "gpac distribution");	pCtx = malloc(sizeof(DDContext));	memset(pCtx, 0, sizeof(DDContext));	driv->opaque = pCtx;	driv->Flush = DD_Flush;	driv->Setup  = DD_Setup;	driv->Shutdown = DD_Shutdown;	driv->SetFullScreen = DD_SetFullScreen;	driv->ProcessEvent = DD_ProcessEvent;    driv->max_screen_width = GetSystemMetrics(SM_CXSCREEN);    driv->max_screen_height = GetSystemMetrics(SM_CYSCREEN);	driv->hw_caps = GF_VIDEO_HW_HAS_OPENGL;	DD_SetupDDraw(driv);	return (void *)driv;}static void DeleteVideoOutput(void *ifce){	GF_VideoOutput *driv = (GF_VideoOutput *) ifce;	DDContext *dd = (DDContext *)driv->opaque;	free(dd);	free(driv);}/*interface query*/Bool QueryInterface(u32 InterfaceType){	if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return 1;	if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) return 1;	return 0;}/*interface create*/GF_BaseInterface *LoadInterface(u32 InterfaceType){	if (InterfaceType == GF_VIDEO_OUTPUT_INTERFACE) return NewDXVideoOutput();	if (InterfaceType == GF_AUDIO_OUTPUT_INTERFACE) return NewAudioOutput();	return NULL;}/*interface destroy*/void ShutdownInterface(GF_BaseInterface *ifce){	switch (ifce->InterfaceType) {	case GF_VIDEO_OUTPUT_INTERFACE:		DeleteVideoOutput((GF_VideoOutput *)ifce);		break;	case GF_AUDIO_OUTPUT_INTERFACE:		DeleteAudioOutput(ifce);		break;	}}

⌨️ 快捷键说明

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