From 60154fca6e44916a8224e857580288c16b90030b Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 13 Apr 2003 14:21:02 +0000 Subject: [PATCH] fix timestamp syncing timestamps are only guessed so add a (big) threshold before starting to drop/insert fix some cl... Original commit message from CVS: fix timestamp syncing timestamps are only guessed so add a (big) threshold before starting to drop/insert fix some clocking madness --- common | 2 +- ext/alsa/gstalsa.c | 25 ++++++++++++++++++------- ext/alsa/gstalsa.h | 10 +++++++--- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/common b/common index 50879a6..0ce4bbf 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 50879a63c4fa8f2544d4d89a9dbfa0f5720c3266 +Subproject commit 0ce4bbf0bc51c08694a8a1e0bec7624094b043d6 diff --git a/ext/alsa/gstalsa.c b/ext/alsa/gstalsa.c index aa252d5..54aba29 100644 --- a/ext/alsa/gstalsa.c +++ b/ext/alsa/gstalsa.c @@ -243,9 +243,9 @@ enum ARG_PERIODCOUNT, ARG_PERIODSIZE, ARG_BUFFERSIZE, - ARG_DEBUG, ARG_AUTORECOVER, - ARG_MMAP + ARG_MMAP, + ARG_MAXDISCONT }; static GstElement *parent_class = NULL; @@ -284,6 +284,9 @@ gst_alsa_class_init (GstAlsaClass *klass) g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MMAP, g_param_spec_boolean ("mmap", "Use mmap'ed access", "Wether to use mmap (faster) or standard read/write (more compatible)", TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAXDISCONT, + g_param_spec_uint64 ("max-discont", "Maximum Discontinuity", "GStreamer timeunits before the timestamp syncing starts dropping/insertting samples", + /* rounding errors */ 1000, GST_SECOND, GST_ALSA_DEFAULT_DISCONT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); element_class->change_state = gst_alsa_change_state; element_class->request_new_pad = gst_alsa_request_new_pad; @@ -379,6 +382,9 @@ gst_alsa_set_property (GObject *object, guint prop_id, const GValue *value, case ARG_MMAP: this->mmap = g_value_get_boolean (value); return; + case ARG_MAXDISCONT: + this->max_discont = (GstClockTime) g_value_get_uint64 (value); + return; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); return; @@ -420,6 +426,9 @@ gst_alsa_get_property (GObject *object, guint prop_id, GValue *value, case ARG_MMAP: g_value_set_boolean (value, this->mmap); break; + case ARG_MAXDISCONT: + g_value_set_uint64 (value, (guint64) this->max_discont); + return; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1189,8 +1198,8 @@ sink_restart: samplestamp = gst_alsa_timestamp_to_samples (this, GST_BUFFER_TIMESTAMP (pad->buf)); if (!GST_BUFFER_TIMESTAMP_IS_VALID (pad->buf) || /* difference between them is < GST_ALSA_DEVIATION */ - ((this->transmitted + GST_ALSA_DEVIATION > samplestamp) && - (this->transmitted < GST_ALSA_DEVIATION + samplestamp))) { + ((this->transmitted + gst_alsa_timestamp_to_samples (this, this->max_discont) >= samplestamp) && + (this->transmitted <= gst_alsa_timestamp_to_samples (this, this->max_discont) + samplestamp))) { no_difference: pad->size = pad->buf->size; pad->data = pad->buf->data; @@ -1200,7 +1209,7 @@ no_difference: int samples = MIN (bytes, samplestamp - this->transmitted) * (element->numpads == 1 ? this->format->channels : 1); int size = samples * snd_pcm_format_physical_width (this->format->format) / 8; - g_print ("Allocating %d bytes (%d silent samples) now to resync to timestamp\n", size, samples); + g_print ("Allocating %d bytes (%ld silent samples) now to resync to timestamp\n", size, MIN (bytes, samplestamp - this->transmitted)); pad->data = g_malloc (size); if (!pad->data) { g_warning ("GstAlsa: error allocating %d bytes, buffers unsynced now.", size); @@ -1212,12 +1221,14 @@ no_difference: } pad->behaviour = 1; } else if (gst_alsa_samples_to_bytes (this, this->transmitted - samplestamp) >= pad->buf->size) { + g_print ("Skipping %lu samples to resync (complete buffer)\n", gst_alsa_bytes_to_samples (this, pad->buf->size)); /* this buffer is way behind */ gst_buffer_unref (pad->buf); pad->buf = NULL; continue; } else if (this->transmitted > samplestamp) { gint difference = gst_alsa_samples_to_bytes (this, this->transmitted - samplestamp); + g_print ("Skipping %lu samples to resync\n", (gulong) this->transmitted - samplestamp); /* this buffer is only a bit behind */ pad->size = pad->buf->size - difference; pad->data = pad->buf->data + difference; @@ -1808,7 +1819,7 @@ gst_alsa_clock_wait (GstClock *clock, GstClockEntry *entry) GstClockTimeDiff diff; GstAlsaClock *this = GST_ALSA_CLOCK (clock); - entry_time = this->get_time (this->owner); + entry_time = gst_alsa_clock_get_internal_time (clock); diff = GST_CLOCK_ENTRY_TIME (entry) - gst_clock_get_time (clock); if (diff < 0) @@ -1827,7 +1838,7 @@ gst_alsa_clock_wait (GstClock *clock, GstClockEntry *entry) " now %" G_GUINT64_FORMAT, target, GST_CLOCK_ENTRY_TIME (entry), entry_time); - while (this->get_time (this->owner) < target && this->last_unlock < entry_time) { + while (gst_alsa_clock_get_internal_time (clock) < target && this->last_unlock < entry_time) { g_usleep (gst_alsa_clock_get_resolution (clock) * G_USEC_PER_SEC / GST_SECOND); } diff --git a/ext/alsa/gstalsa.h b/ext/alsa/gstalsa.h index 1b9f0b3..98b7296 100644 --- a/ext/alsa/gstalsa.h +++ b/ext/alsa/gstalsa.h @@ -31,9 +31,10 @@ #define GST_ALSA_MAX_CHANNELS 64 /* we don't support more than 64 channels */ #define GST_ALSA_MIN_RATE 8000 #define GST_ALSA_MAX_RATE 192000 -/* max allowed deviation between timestamp and playback pointer before killing/inserting samples - should be >= 1 to allow rounding errors on timestamp <=> samplerate conversions */ -#define GST_ALSA_DEVIATION 2 +/* max allowed discontinuity in time units between timestamp and playback pointer + before killing/inserting samples + should be big enough to allow smoothing errors on different video formats */ +#define GST_ALSA_DEFAULT_DISCONT (GST_SECOND / 10) #define GST_ALSA(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, GST_TYPE_ALSA, GstAlsa) #define GST_ALSA_CLASS(klass) G_TYPE_CHECK_CLASS_CAST(klass, GST_TYPE_ALSA, GstAlsaClass) @@ -139,6 +140,9 @@ struct _GstAlsa { We will event insert silent samples or drop some to sync to incoming timestamps. */ + GstClockTime max_discont; /* max difference between current + playback timestamp and buffers timestamps + */ }; struct _GstAlsaClass { GstElementClass parent_class; -- 2.7.4