[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