[vlc-commits] pulse: compute latency correctly if negative (fixes #15046)
Rémi Denis-Courmont
git at videolan.org
Sat Aug 22 11:26:03 CEST 2015
vlc/vlc-2.2 | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Aug 22 12:21:35 2015 +0300| [790c706d9f90358628b18b346b0cea74efd80aec] | committer: Rémi Denis-Courmont
pulse: compute latency correctly if negative (fixes #15046)
This occurs in case of large buffer underflow, such as if stopping the
VLC process.
(cherry picked from commit 887bda11d23665416bd9403151ad1acced68b267)
> http://git.videolan.org/gitweb.cgi/vlc/vlc-2.2.git/?a=commit;h=790c706d9f90358628b18b346b0cea74efd80aec
---
modules/audio_output/vlcpulse.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/modules/audio_output/vlcpulse.c b/modules/audio_output/vlcpulse.c
index feecfa7..0952cb0 100644
--- a/modules/audio_output/vlcpulse.c
+++ b/modules/audio_output/vlcpulse.c
@@ -252,13 +252,33 @@ void vlc_pa_rttime_free (pa_threaded_mainloop *mainloop, pa_time_event *e)
*/
mtime_t vlc_pa_get_latency(vlc_object_t *obj, pa_context *ctx, pa_stream *s)
{
- pa_usec_t latency;
- int negative;
+ /* NOTE: pa_stream_get_latency() will report 0 rather than negative latency
+ * when the write index of a playback stream is behind its read index.
+ * playback streams. So use the lower-level pa_stream_get_timing_info()
+ * directly to obtain the correct write index and convert it to a time,
+ * and compute the correct latency value by substracting the stream (read)
+ * time.
+ *
+ * On the read side, pa_stream_get_time() is used instead of
+ * pa_stream_get_timing_info() for the sake of interpolation. */
+ const pa_sample_spec *ss = pa_stream_get_sample_spec(s);
+ const pa_timing_info *ti = pa_stream_get_timing_info(s);
+
+ if (ti->write_index_corrupt) {
+ msg_Dbg(obj, "write index corrupt");
+ return VLC_TS_INVALID;
+ }
- if (pa_stream_get_latency(s, &latency, &negative)) {
- if (pa_context_errno (ctx) != PA_ERR_NODATA)
- vlc_pa_error(obj, "unknown latency", ctx);
+ pa_usec_t wt = pa_bytes_to_usec((uint64_t)ti->write_index, ss);
+ pa_usec_t rt;
+
+ if (pa_stream_get_time(s, &rt)) {
+ if (pa_context_errno(ctx) != PA_ERR_NODATA)
+ vlc_pa_error(obj, "unknown time", ctx);
return VLC_TS_INVALID;
}
- return negative ? -latency : +latency;
+
+ union { uint64_t u; int64_t s; } d;
+ d.u = wt - rt;
+ return d.s; /* non-overflowing unsigned to signed conversion */
}
More information about the vlc-commits
mailing list