mf: Raise event on session close.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2019-05-31 13:11:29 +03:00 committed by Alexandre Julliard
parent 33a4151bbe
commit 0efb33c2da
2 changed files with 57 additions and 9 deletions

View File

@ -35,7 +35,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
enum session_command enum session_command
{ {
SESSION_CLEAR_TOPOLOGIES, SESSION_CMD_CLEAR_TOPOLOGIES,
SESSION_CMD_CLOSE,
}; };
struct session_op struct session_op
@ -51,6 +52,13 @@ struct queued_topology
IMFTopology *topology; IMFTopology *topology;
}; };
enum session_state
{
SESSION_STATE_STOPPED = 0,
SESSION_STATE_CLOSED,
SESSION_STATE_SHUT_DOWN,
};
struct media_session struct media_session
{ {
IMFMediaSession IMFMediaSession_iface; IMFMediaSession IMFMediaSession_iface;
@ -62,7 +70,7 @@ struct media_session
IMFMediaEventQueue *event_queue; IMFMediaEventQueue *event_queue;
IMFPresentationClock *clock; IMFPresentationClock *clock;
struct list topologies; struct list topologies;
BOOL is_shut_down; enum session_state state;
CRITICAL_SECTION cs; CRITICAL_SECTION cs;
}; };
@ -362,7 +370,16 @@ static HRESULT WINAPI mfsession_SetTopology(IMFMediaSession *iface, DWORD flags,
static HRESULT session_submit_command(struct media_session *session, IUnknown *op) static HRESULT session_submit_command(struct media_session *session, IUnknown *op)
{ {
return MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, op); HRESULT hr;
EnterCriticalSection(&session->cs);
if (session->state == SESSION_STATE_SHUT_DOWN)
hr = MF_E_SHUTDOWN;
else
hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, op);
LeaveCriticalSection(&session->cs);
return hr;
} }
static HRESULT WINAPI mfsession_ClearTopologies(IMFMediaSession *iface) static HRESULT WINAPI mfsession_ClearTopologies(IMFMediaSession *iface)
@ -373,7 +390,7 @@ static HRESULT WINAPI mfsession_ClearTopologies(IMFMediaSession *iface)
TRACE("%p.\n", iface); TRACE("%p.\n", iface);
if (FAILED(hr = create_session_op(SESSION_CLEAR_TOPOLOGIES, &op))) if (FAILED(hr = create_session_op(SESSION_CMD_CLEAR_TOPOLOGIES, &op)))
return hr; return hr;
hr = session_submit_command(session, op); hr = session_submit_command(session, op);
@ -405,9 +422,19 @@ static HRESULT WINAPI mfsession_Stop(IMFMediaSession *iface)
static HRESULT WINAPI mfsession_Close(IMFMediaSession *iface) static HRESULT WINAPI mfsession_Close(IMFMediaSession *iface)
{ {
FIXME("(%p)\n", iface); struct media_session *session = impl_from_IMFMediaSession(iface);
IUnknown *op;
HRESULT hr;
return S_OK; 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);
return hr;
} }
static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface) static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface)
@ -418,11 +445,11 @@ static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface)
FIXME("(%p)\n", iface); FIXME("(%p)\n", iface);
EnterCriticalSection(&session->cs); EnterCriticalSection(&session->cs);
if (session->is_shut_down) if (session->state == SESSION_STATE_SHUT_DOWN)
hr = MF_E_SHUTDOWN; hr = MF_E_SHUTDOWN;
else else
{ {
session->is_shut_down = TRUE; session->state = SESSION_STATE_SHUT_DOWN;
IMFMediaEventQueue_Shutdown(session->event_queue); IMFMediaEventQueue_Shutdown(session->event_queue);
} }
LeaveCriticalSection(&session->cs); LeaveCriticalSection(&session->cs);
@ -572,7 +599,7 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface,
switch (op->command) switch (op->command)
{ {
case SESSION_CLEAR_TOPOLOGIES: case SESSION_CMD_CLEAR_TOPOLOGIES:
EnterCriticalSection(&session->cs); EnterCriticalSection(&session->cs);
session_clear_topologies(session); session_clear_topologies(session);
LeaveCriticalSection(&session->cs); LeaveCriticalSection(&session->cs);
@ -580,6 +607,16 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface,
IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionTopologiesCleared, &GUID_NULL, IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionTopologiesCleared, &GUID_NULL,
S_OK, NULL); S_OK, NULL);
break; break;
case SESSION_CMD_CLOSE:
EnterCriticalSection(&session->cs);
if (session->state != SESSION_STATE_CLOSED)
{
/* FIXME: actually do something to presentation objects */
session->state = SESSION_STATE_CLOSED;
IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionClosed, &GUID_NULL, S_OK, NULL);
}
LeaveCriticalSection(&session->cs);
break;
default: default:
; ;
} }

View File

@ -1000,6 +1000,17 @@ static void test_media_session(void)
IMFMediaSession_Release(session); IMFMediaSession_Release(session);
hr = MFCreateMediaSession(NULL, &session);
ok(hr == S_OK, "Failed to create media session, hr %#x.\n", hr);
hr = IMFMediaSession_Shutdown(session);
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
hr = IMFMediaSession_Close(session);
ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
IMFMediaSession_Release(session);
hr = MFShutdown(); hr = MFShutdown();
ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr); ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr);
} }