[PATCH 2/6] mf: Raise event on session close.

Nikolay Sivov nsivov at codeweavers.com
Fri May 31 05:11:29 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mf/session.c  | 55 ++++++++++++++++++++++++++++++++++++++--------
 dlls/mf/tests/mf.c | 11 ++++++++++
 2 files changed, 57 insertions(+), 9 deletions(-)

diff --git a/dlls/mf/session.c b/dlls/mf/session.c
index 0c283c4392..76573c9f44 100644
--- a/dlls/mf/session.c
+++ b/dlls/mf/session.c
@@ -35,7 +35,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
 
 enum session_command
 {
-    SESSION_CLEAR_TOPOLOGIES,
+    SESSION_CMD_CLEAR_TOPOLOGIES,
+    SESSION_CMD_CLOSE,
 };
 
 struct session_op
@@ -51,6 +52,13 @@ struct queued_topology
     IMFTopology *topology;
 };
 
+enum session_state
+{
+    SESSION_STATE_STOPPED = 0,
+    SESSION_STATE_CLOSED,
+    SESSION_STATE_SHUT_DOWN,
+};
+
 struct media_session
 {
     IMFMediaSession IMFMediaSession_iface;
@@ -62,7 +70,7 @@ struct media_session
     IMFMediaEventQueue *event_queue;
     IMFPresentationClock *clock;
     struct list topologies;
-    BOOL is_shut_down;
+    enum session_state state;
     CRITICAL_SECTION cs;
 };
 
@@ -362,7 +370,16 @@ static HRESULT WINAPI mfsession_SetTopology(IMFMediaSession *iface, DWORD flags,
 
 static HRESULT session_submit_command(struct media_session *session, IUnknown *op)
 {
-    return MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, op);
+    HRESULT hr;
+
+    EnterCriticalSection(&session->cs);
+    if (session->state == SESSION_STATE_SHUT_DOWN)
+        hr = MF_E_SHUTDOWN;
+    else
+        hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, op);
+    LeaveCriticalSection(&session->cs);
+
+    return hr;
 }
 
 static HRESULT WINAPI mfsession_ClearTopologies(IMFMediaSession *iface)
@@ -373,7 +390,7 @@ static HRESULT WINAPI mfsession_ClearTopologies(IMFMediaSession *iface)
 
     TRACE("%p.\n", iface);
 
-    if (FAILED(hr = create_session_op(SESSION_CLEAR_TOPOLOGIES, &op)))
+    if (FAILED(hr = create_session_op(SESSION_CMD_CLEAR_TOPOLOGIES, &op)))
         return hr;
 
     hr = session_submit_command(session, op);
@@ -405,9 +422,19 @@ static HRESULT WINAPI mfsession_Stop(IMFMediaSession *iface)
 
 static HRESULT WINAPI mfsession_Close(IMFMediaSession *iface)
 {
-    FIXME("(%p)\n", iface);
+    struct media_session *session = impl_from_IMFMediaSession(iface);
+    IUnknown *op;
+    HRESULT hr;
 
-    return S_OK;
+    TRACE("(%p)\n", iface);
+
+    if (FAILED(hr = create_session_op(SESSION_CMD_CLOSE, &op)))
+        return hr;
+
+    hr = session_submit_command(session, op);
+    IUnknown_Release(op);
+
+    return hr;
 }
 
 static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface)
@@ -418,11 +445,11 @@ static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface)
     FIXME("(%p)\n", iface);
 
     EnterCriticalSection(&session->cs);
-    if (session->is_shut_down)
+    if (session->state == SESSION_STATE_SHUT_DOWN)
         hr = MF_E_SHUTDOWN;
     else
     {
-        session->is_shut_down = TRUE;
+        session->state = SESSION_STATE_SHUT_DOWN;
         IMFMediaEventQueue_Shutdown(session->event_queue);
     }
     LeaveCriticalSection(&session->cs);
@@ -572,7 +599,7 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface,
 
     switch (op->command)
     {
-        case SESSION_CLEAR_TOPOLOGIES:
+        case SESSION_CMD_CLEAR_TOPOLOGIES:
             EnterCriticalSection(&session->cs);
             session_clear_topologies(session);
             LeaveCriticalSection(&session->cs);
@@ -580,6 +607,16 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface,
             IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionTopologiesCleared, &GUID_NULL,
                     S_OK, NULL);
             break;
+        case SESSION_CMD_CLOSE:
+            EnterCriticalSection(&session->cs);
+            if (session->state != SESSION_STATE_CLOSED)
+            {
+                /* FIXME: actually do something to presentation objects */
+                session->state = SESSION_STATE_CLOSED;
+                IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionClosed, &GUID_NULL, S_OK, NULL);
+            }
+            LeaveCriticalSection(&session->cs);
+            break;
         default:
             ;
     }
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index bae80203c5..39a049000f 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -1000,6 +1000,17 @@ static void test_media_session(void)
 
     IMFMediaSession_Release(session);
 
+    hr = MFCreateMediaSession(NULL, &session);
+    ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
+
+    hr = IMFMediaSession_Shutdown(session);
+    ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
+
+    hr = IMFMediaSession_Close(session);
+    ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
+
+    IMFMediaSession_Release(session);
+
     hr = MFShutdown();
     ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
 }
-- 
2.20.1




More information about the wine-devel mailing list