Module: wine Branch: master Commit: 682093d0bdc24a55fcde37ca4f9cc9ed46c3c7df URL: https://source.winehq.org/git/wine.git/?a=commit;h=682093d0bdc24a55fcde37ca4...
Author: Zebediah Figura zfigura@codeweavers.com Date: Thu Nov 4 15:46:28 2021 -0500
winegstreamer: Implement IWMReaderAdvanced::SetUserProvidedClock().
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winegstreamer/wm_asyncreader.c | 67 ++++++++++++++++++++++++++++--------- dlls/wmvcore/tests/wmvcore.c | 47 ++++++++++++-------------- 2 files changed, 74 insertions(+), 40 deletions(-)
diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index d4bd8914dd6..4193d7d75de 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -41,6 +41,9 @@ struct async_reader CONDITION_VARIABLE stream_cv;
bool running; + + bool user_clock; + QWORD user_time; };
static REFERENCE_TIME get_current_time(const struct async_reader *reader) @@ -85,22 +88,35 @@ static DWORD WINAPI stream_thread(void *arg) hr = wm_reader_get_stream_sample(&reader->reader.streams[i], &sample, &pts, &duration, &flags); if (hr == S_OK) { - for (;;) + if (reader->user_clock) { - REFERENCE_TIME current_time = get_current_time(reader); - - if (pts <= current_time - start_time) - break; - - SleepConditionVariableCS(&reader->stream_cv, &reader->stream_cs, - (pts - (current_time - start_time)) / 10000); - + while (pts > reader->user_time && reader->running) + SleepConditionVariableCS(&reader->stream_cv, &reader->stream_cs, INFINITE); if (!reader->running) { INSSBuffer_Release(sample); goto out; } } + else + { + for (;;) + { + REFERENCE_TIME current_time = get_current_time(reader); + + if (pts <= current_time - start_time) + break; + + SleepConditionVariableCS(&reader->stream_cv, &reader->stream_cs, + (pts - (current_time - start_time)) / 10000); + + if (!reader->running) + { + INSSBuffer_Release(sample); + goto out; + } + } + }
IWMReaderCallback_OnSample(callback, i, pts, duration, flags, sample, reader->context); INSSBuffer_Release(sample); @@ -276,6 +292,7 @@ static HRESULT WINAPI WMReader_Start(IWMReader *iface, wm_reader_seek(&reader->reader, start, duration);
reader->running = true; + reader->user_time = 0;
if (!(reader->stream_thread = CreateThread(NULL, 0, stream_thread, reader, 0, NULL))) { @@ -360,9 +377,14 @@ static ULONG WINAPI WMReaderAdvanced_Release(IWMReaderAdvanced6 *iface)
static HRESULT WINAPI WMReaderAdvanced_SetUserProvidedClock(IWMReaderAdvanced6 *iface, BOOL user_clock) { - struct async_reader *This = impl_from_IWMReaderAdvanced6(iface); - FIXME("(%p)->(%x)\n", This, user_clock); - return E_NOTIMPL; + struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface); + + TRACE("reader %p, user_clock %d.\n", reader, user_clock); + + EnterCriticalSection(&reader->stream_cs); + reader->user_clock = !!user_clock; + LeaveCriticalSection(&reader->stream_cs); + return S_OK; }
static HRESULT WINAPI WMReaderAdvanced_GetUserProvidedClock(IWMReaderAdvanced6 *iface, BOOL *user_clock) @@ -374,9 +396,24 @@ static HRESULT WINAPI WMReaderAdvanced_GetUserProvidedClock(IWMReaderAdvanced6 *
static HRESULT WINAPI WMReaderAdvanced_DeliverTime(IWMReaderAdvanced6 *iface, QWORD time) { - struct async_reader *This = impl_from_IWMReaderAdvanced6(iface); - FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(time)); - return E_NOTIMPL; + struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface); + + TRACE("reader %p, time %s.\n", reader, debugstr_time(time)); + + EnterCriticalSection(&reader->stream_cs); + + if (!reader->user_clock) + { + LeaveCriticalSection(&reader->stream_cs); + WARN("Not using a user-provided clock; returning E_UNEXPECTED.\n"); + return E_UNEXPECTED; + } + + reader->user_time = time; + + LeaveCriticalSection(&reader->stream_cs); + WakeConditionVariable(&reader->stream_cv); + return S_OK; }
static HRESULT WINAPI WMReaderAdvanced_SetManualStreamSelection(IWMReaderAdvanced6 *iface, BOOL selection) diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index 4cc285c2c73..0e7c6380c92 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -1288,38 +1288,35 @@ static void test_async_reader_streaming(void) * according to their presentation time. Call DeliverTime with the file * duration in order to request all samples as fast as possible. */ hr = IWMReaderAdvanced2_DeliverTime(advanced, 3000 * 10000); - todo_wine ok(hr == E_UNEXPECTED, "Got hr %#x.\n", hr); + ok(hr == E_UNEXPECTED, "Got hr %#x.\n", hr); hr = IWMReaderAdvanced2_SetUserProvidedClock(advanced, TRUE); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - if (hr == S_OK) - { - hr = IWMReaderAdvanced2_DeliverTime(advanced, 3000 * 10000); - ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IWMReaderAdvanced2_DeliverTime(advanced, 3000 * 10000); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- ret = WaitForSingleObject(callback.eof_event, 1000); - ok(!ret, "Wait timed out.\n"); - ok(callback.got_eof == 1, "Got %u WMT_EOF callbacks.\n", callback.got_eof); + ret = WaitForSingleObject(callback.eof_event, 1000); + ok(!ret, "Wait timed out.\n"); + ok(callback.got_eof == 1, "Got %u WMT_EOF callbacks.\n", callback.got_eof);
- hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)0xfacade); - ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)0xfacade); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- hr = IWMReaderAdvanced2_DeliverTime(advanced, 3000 * 10000); - ok(hr == S_OK, "Got hr %#x.\n", hr); + hr = IWMReaderAdvanced2_DeliverTime(advanced, 3000 * 10000); + ok(hr == S_OK, "Got hr %#x.\n", hr);
- ret = WaitForSingleObject(callback.eof_event, 1000); - ok(!ret, "Wait timed out.\n"); - ok(callback.got_eof == 1, "Got %u WMT_EOF callbacks.\n", callback.got_eof); + ret = WaitForSingleObject(callback.eof_event, 1000); + ok(!ret, "Wait timed out.\n"); + ok(callback.got_eof == 1, "Got %u WMT_EOF callbacks.\n", callback.got_eof);
- hr = IWMReader_Stop(reader); - ok(hr == S_OK, "Got hr %#x.\n", hr); - ret = WaitForSingleObject(callback.got_stopped, 1000); - ok(!ret, "Wait timed out.\n"); + hr = IWMReader_Stop(reader); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = WaitForSingleObject(callback.got_stopped, 1000); + ok(!ret, "Wait timed out.\n");
- hr = IWMReader_Stop(reader); - ok(hr == S_OK, "Got hr %#x.\n", hr); - ret = WaitForSingleObject(callback.got_stopped, 1000); - ok(!ret, "Wait timed out.\n"); - } + hr = IWMReader_Stop(reader); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ret = WaitForSingleObject(callback.got_stopped, 1000); + ok(!ret, "Wait timed out.\n");
test_reader_attributes(profile);