winegstreamer: Call IWMReaderCallbackAdvanced::OnTime() when using a user clock.

Signed-off-by: Zebediah Figura <zfigura@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2021-11-11 23:43:24 -06:00 committed by Alexandre Julliard
parent f3624e2d64
commit 747905c674
2 changed files with 36 additions and 1 deletions

View File

@ -101,6 +101,10 @@ static DWORD WINAPI stream_thread(void *arg)
{ {
if (reader->user_clock) 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) while (pts > reader->user_time && reader->running)
SleepConditionVariableCS(&reader->stream_cv, &reader->stream_cs, INFINITE); SleepConditionVariableCS(&reader->stream_cv, &reader->stream_cs, INFINITE);
if (!reader->running) if (!reader->running)
@ -152,6 +156,16 @@ static DWORD WINAPI stream_thread(void *arg)
WMT_TYPE_DWORD, (BYTE *)&zero, reader->context); WMT_TYPE_DWORD, (BYTE *)&zero, reader->context);
IWMReaderCallback_OnStatus(callback, WMT_EOF, S_OK, IWMReaderCallback_OnStatus(callback, WMT_EOF, S_OK,
WMT_TYPE_DWORD, (BYTE *)&zero, reader->context); 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"); TRACE("Reached end of stream; exiting.\n");
LeaveCriticalSection(&reader->stream_cs); LeaveCriticalSection(&reader->stream_cs);
return 0; return 0;

View File

@ -1429,6 +1429,9 @@ struct callback
bool read_compressed; bool read_compressed;
DWORD max_stream_sample_size[2]; DWORD max_stream_sample_size[2];
QWORD expect_ontime;
HANDLE ontime_event;
}; };
static struct callback *impl_from_IWMReaderCallback(IWMReaderCallback *iface) 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) static HRESULT WINAPI callback_advanced_OnTime(IWMReaderCallbackAdvanced *iface, QWORD time, void *context)
{ {
struct callback *callback = impl_from_IWMReaderCallbackAdvanced(iface);
if (winetest_debug > 1) if (winetest_debug > 1)
trace("%u: %04x: IWMReaderCallbackAdvanced::OnTime(time %I64u)\n", trace("%u: %04x: IWMReaderCallbackAdvanced::OnTime(time %I64u)\n",
GetTickCount(), GetCurrentThreadId(), time); 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); ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
SetEvent(callback->ontime_event);
return S_OK; return S_OK;
} }
@ -1837,6 +1843,7 @@ static void callback_init(struct callback *callback)
callback->got_opened = CreateEventW(NULL, FALSE, FALSE, NULL); callback->got_opened = CreateEventW(NULL, FALSE, FALSE, NULL);
callback->got_stopped = CreateEventW(NULL, FALSE, FALSE, NULL); callback->got_stopped = CreateEventW(NULL, FALSE, FALSE, NULL);
callback->eof_event = 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) 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_opened);
CloseHandle(callback->got_stopped); CloseHandle(callback->got_stopped);
CloseHandle(callback->eof_event); CloseHandle(callback->eof_event);
CloseHandle(callback->ontime_event);
} }
static void run_async_reader(IWMReader *reader, IWMReaderAdvanced2 *advanced, struct callback *callback) 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); ok(hr == E_UNEXPECTED, "Got hr %#x.\n", hr);
hr = IWMReaderAdvanced2_SetUserProvidedClock(advanced, TRUE); hr = IWMReaderAdvanced2_SetUserProvidedClock(advanced, TRUE);
ok(hr == S_OK, "Got hr %#x.\n", hr); 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); hr = IWMReaderAdvanced2_DeliverTime(advanced, 3000 * 10000);
ok(hr == S_OK, "Got hr %#x.\n", hr); 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); ret = WaitForSingleObject(callback.eof_event, 1000);
ok(!ret, "Wait timed out.\n"); ok(!ret, "Wait timed out.\n");