From 747905c674d521b61923a6cff1d630c85a74d065 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Thu, 11 Nov 2021 23:43:24 -0600 Subject: [PATCH] winegstreamer: Call IWMReaderCallbackAdvanced::OnTime() when using a user clock. Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- dlls/winegstreamer/wm_asyncreader.c | 14 ++++++++++++++ dlls/wmvcore/tests/wmvcore.c | 23 ++++++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index 6549c9052e1..18698a698e2 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -101,6 +101,10 @@ static DWORD WINAPI stream_thread(void *arg) { if (reader->user_clock) { + QWORD user_time = reader->user_time; + + if (pts > user_time && reader->reader.callback_advanced) + IWMReaderCallbackAdvanced_OnTime(reader->reader.callback_advanced, user_time, reader->context); while (pts > reader->user_time && reader->running) SleepConditionVariableCS(&reader->stream_cv, &reader->stream_cs, INFINITE); if (!reader->running) @@ -152,6 +156,16 @@ static DWORD WINAPI stream_thread(void *arg) WMT_TYPE_DWORD, (BYTE *)&zero, reader->context); IWMReaderCallback_OnStatus(callback, WMT_EOF, S_OK, WMT_TYPE_DWORD, (BYTE *)&zero, reader->context); + + if (reader->user_clock && reader->reader.callback_advanced) + { + /* We can only get here if user_time is greater than the PTS + * of all samples, in which case we cannot have sent this + * notification already. */ + IWMReaderCallbackAdvanced_OnTime(reader->reader.callback_advanced, + reader->user_time, reader->context); + } + TRACE("Reached end of stream; exiting.\n"); LeaveCriticalSection(&reader->stream_cs); return 0; diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index bca611e4208..e27011f49a0 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -1429,6 +1429,9 @@ struct callback bool read_compressed; DWORD max_stream_sample_size[2]; + + QWORD expect_ontime; + HANDLE ontime_event; }; static struct callback *impl_from_IWMReaderCallback(IWMReaderCallback *iface) @@ -1672,12 +1675,15 @@ static HRESULT WINAPI callback_advanced_OnStreamSample(IWMReaderCallbackAdvanced static HRESULT WINAPI callback_advanced_OnTime(IWMReaderCallbackAdvanced *iface, QWORD time, void *context) { + struct callback *callback = impl_from_IWMReaderCallbackAdvanced(iface); + if (winetest_debug > 1) trace("%u: %04x: IWMReaderCallbackAdvanced::OnTime(time %I64u)\n", GetTickCount(), GetCurrentThreadId(), time); - ok(time == 3000 * 10000, "Got time %I64u.\n", time); + ok(time == callback->expect_ontime, "Got time %I64u.\n", time); ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context); + SetEvent(callback->ontime_event); return S_OK; } @@ -1837,6 +1843,7 @@ static void callback_init(struct callback *callback) callback->got_opened = CreateEventW(NULL, FALSE, FALSE, NULL); callback->got_stopped = CreateEventW(NULL, FALSE, FALSE, NULL); callback->eof_event = CreateEventW(NULL, FALSE, FALSE, NULL); + callback->ontime_event = CreateEventW(NULL, FALSE, FALSE, NULL); } static void callback_cleanup(struct callback *callback) @@ -1844,6 +1851,7 @@ static void callback_cleanup(struct callback *callback) CloseHandle(callback->got_opened); CloseHandle(callback->got_stopped); CloseHandle(callback->eof_event); + CloseHandle(callback->ontime_event); } static void run_async_reader(IWMReader *reader, IWMReaderAdvanced2 *advanced, struct callback *callback) @@ -2197,8 +2205,21 @@ static void test_async_reader_streaming(void) ok(hr == E_UNEXPECTED, "Got hr %#x.\n", hr); hr = IWMReaderAdvanced2_SetUserProvidedClock(advanced, TRUE); ok(hr == S_OK, "Got hr %#x.\n", hr); + callback.expect_ontime = 0; + hr = IWMReaderAdvanced2_DeliverTime(advanced, 0); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = WaitForSingleObject(callback.ontime_event, 1000); + ok(!ret, "Wait timed out.\n"); + callback.expect_ontime = 1000 * 10000; + hr = IWMReaderAdvanced2_DeliverTime(advanced, 1000 * 10000); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = WaitForSingleObject(callback.ontime_event, 1000); + ok(!ret, "Wait timed out.\n"); + callback.expect_ontime = 3000 * 10000; hr = IWMReaderAdvanced2_DeliverTime(advanced, 3000 * 10000); ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = WaitForSingleObject(callback.ontime_event, 1000); + ok(!ret, "Wait timed out.\n"); ret = WaitForSingleObject(callback.eof_event, 1000); ok(!ret, "Wait timed out.\n");