[PATCH 2/5] dxva2: Add video processor stub.

Nikolay Sivov nsivov at codeweavers.com
Mon Oct 19 09:10:40 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/dxva2/main.c        | 139 ++++++++++++++++++++++++++++++++++++++-
 dlls/dxva2/tests/dxva2.c | 108 ++++++++++++++++++++++++++++--
 2 files changed, 241 insertions(+), 6 deletions(-)

diff --git a/dlls/dxva2/main.c b/dlls/dxva2/main.c
index 53e266d028f..af6ad25697b 100644
--- a/dlls/dxva2/main.c
+++ b/dlls/dxva2/main.c
@@ -65,6 +65,14 @@ struct device_manager
     CONDITION_VARIABLE lock;
 };
 
+struct video_processor
+{
+    IDirectXVideoProcessor IDirectXVideoProcessor_iface;
+    LONG refcount;
+
+    IDirectXVideoProcessorService *service;
+};
+
 static BOOL dxva_array_reserve(void **elements, size_t *capacity, size_t count, size_t size)
 {
     size_t new_capacity, max_capacity;
@@ -102,6 +110,121 @@ static struct device_manager *impl_from_IDirectXVideoProcessorService(IDirectXVi
     return CONTAINING_RECORD(iface, struct device_manager, IDirectXVideoProcessorService_iface);
 }
 
+static struct video_processor *impl_from_IDirectXVideoProcessor(IDirectXVideoProcessor *iface)
+{
+    return CONTAINING_RECORD(iface, struct video_processor, IDirectXVideoProcessor_iface);
+}
+
+static HRESULT WINAPI video_processor_QueryInterface(IDirectXVideoProcessor *iface, REFIID riid, void **obj)
+{
+    if (IsEqualIID(riid, &IID_IDirectXVideoProcessor) ||
+            IsEqualIID(riid, &IID_IUnknown))
+    {
+        *obj = iface;
+        IDirectXVideoProcessor_AddRef(iface);
+        return S_OK;
+    }
+
+    WARN("Unsupported interface %s.\n", debugstr_guid(riid));
+    *obj = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI video_processor_AddRef(IDirectXVideoProcessor *iface)
+{
+    struct video_processor *processor = impl_from_IDirectXVideoProcessor(iface);
+    ULONG refcount = InterlockedIncrement(&processor->refcount);
+
+    TRACE("%p, refcount %u.\n", iface, refcount);
+
+    return refcount;
+}
+
+static ULONG WINAPI video_processor_Release(IDirectXVideoProcessor *iface)
+{
+    struct video_processor *processor = impl_from_IDirectXVideoProcessor(iface);
+    ULONG refcount = InterlockedDecrement(&processor->refcount);
+
+    TRACE("%p, refcount %u.\n", iface, refcount);
+
+    if (!refcount)
+    {
+        IDirectXVideoProcessorService_Release(processor->service);
+        heap_free(processor);
+    }
+
+    return refcount;
+}
+
+static HRESULT WINAPI video_processor_GetVideoProcessorService(IDirectXVideoProcessor *iface,
+        IDirectXVideoProcessorService **service)
+{
+    struct video_processor *processor = impl_from_IDirectXVideoProcessor(iface);
+
+    TRACE("%p, %p.\n", iface, service);
+
+    *service = processor->service;
+    IDirectXVideoProcessorService_AddRef(*service);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI video_processor_GetCreationParameters(IDirectXVideoProcessor *iface,
+        GUID *device, DXVA2_VideoDesc *video_desc, D3DFORMAT *rt_format, UINT *maxstreams)
+{
+    FIXME("%p, %p, %p, %p, %p.\n", iface, device, video_desc, rt_format, maxstreams);
+
+    if (!device && !video_desc && !rt_format && !maxstreams)
+        return E_INVALIDARG;
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI video_processor_GetVideoProcessorCaps(IDirectXVideoProcessor *iface,
+        DXVA2_VideoProcessorCaps *caps)
+{
+    FIXME("%p, %p.\n", iface, caps);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI video_processor_GetProcAmpRange(IDirectXVideoProcessor *iface, UINT cap, DXVA2_ValueRange *range)
+{
+    FIXME("%p, %u, %p.\n", iface, cap, range);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI video_processor_GetFilterPropertyRange(IDirectXVideoProcessor *iface, UINT setting,
+        DXVA2_ValueRange *range)
+{
+    FIXME("%p, %u, %p.\n", iface, setting, range);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI video_processor_VideoProcessBlt(IDirectXVideoProcessor *iface, IDirect3DSurface9 *rt,
+        const DXVA2_VideoProcessBltParams *params, const DXVA2_VideoSample *samples, UINT sample_count,
+        HANDLE *complete_handle)
+{
+    FIXME("%p, %p, %p, %p, %u, %p.\n", iface, rt, params, samples, sample_count, complete_handle);
+
+    return E_NOTIMPL;
+}
+
+static const IDirectXVideoProcessorVtbl video_processor_vtbl =
+{
+    video_processor_QueryInterface,
+    video_processor_AddRef,
+    video_processor_Release,
+    video_processor_GetVideoProcessorService,
+    video_processor_GetCreationParameters,
+    video_processor_GetVideoProcessorCaps,
+    video_processor_GetProcAmpRange,
+    video_processor_GetFilterPropertyRange,
+    video_processor_VideoProcessBlt,
+};
+
 static HRESULT WINAPI device_manager_processor_service_QueryInterface(IDirectXVideoProcessorService *iface,
         REFIID riid, void **obj)
 {
@@ -256,10 +379,24 @@ static HRESULT WINAPI device_manager_processor_service_CreateVideoProcessor(IDir
         REFGUID deviceguid, const DXVA2_VideoDesc *video_desc, D3DFORMAT rt_format, UINT max_substreams,
         IDirectXVideoProcessor **processor)
 {
+    struct video_processor *object;
+
     FIXME("%p, %s, %p, %d, %u, %p.\n", iface, debugstr_guid(deviceguid), video_desc, rt_format, max_substreams,
             processor);
 
-    return E_NOTIMPL;
+    /* FIXME: validate render target format */
+
+    if (!(object = heap_alloc_zero(sizeof(*object))))
+        return E_OUTOFMEMORY;
+
+    object->IDirectXVideoProcessor_iface.lpVtbl = &video_processor_vtbl;
+    object->refcount = 1;
+    object->service = iface;
+    IDirectXVideoProcessorService_AddRef(object->service);
+
+    *processor = &object->IDirectXVideoProcessor_iface;
+
+    return S_OK;
 }
 
 static const IDirectXVideoProcessorServiceVtbl device_manager_processor_service_vtbl =
diff --git a/dlls/dxva2/tests/dxva2.c b/dlls/dxva2/tests/dxva2.c
index 9dcd3e5bf4e..84ccd3b0190 100644
--- a/dlls/dxva2/tests/dxva2.c
+++ b/dlls/dxva2/tests/dxva2.c
@@ -23,10 +23,11 @@
 #include "initguid.h"
 #include "dxva2api.h"
 
-static int get_refcount(IUnknown *object)
+static unsigned int get_refcount(void *object)
 {
-    IUnknown_AddRef(object);
-    return IUnknown_Release(object);
+    IUnknown *iface = object;
+    IUnknown_AddRef(iface);
+    return IUnknown_Release(iface);
 }
 
 static HWND create_window(void)
@@ -120,13 +121,13 @@ static void test_device_manager(void)
 
     hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
-    refcount = get_refcount((IUnknown *)device);
+    refcount = get_refcount(device);
 
     handle1 = NULL;
     hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle1);
     ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
 
-    refcount2 = get_refcount((IUnknown *)device);
+    refcount2 = get_refcount(device);
     ok(refcount2 == refcount, "Unexpected refcount %d.\n", refcount);
 
     handle = NULL;
@@ -357,7 +358,104 @@ done:
     DestroyWindow(window);
 }
 
+static void test_video_processor(void)
+{
+    IDirectXVideoProcessorService *service, *service2;
+    IDirect3DDevice9 *device;
+    IDirect3DDeviceManager9 *manager;
+    HANDLE handle, handle1;
+    IDirect3D9 *d3d;
+    HWND window;
+    UINT token;
+    HRESULT hr;
+    IDirectXVideoProcessor *processor, *processor2;
+    DXVA2_VideoDesc video_desc;
+    GUID guid;
+    D3DFORMAT format;
+
+    window = create_window();
+    d3d = Direct3DCreate9(D3D_SDK_VERSION);
+    ok(!!d3d, "Failed to create a D3D object.\n");
+    if (!(device = create_device(d3d, window)))
+    {
+        skip("Failed to create a D3D device, skipping tests.\n");
+        goto done;
+    }
+
+    hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    handle = NULL;
+    hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    handle1 = NULL;
+    hr = IDirect3DDeviceManager9_OpenDeviceHandle(manager, &handle1);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    ok(get_refcount(manager) == 1, "Unexpected refcount %u.\n", get_refcount(manager));
+
+    hr = IDirect3DDeviceManager9_GetVideoService(manager, handle, &IID_IDirectXVideoProcessorService,
+            (void **)&service);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    memset(&video_desc, 0, sizeof(video_desc));
+    video_desc.SampleWidth = 64;
+    video_desc.SampleHeight = 64;
+    video_desc.Format = D3DFMT_A8R8G8B8;
+
+    hr = IDirectXVideoProcessorService_CreateVideoProcessor(service, &DXVA2_VideoProcSoftwareDevice, &video_desc,
+            D3DFMT_A8R8G8B8, 1, &processor);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IDirectXVideoProcessorService_CreateVideoProcessor(service, &DXVA2_VideoProcSoftwareDevice, &video_desc,
+            D3DFMT_A8R8G8B8, 1, &processor2);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(processor2 != processor, "Unexpected instance.\n");
+
+    hr = IDirectXVideoProcessor_GetCreationParameters(processor, NULL, NULL, NULL, NULL);
+    ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+
+    hr = IDirectXVideoProcessor_GetCreationParameters(processor, &guid, NULL, NULL, NULL);
+todo_wine {
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(IsEqualGUID(&guid, &DXVA2_VideoProcSoftwareDevice), "Unexpected device guid.\n");
+}
+    hr = IDirectXVideoProcessor_GetCreationParameters(processor, NULL, NULL, &format, NULL);
+todo_wine {
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(format == D3DFMT_A8R8G8B8, "Unexpected format %u.\n", format);
+}
+    IDirectXVideoProcessor_Release(processor);
+    IDirectXVideoProcessor_Release(processor2);
+
+    hr = IDirect3DDeviceManager9_GetVideoService(manager, handle, &IID_IDirectXVideoProcessorService,
+            (void **)&service2);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+    ok(service == service2, "Unexpected pointer.\n");
+
+    IDirectXVideoProcessorService_Release(service2);
+    IDirectXVideoProcessorService_Release(service);
+
+    hr = IDirect3DDeviceManager9_CloseDeviceHandle(manager, handle);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    hr = IDirect3DDeviceManager9_CloseDeviceHandle(manager, handle1);
+    ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+    IDirect3DDevice9_Release(device);
+    IDirect3DDeviceManager9_Release(manager);
+
+done:
+    IDirect3D9_Release(d3d);
+    DestroyWindow(window);
+}
+
 START_TEST(dxva2)
 {
     test_device_manager();
+    test_video_processor();
 }
-- 
2.28.0




More information about the wine-devel mailing list