[PATCH 2/2] quartz: Implement IMediaControl::StopWhenReady().
Zebediah Figura
z.figura12 at gmail.com
Mon May 18 15:57:59 CDT 2020
This allows The Bunker to exit cleanly.
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/quartz/filtergraph.c | 56 +++++++++++++++++++++++++++++++--
dlls/quartz/tests/filtergraph.c | 20 ++++++++++++
2 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index 47782f2d24f..137624c8f4c 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -2132,11 +2132,63 @@ static HRESULT WINAPI MediaControl_get_RegFilterCollection(IMediaControl *iface,
return S_OK;
}
+static void CALLBACK wait_pause_cb(TP_CALLBACK_INSTANCE *instance, void *context)
+{
+ IMediaControl *control = context;
+ OAFilterState state;
+ HRESULT hr;
+
+ if ((hr = IMediaControl_GetState(control, INFINITE, &state)) != S_OK)
+ ERR("Failed to get paused state, hr %#x.\n", hr);
+
+ if (FAILED(hr = IMediaControl_Stop(control)))
+ ERR("Failed to stop, hr %#x.\n", hr);
+
+ if ((hr = IMediaControl_GetState(control, INFINITE, &state)) != S_OK)
+ ERR("Failed to get paused state, hr %#x.\n", hr);
+
+ IMediaControl_Release(control);
+}
+
+static void CALLBACK wait_stop_cb(TP_CALLBACK_INSTANCE *instance, void *context)
+{
+ IMediaControl *control = context;
+ OAFilterState state;
+ HRESULT hr;
+
+ if ((hr = IMediaControl_GetState(control, INFINITE, &state)) != S_OK)
+ ERR("Failed to get state, hr %#x.\n", hr);
+
+ IMediaControl_Release(control);
+}
+
static HRESULT WINAPI MediaControl_StopWhenReady(IMediaControl *iface)
{
- IFilterGraphImpl *This = impl_from_IMediaControl(iface);
+ IFilterGraphImpl *graph = impl_from_IMediaControl(iface);
+ HRESULT hr;
+
+ TRACE("graph %p.\n", graph);
+
+ /* Even if we are already stopped, we still pause. */
+ hr = IMediaControl_Pause(iface);
+ if (FAILED(hr))
+ return hr;
+ else if (hr == S_FALSE)
+ {
+ IMediaControl_AddRef(iface);
+ TrySubmitThreadpoolCallback(wait_pause_cb, iface, NULL);
+ return S_FALSE;
+ }
- FIXME("(%p/%p)->(): stub !!!\n", This, iface);
+ hr = IMediaControl_Stop(iface);
+ if (FAILED(hr))
+ return hr;
+ else if (hr == S_FALSE)
+ {
+ IMediaControl_AddRef(iface);
+ TrySubmitThreadpoolCallback(wait_stop_cb, iface, NULL);
+ return S_FALSE;
+ }
return S_OK;
}
diff --git a/dlls/quartz/tests/filtergraph.c b/dlls/quartz/tests/filtergraph.c
index 5a9157bb788..afb32a01569 100644
--- a/dlls/quartz/tests/filtergraph.c
+++ b/dlls/quartz/tests/filtergraph.c
@@ -3203,6 +3203,26 @@ static void test_filter_state(void)
ok(hr == S_OK, "Got hr %#x.\n", hr);
check_filter_state(graph, State_Stopped);
+ hr = IMediaControl_Pause(control);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ check_filter_state(graph, State_Paused);
+
+ hr = IMediaControl_StopWhenReady(control);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ check_filter_state(graph, State_Stopped);
+
+ hr = IMediaControl_Run(control);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ check_filter_state(graph, State_Running);
+
+ hr = IMediaControl_StopWhenReady(control);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ check_filter_state(graph, State_Stopped);
+
+ hr = IMediaControl_StopWhenReady(control);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ check_filter_state(graph, State_Stopped);
+
IReferenceClock_Release(clock);
IMediaFilter_Release(filter);
IMediaControl_Release(control);
--
2.26.2
More information about the wine-devel
mailing list