mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 09:40:37 +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_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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue