summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTanu Kaskinen <tanuk@iki.fi>2017-07-11 21:21:43 +0300
committerTanu Kaskinen <tanuk@iki.fi>2017-07-20 16:56:41 +0300
commit5de4b652cb578f6386e550eba4c5dec7dc0a81b0 (patch)
tree7b263b01574ed04c91f0fb5b2e4f3287bed44a7a
parentb0cd94233af840e13609c420366de0ee8898515b (diff)
downloadpulseaudio-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.c40
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;
}