Module: wine Branch: master Commit: 13cac6287c454146eff73aabc4b92b5c8f76d4df URL: https://source.winehq.org/git/wine.git/?a=commit;h=13cac6287c454146eff73aabc...
Author: Jacek Caban jacek@codeweavers.com Date: Thu May 13 16:05:06 2021 +0200
winepulse: Move timer loop to unix lib.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Andrew Eikum aeikum@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winepulse.drv/mmdevdrv.c | 87 +--------------------------------- dlls/winepulse.drv/pulse.c | 107 +++++++++++++++++++++++++++++++++++++++++- dlls/winepulse.drv/unixlib.h | 2 +- 3 files changed, 107 insertions(+), 89 deletions(-)
diff --git a/dlls/winepulse.drv/mmdevdrv.c b/dlls/winepulse.drv/mmdevdrv.c index 975f38794ac..f9b16bee66b 100644 --- a/dlls/winepulse.drv/mmdevdrv.c +++ b/dlls/winepulse.drv/mmdevdrv.c @@ -251,93 +251,8 @@ static void pulse_op_cb(pa_stream *s, int success, void *user) {
static DWORD WINAPI pulse_timer_cb(void *user) { - LARGE_INTEGER delay; - UINT32 adv_bytes; ACImpl *This = user; - int success; - pa_operation *o; - - pulse->lock(); - delay.QuadPart = -This->pulse_stream->mmdev_period_usec * 10; - pa_stream_get_time(This->pulse_stream->stream, &This->pulse_stream->last_time); - pulse->unlock(); - - while(!This->pulse_stream->please_quit){ - pa_usec_t now, adv_usec = 0; - int err; - - NtDelayExecution(FALSE, &delay); - - pulse->lock(); - - delay.QuadPart = -This->pulse_stream->mmdev_period_usec * 10; - - o = pa_stream_update_timing_info(This->pulse_stream->stream, pulse_op_cb, &success); - if (o) - { - while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) - pulse->cond_wait(); - pa_operation_unref(o); - } - err = pa_stream_get_time(This->pulse_stream->stream, &now); - if(err == 0){ - TRACE("got now: %s, last time: %s\n", wine_dbgstr_longlong(now), wine_dbgstr_longlong(This->pulse_stream->last_time)); - if(This->pulse_stream->started && (This->dataflow == eCapture || This->pulse_stream->held_bytes)){ - if(This->pulse_stream->just_underran){ - This->pulse_stream->last_time = now; - This->pulse_stream->just_started = TRUE; - } - - if(This->pulse_stream->just_started){ - /* let it play out a period to absorb some latency and get accurate timing */ - pa_usec_t diff = now - This->pulse_stream->last_time; - - if(diff > This->pulse_stream->mmdev_period_usec){ - This->pulse_stream->just_started = FALSE; - This->pulse_stream->last_time = now; - } - }else{ - INT32 adjust = This->pulse_stream->last_time + This->pulse_stream->mmdev_period_usec - now; - - adv_usec = now - This->pulse_stream->last_time; - - if(adjust > ((INT32)(This->pulse_stream->mmdev_period_usec / 2))) - adjust = This->pulse_stream->mmdev_period_usec / 2; - else if(adjust < -((INT32)(This->pulse_stream->mmdev_period_usec / 2))) - adjust = -1 * This->pulse_stream->mmdev_period_usec / 2; - - delay.QuadPart = -(This->pulse_stream->mmdev_period_usec + adjust) * 10; - - This->pulse_stream->last_time += This->pulse_stream->mmdev_period_usec; - } - - if(This->dataflow == eRender){ - pulse->write(This->pulse_stream); - - /* regardless of what PA does, advance one period */ - adv_bytes = min(This->pulse_stream->period_bytes, This->pulse_stream->held_bytes); - This->pulse_stream->lcl_offs_bytes += adv_bytes; - This->pulse_stream->lcl_offs_bytes %= This->pulse_stream->real_bufsize_bytes; - This->pulse_stream->held_bytes -= adv_bytes; - }else if(This->dataflow == eCapture){ - pulse->read(This->pulse_stream); - } - }else{ - This->pulse_stream->last_time = now; - delay.QuadPart = -This->pulse_stream->mmdev_period_usec * 10; - } - } - - if (This->pulse_stream->event) - SetEvent(This->pulse_stream->event); - - TRACE("%p after update, adv usec: %d, held: %u, delay usec: %u\n", - This, (int)adv_usec, - (int)(This->pulse_stream->held_bytes/ pa_frame_size(&This->pulse_stream->ss)), (unsigned int)(-delay.QuadPart / 10)); - - pulse->unlock(); - } - + pulse->timer_loop(This->pulse_stream); return 0; }
diff --git a/dlls/winepulse.drv/pulse.c b/dlls/winepulse.drv/pulse.c index 1dd906aef68..d720b79a22d 100644 --- a/dlls/winepulse.drv/pulse.c +++ b/dlls/winepulse.drv/pulse.c @@ -1054,7 +1054,7 @@ static void WINAPI pulse_write(struct pulse_stream *stream) stream->pa_held_bytes -= to_write; }
-static void WINAPI pulse_read(struct pulse_stream *stream) +static void pulse_read(struct pulse_stream *stream) { size_t bytes = pa_stream_readable_size(stream->stream);
@@ -1154,6 +1154,109 @@ static void WINAPI pulse_read(struct pulse_stream *stream) } }
+static void WINAPI pulse_timer_loop(struct pulse_stream *stream) +{ + LARGE_INTEGER delay; + UINT32 adv_bytes; + int success; + pa_operation *o; + + pulse_lock(); + delay.QuadPart = -stream->mmdev_period_usec * 10; + pa_stream_get_time(stream->stream, &stream->last_time); + pulse_unlock(); + + while (!stream->please_quit) + { + pa_usec_t now, adv_usec = 0; + int err; + + NtDelayExecution(FALSE, &delay); + + pulse_lock(); + + delay.QuadPart = -stream->mmdev_period_usec * 10; + + o = pa_stream_update_timing_info(stream->stream, pulse_op_cb, &success); + if (o) + { + while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) + pulse_cond_wait(); + pa_operation_unref(o); + } + err = pa_stream_get_time(stream->stream, &now); + if (err == 0) + { + TRACE("got now: %s, last time: %s\n", wine_dbgstr_longlong(now), wine_dbgstr_longlong(stream->last_time)); + if (stream->started && (stream->dataflow == eCapture || stream->held_bytes)) + { + if(stream->just_underran) + { + stream->last_time = now; + stream->just_started = TRUE; + } + + if (stream->just_started) + { + /* let it play out a period to absorb some latency and get accurate timing */ + pa_usec_t diff = now - stream->last_time; + + if (diff > stream->mmdev_period_usec) + { + stream->just_started = FALSE; + stream->last_time = now; + } + } + else + { + INT32 adjust = stream->last_time + stream->mmdev_period_usec - now; + + adv_usec = now - stream->last_time; + + if(adjust > ((INT32)(stream->mmdev_period_usec / 2))) + adjust = stream->mmdev_period_usec / 2; + else if(adjust < -((INT32)(stream->mmdev_period_usec / 2))) + adjust = -1 * stream->mmdev_period_usec / 2; + + delay.QuadPart = -(stream->mmdev_period_usec + adjust) * 10; + + stream->last_time += stream->mmdev_period_usec; + } + + if (stream->dataflow == eRender) + { + pulse_write(stream); + + /* regardless of what PA does, advance one period */ + adv_bytes = min(stream->period_bytes, stream->held_bytes); + stream->lcl_offs_bytes += adv_bytes; + stream->lcl_offs_bytes %= stream->real_bufsize_bytes; + stream->held_bytes -= adv_bytes; + } + else if(stream->dataflow == eCapture) + { + pulse_read(stream); + } + } + else + { + stream->last_time = now; + delay.QuadPart = -stream->mmdev_period_usec * 10; + } + } + + if (stream->event) + NtSetEvent(stream->event, NULL); + + TRACE("%p after update, adv usec: %d, held: %u, delay usec: %u\n", + stream, (int)adv_usec, + (int)(stream->held_bytes/ pa_frame_size(&stream->ss)), + (unsigned int)(-delay.QuadPart / 10)); + + pulse_unlock(); + } +} + static HRESULT WINAPI pulse_stop(struct pulse_stream *stream) { HRESULT hr = S_OK; @@ -1212,8 +1315,8 @@ static const struct unix_funcs unix_funcs = pulse_create_stream, pulse_release_stream, pulse_write, - pulse_read, pulse_stop, + pulse_timer_loop, pulse_set_volumes, pulse_test_connect, }; diff --git a/dlls/winepulse.drv/unixlib.h b/dlls/winepulse.drv/unixlib.h index 5413c4d2c78..4188dacc25f 100644 --- a/dlls/winepulse.drv/unixlib.h +++ b/dlls/winepulse.drv/unixlib.h @@ -79,8 +79,8 @@ struct unix_funcs struct pulse_stream **ret); void (WINAPI *release_stream)(struct pulse_stream *stream, HANDLE timer); void (WINAPI *write)(struct pulse_stream *stream); - void (WINAPI *read)(struct pulse_stream *stream); HRESULT (WINAPI *stop)(struct pulse_stream *stream); + void (WINAPI *timer_loop)(struct pulse_stream *stream); void (WINAPI *set_volumes)(struct pulse_stream *stream, float master_volume, const float *volumes, const float *session_volumes); HRESULT (WINAPI *test_connect)(const char *name, struct pulse_config *config);