[PATCH v2 0/9] MR803: winegstreamer: Refactor wm async reader clock.
-- v2: winegstreamer: Request the wm_reader stream only when necessary. winegstreamer: Introduce a new async_reader_wait_pts helper. winegstreamer: Factor async_reader waits using async_reader_get_wait_timeout. winegstreamer: Check whether the reader is still running before user time. winegstreamer: Keep start time in the async_reader struct. winegstreamer: Implement async reader asynchronous seeking. winegstreamer: Unconditionally assign new context for ASYNC_OP_START. winegstreamer: Wrap async reader op new_context in a union. wmvcore/tests: Add some tests starting WM reader with NULL context. https://gitlab.winehq.org/wine/wine/-/merge_requests/803
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/wmvcore/tests/wmvcore.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index 3635a2ed642..6883144df6e 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -1785,6 +1785,7 @@ struct callback unsigned int closed_count, started_count, end_of_streaming_count, eof_count, sample_count; bool all_streams_off; bool allocated_samples; + void *expect_context; bool read_compressed; DWORD max_stream_sample_size[2]; @@ -1866,7 +1867,8 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta callback->callback_tid = GetCurrentThreadId(); ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type); ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value); - ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context); + todo_wine_if(!callback->expect_context) + ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); ret = WaitForSingleObject(callback->expect_started, 100); ok(!ret, "Wait timed out.\n"); callback->end_of_streaming_count = callback->eof_count = callback->sample_count = 0; @@ -1879,7 +1881,8 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta ok(callback->callback_tid == GetCurrentThreadId(), "got wrong thread\n"); ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type); ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value); - ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context); + todo_wine_if(!callback->expect_context) + ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); ret = WaitForSingleObject(callback->expect_stopped, 100); ok(!ret, "Wait timed out.\n"); SetEvent(callback->got_stopped); @@ -1888,7 +1891,8 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta case WMT_CLOSED: ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type); ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value); - ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context); + todo_wine_if(!callback->expect_context) + ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); ++callback->closed_count; break; @@ -1896,7 +1900,8 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta ok(callback->callback_tid == GetCurrentThreadId(), "got wrong thread\n"); ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type); ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value); - ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context); + todo_wine_if(!callback->expect_context) + ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); ++callback->end_of_streaming_count; break; @@ -1904,7 +1909,8 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta ok(callback->callback_tid == GetCurrentThreadId(), "got wrong thread\n"); ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type); ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value); - ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context); + todo_wine_if(!callback->expect_context) + ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); if (callback->all_streams_off) ok(callback->sample_count == 0, "Got %u samples.\n", callback->sample_count); else @@ -1922,7 +1928,7 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta ok(callback->callback_tid == GetCurrentThreadId(), "got wrong thread\n"); ok(type == WMT_TYPE_QWORD, "Got type %#x.\n", type); ok(*(QWORD *)value == 3000, "Got value %#lx.\n", *(DWORD *)value); - ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context); + ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); if (callback->all_streams_off) ok(callback->sample_count == 0, "Got %u samples.\n", callback->sample_count); else @@ -2008,7 +2014,8 @@ static HRESULT WINAPI callback_OnSample(IWMReaderCallback *iface, DWORD output, ok(callback->output_tid[1 - output] != GetCurrentThreadId(), "got wrong thread\n"); } - ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context); + todo_wine_if(!callback->expect_context) + ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); check_async_sample(callback, sample); @@ -2084,7 +2091,7 @@ static HRESULT WINAPI callback_advanced_OnStreamSample(IWMReaderCallbackAdvanced ok(callback->output_tid[2 - stream_number] != GetCurrentThreadId(), "got wrong thread\n"); } - ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context); + ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); check_async_sample(callback, sample); @@ -2107,7 +2114,8 @@ static HRESULT WINAPI callback_advanced_OnTime(IWMReaderCallbackAdvanced *iface, ok(callback->callback_tid == GetCurrentThreadId(), "got wrong thread\n"); ok(time == callback->expect_ontime, "Got time %I64u.\n", time); - ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context); + todo_wine_if(!callback->expect_context) + ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); SetEvent(callback->ontime_event); return S_OK; } @@ -2426,6 +2434,7 @@ static void run_async_reader(IWMReader *reader, IWMReaderAdvanced2 *advanced, st check_async_set_output_setting(advanced, 1, L"DedicatedDeliveryThread", WMT_TYPE_BOOL, callback->dedicated_threads, S_OK); + callback->expect_context = (void *)0xfacade; hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)0xfacade); ok(hr == S_OK, "Got hr %#lx.\n", hr); @@ -2881,7 +2890,7 @@ static void test_async_reader_settings(void) WMT_TYPE_DWORD, 0, E_INVALIDARG); SetEvent(callback.expect_started); - hr = IWMReader_Start(reader, 0, 0, 1, (void **)0xfacade); + hr = IWMReader_Start(reader, 0, 0, 1, (void **)NULL); ok(hr == S_OK, "Got hr %#lx.\n", hr); hr = IWMReader_Close(reader); ok(hr == S_OK, "Got hr %#lx.\n", hr); @@ -2954,7 +2963,7 @@ static void test_async_reader_streaming(void) ok(!ref, "Got outstanding refcount %ld.\n", ref); } - hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)0xfacade); + hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)NULL); ok(hr == S_OK, "Got hr %#lx.\n", hr); wait_started_callback(&callback); @@ -2984,7 +2993,7 @@ static void test_async_reader_streaming(void) ret = WaitForSingleObject(callback.ontime_event, 1000); ok(!ret, "Wait timed out.\n"); - hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)0xfacade); + hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)NULL); ok(hr == S_OK, "Got hr %#lx.\n", hr); wait_started_callback(&callback); @@ -3385,6 +3394,7 @@ static void test_async_reader_file(void) ok(hr == S_OK, "Got hr %#lx.\n", hr); ok(count == 2, "Got count %lu.\n", count); + callback.expect_context = (void *)0xfacade; hr = IWMReader_Start(reader, 0, 0, 1.0f, (void *)0xfacade); ok(hr == S_OK, "Got hr %#lx.\n", hr); wait_started_callback(&callback); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/803
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=122919 Your paranoid android. === debian11 (32 bit report) === Report validation errors: wmvcore:wmvcore prints too much data (36104 bytes) === debian11 (32 bit Arabic:Morocco report) === Report validation errors: wmvcore:wmvcore prints too much data (36104 bytes) === debian11 (32 bit German report) === Report validation errors: wmvcore:wmvcore prints too much data (36104 bytes) === debian11 (32 bit French report) === Report validation errors: wmvcore:wmvcore prints too much data (36104 bytes) === debian11 (32 bit Hebrew:Israel report) === Report validation errors: wmvcore:wmvcore prints too much data (36104 bytes) === debian11 (32 bit Hindi:India report) === Report validation errors: wmvcore:wmvcore prints too much data (36104 bytes) === debian11 (32 bit Japanese:Japan report) === Report validation errors: wmvcore:wmvcore prints too much data (36104 bytes) === debian11 (32 bit Chinese:China report) === Report validation errors: wmvcore:wmvcore prints too much data (36104 bytes) === debian11 (32 bit WoW report) === Report validation errors: wmvcore:wmvcore prints too much data (36104 bytes) === debian11 (64 bit WoW report) === Report validation errors: wmvcore:wmvcore prints too much data (36552 bytes)
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/winegstreamer/wm_asyncreader.c | 3 +-- dlls/wmvcore/tests/wmvcore.c | 7 ------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index c280828b616..493075859ad 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -199,13 +199,12 @@ static DWORD WINAPI async_reader_callback_thread(void *arg) struct async_op *op = LIST_ENTRY(entry, struct async_op, entry); list_remove(&op->entry); - if (op->u.start.context) - reader->context = op->u.start.context; hr = list_empty(&reader->async_ops) ? S_OK : E_ABORT; switch (op->type) { case ASYNC_OP_START: { + reader->context = op->u.start.context; LeaveCriticalSection(&reader->callback_cs); IWMReaderCallback_OnStatus(reader->callback, WMT_STARTED, hr, WMT_TYPE_DWORD, (BYTE *)&zero, reader->context); diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index 6883144df6e..06e1852c8c0 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -1867,7 +1867,6 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta callback->callback_tid = GetCurrentThreadId(); ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type); ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value); - todo_wine_if(!callback->expect_context) ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); ret = WaitForSingleObject(callback->expect_started, 100); ok(!ret, "Wait timed out.\n"); @@ -1881,7 +1880,6 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta ok(callback->callback_tid == GetCurrentThreadId(), "got wrong thread\n"); ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type); ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value); - todo_wine_if(!callback->expect_context) ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); ret = WaitForSingleObject(callback->expect_stopped, 100); ok(!ret, "Wait timed out.\n"); @@ -1891,7 +1889,6 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta case WMT_CLOSED: ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type); ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value); - todo_wine_if(!callback->expect_context) ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); ++callback->closed_count; break; @@ -1900,7 +1897,6 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta ok(callback->callback_tid == GetCurrentThreadId(), "got wrong thread\n"); ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type); ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value); - todo_wine_if(!callback->expect_context) ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); ++callback->end_of_streaming_count; break; @@ -1909,7 +1905,6 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta ok(callback->callback_tid == GetCurrentThreadId(), "got wrong thread\n"); ok(type == WMT_TYPE_DWORD, "Got type %#x.\n", type); ok(!*(DWORD *)value, "Got value %#lx.\n", *(DWORD *)value); - todo_wine_if(!callback->expect_context) ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); if (callback->all_streams_off) ok(callback->sample_count == 0, "Got %u samples.\n", callback->sample_count); @@ -2014,7 +2009,6 @@ static HRESULT WINAPI callback_OnSample(IWMReaderCallback *iface, DWORD output, ok(callback->output_tid[1 - output] != GetCurrentThreadId(), "got wrong thread\n"); } - todo_wine_if(!callback->expect_context) ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); check_async_sample(callback, sample); @@ -2114,7 +2108,6 @@ static HRESULT WINAPI callback_advanced_OnTime(IWMReaderCallbackAdvanced *iface, ok(callback->callback_tid == GetCurrentThreadId(), "got wrong thread\n"); ok(time == callback->expect_ontime, "Got time %I64u.\n", time); - todo_wine_if(!callback->expect_context) ok(context == (void *)callback->expect_context, "Got unexpected context %p.\n", context); SetEvent(callback->ontime_event); return S_OK; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/803
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/winegstreamer/wm_asyncreader.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index f3e2209881a..c280828b616 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -22,6 +22,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmvcore); +union async_op_data +{ + struct + { + void *context; + } start; +}; + struct async_op { enum async_op_type @@ -30,7 +38,7 @@ struct async_op ASYNC_OP_STOP, ASYNC_OP_CLOSE, } type; - void *new_context; + union async_op_data u; struct list entry; }; @@ -191,8 +199,8 @@ static DWORD WINAPI async_reader_callback_thread(void *arg) struct async_op *op = LIST_ENTRY(entry, struct async_op, entry); list_remove(&op->entry); - if (op->new_context) - reader->context = op->new_context; + if (op->u.start.context) + reader->context = op->u.start.context; hr = list_empty(&reader->async_ops) ? S_OK : E_ABORT; switch (op->type) { @@ -291,14 +299,15 @@ error: return hr; } -static HRESULT async_reader_queue_op(struct async_reader *reader, enum async_op_type type, void *context) +static HRESULT async_reader_queue_op(struct async_reader *reader, enum async_op_type type, union async_op_data *data) { struct async_op *op; if (!(op = calloc(1, sizeof(*op)))) return E_OUTOFMEMORY; op->type = type; - op->new_context = context; + if (data) + op->u = *data; EnterCriticalSection(&reader->callback_cs); list_add_tail(&reader->async_ops, &op->entry); @@ -432,6 +441,7 @@ static HRESULT WINAPI WMReader_GetOutputFormat(IWMReader *iface, DWORD output, static HRESULT WINAPI WMReader_Start(IWMReader *iface, QWORD start, QWORD duration, float rate, void *context) { + union async_op_data data = {.start = {.context = context}}; struct async_reader *reader = impl_from_IWMReader(iface); HRESULT hr; @@ -448,7 +458,7 @@ static HRESULT WINAPI WMReader_Start(IWMReader *iface, else { wm_reader_seek(&reader->reader, start, duration); - hr = async_reader_queue_op(reader, ASYNC_OP_START, context); + hr = async_reader_queue_op(reader, ASYNC_OP_START, &data); } LeaveCriticalSection(&reader->reader.cs); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/803
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/winegstreamer/wm_asyncreader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index b401fd58bc8..99d891cec53 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -115,7 +115,7 @@ static void callback_thread_run(struct async_reader *reader) EnterCriticalSection(&reader->callback_cs); } - while (pts > reader->user_time && reader->running && list_empty(&reader->async_ops)) + while (reader->running && list_empty(&reader->async_ops) && pts > reader->user_time) SleepConditionVariableCS(&reader->callback_cv, &reader->callback_cs, INFINITE); } else -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/803
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/winegstreamer/wm_asyncreader.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index 493075859ad..2215669309e 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -26,6 +26,8 @@ union async_op_data { struct { + QWORD start; + QWORD duration; void *context; } start; }; @@ -205,6 +207,9 @@ static DWORD WINAPI async_reader_callback_thread(void *arg) case ASYNC_OP_START: { reader->context = op->u.start.context; + if (SUCCEEDED(hr)) + wm_reader_seek(&reader->reader, op->u.start.start, op->u.start.duration); + LeaveCriticalSection(&reader->callback_cs); IWMReaderCallback_OnStatus(reader->callback, WMT_STARTED, hr, WMT_TYPE_DWORD, (BYTE *)&zero, reader->context); @@ -440,7 +445,7 @@ static HRESULT WINAPI WMReader_GetOutputFormat(IWMReader *iface, DWORD output, static HRESULT WINAPI WMReader_Start(IWMReader *iface, QWORD start, QWORD duration, float rate, void *context) { - union async_op_data data = {.start = {.context = context}}; + union async_op_data data = {.start = {.start = start, .duration = duration, .context = context}}; struct async_reader *reader = impl_from_IWMReader(iface); HRESULT hr; @@ -455,10 +460,7 @@ static HRESULT WINAPI WMReader_Start(IWMReader *iface, if (!reader->callback_thread) hr = NS_E_INVALID_REQUEST; else - { - wm_reader_seek(&reader->reader, start, duration); hr = async_reader_queue_op(reader, ASYNC_OP_START, &data); - } LeaveCriticalSection(&reader->reader.cs); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/803
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/winegstreamer/wm_asyncreader.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index 2215669309e..b401fd58bc8 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -60,6 +60,7 @@ struct async_reader IWMReaderCallback *callback; void *context; + REFERENCE_TIME clock_start; LARGE_INTEGER clock_frequency; HANDLE callback_thread; @@ -85,7 +86,6 @@ static void callback_thread_run(struct async_reader *reader) { IWMReaderCallbackAdvanced *callback_advanced = reader->callback_advanced; IWMReaderCallback *callback = reader->callback; - REFERENCE_TIME start_time; struct wm_stream *stream; static const DWORD zero; QWORD pts, duration; @@ -94,8 +94,6 @@ static void callback_thread_run(struct async_reader *reader) HRESULT hr = S_OK; DWORD flags; - start_time = get_current_time(reader); - while (reader->running && list_empty(&reader->async_ops)) { LeaveCriticalSection(&reader->callback_cs); @@ -124,13 +122,13 @@ static void callback_thread_run(struct async_reader *reader) { while (reader->running && list_empty(&reader->async_ops)) { - REFERENCE_TIME current_time = get_current_time(reader); + REFERENCE_TIME current_time = get_current_time(reader) - reader->clock_start; - if (pts <= current_time - start_time) + if (pts <= current_time) break; SleepConditionVariableCS(&reader->callback_cv, &reader->callback_cs, - (pts - (current_time - start_time)) / 10000); + (pts - current_time) / 10000); } } @@ -208,7 +206,10 @@ static DWORD WINAPI async_reader_callback_thread(void *arg) { reader->context = op->u.start.context; if (SUCCEEDED(hr)) + { wm_reader_seek(&reader->reader, op->u.start.start, op->u.start.duration); + reader->clock_start = get_current_time(reader); + } LeaveCriticalSection(&reader->callback_cs); IWMReaderCallback_OnStatus(reader->callback, WMT_STARTED, hr, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/803
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/winegstreamer/wm_asyncreader.c | 47 +++++++++++++++-------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index 99d891cec53..5d987687a84 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -82,6 +82,20 @@ static REFERENCE_TIME get_current_time(const struct async_reader *reader) return (time.QuadPart * 1000) / reader->clock_frequency.QuadPart * 10000; } +static DWORD async_reader_get_wait_timeout(struct async_reader *reader, QWORD pts) +{ + REFERENCE_TIME current_time = reader->user_time; + DWORD timeout = INFINITE; + + if (!reader->user_clock) + { + current_time = get_current_time(reader) - reader->clock_start; + timeout = (pts - current_time) / 10000; + } + + return pts > current_time ? timeout : 0; +} + static void callback_thread_run(struct async_reader *reader) { IWMReaderCallbackAdvanced *callback_advanced = reader->callback_advanced; @@ -96,6 +110,8 @@ static void callback_thread_run(struct async_reader *reader) while (reader->running && list_empty(&reader->async_ops)) { + DWORD timeout; + LeaveCriticalSection(&reader->callback_cs); hr = wm_reader_get_stream_sample(&reader->reader, callback_advanced, 0, &sample, &pts, &duration, &flags, &stream_number); EnterCriticalSection(&reader->callback_cs); @@ -104,32 +120,19 @@ static void callback_thread_run(struct async_reader *reader) stream = wm_reader_get_stream_by_stream_number(&reader->reader, stream_number); - if (reader->user_clock) + if (reader->user_clock && pts > reader->user_time && callback_advanced) { QWORD user_time = reader->user_time; - - if (pts > user_time && callback_advanced) - { - LeaveCriticalSection(&reader->callback_cs); - IWMReaderCallbackAdvanced_OnTime(callback_advanced, user_time, reader->context); - EnterCriticalSection(&reader->callback_cs); - } - - while (reader->running && list_empty(&reader->async_ops) && pts > reader->user_time) - SleepConditionVariableCS(&reader->callback_cv, &reader->callback_cs, INFINITE); + LeaveCriticalSection(&reader->callback_cs); + IWMReaderCallbackAdvanced_OnTime(callback_advanced, user_time, reader->context); + EnterCriticalSection(&reader->callback_cs); } - else - { - while (reader->running && list_empty(&reader->async_ops)) - { - REFERENCE_TIME current_time = get_current_time(reader) - reader->clock_start; - - if (pts <= current_time) - break; - SleepConditionVariableCS(&reader->callback_cv, &reader->callback_cs, - (pts - current_time) / 10000); - } + while (reader->running && list_empty(&reader->async_ops)) + { + if (!(timeout = async_reader_get_wait_timeout(reader, pts))) + break; + SleepConditionVariableCS(&reader->callback_cv, &reader->callback_cs, timeout); } if (reader->running && list_empty(&reader->async_ops)) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/803
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/winegstreamer/wm_asyncreader.c | 44 +++++++++++++++++------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index 5d987687a84..488a03bd4d0 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -96,6 +96,31 @@ static DWORD async_reader_get_wait_timeout(struct async_reader *reader, QWORD pt return pts > current_time ? timeout : 0; } +static bool async_reader_wait_pts(struct async_reader *reader, QWORD pts) +{ + IWMReaderCallbackAdvanced *callback_advanced = reader->callback_advanced; + DWORD timeout; + + TRACE("reader %p, pts %I64d.\n", reader, pts); + + if (reader->user_clock && pts > reader->user_time && callback_advanced) + { + QWORD user_time = reader->user_time; + LeaveCriticalSection(&reader->callback_cs); + IWMReaderCallbackAdvanced_OnTime(callback_advanced, user_time, reader->context); + EnterCriticalSection(&reader->callback_cs); + } + + while (reader->running && list_empty(&reader->async_ops)) + { + if (!(timeout = async_reader_get_wait_timeout(reader, pts))) + return true; + SleepConditionVariableCS(&reader->callback_cv, &reader->callback_cs, timeout); + } + + return false; +} + static void callback_thread_run(struct async_reader *reader) { IWMReaderCallbackAdvanced *callback_advanced = reader->callback_advanced; @@ -110,8 +135,6 @@ static void callback_thread_run(struct async_reader *reader) while (reader->running && list_empty(&reader->async_ops)) { - DWORD timeout; - LeaveCriticalSection(&reader->callback_cs); hr = wm_reader_get_stream_sample(&reader->reader, callback_advanced, 0, &sample, &pts, &duration, &flags, &stream_number); EnterCriticalSection(&reader->callback_cs); @@ -120,22 +143,7 @@ static void callback_thread_run(struct async_reader *reader) stream = wm_reader_get_stream_by_stream_number(&reader->reader, stream_number); - if (reader->user_clock && pts > reader->user_time && callback_advanced) - { - QWORD user_time = reader->user_time; - LeaveCriticalSection(&reader->callback_cs); - IWMReaderCallbackAdvanced_OnTime(callback_advanced, user_time, reader->context); - EnterCriticalSection(&reader->callback_cs); - } - - while (reader->running && list_empty(&reader->async_ops)) - { - if (!(timeout = async_reader_get_wait_timeout(reader, pts))) - break; - SleepConditionVariableCS(&reader->callback_cv, &reader->callback_cs, timeout); - } - - if (reader->running && list_empty(&reader->async_ops)) + if (async_reader_wait_pts(reader, pts)) { LeaveCriticalSection(&reader->callback_cs); if (stream->read_compressed) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/803
From: R��mi Bernon <rbernon(a)codeweavers.com> --- dlls/winegstreamer/wm_asyncreader.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index 488a03bd4d0..b4750592778 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -125,7 +125,6 @@ static void callback_thread_run(struct async_reader *reader) { IWMReaderCallbackAdvanced *callback_advanced = reader->callback_advanced; IWMReaderCallback *callback = reader->callback; - struct wm_stream *stream; static const DWORD zero; QWORD pts, duration; WORD stream_number; @@ -141,10 +140,10 @@ static void callback_thread_run(struct async_reader *reader) if (hr != S_OK) break; - stream = wm_reader_get_stream_by_stream_number(&reader->reader, stream_number); - if (async_reader_wait_pts(reader, pts)) { + struct wm_stream *stream = wm_reader_get_stream_by_stream_number(&reader->reader, stream_number); + LeaveCriticalSection(&reader->callback_cs); if (stream->read_compressed) hr = IWMReaderCallbackAdvanced_OnStreamSample(callback_advanced, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/803
This merge request was approved by Zebediah Figura. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/803
participants (3)
-
Marvin -
Rémi Bernon -
Zebediah Figura (@zfigura)