diff --git a/audio/common/pipewire.c b/audio/common/pipewire.c index d81f68657ab..2f64656e626 100644 --- a/audio/common/pipewire.c +++ b/audio/common/pipewire.c @@ -200,10 +200,7 @@ void pipewire_core_deinit(pipewire_core_t *pw) return pw_deinit(); if (pw->thread_loop) - { - pw_thread_loop_unlock(pw->thread_loop); pw_thread_loop_stop(pw->thread_loop); - } if (pw->registry) pw_proxy_destroy((struct pw_proxy*)pw->registry); @@ -218,7 +215,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..00b51c77b2d 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,7 +284,10 @@ 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; @@ -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) @@ -380,8 +388,10 @@ static void pipewire_free(void *data) if (audio->stream) { + pw_thread_loop_lock(audio->pw->thread_loop); pw_stream_destroy(audio->stream); audio->stream = NULL; + pw_thread_loop_unlock(audio->pw->thread_loop); } pipewire_core_deinit(audio->pw); free(audio); diff --git a/audio/drivers_microphone/pipewire.c b/audio/drivers_microphone/pipewire.c index 41860429ad4..68b7bd71687 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,7 +223,10 @@ 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;