From 35e4b75b86228afc7f5280210dd4fc97cfd9db1c Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Tue, 27 May 2008 16:20:17 +0000 Subject: [PATCH] gst-libs/gst/audio/gstaudioclock.*: Add method to inform the clock that the time starts from 0 again. We use this inf... Original commit message from CVS: * gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_init), (gst_audio_clock_reset), (gst_audio_clock_get_internal_time): * gst-libs/gst/audio/gstaudioclock.h: Add method to inform the clock that the time starts from 0 again. We use this info to calculate a clock offset so that the time we report in internal_time is monotonically increasing, as required by the clock base class. Fixes #521761. API: GstAudioClock::gst_audio_clock_reset() * gst-libs/gst/audio/gstbaseaudiosink.c: (gst_base_audio_sink_skew_slaving), (gst_base_audio_sink_change_state): * gst-libs/gst/audio/gstbaseaudiosrc.c: (gst_base_audio_src_create), (gst_base_audio_src_change_state): Reset reported time when we (re)create the ringbuffer. --- ChangeLog | 18 +++++++++++++++++ gst-libs/gst/audio/gstaudioclock.c | 29 ++++++++++++++++++++++++--- gst-libs/gst/audio/gstaudioclock.h | 9 ++++++++- gst-libs/gst/audio/gstbaseaudiosink.c | 1 + gst-libs/gst/audio/gstbaseaudiosrc.c | 1 + 5 files changed, 54 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7be1ad95e5..cc931ed184 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,21 @@ +2008-05-27 Wim Taymans + + * gst-libs/gst/audio/gstaudioclock.c: (gst_audio_clock_init), + (gst_audio_clock_reset), (gst_audio_clock_get_internal_time): + * gst-libs/gst/audio/gstaudioclock.h: + Add method to inform the clock that the time starts from 0 again. We use + this info to calculate a clock offset so that the time we report in + internal_time is monotonically increasing, as required by the clock base + class. Fixes #521761. + API: GstAudioClock::gst_audio_clock_reset() + + * gst-libs/gst/audio/gstbaseaudiosink.c: + (gst_base_audio_sink_skew_slaving), + (gst_base_audio_sink_change_state): + * gst-libs/gst/audio/gstbaseaudiosrc.c: + (gst_base_audio_src_create), (gst_base_audio_src_change_state): + Reset reported time when we (re)create the ringbuffer. + 2008-05-27 Tim-Philipp Müller * ext/alsa/gstalsamixertrack.c: diff --git a/gst-libs/gst/audio/gstaudioclock.c b/gst-libs/gst/audio/gstaudioclock.c index a13b8405b6..557df4b5f5 100644 --- a/gst-libs/gst/audio/gstaudioclock.c +++ b/gst-libs/gst/audio/gstaudioclock.c @@ -94,6 +94,7 @@ static void gst_audio_clock_init (GstAudioClock * clock) { clock->last_time = 0; + clock->abidata.ABI.time_offset = 0; GST_OBJECT_FLAG_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER); } @@ -122,17 +123,39 @@ gst_audio_clock_new (gchar * name, GstAudioClockGetTimeFunc func, return (GstClock *) aclock; } +/** + * gst_audio_clock_reset: + * @clock: a #GstAudioClock + * @time: a #GstClockTime + * + * Inform @clock that future calls to #GstAudioClockGetTimeFunc will return values + * starting from @time. The clock will update an internal offset to make sure that + * future calls to internal_time will return an increasing result as required by + * the #GstClock object. + */ +void +gst_audio_clock_reset (GstAudioClock * clock, GstClockTime time) +{ + if (clock->last_time >= time) + clock->abidata.ABI.time_offset = clock->last_time - time; + else + clock->abidata.ABI.time_offset = -(time - clock->last_time); +} + static GstClockTime gst_audio_clock_get_internal_time (GstClock * clock) { - GstAudioClock *aclock = GST_AUDIO_CLOCK (clock); + GstAudioClock *aclock; GstClockTime result; + aclock = GST_AUDIO_CLOCK (clock); + result = aclock->func (clock, aclock->user_data); if (result == GST_CLOCK_TIME_NONE) result = aclock->last_time; - else + else { + result += aclock->abidata.ABI.time_offset; aclock->last_time = result; - + } return result; } diff --git a/gst-libs/gst/audio/gstaudioclock.h b/gst-libs/gst/audio/gstaudioclock.h index 621f81bbcb..e0f0d524fc 100644 --- a/gst-libs/gst/audio/gstaudioclock.h +++ b/gst-libs/gst/audio/gstaudioclock.h @@ -71,7 +71,13 @@ struct _GstAudioClock { GstClockTime last_time; /*< private >*/ - gpointer _gst_reserved[GST_PADDING]; + union { + struct { + GstClockTimeDiff time_offset; + } ABI; + /* adding + 0 to mark ABI change to be undone later */ + gpointer _gst_reserved[GST_PADDING + 0]; + } abidata; }; struct _GstAudioClockClass { @@ -84,6 +90,7 @@ struct _GstAudioClockClass { GType gst_audio_clock_get_type (void); GstClock* gst_audio_clock_new (gchar *name, GstAudioClockGetTimeFunc func, gpointer user_data); +void gst_audio_clock_reset (GstAudioClock *clock, GstClockTime time); G_END_DECLS diff --git a/gst-libs/gst/audio/gstbaseaudiosink.c b/gst-libs/gst/audio/gstbaseaudiosink.c index 38b6a0cf31..d0776c3260 100644 --- a/gst-libs/gst/audio/gstbaseaudiosink.c +++ b/gst-libs/gst/audio/gstbaseaudiosink.c @@ -1604,6 +1604,7 @@ gst_base_audio_sink_change_state (GstElement * element, switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: if (sink->ringbuffer == NULL) { + gst_audio_clock_reset (GST_AUDIO_CLOCK (sink->provided_clock), 0); sink->ringbuffer = gst_base_audio_sink_create_ringbuffer (sink); } if (!gst_ring_buffer_open_device (sink->ringbuffer)) diff --git a/gst-libs/gst/audio/gstbaseaudiosrc.c b/gst-libs/gst/audio/gstbaseaudiosrc.c index a152739d88..a47cd9383b 100644 --- a/gst-libs/gst/audio/gstbaseaudiosrc.c +++ b/gst-libs/gst/audio/gstbaseaudiosrc.c @@ -870,6 +870,7 @@ gst_base_audio_src_change_state (GstElement * element, case GST_STATE_CHANGE_NULL_TO_READY: GST_DEBUG_OBJECT (src, "NULL->READY"); if (src->ringbuffer == NULL) { + gst_audio_clock_reset (GST_AUDIO_CLOCK (src->clock), 0); src->ringbuffer = gst_base_audio_src_create_ringbuffer (src); } if (!gst_ring_buffer_open_device (src->ringbuffer))