diff options
author | Matthew Gregan <[email protected]> | 2011-11-25 16:50:13 +1300 |
---|---|---|
committer | Matthew Gregan <[email protected]> | 2011-11-25 16:50:13 +1300 |
commit | 055ac9f222878b6889e26e1b0efc7c27b9ecaf00 (patch) | |
tree | e39f2107afab987c29fcccdfceb8e68db9bfe3af | |
parent | 179f2fbcdd0a2c3a0325d9d60a09ad29bff2a9ec (diff) | |
download | cubeb-055ac9f222878b6889e26e1b0efc7c27b9ecaf00.tar.gz cubeb-055ac9f222878b6889e26e1b0efc7c27b9ecaf00.zip |
pulse: pa_stream_drain is useless (see PA bug# 866), so use a timer instead.
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | src/cubeb_pulse.c | 20 |
2 files changed, 12 insertions, 11 deletions
@@ -1,8 +1,5 @@ TODO: -- osx drain: listener fails to fire on 10.5 often (and sometimes on 10.6) - add watchdog timer to deal with this - osx: understand why AudioQueueGetCurrentTime can return negative mSampleTime -- alsa: drain blocks in nblock mode (for alsa-pulse), so need watchdog timer - test (and fix) sub-prefill size data playback - report stream delay instead of position; leave position calculation to user - capture support diff --git a/src/cubeb_pulse.c b/src/cubeb_pulse.c index 1d82c51..5409226 100644 --- a/src/cubeb_pulse.c +++ b/src/cubeb_pulse.c @@ -21,7 +21,7 @@ struct cubeb_stream { cubeb_data_callback data_callback; cubeb_state_callback state_callback; void * user_ptr; - pa_operation * draining; + pa_time_event * drain_timer; pa_sample_spec sample_spec; int shutdown; }; @@ -54,13 +54,14 @@ stream_success_callback(pa_stream * s, int success, void * m) } static void -stream_drain_success_callback(pa_stream * s, int success, void * u) +stream_drain_callback(pa_mainloop_api * a, pa_time_event * e, struct timeval const * tv, void * u) { cubeb_stream * stm = u; + /* there's no pa_rttime_free, so use this instead. */ + a->time_free(stm->drain_timer); + stm->drain_timer = NULL; stm->state_callback(stm, stm->user_ptr, CUBEB_STATE_DRAINED); - - pa_threaded_mainloop_signal(stm->context->mainloop, 0); } static void @@ -114,7 +115,10 @@ stream_request_callback(pa_stream * s, size_t nbytes, void * u) assert(r == 0); if ((size_t) got < size / frame_size) { - stm->draining = pa_stream_drain(s, stream_drain_success_callback, stm); + size_t buffer_fill = pa_stream_get_buffer_attr(s)->maxlength - pa_stream_writable_size(s); + double buffer_time = (double) buffer_fill / stm->sample_spec.rate; + /* pa_stream_drain is useless, see PA bug# 866. this is a workaround. */ + stm->drain_timer = pa_context_rttime_new(stm->context->context, pa_rtclock_now() + buffer_time * 1e6, stream_drain_callback, stm); stm->shutdown = 1; return; } @@ -321,9 +325,9 @@ cubeb_stream_destroy(cubeb_stream * stm) pa_threaded_mainloop_lock(stm->context->mainloop); - if (stm->draining) { - pa_operation_cancel(stm->draining); - pa_operation_unref(stm->draining); + if (stm->drain_timer) { + /* there's no pa_rttime_free, so use this instead. */ + pa_threaded_mainloop_get_api(stm->context->mainloop)->time_free(stm->drain_timer); } pa_stream_disconnect(stm->stream); |