[PATCH 1/6] mfplat: Implement MFCreateDXGIDeviceManager().

Jactry Zeng jzeng at codeweavers.com
Wed Aug 28 08:37:07 CDT 2019


Signed-off-by: Jactry Zeng <jzeng at codeweavers.com>
---
 dlls/mfplat/main.c         | 158 +++++++++++++++++++++++++++++++++++++
 dlls/mfplat/mfplat.spec    |   1 +
 dlls/mfplat/tests/mfplat.c |  75 ++++++++++++++++++
 include/mfapi.h            |   1 +
 include/mfobjects.idl      |  17 ++++
 5 files changed, 252 insertions(+)

diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index f8f4b502a5..c2293cfd8b 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -7617,3 +7617,161 @@ HRESULT WINAPI CreatePropertyStore(IPropertyStore **store)
 
     return S_OK;
 }
+
+struct mfdxgi_dev_mgr
+{
+    IMFDXGIDeviceManager IMFDXGIDeviceManager_iface;
+    LONG ref;
+    UINT token;
+};
+
+static struct mfdxgi_dev_mgr *impl_from_IMFDXGIDeviceManager(IMFDXGIDeviceManager *iface)
+{
+    return CONTAINING_RECORD(iface, struct mfdxgi_dev_mgr, IMFDXGIDeviceManager_iface);
+}
+
+static HRESULT WINAPI mfdxgi_dev_mgr_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 mfdxgi_dev_mgr_AddRef(IMFDXGIDeviceManager *iface)
+{
+    struct mfdxgi_dev_mgr *manager = impl_from_IMFDXGIDeviceManager(iface);
+    ULONG refcount = InterlockedIncrement(&manager->ref);
+
+    TRACE("(%p) ref=%u.\n", iface, refcount);
+
+    return refcount;
+}
+
+static ULONG WINAPI mfdxgi_dev_mgr_Release(IMFDXGIDeviceManager *iface)
+{
+    struct mfdxgi_dev_mgr *manager = impl_from_IMFDXGIDeviceManager(iface);
+    ULONG refcount = InterlockedDecrement(&manager->ref);
+
+    TRACE("(%p) ref=%u.\n", iface, refcount);
+
+    if (!refcount)
+    {
+        heap_free(manager);
+    }
+
+    return refcount;
+}
+
+static HRESULT WINAPI mfdxgi_dev_mgr_CloseDeviceHandle(IMFDXGIDeviceManager *iface, HANDLE device)
+{
+    struct mfdxgi_dev_mgr *This = impl_from_IMFDXGIDeviceManager(iface);
+
+    FIXME("(%p)->(%p): stub.\n", This, device);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfdxgi_dev_mgr_GetVideoService(IMFDXGIDeviceManager *iface, HANDLE device,
+                                                     REFIID riid, void **service)
+{
+    struct mfdxgi_dev_mgr *This = impl_from_IMFDXGIDeviceManager(iface);
+
+    FIXME("(%p)->(%p, %s, %p): stub.\n", This, device, debugstr_guid(riid), service);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfdxgi_dev_mgr_LockDevice(IMFDXGIDeviceManager *iface, HANDLE device,
+                                                REFIID riid, void **ppv, BOOL block)
+{
+    struct mfdxgi_dev_mgr *This = impl_from_IMFDXGIDeviceManager(iface);
+
+    FIXME("(%p)->(%p, %s, %p, %d): stub.\n", This, device, wine_dbgstr_guid(riid), ppv, block);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfdxgi_dev_mgr_OpenDeviceHandle(IMFDXGIDeviceManager *iface, HANDLE *device)
+{
+    struct mfdxgi_dev_mgr *This = impl_from_IMFDXGIDeviceManager(iface);
+
+    FIXME("(%p)->(%p): stub.\n", This, device);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfdxgi_dev_mgr_ResetDevice(IMFDXGIDeviceManager *iface, IUnknown *device, UINT token)
+{
+    struct mfdxgi_dev_mgr *This = impl_from_IMFDXGIDeviceManager(iface);
+
+    FIXME("(%p)->(%p, %u): stub.\n", This, device, token);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfdxgi_dev_mgr_TestDevice(IMFDXGIDeviceManager *iface, HANDLE device)
+{
+    struct mfdxgi_dev_mgr *This = impl_from_IMFDXGIDeviceManager(iface);
+
+    FIXME("(%p)->(%p): stub.\n", This, device);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI mfdxgi_dev_mgr_UnlockDevice(IMFDXGIDeviceManager *iface, HANDLE device, BOOL state)
+{
+    struct mfdxgi_dev_mgr *This = impl_from_IMFDXGIDeviceManager(iface);
+
+    FIXME("(%p)->(%p, %d): stub.\n", This, device, state);
+
+    return E_NOTIMPL;
+}
+
+static const IMFDXGIDeviceManagerVtbl mfdxgi_dev_mgr_vtbl =
+{
+    mfdxgi_dev_mgr_QueryInterface,
+    mfdxgi_dev_mgr_AddRef,
+    mfdxgi_dev_mgr_Release,
+    mfdxgi_dev_mgr_CloseDeviceHandle,
+    mfdxgi_dev_mgr_GetVideoService,
+    mfdxgi_dev_mgr_LockDevice,
+    mfdxgi_dev_mgr_OpenDeviceHandle,
+    mfdxgi_dev_mgr_ResetDevice,
+    mfdxgi_dev_mgr_TestDevice,
+    mfdxgi_dev_mgr_UnlockDevice,
+};
+
+HRESULT WINAPI MFCreateDXGIDeviceManager(UINT *token, IMFDXGIDeviceManager **manager)
+{
+    struct mfdxgi_dev_mgr *dev_mgr;
+
+    TRACE("(%p, %p).\n", token, manager);
+
+    if (!token || !manager)
+        return E_POINTER;
+
+    dev_mgr = heap_alloc(sizeof(*dev_mgr));
+    if (!dev_mgr)
+        return E_OUTOFMEMORY;
+
+    dev_mgr->IMFDXGIDeviceManager_iface.lpVtbl = &mfdxgi_dev_mgr_vtbl;
+    dev_mgr->ref = 1;
+    dev_mgr->token = MFGetSystemTime();
+
+    TRACE("Created device manager: %p, token: %u.\n", dev_mgr, dev_mgr->token);
+
+    *token = dev_mgr->token;
+    *manager = &dev_mgr->IMFDXGIDeviceManager_iface;
+
+    return S_OK;
+}
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
index 2f16bbd197..cc440c5ee0 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 b4ba6b6c57..312f8b3bb2 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,78 @@ if (0)
     ok(!refcount, "Unexpected refcount %u.\n", refcount);
 }
 
+struct dev_mgr_ret
+{
+    IMFDXGIDeviceManager *dev_mgr;
+    UINT token;
+};
+
+static DWORD WINAPI create_dxgi_dev_mgr(LPVOID lParam)
+{
+    struct dev_mgr_ret *ret = lParam;
+    HRESULT hr;
+
+    hr = pMFCreateDXGIDeviceManager(&ret->token, &ret->dev_mgr);
+    ok(hr == S_OK, "MFCreateDXGIDeviceManager failed: %#x.\n", hr);
+    ok(!!ret->token, "got wrong token: %u.\n", ret->token);
+    EXPECT_REF(ret->dev_mgr, 1);
+
+    return 0;
+}
+
+static void test_create_dxgi_device_manager(void)
+{
+    IMFDXGIDeviceManager *manager, *manager2;
+    struct dev_mgr_ret ret1, ret2;
+    HANDLE thread1, thread2;
+    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);
+
+    memset(&ret1, 0, sizeof(ret1));
+    thread1 = CreateThread(NULL, 0, create_dxgi_dev_mgr, &ret1, 0, NULL);
+    ok(WaitForSingleObject(thread1, 1000) == WAIT_OBJECT_0, "wait failed.\n");
+    Sleep(50);
+    memset(&ret2, 0, sizeof(ret2));
+    thread2 = CreateThread(NULL, 0, create_dxgi_dev_mgr, &ret2, 0, NULL);
+    ok(WaitForSingleObject(thread2, 1000) == WAIT_OBJECT_0, "wait failed.\n");
+    ok(ret1.dev_mgr != ret2.dev_mgr, "got wrong pointer: %p, %p.\n", ret1.dev_mgr, ret2.dev_mgr);
+    ok(ret1.token != ret2.token, "got wrong token: %u, %u.\n", ret1.token, ret2.token);
+
+    IMFDXGIDeviceManager_Release(ret1.dev_mgr);
+    IMFDXGIDeviceManager_Release(ret2.dev_mgr);
+}
+
 START_TEST(mfplat)
 {
     CoInitialize(NULL);
@@ -3741,6 +3815,7 @@ START_TEST(mfplat)
     test_async_create_file();
     test_local_handlers();
     test_create_property_store();
+    test_create_dxgi_device_manager();
 
     CoUninitialize();
 }
diff --git a/include/mfapi.h b/include/mfapi.h
index 957fb0df9f..f84c051792 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 0cc8f422da..203acc770f 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);
+}
-- 
2.23.0.rc1





More information about the wine-devel mailing list