mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-13 02:45:35 +00:00
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
This commit is contained in:
parent
d6a6dbd34b
commit
60154fca6e
3 changed files with 26 additions and 11 deletions
2
common
2
common
|
@ -1 +1 @@
|
||||||
Subproject commit 50879a63c4fa8f2544d4d89a9dbfa0f5720c3266
|
Subproject commit 0ce4bbf0bc51c08694a8a1e0bec7624094b043d6
|
|
@ -243,9 +243,9 @@ enum
|
||||||
ARG_PERIODCOUNT,
|
ARG_PERIODCOUNT,
|
||||||
ARG_PERIODSIZE,
|
ARG_PERIODSIZE,
|
||||||
ARG_BUFFERSIZE,
|
ARG_BUFFERSIZE,
|
||||||
ARG_DEBUG,
|
|
||||||
ARG_AUTORECOVER,
|
ARG_AUTORECOVER,
|
||||||
ARG_MMAP
|
ARG_MMAP,
|
||||||
|
ARG_MAXDISCONT
|
||||||
};
|
};
|
||||||
|
|
||||||
static GstElement *parent_class = NULL;
|
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_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)",
|
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));
|
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->change_state = gst_alsa_change_state;
|
||||||
element_class->request_new_pad = gst_alsa_request_new_pad;
|
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:
|
case ARG_MMAP:
|
||||||
this->mmap = g_value_get_boolean (value);
|
this->mmap = g_value_get_boolean (value);
|
||||||
return;
|
return;
|
||||||
|
case ARG_MAXDISCONT:
|
||||||
|
this->max_discont = (GstClockTime) g_value_get_uint64 (value);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
return;
|
return;
|
||||||
|
@ -420,6 +426,9 @@ gst_alsa_get_property (GObject *object, guint prop_id, GValue *value,
|
||||||
case ARG_MMAP:
|
case ARG_MMAP:
|
||||||
g_value_set_boolean (value, this->mmap);
|
g_value_set_boolean (value, this->mmap);
|
||||||
break;
|
break;
|
||||||
|
case ARG_MAXDISCONT:
|
||||||
|
g_value_set_uint64 (value, (guint64) this->max_discont);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
|
@ -1189,8 +1198,8 @@ sink_restart:
|
||||||
samplestamp = gst_alsa_timestamp_to_samples (this, GST_BUFFER_TIMESTAMP (pad->buf));
|
samplestamp = gst_alsa_timestamp_to_samples (this, GST_BUFFER_TIMESTAMP (pad->buf));
|
||||||
if (!GST_BUFFER_TIMESTAMP_IS_VALID (pad->buf) ||
|
if (!GST_BUFFER_TIMESTAMP_IS_VALID (pad->buf) ||
|
||||||
/* difference between them is < GST_ALSA_DEVIATION */
|
/* difference between them is < GST_ALSA_DEVIATION */
|
||||||
((this->transmitted + GST_ALSA_DEVIATION > samplestamp) &&
|
((this->transmitted + gst_alsa_timestamp_to_samples (this, this->max_discont) >= samplestamp) &&
|
||||||
(this->transmitted < GST_ALSA_DEVIATION + samplestamp))) {
|
(this->transmitted <= gst_alsa_timestamp_to_samples (this, this->max_discont) + samplestamp))) {
|
||||||
no_difference:
|
no_difference:
|
||||||
pad->size = pad->buf->size;
|
pad->size = pad->buf->size;
|
||||||
pad->data = pad->buf->data;
|
pad->data = pad->buf->data;
|
||||||
|
@ -1200,7 +1209,7 @@ no_difference:
|
||||||
int samples = MIN (bytes, samplestamp - this->transmitted) *
|
int samples = MIN (bytes, samplestamp - this->transmitted) *
|
||||||
(element->numpads == 1 ? this->format->channels : 1);
|
(element->numpads == 1 ? this->format->channels : 1);
|
||||||
int size = samples * snd_pcm_format_physical_width (this->format->format) / 8;
|
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);
|
pad->data = g_malloc (size);
|
||||||
if (!pad->data) {
|
if (!pad->data) {
|
||||||
g_warning ("GstAlsa: error allocating %d bytes, buffers unsynced now.", size);
|
g_warning ("GstAlsa: error allocating %d bytes, buffers unsynced now.", size);
|
||||||
|
@ -1212,12 +1221,14 @@ no_difference:
|
||||||
}
|
}
|
||||||
pad->behaviour = 1;
|
pad->behaviour = 1;
|
||||||
} else if (gst_alsa_samples_to_bytes (this, this->transmitted - samplestamp) >= pad->buf->size) {
|
} 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 */
|
/* this buffer is way behind */
|
||||||
gst_buffer_unref (pad->buf);
|
gst_buffer_unref (pad->buf);
|
||||||
pad->buf = NULL;
|
pad->buf = NULL;
|
||||||
continue;
|
continue;
|
||||||
} else if (this->transmitted > samplestamp) {
|
} else if (this->transmitted > samplestamp) {
|
||||||
gint difference = gst_alsa_samples_to_bytes (this, 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 */
|
/* this buffer is only a bit behind */
|
||||||
pad->size = pad->buf->size - difference;
|
pad->size = pad->buf->size - difference;
|
||||||
pad->data = pad->buf->data + difference;
|
pad->data = pad->buf->data + difference;
|
||||||
|
@ -1808,7 +1819,7 @@ gst_alsa_clock_wait (GstClock *clock, GstClockEntry *entry)
|
||||||
GstClockTimeDiff diff;
|
GstClockTimeDiff diff;
|
||||||
GstAlsaClock *this = GST_ALSA_CLOCK (clock);
|
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);
|
diff = GST_CLOCK_ENTRY_TIME (entry) - gst_clock_get_time (clock);
|
||||||
|
|
||||||
if (diff < 0)
|
if (diff < 0)
|
||||||
|
@ -1827,7 +1838,7 @@ gst_alsa_clock_wait (GstClock *clock, GstClockEntry *entry)
|
||||||
" now %" G_GUINT64_FORMAT,
|
" now %" G_GUINT64_FORMAT,
|
||||||
target, GST_CLOCK_ENTRY_TIME (entry), entry_time);
|
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);
|
g_usleep (gst_alsa_clock_get_resolution (clock) * G_USEC_PER_SEC / GST_SECOND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,10 @@
|
||||||
#define GST_ALSA_MAX_CHANNELS 64 /* we don't support more than 64 channels */
|
#define GST_ALSA_MAX_CHANNELS 64 /* we don't support more than 64 channels */
|
||||||
#define GST_ALSA_MIN_RATE 8000
|
#define GST_ALSA_MIN_RATE 8000
|
||||||
#define GST_ALSA_MAX_RATE 192000
|
#define GST_ALSA_MAX_RATE 192000
|
||||||
/* max allowed deviation between timestamp and playback pointer before killing/inserting samples
|
/* max allowed discontinuity in time units between timestamp and playback pointer
|
||||||
should be >= 1 to allow rounding errors on timestamp <=> samplerate conversions */
|
before killing/inserting samples
|
||||||
#define GST_ALSA_DEVIATION 2
|
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(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)
|
#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
|
We will event insert silent samples or
|
||||||
drop some to sync to incoming timestamps.
|
drop some to sync to incoming timestamps.
|
||||||
*/
|
*/
|
||||||
|
GstClockTime max_discont; /* max difference between current
|
||||||
|
playback timestamp and buffers timestamps
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
struct _GstAlsaClass {
|
struct _GstAlsaClass {
|
||||||
GstElementClass parent_class;
|
GstElementClass parent_class;
|
||||||
|
|
Loading…
Reference in a new issue