From: Bernhard Kölbl <bkoelbl@codeweavers.com> Signed-off-by: Bernhard Kölbl <bkoelbl@codeweavers.com> --- dlls/mf/session.c | 4 +- dlls/mf/tests/mf.c | 121 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+), 1 deletion(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 8d2ca079634..b7012e69883 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -2117,7 +2117,7 @@ static void session_set_topology(struct media_session *session, DWORD flags, IMF session_raise_topology_set(session, topology, hr); /* With no current topology set it right away, otherwise queue. */ - if (topology) + if (SUCCEEDED(hr) && topology) { struct queued_topology *queued_topology; @@ -4932,6 +4932,8 @@ HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **ses goto failed; } + session_clear_presentation(object); + *session = &object->IMFMediaSession_iface; return S_OK; diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 0c0590ed195..10a0e7775bb 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -8436,6 +8436,126 @@ static void test_media_session_seek(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); } +static void test_media_session_invalid_topology(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; + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr); + + 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(); + return; + } + + /* test starting an invalid topology */ + source = create_test_source(TRUE); + callback = create_test_callback(TRUE); + + hr = MFCreateMediaSession(NULL, &session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateAudioRendererActivate(&sink_activate); + ok(hr == S_OK, "Failed to create audio renderer sink, 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); + + propvar.vt = VT_I8; + propvar.hVal.QuadPart = 0; + hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionStarted, 5000, &propvar); + ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSession_Stop(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFMediaSource_Release(source); + IMFActivate_ShutdownObject(sink_activate); + IMFActivate_Release(sink_activate); + + /* then start a valid topology */ + source = create_test_source(FALSE); + + 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); + + 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_I8; + propvar.hVal.QuadPart = 0; + hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionStarted, 5000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFMediaSource_Release(source); + IMFActivate_ShutdownObject(sink_activate); + IMFActivate_Release(sink_activate); + + hr = IMFMediaSession_Stop(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* try invalid topology once again */ + source = create_test_source(TRUE); + + hr = MFCreateAudioRendererActivate(&sink_activate); + ok(hr == S_OK, "Failed to create audio renderer sink, 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); + + propvar.vt = VT_I8; + propvar.hVal.QuadPart = 10; + hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionStarted, 5000, &propvar); + ok(hr == E_FAIL, "Unexpected hr %#lx.\n", hr); /* fails because unseekable source is still in use */ + + hr = IMFMediaSession_Stop(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFMediaSource_Release(source); + IMFActivate_ShutdownObject(sink_activate); + IMFActivate_Release(sink_activate); + + IMFAsyncCallback_Release(callback); + IMFMediaSession_Release(session); + + hr = MFShutdown(); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +} + START_TEST(mf) { init_functions(); @@ -8475,4 +8595,5 @@ START_TEST(mf) test_media_session_source_shutdown(); test_media_session_thinning(); test_media_session_seek(); + test_media_session_invalid_topology(); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9742