Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/dxva2/dxvahd.c | 263 ++++++++++++++++++++++++++++++++++- dlls/dxva2/tests/Makefile.in | 3 +- dlls/dxva2/tests/dxvahd.c | 210 ++++++++++++++++++++++++++++ include/dxvahd.idl | 162 +++++++++++++++++++++ 4 files changed, 634 insertions(+), 4 deletions(-) create mode 100644 dlls/dxva2/tests/dxvahd.c
diff --git a/dlls/dxva2/dxvahd.c b/dlls/dxva2/dxvahd.c index ac67f9e5a7..2feb7eb323 100644 --- a/dlls/dxva2/dxvahd.c +++ b/dlls/dxva2/dxvahd.c @@ -16,18 +16,99 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#define COBJMACROS + #include "d3d9.h" +#include "initguid.h" #include "dxvahd.h"
#include "wine/debug.h" +#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(dxva2);
+#define MAX_INPUT_STREAMS 1 +#define MAX_STREAM_STATES 1 + +static const D3DFORMAT output_formats[] = { + D3DFMT_X8R8G8B8 +}; + +static const D3DFORMAT input_formats[] = { + MAKEFOURCC('N','V','1','2') +}; + +static const DXVAHD_VPCAPS video_processors[] = { + {{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, 0, 0, 0, 0, 0} +}; + +static const DXVAHD_VPDEVCAPS dev_caps = { + DXVAHD_DEVICE_TYPE_HARDWARE, + 0, /* DeviceCaps */ + 0, /* FeatureCaps */ + 0, /* FilterCaps */ + 0, /* InputFormatCaps */ + D3DPOOL_DEFAULT, + ARRAY_SIZE(output_formats), + ARRAY_SIZE(input_formats), + ARRAY_SIZE(video_processors), + MAX_INPUT_STREAMS, + MAX_STREAM_STATES +}; + + +struct dxvahd_device +{ + IDXVAHD_Device IDXVAHD_Device_iface; + LONG refcount; + IDirect3DDevice9Ex *d3d_device; +}; + + /******************************************** * Utility functions */
+static struct dxvahd_device *impl_from_IDXVAHD_Device(IDXVAHD_Device *iface) +{ + return CONTAINING_RECORD(iface, struct dxvahd_device, IDXVAHD_Device_iface); +} + +static const char *debug_dxvahd_surface_type(DXVAHD_SURFACE_TYPE surface_type) +{ + switch (surface_type) + { +#define SURFACE_TYPE_TO_STR(e) case e: return #e + SURFACE_TYPE_TO_STR(DXVAHD_SURFACE_TYPE_VIDEO_INPUT); + SURFACE_TYPE_TO_STR(DXVAHD_SURFACE_TYPE_VIDEO_INPUT_PRIVATE); + SURFACE_TYPE_TO_STR(DXVAHD_SURFACE_TYPE_VIDEO_OUTPUT); +#undef SURFACE_TYPE_TO_STR + default: + FIXME("Unrecognized surface type %#x.\n", surface_type); + return "unrecognized"; + } +} + +static const char *debug_dxvahd_filter(DXVAHD_FILTER filter) +{ + switch (filter) + { +#define FILTER_TO_STR(e) case e: return #e + FILTER_TO_STR(DXVAHD_FILTER_BRIGHTNESS); + FILTER_TO_STR(DXVAHD_FILTER_CONTRAST); + FILTER_TO_STR(DXVAHD_FILTER_HUE); + FILTER_TO_STR(DXVAHD_FILTER_SATURATION); + FILTER_TO_STR(DXVAHD_FILTER_NOISE_REDUCTION); + FILTER_TO_STR(DXVAHD_FILTER_EDGE_ENHANCEMENT); + FILTER_TO_STR(DXVAHD_FILTER_ANAMORPHIC_SCALING); +#undef FILTER_TO_STR + default: + FIXME("Unrecognized surface type %#x.\n", filter); + return "unrecognized"; + } +} + static const char *debug_dxvahd_device_usage(DXVAHD_DEVICE_USAGE usage) { switch (usage) @@ -44,6 +125,173 @@ static const char *debug_dxvahd_device_usage(DXVAHD_DEVICE_USAGE usage) }
+/******************************************** + * IDXVAHD_Device functions + */ + +static HRESULT WINAPI dxvahd_device_QueryInterface(IDXVAHD_Device *iface, REFIID riid, void **obj) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + WARN("Unsupported interface %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI dxvahd_device_AddRef(IDXVAHD_Device *iface) +{ + struct dxvahd_device *dev = impl_from_IDXVAHD_Device(iface); + ULONG refcount = InterlockedIncrement(&dev->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI dxvahd_device_Release(IDXVAHD_Device *iface) +{ + struct dxvahd_device *dev = impl_from_IDXVAHD_Device(iface); + ULONG refcount = InterlockedDecrement(&dev->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + heap_free(dev); + } + + return refcount; +} + +static HRESULT WINAPI dxvahd_device_CreateVideoSurface(IDXVAHD_Device *iface, UINT width, UINT height, + D3DFORMAT format, D3DPOOL pool, DWORD usage, DXVAHD_SURFACE_TYPE type, UINT num_surfaces, + IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle) +{ + struct dxvahd_device *dev = impl_from_IDXVAHD_Device(iface); + UINT i; + + FIXME("%p, %u, %u, %#x, %#x, %#x, %s, %u, %p, %p.\n", iface, width, height, format, pool, usage, + debug_dxvahd_surface_type(type), num_surfaces, ppSurface, pSharedHandle); + + if (pool != dev_caps.InputPool || num_surfaces < 1) + return E_INVALIDARG; + + /* FIXME: Return error result (D3DERR_INVALIDCALL or E_INVALIDARG) on invalid format. + * The formats returned by GetVideoProcessor[Input|Output]Formats functions + * may not comprise the entire set of valid formats. */ + + for (i = 0; i < num_surfaces; i++) + { + /* TODO: Determine if CreateOffscreenPlainSurface is sufficient to the task, + * or if a separate implementation of IDirect3DSurface9 is warranted. */ + IDirect3DDevice9Ex_CreateOffscreenPlainSurface(dev->d3d_device, width, height, format, pool, + ppSurface + i, pSharedHandle); + TRACE("Created surface %d: %p.\n", i, ppSurface[i]); + } + + return S_OK; +} + +static HRESULT WINAPI dxvahd_device_GetVideoProcessorDeviceCaps(IDXVAHD_Device *iface, + DXVAHD_VPDEVCAPS *pCaps) +{ + FIXME("%p, %p.\n", iface, pCaps); + + /* TODO: use driver D3DDDICAPS_DXVAHD_GETVPDEVCAPS */ + + memcpy(pCaps, &dev_caps, sizeof(dev_caps)); + + return S_OK; +} + +static HRESULT WINAPI dxvahd_device_GetVideoProcessorOutputFormats(IDXVAHD_Device *iface, UINT count, + D3DFORMAT *pFormats) +{ + FIXME("%p, %u, %p.\n", iface, count, pFormats); + + /* TODO: use driver D3DDDICAPS_DXVAHD_GETVPOUTPUTFORMATS */ + + if (count != dev_caps.OutputFormatCount) + return E_INVALIDARG; + memcpy(pFormats, output_formats, sizeof(output_formats)); + + return S_OK; +} + +static HRESULT WINAPI dxvahd_device_GetVideoProcessorInputFormats(IDXVAHD_Device *iface, UINT count, + D3DFORMAT *pFormats) +{ + FIXME("%p, %u, %p.\n", iface, count, pFormats); + + /* TODO: use driver D3DDDICAPS_DXVAHD_GETVPINPUTFORMATS */ + + if (count != dev_caps.InputFormatCount) + return E_INVALIDARG; + memcpy(pFormats, input_formats, sizeof(input_formats)); + + return S_OK; +} + +static HRESULT WINAPI dxvahd_device_GetVideoProcessorCaps(IDXVAHD_Device *iface, UINT count, + DXVAHD_VPCAPS *pCaps) +{ + FIXME("%p, %u, %p.\n", iface, count, pCaps); + + /* TODO: use driver D3DDDICAPS_DXVAHD_GETVPCAPS */ + + if (count != dev_caps.VideoProcessorCount) + return E_INVALIDARG; + memcpy(pCaps, video_processors, sizeof(video_processors)); + + return S_OK; +} + +static HRESULT WINAPI dxvahd_device_GetVideoProcessorCustomRates(IDXVAHD_Device *iface, + const GUID *pVPGuid, UINT count, DXVAHD_CUSTOM_RATE_DATA *pRates) +{ + FIXME("%p, %s, %u, %p.\n", iface, debugstr_guid(pVPGuid), count, pRates); + + /* TODO: use driver D3DDDICAPS_DXVAHD_GETVPCUSTOMRATES */ + + return (!!count) ? E_INVALIDARG : S_OK; +} + +static HRESULT WINAPI dxvahd_device_GetVideoProcessorFilterRange(IDXVAHD_Device *iface, + DXVAHD_FILTER filter, DXVAHD_FILTER_RANGE_DATA *pRange) +{ + FIXME("%p, %s, %p.\n", iface, debug_dxvahd_filter(filter), pRange); + + /* TODO: use driver D3DDDICAPS_DXVAHD_GETVPFILTERRANGE */ + + return E_INVALIDARG; +} + +static HRESULT WINAPI dxvahd_device_CreateVideoProcessor(IDXVAHD_Device *iface, const GUID *pVPGuid, + IDXVAHD_VideoProcessor **ppVideoProcessor) +{ + FIXME("%p, %s, %p. stub.\n", iface, debugstr_guid(pVPGuid), ppVideoProcessor); + + *ppVideoProcessor = NULL; + + return E_NOINTERFACE; +} + +static const IDXVAHD_DeviceVtbl dxvahd_device_vtbl = +{ + dxvahd_device_QueryInterface, + dxvahd_device_AddRef, + dxvahd_device_Release, + dxvahd_device_CreateVideoSurface, + dxvahd_device_GetVideoProcessorDeviceCaps, + dxvahd_device_GetVideoProcessorOutputFormats, + dxvahd_device_GetVideoProcessorInputFormats, + dxvahd_device_GetVideoProcessorCaps, + dxvahd_device_GetVideoProcessorCustomRates, + dxvahd_device_GetVideoProcessorFilterRange, + dxvahd_device_CreateVideoProcessor, +}; + + /******************************************** * DXVA-HD device creation function */ @@ -51,7 +299,9 @@ static const char *debug_dxvahd_device_usage(DXVAHD_DEVICE_USAGE usage) HRESULT WINAPI DXVAHD_CreateDevice(IDirect3DDevice9Ex *d3d_device, const DXVAHD_CONTENT_DESC *desc, DXVAHD_DEVICE_USAGE usage, PDXVAHDSW_Plugin plugin, IDXVAHD_Device **device) { - FIXME("%p, %p, %s, %p, %p. stub.\n", d3d_device, desc, debug_dxvahd_device_usage(usage), plugin, device); + struct dxvahd_device *object; + + TRACE("%p, %p, %s, %p, %p.\n", d3d_device, desc, debug_dxvahd_device_usage(usage), plugin, device);
TRACE("Frame Format %d Input %ux%u @%.2f Output %ux%u @%.2f\n", desc->InputFrameFormat, desc->InputWidth, desc->InputHeight, @@ -59,7 +309,14 @@ HRESULT WINAPI DXVAHD_CreateDevice(IDirect3DDevice9Ex *d3d_device, const DXVAHD_ desc->OutputWidth, desc->OutputHeight, (double)desc->OutputFrameRate.Numerator / desc->OutputFrameRate.Denominator);
- *device = NULL; + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY;
- return E_NOINTERFACE; + object->IDXVAHD_Device_iface.lpVtbl = &dxvahd_device_vtbl; + object->refcount = 1; + object->d3d_device = d3d_device; + + *device = &object->IDXVAHD_Device_iface; + + return S_OK; } diff --git a/dlls/dxva2/tests/Makefile.in b/dlls/dxva2/tests/Makefile.in index c86c5ab42f..b5d70cd94f 100644 --- a/dlls/dxva2/tests/Makefile.in +++ b/dlls/dxva2/tests/Makefile.in @@ -2,4 +2,5 @@ TESTDLL = dxva2.dll IMPORTS = dxva2 user32 d3d9
C_SRCS = \ - dxva2.c + dxva2.c \ + dxvahd.c diff --git a/dlls/dxva2/tests/dxvahd.c b/dlls/dxva2/tests/dxvahd.c new file mode 100644 index 0000000000..b99dc15796 --- /dev/null +++ b/dlls/dxva2/tests/dxvahd.c @@ -0,0 +1,210 @@ +/* + * Copyright 2020 Jeff Smith + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS +#include "initguid.h" +#include "d3d9.h" +#include "dxvahd.h" + +#include "wine/test.h" +#include "wine/heap.h" + +IDirect3DDevice9Ex *d3d_device; + +static HWND create_window(void) +{ + RECT r = {0, 0, 640, 480}; + + AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); + + return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL); +} + +static IDirect3DDevice9Ex *create_device(IDirect3D9Ex *d3d9, HWND focus_window) +{ + D3DPRESENT_PARAMETERS present_parameters = {0}; + IDirect3DDevice9Ex *device = NULL; + + present_parameters.BackBufferWidth = 640; + present_parameters.BackBufferHeight = 480; + present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.hDeviceWindow = focus_window; + present_parameters.Windowed = TRUE; + present_parameters.EnableAutoDepthStencil = TRUE; + present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8; + + IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window, + D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, NULL, &device); + + return device; +} + +static void init_desc(DXVAHD_CONTENT_DESC *desc) +{ + desc->InputFrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE; + desc->InputFrameRate.Numerator = 30; + desc->InputFrameRate.Denominator = 1; + desc->InputWidth = 640; + desc->InputHeight = 480; + desc->OutputFrameRate.Numerator = 30; + desc->OutputFrameRate.Denominator = 1; + desc->OutputWidth = 640; + desc->OutputHeight = 480; +} + +static void test_dxvahd_device(void) +{ + IDXVAHD_Device *device, *device2; + IDirect3DSurface9 *surfaces[2]; + HRESULT hr; + DXVAHD_CONTENT_DESC desc = {0}; + DXVAHD_VPDEVCAPS caps = {0}; + D3DFORMAT *input_formats; + D3DFORMAT *output_formats; + DXVAHD_VPCAPS *vp_caps; + int i; + + init_desc(&desc); + hr = DXVAHD_CreateDevice(d3d_device, &desc, DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, NULL, &device); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!!device, "Failed to create DXVA-HD device.\n"); + + hr = IDXVAHD_Device_QueryInterface(device, &IID_IDXVAHD_Device, (void **)&device2); + ok(hr == E_NOINTERFACE, "IDXVAHD_Device::QueryInterface for IID_IDXVAHD_Device returned %08x, expected E_NOINTERFACE\n", hr); + ok(device2 == NULL, "QueryInterface returned interface %p, expected NULL\n", device2); + + hr = IDXVAHD_Device_QueryInterface(device, &IID_IUnknown, (void **)&device2); + ok(hr == E_NOINTERFACE, "IDXVAHD_Device::QueryInterface for IID_IUnknown returned %08x, expected E_NOINTERFACE\n", hr); + ok(device2 == NULL, "QueryInterface returned interface %p, expected NULL\n", device2); + + + hr = IDXVAHD_Device_GetVideoProcessorDeviceCaps(device, &caps); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + output_formats = heap_alloc_zero(caps.OutputFormatCount * sizeof(*output_formats)); + hr = IDXVAHD_Device_GetVideoProcessorOutputFormats(device, caps.OutputFormatCount, output_formats); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IDXVAHD_Device_GetVideoProcessorOutputFormats(device, caps.OutputFormatCount + 1, output_formats); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + if (caps.OutputFormatCount >= 1) + { + hr = IDXVAHD_Device_GetVideoProcessorOutputFormats(device, caps.OutputFormatCount - 1, output_formats); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + } + + input_formats = heap_alloc_zero(caps.InputFormatCount * sizeof(*input_formats)); + hr = IDXVAHD_Device_GetVideoProcessorInputFormats(device, caps.InputFormatCount, input_formats); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IDXVAHD_Device_GetVideoProcessorInputFormats(device, caps.InputFormatCount + 1, input_formats); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + if (caps.InputFormatCount >= 1) + { + hr = IDXVAHD_Device_GetVideoProcessorInputFormats(device, caps.InputFormatCount - 1, input_formats); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + } + + vp_caps = heap_alloc_zero(caps.VideoProcessorCount * sizeof(*vp_caps)); + hr = IDXVAHD_Device_GetVideoProcessorCaps(device, caps.VideoProcessorCount, vp_caps); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IDXVAHD_Device_GetVideoProcessorCaps(device, caps.VideoProcessorCount + 1, vp_caps); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + if (caps.VideoProcessorCount >= 1) + { + hr = IDXVAHD_Device_GetVideoProcessorCaps(device, caps.VideoProcessorCount - 1, vp_caps); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + } + + + /* CreateVideoSurface: Try each input format */ + for (i = 0; i < caps.InputFormatCount; i++) + { + hr = IDXVAHD_Device_CreateVideoSurface(device, 2, 2, input_formats[i], caps.InputPool, 0, + DXVAHD_SURFACE_TYPE_VIDEO_INPUT, 1, surfaces, NULL); + ok(hr == S_OK, "Unexpected hr %#x for input format %#x.\n", hr, input_formats[i]); + IDirect3DSurface9_Release(surfaces[0]); + } + + /* NOTE: some video surface formats besides those returned by + * GetVideoProcessor[Input|Output]Formats may be allowed by CreateVideoSurface. */ + + /* CreateVideoSurface: Invalid input format */ + hr = IDXVAHD_Device_CreateVideoSurface(device, 2, 2, 0xdeadbeef, caps.InputPool, 0, + DXVAHD_SURFACE_TYPE_VIDEO_INPUT, 1, surfaces, NULL); + todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x for input format %#x.\n", hr, 0xdeadbeef); + + if (caps.InputFormatCount >= 1) + { + /* CreateVideoSurface: Request 0 surfaces */ + hr = IDXVAHD_Device_CreateVideoSurface(device, 2, 2, input_formats[0], caps.InputPool, 0, + DXVAHD_SURFACE_TYPE_VIDEO_INPUT, 0, surfaces, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + /* CreateVideoSurface: Wrong pool */ + hr = IDXVAHD_Device_CreateVideoSurface(device, 2, 2, input_formats[0], caps.InputPool + 1, 0, + DXVAHD_SURFACE_TYPE_VIDEO_INPUT, 1, surfaces, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + } + + + heap_free(output_formats); + heap_free(input_formats); + heap_free(vp_caps); + IDXVAHD_Device_Release(device); +} + +START_TEST(dxvahd) +{ + IDXVAHD_Device *device = NULL; + IDirect3D9Ex *d3d; + HWND window; + HRESULT hr; + DXVAHD_CONTENT_DESC desc = {0}; + + hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d); + if (hr != S_OK) + { + skip("Failed to create a D3D object, skipping tests.\n"); + return; + } + + window = create_window(); + + if (!(d3d_device = create_device(d3d, window))) + { + skip("Failed to create a D3D device, skipping tests.\n"); + IDirect3D9_Release(d3d); + DestroyWindow(window); + } + + init_desc(&desc); + hr = DXVAHD_CreateDevice(d3d_device, &desc, DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, NULL, &device); + if (hr == E_NOINTERFACE) + { + skip("Device does not support DXVA-HD, skipping tests.\n"); + goto done; + } + IDXVAHD_Device_Release(device); + + test_dxvahd_device(); + +done: + IDirect3DDevice9_Release(d3d_device); + IDirect3D9_Release(d3d); + DestroyWindow(window); +} diff --git a/include/dxvahd.idl b/include/dxvahd.idl index cd6de6eab3..76913c0547 100644 --- a/include/dxvahd.idl +++ b/include/dxvahd.idl @@ -20,6 +20,10 @@ import "unknwn.idl";
cpp_quote("#if 0") interface IDirect3DDevice9Ex; +interface IDirect3DSurface9; + +typedef DWORD D3DFORMAT; +typedef DWORD D3DPOOL; cpp_quote("#endif")
@@ -37,6 +41,73 @@ typedef enum _DXVAHD_DEVICE_USAGE DXVAHD_DEVICE_USAGE_OPTIMAL_QUALITY = 2 } DXVAHD_DEVICE_USAGE;
+typedef enum _DXVAHD_FILTER +{ + DXVAHD_FILTER_BRIGHTNESS = 0, + DXVAHD_FILTER_CONTRAST = 1, + DXVAHD_FILTER_HUE = 2, + DXVAHD_FILTER_SATURATION = 3, + DXVAHD_FILTER_NOISE_REDUCTION = 4, + DXVAHD_FILTER_EDGE_ENHANCEMENT = 5, + DXVAHD_FILTER_ANAMORPHIC_SCALING = 6 +} DXVAHD_FILTER; + +typedef enum _DXVAHD_SURFACE_TYPE +{ + DXVAHD_SURFACE_TYPE_VIDEO_INPUT = 0, + DXVAHD_SURFACE_TYPE_VIDEO_INPUT_PRIVATE = 1, + DXVAHD_SURFACE_TYPE_VIDEO_OUTPUT = 2 +} DXVAHD_SURFACE_TYPE; + +typedef enum _DXVAHD_DEVICE_TYPE +{ + DXVAHD_DEVICE_TYPE_HARDWARE = 0, + DXVAHD_DEVICE_TYPE_SOFTWARE = 1, + DXVAHD_DEVICE_TYPE_REFERENCE = 2, + DXVAHD_DEVICE_TYPE_OTHER = 3 +} DXVAHD_DEVICE_TYPE; + +typedef enum _DXVAHD_DEVICE_CAPS +{ + DXVAHD_DEVICE_CAPS_LINEAR_SPACE = 0x01, + DXVAHD_DEVICE_CAPS_xvYCC = 0x02, + DXVAHD_DEVICE_CAPS_RGB_RANGE_CONVERSION = 0x04, + DXVAHD_DEVICE_CAPS_YCbCr_MATRIX_CONVERSION = 0x08 + /* Based on DDI, Windows 8.1+ should also support: + * ..._NOMINAL_RANGE = 0x10 + */ +} DXVAHD_DEVICE_CAPS; + +typedef enum _DXVAHD_FEATURE_CAPS +{ + DXVAHD_FEATURE_CAPS_ALPHA_FILL = 0x01, + DXVAHD_FEATURE_CAPS_CONSTRICTION = 0x02, + DXVAHD_FEATURE_CAPS_LUMA_KEY = 0x04, + DXVAHD_FEATURE_CAPS_ALPHA_PALETTE = 0x08 + /* Based on DDI, Windows 8+ should also support: + * ..._ROTATION = 0x10 + */ +} DXVAHD_FEATURE_CAPS; + +typedef enum _DXVAHD_FILTER_CAPS +{ + DXVAHD_FILTER_CAPS_BRIGHTNESS = 0x01, + DXVAHD_FILTER_CAPS_CONTRAST = 0x02, + DXVAHD_FILTER_CAPS_HUE = 0x04, + DXVAHD_FILTER_CAPS_SATURATION = 0x08, + DXVAHD_FILTER_CAPS_NOISE_REDUCTION = 0x10, + DXVAHD_FILTER_CAPS_EDGE_ENHANCEMENT = 0x20, + DXVAHD_FILTER_CAPS_ANAMORPHIC_SCALING = 0x40 +} DXVAHD_FILTER_CAPS; + +typedef enum _DXVAHD_INPUT_FORMAT_CAPS +{ + DXVAHD_INPUT_FORMAT_CAPS_RGB_INTERLACED = 0x01, + DXVAHD_INPUT_FORMAT_CAPS_RGB_PROCAMP = 0x02, + DXVAHD_INPUT_FORMAT_CAPS_RGB_LUMA_KEY = 0x04, + DXVAHD_INPUT_FORMAT_CAPS_PALETTE_INTERLACED = 0x08 +} DXVAHD_INPUT_FORMAT_CAPS; +
typedef struct _DXVAHD_RATIONAL { @@ -55,6 +126,47 @@ typedef struct _DXVAHD_CONTENT_DESC UINT OutputHeight; } DXVAHD_CONTENT_DESC;
+typedef struct _DXVAHD_VPCAPS +{ + GUID VPGuid; + UINT PastFrames; + UINT FutureFrames; + UINT ProcessorCaps; + UINT ITelecineCaps; + UINT CustomRateCount; +} DXVAHD_VPCAPS; + +typedef struct _DXVAHD_CUSTOM_RATE_DATA +{ + DXVAHD_RATIONAL CustomRate; + UINT OutputFrames; + BOOL InputInterlaced; + UINT InputFramesOrFields; +} DXVAHD_CUSTOM_RATE_DATA; + +typedef struct _DXVAHD_FILTER_RANGE_DATA +{ + INT Minimum; + INT Maximum; + INT Default; + FLOAT Multiplier; +} DXVAHD_FILTER_RANGE_DATA; + +typedef struct _DXVAHD_VPDEVCAPS +{ + DXVAHD_DEVICE_TYPE DeviceType; + UINT DeviceCaps; + UINT FeatureCaps; + UINT FilterCaps; + UINT InputFormatCaps; + D3DPOOL InputPool; + UINT OutputFormatCount; + UINT InputFormatCount; + UINT VideoProcessorCount; + UINT MaxInputStreams; + UINT MaxStreamStates; +} DXVAHD_VPDEVCAPS; +
/* FIXME */ typedef void* PDXVAHDSW_Plugin; @@ -63,3 +175,53 @@ typedef void* PDXVAHDSW_Plugin; interface IDXVAHD_Device;
cpp_quote("HRESULT WINAPI DXVAHD_CreateDevice(IDirect3DDevice9Ex *d3d_device, const DXVAHD_CONTENT_DESC *desc, DXVAHD_DEVICE_USAGE usage, PDXVAHDSW_Plugin plugin, IDXVAHD_Device **device);") + +/***************************************************************************** + * IDXVAHD_Device interface + */ +[ + object, + uuid(95f12dfd-d77e-49be-815f-57d579634d6d), + local +] +interface IDXVAHD_Device : IUnknown +{ + HRESULT CreateVideoSurface( + [in] UINT width, + [in] UINT height, + [in] D3DFORMAT format, + [in] D3DPOOL pool, + [in] DWORD usage, + [in] DXVAHD_SURFACE_TYPE type, + [in] UINT num_surfaces, + [out] IDirect3DSurface9 **ppSurface, + [in, out] HANDLE *pSharedHandle); + + HRESULT GetVideoProcessorDeviceCaps( + [out] DXVAHD_VPDEVCAPS *pCaps); + + HRESULT GetVideoProcessorOutputFormats( + [in] UINT count, + [out] D3DFORMAT *pFormats); + + HRESULT GetVideoProcessorInputFormats( + [in] UINT count, + [out] D3DFORMAT *pFormats); + + HRESULT GetVideoProcessorCaps( + [in] UINT count, + [out] DXVAHD_VPCAPS *pCaps); + + HRESULT GetVideoProcessorCustomRates( + [in] const GUID *pVPGuid, + [in] UINT count, + [out] DXVAHD_CUSTOM_RATE_DATA *pRates); + + HRESULT GetVideoProcessorFilterRange( + [in] DXVAHD_FILTER filter, + [out] DXVAHD_FILTER_RANGE_DATA *pRange); + + HRESULT CreateVideoProcessor( + [in] const GUID *pVPGuid, + [out] IDXVAHD_VideoProcessor **ppVideoProcessor); +}