dxva2: Add video processor stub.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-10-19 17:10:40 +03:00 committed by Alexandre Julliard
parent 0a3a2e7dcb
commit 6194f50672
2 changed files with 241 additions and 6 deletions

View File

@ -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 =

View File

@ -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();
}