[pulseaudio-discuss] [PATCH 0/2] Improve default buffer latency parameters

David Henningsson david.henningsson at canonical.com
Tue Mar 19 05:51:55 PDT 2013


I spend some of yesterday and today investigating our different buffer
modes to see how they behave in practice, i e when PulseAudio asks for
more data and what the resulting latency will be.

Our buffer modes are
 * "adjust latency mode" / PA_STREAM_ADJUST_LATENCY,
 * "traditional mode" / PA_STREAM_NOFLAGS,
 * "early requests mode" / PA_STREAM_EARLY_REQUESTS.

All tests were done on my onboard soundcard, which has 64K of maximum hardware buffer,
which translates to 371 ms in the chosen sample format.

When reading this, allow a margin of 1-2 ms for various system latencies, including
the turn-around time of the "Stream started" notification, and also remember the
default process_msec of 20 ms.

The first test - high latency scenario, I had all buffer_attr parameters set to -1.

PA_STREAM_ADJUST_LATENCY:
  7.19: Writing 1628.50 ms, latency 0.00 to 1628.50 ms
 10.88: Stream started
 10.96: Writing 363.74 ms, latency 1628.42 to 1992.16 ms
363.12: Writing 358.25 ms, latency 1640.00 to 1998.26 ms
715.59: Writing 352.83 ms, latency 1645.79 to 1998.62 ms

PA_STREAM_NOFLAGS:
  1.35: Writing 2000.00 ms, latency 0.00 to 2000.00 ms
  2.70: Stream started
  2.72: Writing 370.07 ms, latency 1999.98 to 2370.05 ms
355.11: Writing 351.75 ms, latency 2017.66 to 2369.41 ms
706.85: Writing 351.84 ms, latency 2017.67 to 2369.50 ms

PA_STREAM_EARLY_REQUESTS:
 11.67: Writing 2000.00 ms, latency 0.00 to 2000.00 ms
 15.24: Stream started
 25.53: Writing 29.02 ms, latency 1989.71 to 2018.73 ms
 46.16: Writing 20.61 ms, latency 1998.10 to 2018.72 ms
 66.90: Writing 20.63 ms, latency 1997.98 to 2018.62 ms

To sum up:
PA_STREAM_ADJUST_LATENCY - Every time latency is below 2000 - 371 + 20 ms,
we're asked to fill up to 2000 ms.

PA_STREAM_NOFLAGS - Every time latency is below 2000 + 20 ms,
we're asked to fill up to 2000 + 371 ms.

PA_STREAM_EARLY_REQUESTS - Every time latency is below 2000 ms,
we're asked to fill up to 2000 + 20 ms.

Side note: for both PA_STREAM_ADJUST_LATENCY and PA_STREAM_NOFLAGS, after a while
the write request is split, like this:

1771.19: Writing 221.90 ms, latency 2018.19 to 2240.09 ms
1771.55: Writing 130.27 ms, latency 2239.73 to 2370.00 ms
2122.88: Writing 90.48 ms, latency 2018.67 to 2109.15 ms
2123.12: Writing 149.43 ms, latency 2108.91 to 2258.35 ms
2123.35: Writing 111.93 ms, latency 2258.11 to 2370.04 ms

The sum is the same, and it's nothing a well written client shouldn't be able to handle,
but it sounds like there is some room for optimisation here. I haven't looked into why
this could be.


Ok, second test, a medium-latency scenario, where we set tlength = 200 ms, which IIRC
is the GStreamer default.

PA_STREAM_ADJUST_LATENCY:
  8.29: Writing 120.00 ms, latency 0.00 to 120.00 ms
  9.98: Stream started
 10.06: Writing 78.71 ms, latency 119.92 to 198.63 ms
 70.17: Writing 60.32 ms, latency 138.52 to 198.84 ms
130.06: Writing 60.23 ms, latency 138.95 to 199.17 ms

PA_STREAM_NOFLAGS:
  9.01: Writing 200.00 ms, latency 0.00 to 200.00 ms
 10.68: Stream started
 10.77: Writing 158.71 ms, latency 199.90 to 358.61 ms
151.09: Writing 140.29 ms, latency 218.29 to 358.59 ms
291.38: Writing 140.29 ms, latency 218.30 to 358.59 ms

PA_STREAM_EARLY_REQUESTS:
  7.51: Writing 200.00 ms, latency 0.00 to 200.00 ms
  9.07: Stream started
 19.45: Writing 28.98 ms, latency 189.62 to 218.60 ms
 39.67: Writing 20.36 ms, latency 198.38 to 218.74 ms
 60.50: Writing 20.52 ms, latency 197.91 to 218.43 ms

To sum up:

PA_STREAM_ADJUST_LATENCY - Every time latency is below 200 / 2 + 2 * 20 ms = 140 ms,
we're asked to fill up to 200 ms.

PA_STREAM_NOFLAGS - Every time latency is below 200 + 20 ms,
we're asked to fill up to 200 * 2 - 2 * 20 ms = 360 ms.

PA_STREAM_EARLY_REQUESTS - Every time latency is below 200 ms,
we're asked to fill up to 200 + 20 ms.

The 2 * minreq thing used in the core isn't entirely obvious to me,
but the general rule remain; if you want *max* latency to be tlength,
set PA_STREAM_ADJUST_LATENCY, and if you want *min* latency to be tlength,
go for PA_STREAM_NOFLAGS.
PA_STREAM_EARLY_REQUESTS is probably only meant where you specify minreq too,
like the alsa-plugins layer does. Let's leave that for now.


Ok, next is a low-latency scenario of setting maxlength = tlength = 10 ms.
But it failed miserably in all buffer modes, because PulseAudio wouldn't ask
for more data soon enough.
With patch 2/2 in this series applied, things got a lot better:

PA_STREAM_ADJUST_LATENCY:
  7.52: Writing 7.50 ms, latency 0.00 to 7.50 ms
  8.55: Stream started
 10.11: Writing 2.72 ms, latency 5.95 to 8.67 ms
 14.21: Writing 3.88 ms, latency 4.56 to 8.44 ms
 17.88: Writing 3.83 ms, latency 4.77 to 8.60 ms

PA_STREAM_NOFLAGS:
  8.40: Writing 10.00 ms, latency 0.00 to 10.00 ms
  9.80: Stream started
  9.87: Writing 3.70 ms, latency 9.94 to 13.63 ms
 12.33: Writing 2.77 ms, latency 11.16 to 13.93 ms
 15.04: Writing 2.72 ms, latency 11.22 to 13.94 ms

PA_STREAM_EARLY_REQUESTS:
  7.18: Writing 10.00 ms, latency 0.00 to 10.00 ms
  8.15: Stream started
  9.58: Writing 2.65 ms, latency 8.57 to 11.22 ms
 13.27: Writing 3.72 ms, latency 7.54 to 11.26 ms
 17.06: Writing 3.74 ms, latency 7.46 to 11.21 ms

With the minreq patch that sets minreq to 10 / 4 = 2.5 ms, we can see that the result
for PA_STREAM_ADJUST_LATENCY is to try to keep the latency between 7.5 ms and 10 ms,
for PA_STREAM_NOFLAGS to try to keep the latency between 12.5 ms and 15 ms, and
for PA_STREAM_EARLY_REQUESTS to try to keep latency between 10 ms and 12.5 ms.

We end up always writing a little bit more than 2.5 ms in all scenarios, probably due to
scheduling variations within the system.

Comments / questions?

David Henningsson (2):
  protocol-native: Ensure tlength is not set higher than maxlength
  protocol-native: Lower default minreq in low-latency scenarios

 src/pulsecore/protocol-native.c |   13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

-- 
1.7.9.5



More information about the pulseaudio-discuss mailing list