[PATCH 5/6] mf: Forward sink invalidation events to application.

Nikolay Sivov nsivov at codeweavers.com
Tue Mar 17 09:10:33 CDT 2020


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mf/session.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 51 insertions(+), 1 deletion(-)

diff --git a/dlls/mf/session.c b/dlls/mf/session.c
index 07cfc4ee8c..69d1fdf569 100644
--- a/dlls/mf/session.c
+++ b/dlls/mf/session.c
@@ -2492,6 +2492,38 @@ static void session_deliver_sample(struct media_session *session, IMFMediaStream
     IMFTopologyNode_Release(downstream_node);
 }
 
+static void session_sink_invalidated(struct media_session *session, IMFMediaEvent *event, IMFStreamSink *sink)
+{
+    struct topo_node *node, *sink_node = NULL;
+    HRESULT hr;
+
+    LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry)
+    {
+        if (node->type == MF_TOPOLOGY_OUTPUT_NODE && node->object.sink_stream == sink)
+        {
+            sink_node = node;
+            break;
+        }
+    }
+
+    if (!sink_node)
+        return;
+
+    if (!event)
+    {
+        if (FAILED(hr = MFCreateMediaEvent(MESinkInvalidated, &GUID_NULL, S_OK, NULL, &event)))
+            WARN("Failed to create event, hr %#x.\n", hr);
+    }
+
+    if (!event)
+        return;
+
+    IMFMediaEvent_SetUINT64(event, &MF_EVENT_OUTPUT_NODE, sink_node->node_id);
+    IMFMediaEventQueue_QueueEvent(session->event_queue, event);
+
+    session_set_topo_status(session, S_OK, MF_TOPOSTATUS_ENDED);
+}
+
 static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
 {
     struct media_session *session = impl_from_events_callback_IMFAsyncCallback(iface);
@@ -2573,13 +2605,31 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM
             EnterCriticalSection(&session->cs);
             session_request_sample(session, (IMFStreamSink *)event_source);
             LeaveCriticalSection(&session->cs);
-            break;
 
+            break;
         case MEMediaSample:
 
             EnterCriticalSection(&session->cs);
             session_deliver_sample(session, (IMFMediaStream *)event_source, &value);
             LeaveCriticalSection(&session->cs);
+
+            break;
+        case MEAudioSessionDeviceRemoved:
+        case MEAudioSessionDisconnected:
+        case MEAudioSessionExclusiveModeOverride:
+        case MEAudioSessionFormatChanged:
+        case MEAudioSessionServerShutdown:
+
+            IMFMediaEventQueue_QueueEvent(session->event_queue, event);
+            /* fallthrough */
+        case MESinkInvalidated:
+
+            EnterCriticalSection(&session->cs);
+            session_sink_invalidated(session, event_type == MESinkInvalidated ? event : NULL,
+                    (IMFStreamSink *)event_source);
+            LeaveCriticalSection(&session->cs);
+
+            break;
         default:
             ;
     }
-- 
2.25.1




More information about the wine-devel mailing list