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

📄 vo_directx.c

📁 DawnLightPlayer,一个新的基于ffmpeg的全功能播放器
💻 C
📖 第 1 页 / 共 3 页
字号:
	if( user32dll ) 	{		myGetMonitorInfo = GetProcAddress(user32dll,"GetMonitorInfoA");		if( !myGetMonitorInfo && vo_adapter_num )		{			vo_adapter_num = 0;		}	}	hddraw_dll = LoadLibrary("DDRAW.DLL");	if ( hddraw_dll == NULL )	{		av_log(NULL, AV_LOG_ERROR, "vo_directx: failed loading ddraw.dll\n" );		return -1;	}	last_rect.left = 0xDEADC0DE;   // reset window position cache	if(vo_adapter_num) //display other than default	{		OurDirectDrawEnumerateEx = (LPDIRECTDRAWENUMERATEEX) GetProcAddress(hddraw_dll,"DirectDrawEnumerateExA");		if (!OurDirectDrawEnumerateEx)		{			FreeLibrary( hddraw_dll );			hddraw_dll = NULL;			av_log(NULL, AV_LOG_ERROR, "vo_directx: address: DirectDrawEnumerateEx\n");			av_log(NULL, AV_LOG_ERROR, "vo_directx: no directx 7 or higher installed\n");			return -1;		}		// enumerate all display devices attached to the desktop		OurDirectDrawEnumerateEx(EnumCallbackEx, NULL, DDENUM_ATTACHEDSECONDARYDEVICES );	}	FreeLibrary(user32dll);	OurDirectDrawCreateEx = (void *)GetProcAddress(hddraw_dll, "DirectDrawCreateEx");	if ( OurDirectDrawCreateEx == NULL )	{		FreeLibrary( hddraw_dll );		hddraw_dll = NULL;		av_log(NULL, AV_LOG_ERROR, "vo_directx: DirectDrawCreateEx not found\n");		return -1;	}	// initialize DirectDraw and create directx v7 object	if(OurDirectDrawCreateEx(selected_guid_ptr, (VOID**)&g_lpdd, &IID_IDirectDraw7, NULL ) != DD_OK )	{		FreeLibrary( hddraw_dll );		hddraw_dll = NULL;		av_log(NULL, AV_LOG_ERROR, "vo_directx: can't initialize ddraw\n");		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);	vm_height=ddsd.dwHeight;	vm_width=ddsd.dwWidth;	vm_bpp = ddsd.ddpfPixelFormat.dwRGBBitCount;	if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN) != DD_OK)	{		av_log(NULL, AV_LOG_ERROR, "vo_directx: 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)	{		av_log(NULL, AV_LOG_ERROR, "vo_directx: can't set displaymode\n");		return 1;	}	return 0;	if (g_lpdd->lpVtbl->SetCooperativeLevel(g_lpdd, hWnd, DDSCL_NORMAL) != DD_OK)	{		av_log(NULL, AV_LOG_ERROR, "vo_directx: not set cooperativelevel for hardwarecheck\n");		return 1;	}	av_log(NULL, AV_LOG_INFO, "DirectDraw Inited OK\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( !vo_fs )	{		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;	}	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;	}	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 > d_image_width)rs.right=((d_image_width-rd.left)*1000)/xstretch1000;		if (rd.bottom > d_image_height)rs.bottom=((d_image_height-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))		{			rd.right=rd.left+image_width;		}		else if ((width > image_width)&& !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHX))		{			rd.right = rd.left+image_width;		}		if ((height < image_height) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSHRINKY))		{			rd.bottom = rd.top + image_height;		}		else if ((height > image_height ) && !(capsDrv.dwFXCaps & DDFXCAPS_OVERLAYSTRETCHY))		{			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)		{			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	{		g_lpddclipper->lpVtbl->SetHWnd(g_lpddclipper, 0,(vo_fs)?hWndFS: hWnd);	}	RECT rdw=rd;	//          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,HWND_TOPMOST,rdw.left,rdw.top,rdw.right-rdw.left,rdw.bottom-rdw.top,SWP_NOOWNERZORDER);	/*make sure the overlay is inside the screen*/	if (rd.left<0)rd.left=0;	if (rd.right>d_image_width)rd.right=d_image_width;	if (rd.top<0)rd.top=0;	if (rd.bottom>d_image_height)rd.bottom=d_image_height;	/*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		switch (ddrval)		{			case DDERR_NOSTRETCHHW:				{					av_log(NULL, AV_LOG_ERROR, "hardware can't stretch: try to size the window back\n");					break;				}			case DDERR_INVALIDRECT:				{					av_log(NULL, AV_LOG_ERROR, "invalid rectangle\n");					break;				}			case DDERR_INVALIDPARAMS:				{					av_log(NULL, AV_LOG_ERROR, "invalid parameters\n");					break;				}			case DDERR_HEIGHTALIGN:				{					av_log(NULL, AV_LOG_ERROR, "height align\n");					break;				}			case DDERR_XALIGN:				{					av_log(NULL, AV_LOG_ERROR, "x align\n");					break;				}			case DDERR_UNSUPPORTED:				{					av_log(NULL, AV_LOG_ERROR, "unsupported\n");					break;				}			case DDERR_INVALIDSURFACETYPE:				{					av_log(NULL, AV_LOG_ERROR, "invalid surfacetype\n");					break;				}			case DDERR_INVALIDOBJECT:				{					av_log(NULL, AV_LOG_ERROR, "invalid object\n");					break;				}			case DDERR_SURFACELOST:				{					av_log(NULL, AV_LOG_ERROR, "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);					break;				}			default:				av_log(NULL, AV_LOG_ERROR, " 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))	{		av_log(NULL, AV_LOG_ERROR,"vo_directx: failed getting ddrawcaps\n");		return -1;	}	if (!(capsDrv.dwCaps & DDCAPS_OVERLAY))	{		av_log(NULL, AV_LOG_ERROR,"vo_directx: Your card doesn't support overlay\n");		return 1;	}	//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)		{			av_log(NULL, AV_LOG_ERROR,"vo_directx: %i %s supported\n",i,g_ddpf[i].img_format_name);			formatcount++;		}		else			av_log(NULL, AV_LOG_ERROR,"vo_directx: %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 );	if (formatcount == 0)	{		return -1;	}	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);	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 )	{		av_log(NULL, AV_LOG_ERROR,"vo_directx: can't get pixelformat\n");		return -1;	}

⌨️ 快捷键说明

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