Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/Makefile.in | 3 ++- dlls/evr/evr.spec | 2 +- dlls/evr/mixer.c | 28 ++++++++++++++++++++ dlls/evr/tests/Makefile.in | 2 +- dlls/evr/tests/evr.c | 32 ++++++++++++++++++++++ include/evr.idl | 54 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 dlls/evr/mixer.c
diff --git a/dlls/evr/Makefile.in b/dlls/evr/Makefile.in index 053d80e61d7..b1db77e639f 100644 --- a/dlls/evr/Makefile.in +++ b/dlls/evr/Makefile.in @@ -5,6 +5,7 @@ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ evr.c \ - main.c + main.c \ + mixer.c
IDL_SRCS = evr_classes.idl diff --git a/dlls/evr/evr.spec b/dlls/evr/evr.spec index c78900c5762..ea87f16da15 100644 --- a/dlls/evr/evr.spec +++ b/dlls/evr/evr.spec @@ -13,7 +13,7 @@ @ stub MFCreateVideoMediaTypeFromSubtype @ stub MFCreateVideoMediaTypeFromVideoInfoHeader2 @ stub MFCreateVideoMediaTypeFromVideoInfoHeader -@ stub MFCreateVideoMixer +@ stdcall MFCreateVideoMixer(ptr ptr ptr ptr) @ stub MFCreateVideoMixerAndPresenter @ stub MFCreateVideoOTA @ stub MFCreateVideoPresenter2 diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c new file mode 100644 index 00000000000..fe2f4bab1df --- /dev/null +++ b/dlls/evr/mixer.c @@ -0,0 +1,28 @@ +/* + * Copyright 2020 Nikolay Sivov + * + * 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 + */ + +#include "wine/debug.h" +#include "evr.h" + +WINE_DEFAULT_DEBUG_CHANNEL(evr); + +HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) +{ + FIXME("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj); + return E_NOTIMPL; +} diff --git a/dlls/evr/tests/Makefile.in b/dlls/evr/tests/Makefile.in index 8dc11e5e558..529c5354508 100644 --- a/dlls/evr/tests/Makefile.in +++ b/dlls/evr/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = evr.dll -IMPORTS = mfuuid strmiids uuid ole32 oleaut32 +IMPORTS = mfuuid strmiids uuid dxguid ole32 oleaut32 evr
C_SRCS = \ evr.c diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 489b7b949db..adb2b777a2e 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -22,6 +22,7 @@ #include "dshow.h" #include "wine/test.h" #include "d3d9.h" +#include "evr.h" #include "initguid.h" #include "dxva2api.h"
@@ -337,6 +338,36 @@ static void test_pin_info(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void test_default_mixer(void) +{ + IMFTransform *transform; + IUnknown *unk; + HRESULT hr; + + hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform); +todo_wine + ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr); + if (FAILED(hr)) + return; + + hr = IMFTransform_QueryInterface(transform, &IID_IMFTopologyServiceLookupClient, (void **)&unk); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IUnknown_Release(unk); + + hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&unk); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IUnknown_Release(unk); + + IMFTransform_Release(transform); + + hr = MFCreateVideoMixer(NULL, &IID_IMFTransform, &IID_IMFTransform, (void **)&transform); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = CoCreateInstance(&CLSID_MFVideoMixer9, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform); + ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr); + IMFTransform_Release(transform); +} + START_TEST(evr) { CoInitialize(NULL); @@ -346,6 +377,7 @@ START_TEST(evr) test_enum_pins(); test_find_pin(); test_pin_info(); + test_default_mixer();
CoUninitialize(); } diff --git a/include/evr.idl b/include/evr.idl index 3768b41b16e..39b4853b2e3 100644 --- a/include/evr.idl +++ b/include/evr.idl @@ -107,3 +107,57 @@ interface IMFVideoRenderer : IUnknown [in] IMFVideoPresenter *pVideoPresenter ); } + +typedef enum _MF_SERVICE_LOOKUP_TYPE +{ + MF_SERVICE_LOOKUP_UPSTREAM, + MF_SERVICE_LOOKUP_UPSTREAM_DIRECT, + MF_SERVICE_LOOKUP_DOWNSTREAM, + MF_SERVICE_LOOKUP_DOWNSTREAM_DIRECT, + MF_SERVICE_LOOKUP_ALL, + MF_SERVICE_LOOKUP_GLOBAL, +} MF_SERVICE_LOOKUP_TYPE; + +[ + object, + uuid(fa993889-4383-415a-a930-dd472a8cf6f7), + local +] +interface IMFTopologyServiceLookup : IUnknown +{ + HRESULT LookupService( + [in] MF_SERVICE_LOOKUP_TYPE lookup_type, + [in] DWORD index, + [in] REFGUID service, + [in] REFIID riid, + [out, iid_is(riid)] void **objects, + [in, out] DWORD *num_objects + ); +} + +[ + object, + uuid(fa99388a-4383-415a-a930-dd472a8cf6f7), + local +] +interface IMFTopologyServiceLookupClient : IUnknown +{ + HRESULT InitServicePointers( + [in] IMFTopologyServiceLookup *service_lookup + ); + HRESULT ReleaseServicePointers(); +} + +[ + object, + uuid(a38d9567-5a9c-4f3c-b293-8eb415b279ba), + local +] +interface IMFVideoDeviceID : IUnknown +{ + HRESULT GetDeviceID( + [out] IID *device_id + ); +} + +cpp_quote("HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj);")
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/Makefile.in | 2 +- dlls/evr/evr_classes.idl | 9 +- dlls/evr/evr_private.h | 2 +- dlls/evr/main.c | 1 + dlls/evr/mixer.c | 280 ++++++++++++++++++++++++++++++++++++++- dlls/evr/tests/evr.c | 11 +- 6 files changed, 294 insertions(+), 11 deletions(-)
diff --git a/dlls/evr/Makefile.in b/dlls/evr/Makefile.in index b1db77e639f..06b80e3338d 100644 --- a/dlls/evr/Makefile.in +++ b/dlls/evr/Makefile.in @@ -1,5 +1,5 @@ MODULE = evr.dll -IMPORTS = mfuuid strmiids strmbase uuid ole32 oleaut32 +IMPORTS = mfuuid strmiids strmbase uuid dxguid ole32 oleaut32
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/evr/evr_classes.idl b/dlls/evr/evr_classes.idl index 20a346ac67a..31f0d34fe75 100644 --- a/dlls/evr/evr_classes.idl +++ b/dlls/evr/evr_classes.idl @@ -18,11 +18,16 @@
#pragma makedep register
-#include "strmif.idl" - [ helpstring("Enhanced Video Renderer"), threading(both), uuid(fa10746c-9b63-4b6c-bc49-fc300ea5f256) ] coclass EnhancedVideoRenderer { interface IBaseFilter; } + +[ + helpstring("MF Video Mixer"), + threading(both), + uuid(e474e05a-ab65-4f6a-827c-218b1baaf31f) +] +coclass MFVideoMixer9 { interface IMFTransform; } diff --git a/dlls/evr/evr_private.h b/dlls/evr/evr_private.h index ad47bd28b78..5698eb0c21e 100644 --- a/dlls/evr/evr_private.h +++ b/dlls/evr/evr_private.h @@ -24,6 +24,6 @@ #include "wine/strmbase.h"
HRESULT evr_filter_create(IUnknown *outer_unk, void **ppv) DECLSPEC_HIDDEN; - +HRESULT evr_mixer_create(IUnknown *outer_unk, void **ppv) DECLSPEC_HIDDEN;
#endif /* __EVR_PRIVATE_INCLUDED__ */ diff --git a/dlls/evr/main.c b/dlls/evr/main.c index 921e63535f9..85c81f13604 100644 --- a/dlls/evr/main.c +++ b/dlls/evr/main.c @@ -71,6 +71,7 @@ struct object_creation_info static const struct object_creation_info object_creation[] = { { &CLSID_EnhancedVideoRenderer, evr_filter_create }, + { &CLSID_MFVideoMixer9, evr_mixer_create }, };
static HRESULT WINAPI classfactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj) diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index fe2f4bab1df..41d63c8aab5 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -16,13 +16,289 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#define COBJMACROS + #include "wine/debug.h" #include "evr.h" +#include "d3d9.h" + +#include "evr_classes.h"
WINE_DEFAULT_DEBUG_CHANNEL(evr);
-HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) +struct video_mixer +{ + IMFTransform IMFTransform_iface; + LONG refcount; +}; + +static struct video_mixer *impl_from_IMFTransform(IMFTransform *iface) +{ + return CONTAINING_RECORD(iface, struct video_mixer, IMFTransform_iface); +} + +static HRESULT WINAPI video_mixer_transform_QueryInterface(IMFTransform *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IMFTransform) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IMFTransform_AddRef(iface); + return S_OK; + } + + WARN("Unsupported interface %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI video_mixer_transform_AddRef(IMFTransform *iface) +{ + struct video_mixer *mixer = impl_from_IMFTransform(iface); + ULONG refcount = InterlockedIncrement(&mixer->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI video_mixer_transform_Release(IMFTransform *iface) +{ + struct video_mixer *mixer = impl_from_IMFTransform(iface); + ULONG refcount = InterlockedDecrement(&mixer->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + free(mixer); + + return refcount; +} + +static HRESULT WINAPI video_mixer_transform_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, + DWORD *input_maximum, DWORD *output_minimum, DWORD *output_maximum) +{ + FIXME("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) +{ + FIXME("%p, %p, %p.\n", iface, inputs, outputs); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs, + DWORD output_size, DWORD *outputs) +{ + FIXME("%p, %u, %p, %u, %p.\n", iface, input_size, inputs, output_size, outputs); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) { - FIXME("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj); + FIXME("%p, %u, %p.\n", iface, id, info); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) +{ + FIXME("%p, %u, %p.\n", iface, id, info); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) +{ + FIXME("%p, %p.\n", iface, attributes); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetInputStreamAttributes(IMFTransform *iface, DWORD id, + IMFAttributes **attributes) +{ + FIXME("%p, %u, %p.\n", iface, id, attributes); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, + IMFAttributes **attributes) +{ + FIXME("%p, %u, %p.\n", iface, id, attributes); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_DeleteInputStream(IMFTransform *iface, DWORD id) +{ + FIXME("%p, %u.\n", iface, id); + return E_NOTIMPL; } + +static HRESULT WINAPI video_mixer_transform_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) +{ + FIXME("%p, %u, %p.\n", iface, streams, ids); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + FIXME("%p, %u, %u, %p.\n", iface, id, index, type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + FIXME("%p, %u, %u, %p.\n", iface, id, index, type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + FIXME("%p, %u, %p.\n", iface, id, type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + FIXME("%p, %u, %p.\n", iface, id, type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) +{ + FIXME("%p, %u, %p.\n", iface, id, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_GetOutputStatus(IMFTransform *iface, DWORD *flags) +{ + FIXME("%p, %p.\n", iface, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) +{ + FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) +{ + FIXME("%p, %u, %p.\n", iface, id, event); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) +{ + FIXME("%p, %u, %#lx.\n", iface, message, param); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) +{ + FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, + MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) +{ + FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); + + return E_NOTIMPL; +} + +static const IMFTransformVtbl video_mixer_transform_vtbl = +{ + video_mixer_transform_QueryInterface, + video_mixer_transform_AddRef, + video_mixer_transform_Release, + video_mixer_transform_GetStreamLimits, + video_mixer_transform_GetStreamCount, + video_mixer_transform_GetStreamIDs, + video_mixer_transform_GetInputStreamInfo, + video_mixer_transform_GetOutputStreamInfo, + video_mixer_transform_GetAttributes, + video_mixer_transform_GetInputStreamAttributes, + video_mixer_transform_GetOutputStreamAttributes, + video_mixer_transform_DeleteInputStream, + video_mixer_transform_AddInputStreams, + video_mixer_transform_GetInputAvailableType, + video_mixer_transform_GetOutputAvailableType, + video_mixer_transform_SetInputType, + video_mixer_transform_SetOutputType, + video_mixer_transform_GetInputCurrentType, + video_mixer_transform_GetOutputCurrentType, + video_mixer_transform_GetInputStatus, + video_mixer_transform_GetOutputStatus, + video_mixer_transform_SetOutputBounds, + video_mixer_transform_ProcessEvent, + video_mixer_transform_ProcessMessage, + video_mixer_transform_ProcessInput, + video_mixer_transform_ProcessOutput, +}; + +HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) +{ + TRACE("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj); + + *obj = NULL; + + if (!IsEqualIID(riid_device, &IID_IDirect3DDevice9)) + return E_INVALIDARG; + + return CoCreateInstance(&CLSID_MFVideoMixer9, owner, CLSCTX_INPROC_SERVER, riid, obj); +} + +HRESULT evr_mixer_create(IUnknown *outer, void **out) +{ + struct video_mixer *object; + + if (outer) + return E_NOINTERFACE; + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IMFTransform_iface.lpVtbl = &video_mixer_transform_vtbl; + object->refcount = 1; + + *out = &object->IMFTransform_iface; + + return S_OK; +} diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index adb2b777a2e..c4b1a561576 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -345,18 +345,19 @@ static void test_default_mixer(void) HRESULT hr;
hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform); -todo_wine ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr); - if (FAILED(hr)) - return;
hr = IMFTransform_QueryInterface(transform, &IID_IMFTopologyServiceLookupClient, (void **)&unk); +todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - IUnknown_Release(unk); + if (SUCCEEDED(hr)) + IUnknown_Release(unk);
hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&unk); +todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - IUnknown_Release(unk); + if (SUCCEEDED(hr)) + IUnknown_Release(unk);
IMFTransform_Release(transform);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=73619
Your paranoid android.
=== debiant (32 bit report) ===
evr: evr.c:348: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c61).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit French report) ===
evr: evr.c:348: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c61).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit Japanese:Japan report) ===
evr: evr.c:348: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c61).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
evr: evr.c:348: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c61).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit WoW report) ===
evr: evr.c:348: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c61).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (64 bit WoW report) ===
evr: evr.c:348: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c61).
Report validation errors: evr:evr crashed (c0000005)
On 6/17/20 3:33 PM, Marvin wrote:
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=73619
Your paranoid android.
=== debiant (32 bit report) ===
evr: evr.c:348: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c61).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit French report) ===
Probably because prefix wasn't updated.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/mixer.c | 66 ++++++++++++++++++++++++++++++++++++++++---- dlls/evr/tests/evr.c | 16 ++++++++--- 2 files changed, 73 insertions(+), 9 deletions(-)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index 41d63c8aab5..97eaf976fc8 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -29,6 +29,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(evr); struct video_mixer { IMFTransform IMFTransform_iface; + IMFVideoDeviceID IMFVideoDeviceID_iface; LONG refcount; };
@@ -37,19 +38,35 @@ static struct video_mixer *impl_from_IMFTransform(IMFTransform *iface) return CONTAINING_RECORD(iface, struct video_mixer, IMFTransform_iface); }
+static struct video_mixer *impl_from_IMFVideoDeviceID(IMFVideoDeviceID *iface) +{ + return CONTAINING_RECORD(iface, struct video_mixer, IMFVideoDeviceID_iface); +} + static HRESULT WINAPI video_mixer_transform_QueryInterface(IMFTransform *iface, REFIID riid, void **obj) { + struct video_mixer *mixer = impl_from_IMFTransform(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + if (IsEqualIID(riid, &IID_IMFTransform) || IsEqualIID(riid, &IID_IUnknown)) { *obj = iface; - IMFTransform_AddRef(iface); - return S_OK; + } + else if (IsEqualIID(riid, &IID_IMFVideoDeviceID)) + { + *obj = &mixer->IMFVideoDeviceID_iface; + } + else + { + WARN("Unsupported interface %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; }
- WARN("Unsupported interface %s.\n", debugstr_guid(riid)); - *obj = NULL; - return E_NOINTERFACE; + IUnknown_AddRef((IUnknown *)*obj); + return S_OK; }
static ULONG WINAPI video_mixer_transform_AddRef(IMFTransform *iface) @@ -273,6 +290,44 @@ static const IMFTransformVtbl video_mixer_transform_vtbl = video_mixer_transform_ProcessOutput, };
+static HRESULT WINAPI video_mixer_device_id_QueryInterface(IMFVideoDeviceID *iface, REFIID riid, void **obj) +{ + struct video_mixer *mixer = impl_from_IMFVideoDeviceID(iface); + return IMFTransform_QueryInterface(&mixer->IMFTransform_iface, riid, obj); +} + +static ULONG WINAPI video_mixer_device_id_AddRef(IMFVideoDeviceID *iface) +{ + struct video_mixer *mixer = impl_from_IMFVideoDeviceID(iface); + return IMFTransform_AddRef(&mixer->IMFTransform_iface); +} + +static ULONG WINAPI video_mixer_device_id_Release(IMFVideoDeviceID *iface) +{ + struct video_mixer *mixer = impl_from_IMFVideoDeviceID(iface); + return IMFTransform_Release(&mixer->IMFTransform_iface); +} + +static HRESULT WINAPI video_mixer_device_id_GetDeviceID(IMFVideoDeviceID *iface, IID *device_id) +{ + TRACE("%p, %p.\n", iface, device_id); + + if (!device_id) + return E_POINTER; + + memcpy(device_id, &IID_IDirect3DDevice9, sizeof(*device_id)); + + return S_OK; +} + +static const IMFVideoDeviceIDVtbl video_mixer_device_id_vtbl = +{ + video_mixer_device_id_QueryInterface, + video_mixer_device_id_AddRef, + video_mixer_device_id_Release, + video_mixer_device_id_GetDeviceID, +}; + HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) { TRACE("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj); @@ -296,6 +351,7 @@ HRESULT evr_mixer_create(IUnknown *outer, void **out) return E_OUTOFMEMORY;
object->IMFTransform_iface.lpVtbl = &video_mixer_transform_vtbl; + object->IMFVideoDeviceID_iface.lpVtbl = &video_mixer_device_id_vtbl; object->refcount = 1;
*out = &object->IMFTransform_iface; diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index c4b1a561576..7fa6136b0e9 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -340,9 +340,11 @@ static void test_pin_info(void)
static void test_default_mixer(void) { + IMFVideoDeviceID *deviceid; IMFTransform *transform; IUnknown *unk; HRESULT hr; + IID iid;
hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform); ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr); @@ -353,11 +355,17 @@ todo_wine if (SUCCEEDED(hr)) IUnknown_Release(unk);
- hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&unk); -todo_wine + hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&deviceid); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - if (SUCCEEDED(hr)) - IUnknown_Release(unk); + + hr = IMFVideoDeviceID_GetDeviceID(deviceid, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoDeviceID_GetDeviceID(deviceid, &iid); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(IsEqualIID(&iid, &IID_IDirect3DDevice9), "Unexpected id %s.\n", wine_dbgstr_guid(&iid)); + + IMFVideoDeviceID_Release(deviceid);
IMFTransform_Release(transform);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=73620
Your paranoid android.
=== debiant (32 bit report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c69).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit French report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c69).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit Japanese:Japan report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c69).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c69).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit WoW report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c69).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (64 bit WoW report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c69).
Report validation errors: evr:evr crashed (c0000005)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/mixer.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ dlls/evr/tests/evr.c | 4 +--- 2 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index 97eaf976fc8..3101d17ffdb 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -30,6 +30,7 @@ struct video_mixer { IMFTransform IMFTransform_iface; IMFVideoDeviceID IMFVideoDeviceID_iface; + IMFTopologyServiceLookupClient IMFTopologyServiceLookupClient_iface; LONG refcount; };
@@ -43,6 +44,11 @@ static struct video_mixer *impl_from_IMFVideoDeviceID(IMFVideoDeviceID *iface) return CONTAINING_RECORD(iface, struct video_mixer, IMFVideoDeviceID_iface); }
+static struct video_mixer *impl_from_IMFTopologyServiceLookupClient(IMFTopologyServiceLookupClient *iface) +{ + return CONTAINING_RECORD(iface, struct video_mixer, IMFTopologyServiceLookupClient_iface); +} + static HRESULT WINAPI video_mixer_transform_QueryInterface(IMFTransform *iface, REFIID riid, void **obj) { struct video_mixer *mixer = impl_from_IMFTransform(iface); @@ -58,6 +64,10 @@ static HRESULT WINAPI video_mixer_transform_QueryInterface(IMFTransform *iface, { *obj = &mixer->IMFVideoDeviceID_iface; } + else if (IsEqualIID(riid, &IID_IMFTopologyServiceLookupClient)) + { + *obj = &mixer->IMFTopologyServiceLookupClient_iface; + } else { WARN("Unsupported interface %s.\n", debugstr_guid(riid)); @@ -328,6 +338,49 @@ static const IMFVideoDeviceIDVtbl video_mixer_device_id_vtbl = video_mixer_device_id_GetDeviceID, };
+static HRESULT WINAPI video_mixer_service_client_QueryInterface(IMFTopologyServiceLookupClient *iface, + REFIID riid, void **obj) +{ + struct video_mixer *mixer = impl_from_IMFTopologyServiceLookupClient(iface); + return IMFTransform_QueryInterface(&mixer->IMFTransform_iface, riid, obj); +} + +static ULONG WINAPI video_mixer_service_client_AddRef(IMFTopologyServiceLookupClient *iface) +{ + struct video_mixer *mixer = impl_from_IMFTopologyServiceLookupClient(iface); + return IMFTransform_AddRef(&mixer->IMFTransform_iface); +} + +static ULONG WINAPI video_mixer_service_client_Release(IMFTopologyServiceLookupClient *iface) +{ + struct video_mixer *mixer = impl_from_IMFTopologyServiceLookupClient(iface); + return IMFTransform_Release(&mixer->IMFTransform_iface); +} + +static HRESULT WINAPI video_mixer_service_client_InitServicePointers(IMFTopologyServiceLookupClient *iface, + IMFTopologyServiceLookup *service_lookup) +{ + FIXME("%p, %p.\n", iface, service_lookup); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_mixer_service_client_ReleaseServicePointers(IMFTopologyServiceLookupClient *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static const IMFTopologyServiceLookupClientVtbl video_mixer_service_client_vtbl = +{ + video_mixer_service_client_QueryInterface, + video_mixer_service_client_AddRef, + video_mixer_service_client_Release, + video_mixer_service_client_InitServicePointers, + video_mixer_service_client_ReleaseServicePointers, +}; + HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) { TRACE("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj); @@ -352,6 +405,7 @@ HRESULT evr_mixer_create(IUnknown *outer, void **out)
object->IMFTransform_iface.lpVtbl = &video_mixer_transform_vtbl; object->IMFVideoDeviceID_iface.lpVtbl = &video_mixer_device_id_vtbl; + object->IMFTopologyServiceLookupClient_iface.lpVtbl = &video_mixer_service_client_vtbl; object->refcount = 1;
*out = &object->IMFTransform_iface; diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 7fa6136b0e9..56fb1680b07 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -350,10 +350,8 @@ static void test_default_mixer(void) ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
hr = IMFTransform_QueryInterface(transform, &IID_IMFTopologyServiceLookupClient, (void **)&unk); -todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); - if (SUCCEEDED(hr)) - IUnknown_Release(unk); + IUnknown_Release(unk);
hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&deviceid); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=73621
Your paranoid android.
=== debiant (32 bit report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c67).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit French report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c67).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit Japanese:Japan report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c67).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit Chinese:China report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c67).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (32 bit WoW report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c67).
Report validation errors: evr:evr crashed (c0000005)
=== debiant (64 bit WoW report) ===
evr: evr.c:350: Test failed: Failed to create default mixer, hr 0x80040154. Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00402c67).
Report validation errors: evr:evr crashed (c0000005)
On 6/17/20 6:59 AM, Nikolay Sivov wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/evr/Makefile.in | 3 ++- dlls/evr/evr.spec | 2 +- dlls/evr/mixer.c | 28 ++++++++++++++++++++ dlls/evr/tests/Makefile.in | 2 +- dlls/evr/tests/evr.c | 32 ++++++++++++++++++++++ include/evr.idl | 54 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 dlls/evr/mixer.c
diff --git a/dlls/evr/Makefile.in b/dlls/evr/Makefile.in index 053d80e61d7..b1db77e639f 100644 --- a/dlls/evr/Makefile.in +++ b/dlls/evr/Makefile.in @@ -5,6 +5,7 @@ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ evr.c \
- main.c
- main.c \
- mixer.c
IDL_SRCS = evr_classes.idl diff --git a/dlls/evr/evr.spec b/dlls/evr/evr.spec index c78900c5762..ea87f16da15 100644 --- a/dlls/evr/evr.spec +++ b/dlls/evr/evr.spec @@ -13,7 +13,7 @@ @ stub MFCreateVideoMediaTypeFromSubtype @ stub MFCreateVideoMediaTypeFromVideoInfoHeader2 @ stub MFCreateVideoMediaTypeFromVideoInfoHeader -@ stub MFCreateVideoMixer +@ stdcall MFCreateVideoMixer(ptr ptr ptr ptr) @ stub MFCreateVideoMixerAndPresenter @ stub MFCreateVideoOTA @ stub MFCreateVideoPresenter2 diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c new file mode 100644 index 00000000000..fe2f4bab1df --- /dev/null +++ b/dlls/evr/mixer.c @@ -0,0 +1,28 @@ +/*
- Copyright 2020 Nikolay Sivov
- 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
- */
+#include "wine/debug.h" +#include "evr.h"
+WINE_DEFAULT_DEBUG_CHANNEL(evr);
+HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) +{
- FIXME("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj);
- return E_NOTIMPL;
+} diff --git a/dlls/evr/tests/Makefile.in b/dlls/evr/tests/Makefile.in index 8dc11e5e558..529c5354508 100644 --- a/dlls/evr/tests/Makefile.in +++ b/dlls/evr/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = evr.dll -IMPORTS = mfuuid strmiids uuid ole32 oleaut32 +IMPORTS = mfuuid strmiids uuid dxguid ole32 oleaut32 evr
C_SRCS = \ evr.c diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 489b7b949db..adb2b777a2e 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -22,6 +22,7 @@ #include "dshow.h" #include "wine/test.h" #include "d3d9.h" +#include "evr.h" #include "initguid.h" #include "dxva2api.h"
@@ -337,6 +338,36 @@ static void test_pin_info(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void test_default_mixer(void) +{
- IMFTransform *transform;
- IUnknown *unk;
- HRESULT hr;
- hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
+todo_wine
- ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
- if (FAILED(hr))
return;
- hr = IMFTransform_QueryInterface(transform, &IID_IMFTopologyServiceLookupClient, (void **)&unk);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- IUnknown_Release(unk);
- hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&unk);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- IUnknown_Release(unk);
- IMFTransform_Release(transform);
- hr = MFCreateVideoMixer(NULL, &IID_IMFTransform, &IID_IMFTransform, (void **)&transform);
- ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
- hr = CoCreateInstance(&CLSID_MFVideoMixer9, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform);
- ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
- IMFTransform_Release(transform);
+}
START_TEST(evr) { CoInitialize(NULL); @@ -346,6 +377,7 @@ START_TEST(evr) test_enum_pins(); test_find_pin(); test_pin_info();
test_default_mixer();
CoUninitialize();
}
I think it would probably be a good idea to separate mfplat tests from quartz tests, i.e. by putting them in a separate file.
diff --git a/include/evr.idl b/include/evr.idl index 3768b41b16e..39b4853b2e3 100644 --- a/include/evr.idl +++ b/include/evr.idl @@ -107,3 +107,57 @@ interface IMFVideoRenderer : IUnknown [in] IMFVideoPresenter *pVideoPresenter ); }
+typedef enum _MF_SERVICE_LOOKUP_TYPE +{
- MF_SERVICE_LOOKUP_UPSTREAM,
- MF_SERVICE_LOOKUP_UPSTREAM_DIRECT,
- MF_SERVICE_LOOKUP_DOWNSTREAM,
- MF_SERVICE_LOOKUP_DOWNSTREAM_DIRECT,
- MF_SERVICE_LOOKUP_ALL,
- MF_SERVICE_LOOKUP_GLOBAL,
+} MF_SERVICE_LOOKUP_TYPE;
+[
- object,
- uuid(fa993889-4383-415a-a930-dd472a8cf6f7),
- local
+] +interface IMFTopologyServiceLookup : IUnknown +{
- HRESULT LookupService(
[in] MF_SERVICE_LOOKUP_TYPE lookup_type,
[in] DWORD index,
[in] REFGUID service,
[in] REFIID riid,
[out, iid_is(riid)] void **objects,
[in, out] DWORD *num_objects
- );
+}
+[
- object,
- uuid(fa99388a-4383-415a-a930-dd472a8cf6f7),
- local
+] +interface IMFTopologyServiceLookupClient : IUnknown +{
- HRESULT InitServicePointers(
[in] IMFTopologyServiceLookup *service_lookup
- );
- HRESULT ReleaseServicePointers();
+}
+[
- object,
- uuid(a38d9567-5a9c-4f3c-b293-8eb415b279ba),
- local
+] +interface IMFVideoDeviceID : IUnknown +{
- HRESULT GetDeviceID(
[out] IID *device_id
- );
+}
+cpp_quote("HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj);")
On 6/17/20 6:12 PM, Zebediah Figura wrote:
On 6/17/20 6:59 AM, Nikolay Sivov wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/evr/Makefile.in | 3 ++- dlls/evr/evr.spec | 2 +- dlls/evr/mixer.c | 28 ++++++++++++++++++++ dlls/evr/tests/Makefile.in | 2 +- dlls/evr/tests/evr.c | 32 ++++++++++++++++++++++ include/evr.idl | 54 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 dlls/evr/mixer.c
diff --git a/dlls/evr/Makefile.in b/dlls/evr/Makefile.in index 053d80e61d7..b1db77e639f 100644 --- a/dlls/evr/Makefile.in +++ b/dlls/evr/Makefile.in @@ -5,6 +5,7 @@ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ evr.c \
- main.c
main.c \
mixer.c
IDL_SRCS = evr_classes.idl
diff --git a/dlls/evr/evr.spec b/dlls/evr/evr.spec index c78900c5762..ea87f16da15 100644 --- a/dlls/evr/evr.spec +++ b/dlls/evr/evr.spec @@ -13,7 +13,7 @@ @ stub MFCreateVideoMediaTypeFromSubtype @ stub MFCreateVideoMediaTypeFromVideoInfoHeader2 @ stub MFCreateVideoMediaTypeFromVideoInfoHeader -@ stub MFCreateVideoMixer +@ stdcall MFCreateVideoMixer(ptr ptr ptr ptr) @ stub MFCreateVideoMixerAndPresenter @ stub MFCreateVideoOTA @ stub MFCreateVideoPresenter2 diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c new file mode 100644 index 00000000000..fe2f4bab1df --- /dev/null +++ b/dlls/evr/mixer.c @@ -0,0 +1,28 @@ +/*
- Copyright 2020 Nikolay Sivov
- 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
- */
+#include "wine/debug.h" +#include "evr.h"
+WINE_DEFAULT_DEBUG_CHANNEL(evr);
+HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) +{
- FIXME("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj);
- return E_NOTIMPL;
+} diff --git a/dlls/evr/tests/Makefile.in b/dlls/evr/tests/Makefile.in index 8dc11e5e558..529c5354508 100644 --- a/dlls/evr/tests/Makefile.in +++ b/dlls/evr/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = evr.dll -IMPORTS = mfuuid strmiids uuid ole32 oleaut32 +IMPORTS = mfuuid strmiids uuid dxguid ole32 oleaut32 evr
C_SRCS = \ evr.c diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 489b7b949db..adb2b777a2e 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -22,6 +22,7 @@ #include "dshow.h" #include "wine/test.h" #include "d3d9.h" +#include "evr.h" #include "initguid.h" #include "dxva2api.h"
@@ -337,6 +338,36 @@ static void test_pin_info(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void test_default_mixer(void) +{
- IMFTransform *transform;
- IUnknown *unk;
- HRESULT hr;
- hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
+todo_wine
- ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
- if (FAILED(hr))
return;
- hr = IMFTransform_QueryInterface(transform, &IID_IMFTopologyServiceLookupClient, (void **)&unk);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- IUnknown_Release(unk);
- hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&unk);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- IUnknown_Release(unk);
- IMFTransform_Release(transform);
- hr = MFCreateVideoMixer(NULL, &IID_IMFTransform, &IID_IMFTransform, (void **)&transform);
- ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
- hr = CoCreateInstance(&CLSID_MFVideoMixer9, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform);
- ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
- IMFTransform_Release(transform);
+}
- START_TEST(evr) { CoInitialize(NULL);
@@ -346,6 +377,7 @@ START_TEST(evr) test_enum_pins(); test_find_pin(); test_pin_info();
test_default_mixer();
CoUninitialize(); }
I think it would probably be a good idea to separate mfplat tests from quartz tests, i.e. by putting them in a separate file.
Why? IMF* interfaces are also used in DirectShow situation for EVR. I don't see a reason to make tests more separate than the thing it's testing.
diff --git a/include/evr.idl b/include/evr.idl index 3768b41b16e..39b4853b2e3 100644 --- a/include/evr.idl +++ b/include/evr.idl @@ -107,3 +107,57 @@ interface IMFVideoRenderer : IUnknown [in] IMFVideoPresenter *pVideoPresenter ); }
+typedef enum _MF_SERVICE_LOOKUP_TYPE +{
- MF_SERVICE_LOOKUP_UPSTREAM,
- MF_SERVICE_LOOKUP_UPSTREAM_DIRECT,
- MF_SERVICE_LOOKUP_DOWNSTREAM,
- MF_SERVICE_LOOKUP_DOWNSTREAM_DIRECT,
- MF_SERVICE_LOOKUP_ALL,
- MF_SERVICE_LOOKUP_GLOBAL,
+} MF_SERVICE_LOOKUP_TYPE;
+[
- object,
- uuid(fa993889-4383-415a-a930-dd472a8cf6f7),
- local
+] +interface IMFTopologyServiceLookup : IUnknown +{
- HRESULT LookupService(
[in] MF_SERVICE_LOOKUP_TYPE lookup_type,
[in] DWORD index,
[in] REFGUID service,
[in] REFIID riid,
[out, iid_is(riid)] void **objects,
[in, out] DWORD *num_objects
- );
+}
+[
- object,
- uuid(fa99388a-4383-415a-a930-dd472a8cf6f7),
- local
+] +interface IMFTopologyServiceLookupClient : IUnknown +{
- HRESULT InitServicePointers(
[in] IMFTopologyServiceLookup *service_lookup
- );
- HRESULT ReleaseServicePointers();
+}
+[
- object,
- uuid(a38d9567-5a9c-4f3c-b293-8eb415b279ba),
- local
+] +interface IMFVideoDeviceID : IUnknown +{
- HRESULT GetDeviceID(
[out] IID *device_id
- );
+}
+cpp_quote("HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj);")
On 6/17/20 10:16 AM, Nikolay Sivov wrote:
On 6/17/20 6:12 PM, Zebediah Figura wrote:
On 6/17/20 6:59 AM, Nikolay Sivov wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/evr/Makefile.in | 3 ++- dlls/evr/evr.spec | 2 +- dlls/evr/mixer.c | 28 ++++++++++++++++++++ dlls/evr/tests/Makefile.in | 2 +- dlls/evr/tests/evr.c | 32 ++++++++++++++++++++++ include/evr.idl | 54 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 118 insertions(+), 3 deletions(-) create mode 100644 dlls/evr/mixer.c
diff --git a/dlls/evr/Makefile.in b/dlls/evr/Makefile.in index 053d80e61d7..b1db77e639f 100644 --- a/dlls/evr/Makefile.in +++ b/dlls/evr/Makefile.in @@ -5,6 +5,7 @@ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ evr.c \
- main.c
main.c \
mixer.c
IDL_SRCS = evr_classes.idl
diff --git a/dlls/evr/evr.spec b/dlls/evr/evr.spec index c78900c5762..ea87f16da15 100644 --- a/dlls/evr/evr.spec +++ b/dlls/evr/evr.spec @@ -13,7 +13,7 @@ @ stub MFCreateVideoMediaTypeFromSubtype @ stub MFCreateVideoMediaTypeFromVideoInfoHeader2 @ stub MFCreateVideoMediaTypeFromVideoInfoHeader -@ stub MFCreateVideoMixer +@ stdcall MFCreateVideoMixer(ptr ptr ptr ptr) @ stub MFCreateVideoMixerAndPresenter @ stub MFCreateVideoOTA @ stub MFCreateVideoPresenter2 diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c new file mode 100644 index 00000000000..fe2f4bab1df --- /dev/null +++ b/dlls/evr/mixer.c @@ -0,0 +1,28 @@ +/*
- Copyright 2020 Nikolay Sivov
- 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
- */
+#include "wine/debug.h" +#include "evr.h"
+WINE_DEFAULT_DEBUG_CHANNEL(evr);
+HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) +{
- FIXME("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj);
- return E_NOTIMPL;
+} diff --git a/dlls/evr/tests/Makefile.in b/dlls/evr/tests/Makefile.in index 8dc11e5e558..529c5354508 100644 --- a/dlls/evr/tests/Makefile.in +++ b/dlls/evr/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = evr.dll -IMPORTS = mfuuid strmiids uuid ole32 oleaut32 +IMPORTS = mfuuid strmiids uuid dxguid ole32 oleaut32 evr
C_SRCS = \ evr.c diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 489b7b949db..adb2b777a2e 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -22,6 +22,7 @@ #include "dshow.h" #include "wine/test.h" #include "d3d9.h" +#include "evr.h" #include "initguid.h" #include "dxva2api.h"
@@ -337,6 +338,36 @@ static void test_pin_info(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void test_default_mixer(void) +{
- IMFTransform *transform;
- IUnknown *unk;
- HRESULT hr;
- hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
+todo_wine
- ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
- if (FAILED(hr))
return;
- hr = IMFTransform_QueryInterface(transform, &IID_IMFTopologyServiceLookupClient, (void **)&unk);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- IUnknown_Release(unk);
- hr = IMFTransform_QueryInterface(transform, &IID_IMFVideoDeviceID, (void **)&unk);
- ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
- IUnknown_Release(unk);
- IMFTransform_Release(transform);
- hr = MFCreateVideoMixer(NULL, &IID_IMFTransform, &IID_IMFTransform, (void **)&transform);
- ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
- hr = CoCreateInstance(&CLSID_MFVideoMixer9, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform);
- ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
- IMFTransform_Release(transform);
+}
- START_TEST(evr) { CoInitialize(NULL);
@@ -346,6 +377,7 @@ START_TEST(evr) test_enum_pins(); test_find_pin(); test_pin_info();
test_default_mixer();
CoUninitialize(); }
I think it would probably be a good idea to separate mfplat tests from quartz tests, i.e. by putting them in a separate file.
Why? IMF* interfaces are also used in DirectShow situation for EVR. I don't see a reason to make tests more separate than the thing it's testing.
I guess because while the interfaces may be shared, the usage will look very different. I don't care a lot, though.
diff --git a/include/evr.idl b/include/evr.idl index 3768b41b16e..39b4853b2e3 100644 --- a/include/evr.idl +++ b/include/evr.idl @@ -107,3 +107,57 @@ interface IMFVideoRenderer : IUnknown [in] IMFVideoPresenter *pVideoPresenter ); }
+typedef enum _MF_SERVICE_LOOKUP_TYPE +{
- MF_SERVICE_LOOKUP_UPSTREAM,
- MF_SERVICE_LOOKUP_UPSTREAM_DIRECT,
- MF_SERVICE_LOOKUP_DOWNSTREAM,
- MF_SERVICE_LOOKUP_DOWNSTREAM_DIRECT,
- MF_SERVICE_LOOKUP_ALL,
- MF_SERVICE_LOOKUP_GLOBAL,
+} MF_SERVICE_LOOKUP_TYPE;
+[
- object,
- uuid(fa993889-4383-415a-a930-dd472a8cf6f7),
- local
+] +interface IMFTopologyServiceLookup : IUnknown +{
- HRESULT LookupService(
[in] MF_SERVICE_LOOKUP_TYPE lookup_type,
[in] DWORD index,
[in] REFGUID service,
[in] REFIID riid,
[out, iid_is(riid)] void **objects,
[in, out] DWORD *num_objects
- );
+}
+[
- object,
- uuid(fa99388a-4383-415a-a930-dd472a8cf6f7),
- local
+] +interface IMFTopologyServiceLookupClient : IUnknown +{
- HRESULT InitServicePointers(
[in] IMFTopologyServiceLookup *service_lookup
- );
- HRESULT ReleaseServicePointers();
+}
+[
- object,
- uuid(a38d9567-5a9c-4f3c-b293-8eb415b279ba),
- local
+] +interface IMFVideoDeviceID : IUnknown +{
- HRESULT GetDeviceID(
[out] IID *device_id
- );
+}
+cpp_quote("HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj);")