mf: Implement Pause() command for media session.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
74e7e45d9f
commit
43fd6bd94a
|
@ -76,6 +76,9 @@ enum session_state
|
||||||
SESSION_STATE_STARTING_SOURCES,
|
SESSION_STATE_STARTING_SOURCES,
|
||||||
SESSION_STATE_STARTING_SINKS,
|
SESSION_STATE_STARTING_SINKS,
|
||||||
SESSION_STATE_RUNNING,
|
SESSION_STATE_RUNNING,
|
||||||
|
SESSION_STATE_PAUSING_SINKS,
|
||||||
|
SESSION_STATE_PAUSING_SOURCES,
|
||||||
|
SESSION_STATE_PAUSED,
|
||||||
SESSION_STATE_CLOSED,
|
SESSION_STATE_CLOSED,
|
||||||
SESSION_STATE_SHUT_DOWN,
|
SESSION_STATE_SHUT_DOWN,
|
||||||
};
|
};
|
||||||
|
@ -644,6 +647,34 @@ static void session_start(struct media_session *session, const GUID *time_format
|
||||||
LeaveCriticalSection(&session->cs);
|
LeaveCriticalSection(&session->cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void session_pause(struct media_session *session)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
EnterCriticalSection(&session->cs);
|
||||||
|
|
||||||
|
switch (session->state)
|
||||||
|
{
|
||||||
|
case SESSION_STATE_RUNNING:
|
||||||
|
|
||||||
|
/* Transition in two steps - pause clock, wait for sinks and pause sources. */
|
||||||
|
if (SUCCEEDED(hr = IMFPresentationClock_Pause(session->clock)))
|
||||||
|
session->state = SESSION_STATE_PAUSING_SINKS;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
hr = MF_E_INVALIDREQUEST;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
session->state = SESSION_STATE_PAUSED;
|
||||||
|
IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionPaused, &GUID_NULL, hr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&session->cs);
|
||||||
|
}
|
||||||
|
|
||||||
static struct media_source *session_get_media_source(struct media_session *session, IMFMediaSource *source)
|
static struct media_source *session_get_media_source(struct media_session *session, IMFMediaSource *source)
|
||||||
{
|
{
|
||||||
struct media_source *cur;
|
struct media_source *cur;
|
||||||
|
@ -1469,6 +1500,7 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface,
|
||||||
session_start(session, &op->u.start.time_format, &op->u.start.start_position);
|
session_start(session, &op->u.start.time_format, &op->u.start.start_position);
|
||||||
break;
|
break;
|
||||||
case SESSION_CMD_PAUSE:
|
case SESSION_CMD_PAUSE:
|
||||||
|
session_pause(session);
|
||||||
break;
|
break;
|
||||||
case SESSION_CMD_CLOSE:
|
case SESSION_CMD_CLOSE:
|
||||||
EnterCriticalSection(&session->cs);
|
EnterCriticalSection(&session->cs);
|
||||||
|
@ -1744,6 +1776,17 @@ static void session_set_source_object_state(struct media_session *session, IUnkn
|
||||||
if (SUCCEEDED(session_start_clock(session)))
|
if (SUCCEEDED(session_start_clock(session)))
|
||||||
session->state = SESSION_STATE_STARTING_SINKS;
|
session->state = SESSION_STATE_STARTING_SINKS;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SESSION_STATE_PAUSING_SOURCES:
|
||||||
|
if (!session_is_source_nodes_state(session, OBJ_STATE_PAUSED))
|
||||||
|
break;
|
||||||
|
|
||||||
|
session->state = SESSION_STATE_PAUSED;
|
||||||
|
|
||||||
|
session_set_caps(session, session->caps & ~MFSESSIONCAP_PAUSE);
|
||||||
|
|
||||||
|
IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionPaused, &GUID_NULL, S_OK, NULL);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
|
@ -1759,6 +1802,7 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre
|
||||||
BOOL changed = FALSE;
|
BOOL changed = FALSE;
|
||||||
IMFMediaEvent *event;
|
IMFMediaEvent *event;
|
||||||
DWORD caps, flags;
|
DWORD caps, flags;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
if ((state = session_get_object_state_for_event(event_type)) == OBJ_STATE_INVALID)
|
if ((state = session_get_object_state_for_event(event_type)) == OBJ_STATE_INVALID)
|
||||||
return;
|
return;
|
||||||
|
@ -1806,6 +1850,25 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre
|
||||||
IMFMediaEventQueue_QueueEvent(session->event_queue, event);
|
IMFMediaEventQueue_QueueEvent(session->event_queue, event);
|
||||||
IMFMediaEvent_Release(event);
|
IMFMediaEvent_Release(event);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case SESSION_STATE_PAUSING_SINKS:
|
||||||
|
if (!session_is_output_nodes_state(session, OBJ_STATE_PAUSED))
|
||||||
|
break;
|
||||||
|
|
||||||
|
session->state = SESSION_STATE_PAUSING_SOURCES;
|
||||||
|
|
||||||
|
LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry)
|
||||||
|
{
|
||||||
|
if (FAILED(hr = IMFMediaSource_Pause(source->source)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
session->state = SESSION_STATE_PAUSED;
|
||||||
|
IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionPaused, &GUID_NULL, hr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
|
|
Loading…
Reference in New Issue