From 0ef48b808328f2d3a1530ce1048167c9554c49c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Via=C4=8Das=C5=82a=C5=AD=20Chalikin?= Date: Tue, 21 Jan 2025 02:09:39 +0300 Subject: [PATCH] (PipeWire) reset playback buffer on stopping * Fix compile warnings --- audio/common/pipewire.c | 3 ++- audio/drivers/pipewire.c | 24 ++++++++++++++++-------- audio/drivers_microphone/pipewire.c | 12 +++++++----- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/audio/common/pipewire.c b/audio/common/pipewire.c index d81f68657ab..b6000e8c6f3 100644 --- a/audio/common/pipewire.c +++ b/audio/common/pipewire.c @@ -218,7 +218,8 @@ void pipewire_core_deinit(pipewire_core_t *pw) if (pw->ctx) pw_context_destroy(pw->ctx); - pw_thread_loop_destroy(pw->thread_loop); + if (pw->thread_loop) + pw_thread_loop_destroy(pw->thread_loop); if (pw->devicelist) string_list_free(pw->devicelist); diff --git a/audio/drivers/pipewire.c b/audio/drivers/pipewire.c index 934983e7f03..3ddb27cc66a 100644 --- a/audio/drivers/pipewire.c +++ b/audio/drivers/pipewire.c @@ -66,12 +66,12 @@ static void playback_process_cb(void *data) if ((b = pw_stream_dequeue_buffer(audio->stream)) == NULL) { RARCH_WARN("[Audio] [PipeWire]: Out of buffers: %s\n", strerror(errno)); - return; + return pw_thread_loop_signal(audio->pw->thread_loop, false); } buf = b->buffer; if ((p = buf->datas[0].data) == NULL) - goto done; + return pw_thread_loop_signal(audio->pw->thread_loop, false); /* calculate the total no of bytes to read data from buffer */ n_bytes = buf->datas[0].maxsize; @@ -100,7 +100,6 @@ static void playback_process_cb(void *data) buf->datas[0].chunk->stride = audio->frame_size; buf->datas[0].chunk->size = n_bytes; -done: pw_stream_queue_buffer(audio->stream, b); pw_thread_loop_signal(audio->pw->thread_loop, false); } @@ -263,7 +262,7 @@ static ssize_t pipewire_write(void *data, const void *buf_, size_t len) pw_thread_loop_lock(audio->pw->thread_loop); - while (len) + for (;;) { filled = spa_ringbuffer_get_write_index(&audio->ring, &idx); avail = audio->highwater_mark - filled; @@ -285,11 +284,14 @@ static ssize_t pipewire_write(void *data, const void *buf_, size_t len) pw_thread_loop_wait(audio->pw->thread_loop); if (pw_stream_get_state(audio->stream, &error) != PW_STREAM_STATE_STREAMING) + { + pw_thread_loop_unlock(audio->pw->thread_loop); return -1; + } } else break; - } + }; if (filled < 0) RARCH_ERR("[Audio] [Pipewire]: %p: underrun write:%u filled:%d\n", audio, idx, filled); @@ -316,15 +318,21 @@ static bool pipewire_stop(void *data) { pipewire_audio_t *audio = (pipewire_audio_t*)data; const char *error = NULL; + bool res = false; if (!audio || !audio->pw) return false; if (pw_stream_get_state(audio->stream, &error) == PW_STREAM_STATE_STREAMING) - return pipewire_stream_set_active(audio->pw->thread_loop, audio->stream, false); + res = pipewire_stream_set_active(audio->pw->thread_loop, audio->stream, false); + else + /* For other states we assume that the stream is inactive */ + res = true; + + spa_ringbuffer_read_update(&audio->ring, 0); + spa_ringbuffer_write_update(&audio->ring, 0); - /* For other states we assume that the stream is inactive */ - return true; + return res; } static bool pipewire_start(void *data, bool is_shutdown) diff --git a/audio/drivers_microphone/pipewire.c b/audio/drivers_microphone/pipewire.c index 41860429ad4..99133c4f1c6 100644 --- a/audio/drivers_microphone/pipewire.c +++ b/audio/drivers_microphone/pipewire.c @@ -77,12 +77,12 @@ static void capture_process_cb(void *data) if (!(b = pw_stream_dequeue_buffer(mic->stream))) { RARCH_ERR("[Microphone] [PipeWire]: Out of buffers: %s\n", strerror(errno)); - return; + return pw_thread_loop_signal(mic->pw->thread_loop, false); } buf = b->buffer; if ((p = buf->datas[0].data) == NULL) - goto done; + return pw_thread_loop_signal(mic->pw->thread_loop, false); offs = MIN(buf->datas[0].chunk->offset, buf->datas[0].maxsize); n_bytes = MIN(buf->datas[0].chunk->size, buf->datas[0].maxsize - offs); @@ -102,7 +102,6 @@ static void capture_process_cb(void *data) idx += n_bytes; spa_ringbuffer_write_update(&mic->ring, idx); -done: pw_stream_queue_buffer(mic->stream, b); pw_thread_loop_signal(mic->pw->thread_loop, false); } @@ -209,7 +208,7 @@ static int pipewire_microphone_read(void *driver_context, void *mic_context, voi pw_thread_loop_lock(pw->thread_loop); - while (len) + for (;;) { /* get no of available bytes to read data from buffer */ readable = spa_ringbuffer_get_read_index(&mic->ring, &idx); @@ -224,11 +223,14 @@ static int pipewire_microphone_read(void *driver_context, void *mic_context, voi pw_thread_loop_wait(pw->thread_loop); if (pw_stream_get_state(mic->stream, &error) != PW_STREAM_STATE_STREAMING) + { + pw_thread_loop_unlock(mic->pw->thread_loop); return -1; + } } else break; - } + }; spa_ringbuffer_read_data(&mic->ring, mic->buffer, RINGBUFFER_SIZE,