From: R��mi Bernon rbernon@codeweavers.com
--- dlls/mf/session.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 87fe77a730f..8c6ab554f5d 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -258,7 +258,10 @@ struct media_session float rate; } presentation; struct list topologies; - struct list commands; + + struct session_op *pending_command; + struct list queued_commands; + enum session_state state; DWORD caps; CRITICAL_SECTION cs; @@ -459,7 +462,7 @@ static void session_push_back_command(struct media_session *session, enum sessio struct session_op *op;
if (SUCCEEDED(create_session_op(command, &op))) - list_add_head(&session->commands, &op->entry); + list_add_head(&session->queued_commands, &op->entry); }
static HRESULT session_submit_command(struct media_session *session, struct session_op *op) @@ -469,9 +472,9 @@ static HRESULT session_submit_command(struct media_session *session, struct sess EnterCriticalSection(&session->cs); if (SUCCEEDED(hr = session_is_shut_down(session))) { - if (list_empty(&session->commands)) + if (!session->pending_command && list_empty(&session->queued_commands)) hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, &op->IUnknown_iface); - list_add_tail(&session->commands, &op->entry); + list_add_tail(&session->queued_commands, &op->entry); IUnknown_AddRef(&op->IUnknown_iface); } LeaveCriticalSection(&session->cs); @@ -735,7 +738,13 @@ static void session_clear_command_list(struct media_session *session) { struct session_op *op, *op2;
- LIST_FOR_EACH_ENTRY_SAFE(op, op2, &session->commands, struct session_op, entry) + if ((op = session->pending_command)) + { + IUnknown_Release(&op->IUnknown_iface); + session->pending_command = NULL; + } + + LIST_FOR_EACH_ENTRY_SAFE(op, op2, &session->queued_commands, struct session_op, entry) { list_remove(&op->entry); IUnknown_Release(&op->IUnknown_iface); @@ -801,15 +810,15 @@ 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))) + if (!(op = session->pending_command)) + WARN("No pending command to complete in session %p\n", session); + else { - op = LIST_ENTRY(e, struct session_op, entry); - list_remove(&op->entry); IUnknown_Release(&op->IUnknown_iface); + session->pending_command = NULL; }
- if ((e = list_head(&session->commands))) + if ((e = list_head(&session->queued_commands))) { op = LIST_ENTRY(e, struct session_op, entry); MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, &op->IUnknown_iface); @@ -2384,6 +2393,12 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface,
EnterCriticalSection(&session->cs);
+ if (session->pending_command) + WARN("Another command is already pending in session %p!\n", session); + + list_remove(&op->entry); + session->pending_command = op; + switch (op->command) { case SESSION_CMD_CLEAR_TOPOLOGIES: @@ -3930,7 +3945,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->queued_commands); list_init(&object->presentation.sources); list_init(&object->presentation.sinks); list_init(&object->presentation.nodes);