-- 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.
From: R��mi Bernon rbernon@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);
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@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);
From: R��mi Bernon rbernon@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;
From: R��mi Bernon rbernon@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);
From: R��mi Bernon rbernon@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,
From: R��mi Bernon rbernon@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
From: R��mi Bernon rbernon@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))
From: R��mi Bernon rbernon@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)
From: R��mi Bernon rbernon@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,
This merge request was approved by Zebediah Figura.