gst-libs/gst/audio/gstbaseaudiosink.c: When the audio clock is slaved to another...
authorWim Taymans <wim.taymans@gmail.com>
Mon, 24 Jul 2006 15:14:17 +0000 (15:14 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 24 Jul 2006 15:14:17 +0000 (15:14 +0000)
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
gst-libs/gst/audio/gstbaseaudiosink.c

index 3ff5f16..411ce18 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
 2006-07-24  Wim Taymans  <wim@fluendo.com>
 
+       * 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  <wim@fluendo.com>
+
        * ext/alsa/gstalsasink.c: (set_hwparams), (gst_alsasink_prepare):
        Don't try to calculate silence samples, base class does this much
        better now.
index c0c1411..48406d1 100644 (file)
@@ -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 {
+
+  /* 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,