From 01563ba91a0aa8c17b76e8467b41e73b236df3c6 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Fri, 20 Nov 2020 16:21:18 +0300 Subject: [PATCH] mf/session: Shutdown current topology when clearing presentation. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/mf/session.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 0381917826a..19da9a24464 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -783,6 +783,61 @@ static void release_topo_node(struct topo_node *node) heap_free(node); } +static void session_shutdown_current_topology(struct media_session *session) +{ + unsigned int shutdown, force_shutdown; + MF_TOPOLOGY_TYPE node_type; + IMFStreamSink *stream_sink; + IMFTopology *topology; + IMFTopologyNode *node; + IMFActivate *activate; + IMFMediaSink *sink; + IUnknown *object; + WORD idx = 0; + + topology = session->presentation.current_topology; + force_shutdown = session->state == SESSION_STATE_SHUT_DOWN; + + /* FIXME: should handle async MFTs, but these are not supported by the rest of the pipeline currently. */ + + while (SUCCEEDED(IMFTopology_GetNode(topology, idx++, &node))) + { + if (SUCCEEDED(IMFTopologyNode_GetNodeType(node, &node_type)) && + node_type == MF_TOPOLOGY_OUTPUT_NODE) + { + shutdown = 1; + IMFTopologyNode_GetUINT32(node, &MF_TOPONODE_NOSHUTDOWN_ON_REMOVE, &shutdown); + + if (force_shutdown || shutdown) + { + if (SUCCEEDED(IMFTopologyNode_GetUnknown(node, &_MF_TOPONODE_IMFActivate, &IID_IMFActivate, + (void **)&activate))) + { + IMFActivate_ShutdownObject(activate); + IMFActivate_Release(activate); + } + else if (SUCCEEDED(IMFTopologyNode_GetObject(node, &object))) + { + if (SUCCEEDED(IUnknown_QueryInterface(object, &IID_IMFStreamSink, (void **)&stream_sink))) + { + if (SUCCEEDED(IMFStreamSink_GetMediaSink(stream_sink, &sink))) + { + IMFMediaSink_Shutdown(sink); + IMFMediaSink_Release(sink); + } + + IMFStreamSink_Release(stream_sink); + } + + IUnknown_Release(object); + } + } + } + + IMFTopologyNode_Release(node); + } +} + static void session_clear_presentation(struct media_session *session) { struct media_source *source, *source2; @@ -790,6 +845,8 @@ static void session_clear_presentation(struct media_session *session) struct topo_node *node, *node2; struct session_op *op, *op2; + session_shutdown_current_topology(session); + IMFTopology_Clear(session->presentation.current_topology); session->presentation.topo_status = MF_TOPOSTATUS_INVALID; @@ -1790,7 +1847,7 @@ static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface) struct media_session *session = impl_from_IMFMediaSession(iface); HRESULT hr = S_OK; - FIXME("%p.\n", iface); + TRACE("%p.\n", iface); EnterCriticalSection(&session->cs); if (SUCCEEDED(hr = session_is_shut_down(session))) @@ -1802,6 +1859,7 @@ static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface) MFShutdownObject((IUnknown *)session->clock); IMFPresentationClock_Release(session->clock); session->clock = NULL; + session_clear_presentation(session); } LeaveCriticalSection(&session->cs);