[PATCH 2/5] mf/session: Fix pause command handling from invalid states.
Nikolay Sivov
nsivov at codeweavers.com
Wed Jun 23 06:03:03 CDT 2021
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/mf/session.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c
index 76c39631bd9..4e70aba410a 100644
--- a/dlls/mf/session.c
+++ b/dlls/mf/session.c
@@ -903,9 +903,12 @@ static void session_set_started(struct media_session *session)
session_command_complete(session);
}
-static void session_set_paused(struct media_session *session, HRESULT status)
+static void session_set_paused(struct media_session *session, unsigned int state, HRESULT status)
{
- session->state = SESSION_STATE_PAUSED;
+ /* Failed event status could indicate a failure during normal transition to paused state,
+ or an attempt to pause from invalid initial state. To finalize failed transition in the former case,
+ state is still forced to PAUSED, otherwise previous state is retained. */
+ if (state != ~0u) session->state = state;
if (SUCCEEDED(status))
session_set_caps(session, session->caps & ~MFSESSIONCAP_PAUSE);
IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionPaused, &GUID_NULL, status, NULL);
@@ -923,6 +926,7 @@ static void session_set_closed(struct media_session *session, HRESULT status)
static void session_pause(struct media_session *session)
{
+ unsigned int state = ~0u;
HRESULT hr;
switch (session->state)
@@ -932,14 +936,19 @@ static void session_pause(struct media_session *session)
/* Transition in two steps - pause the clock, wait for sinks, then pause sources. */
if (SUCCEEDED(hr = IMFPresentationClock_Pause(session->clock)))
session->state = SESSION_STATE_PAUSING_SINKS;
+ state = SESSION_STATE_PAUSED;
break;
+
+ case SESSION_STATE_STOPPED:
+ hr = MF_E_SESSION_PAUSEWHILESTOPPED;
+ break;
default:
hr = MF_E_INVALIDREQUEST;
}
if (FAILED(hr))
- session_set_paused(session, hr);
+ session_set_paused(session, state, hr);
}
static void session_clear_end_of_presentation(struct media_session *session)
@@ -2502,7 +2511,7 @@ static void session_set_source_object_state(struct media_session *session, IUnkn
if (!session_is_source_nodes_state(session, OBJ_STATE_PAUSED))
break;
- session_set_paused(session, S_OK);
+ session_set_paused(session, SESSION_STATE_PAUSED, S_OK);
break;
case SESSION_STATE_STOPPING_SOURCES:
if (!session_is_source_nodes_state(session, OBJ_STATE_STOPPED))
@@ -2578,7 +2587,7 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre
}
if (FAILED(hr))
- session_set_paused(session, hr);
+ session_set_paused(session, SESSION_STATE_PAUSED, hr);
break;
case SESSION_STATE_STOPPING_SINKS:
--
2.30.2
More information about the wine-devel
mailing list