From: Torge Matthies tmatthies@codeweavers.com
--- dlls/mf/tests/mf.c | 181 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index f05ec623d26..5e45cfb5a3c 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -5778,6 +5778,186 @@ done: ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); }
+#define wait_media_event_generator(a, b, c, d, e) wait_media_event_generator_(__LINE__, a, b, c, d, e) +static HRESULT wait_media_event_generator_(int line, IMFMediaEventGenerator *generator, IMFAsyncCallback *callback, + MediaEventType expect_type, DWORD timeout, PROPVARIANT *value) +{ + struct test_callback *impl = impl_from_IMFAsyncCallback(callback); + MediaEventType type; + HRESULT hr, status; + DWORD ret; + GUID guid; + + do + { + hr = IMFMediaEventGenerator_BeginGetEvent(generator, &impl->IMFAsyncCallback_iface, (IUnknown *)generator); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ret = WaitForSingleObject(impl->event, timeout); + ok_(__FILE__, line)(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", ret); + hr = IMFMediaEvent_GetType(impl->media_event, &type); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } while (type != expect_type); + + ok_(__FILE__, line)(type == expect_type, "got type %lu\n", type); + + hr = IMFMediaEvent_GetExtendedType(impl->media_event, &guid); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok_(__FILE__, line)(IsEqualGUID(&guid, &GUID_NULL), "got extended type %s\n", debugstr_guid(&guid)); + + hr = IMFMediaEvent_GetValue(impl->media_event, value); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaEvent_GetStatus(impl->media_event, &status); + ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + return status; +} + +static void load_resource(const WCHAR *filename, const BYTE **data, DWORD *length) +{ + HRSRC resource = FindResourceW(NULL, filename, (const WCHAR *)RT_RCDATA); + ok(resource != 0, "FindResourceW failed, error %lu\n", GetLastError()); + *data = LockResource(LoadResource(GetModuleHandleW(NULL), resource)); + *length = SizeofResource(GetModuleHandleW(NULL), resource); +} + +static void test_media_sink_events(void) +{ + IMFPresentationTimeSource *time_source; + IMFPresentationClock *clock, *clock2; + IMFMediaEventGenerator *eg; + IMFAsyncCallback *callback; + IMFByteStream *bytestream; + IMFMediaType *audio_type; + const BYTE *aacenc_data; + IMFSample *input_sample; + IMFStreamSink *stream; + ULONG aacenc_data_len; + IMFMediaEvent *event; + PROPVARIANT propvar; + IMFMediaSink *sink; + HRESULT hr; + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr); + + callback = create_test_callback(TRUE); + + hr = MFCreateTempFile(MF_ACCESSMODE_WRITE, MF_OPENMODE_DELETE_IF_EXIST, 0, &bytestream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateMediaType(&audio_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaType_SetGUID(audio_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(audio_type, &MF_MT_SUBTYPE, &MFAudioFormat_AAC); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(audio_type, &MF_MT_AUDIO_NUM_CHANNELS, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(audio_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, 16); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(audio_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(audio_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 12000); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(audio_type, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, 41); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(audio_type, &MF_MT_AAC_PAYLOAD_TYPE, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateADTSMediaSink(bytestream, audio_type, &sink); + IMFMediaType_Release(audio_type); + if (hr == REGDB_E_CLASSNOTREG) + { + skip("ADTS media sink is not supported, skipping tests.\n"); + goto done; + } + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreatePresentationClock(&clock); + ok(hr == S_OK, "Failed to create clock object, hr %#lx.\n", hr); + + hr = IMFMediaSink_SetPresentationClock(sink, clock); + ok(hr == S_OK, "Failed to set presentation clock, hr %#lx.\n", hr); + + hr = MFCreateSystemTimeSource(&time_source); + ok(hr == S_OK, "Failed to create time source, hr %#lx.\n", hr); + + hr = IMFPresentationClock_SetTimeSource(clock, time_source); + ok(hr == S_OK, "Failed to set time source, hr %#lx.\n", hr); + IMFPresentationTimeSource_Release(time_source); + + hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFStreamSink_QueryInterface(stream, &IID_IMFMediaEventGenerator, (void **)&eg); + ok(hr == S_OK, "Failed to get interface, hr %#lx.\n", hr); + + hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event); + ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr); + + hr = IMFPresentationClock_Start(clock, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = wait_media_event_generator(eg, callback, MEStreamSinkStarted, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + PropVariantClear(&propvar); + + hr = wait_media_event_generator(eg, callback, MEStreamSinkRequestSample, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + PropVariantClear(&propvar); + + hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event); + ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr); + + load_resource(L"aacencdata.bin", &aacenc_data, &aacenc_data_len); + ok(aacenc_data_len == 24861, "got length %lu\n", aacenc_data_len); + + input_sample = create_sample(aacenc_data + sizeof(DWORD), *(DWORD *)aacenc_data); + + hr = IMFStreamSink_ProcessSample(stream, input_sample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = wait_media_event_generator(eg, callback, MEStreamSinkRequestSample, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + PropVariantClear(&propvar); + + hr = IMFMediaEventGenerator_GetEvent(eg, MF_EVENT_FLAG_NO_WAIT, &event); + ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#lx.\n", hr); + + /* Shutdown */ + EXPECT_REF(clock, 2); + hr = IMFMediaSink_Shutdown(sink); + ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr); + EXPECT_REF(clock, 1); + + hr = IMFMediaSink_Shutdown(sink); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr); + + clock2 = NULL; + hr = IMFMediaSink_GetPresentationClock(sink, &clock2); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr); + ok(!clock2, "Unexpected clock %p.\n", clock2); + + hr = IMFMediaSink_SetPresentationClock(sink, clock); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr); + + IMFMediaEventGenerator_Release(eg); + IMFStreamSink_Release(stream); + IMFPresentationClock_Release(clock); + IMFMediaSink_Release(sink); +done: + IMFAsyncCallback_Release(callback); + IMFByteStream_Release(bytestream); + + hr = MFShutdown(); + ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr); +} + static void test_quality_manager(void) { IMFPresentationClock *clock; @@ -8259,6 +8439,7 @@ START_TEST(mf) test_sample_grabber_is_mediatype_supported(); test_sample_grabber_orientation(MFVideoFormat_RGB32); test_sample_grabber_orientation(MFVideoFormat_NV12); + test_media_sink_events(); test_quality_manager(); test_sar(); test_evr();