Nikolay Sivov : mfplay: Update player state on session state changes.

Alexandre Julliard julliard at winehq.org
Wed Apr 7 15:48:30 CDT 2021


Module: wine
Branch: master
Commit: 11f4927fedafca7a61b973941dd56442f68bf18e
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=11f4927fedafca7a61b973941dd56442f68bf18e

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Apr  7 11:07:01 2021 +0300

mfplay: Update player state on session state changes.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mfplay/player.c | 99 ++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 85 insertions(+), 14 deletions(-)

diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c
index 6fbbc0f4632..16592f2b3b6 100644
--- a/dlls/mfplay/player.c
+++ b/dlls/mfplay/player.c
@@ -70,8 +70,10 @@ struct media_player
     IMFSourceResolver *resolver;
     IMFMediaSession *session;
     MFP_CREATION_OPTIONS options;
+    MFP_MEDIAPLAYER_STATE state;
     HWND event_window;
     HWND output_window;
+    CRITICAL_SECTION cs;
 };
 
 struct generic_event
@@ -215,8 +217,8 @@ static const IUnknownVtbl media_event_vtbl =
     media_event_Release,
 };
 
-static HRESULT media_event_create(MFP_EVENT_TYPE event_type, HRESULT hr,
-        IMFPMediaPlayer *player, struct media_event **event)
+static HRESULT media_event_create(struct media_player *player, MFP_EVENT_TYPE event_type,
+        HRESULT hr, struct media_event **event)
 {
     struct media_event *object;
 
@@ -227,9 +229,9 @@ static HRESULT media_event_create(MFP_EVENT_TYPE event_type, HRESULT hr,
     object->refcount = 1;
     object->u.header.eEventType = event_type;
     object->u.header.hrEvent = hr;
-    object->u.header.pMediaPlayer = player;
+    object->u.header.pMediaPlayer = &player->IMFPMediaPlayer_iface;
     IMFPMediaPlayer_AddRef(object->u.header.pMediaPlayer);
-    /* FIXME: set player state field */
+    object->u.header.eState = player->state;
     /* FIXME: set properties for some events? */
 
     *event = object;
@@ -254,6 +256,16 @@ static LRESULT WINAPI media_player_event_proc(HWND hwnd, UINT msg, WPARAM wparam
     return DefWindowProcW(hwnd, msg, wparam, lparam);
 }
 
+static void media_player_set_state(struct media_player *player, MFP_MEDIAPLAYER_STATE state)
+{
+    if (player->state != MFP_MEDIAPLAYER_STATE_SHUTDOWN)
+    {
+        if (state == MFP_MEDIAPLAYER_STATE_SHUTDOWN)
+            IMFMediaSession_Shutdown(player->session);
+        player->state = state;
+    }
+}
+
 static HRESULT WINAPI media_item_QueryInterface(IMFPMediaItem *iface, REFIID riid, void **obj)
 {
     TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
@@ -628,6 +640,7 @@ static ULONG WINAPI media_player_Release(IMFPMediaPlayer *iface)
         if (player->session)
             IMFMediaSession_Release(player->session);
         DestroyWindow(player->event_window);
+        DeleteCriticalSection(&player->cs);
         heap_free(player);
 
         platform_shutdown();
@@ -708,9 +721,13 @@ static HRESULT WINAPI media_player_GetSupportedRates(IMFPMediaPlayer *iface, BOO
 
 static HRESULT WINAPI media_player_GetState(IMFPMediaPlayer *iface, MFP_MEDIAPLAYER_STATE *state)
 {
-    FIXME("%p, %p.\n", iface, state);
+    struct media_player *player = impl_from_IMFPMediaPlayer(iface);
 
-    return E_NOTIMPL;
+    TRACE("%p, %p.\n", iface, state);
+
+    *state = player->state;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI media_player_CreateMediaItemFromURL(IMFPMediaPlayer *iface,
@@ -928,9 +945,15 @@ static HRESULT WINAPI media_player_RemoveAllEffects(IMFPMediaPlayer *iface)
 
 static HRESULT WINAPI media_player_Shutdown(IMFPMediaPlayer *iface)
 {
-    FIXME("%p.\n", iface);
+    struct media_player *player = impl_from_IMFPMediaPlayer(iface);
 
-    return E_NOTIMPL;
+    TRACE("%p.\n", iface);
+
+    EnterCriticalSection(&player->cs);
+    media_player_set_state(player, MFP_MEDIAPLAYER_STATE_SHUTDOWN);
+    LeaveCriticalSection(&player->cs);
+
+    return S_OK;
 }
 
 static const IMFPMediaPlayerVtbl media_player_vtbl =
@@ -1108,7 +1131,7 @@ static HRESULT WINAPI media_player_resolver_callback_Invoke(IMFAsyncCallback *if
     if (FAILED(hr))
         WARN("Failed to set media source, hr %#x.\n", hr);
 
-    if (FAILED(media_event_create(MFP_EVENT_TYPE_MEDIAITEM_CREATED, hr, &player->IMFPMediaPlayer_iface, &event)))
+    if (FAILED(media_event_create(player, MFP_EVENT_TYPE_MEDIAITEM_CREATED, hr, &event)))
     {
         WARN("Failed to create event object.\n");
         IUnknown_Release(state);
@@ -1195,14 +1218,61 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba
         IMFAsyncResult *result)
 {
     struct media_player *player = impl_from_session_events_IMFAsyncCallback(iface);
-    IMFMediaEvent *event;
-    HRESULT hr;
-
-    if (FAILED(hr = IMFMediaSession_EndGetEvent(player->session, result, &event)))
+    MediaEventType session_event_type = MEUnknown;
+    struct media_event *event = NULL;
+    IMFMediaEvent *session_event;
+    MFP_MEDIAPLAYER_STATE state;
+    MFP_EVENT_TYPE event_type;
+    HRESULT hr, event_status;
+
+    if (FAILED(hr = IMFMediaSession_EndGetEvent(player->session, result, &session_event)))
         return S_OK;
 
+    IMFMediaEvent_GetType(session_event, &session_event_type);
+    IMFMediaEvent_GetStatus(session_event, &event_status);
+
+    switch (session_event_type)
+    {
+        case MESessionStarted:
+        case MESessionStopped:
+        case MESessionPaused:
+            if (session_event_type == MESessionStarted)
+            {
+                event_type = MFP_EVENT_TYPE_PLAY;
+                state = MFP_MEDIAPLAYER_STATE_PLAYING;
+            }
+            else if (session_event_type == MESessionStopped)
+            {
+                event_type = MFP_EVENT_TYPE_STOP;
+                state = MFP_MEDIAPLAYER_STATE_STOPPED;
+            }
+            else
+            {
+                event_type = MFP_EVENT_TYPE_PAUSE;
+                state = MFP_MEDIAPLAYER_STATE_PAUSED;
+            }
+
+            EnterCriticalSection(&player->cs);
+            media_player_set_state(player, state);
+            media_event_create(player, event_type, event_status, &event);
+            LeaveCriticalSection(&player->cs);
+
+            /* FIXME: set pMediaItem */
+            media_player_queue_event(player, event);
+            IUnknown_Release(&event->IUnknown_iface);
+
+            break;
+        default:
+            ;
+    }
+
+    if (event)
+    {
+        IUnknown_Release(&event->IUnknown_iface);
+    }
+
     IMFMediaSession_BeginGetEvent(player->session, &player->session_events_callback, NULL);
-    IMFMediaEvent_Release(event);
+    IMFMediaEvent_Release(session_event);
 
     return S_OK;
 }
@@ -1240,6 +1310,7 @@ HRESULT WINAPI MFPCreateMediaPlayer(const WCHAR *url, BOOL start_playback, MFP_C
         IMFPMediaPlayerCallback_AddRef(object->callback);
     object->options = options;
     object->output_window = window;
+    InitializeCriticalSection(&object->cs);
     if (FAILED(hr = CreatePropertyStore(&object->propstore)))
         goto failed;
     if (FAILED(hr = MFCreateSourceResolver(&object->resolver)))




More information about the wine-cvs mailing list