+2006-04-28 Wim Taymans <wim@fluendo.com>
+
+ * gst-libs/gst/audio/gstbaseaudiosink.c:
+ (gst_base_audio_sink_drain), (gst_base_audio_sink_event),
+ (gst_base_audio_sink_render), (gst_base_audio_sink_change_state):
+ patch to make timestamp checking more tollerant to rounding
+ errors given that real discontinuities are to be marked on
+ buffers. Fixes some asf files and #338778.
+ Also avoid some crashers when we receive an event in the
+ NULL state.
+
2006-04-28 Michael Smith <msmith@fluendo.com>
* ext/gnomevfs/gstgnomevfssrc.c: (gst_gnome_vfs_src_class_init),
LAST_SIGNAL
};
-/* we tollerate a 10th of a second diff before we start resyncing. This
+/* 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. */
-#define DIFF_TOLERANCE 10
+ * and sample offset position.
+ * This is an emergency resync fallback since buffers marked as DISCONT will
+ * always lock to the correct timestamp immediatly and buffers not marked as
+ * DISCONT are contiguous bu definition.
+ */
+#define DIFF_TOLERANCE 2
#define DEFAULT_BUFFER_TIME 200 * GST_USECOND
#define DEFAULT_LATENCY_TIME 10 * GST_USECOND
if (!sink->ringbuffer->spec.rate)
return TRUE;
+ /* need to start playback before we can drain, but only when
+ * we have successfully negotiated a format and thus aqcuired the
+ * ringbuffer. */
+ if (gst_ring_buffer_is_acquired (sink->ringbuffer))
+ gst_ring_buffer_start (sink->ringbuffer);
+
if (sink->next_sample != -1) {
GstClockTime time;
GstClock *clock;
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH_START:
- gst_ring_buffer_set_flushing (sink->ringbuffer, TRUE);
+ if (sink->ringbuffer)
+ gst_ring_buffer_set_flushing (sink->ringbuffer, TRUE);
break;
case GST_EVENT_FLUSH_STOP:
/* always resync on sample after a flush */
sink->next_sample = -1;
- gst_ring_buffer_set_flushing (sink->ringbuffer, FALSE);
+ if (sink->ringbuffer)
+ gst_ring_buffer_set_flushing (sink->ringbuffer, FALSE);
break;
case GST_EVENT_EOS:
- /* need to start playback when we reach EOS, but only when
- * we have successfully negotiated a format. */
- if (gst_ring_buffer_is_acquired (sink->ringbuffer))
- gst_ring_buffer_start (sink->ringbuffer);
/* now wait till we played everything */
gst_base_audio_sink_drain (sink);
break;
if (G_LIKELY (sink->next_sample != -1)) {
diff = ABS ((gint64) render_offset - (gint64) sink->next_sample);
- /* we tollerate a 10th of a second diff before we start resyncing. This
+ /* 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 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,
/* just align with previous sample then */
render_offset = sink->next_sample;
} else {
- GST_DEBUG_OBJECT (sink,
+ /* 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_OBJECT_UNLOCK (sink);
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
+ /* make sure we unblock before calling the parent state change
+ * so it can grab the STREAM_LOCK */
gst_ring_buffer_set_flushing (sink->ringbuffer, TRUE);
break;
default:
return ret;
+ /* ERRORS */
open_failed:
{
+ /* subclass must post a meaningfull error message */
GST_DEBUG_OBJECT (sink, "open failed");
return GST_STATE_CHANGE_FAILURE;
}