[vlc-commits] pulse: fix start time, do not confuse first and last PTS in buffer
Rémi Denis-Courmont
git at videolan.org
Thu Oct 18 21:58:48 CEST 2012
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Thu Oct 18 22:46:35 2012 +0300| [ce87f749aef0db130f494fb8d8e9e2653e0be4f5] | committer: Rémi Denis-Courmont
pulse: fix start time, do not confuse first and last PTS in buffer
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ce87f749aef0db130f494fb8d8e9e2653e0be4f5
---
modules/audio_output/pulse.c | 45 ++++++++++++++++++++++++++----------------
1 file changed, 28 insertions(+), 17 deletions(-)
diff --git a/modules/audio_output/pulse.c b/modules/audio_output/pulse.c
index 80d4490..22a604c 100644
--- a/modules/audio_output/pulse.c
+++ b/modules/audio_output/pulse.c
@@ -64,8 +64,9 @@ struct aout_sys_t
pa_time_event *trigger; /**< Deferred stream trigger */
pa_volume_t base_volume; /**< 0dB reference volume */
pa_cvolume cvolume; /**< actual sink input volume */
+ mtime_t first_pts; /**< Play time of buffer start */
+ mtime_t last_pts; /**< Play time of buffer write offset */
mtime_t paused; /**< Time when (last) paused */
- mtime_t pts; /**< Play time of buffer write offset */
mtime_t desync; /**< Measured desynchronization */
unsigned rate; /**< Current stream sample rate */
};
@@ -181,7 +182,8 @@ static void stream_reset_sync(pa_stream *s, audio_output_t *aout)
aout_sys_t *sys = aout->sys;
const unsigned rate = aout->format.i_rate;
- sys->pts = VLC_TS_INVALID;
+ sys->first_pts = VLC_TS_INVALID;
+ sys->last_pts = VLC_TS_INVALID;
sys->desync = 0;
pa_operation *op = pa_stream_update_sample_rate(s, rate, NULL, NULL);
if (unlikely(op == NULL))
@@ -190,7 +192,7 @@ static void stream_reset_sync(pa_stream *s, audio_output_t *aout)
sys->rate = rate;
}
-static void stream_start(pa_stream *s, audio_output_t *aout)
+static void stream_start_now(pa_stream *s, audio_output_t *aout)
{
aout_sys_t *sys = aout->sys;
pa_operation *op;
@@ -231,7 +233,7 @@ static void stream_trigger_cb(pa_mainloop_api *api, pa_time_event *e,
msg_Dbg(aout, "starting deferred");
vlc_pa_rttime_free(sys->mainloop, sys->trigger);
sys->trigger = NULL;
- stream_start(sys->stream, aout);
+ stream_start_now(sys->stream, aout);
(void) api; (void) e; (void) tv;
}
@@ -241,12 +243,12 @@ static void stream_trigger_cb(pa_mainloop_api *api, pa_time_event *e,
* in order to minimize desync and resampling during early playback.
* @note PulseAudio lock required.
*/
-static void stream_resync(audio_output_t *aout, pa_stream *s)
+static void stream_start(pa_stream *s, audio_output_t *aout)
{
aout_sys_t *sys = aout->sys;
mtime_t delta;
- assert (sys->pts != VLC_TS_INVALID);
+ assert (sys->first_pts != VLC_TS_INVALID);
if (sys->trigger != NULL) {
vlc_pa_rttime_free(sys->mainloop, sys->trigger);
@@ -259,7 +261,7 @@ static void stream_resync(audio_output_t *aout, pa_stream *s)
delta = 0; /* screwed */
}
- delta = (sys->pts - mdate()) - delta;
+ delta = (sys->first_pts - mdate()) - delta;
if (delta > 0) {
msg_Dbg(aout, "deferring start (%"PRId64" us)", delta);
delta += pa_rtclock_now();
@@ -267,7 +269,7 @@ static void stream_resync(audio_output_t *aout, pa_stream *s)
stream_trigger_cb, aout);
} else {
msg_Warn(aout, "starting late (%"PRId64" us)", delta);
- stream_start(s, aout);
+ stream_start_now(s, aout);
}
}
@@ -279,12 +281,13 @@ static void stream_latency_cb(pa_stream *s, void *userdata)
if (sys->paused != VLC_TS_INVALID)
return; /* nothing to do while paused */
- if (sys->pts == VLC_TS_INVALID) {
- msg_Dbg(aout, "missing latency from input");
+ if (sys->last_pts == VLC_TS_INVALID) {
+ msg_Dbg(aout, "nothing to play");
+ assert (sys->first_pts == VLC_TS_INVALID);
return;
}
if (pa_stream_is_corked(s) > 0) {
- stream_resync(aout, s);
+ stream_start(s, aout);
return;
}
@@ -293,7 +296,7 @@ static void stream_latency_cb(pa_stream *s, void *userdata)
if (delta == VLC_TS_INVALID)
return;
- delta = (sys->pts - mdate()) - delta;
+ delta = (sys->last_pts - mdate()) - delta;
change = delta - sys->desync;
sys->desync = delta;
//msg_Dbg(aout, "desync: %+"PRId64" us (variation: %+"PRId64" us)",
@@ -542,9 +545,12 @@ static void Play(audio_output_t *aout, block_t *block, mtime_t *restrict drift)
* will take place, and sooner or later a deadlock. */
pa_threaded_mainloop_lock(sys->mainloop);
- sys->pts = pts;
+ if (sys->first_pts == VLC_TS_INVALID)
+ sys->first_pts = block->i_pts;
+ sys->last_pts = pts;
+
if (pa_stream_is_corked(s) > 0)
- stream_resync(aout, s);
+ stream_start(s, aout);
#if 0 /* Fault injector to test underrun recovery */
static volatile unsigned u = 0;
@@ -581,8 +587,12 @@ static void Pause(audio_output_t *aout, bool paused, mtime_t date)
date -= sys->paused;
msg_Dbg(aout, "resuming after %"PRId64" us", date);
sys->paused = VLC_TS_INVALID;
- sys->pts += date;
- stream_resync(aout, s);
+
+ if (sys->last_pts != VLC_TS_INVALID) {
+ sys->first_pts += date;
+ sys->last_pts += date;
+ stream_start(s, aout);
+ }
}
pa_threaded_mainloop_unlock(sys->mainloop);
@@ -855,8 +865,9 @@ static int Open(vlc_object_t *obj)
sys->stream = NULL;
sys->context = ctx;
sys->trigger = NULL;
+ sys->first_pts = VLC_TS_INVALID;
+ sys->last_pts = VLC_TS_INVALID;
sys->paused = VLC_TS_INVALID;
- sys->pts = VLC_TS_INVALID;
sys->desync = 0;
sys->rate = ss.rate;
More information about the vlc-commits
mailing list