Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/tests/mediadet.c | 12 ++++++++++++ dlls/qedit/tests/samplegrabber.c | 12 ++++++++++++ dlls/qedit/tests/timeline.c | 12 ++++++++++++ 3 files changed, 36 insertions(+)
diff --git a/dlls/qedit/tests/mediadet.c b/dlls/qedit/tests/mediadet.c index 34c43fd295..311d77bfa0 100644 --- a/dlls/qedit/tests/mediadet.c +++ b/dlls/qedit/tests/mediadet.c @@ -647,6 +647,9 @@ static void test_COM_sg_enumpins(void)
START_TEST(mediadet) { + IMediaDet *detector; + HRESULT hr; + if (!init_tests()) { skip("Couldn't initialize tests!\n"); @@ -655,6 +658,15 @@ START_TEST(mediadet)
CoInitialize(NULL);
+ if (FAILED(hr = CoCreateInstance(&CLSID_MediaDet, NULL, CLSCTX_INPROC_SERVER, + &IID_IMediaDet, (void **)&detector))) + { + /* qedit.dll does not exist on 2003. */ + win_skip("Failed to create media detector object, hr %#x.\n", hr); + return; + } + IMediaDet_Release(detector); + test_aggregation(); test_mediadet(); test_samplegrabber(); diff --git a/dlls/qedit/tests/samplegrabber.c b/dlls/qedit/tests/samplegrabber.c index 22f6ddb673..8bc44b9c22 100644 --- a/dlls/qedit/tests/samplegrabber.c +++ b/dlls/qedit/tests/samplegrabber.c @@ -451,8 +451,20 @@ static void test_aggregation(void)
START_TEST(samplegrabber) { + IBaseFilter *filter; + HRESULT hr; + CoInitialize(NULL);
+ if (FAILED(hr = CoCreateInstance(&CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&filter))) + { + /* qedit.dll does not exist on 2003. */ + win_skip("Failed to create sample grabber filter, hr %#x.\n", hr); + return; + } + IBaseFilter_Release(filter); + test_interfaces(); test_enum_pins(); test_find_pin(); diff --git a/dlls/qedit/tests/timeline.c b/dlls/qedit/tests/timeline.c index 9e24062a9d..0d01d519fd 100644 --- a/dlls/qedit/tests/timeline.c +++ b/dlls/qedit/tests/timeline.c @@ -246,8 +246,20 @@ static void test_timelineobj_interfaces(void)
START_TEST(timeline) { + IAMTimeline *timeline; + HRESULT hr; + CoInitialize(NULL);
+ if (FAILED(hr = CoCreateInstance(&CLSID_AMTimeline, NULL, CLSCTX_INPROC_SERVER, + &IID_IAMTimeline, (void **)&timeline))) + { + /* qedit.dll does not exist on 2003. */ + win_skip("Failed to create timeline object, hr %#x.\n", hr); + return; + } + IAMTimeline_Release(timeline); + test_aggregation(); test_timeline(); test_timelineobj_interfaces();
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/tests/Makefile.in | 1 + dlls/qedit/tests/nullrenderer.c | 95 +++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 dlls/qedit/tests/nullrenderer.c
diff --git a/dlls/qedit/tests/Makefile.in b/dlls/qedit/tests/Makefile.in index 052336d64d..53d95d774c 100644 --- a/dlls/qedit/tests/Makefile.in +++ b/dlls/qedit/tests/Makefile.in @@ -3,6 +3,7 @@ IMPORTS = oleaut32 ole32
C_SRCS = \ mediadet.c \ + nullrenderer.c \ samplegrabber.c \ timeline.c
diff --git a/dlls/qedit/tests/nullrenderer.c b/dlls/qedit/tests/nullrenderer.c new file mode 100644 index 0000000000..025a258481 --- /dev/null +++ b/dlls/qedit/tests/nullrenderer.c @@ -0,0 +1,95 @@ +/* + * Null renderer filter unit tests + * + * Copyright 2018 Zebediah Figura + * + * 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 "dshow.h" +#include "wine/test.h" + +static IBaseFilter *create_null_renderer(void) +{ + IBaseFilter *filter = NULL; + HRESULT hr = CoCreateInstance(&CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + return filter; +} + +#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) +static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported) +{ + IUnknown *iface = iface_ptr; + HRESULT hr, expected_hr; + IUnknown *unk; + + expected_hr = supported ? S_OK : E_NOINTERFACE; + + hr = IUnknown_QueryInterface(iface, iid, (void **)&unk); + ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr); + if (SUCCEEDED(hr)) + IUnknown_Release(unk); +} + +static void test_interfaces(void) +{ + IBaseFilter *filter = create_null_renderer(); + ULONG ref; + + check_interface(filter, &IID_IBaseFilter, TRUE); + check_interface(filter, &IID_IMediaFilter, TRUE); + check_interface(filter, &IID_IMediaPosition, TRUE); + check_interface(filter, &IID_IMediaSeeking, TRUE); + check_interface(filter, &IID_IPersist, TRUE); + check_interface(filter, &IID_IUnknown, TRUE); + + todo_wine check_interface(filter, &IID_IAMFilterMiscFlags, FALSE); + check_interface(filter, &IID_IBasicAudio, FALSE); + check_interface(filter, &IID_IBasicVideo, FALSE); + check_interface(filter, &IID_IKsPropertySet, FALSE); + check_interface(filter, &IID_IPersistPropertyBag, FALSE); + check_interface(filter, &IID_IPin, FALSE); + todo_wine check_interface(filter, &IID_IQualityControl, FALSE); + check_interface(filter, &IID_IQualProp, FALSE); + check_interface(filter, &IID_IReferenceClock, FALSE); + check_interface(filter, &IID_IVideoWindow, FALSE); + + ref = IBaseFilter_Release(filter); + ok(!ref, "Got unexpected refcount %d.\n", ref); +} + +START_TEST(nullrenderer) +{ + IBaseFilter *filter; + HRESULT hr; + + CoInitialize(NULL); + + if (FAILED(hr = CoCreateInstance(&CLSID_NullRenderer, NULL, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&filter))) + { + /* qedit.dll does not exist on 2003. */ + win_skip("Failed to create null renderer filter, hr %#x.\n", hr); + return; + } + IBaseFilter_Release(filter); + + test_interfaces(); + + CoUninitialize(); +}
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=51134
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/tests/nullrenderer.c | 98 +++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+)
diff --git a/dlls/qedit/tests/nullrenderer.c b/dlls/qedit/tests/nullrenderer.c index 025a258481..5bdfc184ef 100644 --- a/dlls/qedit/tests/nullrenderer.c +++ b/dlls/qedit/tests/nullrenderer.c @@ -31,6 +31,13 @@ static IBaseFilter *create_null_renderer(void) return filter; }
+static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported) { @@ -73,6 +80,96 @@ static void test_interfaces(void) ok(!ref, "Got unexpected refcount %d.\n", ref); }
+static void test_enum_pins(void) +{ + IBaseFilter *filter = create_null_renderer(); + IEnumPins *enum1, *enum2; + ULONG count, ref; + IPin *pins[2]; + HRESULT hr; + + ref = get_refcount(filter); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + + hr = IBaseFilter_EnumPins(filter, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + hr = IBaseFilter_EnumPins(filter, &enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ref = get_refcount(filter); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(enum1); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + + hr = IEnumPins_Next(enum1, 1, NULL, NULL); + ok(hr == E_POINTER, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ref = get_refcount(filter); + todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(pins[0]); + todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(enum1); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + IPin_Release(pins[0]); + ref = get_refcount(filter); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 1, pins, &count); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(count == 1, "Got count %u.\n", count); + IPin_Release(pins[0]); + + hr = IEnumPins_Next(enum1, 1, pins, &count); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(!count, "Got count %u.\n", count); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 2, pins, NULL); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 2, pins, &count); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(count == 1, "Got count %u.\n", count); + IPin_Release(pins[0]); + + hr = IEnumPins_Reset(enum1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Clone(enum1, &enum2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Skip(enum1, 2); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Skip(enum1, 1); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IEnumPins_Skip(enum1, 1); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum1, 1, pins, NULL); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); + + hr = IEnumPins_Next(enum2, 1, pins, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + IPin_Release(pins[0]); + + IEnumPins_Release(enum2); + IEnumPins_Release(enum1); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + START_TEST(nullrenderer) { IBaseFilter *filter; @@ -90,6 +187,7 @@ START_TEST(nullrenderer) IBaseFilter_Release(filter);
test_interfaces(); + test_enum_pins();
CoUninitialize(); }
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=51135
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/tests/nullrenderer.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
diff --git a/dlls/qedit/tests/nullrenderer.c b/dlls/qedit/tests/nullrenderer.c index 5bdfc184ef..f709d2a206 100644 --- a/dlls/qedit/tests/nullrenderer.c +++ b/dlls/qedit/tests/nullrenderer.c @@ -22,6 +22,8 @@ #include "dshow.h" #include "wine/test.h"
+static const WCHAR sink_id[] = {'I','n',0}; + static IBaseFilter *create_null_renderer(void) { IBaseFilter *filter = NULL; @@ -170,6 +172,34 @@ static void test_enum_pins(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void test_find_pin(void) +{ + static const WCHAR input_pinW[] = {'i','n','p','u','t',' ','p','i','n',0}; + IBaseFilter *filter = create_null_renderer(); + IEnumPins *enum_pins; + IPin *pin, *pin2; + HRESULT hr; + ULONG ref; + + hr = IBaseFilter_FindPin(filter, input_pinW, &pin); + ok(hr == VFW_E_NOT_FOUND, "Got hr %#x.\n", hr); + + hr = IBaseFilter_EnumPins(filter, &enum_pins); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IBaseFilter_FindPin(filter, sink_id, &pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IEnumPins_Next(enum_pins, 1, &pin2, NULL); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(pin2 == pin, "Expected pin %p, got %p.\n", pin, pin2); + IPin_Release(pin2); + IPin_Release(pin); + + IEnumPins_Release(enum_pins); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + START_TEST(nullrenderer) { IBaseFilter *filter; @@ -188,6 +218,7 @@ START_TEST(nullrenderer)
test_interfaces(); test_enum_pins(); + test_find_pin();
CoUninitialize(); }
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=51136
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/tests/nullrenderer.c | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+)
diff --git a/dlls/qedit/tests/nullrenderer.c b/dlls/qedit/tests/nullrenderer.c index f709d2a206..97938600af 100644 --- a/dlls/qedit/tests/nullrenderer.c +++ b/dlls/qedit/tests/nullrenderer.c @@ -200,6 +200,51 @@ static void test_find_pin(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static void test_pin_info(void) +{ + IBaseFilter *filter = create_null_renderer(); + PIN_DIRECTION dir; + PIN_INFO info; + HRESULT hr; + WCHAR *id; + ULONG ref; + IPin *pin; + + hr = IBaseFilter_FindPin(filter, sink_id, &pin); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ref = get_refcount(filter); + todo_wine ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(pin); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + + hr = IPin_QueryPinInfo(pin, &info); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(info.pFilter == filter, "Expected filter %p, got %p.\n", filter, info.pFilter); + ok(info.dir == PINDIR_INPUT, "Got direction %d.\n", info.dir); + ok(!lstrcmpW(info.achName, sink_id), "Got name %s.\n", wine_dbgstr_w(info.achName)); + ref = get_refcount(filter); + todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); + ref = get_refcount(pin); + todo_wine ok(ref == 3, "Got unexpected refcount %d.\n", ref); + IBaseFilter_Release(info.pFilter); + + hr = IPin_QueryDirection(pin, &dir); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(dir == PINDIR_INPUT, "Got direction %d.\n", dir); + + hr = IPin_QueryId(pin, &id); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(!lstrcmpW(id, sink_id), "Got id %s.\n", wine_dbgstr_w(id)); + CoTaskMemFree(id); + + hr = IPin_QueryInternalConnections(pin, NULL, NULL); + ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr); + + IPin_Release(pin); + ref = IBaseFilter_Release(filter); + ok(!ref, "Got outstanding refcount %d.\n", ref); +} + START_TEST(nullrenderer) { IBaseFilter *filter; @@ -219,6 +264,7 @@ START_TEST(nullrenderer) test_interfaces(); test_enum_pins(); test_find_pin(); + test_pin_info();
CoUninitialize(); }
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=51137
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/tests/nullrenderer.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/dlls/qedit/tests/nullrenderer.c b/dlls/qedit/tests/nullrenderer.c index 97938600af..be38e5ffd6 100644 --- a/dlls/qedit/tests/nullrenderer.c +++ b/dlls/qedit/tests/nullrenderer.c @@ -59,6 +59,7 @@ static void test_interfaces(void) { IBaseFilter *filter = create_null_renderer(); ULONG ref; + IPin *pin;
check_interface(filter, &IID_IBaseFilter, TRUE); check_interface(filter, &IID_IMediaFilter, TRUE); @@ -78,6 +79,18 @@ static void test_interfaces(void) check_interface(filter, &IID_IReferenceClock, FALSE); check_interface(filter, &IID_IVideoWindow, FALSE);
+ IBaseFilter_FindPin(filter, sink_id, &pin); + + check_interface(pin, &IID_IMemInputPin, TRUE); + check_interface(pin, &IID_IPin, TRUE); + todo_wine check_interface(pin, &IID_IQualityControl, TRUE); + check_interface(pin, &IID_IUnknown, TRUE); + + check_interface(pin, &IID_IKsPropertySet, FALSE); + check_interface(pin, &IID_IMediaPosition, FALSE); + todo_wine check_interface(pin, &IID_IMediaSeeking, FALSE); + + IPin_Release(pin); ref = IBaseFilter_Release(filter); ok(!ref, "Got unexpected refcount %d.\n", ref); }
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=51138
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/qedit/tests/nullrenderer.c | 95 +++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+)
diff --git a/dlls/qedit/tests/nullrenderer.c b/dlls/qedit/tests/nullrenderer.c index be38e5ffd6..0ae17b17b6 100644 --- a/dlls/qedit/tests/nullrenderer.c +++ b/dlls/qedit/tests/nullrenderer.c @@ -258,6 +258,100 @@ static void test_pin_info(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static const GUID test_iid = {0x33333333}; +static LONG outer_ref = 1; + +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IBaseFilter) + || IsEqualGUID(iid, &test_iid)) + { + *out = (IUnknown *)0xdeadbeef; + return S_OK; + } + ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI outer_AddRef(IUnknown *iface) +{ + return InterlockedIncrement(&outer_ref); +} + +static ULONG WINAPI outer_Release(IUnknown *iface) +{ + return InterlockedDecrement(&outer_ref); +} + +static const IUnknownVtbl outer_vtbl = +{ + outer_QueryInterface, + outer_AddRef, + outer_Release, +}; + +static IUnknown test_outer = {&outer_vtbl}; + +static void test_aggregation(void) +{ + IBaseFilter *filter, *filter2; + IUnknown *unk, *unk2; + HRESULT hr; + ULONG ref; + + filter = (IBaseFilter *)0xdeadbeef; + hr = CoCreateInstance(&CLSID_NullRenderer, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&filter); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!filter, "Got interface %p.\n", filter); + + hr = CoCreateInstance(&CLSID_NullRenderer, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&unk); + ok(hr == S_OK, "Got hr %#x.\n", 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); + + ref = IUnknown_AddRef(unk); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + ref = IUnknown_Release(unk); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2); + IUnknown_Release(unk2); + + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2); + + hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!unk2, "Got unexpected IUnknown %p.\n", unk2); + + hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + IBaseFilter_Release(filter); + ref = IUnknown_Release(unk); + ok(!ref, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); +} + START_TEST(nullrenderer) { IBaseFilter *filter; @@ -278,6 +372,7 @@ START_TEST(nullrenderer) test_enum_pins(); test_find_pin(); test_pin_info(); + test_aggregation();
CoUninitialize(); }
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=51139
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/Makefile.in | 1 - dlls/quartz/tests/filtergraph.c | 139 +++++++++--------- dlls/quartz/tests/filtermapper.c | 159 ++++++++++---------- dlls/quartz/tests/misc.c | 233 ------------------------------ dlls/quartz/tests/videorenderer.c | 94 ++++++++++++ dlls/quartz/tests/vmr7.c | 95 ++++++++++++ dlls/quartz/tests/vmr9.c | 95 ++++++++++++ 7 files changed, 442 insertions(+), 374 deletions(-) delete mode 100644 dlls/quartz/tests/misc.c
diff --git a/dlls/quartz/tests/Makefile.in b/dlls/quartz/tests/Makefile.in index 59124c32af..2ba32921e1 100644 --- a/dlls/quartz/tests/Makefile.in +++ b/dlls/quartz/tests/Makefile.in @@ -10,7 +10,6 @@ C_SRCS = \ filtergraph.c \ filtermapper.c \ memallocator.c \ - misc.c \ mpegsplit.c \ systemclock.c \ videorenderer.c \ diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c index f0e4b58cb3..6b6d8aeb20 100644 --- a/dlls/quartz/tests/filtergraph.c +++ b/dlls/quartz/tests/filtergraph.c @@ -78,6 +78,13 @@ static IFilterGraph2 *create_graph(void) return ret; }
+static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + #define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported) { @@ -2291,96 +2298,98 @@ out: ok(parser3_pins[1].ref == 1, "Got outstanding refcount %d.\n", parser3_pins[1].ref); }
-typedef struct IUnknownImpl -{ - IUnknown IUnknown_iface; - int AddRef_called; - int Release_called; -} IUnknownImpl; - -static IUnknownImpl *IUnknownImpl_from_iface(IUnknown * iface) -{ - return CONTAINING_RECORD(iface, IUnknownImpl, IUnknown_iface); -} +static const GUID test_iid = {0x33333333}; +static LONG outer_ref = 1;
-static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv) +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out) { - ok(0, "QueryInterface should not be called for %s\n", wine_dbgstr_guid(riid)); + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IFilterGraph2) + || IsEqualGUID(iid, &test_iid)) + { + *out = (IUnknown *)0xdeadbeef; + return S_OK; + } + ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid)); return E_NOINTERFACE; }
-static ULONG WINAPI IUnknownImpl_AddRef(IUnknown * iface) +static ULONG WINAPI outer_AddRef(IUnknown *iface) { - IUnknownImpl *This = IUnknownImpl_from_iface(iface); - This->AddRef_called++; - return 2; + return InterlockedIncrement(&outer_ref); }
-static ULONG WINAPI IUnknownImpl_Release(IUnknown * iface) +static ULONG WINAPI outer_Release(IUnknown *iface) { - IUnknownImpl *This = IUnknownImpl_from_iface(iface); - This->Release_called++; - return 1; + return InterlockedDecrement(&outer_ref); }
-static CONST_VTBL IUnknownVtbl IUnknownImpl_Vtbl = +static const IUnknownVtbl outer_vtbl = { - IUnknownImpl_QueryInterface, - IUnknownImpl_AddRef, - IUnknownImpl_Release + outer_QueryInterface, + outer_AddRef, + outer_Release, };
-static void test_aggregate_filter_graph(void) +static IUnknown test_outer = {&outer_vtbl}; + +static void test_aggregation(void) { + IFilterGraph2 *graph, *graph2; + IUnknown *unk, *unk2; HRESULT hr; - IUnknown *pgraph; - IUnknown *punk; - IUnknownImpl unk_outer = { { &IUnknownImpl_Vtbl }, 0, 0 }; + ULONG ref;
- hr = CoCreateInstance(&CLSID_FilterGraph, &unk_outer.IUnknown_iface, CLSCTX_INPROC_SERVER, - &IID_IUnknown, (void **)&pgraph); - ok(hr == S_OK, "CoCreateInstance returned %x\n", hr); - ok(pgraph != &unk_outer.IUnknown_iface, "pgraph = %p, expected not %p\n", pgraph, &unk_outer.IUnknown_iface); + graph = (IFilterGraph2 *)0xdeadbeef; + hr = CoCreateInstance(&CLSID_FilterGraph, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IFilterGraph2, (void **)&graph); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!graph, "Got interface %p.\n", graph);
- hr = IUnknown_QueryInterface(pgraph, &IID_IUnknown, (void **)&punk); - ok(hr == S_OK, "CoCreateInstance returned %x\n", hr); - ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface); - IUnknown_Release(punk); + hr = CoCreateInstance(&CLSID_FilterGraph, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&unk); + ok(hr == S_OK, "Got hr %#x.\n", 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);
- ok(unk_outer.AddRef_called == 0, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called); - ok(unk_outer.Release_called == 0, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called); - unk_outer.AddRef_called = 0; - unk_outer.Release_called = 0; + ref = IUnknown_AddRef(unk); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
- hr = IUnknown_QueryInterface(pgraph, &IID_IFilterMapper, (void **)&punk); - ok(hr == S_OK, "CoCreateInstance returned %x\n", hr); - ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface); - IUnknown_Release(punk); + ref = IUnknown_Release(unk); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref);
- ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called); - ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called); - unk_outer.AddRef_called = 0; - unk_outer.Release_called = 0; + hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2); + IUnknown_Release(unk2);
- hr = IUnknown_QueryInterface(pgraph, &IID_IFilterMapper2, (void **)&punk); - ok(hr == S_OK, "CoCreateInstance returned %x\n", hr); - ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface); - IUnknown_Release(punk); + hr = IUnknown_QueryInterface(unk, &IID_IFilterGraph2, (void **)&graph); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called); - ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called); - unk_outer.AddRef_called = 0; - unk_outer.Release_called = 0; + hr = IFilterGraph2_QueryInterface(graph, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2);
- hr = IUnknown_QueryInterface(pgraph, &IID_IFilterMapper3, (void **)&punk); - ok(hr == S_OK, "CoCreateInstance returned %x\n", hr); - ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface); - IUnknown_Release(punk); + hr = IFilterGraph2_QueryInterface(graph, &IID_IFilterGraph2, (void **)&graph2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(graph2 == (IFilterGraph2 *)0xdeadbeef, "Got unexpected IFilterGraph2 %p.\n", graph2);
- ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called); - ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called); + hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!unk2, "Got unexpected IUnknown %p.\n", unk2);
- IUnknown_Release(pgraph); + hr = IFilterGraph2_QueryInterface(graph, &test_iid, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + IFilterGraph2_Release(graph); + ref = IUnknown_Release(unk); + ok(!ref, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); }
/* Test how methods from "control" interfaces (IBasicAudio, IBasicVideo, @@ -3220,7 +3229,7 @@ START_TEST(filtergraph) test_enum_filters(); test_graph_builder_render(); test_graph_builder_connect(); - test_aggregate_filter_graph(); + test_aggregation(); test_control_delegation(); test_add_remove_filter(); test_connect_direct(); diff --git a/dlls/quartz/tests/filtermapper.c b/dlls/quartz/tests/filtermapper.c index fc4fa95fa4..1f7080965f 100644 --- a/dlls/quartz/tests/filtermapper.c +++ b/dlls/quartz/tests/filtermapper.c @@ -27,6 +27,13 @@ #include "initguid.h" #include "wine/fil_data.h"
+static ULONG get_refcount(void *iface) +{ + IUnknown *unknown = iface; + IUnknown_AddRef(unknown); + return IUnknown_Release(unknown); +} + /* Helper function, checks if filter with given name was enumerated. */ static BOOL enum_find_filter(const WCHAR *wszFilterName, IEnumMoniker *pEnum) { @@ -527,96 +534,98 @@ out: IFilterMapper2_Release(pMapper); }
-typedef struct IUnknownImpl -{ - IUnknown IUnknown_iface; - int AddRef_called; - int Release_called; -} IUnknownImpl; - -static IUnknownImpl *IUnknownImpl_from_iface(IUnknown * iface) -{ - return CONTAINING_RECORD(iface, IUnknownImpl, IUnknown_iface); -} +static const GUID test_iid = {0x33333333}; +static LONG outer_ref = 1;
-static HRESULT WINAPI IUnknownImpl_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv) +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out) { - ok(0, "QueryInterface should not be called for %s\n", wine_dbgstr_guid(riid)); + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IFilterMapper3) + || IsEqualGUID(iid, &test_iid)) + { + *out = (IUnknown *)0xdeadbeef; + return S_OK; + } + ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid)); return E_NOINTERFACE; }
-static ULONG WINAPI IUnknownImpl_AddRef(IUnknown * iface) +static ULONG WINAPI outer_AddRef(IUnknown *iface) { - IUnknownImpl *This = IUnknownImpl_from_iface(iface); - This->AddRef_called++; - return 2; + return InterlockedIncrement(&outer_ref); }
-static ULONG WINAPI IUnknownImpl_Release(IUnknown * iface) +static ULONG WINAPI outer_Release(IUnknown *iface) { - IUnknownImpl *This = IUnknownImpl_from_iface(iface); - This->Release_called++; - return 1; + return InterlockedDecrement(&outer_ref); }
-static CONST_VTBL IUnknownVtbl IUnknownImpl_Vtbl = +static const IUnknownVtbl outer_vtbl = { - IUnknownImpl_QueryInterface, - IUnknownImpl_AddRef, - IUnknownImpl_Release + outer_QueryInterface, + outer_AddRef, + outer_Release, };
-static void test_aggregate_filter_mapper(void) +static IUnknown test_outer = {&outer_vtbl}; + +static void test_aggregation(void) { + IFilterMapper3 *mapper, *mapper2; + IUnknown *unk, *unk2; HRESULT hr; - IUnknown *pmapper; - IUnknown *punk; - IUnknownImpl unk_outer = { { &IUnknownImpl_Vtbl }, 0, 0 }; - - hr = CoCreateInstance(&CLSID_FilterMapper2, &unk_outer.IUnknown_iface, CLSCTX_INPROC_SERVER, - &IID_IUnknown, (void **)&pmapper); - ok(hr == S_OK, "CoCreateInstance returned %x\n", hr); - ok(pmapper != &unk_outer.IUnknown_iface, "pmapper = %p, expected not %p\n", pmapper, &unk_outer.IUnknown_iface); - - hr = IUnknown_QueryInterface(pmapper, &IID_IUnknown, (void **)&punk); - ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); - ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface); - IUnknown_Release(punk); - - ok(unk_outer.AddRef_called == 0, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called); - ok(unk_outer.Release_called == 0, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called); - unk_outer.AddRef_called = 0; - unk_outer.Release_called = 0; - - hr = IUnknown_QueryInterface(pmapper, &IID_IFilterMapper, (void **)&punk); - ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); - ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface); - IUnknown_Release(punk); - - ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called); - ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called); - unk_outer.AddRef_called = 0; - unk_outer.Release_called = 0; - - hr = IUnknown_QueryInterface(pmapper, &IID_IFilterMapper2, (void **)&punk); - ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); - ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface); - IUnknown_Release(punk); - - ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called); - ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called); - unk_outer.AddRef_called = 0; - unk_outer.Release_called = 0; - - hr = IUnknown_QueryInterface(pmapper, &IID_IFilterMapper3, (void **)&punk); - ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); - ok(punk != &unk_outer.IUnknown_iface, "punk = %p, expected not %p\n", punk, &unk_outer.IUnknown_iface); - IUnknown_Release(punk); - - ok(unk_outer.AddRef_called == 1, "IUnknownImpl_AddRef called %d times\n", unk_outer.AddRef_called); - ok(unk_outer.Release_called == 1, "IUnknownImpl_Release called %d times\n", unk_outer.Release_called); - - IUnknown_Release(pmapper); + ULONG ref; + + mapper = (IFilterMapper3 *)0xdeadbeef; + hr = CoCreateInstance(&CLSID_FilterMapper2, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IFilterMapper3, (void **)&mapper); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!mapper, "Got interface %p.\n", mapper); + + hr = CoCreateInstance(&CLSID_FilterMapper2, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&unk); + ok(hr == S_OK, "Got hr %#x.\n", 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); + + ref = IUnknown_AddRef(unk); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + ref = IUnknown_Release(unk); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2); + IUnknown_Release(unk2); + + hr = IUnknown_QueryInterface(unk, &IID_IFilterMapper3, (void **)&mapper); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IFilterMapper3_QueryInterface(mapper, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + hr = IFilterMapper3_QueryInterface(mapper, &IID_IFilterMapper3, (void **)&mapper2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(mapper2 == (IFilterMapper3 *)0xdeadbeef, "Got unexpected IFilterMapper3 %p.\n", mapper2); + + hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!unk2, "Got unexpected IUnknown %p.\n", unk2); + + hr = IFilterMapper3_QueryInterface(mapper, &test_iid, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + IFilterMapper3_Release(mapper); + ref = IUnknown_Release(unk); + ok(!ref, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); }
START_TEST(filtermapper) @@ -628,7 +637,7 @@ START_TEST(filtermapper) test_ifiltermapper_from_filtergraph(); test_register_filter_with_null_clsMinorType(); test_parse_filter_data(); - test_aggregate_filter_mapper(); + test_aggregation();
CoUninitialize(); } diff --git a/dlls/quartz/tests/misc.c b/dlls/quartz/tests/misc.c deleted file mode 100644 index 16b6d40ce4..0000000000 --- a/dlls/quartz/tests/misc.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Misc unit tests for Quartz - * - * Copyright (C) 2007 Google (Lei Zhang) - * - * 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 "wine/test.h" -#include "dshow.h" - -#define QI_SUCCEED(iface, riid, ppv) hr = IUnknown_QueryInterface(iface, &riid, (LPVOID*)&ppv); \ - ok(hr == S_OK, "IUnknown_QueryInterface returned %x\n", hr); \ - ok(ppv != NULL, "Pointer is NULL\n"); - -#define QI_FAIL(iface, riid, ppv) hr = IUnknown_QueryInterface(iface, &riid, (LPVOID*)&ppv); \ - ok(hr == E_NOINTERFACE, "IUnknown_QueryInterface returned %x\n", hr); \ - ok(ppv == NULL, "Pointer is %p\n", ppv); - -#define ADDREF_EXPECT(iface, num) if (iface) { \ - refCount = IUnknown_AddRef(iface); \ - ok(refCount == num, "IUnknown_AddRef should return %d, got %d\n", num, refCount); \ -} - -#define RELEASE_EXPECT(iface, num) if (iface) { \ - refCount = IUnknown_Release(iface); \ - ok(refCount == num, "IUnknown_Release should return %d, got %d\n", num, refCount); \ -} - -static void test_aggregation(const CLSID clsidOuter, const CLSID clsidInner, - const IID iidOuter, const IID iidInner) -{ - HRESULT hr; - ULONG refCount; - IUnknown *pUnkOuter = NULL; - IUnknown *pUnkInner = NULL; - IUnknown *pUnkInnerFail = NULL; - IUnknown *pUnkOuterTest = NULL; - IUnknown *pUnkInnerTest = NULL; - IUnknown *pUnkAggregatee = NULL; - IUnknown *pUnkAggregator = NULL; - IUnknown *pUnkTest = NULL; - - hr = CoCreateInstance(&clsidOuter, NULL, CLSCTX_INPROC_SERVER, - &IID_IUnknown, (LPVOID*)&pUnkOuter); - ok(hr == S_OK, "CoCreateInstance failed with %x\n", hr); - ok(pUnkOuter != NULL, "pUnkOuter is NULL\n"); - - if (!pUnkOuter) - { - skip("pUnkOuter is NULL\n"); - return; - } - - /* for aggregation, we should only be able to request IUnknown */ - hr = CoCreateInstance(&clsidInner, pUnkOuter, CLSCTX_INPROC_SERVER, - &iidInner, (LPVOID*)&pUnkInnerFail); - if (hr == REGDB_E_CLASSNOTREG) - { - skip("Class not registered\n"); - return; - } - ok(hr == E_NOINTERFACE, "CoCreateInstance returned %x\n", hr); - ok(pUnkInnerFail == NULL, "pUnkInnerFail is not NULL\n"); - - /* aggregation, request IUnknown */ - hr = CoCreateInstance(&clsidInner, pUnkOuter, CLSCTX_INPROC_SERVER, - &IID_IUnknown, (LPVOID*)&pUnkInner); - ok(hr == S_OK, "CoCreateInstance returned %x\n", hr); - ok(pUnkInner != NULL, "pUnkInner is NULL\n"); - - if (!pUnkInner) - { - skip("pUnkInner is NULL\n"); - return; - } - - ADDREF_EXPECT(pUnkOuter, 2); - ADDREF_EXPECT(pUnkInner, 2); - RELEASE_EXPECT(pUnkOuter, 1); - RELEASE_EXPECT(pUnkInner, 1); - - QI_FAIL(pUnkOuter, iidInner, pUnkAggregatee); - QI_FAIL(pUnkInner, iidOuter, pUnkAggregator); - - /* these QueryInterface calls should work */ - QI_SUCCEED(pUnkOuter, iidOuter, pUnkAggregator); - QI_SUCCEED(pUnkOuter, IID_IUnknown, pUnkOuterTest); - /* IGraphConfig interface comes with DirectShow 9 */ - if(IsEqualGUID(&IID_IGraphConfig, &iidInner)) - { - hr = IUnknown_QueryInterface(pUnkInner, &iidInner, (LPVOID*)&pUnkAggregatee); - ok(hr == S_OK || broken(hr == E_NOINTERFACE), "IUnknown_QueryInterface returned %x\n", hr); - ok(pUnkAggregatee != NULL || broken(!pUnkAggregatee), "Pointer is NULL\n"); - } - else - { - QI_SUCCEED(pUnkInner, iidInner, pUnkAggregatee); - } - QI_SUCCEED(pUnkInner, IID_IUnknown, pUnkInnerTest); - - if (!pUnkAggregator || !pUnkOuterTest || !pUnkAggregatee - || !pUnkInnerTest) - { - skip("One of the required interfaces is NULL\n"); - return; - } - - ADDREF_EXPECT(pUnkAggregator, 5); - ADDREF_EXPECT(pUnkOuterTest, 6); - ADDREF_EXPECT(pUnkAggregatee, 7); - ADDREF_EXPECT(pUnkInnerTest, 3); - RELEASE_EXPECT(pUnkAggregator, 6); - RELEASE_EXPECT(pUnkOuterTest, 5); - RELEASE_EXPECT(pUnkAggregatee, 4); - RELEASE_EXPECT(pUnkInnerTest, 2); - - QI_SUCCEED(pUnkAggregator, IID_IUnknown, pUnkTest); - QI_SUCCEED(pUnkOuterTest, IID_IUnknown, pUnkTest); - QI_SUCCEED(pUnkAggregatee, IID_IUnknown, pUnkTest); - QI_SUCCEED(pUnkInnerTest, IID_IUnknown, pUnkTest); - - QI_FAIL(pUnkAggregator, iidInner, pUnkTest); - QI_FAIL(pUnkOuterTest, iidInner, pUnkTest); - QI_FAIL(pUnkAggregatee, iidInner, pUnkTest); - QI_SUCCEED(pUnkInnerTest, iidInner, pUnkTest); - - QI_SUCCEED(pUnkAggregator, iidOuter, pUnkTest); - QI_SUCCEED(pUnkOuterTest, iidOuter, pUnkTest); - QI_SUCCEED(pUnkAggregatee, iidOuter, pUnkTest); - QI_FAIL(pUnkInnerTest, iidOuter, pUnkTest); - - RELEASE_EXPECT(pUnkAggregator, 10); - RELEASE_EXPECT(pUnkOuterTest, 9); - RELEASE_EXPECT(pUnkAggregatee, 8); - RELEASE_EXPECT(pUnkInnerTest, 2); - RELEASE_EXPECT(pUnkOuter, 7); - RELEASE_EXPECT(pUnkInner, 1); - - do - { - refCount = IUnknown_Release(pUnkInner); - } while (refCount); - - do - { - refCount = IUnknown_Release(pUnkOuter); - } while (refCount); -} - -static void test_null_renderer_aggregations(void) -{ - const IID * iids[] = { - &IID_IMediaFilter, &IID_IBaseFilter - }; - int i; - - for (i = 0; i < ARRAY_SIZE(iids); i++) - { - test_aggregation(CLSID_SystemClock, CLSID_NullRenderer, IID_IReferenceClock, *iids[i]); - } -} - -static void test_video_renderer_aggregations(void) -{ - const IID * iids[] = { - &IID_IMediaFilter, &IID_IBaseFilter, &IID_IBasicVideo, &IID_IVideoWindow - }; - int i; - - for (i = 0; i < ARRAY_SIZE(iids); i++) - { - test_aggregation(CLSID_SystemClock, CLSID_VideoRenderer, - IID_IReferenceClock, *iids[i]); - } -} - -static void test_filter_graph_aggregations(void) -{ - const IID * iids[] = { - &IID_IFilterGraph2, &IID_IMediaControl, &IID_IGraphBuilder, - &IID_IFilterGraph, &IID_IMediaSeeking, &IID_IBasicAudio, &IID_IBasicVideo, - &IID_IVideoWindow, &IID_IMediaEventEx, &IID_IMediaFilter, - &IID_IMediaEventSink, &IID_IGraphConfig, &IID_IMediaPosition - }; - int i; - - for (i = 0; i < ARRAY_SIZE(iids); i++) - { - test_aggregation(CLSID_SystemClock, CLSID_FilterGraph, - IID_IReferenceClock, *iids[i]); - } -} - -static void test_filter_mapper_aggregations(void) -{ - const IID * iids[] = { - &IID_IFilterMapper2, &IID_IFilterMapper - }; - int i; - - for (i = 0; i < ARRAY_SIZE(iids); i++) - { - test_aggregation(CLSID_SystemClock, CLSID_FilterMapper2, - IID_IReferenceClock, *iids[i]); - } -} - -START_TEST(misc) -{ - CoInitialize(NULL); - - test_null_renderer_aggregations(); - test_video_renderer_aggregations(); - test_filter_graph_aggregations(); - test_filter_mapper_aggregations(); - - CoUninitialize(); -} diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c index 48e21fc427..ec31303480 100644 --- a/dlls/quartz/tests/videorenderer.c +++ b/dlls/quartz/tests/videorenderer.c @@ -99,6 +99,99 @@ static void test_interfaces(void) IBaseFilter_Release(filter); }
+static const GUID test_iid = {0x33333333}; +static LONG outer_ref = 1; + +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IBaseFilter) + || IsEqualGUID(iid, &test_iid)) + { + *out = (IUnknown *)0xdeadbeef; + return S_OK; + } + ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI outer_AddRef(IUnknown *iface) +{ + return InterlockedIncrement(&outer_ref); +} + +static ULONG WINAPI outer_Release(IUnknown *iface) +{ + return InterlockedDecrement(&outer_ref); +} + +static const IUnknownVtbl outer_vtbl = +{ + outer_QueryInterface, + outer_AddRef, + outer_Release, +}; + +static IUnknown test_outer = {&outer_vtbl}; + +static void test_aggregation(void) +{ + IBaseFilter *filter, *filter2; + IUnknown *unk, *unk2; + HRESULT hr; + ULONG ref; + + filter = (IBaseFilter *)0xdeadbeef; + hr = CoCreateInstance(&CLSID_VideoRenderer, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&filter); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!filter, "Got interface %p.\n", filter); + + hr = CoCreateInstance(&CLSID_VideoRenderer, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&unk); + ok(hr == S_OK, "Got hr %#x.\n", 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); + + ref = IUnknown_AddRef(unk); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + ref = IUnknown_Release(unk); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2); + IUnknown_Release(unk2); + + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2); + + hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!unk2, "Got unexpected IUnknown %p.\n", unk2); + + hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + IBaseFilter_Release(filter); + ref = IUnknown_Release(unk); + ok(!ref, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); +}
static void test_enum_pins(void) { @@ -422,6 +515,7 @@ START_TEST(videorenderer) CoInitialize(NULL);
test_interfaces(); + test_aggregation(); test_enum_pins(); test_find_pin(); test_pin_info(); diff --git a/dlls/quartz/tests/vmr7.c b/dlls/quartz/tests/vmr7.c index 8a16039673..5defcc5245 100644 --- a/dlls/quartz/tests/vmr7.c +++ b/dlls/quartz/tests/vmr7.c @@ -307,6 +307,100 @@ static void test_interfaces(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static const GUID test_iid = {0x33333333}; +static LONG outer_ref = 1; + +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IBaseFilter) + || IsEqualGUID(iid, &test_iid)) + { + *out = (IUnknown *)0xdeadbeef; + return S_OK; + } + ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI outer_AddRef(IUnknown *iface) +{ + return InterlockedIncrement(&outer_ref); +} + +static ULONG WINAPI outer_Release(IUnknown *iface) +{ + return InterlockedDecrement(&outer_ref); +} + +static const IUnknownVtbl outer_vtbl = +{ + outer_QueryInterface, + outer_AddRef, + outer_Release, +}; + +static IUnknown test_outer = {&outer_vtbl}; + +static void test_aggregation(void) +{ + IBaseFilter *filter, *filter2; + IUnknown *unk, *unk2; + HRESULT hr; + ULONG ref; + + filter = (IBaseFilter *)0xdeadbeef; + hr = CoCreateInstance(&CLSID_VideoMixingRenderer, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&filter); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!filter, "Got interface %p.\n", filter); + + hr = CoCreateInstance(&CLSID_VideoMixingRenderer, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&unk); + ok(hr == S_OK, "Got hr %#x.\n", 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); + + ref = IUnknown_AddRef(unk); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + ref = IUnknown_Release(unk); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2); + IUnknown_Release(unk2); + + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2); + + hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!unk2, "Got unexpected IUnknown %p.\n", unk2); + + hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + IBaseFilter_Release(filter); + ref = IUnknown_Release(unk); + ok(!ref, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); +} + static void test_enum_pins(void) { IBaseFilter *filter = create_vmr7(0); @@ -697,6 +791,7 @@ START_TEST(vmr7)
test_filter_config(); test_interfaces(); + test_aggregation(); test_enum_pins(); test_find_pin(); test_pin_info(); diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c index 6c1c314502..0f3e470d6e 100644 --- a/dlls/quartz/tests/vmr9.c +++ b/dlls/quartz/tests/vmr9.c @@ -300,6 +300,100 @@ static void test_interfaces(void) ok(!ref, "Got outstanding refcount %d.\n", ref); }
+static const GUID test_iid = {0x33333333}; +static LONG outer_ref = 1; + +static HRESULT WINAPI outer_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + if (IsEqualGUID(iid, &IID_IUnknown) + || IsEqualGUID(iid, &IID_IBaseFilter) + || IsEqualGUID(iid, &test_iid)) + { + *out = (IUnknown *)0xdeadbeef; + return S_OK; + } + ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI outer_AddRef(IUnknown *iface) +{ + return InterlockedIncrement(&outer_ref); +} + +static ULONG WINAPI outer_Release(IUnknown *iface) +{ + return InterlockedDecrement(&outer_ref); +} + +static const IUnknownVtbl outer_vtbl = +{ + outer_QueryInterface, + outer_AddRef, + outer_Release, +}; + +static IUnknown test_outer = {&outer_vtbl}; + +static void test_aggregation(void) +{ + IBaseFilter *filter, *filter2; + IUnknown *unk, *unk2; + HRESULT hr; + ULONG ref; + + filter = (IBaseFilter *)0xdeadbeef; + hr = CoCreateInstance(&CLSID_VideoMixingRenderer, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IBaseFilter, (void **)&filter); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!filter, "Got interface %p.\n", filter); + + hr = CoCreateInstance(&CLSID_VideoMixingRenderer, &test_outer, CLSCTX_INPROC_SERVER, + &IID_IUnknown, (void **)&unk); + ok(hr == S_OK, "Got hr %#x.\n", 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); + + ref = IUnknown_AddRef(unk); + ok(ref == 2, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + ref = IUnknown_Release(unk); + ok(ref == 1, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); + + hr = IUnknown_QueryInterface(unk, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == unk, "Got unexpected IUnknown %p.\n", unk2); + IUnknown_Release(unk2); + + hr = IUnknown_QueryInterface(unk, &IID_IBaseFilter, (void **)&filter); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IBaseFilter_QueryInterface(filter, &IID_IUnknown, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + hr = IBaseFilter_QueryInterface(filter, &IID_IBaseFilter, (void **)&filter2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(filter2 == (IBaseFilter *)0xdeadbeef, "Got unexpected IBaseFilter %p.\n", filter2); + + hr = IUnknown_QueryInterface(unk, &test_iid, (void **)&unk2); + ok(hr == E_NOINTERFACE, "Got hr %#x.\n", hr); + ok(!unk2, "Got unexpected IUnknown %p.\n", unk2); + + hr = IBaseFilter_QueryInterface(filter, &test_iid, (void **)&unk2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(unk2 == (IUnknown *)0xdeadbeef, "Got unexpected IUnknown %p.\n", unk2); + + IBaseFilter_Release(filter); + ref = IUnknown_Release(unk); + ok(!ref, "Got unexpected refcount %d.\n", ref); + ok(outer_ref == 1, "Got unexpected refcount %d.\n", outer_ref); +} + static HRESULT set_mixing_mode(IBaseFilter *filter) { IVMRFilterConfig9 *config; @@ -687,6 +781,7 @@ START_TEST(vmr9)
test_filter_config(); test_interfaces(); + test_aggregation(); test_enum_pins(); test_find_pin(); test_pin_info();
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=51140
Your paranoid android.
=== w2008s64 (32 bit report) ===
quartz: filtergraph.c:777: Test failed: wait failed
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 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=51133
Your paranoid android.
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply
=== debian9 (build log) ===
error: patch failed: dlls/qedit/tests/mediadet.c:655 error: patch failed: dlls/qedit/tests/timeline.c:246 Task: Patch failed to apply