[PATCH v2] quartz/filtergraph: Improve HRESULT propagation from IFilterGraph2_Connect().
Zebediah Figura
z.figura12 at gmail.com
Mon Sep 24 23:55:21 CDT 2018
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/quartz/filtergraph.c | 11 +++++--
dlls/quartz/tests/filtergraph.c | 67 +++++++++++++++++++++++++++++++++++++++--
2 files changed, 73 insertions(+), 5 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index 0468cb5..c8e3c08 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -1181,7 +1181,11 @@ static HRESULT WINAPI FilterGraph2_Connect(IFilterGraph2 *iface, IPin *ppinOut,
/* Try direct connection first */
hr = IPin_Connect(ppinOut, ppinIn, NULL);
- if (SUCCEEDED(hr))
+
+ /* If direct connection succeeded, we should propagate that return value.
+ * If it returned VFW_E_NOT_CONNECTED or VFW_E_NO_AUDIO_HARDWARE, then don't
+ * even bother trying intermediate filters, since they won't succeed. */
+ if (SUCCEEDED(hr) || hr == VFW_E_NOT_CONNECTED || hr == VFW_E_NO_AUDIO_HARDWARE)
goto out;
TRACE("Direct connection failed, trying to render using extra filters\n");
@@ -1379,6 +1383,9 @@ error:
}
}
+ if (FAILED(hr))
+ hr = VFW_E_CANNOT_CONNECT;
+
IEnumMoniker_Release(pEnumMoniker);
out:
@@ -1391,7 +1398,7 @@ out:
--This->recursioncount;
LeaveCriticalSection(&This->cs);
TRACE("--> %08x\n", hr);
- return SUCCEEDED(hr) ? S_OK : hr;
+ return hr;
}
/* Render all output pins of the given filter. Helper for FilterGraph2_Render(). */
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c
index 6c8b9fa..5693c86 100644
--- a/dlls/quartz/tests/filtergraph.c
+++ b/dlls/quartz/tests/filtergraph.c
@@ -609,7 +609,6 @@ static void test_render_run(const WCHAR *file)
ok(!refs, "Graph has %u references\n", refs);
hr = test_graph_builder_connect_file(filename);
-todo_wine
ok(hr == VFW_E_CANNOT_CONNECT, "got %#x\n", hr);
}
else
@@ -776,6 +775,8 @@ struct testpin
unsigned int type_count, enum_idx;
AM_MEDIA_TYPE *request_mt, *accept_mt;
+ HRESULT Connect_hr;
+ HRESULT EnumMediaTypes_hr;
HRESULT QueryInternalConnections_hr;
};
@@ -964,6 +965,9 @@ static HRESULT WINAPI testpin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **out)
struct testpin *pin = impl_from_IPin(iface);
if (winetest_debug > 1) trace("%p->EnumMediaTypes()\n", pin);
+ if (FAILED(pin->EnumMediaTypes_hr))
+ return pin->EnumMediaTypes_hr;
+
*out = &pin->IEnumMediaTypes_iface;
IEnumMediaTypes_AddRef(*out);
pin->enum_idx = 0;
@@ -1063,6 +1067,8 @@ static void testpin_init(struct testpin *pin, const IPinVtbl *vtbl, PIN_DIRECTIO
pin->IEnumMediaTypes_iface.lpVtbl = &testenummt_vtbl;
pin->ref = 1;
pin->dir = dir;
+ pin->Connect_hr = S_OK;
+ pin->EnumMediaTypes_hr = S_OK;
pin->QueryInternalConnections_hr = E_NOTIMPL;
}
@@ -1077,12 +1083,16 @@ static HRESULT WINAPI testsource_Connect(IPin *iface, IPin *peer, const AM_MEDIA
HRESULT hr;
if (winetest_debug > 1) trace("%p->Connect(%p)\n", pin, peer);
+ if (FAILED(pin->Connect_hr))
+ return pin->Connect_hr;
+
ok(!mt, "Got media type %p.\n", mt);
if (SUCCEEDED(hr = IPin_ReceiveConnection(peer, &pin->IPin_iface, pin->request_mt)))
{
pin->peer = peer;
IPin_AddRef(peer);
+ return pin->Connect_hr;
}
return hr;
}
@@ -1711,12 +1721,50 @@ static void test_graph_builder_connect(void)
IFilterGraph2_Disconnect(graph, source_pin.peer);
IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
+ for (source_pin.Connect_hr = 0x00040200; source_pin.Connect_hr <= 0x000402ff;
+ ++source_pin.Connect_hr)
+ {
+ hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
+ ok(hr == source_pin.Connect_hr, "Got hr %#x for Connect() hr %#x.\n",
+ hr, source_pin.Connect_hr);
+ ok(source_pin.peer == &sink_pin.IPin_iface, "Got peer %p.\n", source_pin.peer);
+ IFilterGraph2_Disconnect(graph, source_pin.peer);
+ IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
+ }
+ source_pin.Connect_hr = S_OK;
+
sink_pin.accept_mt = &sink_type;
hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
-todo_wine
ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x.\n", hr);
ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
+ for (source_pin.Connect_hr = 0x80040200; source_pin.Connect_hr <= 0x800402ff;
+ ++source_pin.Connect_hr)
+ {
+ hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
+ if (source_pin.Connect_hr == VFW_E_NOT_CONNECTED
+ || source_pin.Connect_hr == VFW_E_NO_AUDIO_HARDWARE)
+ ok(hr == source_pin.Connect_hr, "Got hr %#x for Connect() hr %#x.\n",
+ hr, source_pin.Connect_hr);
+ else
+ ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x for Connect() hr %#x.\n",
+ hr, source_pin.Connect_hr);
+ ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
+ ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
+ }
+ source_pin.Connect_hr = S_OK;
+
+ for (source_pin.EnumMediaTypes_hr = 0x80040200; source_pin.EnumMediaTypes_hr <= 0x800402ff;
+ ++source_pin.EnumMediaTypes_hr)
+ {
+ hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
+ ok(hr == source_pin.EnumMediaTypes_hr, "Got hr %#x for EnumMediaTypes() hr %#x.\n",
+ hr, source_pin.EnumMediaTypes_hr);
+ ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
+ ok(!sink_pin.peer, "Got peer %p.\n", sink_pin.peer);
+ }
+ source_pin.EnumMediaTypes_hr = S_OK;
+
/* Test usage of intermediate filters. Similarly to Render(), filters are
* simply tried in enumeration order. */
@@ -1740,6 +1788,20 @@ todo_wine
IFilterGraph2_Disconnect(graph, sink_pin.peer);
IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
+ for (source_pin.Connect_hr = 0x00040200; source_pin.Connect_hr <= 0x000402ff;
+ ++source_pin.Connect_hr)
+ {
+ hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
+ ok(hr == S_OK, "Got hr %#x for Connect() hr %#x.\n", hr, source_pin.Connect_hr);
+ ok(source_pin.peer == &parser2_pins[0].IPin_iface, "Got peer %p.\n", source_pin.peer);
+ ok(sink_pin.peer == &parser2_pins[1].IPin_iface, "Got peer %p.\n", sink_pin.peer);
+ IFilterGraph2_Disconnect(graph, source_pin.peer);
+ IFilterGraph2_Disconnect(graph, &source_pin.IPin_iface);
+ IFilterGraph2_Disconnect(graph, sink_pin.peer);
+ IFilterGraph2_Disconnect(graph, &sink_pin.IPin_iface);
+ }
+ source_pin.Connect_hr = S_OK;
+
IFilterGraph2_RemoveFilter(graph, &parser1.IBaseFilter_iface);
IFilterGraph2_AddFilter(graph, &parser1.IBaseFilter_iface, NULL);
@@ -1805,7 +1867,6 @@ todo_wine
parser1_pins[1].name[0] = '~';
hr = IFilterGraph2_Connect(graph, &source_pin.IPin_iface, &sink_pin.IPin_iface);
-todo_wine
ok(hr == VFW_E_CANNOT_CONNECT, "Got hr %#x.\n", hr);
ok(!source_pin.peer, "Got peer %p.\n", source_pin.peer);
--
2.7.4
More information about the wine-devel
mailing list