From f3ae89426aa0e15802295dc38c1736aa62820f86 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 24 Jul 2006 15:14:17 +0000 Subject: [PATCH] gst-libs/gst/audio/gstbaseaudiosink.c: When the audio clock is slaved to another clock, never try to align samples bu... Original commit message from CVS: * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_provide_clock), (gst_base_audio_sink_render): When the audio clock is slaved to another clock, never try to align samples but trust the rate interpolation algorithm. --- ChangeLog | 7 +++ gst-libs/gst/audio/gstbaseaudiosink.c | 61 +++++++++++++++------------ 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3ff5f168ce..411ce18ba0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-07-24 Wim Taymans + + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_provide_clock), (gst_base_audio_sink_render): + When the audio clock is slaved to another clock, never try to align + samples but trust the rate interpolation algorithm. + 2006-07-24 Wim Taymans * ext/alsa/gstalsasink.c: (set_hwparams), (gst_alsasink_prepare): diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index c0c1411aa8..48406d1d3d 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -200,6 +200,7 @@ gst_base_audio_sink_provide_clock (GstElement * elem) return clock; + /* ERRORS */ wrong_state: { GST_DEBUG_OBJECT (sink, "ringbuffer not acquired"); @@ -490,11 +491,6 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf) sink = GST_BASE_AUDIO_SINK (bsink); - if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) { - /* always resync after a discont */ - sink->next_sample = -1; - } - ringbuf = sink->ringbuffer; /* can't do anything when we don't have the device */ @@ -581,30 +577,43 @@ gst_base_audio_sink_render (GstBaseSink * bsink, GstBuffer * buf) ", render offset %llu, samples %lu", GST_TIME_ARGS (render_time), render_offset, samples); - /* roundoff errors in timestamp conversion */ - if (G_LIKELY (sink->next_sample != -1)) { - diff = ABS ((gint64) render_offset - (gint64) sink->next_sample); - /* we tollerate half a second diff before we start resyncing. This - * should be enough to compensate for various rounding errors in the timestamp - * and sample offset position. We always resync if we got a discont anyway and - * non-discont should be aligned by definition. */ - if (diff < ringbuf->spec.rate / DIFF_TOLERANCE) { - GST_DEBUG_OBJECT (sink, - "align with prev sample, %" G_GINT64_FORMAT " < %lu", diff, - ringbuf->spec.rate / DIFF_TOLERANCE); - /* just align with previous sample then */ - render_offset = sink->next_sample; - } else { - /* timestamps drifted apart from previous samples too much, we need to - * resync. */ - GST_WARNING_OBJECT (sink, - "resync after discont with previous sample of diff: %lu", diff); - } - } else { - GST_DEBUG_OBJECT (sink, "resync after discont"); + /* never try to align samples when we are slaved to another clock, just + * trust the rate control algorithm to align the two clocks. We don't take + * the LOCK to read the clock because it does not really matter here and the + * clock is not changed while playing normally. */ + if (GST_ELEMENT_CLOCK (sink) != sink->provided_clock) { + GST_DEBUG_OBJECT (sink, "no align needed: we are slaved"); + goto no_align; } + /* always resync after a discont */ + if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DISCONT))) { + GST_DEBUG_OBJECT (sink, "resync after discont"); + goto no_align; + } + + /* now try to align the sample to the previous one */ + diff = ABS ((gint64) render_offset - (gint64) sink->next_sample); + + /* we tollerate half a second diff before we start resyncing. This + * should be enough to compensate for various rounding errors in the timestamp + * and sample offset position. We always resync if we got a discont anyway and + * non-discont should be aligned by definition. */ + if (diff < ringbuf->spec.rate / DIFF_TOLERANCE) { + GST_DEBUG_OBJECT (sink, + "align with prev sample, %" G_GINT64_FORMAT " < %lu", diff, + ringbuf->spec.rate / DIFF_TOLERANCE); + /* just align with previous sample then */ + render_offset = sink->next_sample; + } else { + /* timestamps drifted apart from previous samples too much, we need to + * resync. We log this as an element warning. */ + GST_ELEMENT_WARNING (sink, CORE, CLOCK, (NULL), + ("Unexpected discontinuity in audio timestamps of more than half a second")); + } + +no_align: crate = gst_guint64_to_gdouble (crate_num) / gst_guint64_to_gdouble (crate_denom); GST_DEBUG_OBJECT (sink,