mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-11-04 13:29:59 -05:00
alsa: handle correctly if alsa returns us 0 or EAGAIN on snd_pcm_mmap_begin if we didn't call snd_pcm_avail immediately before
This commit is contained in:
parent
a81244a726
commit
18433c19b6
2 changed files with 39 additions and 11 deletions
|
|
@ -391,6 +391,7 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
|
|||
snd_pcm_sframes_t n;
|
||||
size_t n_bytes;
|
||||
int r;
|
||||
pa_bool_t after_avail = TRUE;
|
||||
|
||||
if (PA_UNLIKELY((n = pa_alsa_safe_avail(u->pcm_handle, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
|
||||
|
||||
|
|
@ -463,6 +464,9 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
|
|||
|
||||
if (PA_UNLIKELY((err = pa_alsa_safe_mmap_begin(u->pcm_handle, &areas, &offset, &frames, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
|
||||
|
||||
if (!after_avail && err == -EAGAIN)
|
||||
break;
|
||||
|
||||
if ((r = try_recover(u, "snd_pcm_mmap_begin", err)) == 0)
|
||||
continue;
|
||||
|
||||
|
|
@ -473,9 +477,12 @@ static int mmap_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
|
|||
if (frames > pa_mempool_block_size_max(u->source->core->mempool)/u->frame_size)
|
||||
frames = pa_mempool_block_size_max(u->source->core->mempool)/u->frame_size;
|
||||
|
||||
if (frames == 0)
|
||||
if (!after_avail && frames == 0)
|
||||
break;
|
||||
|
||||
pa_assert(frames > 0);
|
||||
after_avail = FALSE;
|
||||
|
||||
/* Check these are multiples of 8 bit */
|
||||
pa_assert((areas[0].first & 7) == 0);
|
||||
pa_assert((areas[0].step & 7)== 0);
|
||||
|
|
@ -542,6 +549,7 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
|
|||
snd_pcm_sframes_t n;
|
||||
size_t n_bytes;
|
||||
int r;
|
||||
pa_bool_t after_avail = TRUE;
|
||||
|
||||
if (PA_UNLIKELY((n = pa_alsa_safe_avail(u->pcm_handle, u->hwbuf_size, &u->source->sample_spec)) < 0)) {
|
||||
|
||||
|
|
@ -602,20 +610,26 @@ static int unix_read(struct userdata *u, pa_usec_t *sleep_usec, pa_bool_t polled
|
|||
frames = snd_pcm_readi(u->pcm_handle, (uint8_t*) p, (snd_pcm_uframes_t) frames);
|
||||
pa_memblock_release(chunk.memblock);
|
||||
|
||||
if (frames == 0) {
|
||||
pa_memblock_unref(chunk.memblock);
|
||||
break;
|
||||
}
|
||||
|
||||
if (PA_UNLIKELY(frames < 0)) {
|
||||
pa_memblock_unref(chunk.memblock);
|
||||
|
||||
if ((r = try_recover(u, "snd_pcm_readi", (int) (frames))) == 0)
|
||||
if (!after_avail && (int) frames == -EAGAIN)
|
||||
break;
|
||||
|
||||
if ((r = try_recover(u, "snd_pcm_readi", (int) frames)) == 0)
|
||||
continue;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!after_avail && frames == 0) {
|
||||
pa_memblock_unref(chunk.memblock);
|
||||
break;
|
||||
}
|
||||
|
||||
pa_assert(frames > 0);
|
||||
after_avail = FALSE;
|
||||
|
||||
chunk.index = 0;
|
||||
chunk.length = (size_t) frames * u->frame_size;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue