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