From 47a6f54910ffbb914a2aadf9daa9f8df3d5dcfb0 Mon Sep 17 00:00:00 2001 From: fryshorts Date: Sun, 16 Feb 2014 13:49:28 +0100 Subject: [PATCH] use pa_mainloop_iterate instead of own implementation pulse audio provides it's own convenience function to iterate the mainloop, no need to use a custom one. pulseaudio provides timing information for the stream, we use that instead of system time. --- test/linux/pulse-input.c | 37 ++++++++++++------------------------- 1 file changed, 12 insertions(+), 25 deletions(-) diff --git a/test/linux/pulse-input.c b/test/linux/pulse-input.c index c5831935c..5284cf765 100644 --- a/test/linux/pulse-input.c +++ b/test/linux/pulse-input.c @@ -17,7 +17,6 @@ along with this program. If not, see . #include #include -#include #include #include @@ -30,13 +29,13 @@ along with this program. If not, see . #define PULSE_DATA(voidptr) struct pulse_data *data = voidptr; /* - * delay in nanos before starting to record, this eliminates problems with + * delay in usecs before starting to record, this eliminates problems with * pulse audio sending weird data/timestamps when the stream is connected * * for more information see: * github.com/MaartenBaert/ssr/blob/master/src/AV/Input/PulseAudioInput.cpp */ -const uint64_t pulse_start_delay = 100000000; +const uint64_t pulse_start_delay = 100000; struct pulse_data { pthread_t thread; @@ -53,20 +52,6 @@ struct pulse_data { pa_stream *stream; }; -static void pulse_iterate(struct pulse_data *data) -{ - if (pa_mainloop_prepare(data->mainloop, 1000) < 0) { - blog(LOG_ERROR, "Unable to prepare main loop"); - return; - } - if (pa_mainloop_poll(data->mainloop) < 0) { - blog(LOG_ERROR, "Unable to poll main loop"); - return; - } - if (pa_mainloop_dispatch(data->mainloop) < 0) - blog(LOG_ERROR, "Unable to dispatch main loop"); -} - /* * Create a new pulse audio main loop and connect to the server * @@ -96,7 +81,7 @@ static int pulse_connect(struct pulse_data *data) // wait until connected for (;;) { - pulse_iterate(data); + pa_mainloop_iterate(data->mainloop, 0, NULL); pa_context_state_t state = pa_context_get_state(data->context); if (state == PA_CONTEXT_READY) { blog(LOG_DEBUG, "Context ready"); @@ -160,7 +145,7 @@ static int pulse_connect_stream(struct pulse_data *data) } for (;;) { - pulse_iterate(data); + pa_mainloop_iterate(data->mainloop, 0, NULL); pa_stream_state_t state = pa_stream_get_state(data->stream); if (state == PA_STREAM_READY) { blog(LOG_DEBUG, "Stream ready"); @@ -203,9 +188,7 @@ static void *pulse_thread(void *vptr) uint64_t skip = 1; while (event_try(&data->event) == EAGAIN) { - uint64_t cur_time = os_gettime_ns(); - - pulse_iterate(data); + pa_mainloop_iterate(data->mainloop, 0, NULL); const void *frames; size_t bytes; @@ -217,12 +200,16 @@ static void *pulse_thread(void *vptr) continue; } + uint64_t pa_time; + if (pa_stream_get_time(data->stream, &pa_time) < 0) + continue; + // skip the first frames received if (skip) { // start delay when we receive the first bytes if (skip == 1 && bytes) - skip = os_gettime_ns(); - if (skip + pulse_start_delay < os_gettime_ns()) + skip = pa_time; + if (skip + pulse_start_delay < pa_time) skip = 0; pa_stream_drop(data->stream); continue; @@ -240,7 +227,7 @@ static void *pulse_thread(void *vptr) out.frames = bytes / data->channels; out.speakers = data->speakers; out.samples_per_sec = data->samples_per_sec; - out.timestamp = cur_time - (latency * 1000); + out.timestamp = (pa_time - latency) * 1000; out.format = AUDIO_FORMAT_U8BIT; // send data to obs