From: Santino Mazza smazza@codeweavers.com
--- dlls/mf/tests/mf.c | 198 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index e8d7252aa3f..5e38e0a2a72 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2037,6 +2037,11 @@ static IMFMediaSource *create_media_source(const WCHAR *name, const WCHAR *mime)
static void test_media_session_events(void) { + media_type_desc audio_mp3_desc = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), + ATTR_GUID(MF_MT_SUBTYPE, MFAudioFormat_MP3), + }; static const media_type_desc audio_float_44100 = { ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio), @@ -2062,17 +2067,19 @@ static void test_media_session_events(void) struct test_media_sink media_sink = test_media_sink; struct test_handler handler = test_handler; struct test_source *source_impl; + IMFActivate *sink_activate, *sink_activate2; IMFAsyncCallback *callback, *callback2; IMFMediaType *input_type, *output_type; IMFTopologyNode *src_node, *sink_node; + IMFTopology *topology, *topology2; + IMFMediaSource *source, *source2; IMFPresentationDescriptor *pd; IMFMediaSession *session; IMFStreamDescriptor *sd; IMFAsyncResult *result; - IMFMediaSource *source; - IMFTopology *topology; IMFMediaEvent *event; PROPVARIANT propvar; + BOOL selected; HRESULT hr; ULONG ref;
@@ -2564,6 +2571,193 @@ static void test_media_session_events(void) ok(ref == 0, "Release returned %ld\n", ref);
+ /* Test for events when setting a new topology after stopping a media session */ + if (!(source = create_media_source(L"mp3encdata.bin", L"audio/mp3")) || + !(source2 = create_media_source(L"mp3encdata.bin", L"audio/mp3"))) + { + win_skip("MP3 media source is not supported, skipping tests.\n"); + hr = MFShutdown(); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + return; + } + + + callback = create_test_callback(TRUE); + + hr = MFCreateMediaSession(NULL, &session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateTopology(&topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopology_AddNode(topology, sink_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopology_AddNode(topology, src_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd); + ok(selected, "got selected %u.\n", !!selected); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_source_node(source, -1, src_node, pd, sd); + IMFTopologyNode_Release(src_node); + IMFPresentationDescriptor_Release(pd); + IMFStreamDescriptor_Release(sd); + + hr = MFCreateMediaType(&output_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(output_type, audio_mp3_desc, -1); + hr = MFCreateAudioRendererActivate(&sink_activate); + ok(hr == S_OK, "Failed to create grabber sink, hr %#lx.\n", hr); + IMFMediaType_Release(output_type); + + hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink_activate); + ok(hr == S_OK, "Failed to set object, hr %#lx.\n", hr); + hr = IMFTopologyNode_SetUINT32(sink_node, &MF_TOPONODE_CONNECT_METHOD, MF_CONNECT_ALLOW_DECODER); + ok(hr == S_OK, "Failed to set connect method, hr %#lx.\n", hr); + IMFTopologyNode_Release(sink_node); + + hr = IMFTopology_SetUINT32(topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + + hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateTopology(&topology2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopology_AddNode(topology2, sink_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopology_AddNode(topology2, src_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSource_CreatePresentationDescriptor(source2, &pd); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd); + ok(selected, "got selected %u.\n", !!selected); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_source_node(source2, -1, src_node, pd, sd); + IMFTopologyNode_Release(src_node); + IMFPresentationDescriptor_Release(pd); + IMFStreamDescriptor_Release(sd); + + hr = MFCreateMediaType(&output_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(output_type, audio_mp3_desc, -1); + IMFMediaType_Release(output_type); + + hr = MFCreateAudioRendererActivate(&sink_activate2); + ok(hr == S_OK, "Failed to create grabber sink, hr %#lx.\n", hr); + + hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink_activate2); + ok(hr == S_OK, "Failed to set object, hr %#lx.\n", hr); + hr = IMFTopologyNode_SetUINT32(sink_node, &MF_TOPONODE_CONNECT_METHOD, MF_CONNECT_ALLOW_DECODER); + ok(hr == S_OK, "Failed to set connect method, hr %#lx.\n", hr); + IMFTopologyNode_Release(sink_node); + + hr = IMFTopology_SetUINT32(topology2, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + + propvar.vt = VT_EMPTY; + hr = IMFMediaSession_SetTopology(session, MFSESSION_SETTOPOLOGY_IMMEDIATE, topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event_until_blocking(session, callback, MESessionTopologySet, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_UNKNOWN, "got vt %u\n", propvar.vt); + ok(propvar.punkVal != (IUnknown *)topology, "got punkVal %p\n", propvar.punkVal); + PropVariantClear(&propvar); + + 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, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + ok(propvar.punkVal != (IUnknown *)topology2, "got punkVal %p\n", propvar.punkVal); + PropVariantClear(&propvar); + + propvar.vt = VT_EMPTY; + 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 == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + ok(propvar.punkVal != (IUnknown *)topology2, "got punkVal %p\n", propvar.punkVal); + PropVariantClear(&propvar); + + propvar.vt = VT_EMPTY; + hr = IMFMediaSession_SetTopology(session, MFSESSION_SETTOPOLOGY_IMMEDIATE, topology2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event_until_blocking(session, callback, MESessionTopologySet, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_UNKNOWN, "got vt %u\n", propvar.vt); + ok(propvar.punkVal != (IUnknown *)topology2, "got punkVal %p\n", propvar.punkVal); + PropVariantClear(&propvar); + + 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, 1000, &propvar); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + ok(propvar.punkVal != (IUnknown *)topology2, "got punkVal %p\n", propvar.punkVal); + PropVariantClear(&propvar); + + propvar.vt = VT_EMPTY; + hr = IMFMediaSession_Close(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + { + hr = wait_media_event_until_blocking(session, callback, MESessionClosed, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + ok(propvar.punkVal != (IUnknown *)topology2, "got punkVal %p\n", propvar.punkVal); + PropVariantClear(&propvar); + + hr = IMFMediaSession_Shutdown(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFMediaSession_Release(session); + todo_wine ok(ref == 0, "Release returned %ld\n", ref); + + hr = IMFTopology_Clear(topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFTopology_Release(topology); + ok(ref == 0, "Release returned %ld\n", ref); + hr = IMFMediaSource_Shutdown(source); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFMediaSource_Release(source); + ok(ref == 0, "Release returned %ld\n", ref); + hr = IMFActivate_ShutdownObject(sink_activate); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFActivate_Release(sink_activate); + ok(ref == 0, "Release returned %ld\n", ref); + + hr = IMFTopology_Clear(topology2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFTopology_Release(topology2); + ok(ref == 0, "Release returned %ld\n", ref); + hr = IMFMediaSource_Shutdown(source2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFMediaSource_Release(source2); + todo_wine ok(ref == 0, "Release returned %ld\n", ref); + hr = IMFActivate_ShutdownObject(sink_activate2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ref = IMFActivate_Release(sink_activate2); + todo_wine ok(ref == 0, "Release returned %ld\n", ref); + hr = MFShutdown(); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); }