These changes are the documented way to implement IMFMediaEventGenerator for a media source. On top of !6783 it seems to greatly reduce the chance of hanging while switching characters in Killsquad if tracing is not enabled.
-- v4: winegstreamer: Send media source shutdown notification via IMFMediaShutdownNotify. mf: Introduce IMFMediaShutdownNotify for notification of media source shutdown. mf: Handle media source Start() failure due to source shutdown. mf: Handle media source event subscription failure due to source shutdown. mf: Handle media source BeginGetEvent() failure due to shutdown. mf: Handle media source EndGetEvent() failure due to shutdown. mf/tests: Add tests for shutting down a media source used in a session. winegstreamer: Return the result code from media_source_Pause().
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/winegstreamer/media_source.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 030d0c1b9a2..8dc8145b60f 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -1537,7 +1537,7 @@ static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface)
LeaveCriticalSection(&source->cs);
- return S_OK; + return hr; }
static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/mf/tests/mf.c | 174 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 09830191363..429d693f14f 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -6434,6 +6434,179 @@ static void test_media_session_Start(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); }
+static void test_media_session_source_shutdown(void) +{ + media_type_desc video_rgb32_desc = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), + }; + struct test_grabber_callback *grabber_callback; + IMFActivate *sink_activate; + IMFAsyncCallback *callback; + IMFMediaType *output_type; + IMFMediaSession *session; + IMFMediaSource *source; + IMFTopology *topology; + PROPVARIANT propvar; + UINT64 duration; + HRESULT hr; + enum + { + TEST_START, + TEST_RESTART, + TEST_PAUSE, + TEST_STOP, + TEST_CLOSE, + } shutdown_point; + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr); + + /* These tests don't cover asynchronous shutdown, which is difficult to consistently test. */ + + for (shutdown_point = TEST_START; shutdown_point <= TEST_CLOSE; ++shutdown_point) + { + winetest_push_context("Test %d", shutdown_point); + + if (!(source = create_media_source(L"test.mp4", L"video/mp4"))) + { + todo_wine /* Gitlab CI Debian runner */ + win_skip("MP4 media source is not supported, skipping tests.\n"); + MFShutdown(); + winetest_pop_context(); + return; + } + + grabber_callback = impl_from_IMFSampleGrabberSinkCallback(create_test_grabber_callback()); + hr = MFCreateMediaType(&output_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(output_type, video_rgb32_desc, -1); + hr = MFCreateSampleGrabberSinkActivate(output_type, &grabber_callback->IMFSampleGrabberSinkCallback_iface, &sink_activate); + ok(hr == S_OK, "Failed to create grabber sink, hr %#lx.\n", hr); + IMFMediaType_Release(output_type); + + hr = MFCreateMediaSession(NULL, &session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + topology = create_test_topology(source, sink_activate, &duration); + hr = IMFMediaSession_SetTopology(session, 0, topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFTopology_Release(topology); + + callback = create_test_callback(TRUE); + + propvar.vt = VT_EMPTY; + hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); + if (shutdown_point == TEST_START) + IMFMediaSource_Shutdown(source); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionStarted, 5000, &propvar); + todo_wine_if(shutdown_point == TEST_START) + ok(hr == (shutdown_point == TEST_START ? MF_E_INVALIDREQUEST : S_OK), "Unexpected hr %#lx.\n", hr); + + switch (shutdown_point) + { + case TEST_RESTART: + /* Seek to 1s */ + propvar.vt = VT_I8; + propvar.hVal.QuadPart = 10000000; + hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); + IMFMediaSource_Shutdown(source); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionStarted, 5000, &propvar); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + break; + case TEST_PAUSE: + hr = IMFMediaSession_Pause(session); + IMFMediaSource_Shutdown(source); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionPaused, 1000, &propvar); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr); + break; + case TEST_STOP: + hr = IMFMediaSession_Stop(session); + IMFMediaSource_Shutdown(source); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionStopped, 1000, &propvar); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr); + break; + case TEST_CLOSE: + hr = IMFMediaSession_Close(session); + IMFMediaSource_Shutdown(source); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionClosed, 1000, &propvar); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr); + default: + break; + } + + if (shutdown_point == TEST_CLOSE) + goto done; + + IMFMediaSource_Release(source); + + IMFActivate_ShutdownObject(sink_activate); + IMFActivate_Release(sink_activate); + IMFSampleGrabberSinkCallback_Release(&grabber_callback->IMFSampleGrabberSinkCallback_iface); + + /* Re-use the session. For shutdown after Start(), the session can be re-used in native + * Windows but waits may still return MF_E_SHUTDOWN. The other tests can cause timeouts + * on close. Clearing topologies has no effect on these errors. */ + + grabber_callback = impl_from_IMFSampleGrabberSinkCallback(create_test_grabber_callback()); + hr = MFCreateMediaType(&output_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(output_type, video_rgb32_desc, -1); + hr = MFCreateSampleGrabberSinkActivate(output_type, &grabber_callback->IMFSampleGrabberSinkCallback_iface, &sink_activate); + ok(hr == S_OK, "Failed to create grabber sink, hr %#lx.\n", hr); + IMFMediaType_Release(output_type); + + source = create_media_source(L"test.mp4", L"video/mp4"); + ok(!!source, "Failed to create source.\n"); + + topology = create_test_topology(source, sink_activate, &duration); + hr = IMFMediaSession_SetTopology(session, 0, topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFTopology_Release(topology); + + propvar.vt = VT_EMPTY; + hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event_until_blocking(session, callback, MESessionStarted, 5000, &propvar); + flaky_wine + ok(hr == MF_E_SHUTDOWN || hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSession_Stop(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event_until_blocking(session, callback, MESessionStopped, 1000, &propvar); + ok(hr == MF_E_SHUTDOWN || hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaSession_Close(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event_until_blocking(session, callback, MESessionClosed, 1000, &propvar); + if (shutdown_point >= TEST_PAUSE) + ok(hr == MF_E_SHUTDOWN || hr == S_OK || hr == WAIT_TIMEOUT, "Unexpected hr %#lx.\n", hr); + else + ok(hr == MF_E_SHUTDOWN || hr == S_OK, "Unexpected hr %#lx.\n", hr); + +done: + hr = IMFMediaSession_Shutdown(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFMediaSource_Release(source); + IMFAsyncCallback_Release(callback); + IMFMediaSession_Release(session); + IMFActivate_ShutdownObject(sink_activate); + IMFActivate_Release(sink_activate); + IMFSampleGrabberSinkCallback_Release(&grabber_callback->IMFSampleGrabberSinkCallback_iface); + + winetest_pop_context(); + } + + hr = MFShutdown(); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +} + static void test_MFEnumDeviceSources(void) { static const WCHAR devinterface_audio_capture_wstr[] = L"{2eef81be-33fa-4800-9670-1cd474972c3f}"; @@ -6658,4 +6831,5 @@ START_TEST(mf) test_media_session_Start(); test_MFEnumDeviceSources(); test_media_session_Close(); + test_media_session_source_shutdown(); }
From: Conor McCarthy cmccarthy@codeweavers.com
Windows robustly handles asynchronous shutdown of a media source used in a session. --- dlls/mf/session.c | 74 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index e24cc6376b4..817ea5f3efd 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -1001,6 +1001,32 @@ static void session_flush_nodes(struct media_session *session) } }
+static void session_purge_pending_commands(struct media_session *session) +{ + struct session_op *op, *op2; + + /* Purge all commands which are no longer valid after a forced source shutdown. + * Calling Stop() in this case is not required in native Windows. */ + LIST_FOR_EACH_ENTRY_SAFE(op, op2, &session->commands, struct session_op, entry) + { + if (op->command == SESSION_CMD_CLEAR_TOPOLOGIES || op->command == SESSION_CMD_SET_TOPOLOGY + || op->command == SESSION_CMD_CLOSE || op->command == SESSION_CMD_SHUTDOWN) + continue; + list_remove(&op->entry); + IUnknown_Release(&op->IUnknown_iface); + } +} + +static void session_reset(struct media_session *session) +{ + /* Media sessions in native Windows are not consistently usable after a + * forced source shutdown, but we try to clean up as well as possible. */ + session->state = SESSION_STATE_STOPPED; + session_clear_presentation(session); + session_purge_pending_commands(session); + session_command_complete(session); +} + static void session_start(struct media_session *session, const GUID *time_format, const PROPVARIANT *start_position) { struct media_source *source; @@ -2829,6 +2855,43 @@ static const IMFAsyncCallbackVtbl session_sa_ready_callback_vtbl = session_sa_ready_callback_Invoke, };
+static void session_handle_source_shutdown(struct media_session *session) +{ + BOOL finalize_sinks; + + EnterCriticalSection(&session->cs); + + finalize_sinks = session->presentation.flags & SESSION_FLAG_FINALIZE_SINKS; + + /* When stopping the session, MESessionStopped is sent without waiting + * for MESourceStopped, so we need do nothing in that case. */ + switch (session->state) + { + case SESSION_STATE_STARTING_SOURCES: + case SESSION_STATE_RESTARTING_SOURCES: + case SESSION_STATE_PREROLLING_SINKS: + case SESSION_STATE_STARTING_SINKS: + IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionStarted, &GUID_NULL, + MF_E_INVALIDREQUEST, NULL); + break; + case SESSION_STATE_STOPPING_SINKS: + case SESSION_STATE_STOPPING_SOURCES: + if (!finalize_sinks) + IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MESessionStopped, &GUID_NULL, + MF_E_INVALIDREQUEST, NULL); + break; + default: + break; + } + + if (session->state != SESSION_STATE_CLOSED && finalize_sinks) + session_finalize_sinks(session); + else + session_reset(session); + + LeaveCriticalSection(&session->cs); +} + static HRESULT WINAPI session_events_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IMFAsyncCallback) || @@ -4050,8 +4113,15 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM
if (FAILED(hr = IMFMediaEventGenerator_EndGetEvent(event_source, result, &event))) { - WARN("Failed to get event from %p, hr %#lx.\n", event_source, hr); - IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MEError, &GUID_NULL, hr, NULL); + if (hr == MF_E_SHUTDOWN) + { + session_handle_source_shutdown(session); + } + else + { + WARN("Failed to get event from %p, hr %#lx.\n", event_source, hr); + IMFMediaEventQueue_QueueEventParamVar(session->event_queue, MEError, &GUID_NULL, hr, NULL); + } IMFMediaEventGenerator_Release(event_source); return hr; }
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/mf/session.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 817ea5f3efd..ea8196aae4c 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -4319,8 +4319,15 @@ failed:
if (FAILED(hr = IMFMediaEventGenerator_BeginGetEvent(event_source, iface, (IUnknown *)event_source))) { - WARN("Failed to re-subscribe, hr %#lx.\n", hr); - IMFMediaEventQueue_QueueEvent(session->event_queue, event); + if (hr == MF_E_SHUTDOWN) + { + session_handle_source_shutdown(session); + } + else + { + WARN("Failed to re-subscribe, hr %#lx.\n", hr); + IMFMediaEventQueue_QueueEvent(session->event_queue, event); + } }
if (event)
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/mf/session.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index ea8196aae4c..bfaca8ca2a4 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -1027,6 +1027,16 @@ static void session_reset(struct media_session *session) session_command_complete(session); }
+static void session_handle_start_error(struct media_session *session, HRESULT hr) +{ + if (hr == MF_E_SHUTDOWN) + { + session_reset(session); + hr = MF_E_INVALIDREQUEST; + } + session_command_complete_with_event(session, MESessionStarted, hr, NULL); +} + static void session_start(struct media_session *session, const GUID *time_format, const PROPVARIANT *start_position) { struct media_source *source; @@ -1055,7 +1065,7 @@ static void session_start(struct media_session *session, const GUID *time_format
if (FAILED(hr = session_subscribe_sources(session))) { - session_command_complete_with_event(session, MESessionStarted, hr, NULL); + session_handle_start_error(session, hr); return; }
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/mf/session.c | 2 +- dlls/mf/tests/mf.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index bfaca8ca2a4..66ec634ea59 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -1074,7 +1074,7 @@ static void session_start(struct media_session *session, const GUID *time_format if (FAILED(hr = IMFMediaSource_Start(source->source, source->pd, &GUID_NULL, start_position))) { WARN("Failed to start media source %p, hr %#lx.\n", source->source, hr); - session_command_complete_with_event(session, MESessionStarted, hr, NULL); + session_handle_start_error(session, hr); return; } } diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 429d693f14f..c061250b1f2 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -6501,7 +6501,6 @@ static void test_media_session_source_shutdown(void) IMFMediaSource_Shutdown(source); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = wait_media_event(session, callback, MESessionStarted, 5000, &propvar); - todo_wine_if(shutdown_point == TEST_START) ok(hr == (shutdown_point == TEST_START ? MF_E_INVALIDREQUEST : S_OK), "Unexpected hr %#lx.\n", hr);
switch (shutdown_point)
From: Conor McCarthy cmccarthy@codeweavers.com
Native Windows robustly handles unexpected shutdown of a media source used in a session, but if the native source is contained within a wrapper source object, it hangs even if BeginGetEvent() fails with MF_E_SHUTDOWN, which should be easily handled. This implies that Windows uses a private interface for shutdown notification, and its proper functioning is disrupted when the source is wrapped. --- dlls/mf/session.c | 84 +++++++++++++++++++++++++++++++++++++ include/wine/mfinternal.idl | 14 +++++++ 2 files changed, 98 insertions(+)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 66ec634ea59..4c0e1f8819a 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -29,6 +29,7 @@
#include "wine/debug.h" #include "wine/list.h" +#include "wine/mfinternal.h"
#include "mf_private.h"
@@ -230,9 +231,11 @@ struct media_session IMFTopologyNodeAttributeEditor IMFTopologyNodeAttributeEditor_iface; IMFAsyncCallback commands_callback; IMFAsyncCallback sa_ready_callback; + IMFAsyncCallback shutdown_callback; IMFAsyncCallback events_callback; IMFAsyncCallback sink_finalizer_callback; LONG refcount; + BOOL source_shutdown_handled; IMFMediaEventQueue *event_queue; IMFPresentationClock *clock; IMFPresentationTimeSource *system_time_source; @@ -278,6 +281,11 @@ static struct media_session *impl_from_sa_ready_callback_IMFAsyncCallback(IMFAsy return CONTAINING_RECORD(iface, struct media_session, sa_ready_callback); }
+static struct media_session *impl_from_shutdown_callback_IMFAsyncCallback(IMFAsyncCallback *iface) +{ + return CONTAINING_RECORD(iface, struct media_session, shutdown_callback); +} + static struct media_session *impl_from_events_callback_IMFAsyncCallback(IMFAsyncCallback *iface) { return CONTAINING_RECORD(iface, struct media_session, events_callback); @@ -1583,6 +1591,7 @@ static void session_release_media_source(struct media_source *source) static HRESULT session_add_media_source(struct media_session *session, IMFTopologyNode *node, IMFMediaSource *source) { struct media_source *media_source; + IMFMediaShutdownNotify *notify; HRESULT hr;
if (session_get_media_source(session, source)) @@ -1594,6 +1603,17 @@ static HRESULT session_add_media_source(struct media_session *session, IMFTopolo media_source->source = source; IMFMediaSource_AddRef(media_source->source);
+ if (SUCCEEDED(hr = IMFMediaSource_QueryInterface(media_source->source, + &IID_IMFMediaShutdownNotify, (void **)¬ify))) + { + IMFMediaShutdownNotify_set_notification_callback(notify, &session->shutdown_callback, + (IUnknown *)media_source->source); + } + else + { + TRACE("IMFMediaShutdownNotify unsupported, hr %#lx; session not robust to unexpected shutdown.\n", hr); + } + hr = IMFTopologyNode_GetUnknown(node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, &IID_IMFPresentationDescriptor, (void **)&media_source->pd);
@@ -1960,6 +1980,8 @@ static HRESULT session_set_current_topology(struct media_session *session, IMFTo return hr; }
+ session->source_shutdown_handled = FALSE; + session_collect_nodes(session);
LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry) @@ -2871,6 +2893,14 @@ static void session_handle_source_shutdown(struct media_session *session)
EnterCriticalSection(&session->cs);
+ /* Shutdown may be notified via a dedicated callback or by Begin/EndGetEvent() failure. */ + if (session->source_shutdown_handled) + { + LeaveCriticalSection(&session->cs); + return; + } + session->source_shutdown_handled = TRUE; + finalize_sinks = session->presentation.flags & SESSION_FLAG_FINALIZE_SINKS;
/* When stopping the session, MESessionStopped is sent without waiting @@ -2902,6 +2932,59 @@ static void session_handle_source_shutdown(struct media_session *session) LeaveCriticalSection(&session->cs); }
+static HRESULT WINAPI session_shutdown_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IMFAsyncCallback) + || IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IMFAsyncCallback_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI session_shutdown_callback_AddRef(IMFAsyncCallback *iface) +{ + struct media_session *session = impl_from_shutdown_callback_IMFAsyncCallback(iface); + return IMFMediaSession_AddRef(&session->IMFMediaSession_iface); +} + +static ULONG WINAPI session_shutdown_callback_Release(IMFAsyncCallback *iface) +{ + struct media_session *session = impl_from_shutdown_callback_IMFAsyncCallback(iface); + return IMFMediaSession_Release(&session->IMFMediaSession_iface); +} + +static HRESULT WINAPI session_shutdown_callback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI session_shutdown_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +{ + struct media_session *session = impl_from_shutdown_callback_IMFAsyncCallback(iface); + IMFMediaSource *source = (IMFMediaSource *)IMFAsyncResult_GetStateNoAddRef(result); + + TRACE("Source %p was shut down.\n", source); + + session_handle_source_shutdown(session); + + return S_OK; +} + +static const IMFAsyncCallbackVtbl session_shutdown_callback_vtbl = +{ + session_shutdown_callback_QueryInterface, + session_shutdown_callback_AddRef, + session_shutdown_callback_Release, + session_shutdown_callback_GetParameters, + session_shutdown_callback_Invoke, +}; + static HRESULT WINAPI session_events_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IMFAsyncCallback) || @@ -4705,6 +4788,7 @@ HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **ses object->IMFTopologyNodeAttributeEditor_iface.lpVtbl = &node_attribute_editor_vtbl; object->commands_callback.lpVtbl = &session_commands_callback_vtbl; object->sa_ready_callback.lpVtbl = &session_sa_ready_callback_vtbl; + object->shutdown_callback.lpVtbl = &session_shutdown_callback_vtbl; object->events_callback.lpVtbl = &session_events_callback_vtbl; object->sink_finalizer_callback.lpVtbl = &session_sink_finalizer_callback_vtbl; object->refcount = 1; diff --git a/include/wine/mfinternal.idl b/include/wine/mfinternal.idl index 0106c2b50d5..3fc915c0437 100644 --- a/include/wine/mfinternal.idl +++ b/include/wine/mfinternal.idl @@ -25,6 +25,7 @@ import "unknwn.idl"; interface IMFByteStream; interface IMFMediaSink; interface IMFMediaType; +interface IMFAsyncCallback;
/* Internal interface used to instantiate registered sinks. It should be compatible, except for used method names. */ @@ -44,6 +45,19 @@ interface IMFSinkClassFactory : IUnknown ); }
+[ + uuid(0aab315c-33a4-43db-af6b-c9c86921034e), + object, + local +] +interface IMFMediaShutdownNotify : IUnknown +{ + HRESULT set_notification_callback( + [in] IMFAsyncCallback *callback, + [in] IUnknown *state + ); +} + cpp_quote("DEFINE_GUID(CLSID_MF3GPSinkClassFactory, 0xe54cdfaf, 0x2381, 0x4cad, 0xab, 0x99, 0xf3, 0x85, 0x17, 0x12, 0x7d, 0x5c);") cpp_quote("DEFINE_GUID(CLSID_MFAC3SinkClassFactory, 0x255a6fda, 0x6f93, 0x4e8a, 0x96, 0x11, 0xde, 0xd1, 0x16, 0x9e, 0xef, 0xb4);") cpp_quote("DEFINE_GUID(CLSID_MFADTSSinkClassFactory, 0xd7ca55ab, 0x5022, 0x4db3, 0xa5, 0x99, 0xab, 0xaf, 0xa3, 0x58, 0xe6, 0xf3);")
From: Conor McCarthy cmccarthy@codeweavers.com
--- dlls/winegstreamer/media_source.c | 94 +++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 8dc8145b60f..16307a6fa87 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -174,12 +174,16 @@ struct media_source IMFGetService IMFGetService_iface; IMFRateSupport IMFRateSupport_iface; IMFRateControl IMFRateControl_iface; + IMFMediaShutdownNotify IMFMediaShutdownNotify_iface; IMFAsyncCallback async_commands_callback; LONG ref; DWORD async_commands_queue; IMFMediaEventQueue *event_queue; IMFByteStream *byte_stream;
+ IMFAsyncCallback *shutdown_callback; + IUnknown *shutdown_state; + CRITICAL_SECTION cs;
UINT64 file_size; @@ -229,6 +233,11 @@ static inline struct media_source *impl_from_IMFRateControl(IMFRateControl *ifac return CONTAINING_RECORD(iface, struct media_source, IMFRateControl_iface); }
+static inline struct media_source *impl_from_IMFMediaShutdownNotify(IMFMediaShutdownNotify *iface) +{ + return CONTAINING_RECORD(iface, struct media_source, IMFMediaShutdownNotify_iface); +} + static inline struct media_source *impl_from_async_commands_callback_IMFAsyncCallback(IMFAsyncCallback *iface) { return CONTAINING_RECORD(iface, struct media_source, async_commands_callback); @@ -1315,6 +1324,77 @@ static const IMFRateControlVtbl media_source_rate_control_vtbl = media_source_rate_control_GetRate, };
+static void media_source_release_shutdown_callback(struct media_source *source) +{ + if (source->shutdown_callback) + IMFAsyncCallback_Release(source->shutdown_callback); + if (source->shutdown_state) + IUnknown_Release(source->shutdown_state); + + source->shutdown_callback = NULL; + source->shutdown_state = NULL; +} + +static HRESULT WINAPI media_source_shutdown_notify_QueryInterface(IMFMediaShutdownNotify *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IMFMediaShutdownNotify) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IUnknown_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI media_source_shutdown_notify_AddRef(IMFMediaShutdownNotify *iface) +{ + struct media_source *source = impl_from_IMFMediaShutdownNotify(iface); + return IMFMediaSource_AddRef(&source->IMFMediaSource_iface); +} + +static ULONG WINAPI media_source_shutdown_notify_Release(IMFMediaShutdownNotify *iface) +{ + struct media_source *source = impl_from_IMFMediaShutdownNotify(iface); + return IMFMediaSource_Release(&source->IMFMediaSource_iface); +} + +static HRESULT media_source_shutdown_notify_set_notification_callback(IMFMediaShutdownNotify *iface, + IMFAsyncCallback *callback, IUnknown *state) +{ + struct media_source *source = impl_from_IMFMediaShutdownNotify(iface); + HRESULT hr = S_OK; + + EnterCriticalSection(&source->cs); + + if (source->state == SOURCE_SHUTDOWN) + hr = MF_E_SHUTDOWN; + else + { + media_source_release_shutdown_callback(source); + source->shutdown_callback = callback; + IMFAsyncCallback_AddRef(callback); + source->shutdown_state = state; + if (state) + IUnknown_AddRef(state); + } + + LeaveCriticalSection(&source->cs); + + return hr; +} + +static const IMFMediaShutdownNotifyVtbl media_source_shutdown_notify_vtbl = +{ + media_source_shutdown_notify_QueryInterface, + media_source_shutdown_notify_AddRef, + media_source_shutdown_notify_Release, + media_source_shutdown_notify_set_notification_callback, +}; + static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) { struct media_source *source = impl_from_IMFMediaSource(iface); @@ -1331,6 +1411,10 @@ static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID { *out = &source->IMFGetService_iface; } + else if (IsEqualIID(riid, &IID_IMFMediaShutdownNotify)) + { + *out = &source->IMFMediaShutdownNotify_iface; + } else { FIXME("%s, %p.\n", debugstr_guid(riid), out); @@ -1361,6 +1445,7 @@ static ULONG WINAPI media_source_Release(IMFMediaSource *iface)
if (!ref) { + media_source_release_shutdown_callback(source); IMFMediaSource_Shutdown(iface); IMFMediaEventQueue_Release(source->event_queue); IMFByteStream_Release(source->byte_stream); @@ -1543,6 +1628,7 @@ static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface) static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) { struct media_source *source = impl_from_IMFMediaSource(iface); + HRESULT hr;
TRACE("%p.\n", iface);
@@ -1575,6 +1661,13 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) free(source->descriptors); free(source->streams);
+ if (source->shutdown_callback) + { + if (FAILED(hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, source->shutdown_callback, source->shutdown_state))) + WARN("Failed to put shutdown notification, hr %#lx.\n", hr); + media_source_release_shutdown_callback(source); + } + LeaveCriticalSection(&source->cs);
MFUnlockWorkQueue(source->async_commands_queue); @@ -1633,6 +1726,7 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc object->IMFGetService_iface.lpVtbl = &media_source_get_service_vtbl; object->IMFRateSupport_iface.lpVtbl = &media_source_rate_support_vtbl; object->IMFRateControl_iface.lpVtbl = &media_source_rate_control_vtbl; + object->IMFMediaShutdownNotify_iface.lpVtbl = &media_source_shutdown_notify_vtbl; object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl; object->ref = 1; object->byte_stream = context->stream;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=150075
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
mf: mf.c:5383: Test failed: got hr 0x80072f8f mf.c:5383: Test failed: got hr 0x80072f8f mf.c:5454: Test failed: got hr 0x80072f8f mf.c:5460: Test failed: got hr 0x80072f8f mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf.c:6339: Test failed: WaitForSingleObject returned 258 mf.c:6339: Test failed: Unexpected hr 0xd36d8. mf: Timeout
=== debian11 (32 bit report) ===
mf: mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf.c:6523: Test failed: Test 2: WaitForSingleObject returned 258 mf.c:6523: Test failed: Test 2: Unexpected hr 0xd36d8. mf: Timeout
=== debian11 (32 bit de report) ===
mf: mf.c:6781: Test failed: Unexpected hr 0. mf.c:6524: Test failed: Test 2: Unexpected hr 0xc00d36fc.
=== debian11 (32 bit fr report) ===
mf: mf.c:6781: Test failed: Unexpected hr 0.
=== debian11 (32 bit he:IL report) ===
mf: mf.c:6524: Test failed: Test 2: Unexpected hr 0xc00d36fc.
=== debian11b (32 bit WoW report) ===
mf: mf.c:6531: Test failed: Test 3: Unexpected hr 0. mf.c:6538: Test failed: Test 4: Unexpected hr 0.
=== debian11b (64 bit WoW report) ===
mf: mf.c:6781: Test failed: Unexpected hr 0.
=== debian11b (build log) ===
0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins. 0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins. 0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins. 0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins. 0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins. 0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins. 0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins. 0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins. 0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins. 0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins. 0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins. 0134:err:winediag:video_processor_create GStreamer doesn't support video conversion, please install appropriate plugins.
I sorted out multithreaded source shutdown using `CreateThread()`. Windows handles unexpected shutdown without issue when the media source is not wrapped, but with a wrapped source the session fails to raise `MESessionStarted`. It cannot even handle failure of `BeginGetEvent()` with `MF_E_SHUTDOWN`. (The wrapped source works fine without shutdown). This implies that a private interface is used for all cases of unexpected shutdown. Therefore I changed this MR to use a private interface. The work queue changes are no longer needed and can be raised in a separate MR.
For a private interface used internally it doesn't seem necessary to check that the shut-down media source is actually used by the session. It's interesting to note, however that if native Windows validates this it would explain why wrapping the source disrupts shutdown handling.