[alsa-devel] Immediate underrun with PulseAudio ALSA plugin when PA and ALSA buffer sizes differ
David Henningsson
david.henningsson at canonical.com
Thu Jul 19 10:56:09 CEST 2012
On 07/19/2012 12:14 AM, Matthew Gregan wrote:
> At 2012-07-17T08:22:20+0200, David Henningsson wrote:
>> 100 ms of latency is a lot, even for PulseAudio - is this some
>> special hardware?
>
> No, it's just a random value for media playback.
What I meant was that I can successfully run your latency test with 10
ms here - when I go down to 5 I start to get xruns. In that context,
getting problems around 50 - 100 ms of latency is quite a lot.
Anyway, I've dived a bit deeper here. I've run your latency test with 5
ms (i e 221 frames), and here's what I believe happens:
1) At the first write, 221 frames of data is written.
2) Now the stream is started. This is done by PulseAudio because the
prebuf is reached. (And should we short-cut this, there is also
something in snd_pcm_write_areas that would start it due to
start_threshold being reached.) We then wait for PulseAudio, because we
call pa_stream_writable_size right after write.
3) PulseAudio, on its side, starts the stream, quickly consumes the 221
frames of data from the client buffer, and sends out an underrun.
4) In fact, this underrun reaches alsa-plugins even while waiting for
pulse_start to finish.
5) At the next call to snd_pcm_avail_update / pulse_pointer, the XRUN is
returned to the client application.
6) snd_pcm_recover / pulse_prepare resets the stream, and then the same
thing happens over and over again.
So how do we solve this? Well, I believe the best fix would be to fix
PulseAudio to give back underruns later, i e, not until we know for sure
that the 221 frames have been played back. Right now we send it out when
the client buffer is emptied, which is too early. Deferring the underrun
on the PulseAudio side would give the client side a fair chance to fill
up PulseAudio's big buffer and thus avoid the underrun.
I remember VLC having some trouble with this behaviour as well.
This would, however, be some work in PulseAudio to get right. :-/
Meanwhile, you could make a workaround like this in ~/.asoundrc:
pcm.pulse_no_underrun {
type pulse
handle_underrun 0
}
and then open the device "pulse_no_underrun". With that workaround I can
run with 1 ms without problem in your latency test. (We can't ignore
underruns for everyone though, as that would break applications
depending on these being delivered as well. Been there, done that.)
--
David Henningsson, Canonical Ltd.
https://launchpad.net/~diwic
More information about the Alsa-devel
mailing list