diff options
author | Tanu Kaskinen <tanuk@iki.fi> | 2017-07-11 21:21:43 +0300 |
---|---|---|
committer | Tanu Kaskinen <tanuk@iki.fi> | 2017-07-20 16:56:41 +0300 |
commit | 5de4b652cb578f6386e550eba4c5dec7dc0a81b0 (patch) | |
tree | 7b263b01574ed04c91f0fb5b2e4f3287bed44a7a | |
parent | b0cd94233af840e13609c420366de0ee8898515b (diff) | |
download | pulseaudio-5de4b652cb578f6386e550eba4c5dec7dc0a81b0.tar.gz |
simple: fix negative latency handling
pa_usec_t is an unsigned type, but there were calculations that used it
as if it were a signed type.
If the latency is negative, pa_simple_get_latency() now reports 0.
Added some comments too.
-rw-r--r-- | src/pulse/simple.c | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/src/pulse/simple.c b/src/pulse/simple.c index c8e89b09b..7b66f62d7 100644 --- a/src/pulse/simple.c +++ b/src/pulse/simple.c @@ -463,18 +463,34 @@ pa_usec_t pa_simple_get_latency(pa_simple *p, int *rerror) { CHECK_DEAD_GOTO(p, rerror, unlock_and_fail); if (pa_stream_get_latency(p->stream, &t, &negative) >= 0) { - pa_usec_t extra = 0; - - if (p->direction == PA_STREAM_RECORD) - extra = -pa_bytes_to_usec(p->read_index, pa_stream_get_sample_spec(p->stream)); - - if (negative) { - if (extra > t) - t = extra - t; - else - t = 0; - } else - t += extra; + if (p->direction == PA_STREAM_RECORD) { + pa_usec_t already_read; + + /* pa_simple_read() calls pa_stream_peek() to get the next + * chunk of audio. If the next chunk is larger than what the + * pa_simple_read() caller wanted, the leftover data is stored + * in p->read_data until pa_simple_read() is called again. + * pa_stream_drop() won't be called until the whole chunk has + * been consumed, which means that pa_stream_get_latency() will + * return too large values, because the whole size of the + * partially read chunk is included in the latency. Therefore, + * we need to substract the already-read amount from the + * latency. */ + already_read = pa_bytes_to_usec(p->read_index, pa_stream_get_sample_spec(p->stream)); + + if (!negative) { + if (t > already_read) + t -= already_read; + else + t = 0; + } + } + + /* We don't have a way to report negative latencies from + * pa_simple_get_latency(). If the latency is negative, let's + * report zero. */ + if (negative) + t = 0; break; } |