diff options
author | Wim Taymans <wtaymans@redhat.com> | 2020-05-13 12:09:28 +0200 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2020-05-13 12:09:28 +0200 |
commit | 56730197d9e7a9c27c41e30cfe59bc929f8bfe8e (patch) | |
tree | e94e4b538b8a9555b7deeab0b2a5564e7fa6cb56 /pipewire-alsa | |
parent | fefdc26f84f6735131b91ca7c046105af7208204 (diff) |
alsa: report xrun
When we record but there is not enough space in the ringbuffer, report
xrun.
Diffstat (limited to 'pipewire-alsa')
-rw-r--r-- | pipewire-alsa/alsa-plugins/pcm_pipewire.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/pipewire-alsa/alsa-plugins/pcm_pipewire.c b/pipewire-alsa/alsa-plugins/pcm_pipewire.c index 25626113..0e9944f7 100644 --- a/pipewire-alsa/alsa-plugins/pcm_pipewire.c +++ b/pipewire-alsa/alsa-plugins/pcm_pipewire.c @@ -64,6 +64,7 @@ typedef struct { unsigned int activated:1; /* PipeWire is activated? */ unsigned int drained:1; unsigned int draining:1; + unsigned int xrun_detected:1; snd_pcm_uframes_t hw_ptr; snd_pcm_uframes_t boundary; @@ -160,9 +161,15 @@ static int snd_pcm_pipewire_poll_revents(snd_pcm_ioplug_t *io, static snd_pcm_sframes_t snd_pcm_pipewire_pointer(snd_pcm_ioplug_t *io) { snd_pcm_pipewire_t *pw = io->private_data; + if (pw->xrun_detected) + return -EPIPE; if (pw->error < 0) return pw->error; +#ifdef SND_PCM_IOPLUG_FLAG_BOUNDARY_WA return pw->hw_ptr; +#else + return pw->hw_ptr % io->buffer_size; +#endif } static int @@ -274,13 +281,16 @@ snd_pcm_pipewire_process_record(snd_pcm_pipewire_t *pw, struct pw_buffer *b, snd avail = SPA_MIN(maxsize, *hw_avail * bpf); index = d[0].chunk->offset; + if (maxsize > *hw_avail) + pw->xrun_detected = true; + do { avail = SPA_MIN(avail, pw->min_avail * bpf); offset = index % maxsize; nbytes = SPA_MIN(avail, maxsize - offset); ptr = SPA_MEMBER(d[0].data, offset, void); - pw_log_trace(NAME" %p: %d %d %d %p", pw, nbytes, avail, offset, ptr); + pw_log_trace(NAME" %p: %d %ld %d %d %d %p", pw, maxsize, *hw_avail, nbytes, avail, offset, ptr); nframes = nbytes / bpf; for (channel = 0; channel < io->channels; channel++) { @@ -481,6 +491,7 @@ static int snd_pcm_pipewire_prepare(snd_pcm_ioplug_t *io) done: pw->hw_ptr = 0; + pw->xrun_detected = false; pw_thread_loop_unlock(pw->main_loop); @@ -951,6 +962,11 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name, pw->io.poll_fd = pw->fd; pw->io.poll_events = POLLIN; pw->io.mmap_rw = 1; +#ifdef SND_PCM_IOPLUG_FLAG_BOUNDARY_WA + pw->io.flags = SND_PCM_IOPLUG_FLAG_BOUNDARY_WA; +#else +#warning hw_ptr updates of buffer_size will not be recognized by the ALSA library. Consider to update your ALSA library. +#endif if ((err = snd_pcm_ioplug_create(&pw->io, name, stream, mode)) < 0) goto error; |