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

📄 vo_directx.c.orig

📁 DawnLightPlayer,一个新的基于ffmpeg的全功能播放器
💻 ORIG
📖 第 1 页 / 共 4 页
字号:
		return 1;	}	//get current screen siz for selected monitor ...	ddsd.dwSize=sizeof(ddsd);	ddsd.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT;	g_lpdd->lpVtbl->GetDisplayMode(g_lpdd, &ddsd);	if (vo_screenwidth && vo_screenheight)	{		vm_height=vo_screenheight;		vm_width=vo_screenwidth;	}	else	{		vm_height=ddsd.dwHeight;		vm_width=ddsd.dwWidth;	}	if (vo_dbpp)vm_bpp=vo_dbpp;	else vm_bpp=ddsd.ddpfPixelFormat.dwRGBBitCount;	if (vidmode)	{		if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK)		{			mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set cooperativelevel for exclusive mode\n");			return 1;		}		/*SetDisplayMode(ddobject,width,height,bpp,refreshrate,aditionalflags)*/		if (g_lpdd->lpVtbl->SetDisplayMode(g_lpdd,vm_width, vm_height, vm_bpp,0,0) != DD_OK)		{			mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>can't set displaymode\n");			return 1;		}		mp_msg(MSGT_VO, MSGL_V,"<vo_directx><INFO>Inited adapter %i for %i x %i @ %i \n",vo_adapter_num,vm_width,vm_height,vm_bpp);		return 0;	}	if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_NORMAL) != DD_OK) // or DDSCL_SETFOCUSWINDOW	{		mp_msg(MSGT_VO, MSGL_FATAL,"<vo_directx><FATAL ERROR>could not set cooperativelevel for hardwarecheck\n");		return 1;	}	mp_msg(MSGT_VO, MSGL_DBG3,"<vo_directx><INFO>DirectDraw Inited\n");	return 0;}static void check_events(void){	MSG msg;	while (PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))	{		TranslateMessage(&msg);		DispatchMessage(&msg);	}}static uint32_t Directx_ManageDisplay(){	HRESULT         ddrval;	DDCAPS          capsDrv;	DDOVERLAYFX     ovfx;	DWORD           dwUpdateFlags=0;	int width,height;	if (!vidmode && !vo_fs && WinID!=-1)	{		RECT current_rect = {0, 0, 0, 0};		GetWindowRect(hWnd, &current_rect);		if ((current_rect.left   == last_rect.left)		        &&  (current_rect.top    == last_rect.top)		        &&  (current_rect.right  == last_rect.right)		        &&  (current_rect.bottom == last_rect.bottom))			return 0;		last_rect = current_rect;	}	if (vo_fs || vidmode)	{		aspect(&width,&height,A_ZOOM);		rd.left=(vo_screenwidth-width)/2;		rd.top=(vo_screenheight-height)/2;		if (WinID == -1)			if (ShowCursor(FALSE)>=0)while (ShowCursor(FALSE)>=0){}	}	else if (WinID != -1 && vo_geometry)	{		POINT pt;		pt.x = vo_dx;		pt.y = vo_dy;		ClientToScreen(hWnd,&pt);		width=d_image_width;		height=d_image_height;		rd.left = pt.x;		rd.top = pt.y;		while (ShowCursor(TRUE)<=0){}	}	else	{		POINT pt;		pt.x = 0;  //overlayposition relative to the window		pt.y = 0;		ClientToScreen(hWnd,&pt);		GetClientRect(hWnd, &rd);		width=rd.right - rd.left;		height=rd.bottom - rd.top;		pt.x -= monitor_rect.left;    /* move coordinates from global to local monitor space */		pt.y -= monitor_rect.top;		rd.right -= monitor_rect.left;		rd.bottom -= monitor_rect.top;		rd.left = pt.x;		rd.top = pt.y;		if (!nooverlay && (!width || !height))		{			/*window is minimized*/			ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL);			return 0;		}		if (vo_keepaspect)		{			int tmpheight=((float)width/window_aspect);			tmpheight+=tmpheight%2;			if (tmpheight > height)			{				width=((float)height*window_aspect);				width+=width%2;			}			else height=tmpheight;		}		if (WinID == -1)			while (ShowCursor(TRUE)<=0){}	}	rd.right=rd.left+width;	rd.bottom=rd.top+height;	/*ok, let's workaround some overlay limitations*/	if (!nooverlay)	{		uint32_t        uStretchFactor1000;  //minimum stretch		uint32_t        xstretch1000,ystretch1000;		/*get driver capabilities*/		ZeroMemory(&capsDrv, sizeof(capsDrv));		capsDrv.dwSize = sizeof(capsDrv);		if (g_lpdd->lpVtbl->GetCaps(g_lpdd,&capsDrv, NULL) != DD_OK)return 1;		/*get minimum stretch, depends on display adaptor and mode (refresh rate!) */		uStretchFactor1000 = capsDrv.dwMinOverlayStretch>1000 ? capsDrv.dwMinOverlayStretch : 1000;		rd.right = ((width+rd.left)*uStretchFactor1000+999)/1000;		rd.bottom = (height+rd.top)*uStretchFactor1000/1000;		/*calculate xstretch1000 and ystretch1000*/		xstretch1000 = ((rd.right - rd.left)* 1000)/image_width ;		ystretch1000 = ((rd.bottom - rd.top)* 1000)/image_height;		rs.left=0;		rs.right=image_width;		rs.top=0;		rs.bottom=image_height;		if (rd.left < 0)rs.left=(-rd.left*1000)/xstretch1000;		if (rd.top < 0)rs.top=(-rd.top*1000)/ystretch1000;		if (rd.right > vo_screenwidth)rs.right=((vo_screenwidth-rd.left)*1000)/xstretch1000;		if (rd.bottom > vo_screenheight)rs.bottom=((vo_screenheight-rd.top)*1000)/ystretch1000;		/*do not allow to zoom or shrink if hardware isn't able to do so*/		if ((width < image_width)&& !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKX))		{			if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKXN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only shrinkN\n");			else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't shrink x\n");			rd.right=rd.left+image_width;		}		else if ((width > image_width)&& !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHX))		{			if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHXN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only stretchN\n");			else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't stretch x\n");			rd.right = rd.left+image_width;		}		if ((height < image_height) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKY))		{			if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKYN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only shrinkN\n");			else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't shrink y\n");			rd.bottom = rd.top + image_height;		}		else if ((height > image_height ) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHY))		{			if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHYN)mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can only stretchN\n");			else mp_msg(MSGT_VO, MSGL_ERR,"<vo_directx><ERROR>can't stretch y\n");			rd.bottom = rd.top + image_height;		}		/*the last thing to check are alignment restrictions		  these expressions (x & -y) just do alignment by dropping low order bits...		  so to round up, we add first, then truncate*/		if ((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYSRC) && capsDrv.dwAlignBoundarySrc)			rs.left = (rs.left + capsDrv.dwAlignBoundarySrc / 2) & -(signed)(capsDrv.dwAlignBoundarySrc);		if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZESRC) && capsDrv.dwAlignSizeSrc)			rs.right = rs.left + ((rs.right - rs.left + capsDrv.dwAlignSizeSrc / 2) & -(signed) (capsDrv.dwAlignSizeSrc));		if ((capsDrv.dwCaps & DDCAPS_ALIGNBOUNDARYDEST) && capsDrv.dwAlignBoundaryDest)			rd.left = (rd.left + capsDrv.dwAlignBoundaryDest / 2) & -(signed)(capsDrv.dwAlignBoundaryDest);		if ((capsDrv.dwCaps & DDCAPS_ALIGNSIZEDEST) && capsDrv.dwAlignSizeDest)			rd.right = rd.left + ((rd.right - rd.left) & -(signed) (capsDrv.dwAlignSizeDest));		/*create an overlay FX structure to specify a destination color key*/		ZeroMemory(&ovfx, sizeof(ovfx));		ovfx.dwSize = sizeof(ovfx);		if (vo_fs||vidmode)		{			ovfx.dckDestColorkey.dwColorSpaceLowValue = 0;			ovfx.dckDestColorkey.dwColorSpaceHighValue = 0;		}		else		{			ovfx.dckDestColorkey.dwColorSpaceLowValue = destcolorkey;			ovfx.dckDestColorkey.dwColorSpaceHighValue = destcolorkey;		}		// set the flags we'll send to UpdateOverlay      //DDOVER_AUTOFLIP|DDOVERFX_MIRRORLEFTRIGHT|DDOVERFX_MIRRORUPDOWN could be useful?;		dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX;		/*if hardware can't do colorkeying set the window on top*/		if (capsDrv.dwCKeyCaps & DDCKEYCAPS_DESTOVERLAY) dwUpdateFlags |= DDOVER_KEYDESTOVERRIDE;		else if (!tmp_image) vo_ontop = 1;	}	else	{		g_lpddclipper->lpVtbl->SetHWnd(g_lpddclipper, 0,(vo_fs && !vidmode)?hWndFS: hWnd);	}	if (!vidmode && !vo_fs)	{		if (WinID == -1)		{			RECT rdw=rd;			if (vo_border)				AdjustWindowRect(&rdw,WNDSTYLE,FALSE);			//          printf("window: %i %i %ix%i\n",rdw.left,rdw.top,rdw.right - rdw.left,rdw.bottom - rdw.top);			rdw.left += monitor_rect.left; /* move to global coordinate space */			rdw.top += monitor_rect.top;			rdw.right += monitor_rect.left;			rdw.bottom += monitor_rect.top;			SetWindowPos(hWnd,(vo_ontop)?HWND_TOPMOST:(vo_rootwin?HWND_BOTTOM:HWND_NOTOPMOST),rdw.left,rdw.top,rdw.right-rdw.left,rdw.bottom-rdw.top,SWP_NOOWNERZORDER);		}	}	else SetWindowPos(vidmode?hWnd:hWndFS,vo_rootwin?HWND_BOTTOM:HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_NOOWNERZORDER|SWP_NOCOPYBITS);	/*make sure the overlay is inside the screen*/	if (rd.left<0)rd.left=0;	if (rd.right>vo_screenwidth)rd.right=vo_screenwidth;	if (rd.top<0)rd.top=0;	if (rd.bottom>vo_screenheight)rd.bottom=vo_screenheight;	/*for nonoverlay mode we are finished, for overlay mode we have to display the overlay first*/	if (nooverlay)return 0;	//    printf("overlay: %i %i %ix%i\n",rd.left,rd.top,rd.right - rd.left,rd.bottom - rd.top);	ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,&rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx);	if (FAILED(ddrval))	{		// one cause might be the driver lied about minimum stretch		// we should try upping the destination size a bit, or		// perhaps shrinking the source size		mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>UpdateOverlay failed\n" );		mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>Overlay:x1:%i,y1:%i,x2:%i,y2:%i,w:%i,h:%i\n",rd.left,rd.top,rd.right,rd.bottom,rd.right - rd.left,rd.bottom - rd.top );		mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>");		switch (ddrval)		{		case DDERR_NOSTRETCHHW:		{			mp_msg(MSGT_VO, MSGL_ERR ,"hardware can't stretch: try to size the window back\n");			break;		}		case DDERR_INVALIDRECT:		{			mp_msg(MSGT_VO, MSGL_ERR ,"invalid rectangle\n");			break;		}		case DDERR_INVALIDPARAMS:		{			mp_msg(MSGT_VO, MSGL_ERR ,"invalid parameters\n");			break;		}		case DDERR_HEIGHTALIGN:		{			mp_msg(MSGT_VO, MSGL_ERR ,"height align\n");			break;		}		case DDERR_XALIGN:		{			mp_msg(MSGT_VO, MSGL_ERR ,"x align\n");			break;		}		case DDERR_UNSUPPORTED:		{			mp_msg(MSGT_VO, MSGL_ERR ,"unsupported\n");			break;		}		case DDERR_INVALIDSURFACETYPE:		{			mp_msg(MSGT_VO, MSGL_ERR ,"invalid surfacetype\n");			break;		}		case DDERR_INVALIDOBJECT:		{			mp_msg(MSGT_VO, MSGL_ERR ,"invalid object\n");			break;		}		case DDERR_SURFACELOST:		{			mp_msg(MSGT_VO, MSGL_ERR ,"surfaces lost\n");			g_lpddsOverlay->lpVtbl->Restore( g_lpddsOverlay ); //restore and try again			g_lpddsPrimary->lpVtbl->Restore( g_lpddsPrimary );			ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,&rs, g_lpddsPrimary, &rd, dwUpdateFlags, &ovfx);			if (ddrval !=DD_OK)mp_msg(MSGT_VO, MSGL_FATAL ,"<vo_directx><FATAL ERROR>UpdateOverlay failed again\n" );			break;		}		default:			mp_msg(MSGT_VO, MSGL_ERR ," 0x%x\n",ddrval);		}		/*ok we can't do anything about it -> hide overlay*/		if (ddrval != DD_OK)		{			ddrval = g_lpddsOverlay->lpVtbl->UpdateOverlay(g_lpddsOverlay,NULL, g_lpddsPrimary, NULL, DDOVER_HIDE, NULL);			return 1;		}	}	return 0;}//find out supported overlay pixelformatsstatic uint32_t Directx_CheckOverlayPixelformats(){	DDCAPS          capsDrv;	HRESULT         ddrval;	DDSURFACEDESC2   ddsdOverlay;	uint32_t        i;	uint32_t        formatcount = 0;	//get driver caps to determine overlay support	ZeroMemory(&capsDrv, sizeof(capsDrv));	capsDrv.dwSize = sizeof(capsDrv);	ddrval = g_lpdd->lpVtbl->GetCaps(g_lpdd,&capsDrv, NULL);	if (FAILED(ddrval))	{		mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>failed getting ddrawcaps\n");		return 1;	}	if (!(capsDrv.dwCaps & DDCAPS_OVERLAY))	{		mp_msg(MSGT_VO, MSGL_ERR ,"<vo_directx><ERROR>Your card doesn't support overlay\n");		return 1;	}	mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>testing supported overlay pixelformats\n");	//it is not possible to query for pixel formats supported by the	//overlay hardware: try out various formats till one works	ZeroMemory(&ddsdOverlay, sizeof(ddsdOverlay));	ddsdOverlay.dwSize = sizeof(ddsdOverlay);	ddsdOverlay.ddsCaps.dwCaps=DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;	ddsdOverlay.dwFlags= DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH| DDSD_PIXELFORMAT;	ddsdOverlay.dwWidth=300;	ddsdOverlay.dwHeight=280;	ddsdOverlay.dwBackBufferCount=0;	//try to create an overlay surface using one of the pixel formats in our global list	i=0;	do	{		ddsdOverlay.ddpfPixelFormat=g_ddpf[i].g_ddpfOverlay;		ddrval = g_lpdd->lpVtbl->CreateSurface(g_lpdd,&ddsdOverlay, &g_lpddsOverlay, NULL);		if (ddrval == DD_OK)		{			mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT OVERLAY>%i %s supported\n",i,g_ddpf[i].img_format_name);			g_ddpf[i].drv_caps = VFCAP_CSP_SUPPORTED |VFCAP_OSD |VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_HWSCALE_UP;			formatcount++;		}		else mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT OVERLAY>%i %s not supported\n",i,g_ddpf[i].img_format_name);		if (g_lpddsOverlay != NULL)		{			g_lpddsOverlay->lpVtbl->Release(g_lpddsOverlay);			g_lpddsOverlay = NULL;		}	}	while ( ++i < NUM_FORMATS );	mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>Your card supports %i of %i overlayformats\n",formatcount, NUM_FORMATS);	if (formatcount == 0)	{		mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><WARN>Your card supports overlay, but we couldn't create one\n");		mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>This can have the following reasons:\n");		mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- you are already using an overlay with another app\n");		mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- you don't have enough videomemory\n");		mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>- vo_directx doesn't support the cards overlay pixelformat\n");		return 1;	}	if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYMIRRORLEFTRIGHT)mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>can mirror left right\n"); //I don't have hardware which	if (capsDrv.dwFXCaps & DDFXCAPS_OVERLAYMIRRORUPDOWN )mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>can mirror up down\n");     //supports those send me one and I'll implement ;)	return 0;}//find out the Pixelformat of the Primary Surfacestatic uint32_t Directx_CheckPrimaryPixelformat(){	uint32_t i=0;	uint32_t formatcount = 0;	DDPIXELFORMAT	ddpf;	DDSURFACEDESC2   ddsd;	HDC             hdc;	HRESULT         hres;	COLORREF        rgbT=RGB(0,0,0);	mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><INFO>checking primary surface\n");	memset( &ddpf, 0, sizeof( DDPIXELFORMAT ));	ddpf.dwSize = sizeof( DDPIXELFORMAT );	//we have to create a primary surface first	if (Directx_CreatePrimarySurface()!=0)return 1;	if (g_lpddsPrimary->lpVtbl->GetPixelFormat( g_lpddsPrimary, &ddpf ) != DD_OK )	{		mp_msg(MSGT_VO, MSGL_FATAL ,"<vo_directx><FATAL ERROR>can't get pixelformat\n");		return 1;	}	while ( i < NUM_FORMATS )	{		if (g_ddpf[i].g_ddpfOverlay.dwRGBBitCount == ddpf.dwRGBBitCount)		{			if (g_ddpf[i].g_ddpfOverlay.dwRBitMask == ddpf.dwRBitMask)			{				mp_msg(MSGT_VO, MSGL_V ,"<vo_directx><FORMAT PRIMARY>%i %s supported\n",i,g_ddpf[i].img_format_name);				g_ddpf[i].drv_caps = VFCAP_CSP_SUPPORTED |VFCAP_OSD;				formatcount++;				primary_image_format=g_ddpf[i].img_format;			}		}		i++;	}	//get the colorkey for overlay mode	destcolorkey = CLR_INVALID;	if (windowcolor != CLR_INVALID && g_lpddsPrimary->lpVtbl->GetDC(g_lpddsPrimary,&hdc) == DD_OK)	{

⌨️ 快捷键说明

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