Signed-off-by: Jeff Smith whydoubt@gmail.com --- dlls/dxva2/Makefile.in | 3 +- dlls/dxva2/dxva2.spec | 1 + dlls/dxva2/dxvahd.c | 465 ++++++++++++++++++++++++++++++++++ dlls/dxva2/tests/Makefile.in | 3 +- dlls/dxva2/tests/dxvahd.c | 293 ++++++++++++++++++++++ include/Makefile.in | 1 + include/dxvahd.idl | 473 +++++++++++++++++++++++++++++++++++ 7 files changed, 1237 insertions(+), 2 deletions(-) create mode 100644 dlls/dxva2/dxvahd.c create mode 100644 dlls/dxva2/tests/dxvahd.c create mode 100644 include/dxvahd.idl
diff --git a/dlls/dxva2/Makefile.in b/dlls/dxva2/Makefile.in index e3fc2fd6c3a..0248c7f20b0 100644 --- a/dlls/dxva2/Makefile.in +++ b/dlls/dxva2/Makefile.in @@ -5,4 +5,5 @@ IMPORTLIB = dxva2 EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ - main.c + main.c \ + dxvahd.c diff --git a/dlls/dxva2/dxva2.spec b/dlls/dxva2/dxva2.spec index 024a972697d..ea7a98718b0 100644 --- a/dlls/dxva2/dxva2.spec +++ b/dlls/dxva2/dxva2.spec @@ -1,6 +1,7 @@ @ stdcall CapabilitiesRequestAndCapabilitiesReply(ptr ptr long) @ stdcall DXVA2CreateDirect3DDeviceManager9(ptr ptr) @ stdcall DXVA2CreateVideoService(ptr ptr ptr) +@ stdcall DXVAHD_CreateDevice(ptr ptr long ptr ptr) @ stdcall DegaussMonitor(ptr) @ stdcall DestroyPhysicalMonitor(ptr) @ stdcall DestroyPhysicalMonitors(long ptr) diff --git a/dlls/dxva2/dxvahd.c b/dlls/dxva2/dxvahd.c new file mode 100644 index 00000000000..7c197b9a2f8 --- /dev/null +++ b/dlls/dxva2/dxvahd.c @@ -0,0 +1,465 @@ +#define COBJMACROS + +#include "d3d9.h" +#include "initguid.h" +#include "dxvahd.h" + +#include "wine/debug.h" +#include "wine/heap.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dxva2); + + +static const D3DFORMAT output_formats[] = { + D3DFMT_R8G8B8 +}; + +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), + 1, /* MaxInputStreams */ + 1 /* MaxStreamStates */ +}; + + +struct dxvahd_device +{ + IDXVAHD_Device IDXVAHD_Device_iface; + LONG refcount; + IDirect3DDevice9Ex *d3d_device; +}; + +struct dxvahd_vp +{ + IDXVAHD_VideoProcessor IDXVAHD_VideoProcessor_iface; + LONG refcount; + GUID guid; +}; + + +/******************************************** + * Utility functions + */ + +static struct dxvahd_device *impl_from_IDXVAHD_Device(IDXVAHD_Device *iface) +{ + return CONTAINING_RECORD(iface, struct dxvahd_device, IDXVAHD_Device_iface); +} + +static struct dxvahd_vp *impl_from_IDXVAHD_VideoProcessor(IDXVAHD_VideoProcessor *iface) +{ + return CONTAINING_RECORD(iface, struct dxvahd_vp, IDXVAHD_VideoProcessor_iface); +} + +static const char *debug_dxvahd_bltstate(DXVAHD_BLT_STATE blt_state) +{ + switch (blt_state) + { +#define STATE_TO_STR(e) case e: return #e + STATE_TO_STR(DXVAHD_BLT_STATE_TARGET_RECT); + STATE_TO_STR(DXVAHD_BLT_STATE_BACKGROUND_COLOR); + STATE_TO_STR(DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE); + STATE_TO_STR(DXVAHD_BLT_STATE_ALPHA_FILL); + STATE_TO_STR(DXVAHD_BLT_STATE_CONSTRICTION); + STATE_TO_STR(DXVAHD_BLT_STATE_PRIVATE); +#undef STATE_TO_STR + default: + FIXME("Unrecognized blt state %#x.\n", blt_state); + return "unrecognized"; + } +} + +static const char *debug_dxvahd_streamstate(DXVAHD_STREAM_STATE stream_state) +{ + switch (stream_state) + { +#define STATE_TO_STR(e) case e: return #e + STATE_TO_STR(DXVAHD_STREAM_STATE_D3DFORMAT); + STATE_TO_STR(DXVAHD_STREAM_STATE_FRAME_FORMAT); + STATE_TO_STR(DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE); + STATE_TO_STR(DXVAHD_STREAM_STATE_OUTPUT_RATE); + STATE_TO_STR(DXVAHD_STREAM_STATE_SOURCE_RECT); + STATE_TO_STR(DXVAHD_STREAM_STATE_DESTINATION_RECT); + STATE_TO_STR(DXVAHD_STREAM_STATE_ALPHA); + STATE_TO_STR(DXVAHD_STREAM_STATE_PALETTE); + STATE_TO_STR(DXVAHD_STREAM_STATE_LUMA_KEY); + STATE_TO_STR(DXVAHD_STREAM_STATE_ASPECT_RATIO); + STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_BRIGHTNESS); + STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_CONTRAST); + STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_HUE); + STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_SATURATION); + STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_NOISE_REDUCTION); + STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_EDGE_ENHANCEMENT); + STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_ANAMORPHIC_SCALING); + STATE_TO_STR(DXVAHD_STREAM_STATE_PRIVATE); +#undef STATE_TO_STR + default: + FIXME("Unrecognized stream state %#x.\n", stream_state); + return "unrecognized"; + } +} + +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) + { +#define USAGE_TO_STR(e) case e: return #e + USAGE_TO_STR(DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL); + USAGE_TO_STR(DXVAHD_DEVICE_USAGE_OPTIMAL_SPEED); + USAGE_TO_STR(DXVAHD_DEVICE_USAGE_OPTIMAL_QUALITY); +#undef USAGE_TO_STR + default: + FIXME("Unrecognized device usage %#x.\n", usage); + return "unrecognized"; + } +} + + +/******************************************** + * IDXVAHD_VideoProcessor functions + */ + +static HRESULT WINAPI dxvahd_vp_QueryInterface(IDXVAHD_VideoProcessor *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_vp_AddRef(IDXVAHD_VideoProcessor *iface) +{ + struct dxvahd_vp *processor = impl_from_IDXVAHD_VideoProcessor(iface); + ULONG refcount = InterlockedIncrement(&processor->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI dxvahd_vp_Release(IDXVAHD_VideoProcessor *iface) +{ + struct dxvahd_vp *processor = impl_from_IDXVAHD_VideoProcessor(iface); + ULONG refcount = InterlockedDecrement(&processor->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + heap_free(processor); + } + + return refcount; +} + +static HRESULT WINAPI dxvahd_vp_SetVideoProcessBltState(IDXVAHD_VideoProcessor *iface, + DXVAHD_BLT_STATE State, UINT DataSize, const void *pData) +{ + FIXME("%p, %s, %u, %p.\n", iface, debug_dxvahd_bltstate(State), DataSize, pData); + return S_OK; +} + +static HRESULT WINAPI dxvahd_vp_GetVideoProcessBltState(IDXVAHD_VideoProcessor *iface, + DXVAHD_BLT_STATE State, UINT DataSize, void *pData) +{ + FIXME("%p, %s, %u, %p.\n", iface, debug_dxvahd_bltstate(State), DataSize, pData); + return S_OK; +} + +static HRESULT WINAPI dxvahd_vp_SetVideoProcessStreamState(IDXVAHD_VideoProcessor *iface, + UINT StreamNumber, DXVAHD_STREAM_STATE State, UINT DataSize, const void *pData) +{ + FIXME("%p, %u, %s, %u, %p.\n", iface, StreamNumber, debug_dxvahd_streamstate(State), DataSize, pData); + return S_OK; +} + +static HRESULT WINAPI dxvahd_vp_GetVideoProcessStreamState(IDXVAHD_VideoProcessor *iface, + UINT StreamNumber, DXVAHD_STREAM_STATE State, UINT DataSize, void *pData) +{ + FIXME("%p, %u, %s, %u, %p.\n", iface, StreamNumber, debug_dxvahd_streamstate(State), DataSize, pData); + return S_OK; +} + +static HRESULT WINAPI dxvahd_vp_VideoProcessBltHD(IDXVAHD_VideoProcessor *iface, + IDirect3DSurface9 *pOutputSurface, UINT OutputFrame, UINT StreamCount, + const DXVAHD_STREAM_DATA *pStreams) +{ + UINT i; + + FIXME("%p, %p, %u, %u, %p.\n", iface, pOutputSurface, OutputFrame, StreamCount, pStreams); + + for (i = 0; i < StreamCount; i++) + { + TRACE("stream[%d]: %d %u %u %u %u %p %p %p\n", i, pStreams[i].Enable, pStreams[i].OutputIndex, + pStreams[i].InputFrameOrField, pStreams[i].PastFrames, pStreams[i].FutureFrames, + pStreams[i].ppPastSurfaces, pStreams[i].pInputSurface, pStreams[i].ppFutureSurfaces); + } + + return S_OK; +} + +static const IDXVAHD_VideoProcessorVtbl dxvahd_vp_vtbl = +{ + dxvahd_vp_QueryInterface, + dxvahd_vp_AddRef, + dxvahd_vp_Release, + dxvahd_vp_SetVideoProcessBltState, + dxvahd_vp_GetVideoProcessBltState, + dxvahd_vp_SetVideoProcessStreamState, + dxvahd_vp_GetVideoProcessStreamState, + dxvahd_vp_VideoProcessBltHD, +}; + + +/******************************************** + * 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) +{ + struct dxvahd_vp *object; + + FIXME("%p, %s, %p.\n", iface, debugstr_guid(pVPGuid), ppVideoProcessor); + + // TODO: use driver function CreateVideoProcessor + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IDXVAHD_VideoProcessor_iface.lpVtbl = &dxvahd_vp_vtbl; + object->refcount = 1; + memcpy(&object->guid, pVPGuid, sizeof(*pVPGuid)); + + *ppVideoProcessor = &object->IDXVAHD_VideoProcessor_iface; + + return S_OK; +} + +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, +}; + + +HRESULT WINAPI DXVAHD_CreateDevice(IDirect3DDevice9Ex *d3d_device, const DXVAHD_CONTENT_DESC *desc, + DXVAHD_DEVICE_USAGE usage, PDXVAHDSW_Plugin plugin, IDXVAHD_Device **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, + (double)desc->InputFrameRate.Numerator / desc->InputFrameRate.Denominator, + desc->OutputWidth, desc->OutputHeight, + (double)desc->OutputFrameRate.Numerator / desc->OutputFrameRate.Denominator); + + if (!(object = heap_alloc_zero(sizeof(*object)))) + return E_OUTOFMEMORY; + + 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 c86c5ab42fc..b5d70cd94f7 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 00000000000..e67350dfdb7 --- /dev/null +++ b/dlls/dxva2/tests/dxvahd.c @@ -0,0 +1,293 @@ +/* + * 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); +} + +static void test_dxvahd_processor(void) +{ + IDXVAHD_Device *device; + DXVAHD_CONTENT_DESC desc = {0}; + DXVAHD_VPDEVCAPS caps = {0}; + D3DFORMAT *input_formats; + DXVAHD_VPCAPS *vp_caps; + IDXVAHD_VideoProcessor *processor; + void *data = heap_alloc_zero(64); + HRESULT hr; + int i; + + static struct { + DXVAHD_BLT_STATE state; + ULONG size; + } test_blt[] = { + {DXVAHD_BLT_STATE_TARGET_RECT, sizeof(DXVAHD_BLT_STATE_TARGET_RECT_DATA)}, + {DXVAHD_BLT_STATE_BACKGROUND_COLOR, sizeof(DXVAHD_BLT_STATE_BACKGROUND_COLOR_DATA)}, + {DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE, sizeof(DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA)}, + {DXVAHD_BLT_STATE_ALPHA_FILL, sizeof(DXVAHD_BLT_STATE_ALPHA_FILL_DATA)}, + {DXVAHD_BLT_STATE_CONSTRICTION, sizeof(DXVAHD_BLT_STATE_CONSTRICTION_DATA)}, + }; + + static struct { + DXVAHD_STREAM_STATE state; + ULONG size; + } test_stream[] = { + {DXVAHD_STREAM_STATE_D3DFORMAT, sizeof(DXVAHD_STREAM_STATE_D3DFORMAT_DATA)}, + {DXVAHD_STREAM_STATE_FRAME_FORMAT, sizeof(DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA)}, + {DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE, sizeof(DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA)}, + {DXVAHD_STREAM_STATE_OUTPUT_RATE, sizeof(DXVAHD_STREAM_STATE_OUTPUT_RATE_DATA)}, + {DXVAHD_STREAM_STATE_SOURCE_RECT, sizeof(DXVAHD_STREAM_STATE_SOURCE_RECT_DATA)}, + {DXVAHD_STREAM_STATE_DESTINATION_RECT, sizeof(DXVAHD_STREAM_STATE_DESTINATION_RECT_DATA)}, + {DXVAHD_STREAM_STATE_ALPHA, sizeof(DXVAHD_STREAM_STATE_ALPHA_DATA)}, + {DXVAHD_STREAM_STATE_PALETTE, sizeof(DXVAHD_STREAM_STATE_PALETTE_DATA)}, + {DXVAHD_STREAM_STATE_LUMA_KEY, sizeof(DXVAHD_STREAM_STATE_LUMA_KEY_DATA)}, + {DXVAHD_STREAM_STATE_ASPECT_RATIO, sizeof(DXVAHD_STREAM_STATE_ASPECT_RATIO_DATA)}, + {DXVAHD_STREAM_STATE_FILTER_BRIGHTNESS, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)}, + {DXVAHD_STREAM_STATE_FILTER_CONTRAST, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)}, + {DXVAHD_STREAM_STATE_FILTER_HUE, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)}, + {DXVAHD_STREAM_STATE_FILTER_SATURATION, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)}, + {DXVAHD_STREAM_STATE_FILTER_NOISE_REDUCTION, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)}, + {DXVAHD_STREAM_STATE_FILTER_EDGE_ENHANCEMENT, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)}, + {DXVAHD_STREAM_STATE_FILTER_ANAMORPHIC_SCALING, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)}, + }; + + init_desc(&desc); + DXVAHD_CreateDevice(d3d_device, &desc, DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, NULL, &device); + IDXVAHD_Device_GetVideoProcessorDeviceCaps(device, &caps); + input_formats = heap_alloc_zero(caps.InputFormatCount * sizeof(*input_formats)); + vp_caps = heap_alloc_zero(caps.VideoProcessorCount * sizeof(*vp_caps)); + IDXVAHD_Device_GetVideoProcessorCaps(device, caps.VideoProcessorCount, vp_caps); + + hr = IDXVAHD_Device_CreateVideoProcessor(device, &vp_caps[0].VPGuid, &processor); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(test_blt); i++) + { + hr = IDXVAHD_VideoProcessor_GetVideoProcessBltState(processor, test_blt[i].state, test_blt[i].size, data); + ok(hr == S_OK, "Unexpected hr %#x for blt state %#x.\n", hr, test_blt[i].state); + /* Pass wrong data size for state */ + hr = IDXVAHD_VideoProcessor_GetVideoProcessBltState(processor, test_blt[i].state, 64, data); + todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#x for blt state %#x.\n", hr, test_blt[i].state); + } + + for (i = 0; i < ARRAY_SIZE(test_stream); i++) + { + hr = IDXVAHD_VideoProcessor_GetVideoProcessStreamState(processor, 0, test_stream[i].state, test_stream[i].size, data); + ok(hr == S_OK, "Unexpected hr %#x for stream state %#x.\n", hr, test_stream[i].state); + /* Pass wrong data size for state */ + hr = IDXVAHD_VideoProcessor_GetVideoProcessStreamState(processor, 0, test_stream[i].state, 64, data); + todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#x for stream state %#x.\n", hr, test_stream[i].state); + } + + IDXVAHD_VideoProcessor_Release(processor); + + heap_free(data); + 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(); + test_dxvahd_processor(); + +done: + IDirect3DDevice9_Release(d3d_device); + IDirect3D9_Release(d3d); + DestroyWindow(window); +} diff --git a/include/Makefile.in b/include/Makefile.in index 216adf0d7ae..f986ef42dd5 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -268,6 +268,7 @@ SOURCES = \ dxgitype.idl \ dxva.h \ dxva2api.idl \ + dxvahd.idl \ dyngraph.idl \ endpointvolume.idl \ errorrep.h \ diff --git a/include/dxvahd.idl b/include/dxvahd.idl new file mode 100644 index 00000000000..b6ed6b3217c --- /dev/null +++ b/include/dxvahd.idl @@ -0,0 +1,473 @@ +/* + * 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 + */ + +import "unknwn.idl"; + +cpp_quote("#if 0") +interface IDirect3DDevice9Ex; +interface IDirect3DSurface9; + +typedef DWORD D3DFORMAT; +typedef DWORD D3DPOOL; +typedef DWORD D3DCOLOR; +cpp_quote("#endif") + + +typedef enum _DXVAHD_FRAME_FORMAT +{ + DXVAHD_FRAME_FORMAT_PROGRESSIVE = 0, + DXVAHD_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST = 1, + DXVAHD_FRAME_FORMAT_INTERLACED_BOTTOM_FIELD_FIRST = 2 +} DXVAHD_FRAME_FORMAT; + +typedef enum _DXVAHD_DEVICE_USAGE +{ + DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL = 0, + DXVAHD_DEVICE_USAGE_OPTIMAL_SPEED = 1, + 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_BLT_STATE +{ + DXVAHD_BLT_STATE_TARGET_RECT = 0, + DXVAHD_BLT_STATE_BACKGROUND_COLOR = 1, + DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE = 2, + DXVAHD_BLT_STATE_ALPHA_FILL = 3, + DXVAHD_BLT_STATE_CONSTRICTION = 4, + DXVAHD_BLT_STATE_PRIVATE = 1000 +} DXVAHD_BLT_STATE; + +typedef enum _DXVAHD_STREAM_STATE +{ + DXVAHD_STREAM_STATE_D3DFORMAT = 0, + DXVAHD_STREAM_STATE_FRAME_FORMAT = 1, + DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE = 2, + DXVAHD_STREAM_STATE_OUTPUT_RATE = 3, + DXVAHD_STREAM_STATE_SOURCE_RECT = 4, + DXVAHD_STREAM_STATE_DESTINATION_RECT = 5, + DXVAHD_STREAM_STATE_ALPHA = 6, + DXVAHD_STREAM_STATE_PALETTE = 7, + DXVAHD_STREAM_STATE_LUMA_KEY = 8, + DXVAHD_STREAM_STATE_ASPECT_RATIO = 9, + DXVAHD_STREAM_STATE_FILTER_BRIGHTNESS = 100, + DXVAHD_STREAM_STATE_FILTER_CONTRAST = 101, + DXVAHD_STREAM_STATE_FILTER_HUE = 102, + DXVAHD_STREAM_STATE_FILTER_SATURATION = 103, + DXVAHD_STREAM_STATE_FILTER_NOISE_REDUCTION = 104, + DXVAHD_STREAM_STATE_FILTER_EDGE_ENHANCEMENT = 105, + DXVAHD_STREAM_STATE_FILTER_ANAMORPHIC_SCALING = 106, + DXVAHD_STREAM_STATE_PRIVATE = 1000 +} DXVAHD_STREAM_STATE; + +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 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 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 enum _DXVAHD_ALPHA_FILL_MODE +{ + DXVAHD_ALPHA_FILL_MODE_OPAQUE = 0, + DXVAHD_ALPHA_FILL_MODE_BACKGROUND = 1, + DXVAHD_ALPHA_FILL_MODE_DESTINATION = 2, + DXVAHD_ALPHA_FILL_MODE_SOURCE_STREAM = 3 +} DXVAHD_ALPHA_FILL_MODE; + +typedef enum _DXVAHD_OUTPUT_RATE +{ + DXVAHD_OUTPUT_RATE_NORMAL = 0, + DXVAHD_OUTPUT_RATE_HALF = 1, + DXVAHD_OUTPUT_RATE_CUSTOM = 2 +} DXVAHD_OUTPUT_RATE; + + +typedef struct _DXVAHD_RATIONAL +{ + UINT Numerator; + UINT Denominator; +} DXVAHD_RATIONAL; + +typedef struct _DXVAHD_CONTENT_DESC +{ + DXVAHD_FRAME_FORMAT InputFrameFormat; + DXVAHD_RATIONAL InputFrameRate; + UINT InputWidth; + UINT InputHeight; + DXVAHD_RATIONAL OutputFrameRate; + UINT OutputWidth; + 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; + +typedef struct _DXVAHD_STREAM_DATA +{ + BOOL Enable; + UINT OutputIndex; + UINT InputFrameOrField; + UINT PastFrames; + UINT FutureFrames; + IDirect3DSurface9 **ppPastSurfaces; + IDirect3DSurface9 *pInputSurface; + IDirect3DSurface9 **ppFutureSurfaces; +} DXVAHD_STREAM_DATA; + +typedef struct _DXVAHD_BLT_STATE_TARGET_RECT_DATA +{ + BOOL Enable; + RECT TargetRect; +} DXVAHD_BLT_STATE_TARGET_RECT_DATA; + +typedef struct _DXVAHD_COLOR_RGBA +{ + FLOAT R; + FLOAT G; + FLOAT B; + FLOAT A; +} DXVAHD_COLOR_RGBA; + +typedef struct _DXVAHD_COLOR_YCbCrA +{ + FLOAT Y; + FLOAT Cb; + FLOAT Cr; + FLOAT A; +} DXVAHD_COLOR_YCbCrA; + +typedef union _DXVAHD_COLOR +{ + DXVAHD_COLOR_RGBA RGB; + DXVAHD_COLOR_YCbCrA YCbCr; +} DXVAHD_COLOR; + +typedef struct _DXVAHD_BLT_STATE_BACKGROUND_COLOR_DATA +{ + BOOL YCbCr; + DXVAHD_COLOR BackgroundColor; +} DXVAHD_BLT_STATE_BACKGROUND_COLOR_DATA; + +typedef struct _DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA +{ + union + { + struct + { + UINT Usage : 1; + UINT RGB_Range : 1; + UINT YCbCr_Matrix : 1; + UINT YCbCr_xvYCC : 1; + UINT Reserved : 28; + }; + UINT Value; + }; +} DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA; + +typedef struct _DXVAHD_BLT_STATE_ALPHA_FILL_DATA +{ + DXVAHD_ALPHA_FILL_MODE Mode; + UINT StreamNumber; +} DXVAHD_BLT_STATE_ALPHA_FILL_DATA; + +typedef struct _DXVAHD_BLT_STATE_CONSTRICTION_DATA +{ + BOOL Enable; + SIZE Size; +} DXVAHD_BLT_STATE_CONSTRICTION_DATA; + +typedef struct _DXVAHD_BLT_STATE_PRIVATE_DATA +{ + GUID Guid; + UINT DataSize; + void *pData; +} DXVAHD_BLT_STATE_PRIVATE_DATA; + +typedef struct _DXVAHD_STREAM_STATE_D3DFORMAT_DATA +{ + D3DFORMAT Format; +} DXVAHD_STREAM_STATE_D3DFORMAT_DATA; + +typedef struct _DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA +{ + DXVAHD_FRAME_FORMAT FrameFormat; +} DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA; + +typedef struct _DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA +{ + union + { + struct + { + UINT Type : 1; + UINT RGB_Range : 1; + UINT YCbCr_Matrix : 1; + UINT YCbCr_xvYCC : 1; + UINT Reserved : 28; + }; + UINT Value; + }; +} DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA; + +typedef struct _DXVAHD_STREAM_STATE_OUTPUT_RATE_DATA +{ + BOOL RepeatFrame; + DXVAHD_OUTPUT_RATE OutputRate; + DXVAHD_RATIONAL CustomRate; +} DXVAHD_STREAM_STATE_OUTPUT_RATE_DATA; + +typedef struct _DXVAHD_STREAM_STATE_SOURCE_RECT_DATA +{ + BOOL Enable; + RECT SourceRect; +} DXVAHD_STREAM_STATE_SOURCE_RECT_DATA; + +typedef struct _DXVAHD_STREAM_STATE_DESTINATION_RECT_DATA +{ + BOOL Enable; + RECT DestinationRect; +} DXVAHD_STREAM_STATE_DESTINATION_RECT_DATA; + +typedef struct _DXVAHD_STREAM_STATE_ALPHA_DATA +{ + BOOL Enable; + FLOAT Alpha; +} DXVAHD_STREAM_STATE_ALPHA_DATA; + +typedef struct _DXVAHD_STREAM_STATE_PALETTE_DATA +{ + UINT Count; + D3DCOLOR *pEntries; +} DXVAHD_STREAM_STATE_PALETTE_DATA; + +typedef struct _DXVAHD_STREAM_STATE_LUMA_KEY_DATA +{ + BOOL Enable; + FLOAT Lower; + FLOAT Upper; +} DXVAHD_STREAM_STATE_LUMA_KEY_DATA; + +typedef struct _DXVAHD_STREAM_STATE_ASPECT_RATIO_DATA +{ + BOOL Enable; + DXVAHD_RATIONAL SourceAspectRatio; + DXVAHD_RATIONAL DestinationAspectRatio; +} DXVAHD_STREAM_STATE_ASPECT_RATIO_DATA; + +typedef struct _DXVAHD_STREAM_STATE_FILTER_DATA +{ + BOOL Enable; + INT Level; +} DXVAHD_STREAM_STATE_FILTER_DATA; + + +// FIXME +typedef void* PDXVAHDSW_Plugin; + + +interface IDXVAHD_Device; +interface IDXVAHD_VideoProcessor; + +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); +} + + +/***************************************************************************** + * IDXVAHD_VideoProcessor interface + */ +[ + object, + uuid(95f4edf4-6e03-4cd7-be1b-3075d665aa52), + local +] +interface IDXVAHD_VideoProcessor : IUnknown +{ + HRESULT SetVideoProcessBltState( + [in] DXVAHD_BLT_STATE State, + [in] UINT DataSize, + [in] const void *pData); + + HRESULT GetVideoProcessBltState( + [in] DXVAHD_BLT_STATE State, + [in] UINT DataSize, + [out] void *pData); + + HRESULT SetVideoProcessStreamState( + [in] UINT StreamNumber, + [in] DXVAHD_STREAM_STATE State, + [in] UINT DataSize, + [in] const void *pData); + + HRESULT GetVideoProcessStreamState( + [in] UINT StreamNumber, + [in] DXVAHD_STREAM_STATE State, + [in] UINT DataSize, + [out] void *pData); + + HRESULT VideoProcessBltHD( + [in, out] IDirect3DSurface9 *pOutputSurface, + [in] UINT OutputFrame, + [in] UINT StreamCount, + [in] const DXVAHD_STREAM_DATA *pStreams); +}