Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/Makefile.in | 3 +- dlls/evr/evr.spec | 2 +- dlls/evr/evr_classes.idl | 7 ++ dlls/evr/evr_private.h | 23 +++++ dlls/evr/main.c | 1 + dlls/evr/presenter.c | 218 +++++++++++++++++++++++++++++++++++++++ dlls/evr/tests/evr.c | 35 +++++++ include/evr.idl | 1 + 8 files changed, 288 insertions(+), 2 deletions(-) create mode 100644 dlls/evr/presenter.c
diff --git a/dlls/evr/Makefile.in b/dlls/evr/Makefile.in index 5671511f6ae..daaf9cc872a 100644 --- a/dlls/evr/Makefile.in +++ b/dlls/evr/Makefile.in @@ -8,6 +8,7 @@ EXTRADLLFLAGS = -mno-cygwin C_SRCS = \ evr.c \ main.c \ - mixer.c + mixer.c \ + presenter.c
IDL_SRCS = evr_classes.idl diff --git a/dlls/evr/evr.spec b/dlls/evr/evr.spec index 214f2b81d85..e46cb04f644 100644 --- a/dlls/evr/evr.spec +++ b/dlls/evr/evr.spec @@ -17,7 +17,7 @@ @ stub MFCreateVideoMixerAndPresenter @ stub MFCreateVideoOTA @ stub MFCreateVideoPresenter2 -@ stub MFCreateVideoPresenter +@ stdcall MFCreateVideoPresenter(ptr ptr ptr ptr) @ stub MFCreateVideoSampleAllocator @ stdcall MFCreateVideoSampleFromSurface(ptr ptr) @ stub MFGetPlaneSize diff --git a/dlls/evr/evr_classes.idl b/dlls/evr/evr_classes.idl index 31f0d34fe75..1885a34d77f 100644 --- a/dlls/evr/evr_classes.idl +++ b/dlls/evr/evr_classes.idl @@ -31,3 +31,10 @@ coclass EnhancedVideoRenderer { interface IBaseFilter; } uuid(e474e05a-ab65-4f6a-827c-218b1baaf31f) ] coclass MFVideoMixer9 { interface IMFTransform; } + +[ + helpstring("MF Video Presenter"), + threading(both), + uuid(98455561-5136-4d28-ab08-4cee40ea2781) +] +coclass MFVideoPresenter9 { interface IMFVideoPresenter; } diff --git a/dlls/evr/evr_private.h b/dlls/evr/evr_private.h index 5698eb0c21e..7ae83140579 100644 --- a/dlls/evr/evr_private.h +++ b/dlls/evr/evr_private.h @@ -22,8 +22,31 @@ #include "dshow.h" #include "evr.h" #include "wine/strmbase.h" +#include "wine/debug.h" + +static inline const char *debugstr_time(LONGLONG time) +{ + ULONGLONG abstime = time >= 0 ? time : -time; + unsigned int i = 0, j = 0; + char buffer[23], rev[23]; + + while (abstime || i <= 8) + { + buffer[i++] = '0' + (abstime % 10); + abstime /= 10; + if (i == 7) buffer[i++] = '.'; + } + if (time < 0) buffer[i++] = '-'; + + while (i--) rev[j++] = buffer[i]; + while (rev[j-1] == '0' && rev[j-2] != '.') --j; + rev[j] = 0; + + return wine_dbg_sprintf("%s", rev); +}
HRESULT evr_filter_create(IUnknown *outer_unk, void **ppv) DECLSPEC_HIDDEN; HRESULT evr_mixer_create(IUnknown *outer_unk, void **ppv) DECLSPEC_HIDDEN; +HRESULT evr_presenter_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 85c81f13604..2c6db8430ba 100644 --- a/dlls/evr/main.c +++ b/dlls/evr/main.c @@ -72,6 +72,7 @@ static const struct object_creation_info object_creation[] = { { &CLSID_EnhancedVideoRenderer, evr_filter_create }, { &CLSID_MFVideoMixer9, evr_mixer_create }, + { &CLSID_MFVideoPresenter9, evr_presenter_create }, };
static HRESULT WINAPI classfactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj) diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c new file mode 100644 index 00000000000..234c1f076ca --- /dev/null +++ b/dlls/evr/presenter.c @@ -0,0 +1,218 @@ +/* + * 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 + */ + +#define COBJMACROS + +#include "evr.h" +#include "d3d9.h" +#include "mfapi.h" +#include "mferror.h" + +#include "evr_classes.h" +#include "evr_private.h" + +#include "wine/debug.h" +#include "wine/heap.h" + +WINE_DEFAULT_DEBUG_CHANNEL(evr); + +struct video_presenter +{ + IMFVideoPresenter IMFVideoPresenter_iface; + IUnknown IUnknown_inner; + IUnknown *outer_unk; + LONG refcount; +}; + +static struct video_presenter *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct video_presenter, IUnknown_inner); +} + +static struct video_presenter *impl_from_IMFVideoPresenter(IMFVideoPresenter *iface) +{ + return CONTAINING_RECORD(iface, struct video_presenter, IMFVideoPresenter_iface); +} + +static HRESULT WINAPI video_presenter_inner_QueryInterface(IUnknown *iface, REFIID riid, void **obj) +{ + struct video_presenter *presenter = impl_from_IUnknown(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + } + else if (IsEqualIID(riid, &IID_IMFClockStateSink) + || IsEqualIID(riid, &IID_IMFVideoPresenter)) + { + *obj = &presenter->IMFVideoPresenter_iface; + } + else + { + WARN("Unimplemented interface %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*obj); + return S_OK; +} + +static ULONG WINAPI video_presenter_inner_AddRef(IUnknown *iface) +{ + struct video_presenter *presenter = impl_from_IUnknown(iface); + ULONG refcount = InterlockedIncrement(&presenter->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI video_presenter_inner_Release(IUnknown *iface) +{ + struct video_presenter *presenter = impl_from_IUnknown(iface); + ULONG refcount = InterlockedDecrement(&presenter->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + heap_free(presenter); + } + + return refcount; +} + +static const IUnknownVtbl video_presenter_inner_vtbl = +{ + video_presenter_inner_QueryInterface, + video_presenter_inner_AddRef, + video_presenter_inner_Release, +}; + +static HRESULT WINAPI video_presenter_QueryInterface(IMFVideoPresenter *iface, REFIID riid, void **obj) +{ + struct video_presenter *presenter = impl_from_IMFVideoPresenter(iface); + return IUnknown_QueryInterface(presenter->outer_unk, riid, obj); +} + +static ULONG WINAPI video_presenter_AddRef(IMFVideoPresenter *iface) +{ + struct video_presenter *presenter = impl_from_IMFVideoPresenter(iface); + return IUnknown_AddRef(presenter->outer_unk); +} + +static ULONG WINAPI video_presenter_Release(IMFVideoPresenter *iface) +{ + struct video_presenter *presenter = impl_from_IMFVideoPresenter(iface); + return IUnknown_Release(presenter->outer_unk); +} + +static HRESULT WINAPI video_presenter_OnClockStart(IMFVideoPresenter *iface, MFTIME systime, LONGLONG offset) +{ + FIXME("%p, %s, %s.\n", iface, debugstr_time(systime), wine_dbgstr_longlong(offset)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_OnClockStop(IMFVideoPresenter *iface, MFTIME systime) +{ + FIXME("%p, %s.\n", iface, debugstr_time(systime)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_OnClockPause(IMFVideoPresenter *iface, MFTIME systime) +{ + FIXME("%p, %s.\n", iface, debugstr_time(systime)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_OnClockRestart(IMFVideoPresenter *iface, MFTIME systime) +{ + FIXME("%p, %s.\n", iface, debugstr_time(systime)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_OnClockSetRate(IMFVideoPresenter *iface, MFTIME systime, float rate) +{ + FIXME("%p, %s, %f.\n", iface, debugstr_time(systime), rate); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_ProcessMessage(IMFVideoPresenter *iface, MFVP_MESSAGE_TYPE message, ULONG_PTR param) +{ + FIXME("%p, %d, %lu.\n", iface, message, param); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_GetCurrentMediaType(IMFVideoPresenter *iface, IMFVideoMediaType **media_type) +{ + FIXME("%p, %p.\n", iface, media_type); + + return E_NOTIMPL; +} + +static const IMFVideoPresenterVtbl video_presenter_vtbl = +{ + video_presenter_QueryInterface, + video_presenter_AddRef, + video_presenter_Release, + video_presenter_OnClockStart, + video_presenter_OnClockStop, + video_presenter_OnClockPause, + video_presenter_OnClockRestart, + video_presenter_OnClockSetRate, + video_presenter_ProcessMessage, + video_presenter_GetCurrentMediaType, +}; + +HRESULT WINAPI MFCreateVideoPresenter(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_MFVideoPresenter9, owner, CLSCTX_INPROC_SERVER, riid, obj); +} + +HRESULT evr_presenter_create(IUnknown *outer, void **out) +{ + struct video_presenter *object; + + if (!(object = heap_alloc(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IMFVideoPresenter_iface.lpVtbl = &video_presenter_vtbl; + object->IUnknown_inner.lpVtbl = &video_presenter_inner_vtbl; + object->outer_unk = outer ? outer : &object->IUnknown_inner; + object->refcount = 1; + + *out = &object->IUnknown_inner; + + return S_OK; +} diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 70fc6b18e2f..6805a7ae2b7 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -117,6 +117,7 @@ static IUnknown test_outer = {&outer_vtbl}; static void test_aggregation(void) { IBaseFilter *filter, *filter2; + IMFVideoPresenter *presenter; IUnknown *unk, *unk2; HRESULT hr; ULONG ref; @@ -171,6 +172,25 @@ static void test_aggregation(void) ref = IUnknown_Release(unk); ok(!ref, "Got unexpected refcount %d.\n", ref); ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + /* Default presenter. */ + presenter = (void *)0xdeadbeef; + hr = CoCreateInstance(&CLSID_MFVideoPresenter9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IMFVideoPresenter, + (void **)&presenter); + ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr); + ok(!presenter, "Got interface %p.\n", presenter); + + hr = CoCreateInstance(&CLSID_MFVideoPresenter9, &test_outer, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&unk); + ok(hr == S_OK || broken(hr == E_FAIL) /* WinXP */, "Unexpected hr %#x.\n", hr); + if (SUCCEEDED(hr)) + { + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + ok(unk != &test_outer, "Returned IUnknown should not be outer IUnknown.\n"); + ref = get_refcount(unk); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + + IUnknown_Release(unk); + } }
#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) @@ -846,6 +866,20 @@ done: DestroyWindow(window); }
+static void test_default_presenter(void) +{ + IMFVideoPresenter *presenter; + HRESULT hr; + + hr = MFCreateVideoPresenter(NULL, &IID_IMFVideoPresenter, &IID_IMFVideoPresenter, (void **)&presenter); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter); + ok(hr == S_OK || broken(hr == E_FAIL) /* WinXP */, "Failed to create default presenter, hr %#x.\n", hr); + if (SUCCEEDED(hr)) + IMFVideoPresenter_Release(presenter); +} + START_TEST(evr) { CoInitialize(NULL); @@ -860,6 +894,7 @@ START_TEST(evr) test_default_mixer(); test_default_mixer_type_negotiation(); test_surface_sample(); + test_default_presenter();
CoUninitialize(); } diff --git a/include/evr.idl b/include/evr.idl index 4599e298790..5a623c2c29c 100644 --- a/include/evr.idl +++ b/include/evr.idl @@ -225,4 +225,5 @@ cpp_quote("DEFINE_GUID(MR_BUFFER_SERVICE, 0xa562248c, 0x9ac6, 0x4ffc, 0x9f, 0xba cpp_quote("DEFINE_GUID(VIDEO_ZOOM_RECT, 0x7aaa1638, 0x1b7f, 0x4c93, 0xbd, 0x89, 0x5b, 0x9c, 0x9f, 0xb6, 0xfc, 0xf0);")
cpp_quote("HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj);") +cpp_quote("HRESULT WINAPI MFCreateVideoPresenter(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj);") cpp_quote("HRESULT WINAPI MFCreateVideoSampleFromSurface(IUnknown *surface, IMFSample **sample);")
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/presenter.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ dlls/evr/tests/evr.c | 20 ++++++++++++++++-- 2 files changed, 67 insertions(+), 2 deletions(-)
diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index 234c1f076ca..34c9a06fcf3 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -34,6 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(evr); struct video_presenter { IMFVideoPresenter IMFVideoPresenter_iface; + IMFVideoDeviceID IMFVideoDeviceID_iface; IUnknown IUnknown_inner; IUnknown *outer_unk; LONG refcount; @@ -49,6 +50,11 @@ static struct video_presenter *impl_from_IMFVideoPresenter(IMFVideoPresenter *if return CONTAINING_RECORD(iface, struct video_presenter, IMFVideoPresenter_iface); }
+static struct video_presenter *impl_from_IMFVideoDeviceID(IMFVideoDeviceID *iface) +{ + return CONTAINING_RECORD(iface, struct video_presenter, IMFVideoDeviceID_iface); +} + static HRESULT WINAPI video_presenter_inner_QueryInterface(IUnknown *iface, REFIID riid, void **obj) { struct video_presenter *presenter = impl_from_IUnknown(iface); @@ -64,6 +70,10 @@ static HRESULT WINAPI video_presenter_inner_QueryInterface(IUnknown *iface, REFI { *obj = &presenter->IMFVideoPresenter_iface; } + else if (IsEqualIID(riid, &IID_IMFVideoDeviceID)) + { + *obj = &presenter->IMFVideoDeviceID_iface; + } else { WARN("Unimplemented interface %s.\n", debugstr_guid(riid)); @@ -188,6 +198,44 @@ static const IMFVideoPresenterVtbl video_presenter_vtbl = video_presenter_GetCurrentMediaType, };
+static HRESULT WINAPI video_presenter_device_id_QueryInterface(IMFVideoDeviceID *iface, REFIID riid, void **obj) +{ + struct video_presenter *presenter = impl_from_IMFVideoDeviceID(iface); + return IMFVideoPresenter_QueryInterface(&presenter->IMFVideoPresenter_iface, riid, obj); +} + +static ULONG WINAPI video_presenter_device_id_AddRef(IMFVideoDeviceID *iface) +{ + struct video_presenter *presenter = impl_from_IMFVideoDeviceID(iface); + return IMFVideoPresenter_AddRef(&presenter->IMFVideoPresenter_iface); +} + +static ULONG WINAPI video_presenter_device_id_Release(IMFVideoDeviceID *iface) +{ + struct video_presenter *presenter = impl_from_IMFVideoDeviceID(iface); + return IMFVideoPresenter_Release(&presenter->IMFVideoPresenter_iface); +} + +static HRESULT WINAPI video_presenter_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_presenter_device_id_vtbl = +{ + video_presenter_device_id_QueryInterface, + video_presenter_device_id_AddRef, + video_presenter_device_id_Release, + video_presenter_device_id_GetDeviceID, +}; + HRESULT WINAPI MFCreateVideoPresenter(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) { TRACE("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj); @@ -208,6 +256,7 @@ HRESULT evr_presenter_create(IUnknown *outer, void **out) return E_OUTOFMEMORY;
object->IMFVideoPresenter_iface.lpVtbl = &video_presenter_vtbl; + object->IMFVideoDeviceID_iface.lpVtbl = &video_presenter_device_id_vtbl; object->IUnknown_inner.lpVtbl = &video_presenter_inner_vtbl; object->outer_unk = outer ? outer : &object->IUnknown_inner; object->refcount = 1; diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 6805a7ae2b7..965b921937c 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -869,15 +869,31 @@ done: static void test_default_presenter(void) { IMFVideoPresenter *presenter; + IMFVideoDeviceID *deviceid; HRESULT hr; + GUID iid;
hr = MFCreateVideoPresenter(NULL, &IID_IMFVideoPresenter, &IID_IMFVideoPresenter, (void **)&presenter); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter); ok(hr == S_OK || broken(hr == E_FAIL) /* WinXP */, "Failed to create default presenter, hr %#x.\n", hr); - if (SUCCEEDED(hr)) - IMFVideoPresenter_Release(presenter); + if (FAILED(hr)) + return; + + hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDeviceID, (void **)&deviceid); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + 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); + + IMFVideoPresenter_Release(presenter); }
START_TEST(evr)
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=74505
Your paranoid android.
=== debiant (32 bit report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:880: Test failed: Failed to create default presenter, hr 0x80040154.
=== debiant (32 bit French report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:880: Test failed: Failed to create default presenter, hr 0x80040154.
=== debiant (32 bit Japanese:Japan report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:880: Test failed: Failed to create default presenter, hr 0x80040154.
=== debiant (32 bit Chinese:China report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:880: Test failed: Failed to create default presenter, hr 0x80040154.
=== debiant (32 bit WoW report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:880: Test failed: Failed to create default presenter, hr 0x80040154.
=== debiant (64 bit WoW report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:880: Test failed: Failed to create default presenter, hr 0x80040154.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/presenter.c | 54 ++++++++++++++++++++++++++++++++++++++++++++ dlls/evr/tests/evr.c | 5 ++++ 2 files changed, 59 insertions(+)
diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index 34c9a06fcf3..db2f85b46fd 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -35,6 +35,7 @@ struct video_presenter { IMFVideoPresenter IMFVideoPresenter_iface; IMFVideoDeviceID IMFVideoDeviceID_iface; + IMFTopologyServiceLookupClient IMFTopologyServiceLookupClient_iface; IUnknown IUnknown_inner; IUnknown *outer_unk; LONG refcount; @@ -55,6 +56,11 @@ static struct video_presenter *impl_from_IMFVideoDeviceID(IMFVideoDeviceID *ifac return CONTAINING_RECORD(iface, struct video_presenter, IMFVideoDeviceID_iface); }
+static struct video_presenter *impl_from_IMFTopologyServiceLookupClient(IMFTopologyServiceLookupClient *iface) +{ + return CONTAINING_RECORD(iface, struct video_presenter, IMFTopologyServiceLookupClient_iface); +} + static HRESULT WINAPI video_presenter_inner_QueryInterface(IUnknown *iface, REFIID riid, void **obj) { struct video_presenter *presenter = impl_from_IUnknown(iface); @@ -74,6 +80,10 @@ static HRESULT WINAPI video_presenter_inner_QueryInterface(IUnknown *iface, REFI { *obj = &presenter->IMFVideoDeviceID_iface; } + else if (IsEqualIID(riid, &IID_IMFTopologyServiceLookupClient)) + { + *obj = &presenter->IMFTopologyServiceLookupClient_iface; + } else { WARN("Unimplemented interface %s.\n", debugstr_guid(riid)); @@ -236,6 +246,49 @@ static const IMFVideoDeviceIDVtbl video_presenter_device_id_vtbl = video_presenter_device_id_GetDeviceID, };
+static HRESULT WINAPI video_presenter_service_client_QueryInterface(IMFTopologyServiceLookupClient *iface, + REFIID riid, void **obj) +{ + struct video_presenter *presenter = impl_from_IMFTopologyServiceLookupClient(iface); + return IMFVideoPresenter_QueryInterface(&presenter->IMFVideoPresenter_iface, riid, obj); +} + +static ULONG WINAPI video_presenter_service_client_AddRef(IMFTopologyServiceLookupClient *iface) +{ + struct video_presenter *presenter = impl_from_IMFTopologyServiceLookupClient(iface); + return IMFVideoPresenter_AddRef(&presenter->IMFVideoPresenter_iface); +} + +static ULONG WINAPI video_presenter_service_client_Release(IMFTopologyServiceLookupClient *iface) +{ + struct video_presenter *presenter = impl_from_IMFTopologyServiceLookupClient(iface); + return IMFVideoPresenter_Release(&presenter->IMFVideoPresenter_iface); +} + +static HRESULT WINAPI video_presenter_service_client_InitServicePointers(IMFTopologyServiceLookupClient *iface, + IMFTopologyServiceLookup *service_lookup) +{ + FIXME("%p, %p.\n", iface, service_lookup); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_service_client_ReleaseServicePointers(IMFTopologyServiceLookupClient *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static const IMFTopologyServiceLookupClientVtbl video_presenter_service_client_vtbl = +{ + video_presenter_service_client_QueryInterface, + video_presenter_service_client_AddRef, + video_presenter_service_client_Release, + video_presenter_service_client_InitServicePointers, + video_presenter_service_client_ReleaseServicePointers, +}; + HRESULT WINAPI MFCreateVideoPresenter(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) { TRACE("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj); @@ -257,6 +310,7 @@ HRESULT evr_presenter_create(IUnknown *outer, void **out)
object->IMFVideoPresenter_iface.lpVtbl = &video_presenter_vtbl; object->IMFVideoDeviceID_iface.lpVtbl = &video_presenter_device_id_vtbl; + object->IMFTopologyServiceLookupClient_iface.lpVtbl = &video_presenter_service_client_vtbl; object->IUnknown_inner.lpVtbl = &video_presenter_inner_vtbl; object->outer_unk = outer ? outer : &object->IUnknown_inner; object->refcount = 1; diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 965b921937c..af9e6567101 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -870,6 +870,7 @@ static void test_default_presenter(void) { IMFVideoPresenter *presenter; IMFVideoDeviceID *deviceid; + IUnknown *unk; HRESULT hr; GUID iid;
@@ -893,6 +894,10 @@ static void test_default_presenter(void)
IMFVideoDeviceID_Release(deviceid);
+ hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&unk); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IUnknown_Release(unk); + IMFVideoPresenter_Release(presenter); }
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=74590
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/evr/presenter.c:35 error: patch failed: dlls/evr/tests/evr.c:870 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/evr/presenter.c:35 error: patch failed: dlls/evr/tests/evr.c:870 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/evr/presenter.c:35 error: patch failed: dlls/evr/tests/evr.c:870 Task: Patch failed to apply
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- include/evr.idl | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)
diff --git a/include/evr.idl b/include/evr.idl index 5a623c2c29c..384a051944c 100644 --- a/include/evr.idl +++ b/include/evr.idl @@ -218,6 +218,82 @@ interface IMFDesiredSample : IUnknown void Clear(); }
+[ + object, + uuid(a490b1e4-ab84-4d31-a1b2-181e03b1077a), +] +interface IMFVideoDisplayControl : IUnknown +{ + HRESULT GetNativeVideoSize( + [in, out, unique] SIZE *video_size, + [in, out, unique] SIZE *aspect_ratio + ); + + HRESULT GetIdealVideoSize( + [in, out, unique] SIZE *min_size, + [in, out, unique] SIZE *max_size + ); + + HRESULT SetVideoPosition( + [in, unique] const MFVideoNormalizedRect *source, + [in, unique] const RECT *dest + ); + + HRESULT GetVideoPosition( + [out] MFVideoNormalizedRect *source, + [out] RECT *dest + ); + + HRESULT SetAspectRatioMode( + [in] DWORD mode + ); + + HRESULT GetAspectRatioMode( + [out] DWORD *mode + ); + + HRESULT SetVideoWindow( + [in] HWND window + ); + + HRESULT GetVideoWindow( + [out] HWND *window + ); + + HRESULT RepaintVideo(); + + HRESULT GetCurrentImage( + [in, out] LPBITMAPINFOHEADER header, + [out, size_is(, *dib_size)] BYTE **dib, + [out] DWORD *dib_size, + [in, out, unique] LONGLONG *timestamp + ); + + HRESULT SetBorderColor( + [in] COLORREF color + ); + + HRESULT GetBorderColor( + [out] COLORREF *color + ); + + HRESULT SetRenderingPrefs( + [in] DWORD flags + ); + + HRESULT GetRenderingPrefs( + [out] DWORD *flags + ); + + HRESULT SetFullscreen( + [in] BOOL fullscreen + ); + + HRESULT GetFullscreen( + [out] BOOL *fullscreen + ); +} + cpp_quote("DEFINE_GUID(MR_VIDEO_RENDER_SERVICE, 0x1092a86c, 0xab1a, 0x459a, 0xa3, 0x36, 0x83, 0x1f, 0xbc, 0x4d, 0x11, 0xff);") cpp_quote("DEFINE_GUID(MR_VIDEO_MIXER_SERVICE, 0x073cd2fc, 0x6cf4, 0x40b7, 0x88, 0x59, 0xe8, 0x95, 0x52, 0xc8, 0x41, 0xf8);") cpp_quote("DEFINE_GUID(MR_VIDEO_ACCELERATION_SERVICE, 0xefef5175, 0x5c7d, 0x4ce2, 0xbb, 0xbd, 0x34, 0xff, 0x8b, 0xca, 0x65, 0x54);")
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=74591
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/evr/presenter.c:35 error: patch failed: dlls/evr/tests/evr.c:870 error: patch failed: include/evr.idl:218 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/evr/presenter.c:35 error: patch failed: dlls/evr/tests/evr.c:870 error: patch failed: include/evr.idl:218 Task: Patch failed to apply
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/presenter.c | 121 +++++++++++++++++++++++++++++++++++++++++++ dlls/evr/tests/evr.c | 4 ++ 2 files changed, 125 insertions(+)
diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index db2f85b46fd..cbe8b0d2ff4 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -36,6 +36,7 @@ struct video_presenter IMFVideoPresenter IMFVideoPresenter_iface; IMFVideoDeviceID IMFVideoDeviceID_iface; IMFTopologyServiceLookupClient IMFTopologyServiceLookupClient_iface; + IMFVideoDisplayControl IMFVideoDisplayControl_iface; IUnknown IUnknown_inner; IUnknown *outer_unk; LONG refcount; @@ -61,6 +62,11 @@ static struct video_presenter *impl_from_IMFTopologyServiceLookupClient(IMFTopol return CONTAINING_RECORD(iface, struct video_presenter, IMFTopologyServiceLookupClient_iface); }
+static struct video_presenter *impl_from_IMFVideoDisplayControl(IMFVideoDisplayControl *iface) +{ + return CONTAINING_RECORD(iface, struct video_presenter, IMFVideoDisplayControl_iface); +} + static HRESULT WINAPI video_presenter_inner_QueryInterface(IUnknown *iface, REFIID riid, void **obj) { struct video_presenter *presenter = impl_from_IUnknown(iface); @@ -84,6 +90,10 @@ static HRESULT WINAPI video_presenter_inner_QueryInterface(IUnknown *iface, REFI { *obj = &presenter->IMFTopologyServiceLookupClient_iface; } + else if (IsEqualIID(riid, &IID_IMFVideoDisplayControl)) + { + *obj = &presenter->IMFVideoDisplayControl_iface; + } else { WARN("Unimplemented interface %s.\n", debugstr_guid(riid)); @@ -289,6 +299,116 @@ static const IMFTopologyServiceLookupClientVtbl video_presenter_service_client_v video_presenter_service_client_ReleaseServicePointers, };
+static HRESULT WINAPI video_presenter_control_QueryInterface(IMFVideoDisplayControl *iface, REFIID riid, void **obj) +{ + struct video_presenter *presenter = impl_from_IMFVideoDisplayControl(iface); + return IMFVideoPresenter_QueryInterface(&presenter->IMFVideoPresenter_iface, riid, obj); +} + +static ULONG WINAPI video_presenter_control_AddRef(IMFVideoDisplayControl *iface) +{ + struct video_presenter *presenter = impl_from_IMFVideoDisplayControl(iface); + return IMFVideoPresenter_AddRef(&presenter->IMFVideoPresenter_iface); +} + +static ULONG WINAPI video_presenter_control_Release(IMFVideoDisplayControl *iface) +{ + struct video_presenter *presenter = impl_from_IMFVideoDisplayControl(iface); + return IMFVideoPresenter_Release(&presenter->IMFVideoPresenter_iface); +} + +static HRESULT WINAPI video_presenter_control_GetNativeVideoSize(IMFVideoDisplayControl *iface, SIZE *video_size, + SIZE *aspect_ratio) +{ + FIXME("%p, %p, %p.\n", iface, video_size, aspect_ratio); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_control_GetIdealVideoSize(IMFVideoDisplayControl *iface, SIZE *min_size, + SIZE *max_size) +{ + FIXME("%p, %p, %p.\n", iface, min_size, max_size); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_control_SetVideoPosition(IMFVideoDisplayControl *iface, + const MFVideoNormalizedRect *source, const RECT *dest) +{ + FIXME("%p, %p, %p.\n", iface, source, dest); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_control_GetVideoPosition(IMFVideoDisplayControl *iface, MFVideoNormalizedRect *source, + RECT *dest) +{ + FIXME("%p, %p, %p.\n", iface, source, dest); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_control_SetAspectRatioMode(IMFVideoDisplayControl *iface, DWORD mode) +{ + FIXME("%p, %d.\n", iface, mode); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_control_GetAspectRatioMode(IMFVideoDisplayControl *iface, DWORD *mode) +{ + FIXME("%p, %p.\n", iface, mode); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_control_SetVideoWindow(IMFVideoDisplayControl *iface, HWND window) +{ + FIXME("%p, %p.\n", iface, window); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_control_GetVideoWindow(IMFVideoDisplayControl *iface, HWND *window) +{ + FIXME("%p, %p.\n", iface, window); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_control_RepaintVideo(IMFVideoDisplayControl *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static HRESULT WINAPI video_presenter_control_GetCurrentImage(IMFVideoDisplayControl *iface, BITMAPINFOHEADER *header, + BYTE **dib, DWORD *dib_size, LONGLONG *timestamp) +{ + FIXME("%p, %p, %p, %p, %p.\n", iface, header, dib, dib_size, timestamp); + + return E_NOTIMPL; +} + +static const IMFVideoDisplayControlVtbl video_presenter_control_vtbl = +{ + video_presenter_control_QueryInterface, + video_presenter_control_AddRef, + video_presenter_control_Release, + video_presenter_control_GetNativeVideoSize, + video_presenter_control_GetIdealVideoSize, + video_presenter_control_SetVideoPosition, + video_presenter_control_GetVideoPosition, + video_presenter_control_SetAspectRatioMode, + video_presenter_control_GetAspectRatioMode, + video_presenter_control_SetVideoWindow, + video_presenter_control_GetVideoWindow, + video_presenter_control_RepaintVideo, + video_presenter_control_GetCurrentImage, +}; + HRESULT WINAPI MFCreateVideoPresenter(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj) { TRACE("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj); @@ -311,6 +431,7 @@ HRESULT evr_presenter_create(IUnknown *outer, void **out) object->IMFVideoPresenter_iface.lpVtbl = &video_presenter_vtbl; object->IMFVideoDeviceID_iface.lpVtbl = &video_presenter_device_id_vtbl; object->IMFTopologyServiceLookupClient_iface.lpVtbl = &video_presenter_service_client_vtbl; + object->IMFVideoDisplayControl_iface.lpVtbl = &video_presenter_control_vtbl; object->IUnknown_inner.lpVtbl = &video_presenter_inner_vtbl; object->outer_unk = outer ? outer : &object->IUnknown_inner; object->refcount = 1; diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index af9e6567101..037916fc4e1 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -898,6 +898,10 @@ static void test_default_presenter(void) ok(hr == S_OK, "Unexpected hr %#x.\n", hr); IUnknown_Release(unk);
+ hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&unk); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IUnknown_Release(unk); + IMFVideoPresenter_Release(presenter); }
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=74592
Your paranoid android.
=== build (build log) ===
error: patch failed: dlls/evr/presenter.c:35 error: patch failed: dlls/evr/tests/evr.c:870 error: patch failed: include/evr.idl:218 error: patch failed: dlls/evr/presenter.c:36 error: patch failed: dlls/evr/tests/evr.c:898 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/evr/presenter.c:35 error: patch failed: dlls/evr/tests/evr.c:870 error: patch failed: include/evr.idl:218 error: patch failed: dlls/evr/presenter.c:36 error: patch failed: dlls/evr/tests/evr.c:898 Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/evr/presenter.c:35 error: patch failed: dlls/evr/tests/evr.c:870 error: patch failed: include/evr.idl:218 error: patch failed: dlls/evr/presenter.c:36 error: patch failed: dlls/evr/tests/evr.c:898 Task: Patch failed to apply
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=74504
Your paranoid android.
=== debiant (32 bit report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:878: Test failed: Failed to create default presenter, hr 0x80040154.
=== debiant (32 bit French report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:878: Test failed: Failed to create default presenter, hr 0x80040154.
=== debiant (32 bit Japanese:Japan report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:878: Test failed: Failed to create default presenter, hr 0x80040154.
=== debiant (32 bit Chinese:China report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:878: Test failed: Failed to create default presenter, hr 0x80040154.
=== debiant (32 bit WoW report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:878: Test failed: Failed to create default presenter, hr 0x80040154.
=== debiant (64 bit WoW report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:878: Test failed: Failed to create default presenter, hr 0x80040154.
On 6/30/20 4:42 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=74504
Your paranoid android.
=== debiant (32 bit report) ===
evr: evr.c:180: Test failed: Unexpected hr 0x80040154. evr.c:184: Test failed: Unexpected hr 0x80040154. evr.c:878: Test failed: Failed to create default presenter, hr 0x80040154.
This is because prefix was not updated.