static UINT D3D_FindAdapter(IDirect3D9 * d3d, SDL_VideoDisplay * display) { SDL_DisplayData *displaydata = (SDL_DisplayData *) display->driverdata; UINT adapter, count; count = IDirect3D9_GetAdapterCount(d3d); for (adapter = 0; adapter < count; ++adapter) { HRESULT result; D3DADAPTER_IDENTIFIER9 info; char *name; result = IDirect3D9_GetAdapterIdentifier(d3d, adapter, 0, &info); if (FAILED(result)) { continue; } name = WIN_StringToUTF8(displaydata->DeviceName); if (SDL_strcmp(name, info.DeviceName) == 0) { SDL_free(name); return adapter; } SDL_free(name); } /* This should never happen, but just in case... */ return D3DADAPTER_DEFAULT; }
/** * It creates a Direct3D device and the associated resources. */ static int Direct3DOpen(vout_display_t *vd, video_format_t *fmt) { vout_display_sys_t *sys = vd->sys; LPDIRECT3D9 d3dobj = sys->d3dobj; if (Direct3DFillPresentationParameters(vd)) return VLC_EGENERIC; // Create the D3DDevice LPDIRECT3DDEVICE9 d3ddev; UINT AdapterToUse = D3DADAPTER_DEFAULT; D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL; #ifndef NDEBUG // Look for 'NVIDIA PerfHUD' adapter // If it is present, override default settings for (UINT Adapter=0; Adapter< IDirect3D9_GetAdapterCount(d3dobj); ++Adapter) { D3DADAPTER_IDENTIFIER9 Identifier; HRESULT Res; Res = IDirect3D9_GetAdapterIdentifier(d3dobj,Adapter,0,&Identifier); if (strstr(Identifier.Description,"PerfHUD") != 0) { AdapterToUse = Adapter; DeviceType = D3DDEVTYPE_REF; break; } } #endif HRESULT hr = IDirect3D9_CreateDevice(d3dobj, AdapterToUse, DeviceType, sys->hvideownd, D3DCREATE_SOFTWARE_VERTEXPROCESSING| D3DCREATE_MULTITHREADED, &sys->d3dpp, &d3ddev); if (FAILED(hr)) { msg_Err(vd, "Could not create the D3D device! (hr=0x%lX)", hr); return VLC_EGENERIC; } sys->d3ddev = d3ddev; UpdateRects(vd, NULL, NULL, true); if (Direct3DCreateResources(vd, fmt)) { msg_Err(vd, "Failed to allocate resources"); return VLC_EGENERIC; } /* Change the window title bar text */ EventThreadUpdateTitle(sys->event, VOUT_TITLE " (Direct3D output)"); msg_Dbg(vd, "Direct3D device adapter successfully initialized"); return VLC_SUCCESS; }
static gboolean gst_dx9screencapsrc_start (GstBaseSrc * bsrc) { GstDX9ScreenCapSrc *src = GST_DX9SCREENCAPSRC (bsrc); D3DPRESENT_PARAMETERS d3dpp; HMONITOR monitor; HRESULT res; src->frame_number = -1; ZeroMemory (&d3dpp, sizeof (D3DPRESENT_PARAMETERS)); d3dpp.Windowed = TRUE; d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; d3dpp.BackBufferFormat = src->disp_mode.Format; d3dpp.BackBufferHeight = src->disp_mode.Height; d3dpp.BackBufferWidth = src->disp_mode.Width; d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = GetDesktopWindow (); d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; if (src->monitor >= IDirect3D9_GetAdapterCount (g_d3d9)) { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("Specified monitor with index %d not found", src->monitor), (NULL)); return FALSE; } res = IDirect3D9_CreateDevice (g_d3d9, src->monitor, D3DDEVTYPE_HAL, GetDesktopWindow (), D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &src->d3d9_device); if (FAILED (res)) return FALSE; monitor = IDirect3D9_GetAdapterMonitor (g_d3d9, src->monitor); GetMonitorInfo (monitor, &src->monitor_info); return SUCCEEDED (IDirect3DDevice9_CreateOffscreenPlainSurface (src->d3d9_device, src->disp_mode.Width, src->disp_mode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &src->surface, NULL)); }
int SDL_Direct3D9GetAdapterIndex( int displayIndex ) { void *pD3DDLL; IDirect3D9 *pD3D; if (!D3D_LoadDLL(&pD3DDLL, &pD3D)) { SDL_SetError("Unable to create Direct3D interface"); return D3DADAPTER_DEFAULT; } else { SDL_DisplayData *pData = (SDL_DisplayData *)SDL_GetDisplayDriverData(displayIndex); int adapterIndex = D3DADAPTER_DEFAULT; if (!pData) { SDL_SetError("Invalid display index"); adapterIndex = -1; /* make sure we return something invalid */ } else { char *displayName = WIN_StringToUTF8(pData->DeviceName); unsigned int count = IDirect3D9_GetAdapterCount(pD3D); unsigned int i; for (i=0; i<count; i++) { D3DADAPTER_IDENTIFIER9 id; IDirect3D9_GetAdapterIdentifier(pD3D, i, 0, &id); if (SDL_strcmp(id.DeviceName, displayName) == 0) { adapterIndex = i; break; } } SDL_free(displayName); } /* free up the D3D stuff we inited */ IDirect3D9_Release(pD3D); SDL_UnloadObject(pD3DDLL); return adapterIndex; } }
static UINT get_adapter_count(base *d3dptr) { IDirect3D9 *d3d9 = (IDirect3D9 *)d3dptr->d3dobj; return IDirect3D9_GetAdapterCount(d3d9); }
static GstCaps * gst_dx9screencapsrc_get_caps (GstBaseSrc * bsrc, GstCaps * filter) { GstDX9ScreenCapSrc *src = GST_DX9SCREENCAPSRC (bsrc); RECT rect_dst; GstCaps *caps; if (src->monitor >= IDirect3D9_GetAdapterCount (g_d3d9)) { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("Specified monitor with index %d not found", src->monitor), (NULL)); return NULL; } if (FAILED (IDirect3D9_GetAdapterDisplayMode (g_d3d9, src->monitor, &src->disp_mode))) { return NULL; } SetRect (&rect_dst, 0, 0, src->disp_mode.Width, src->disp_mode.Height); src->screen_rect = rect_dst; if (src->capture_w && src->capture_h && src->capture_x + src->capture_w < rect_dst.right - rect_dst.left && src->capture_y + src->capture_h < rect_dst.bottom - rect_dst.top) { rect_dst.left = src->capture_x; rect_dst.top = src->capture_y; rect_dst.right = src->capture_x + src->capture_w; rect_dst.bottom = src->capture_y + src->capture_h; } else { /* Default values */ src->capture_x = src->capture_y = 0; src->capture_w = src->capture_h = 0; } /* Note: * Expose as xRGB even though the Surface is allocated as ARGB! * This is due to IDirect3DDevice9_GetFrontBufferData which only takes * ARGB surface, but the A channel is in reality never used. * I should add that I had problems specifying ARGB. It might be a bug * in ffmpegcolorspace which I used for testing. * Another interesting thing is that directdrawsink did not support ARGB, * but only xRGB. (On my system, using 32b color depth) And according to * the DirectX documentation ARGB is NOT a valid display buffer format, * but xRGB is. */ caps = gst_caps_new_simple ("video/x-raw", "format", G_TYPE_STRING, "BGRx", "width", G_TYPE_INT, rect_dst.right - rect_dst.left, "height", G_TYPE_INT, rect_dst.bottom - rect_dst.top, "framerate", GST_TYPE_FRACTION_RANGE, 1, 1, G_MAXINT, 1, "pixel-aspect-ratio", GST_TYPE_FRACTION, 1, 1, NULL); if (filter) { GstCaps *tmp = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST); gst_caps_unref (caps); caps = tmp; } return caps; }
HRESULT D3D9_CreateDevice(vlc_object_t *o, d3d9_handle_t *hd3d, HWND hwnd, const video_format_t *source, d3d9_device_t *out) { HRESULT hr; UINT AdapterToUse = D3DADAPTER_DEFAULT; D3DDEVTYPE DeviceType = D3DDEVTYPE_HAL; #ifndef NDEBUG // Look for 'NVIDIA PerfHUD' adapter // If it is present, override default settings for (UINT Adapter=0; Adapter< IDirect3D9_GetAdapterCount(hd3d->obj); ++Adapter) { D3DADAPTER_IDENTIFIER9 Identifier; hr = IDirect3D9_GetAdapterIdentifier(hd3d->obj,Adapter,0,&Identifier); if (SUCCEEDED(hr) && strstr(Identifier.Description,"PerfHUD") != 0) { AdapterToUse = Adapter; DeviceType = D3DDEVTYPE_REF; break; } } #endif /* ** Get device capabilities */ ZeroMemory(&out->caps, sizeof(out->caps)); hr = IDirect3D9_GetDeviceCaps(hd3d->obj, AdapterToUse, DeviceType, &out->caps); if (FAILED(hr)) { msg_Err(o, "Could not read adapter capabilities. (hr=0x%0lx)", hr); return hr; } msg_Dbg(o, "D3D9 device caps 0x%0lX / 0x%0lX", out->caps.DevCaps, out->caps.DevCaps2); /* TODO: need to test device capabilities and select the right render function */ if (!(out->caps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES)) { msg_Err(o, "Device does not support stretching from textures."); return E_INVALIDARG; } if ( source->i_width > out->caps.MaxTextureWidth || source->i_height > out->caps.MaxTextureHeight ) { msg_Err(o, "Textures too large %ux%u max possible: %ux%u", source->i_width, source->i_height, (unsigned) out->caps.MaxTextureWidth, (unsigned) out->caps.MaxTextureHeight); return E_INVALIDARG; } out->adapterId = AdapterToUse; out->hwnd = hwnd; if (D3D9_FillPresentationParameters(hd3d, source, out)) { msg_Err(o, "Could not presentation parameters"); return E_INVALIDARG; } /* */ D3DADAPTER_IDENTIFIER9 d3dai; if (FAILED(IDirect3D9_GetAdapterIdentifier(hd3d->obj, AdapterToUse,0, &d3dai))) { msg_Warn(o, "IDirect3D9_GetAdapterIdentifier failed"); } else { msg_Dbg(o, "Direct3d9 Device: %s %lx %lx %lx", d3dai.Description, d3dai.VendorId, d3dai.DeviceId, d3dai.Revision ); } DWORD thread_modes[] = { D3DCREATE_MULTITHREADED, 0 }; DWORD vertex_modes[] = { D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, D3DCREATE_HARDWARE_VERTEXPROCESSING, D3DCREATE_MIXED_VERTEXPROCESSING, D3DCREATE_SOFTWARE_VERTEXPROCESSING }; for (size_t t = 0; t < ARRAY_SIZE(thread_modes); t++) { for (size_t v = 0; v < ARRAY_SIZE(vertex_modes); v++) { DWORD creationFlags = thread_modes[t] | vertex_modes[v]; if (hd3d->use_ex) hr = IDirect3D9Ex_CreateDeviceEx(hd3d->objex, AdapterToUse, DeviceType, hwnd, creationFlags, &out->pp, NULL, &out->devex); else hr = IDirect3D9_CreateDevice(hd3d->obj, AdapterToUse, DeviceType, hwnd, creationFlags, &out->pp, &out->dev); if (SUCCEEDED(hr)) { out->owner = true; return hr; } } } msg_Err(o, "failed to create the D3D9%s device %d/%d. (hr=0x%lX)", hd3d->use_ex?"Ex":"", AdapterToUse, DeviceType, hr); return hr; }