Nikolay Sivov : mf/session: Shutdown current topology when clearing presentation.
Alexandre Julliard
julliard at winehq.org
Fri Nov 20 14:54:32 CST 2020
Module: wine
Branch: master
Commit: 01563ba91a0aa8c17b76e8467b41e73b236df3c6
URL: https://source.winehq.org/git/wine.git/?a=commit;h=01563ba91a0aa8c17b76e8467b41e73b236df3c6
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Fri Nov 20 16:21:18 2020 +0300
mf/session: Shutdown current topology when clearing presentation.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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);
More information about the wine-cvs
mailing list