From 645cf84677428fd4541387eed79ae7dbdedb5a4d Mon Sep 17 00:00:00 2001 From: Jactry Zeng Date: Thu, 29 Aug 2019 23:49:17 +0800 Subject: [PATCH] mfplat: Implement MFCreateDXGIDeviceManager(). Signed-off-by: Jactry Zeng Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/mfplat/main.c | 144 +++++++++++++++++++++++++++++++++++++ dlls/mfplat/mfplat.spec | 1 + dlls/mfplat/tests/mfplat.c | 41 +++++++++++ include/mfapi.h | 1 + include/mfobjects.idl | 17 +++++ 5 files changed, 204 insertions(+) diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index f8f4b502a5b..706251b3e07 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -7617,3 +7617,147 @@ HRESULT WINAPI CreatePropertyStore(IPropertyStore **store) return S_OK; } + +struct dxgi_device_manager +{ + IMFDXGIDeviceManager IMFDXGIDeviceManager_iface; + LONG refcount; + UINT token; +}; + +static struct dxgi_device_manager *impl_from_IMFDXGIDeviceManager(IMFDXGIDeviceManager *iface) +{ + return CONTAINING_RECORD(iface, struct dxgi_device_manager, IMFDXGIDeviceManager_iface); +} + +static HRESULT WINAPI dxgi_device_manager_QueryInterface(IMFDXGIDeviceManager *iface, REFIID riid, void **obj) +{ + TRACE("(%p, %s, %p).\n", iface, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IMFDXGIDeviceManager) || + IsEqualGUID(riid, &IID_IUnknown)) + { + *obj = iface; + IMFDXGIDeviceManager_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI dxgi_device_manager_AddRef(IMFDXGIDeviceManager *iface) +{ + struct dxgi_device_manager *manager = impl_from_IMFDXGIDeviceManager(iface); + ULONG refcount = InterlockedIncrement(&manager->refcount); + + TRACE("(%p) ref=%u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI dxgi_device_manager_Release(IMFDXGIDeviceManager *iface) +{ + struct dxgi_device_manager *manager = impl_from_IMFDXGIDeviceManager(iface); + ULONG refcount = InterlockedDecrement(&manager->refcount); + + TRACE("(%p) ref=%u.\n", iface, refcount); + + if (!refcount) + { + heap_free(manager); + } + + return refcount; +} + +static HRESULT WINAPI dxgi_device_manager_CloseDeviceHandle(IMFDXGIDeviceManager *iface, HANDLE device) +{ + FIXME("(%p, %p): stub.\n", iface, device); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dxgi_device_manager_GetVideoService(IMFDXGIDeviceManager *iface, HANDLE device, + REFIID riid, void **service) +{ + FIXME("(%p, %p, %s, %p): stub.\n", iface, device, debugstr_guid(riid), service); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dxgi_device_manager_LockDevice(IMFDXGIDeviceManager *iface, HANDLE device, + REFIID riid, void **ppv, BOOL block) +{ + FIXME("(%p, %p, %s, %p, %d): stub.\n", iface, device, wine_dbgstr_guid(riid), ppv, block); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dxgi_device_manager_OpenDeviceHandle(IMFDXGIDeviceManager *iface, HANDLE *device) +{ + FIXME("(%p, %p): stub.\n", iface, device); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dxgi_device_manager_ResetDevice(IMFDXGIDeviceManager *iface, IUnknown *device, UINT token) +{ + FIXME("(%p, %p, %u): stub.\n", iface, device, token); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dxgi_device_manager_TestDevice(IMFDXGIDeviceManager *iface, HANDLE device) +{ + FIXME("(%p, %p): stub.\n", iface, device); + + return E_NOTIMPL; +} + +static HRESULT WINAPI dxgi_device_manager_UnlockDevice(IMFDXGIDeviceManager *iface, HANDLE device, BOOL state) +{ + FIXME("(%p, %p, %d): stub.\n", iface, device, state); + + return E_NOTIMPL; +} + +static const IMFDXGIDeviceManagerVtbl dxgi_device_manager_vtbl = +{ + dxgi_device_manager_QueryInterface, + dxgi_device_manager_AddRef, + dxgi_device_manager_Release, + dxgi_device_manager_CloseDeviceHandle, + dxgi_device_manager_GetVideoService, + dxgi_device_manager_LockDevice, + dxgi_device_manager_OpenDeviceHandle, + dxgi_device_manager_ResetDevice, + dxgi_device_manager_TestDevice, + dxgi_device_manager_UnlockDevice, +}; + +HRESULT WINAPI MFCreateDXGIDeviceManager(UINT *token, IMFDXGIDeviceManager **manager) +{ + struct dxgi_device_manager *object; + + TRACE("(%p, %p).\n", token, manager); + + if (!token || !manager) + return E_POINTER; + + object = heap_alloc(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->IMFDXGIDeviceManager_iface.lpVtbl = &dxgi_device_manager_vtbl; + object->refcount = 1; + object->token = GetTickCount(); + + TRACE("Created device manager: %p, token: %u.\n", object, object->token); + + *token = object->token; + *manager = &object->IMFDXGIDeviceManager_iface; + + return S_OK; +} diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 2f16bbd1973..cc440c5ee08 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -42,6 +42,7 @@ @ stdcall MFCreateAttributes(ptr long) @ stub MFCreateAudioMediaType @ stdcall MFCreateCollection(ptr) +@ stdcall MFCreateDXGIDeviceManager(ptr ptr) @ stdcall MFCreateEventQueue(ptr) @ stdcall MFCreateFile(long long long wstr ptr) @ stub MFCreateLegacyMediaBufferOnMFMediaBuffer diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index b4ba6b6c572..e0029ab4ff6 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -58,6 +58,7 @@ static void _expect_ref(IUnknown *obj, ULONG ref, int line) static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride, DWORD width, DWORD lines); +static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager); static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver); static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream); static void* (WINAPI *pMFHeapAlloc)(SIZE_T size, ULONG flags, char *file, int line, EAllocationType type); @@ -510,6 +511,7 @@ static void init_functions(void) X(MFAddPeriodicCallback); X(MFAllocateSerialWorkQueue); X(MFCopyImage); + X(MFCreateDXGIDeviceManager); X(MFCreateSourceResolver); X(MFCreateMFByteStreamOnStream); X(MFHeapAlloc); @@ -3704,6 +3706,44 @@ if (0) ok(!refcount, "Unexpected refcount %u.\n", refcount); } +static void test_dxgi_device_manager(void) +{ + IMFDXGIDeviceManager *manager, *manager2; + UINT token, token2; + HRESULT hr; + + if (!pMFCreateDXGIDeviceManager) + { + win_skip("MFCreateDXGIDeviceManager not found.\n"); + return; + } + + hr = pMFCreateDXGIDeviceManager(NULL, &manager); + ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr); + + token = 0; + hr = pMFCreateDXGIDeviceManager(&token, NULL); + ok(hr == E_POINTER, "MFCreateDXGIDeviceManager should failed: %#x.\n", hr); + ok(!token, "got wrong token: %u.\n", token); + + hr = pMFCreateDXGIDeviceManager(&token, &manager); + ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr); + EXPECT_REF(manager, 1); + ok(!!token, "got wrong token: %u.\n", token); + + Sleep(50); + token2 = 0; + hr = pMFCreateDXGIDeviceManager(&token2, &manager2); + ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr); + EXPECT_REF(manager2, 1); + ok(token2 && token2 != token, "got wrong token: %u, %u.\n", token2, token); + ok(manager != manager2, "got wrong pointer: %p.\n", manager2); + EXPECT_REF(manager, 1); + + IMFDXGIDeviceManager_Release(manager); + IMFDXGIDeviceManager_Release(manager2); +} + START_TEST(mfplat) { CoInitialize(NULL); @@ -3741,6 +3781,7 @@ START_TEST(mfplat) test_async_create_file(); test_local_handlers(); test_create_property_store(); + test_dxgi_device_manager(); CoUninitialize(); } diff --git a/include/mfapi.h b/include/mfapi.h index 957fb0df9fc..f84c051792d 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -384,6 +384,7 @@ HRESULT WINAPI MFCreateAlignedMemoryBuffer(DWORD max_length, DWORD alignment, IM HRESULT WINAPI MFCreateAttributes(IMFAttributes **attributes, UINT32 size); HRESULT WINAPI MFCreateAsyncResult(IUnknown *object, IMFAsyncCallback *callback, IUnknown *state, IMFAsyncResult **result); HRESULT WINAPI MFCreateCollection(IMFCollection **collection); +HRESULT WINAPI MFCreateDXGIDeviceManager(UINT *token, IMFDXGIDeviceManager **manager); HRESULT WINAPI MFCreateEventQueue(IMFMediaEventQueue **queue); HRESULT WINAPI MFCreateFile(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPENMODE openmode, MF_FILE_FLAGS flags, LPCWSTR url, IMFByteStream **bytestream); diff --git a/include/mfobjects.idl b/include/mfobjects.idl index 0cc8f422da4..203acc770f6 100644 --- a/include/mfobjects.idl +++ b/include/mfobjects.idl @@ -727,3 +727,20 @@ interface IMFMediaEventQueue : IUnknown [in] HRESULT status, [in, unique] IUnknown *unk); HRESULT Shutdown(); } + +[ + object, + uuid(eb533d5d-2db6-40f8-97a9-494692014f07), + local, + pointer_default(unique) +] +interface IMFDXGIDeviceManager : IUnknown +{ + HRESULT CloseDeviceHandle([in] HANDLE device); + HRESULT GetVideoService([in] HANDLE device, [in] REFIID riid, [out] void **service); + HRESULT LockDevice([in] HANDLE device, [in] REFIID riid, [out] void **ppv, [in] BOOL block); + HRESULT OpenDeviceHandle([out] HANDLE *device); + HRESULT ResetDevice([in] IUnknown *device, [in] UINT token); + HRESULT TestDevice([in] HANDLE device); + HRESULT UnlockDevice([in] HANDLE device, [in] BOOL state); +}