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

Alexandre Julliard julliard at winehq.org
Fri Nov 12 16:16:03 CST 2021


Module: wine
Branch: master
Commit: 747905c674d521b61923a6cff1d630c85a74d065
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=747905c674d521b61923a6cff1d630c85a74d065

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Thu Nov 11 23:43:24 2021 -0600

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

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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");




More information about the wine-cvs mailing list