From: Santino Mazza smazza@codeweavers.com
--- dlls/mf/tests/mf.c | 152 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 150 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 58688c0cfba..14a66bc9f57 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2006,9 +2006,10 @@ static HRESULT wait_media_event_(int line, IMFMediaSession *session, IMFAsyncCal return status; }
-#define wait_media_event_until_blocking(a, b, c, d, e) wait_media_event_until_blocking_(__LINE__, a, b, c, d, e) +#define get_media_event(a, b, c, d, e, f) wait_media_event_until_blocking_(__LINE__, a, b, c, d, e, f) +#define wait_media_event_until_blocking(a, b, c, d, e) wait_media_event_until_blocking_(__LINE__, a, b, c, d, e, NULL) static HRESULT wait_media_event_until_blocking_(int line, IMFMediaSession *session, IMFAsyncCallback *callback, - MediaEventType expect_type, DWORD timeout, PROPVARIANT *value) + MediaEventType expect_type, DWORD timeout, PROPVARIANT *value, IMFMediaEvent **media_event) { struct test_callback *impl = impl_from_IMFAsyncCallback(callback); MediaEventType type; @@ -2016,6 +2017,9 @@ static HRESULT wait_media_event_until_blocking_(int line, IMFMediaSession *sessi DWORD ret; GUID guid;
+ if (media_event) + *media_event = NULL; + do { hr = IMFMediaSession_BeginGetEvent(session, &impl->IMFAsyncCallback_iface, (IUnknown *)session); @@ -2038,6 +2042,12 @@ static HRESULT wait_media_event_until_blocking_(int line, IMFMediaSession *sessi hr = IMFMediaEvent_GetStatus(impl->media_event, &status); ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ if (media_event) + { + IMFMediaEvent_AddRef(impl->media_event); + *media_event = impl->media_event; + } + return status; }
@@ -3452,6 +3462,143 @@ static void test_media_session_rate_control(void) ok(hr == S_OK, "Shutdown failure, hr %#lx.\n", hr); }
+#define check_topologyid(a, b) check_topologyid_(__LINE__, a, b) +static void check_topologyid_(unsigned int line, IMFMediaEvent *event, TOPOID expected_topoid) +{ + PROPVARIANT pv; + TOPOID topoid; + IMFTopology *topology; + + IMFMediaEvent_GetValue(event, &pv); + IUnknown_QueryInterface(pv.punkVal, &IID_IMFTopology, (void**)&topology); + IMFTopology_GetTopologyID(topology, &topoid); + ok_(__FILE__, line)(topoid == expected_topoid, "Expected topoid %I64u, got %I64u\n", expected_topoid, topoid); + IMFTopology_Release(topology); +} + +#define check_topostatus(a, b) check_topostatus_(__LINE__, a, b) +static void check_topostatus_(unsigned int line, IMFMediaEvent *event, UINT32 expected_status) +{ + UINT32 topostatus; + IMFMediaEvent_GetUINT32(event, &MF_EVENT_TOPOLOGY_STATUS, &topostatus); + ok_(__FILE__, line)(topostatus == expected_status, "Expected MF_TOPOSTATUS_READY got %d\n", topostatus); +} + +static IMFTopology *create_topology_from_file(LPCWSTR file, LPCWSTR mime) +{ + IMFTopologyNode *src_node, *sink_node; + IMFPresentationDescriptor *pd; + IMFActivate *sar_activate; + IMFStreamDescriptor *sd; + IMFMediaSource *source; + IMFTopology *topology; + BOOL selected; + HRESULT hr; + + if(!(source = create_media_source(file, mime))) + return NULL; + + hr = MFCreateTopology(&topology); + 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); + + IMFMediaSource_CreatePresentationDescriptor(source, &pd); + hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_source_node(source, -1, src_node, pd, sd); + + hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateAudioRendererActivate(&sar_activate); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFTopologyNode_SetObject(sink_node, (IUnknown *)sar_activate); + + IMFTopology_AddNode(topology, src_node); + IMFTopology_AddNode(topology, sink_node); + IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0); + + IMFTopologyNode_Release(src_node); + IMFTopologyNode_Release(sink_node); + IMFActivate_Release(sar_activate); + IMFPresentationDescriptor_Release(pd); + IMFStreamDescriptor_Release(sd); + + return topology; +} + +static void test_media_session_topologies(void) +{ + IMFTopology *topology; + IMFAsyncCallback *callback; + IMFMediaSession *session; + IMFMediaEvent *event; + TOPOID topoid; + PROPVARIANT pv; + HRESULT hr; + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Startup failure, hr %#lx.\n", hr); + + if (!(topology = create_topology_from_file(L"mp3encdata.bin", L"audio/mpeg"))) + { + win_skip("MP3 not supported.\n"); + MFShutdown(); + return; + } + + IMFTopology_GetTopologyID(topology, &topoid); + + callback = create_test_callback(TRUE); + hr = MFCreateMediaSession(NULL, &session); + ok(hr == S_OK, "Failed to create media session, hr %#lx.\n", hr); + + hr = IMFMediaSession_SetTopology(session, 0, topology); + ok(hr == S_OK, "Unexpected hr %#lx\n", hr); + hr = wait_media_event(session, callback, MESessionTopologySet, 1000, &pv); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(pv.vt == VT_UNKNOWN, "got vt %u\n", pv.vt); + ok(pv.punkVal != (IUnknown *)topology, "got punkVal %p\n", pv.punkVal); + PropVariantClear(&pv); + + hr = get_media_event(session, callback, MESessionTopologyStatus, 1000, &pv, &event); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine check_topologyid(event, topoid); + check_topostatus(event, MF_TOPOSTATUS_READY); + IMFMediaEvent_Release(event); + + pv.vt = VT_EMPTY; + hr = IMFMediaSession_Start(session, &GUID_NULL, &pv); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionStarted, 1000, &pv); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(pv.vt == VT_EMPTY, "got vt %u\n", pv.vt); + ok(pv.punkVal != (IUnknown *)topology, "got punkVal %p\n", pv.punkVal); + PropVariantClear(&pv); + + hr = get_media_event(session, callback, MESessionTopologyStatus, 1000, &pv, &event); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine check_topologyid(event, topoid); + check_topostatus(event, MF_TOPOSTATUS_ENDED); + IMFMediaEvent_Release(event); + + hr = wait_media_event(session, callback, MESessionEnded, 1000, &pv); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(pv.vt == VT_EMPTY, "got vt %u\n", pv.vt); + ok(pv.punkVal != (IUnknown *)topology, "got punkVal %p\n", pv.punkVal); + PropVariantClear(&pv); + + IMFMediaSession_Shutdown(session); + IMFMediaSession_Release(session); + IMFAsyncCallback_Release(callback); + IMFTopology_Release(topology); + + MFShutdown(); +} + struct test_grabber_callback { IMFSampleGrabberSinkCallback IMFSampleGrabberSinkCallback_iface; @@ -8259,6 +8406,7 @@ START_TEST(mf) test_media_session(); test_media_session_events(); test_media_session_rate_control(); + test_media_session_topologies(); test_MFShutdownObject(); test_presentation_clock(); test_sample_grabber();