Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 53 +++++++++++++++-------------------------------- 1 file changed, 17 insertions(+), 36 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 25832afdbb..375dd8e196 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -536,6 +536,19 @@ static HRESULT session_submit_command(struct media_session *session, struct sess return hr; }
+static HRESULT session_submit_simple_command(struct media_session *session, enum session_command command) +{ + struct session_op *op; + HRESULT hr; + + if (FAILED(hr = create_session_op(command, &op))) + return hr; + + hr = session_submit_command(session, op); + IUnknown_Release(&op->IUnknown_iface); + return hr; +} + static void session_clear_topologies(struct media_session *session) { struct queued_topology *ptr, *next; @@ -1499,18 +1512,10 @@ static HRESULT WINAPI mfsession_SetTopology(IMFMediaSession *iface, DWORD flags, static HRESULT WINAPI mfsession_ClearTopologies(IMFMediaSession *iface) { struct media_session *session = impl_from_IMFMediaSession(iface); - struct session_op *op; - HRESULT hr;
TRACE("%p.\n", iface);
- if (FAILED(hr = create_session_op(SESSION_CMD_CLEAR_TOPOLOGIES, &op))) - return hr; - - hr = session_submit_command(session, op); - IUnknown_Release(&op->IUnknown_iface); - - return hr; + return session_submit_simple_command(session, SESSION_CMD_CLEAR_TOPOLOGIES); }
static HRESULT WINAPI mfsession_Start(IMFMediaSession *iface, const GUID *format, const PROPVARIANT *start_position) @@ -1541,52 +1546,28 @@ static HRESULT WINAPI mfsession_Start(IMFMediaSession *iface, const GUID *format static HRESULT WINAPI mfsession_Pause(IMFMediaSession *iface) { struct media_session *session = impl_from_IMFMediaSession(iface); - struct session_op *op; - HRESULT hr;
TRACE("%p.\n", iface);
- if (FAILED(hr = create_session_op(SESSION_CMD_PAUSE, &op))) - return hr; - - hr = session_submit_command(session, op); - IUnknown_Release(&op->IUnknown_iface); - - return hr; + return session_submit_simple_command(session, SESSION_CMD_PAUSE); }
static HRESULT WINAPI mfsession_Stop(IMFMediaSession *iface) { struct media_session *session = impl_from_IMFMediaSession(iface); - struct session_op *op; - HRESULT hr;
TRACE("%p.\n", iface);
- if (FAILED(hr = create_session_op(SESSION_CMD_STOP, &op))) - return hr; - - hr = session_submit_command(session, op); - IUnknown_Release(&op->IUnknown_iface); - - return hr; + return session_submit_simple_command(session, SESSION_CMD_STOP); }
static HRESULT WINAPI mfsession_Close(IMFMediaSession *iface) { struct media_session *session = impl_from_IMFMediaSession(iface); - struct session_op *op; - HRESULT hr;
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->IUnknown_iface); - - return hr; + return session_submit_simple_command(session, SESSION_CMD_CLOSE); }
static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 375dd8e196..62b0b6e978 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -812,6 +812,14 @@ static void session_start(struct media_session *session, const GUID *time_format LeaveCriticalSection(&session->cs); }
+static void session_set_closed(struct media_session *session, HRESULT status) +{ + session->state = SESSION_STATE_CLOSED; + if (SUCCEEDED(status)) + session_set_caps(session, session->caps & ~(MFSESSIONCAP_START | MFSESSIONCAP_SEEK)); + IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionClosed, &GUID_NULL, status, NULL); +} + static void session_pause(struct media_session *session) { HRESULT hr; @@ -911,11 +919,7 @@ static HRESULT session_finalize_sinks(struct media_session *session) }
if (sinks_finalized) - { - session->state = SESSION_STATE_CLOSED; - session_set_caps(session, session->caps & ~(MFSESSIONCAP_START | MFSESSIONCAP_SEEK)); - IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionClosed, &GUID_NULL, hr, NULL); - } + session_set_closed(session, hr);
return hr; } @@ -945,10 +949,7 @@ static void session_close(struct media_session *session) }
if (FAILED(hr)) - { - session->state = SESSION_STATE_CLOSED; - IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionClosed, &GUID_NULL, hr, NULL); - } + session_set_closed(session, hr);
LeaveCriticalSection(&session->cs); } @@ -3018,11 +3019,7 @@ static HRESULT WINAPI session_sink_finalizer_callback_Invoke(IMFAsyncCallback *i { sink->finalized = TRUE; if (sinks_finalized) - { - session->state = SESSION_STATE_CLOSED; - session_set_caps(session, session->caps & ~(MFSESSIONCAP_START | MFSESSIONCAP_SEEK)); - IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionClosed, &GUID_NULL, hr, NULL); - } + session_set_closed(session, hr); } IMFFinalizableMediaSink_Release(fin_sink); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 62b0b6e978..26ea34b441 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -812,6 +812,14 @@ static void session_start(struct media_session *session, const GUID *time_format LeaveCriticalSection(&session->cs); }
+static void session_set_paused(struct media_session *session, HRESULT status) +{ + session->state = SESSION_STATE_PAUSED; + if (SUCCEEDED(status)) + session_set_caps(session, session->caps & ~MFSESSIONCAP_PAUSE); + IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionPaused, &GUID_NULL, status, NULL); +} + static void session_set_closed(struct media_session *session, HRESULT status) { session->state = SESSION_STATE_CLOSED; @@ -840,10 +848,7 @@ static void session_pause(struct media_session *session) }
if (FAILED(hr)) - { - session->state = SESSION_STATE_PAUSED; - IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionPaused, &GUID_NULL, hr, NULL); - } + session_set_paused(session, hr);
LeaveCriticalSection(&session->cs); } @@ -2185,12 +2190,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->state = SESSION_STATE_PAUSED; - - session_set_caps(session, session->caps & ~MFSESSIONCAP_PAUSE); - - IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionPaused, &GUID_NULL, S_OK, NULL); - + session_set_paused(session, S_OK); break; case SESSION_STATE_STOPPING_SOURCES: if (!session_is_source_nodes_state(session, OBJ_STATE_STOPPED)) @@ -2291,10 +2291,7 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre }
if (FAILED(hr)) - { - session->state = SESSION_STATE_PAUSED; - IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionPaused, &GUID_NULL, hr, NULL); - } + session_set_paused(session, hr);
break; case SESSION_STATE_STOPPING_SINKS:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 27 ++++----------------------- 1 file changed, 4 insertions(+), 23 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 26ea34b441..7b479dbfd7 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -769,8 +769,6 @@ static void session_start(struct media_session *session, const GUID *time_format struct media_source *source; HRESULT hr;
- EnterCriticalSection(&session->cs); - switch (session->state) { case SESSION_STATE_STOPPED: @@ -808,8 +806,6 @@ static void session_start(struct media_session *session, const GUID *time_format default: ; } - - LeaveCriticalSection(&session->cs); }
static void session_set_paused(struct media_session *session, HRESULT status) @@ -832,8 +828,6 @@ static void session_pause(struct media_session *session) { HRESULT hr;
- EnterCriticalSection(&session->cs); - switch (session->state) { case SESSION_STATE_STARTED: @@ -849,8 +843,6 @@ static void session_pause(struct media_session *session)
if (FAILED(hr)) session_set_paused(session, hr); - - LeaveCriticalSection(&session->cs); }
static void session_set_stopped(struct media_session *session, HRESULT status) @@ -873,8 +865,6 @@ static void session_stop(struct media_session *session) { HRESULT hr;
- EnterCriticalSection(&session->cs); - switch (session->state) { case SESSION_STATE_STARTED: @@ -894,8 +884,6 @@ static void session_stop(struct media_session *session) default: ; } - - LeaveCriticalSection(&session->cs); }
static HRESULT session_finalize_sinks(struct media_session *session) @@ -933,8 +921,6 @@ static void session_close(struct media_session *session) { HRESULT hr = S_OK;
- EnterCriticalSection(&session->cs); - switch (session->state) { case SESSION_STATE_STOPPED: @@ -955,8 +941,6 @@ static void session_close(struct media_session *session)
if (FAILED(hr)) session_set_closed(session, hr); - - LeaveCriticalSection(&session->cs); }
static struct media_source *session_get_media_source(struct media_session *session, IMFMediaSource *source) @@ -1333,8 +1317,6 @@ static void session_set_topology(struct media_session *session, DWORD flags, IMF } }
- EnterCriticalSection(&session->cs); - if (flags & MFSESSION_SETTOPOLOGY_CLEAR_CURRENT) { if ((topology && topology == session->presentation.current_topology) || !topology) @@ -1375,8 +1357,6 @@ static void session_set_topology(struct media_session *session, DWORD flags, IMF } }
- LeaveCriticalSection(&session->cs); - if (resolved_topology) IMFTopology_Release(resolved_topology); } @@ -1791,13 +1771,12 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, struct session_op *op = impl_op_from_IUnknown(IMFAsyncResult_GetStateNoAddRef(result)); struct media_session *session = impl_from_commands_callback_IMFAsyncCallback(iface);
+ EnterCriticalSection(&session->cs); + switch (op->command) { case SESSION_CMD_CLEAR_TOPOLOGIES: - EnterCriticalSection(&session->cs); session_clear_topologies(session); - LeaveCriticalSection(&session->cs); - IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionTopologiesCleared, &GUID_NULL, S_OK, NULL); break; @@ -1820,6 +1799,8 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, ; }
+ LeaveCriticalSection(&session->cs); + return S_OK; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 102 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 75 insertions(+), 27 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 7b479dbfd7..bf6e29471d 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -63,6 +63,7 @@ struct session_op PROPVARIANT start_position; } start; } u; + struct list entry; };
struct queued_topology @@ -218,6 +219,7 @@ struct media_session PROPVARIANT start_position; } presentation; struct list topologies; + struct list commands; enum session_state state; DWORD caps; CRITICAL_SECTION cs; @@ -530,7 +532,12 @@ static HRESULT session_submit_command(struct media_session *session, struct sess
EnterCriticalSection(&session->cs); if (SUCCEEDED(hr = session_is_shut_down(session))) - hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, &op->IUnknown_iface); + { + if (list_empty(&session->commands)) + hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, &op->IUnknown_iface); + list_add_tail(&session->commands, &op->entry); + IUnknown_AddRef(&op->IUnknown_iface); + } LeaveCriticalSection(&session->cs);
return hr; @@ -730,6 +737,7 @@ static void session_clear_presentation(struct media_session *session) struct media_source *source, *source2; struct media_sink *sink, *sink2; struct topo_node *node, *node2; + struct session_op *op, *op2;
IMFTopology_Clear(session->presentation.current_topology); session->presentation.topo_status = MF_TOPOSTATUS_INVALID; @@ -762,6 +770,12 @@ static void session_clear_presentation(struct media_session *session) IMFMediaEventGenerator_Release(sink->event_generator); heap_free(sink); } + + LIST_FOR_EACH_ENTRY_SAFE(op, op2, &session->commands, struct session_op, entry) + { + list_remove(&op->entry); + IUnknown_Release(&op->IUnknown_iface); + } }
static void session_start(struct media_session *session, const GUID *time_format, const PROPVARIANT *start_position) @@ -808,12 +822,66 @@ static void session_start(struct media_session *session, const GUID *time_format } }
+static void session_command_complete(struct media_session *session) +{ + struct session_op *op; + struct list *e; + + /* Pop current command, submit next. */ + if ((e = list_head(&session->commands))) + { + op = LIST_ENTRY(e, struct session_op, entry); + list_remove(&op->entry); + IUnknown_Release(&op->IUnknown_iface); + } + + if ((e = list_head(&session->commands))) + { + op = LIST_ENTRY(e, struct session_op, entry); + MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, &op->IUnknown_iface); + } +} + +static void session_set_started(struct media_session *session) +{ + struct media_source *source; + unsigned int caps, flags; + IMFMediaEvent *event; + + session->state = SESSION_STATE_STARTED; + + caps = session->caps | MFSESSIONCAP_PAUSE; + + LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) + { + if (SUCCEEDED(IMFMediaSource_GetCharacteristics(source->source, &flags))) + { + if (!(flags & MFMEDIASOURCE_CAN_PAUSE)) + { + caps &= ~MFSESSIONCAP_PAUSE; + break; + } + } + } + + session_set_caps(session, caps); + + if (SUCCEEDED(MFCreateMediaEvent(MESessionStarted, &GUID_NULL, S_OK, NULL, &event))) + { + IMFMediaEvent_SetUINT64(event, &MF_EVENT_PRESENTATION_TIME_OFFSET, 0); + IMFMediaEventQueue_QueueEvent(session->event_queue, event); + IMFMediaEvent_Release(event); + } + session_command_complete(session); +} + static void session_set_paused(struct media_session *session, HRESULT status) { session->state = SESSION_STATE_PAUSED; if (SUCCEEDED(status)) session_set_caps(session, session->caps & ~MFSESSIONCAP_PAUSE); IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionPaused, &GUID_NULL, status, NULL); + session_command_complete(session); }
static void session_set_closed(struct media_session *session, HRESULT status) @@ -822,6 +890,7 @@ static void session_set_closed(struct media_session *session, HRESULT status) if (SUCCEEDED(status)) session_set_caps(session, session->caps & ~(MFSESSIONCAP_START | MFSESSIONCAP_SEEK)); IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionClosed, &GUID_NULL, status, NULL); + session_command_complete(session); }
static void session_pause(struct media_session *session) @@ -859,6 +928,7 @@ static void session_set_stopped(struct media_session *session, HRESULT status) IMFMediaEventQueue_QueueEvent(session->event_queue, event); IMFMediaEvent_Release(event); } + session_command_complete(session); }
static void session_stop(struct media_session *session) @@ -1779,9 +1849,11 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, session_clear_topologies(session); IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionTopologiesCleared, &GUID_NULL, S_OK, NULL); + session_command_complete(session); break; case SESSION_CMD_SET_TOPOLOGY: session_set_topology(session, op->u.set_topology.flags, op->u.set_topology.topology); + session_command_complete(session); break; case SESSION_CMD_START: session_start(session, &op->u.start.time_format, &op->u.start.start_position); @@ -2210,8 +2282,6 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre { struct media_source *source; enum object_state state; - IMFMediaEvent *event; - DWORD caps, flags; HRESULT hr = S_OK; BOOL changed;
@@ -2234,30 +2304,7 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre if (!session_is_output_nodes_state(session, OBJ_STATE_STARTED)) break;
- session->state = SESSION_STATE_STARTED; - - caps = session->caps | MFSESSIONCAP_PAUSE; - - LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) - { - if (SUCCEEDED(IMFMediaSource_GetCharacteristics(source->source, &flags))) - { - if (!(flags & MFMEDIASOURCE_CAN_PAUSE)) - { - caps &= ~MFSESSIONCAP_PAUSE; - break; - } - } - } - - session_set_caps(session, caps); - - if (SUCCEEDED(MFCreateMediaEvent(MESessionStarted, &GUID_NULL, S_OK, NULL, &event))) - { - IMFMediaEvent_SetUINT64(event, &MF_EVENT_PRESENTATION_TIME_OFFSET, 0); - IMFMediaEventQueue_QueueEvent(session->event_queue, event); - IMFMediaEvent_Release(event); - } + session_set_started(session); break; case SESSION_STATE_PAUSING_SINKS: if (!session_is_output_nodes_state(session, OBJ_STATE_PAUSED)) @@ -3210,6 +3257,7 @@ HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **ses object->sink_finalizer_callback.lpVtbl = &session_sink_finalizer_callback_vtbl; object->refcount = 1; list_init(&object->topologies); + list_init(&object->commands); list_init(&object->presentation.sources); list_init(&object->presentation.sinks); list_init(&object->presentation.nodes);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index bf6e29471d..ba30733fe5 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -43,6 +43,7 @@ enum session_command SESSION_CMD_START, SESSION_CMD_PAUSE, SESSION_CMD_STOP, + SESSION_CMD_END, /* Internal use only. */ };
struct session_op @@ -526,6 +527,14 @@ static HRESULT session_is_shut_down(struct media_session *session) return session->state == SESSION_STATE_SHUT_DOWN ? MF_E_SHUTDOWN : S_OK; }
+static void session_push_back_command(struct media_session *session, enum session_command command) +{ + struct session_op *op; + + if (SUCCEEDED(create_session_op(command, &op))) + list_add_head(&session->commands, &op->entry); +} + static HRESULT session_submit_command(struct media_session *session, struct session_op *op) { HRESULT hr; @@ -933,7 +942,7 @@ static void session_set_stopped(struct media_session *session, HRESULT status)
static void session_stop(struct media_session *session) { - HRESULT hr; + HRESULT hr = MF_E_INVALIDREQUEST;
switch (session->state) { @@ -949,10 +958,12 @@ static void session_stop(struct media_session *session)
break; case SESSION_STATE_STOPPED: - IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionStopped, &GUID_NULL, S_OK, NULL); - break; + hr = S_OK; + /* fallthrough */ default: - ; + IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionStopped, &GUID_NULL, hr, NULL); + session_command_complete(session); + break; } }
@@ -1002,11 +1013,9 @@ static void session_close(struct media_session *session) if (SUCCEEDED(hr = IMFPresentationClock_Stop(session->clock))) session->state = SESSION_STATE_STOPPING_SINKS; break; - case SESSION_STATE_CLOSED: + default: hr = MF_E_INVALIDREQUEST; break; - default: - ; }
if (FAILED(hr)) @@ -2749,8 +2758,9 @@ static void session_raise_end_of_presentation(struct media_session *session) { if (session_nodes_is_mask_set(session, MF_TOPOLOGY_MAX, SOURCE_FLAG_END_OF_PRESENTATION)) { - IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MEEndOfPresentation, &GUID_NULL, S_OK, NULL); session->presentation.flags |= SESSION_FLAG_END_OF_PRESENTATION; + session_push_back_command(session, SESSION_CMD_END); + IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MEEndOfPresentation, &GUID_NULL, S_OK, NULL); } } }