From eb84682e923431f41223bf754527ed27b0deccb9 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 27 Feb 2012 09:02:07 +0100 Subject: [PATCH] clock: make more stuff private Expose methods to get and set the timeout because subclasses uses this. --- gst/gstclock.c | 227 ++++++++++++++++++++----------- gst/gstclock.h | 66 +-------- gst/gstsystemclock.c | 98 +++++++------ libs/gst/net/gstnetclientclock.c | 29 ++-- tests/check/gst/gstsystemclock.c | 2 +- win32/common/libgstreamer.def | 2 + 6 files changed, 224 insertions(+), 200 deletions(-) diff --git a/gst/gstclock.c b/gst/gstclock.c index 180fe6aa61..6cbfe1f04f 100644 --- a/gst/gstclock.c +++ b/gst/gstclock.c @@ -131,8 +131,35 @@ enum PROP_TIMEOUT }; +#define GST_CLOCK_SLAVE_LOCK(clock) g_mutex_lock (&GST_CLOCK_CAST (clock)->priv->slave_lock) +#define GST_CLOCK_SLAVE_UNLOCK(clock) g_mutex_unlock (&GST_CLOCK_CAST (clock)->priv->slave_lock) + struct _GstClockPrivate { + GMutex slave_lock; /* order: SLAVE_LOCK, OBJECT_LOCK */ + + /* with LOCK */ + GstClockTime internal_calibration; + GstClockTime external_calibration; + GstClockTime rate_numerator; + GstClockTime rate_denominator; + GstClockTime last_time; + + /* with LOCK */ + GstClockTime resolution; + + /* for master/slave clocks */ + GstClock *master; + + /* with SLAVE_LOCK */ + gboolean filling; + gint window_size; + gint window_threshold; + gint time_index; + GstClockTime timeout; + GstClockTime *times; + GstClockID clockid; + gint pre_count; gint post_count; }; @@ -679,25 +706,25 @@ gst_clock_class_init (GstClockClass * klass) static void gst_clock_init (GstClock * clock) { - clock->last_time = 0; - clock->entries = NULL; - g_cond_init (&clock->entries_changed); + GstClockPrivate *priv; - clock->priv = + clock->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (clock, GST_TYPE_CLOCK, GstClockPrivate); - clock->internal_calibration = 0; - clock->external_calibration = 0; - clock->rate_numerator = 1; - clock->rate_denominator = 1; + priv->last_time = 0; - g_mutex_init (&clock->slave_lock); - clock->window_size = DEFAULT_WINDOW_SIZE; - clock->window_threshold = DEFAULT_WINDOW_THRESHOLD; - clock->filling = TRUE; - clock->time_index = 0; - clock->timeout = DEFAULT_TIMEOUT; - clock->times = g_new0 (GstClockTime, 4 * clock->window_size); + priv->internal_calibration = 0; + priv->external_calibration = 0; + priv->rate_numerator = 1; + priv->rate_denominator = 1; + + g_mutex_init (&priv->slave_lock); + priv->window_size = DEFAULT_WINDOW_SIZE; + priv->window_threshold = DEFAULT_WINDOW_THRESHOLD; + priv->filling = TRUE; + priv->time_index = 0; + priv->timeout = DEFAULT_TIMEOUT; + priv->times = g_new0 (GstClockTime, 4 * priv->window_size); } static void @@ -707,7 +734,7 @@ gst_clock_dispose (GObject * object) GstClock **master_p; GST_OBJECT_LOCK (clock); - master_p = &clock->master; + master_p = &clock->priv->master; gst_object_replace ((GstObject **) master_p, NULL); GST_OBJECT_UNLOCK (clock); @@ -720,17 +747,16 @@ gst_clock_finalize (GObject * object) GstClock *clock = GST_CLOCK (object); GST_CLOCK_SLAVE_LOCK (clock); - if (clock->clockid) { - gst_clock_id_unschedule (clock->clockid); - gst_clock_id_unref (clock->clockid); - clock->clockid = NULL; + if (clock->priv->clockid) { + gst_clock_id_unschedule (clock->priv->clockid); + gst_clock_id_unref (clock->priv->clockid); + clock->priv->clockid = NULL; } - g_free (clock->times); - clock->times = NULL; + g_free (clock->priv->times); + clock->priv->times = NULL; GST_CLOCK_SLAVE_UNLOCK (clock); - g_cond_clear (&clock->entries_changed); - g_mutex_clear (&clock->slave_lock); + g_mutex_clear (&clock->priv->slave_lock); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -751,18 +777,20 @@ gst_clock_finalize (GObject * object) GstClockTime gst_clock_set_resolution (GstClock * clock, GstClockTime resolution) { + GstClockPrivate *priv; GstClockClass *cclass; g_return_val_if_fail (GST_IS_CLOCK (clock), 0); g_return_val_if_fail (resolution != 0, 0); cclass = GST_CLOCK_GET_CLASS (clock); + priv = clock->priv; if (cclass->change_resolution) - clock->resolution = - cclass->change_resolution (clock, clock->resolution, resolution); + priv->resolution = + cclass->change_resolution (clock, priv->resolution, resolution); - return clock->resolution; + return priv->resolution; } /** @@ -809,12 +837,13 @@ GstClockTime gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal) { GstClockTime ret, cinternal, cexternal, cnum, cdenom; + GstClockPrivate *priv = clock->priv; /* get calibration values for readability */ - cinternal = clock->internal_calibration; - cexternal = clock->external_calibration; - cnum = clock->rate_numerator; - cdenom = clock->rate_denominator; + cinternal = priv->internal_calibration; + cexternal = priv->external_calibration; + cnum = priv->rate_numerator; + cdenom = priv->rate_denominator; /* avoid divide by 0 */ if (G_UNLIKELY (cdenom == 0)) @@ -841,9 +870,9 @@ gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal) } /* make sure the time is increasing */ - clock->last_time = MAX (ret, clock->last_time); + priv->last_time = MAX (ret, priv->last_time); - return clock->last_time; + return priv->last_time; } /** @@ -866,12 +895,13 @@ GstClockTime gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external) { GstClockTime ret, cinternal, cexternal, cnum, cdenom; + GstClockPrivate *priv = clock->priv; /* get calibration values for readability */ - cinternal = clock->internal_calibration; - cexternal = clock->external_calibration; - cnum = clock->rate_numerator; - cdenom = clock->rate_denominator; + cinternal = priv->internal_calibration; + cexternal = priv->external_calibration; + cnum = priv->rate_numerator; + cdenom = priv->rate_denominator; /* avoid divide by 0 */ if (G_UNLIKELY (cnum == 0)) @@ -1008,10 +1038,14 @@ void gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime external, GstClockTime rate_num, GstClockTime rate_denom) { + GstClockPrivate *priv; + g_return_if_fail (GST_IS_CLOCK (clock)); g_return_if_fail (rate_num != GST_CLOCK_TIME_NONE); g_return_if_fail (rate_denom > 0 && rate_denom != GST_CLOCK_TIME_NONE); + priv = clock->priv; + write_seqlock (clock); GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %" @@ -1019,10 +1053,10 @@ gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime GST_TIME_ARGS (external), rate_num, rate_denom, gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom)); - clock->internal_calibration = internal; - clock->external_calibration = external; - clock->rate_numerator = rate_num; - clock->rate_denominator = rate_denom; + priv->internal_calibration = internal; + priv->external_calibration = external; + priv->rate_numerator = rate_num; + priv->rate_denominator = rate_denom; write_sequnlock (clock); } @@ -1047,19 +1081,22 @@ gst_clock_get_calibration (GstClock * clock, GstClockTime * internal, GstClockTime * external, GstClockTime * rate_num, GstClockTime * rate_denom) { gint seq; + GstClockPrivate *priv; g_return_if_fail (GST_IS_CLOCK (clock)); + priv = clock->priv; + do { seq = read_seqbegin (clock); if (rate_num) - *rate_num = clock->rate_numerator; + *rate_num = priv->rate_numerator; if (rate_denom) - *rate_denom = clock->rate_denominator; + *rate_denom = priv->rate_denominator; if (external) - *external = clock->external_calibration; + *external = priv->external_calibration; if (internal) - *internal = clock->internal_calibration; + *internal = priv->internal_calibration; } while (read_seqretry (clock, seq)); } @@ -1113,6 +1150,7 @@ gboolean gst_clock_set_master (GstClock * clock, GstClock * master) { GstClock **master_p; + GstClockPrivate *priv; g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE); g_return_val_if_fail (master != clock, FALSE); @@ -1125,27 +1163,29 @@ gst_clock_set_master (GstClock * clock, GstClock * master) "slaving %p to master clock %p", clock, master); GST_OBJECT_UNLOCK (clock); + priv = clock->priv; + GST_CLOCK_SLAVE_LOCK (clock); - if (clock->clockid) { - gst_clock_id_unschedule (clock->clockid); - gst_clock_id_unref (clock->clockid); - clock->clockid = NULL; + if (priv->clockid) { + gst_clock_id_unschedule (priv->clockid); + gst_clock_id_unref (priv->clockid); + priv->clockid = NULL; } if (master) { - clock->filling = TRUE; - clock->time_index = 0; + priv->filling = TRUE; + priv->time_index = 0; /* use the master periodic id to schedule sampling and * clock calibration. */ - clock->clockid = gst_clock_new_periodic_id (master, - gst_clock_get_time (master), clock->timeout); - gst_clock_id_wait_async_full (clock->clockid, + priv->clockid = gst_clock_new_periodic_id (master, + gst_clock_get_time (master), priv->timeout); + gst_clock_id_wait_async_full (priv->clockid, (GstClockCallback) gst_clock_slave_callback, gst_object_ref (clock), (GDestroyNotify) gst_object_unref); } GST_CLOCK_SLAVE_UNLOCK (clock); GST_OBJECT_LOCK (clock); - master_p = &clock->master; + master_p = &priv->master; gst_object_replace ((GstObject **) master_p, (GstObject *) master); GST_OBJECT_UNLOCK (clock); @@ -1177,12 +1217,15 @@ GstClock * gst_clock_get_master (GstClock * clock) { GstClock *result = NULL; + GstClockPrivate *priv; g_return_val_if_fail (GST_IS_CLOCK (clock), NULL); + priv = clock->priv; + GST_OBJECT_LOCK (clock); - if (clock->master) - result = gst_object_ref (clock->master); + if (priv->master) + result = gst_object_ref (priv->master); GST_OBJECT_UNLOCK (clock); return result; @@ -1202,12 +1245,15 @@ do_linear_regression (GstClock * clock, GstClockTime * m_num, GstClockTime *x, *y; gint i, j; guint n; + GstClockPrivate *priv; xbar = ybar = sxx = syy = sxy = 0; - x = clock->times; - y = clock->times + 2; - n = clock->filling ? clock->time_index : clock->window_size; + priv = clock->priv; + + x = priv->times; + y = priv->times + 2; + n = priv->filling ? priv->time_index : priv->window_size; #ifdef DEBUGGING_ENABLED GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "doing regression on:"); @@ -1229,8 +1275,8 @@ do_linear_regression (GstClock * clock, GstClockTime * m_num, ymin); #endif - newx = clock->times + 1; - newy = clock->times + 3; + newx = priv->times + 1; + newy = priv->times + 3; /* strip off unnecessary bits of precision */ for (i = j = 0; i < n; i++, j += 4) { @@ -1339,27 +1385,29 @@ gst_clock_add_observation (GstClock * clock, GstClockTime slave, GstClockTime master, gdouble * r_squared) { GstClockTime m_num, m_denom, b, xbase; + GstClockPrivate *priv; g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE); g_return_val_if_fail (r_squared != NULL, FALSE); + priv = clock->priv; + GST_CLOCK_SLAVE_LOCK (clock); GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, clock, "adding observation slave %" GST_TIME_FORMAT ", master %" GST_TIME_FORMAT, GST_TIME_ARGS (slave), GST_TIME_ARGS (master)); - clock->times[(4 * clock->time_index)] = slave; - clock->times[(4 * clock->time_index) + 2] = master; + priv->times[(4 * priv->time_index)] = slave; + priv->times[(4 * priv->time_index) + 2] = master; - clock->time_index++; - if (G_UNLIKELY (clock->time_index == clock->window_size)) { - clock->filling = FALSE; - clock->time_index = 0; + priv->time_index++; + if (G_UNLIKELY (priv->time_index == priv->window_size)) { + priv->filling = FALSE; + priv->time_index = 0; } - if (G_UNLIKELY (clock->filling - && clock->time_index < clock->window_threshold)) + if (G_UNLIKELY (priv->filling && priv->time_index < priv->window_threshold)) goto filling; if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared)) @@ -1389,36 +1437,47 @@ invalid: } } +void +gst_clock_set_timeout (GstClock * clock, GstClockTime timeout) +{ + clock->priv->timeout = timeout; +} + +GstClockTime +gst_clock_get_timeout (GstClock * clock) +{ + return clock->priv->timeout; +} + static void gst_clock_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) { GstClock *clock; + GstClockPrivate *priv; clock = GST_CLOCK (object); + priv = clock->priv; switch (prop_id) { case PROP_WINDOW_SIZE: GST_CLOCK_SLAVE_LOCK (clock); - clock->window_size = g_value_get_int (value); - clock->window_threshold = - MIN (clock->window_threshold, clock->window_size); - clock->times = - g_renew (GstClockTime, clock->times, 4 * clock->window_size); + priv->window_size = g_value_get_int (value); + priv->window_threshold = MIN (priv->window_threshold, priv->window_size); + priv->times = g_renew (GstClockTime, priv->times, 4 * priv->window_size); /* restart calibration */ - clock->filling = TRUE; - clock->time_index = 0; + priv->filling = TRUE; + priv->time_index = 0; GST_CLOCK_SLAVE_UNLOCK (clock); break; case PROP_WINDOW_THRESHOLD: GST_CLOCK_SLAVE_LOCK (clock); - clock->window_threshold = - MIN (g_value_get_int (value), clock->window_size); + priv->window_threshold = MIN (g_value_get_int (value), priv->window_size); GST_CLOCK_SLAVE_UNLOCK (clock); break; case PROP_TIMEOUT: GST_CLOCK_SLAVE_LOCK (clock); - clock->timeout = g_value_get_uint64 (value); + priv->timeout = g_value_get_uint64 (value); GST_CLOCK_SLAVE_UNLOCK (clock); break; default: @@ -1432,23 +1491,25 @@ gst_clock_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec) { GstClock *clock; + GstClockPrivate *priv; clock = GST_CLOCK (object); + priv = clock->priv; switch (prop_id) { case PROP_WINDOW_SIZE: GST_CLOCK_SLAVE_LOCK (clock); - g_value_set_int (value, clock->window_size); + g_value_set_int (value, priv->window_size); GST_CLOCK_SLAVE_UNLOCK (clock); break; case PROP_WINDOW_THRESHOLD: GST_CLOCK_SLAVE_LOCK (clock); - g_value_set_int (value, clock->window_threshold); + g_value_set_int (value, priv->window_threshold); GST_CLOCK_SLAVE_UNLOCK (clock); break; case PROP_TIMEOUT: GST_CLOCK_SLAVE_LOCK (clock); - g_value_set_uint64 (value, clock->timeout); + g_value_set_uint64 (value, priv->timeout); GST_CLOCK_SLAVE_UNLOCK (clock); break; default: diff --git a/gst/gstclock.h b/gst/gstclock.h index e0b3afcf20..253fc09eea 100644 --- a/gst/gstclock.h +++ b/gst/gstclock.h @@ -35,9 +35,6 @@ G_BEGIN_DECLS #define GST_CLOCK_GET_CLASS(clock) (G_TYPE_INSTANCE_GET_CLASS ((clock), GST_TYPE_CLOCK, GstClockClass)) #define GST_CLOCK_CAST(clock) ((GstClock*)(clock)) -#define GST_CLOCK_SLAVE_LOCK(clock) g_mutex_lock (&GST_CLOCK_CAST (clock)->slave_lock) -#define GST_CLOCK_SLAVE_UNLOCK(clock) g_mutex_unlock (&GST_CLOCK_CAST (clock)->slave_lock) - /** * GstClockTime: * @@ -401,38 +398,6 @@ typedef enum { */ #define GST_CLOCK_FLAGS(clock) GST_OBJECT_FLAGS(clock) -/** - * GST_CLOCK_GET_COND: - * @clock: the clock to query - * - * Gets the #GCond that gets signalled when the entries of the clock - * changed. - */ -#define GST_CLOCK_GET_COND(clock) (&GST_CLOCK_CAST(clock)->entries_changed) -/** - * GST_CLOCK_WAIT: - * @clock: the clock to wait on - * - * Wait on the clock until the entries changed. - */ -#define GST_CLOCK_WAIT(clock) g_cond_wait(GST_CLOCK_GET_COND(clock),GST_OBJECT_GET_LOCK(clock)) -/** - * GST_CLOCK_TIMED_WAIT: - * @clock: the clock to wait on - * @tv: a #GTimeVal to wait. - * - * Wait on the clock until the entries changed or the specified timeout - * occurred. - */ -#define GST_CLOCK_TIMED_WAIT(clock,tv) g_cond_timed_wait(GST_CLOCK_GET_COND(clock),GST_OBJECT_GET_LOCK(clock),tv) -/** - * GST_CLOCK_BROADCAST: - * @clock: the clock to broadcast - * - * Signal that the entries in the clock have changed. - */ -#define GST_CLOCK_BROADCAST(clock) g_cond_broadcast(GST_CLOCK_GET_COND(clock)) - /** * GstClock: * @@ -442,32 +407,6 @@ typedef enum { struct _GstClock { GstObject object; - GMutex slave_lock; /* order: SLAVE_LOCK, OBJECT_LOCK */ - - /*< protected >*/ /* with LOCK */ - GstClockTime internal_calibration; - GstClockTime external_calibration; - GstClockTime rate_numerator; - GstClockTime rate_denominator; - GstClockTime last_time; - GList *entries; - GCond entries_changed; - - /*< private >*/ /* with LOCK */ - GstClockTime resolution; - - /* for master/slave clocks */ - GstClock *master; - - /* with SLAVE_LOCK */ - gboolean filling; - gint window_size; - gint window_threshold; - gint time_index; - GstClockTime timeout; - GstClockTime *times; - GstClockID clockid; - /*< private >*/ GstClockPrivate *priv; @@ -531,6 +470,11 @@ void gst_clock_get_calibration (GstClock *clock, GstClo /* master/slave clocks */ gboolean gst_clock_set_master (GstClock *clock, GstClock *master); GstClock* gst_clock_get_master (GstClock *clock); + +void gst_clock_set_timeout (GstClock *clock, + GstClockTime timeout); +GstClockTime gst_clock_get_timeout (GstClock *clock); + gboolean gst_clock_add_observation (GstClock *clock, GstClockTime slave, GstClockTime master, gdouble *r_squared); diff --git a/gst/gstsystemclock.c b/gst/gstsystemclock.c index 26e787b326..7c461c9332 100644 --- a/gst/gstsystemclock.c +++ b/gst/gstsystemclock.c @@ -63,11 +63,18 @@ /* Define this to get some extra debug about jitter from each clock_wait */ #undef WAIT_DEBUGGING +#define GST_SYSTEM_CLOCK_GET_COND(clock) (&GST_SYSTEM_CLOCK_CAST(clock)->priv->entries_changed) +#define GST_SYSTEM_CLOCK_WAIT(clock) g_cond_wait(GST_SYSTEM_CLOCK_GET_COND(clock),GST_OBJECT_GET_LOCK(clock)) +#define GST_SYSTEM_CLOCK_TIMED_WAIT(clock,tv) g_cond_timed_wait(GST_SYSTEM_CLOCK_GET_COND(clock),GST_OBJECT_GET_LOCK(clock),tv) +#define GST_SYSTEM_CLOCK_BROADCAST(clock) g_cond_broadcast(GST_SYSTEM_CLOCK_GET_COND(clock)) + struct _GstSystemClockPrivate { GThread *thread; /* thread for async notify */ gboolean stopping; + GList *entries; + GCond entries_changed; GstClockType clock_type; GstPoll *timer; @@ -163,23 +170,28 @@ gst_system_clock_class_init (GstSystemClockClass * klass) static void gst_system_clock_init (GstSystemClock * clock) { + GstSystemClockPrivate *priv; + GST_OBJECT_FLAG_SET (clock, GST_CLOCK_FLAG_CAN_DO_SINGLE_SYNC | GST_CLOCK_FLAG_CAN_DO_SINGLE_ASYNC | GST_CLOCK_FLAG_CAN_DO_PERIODIC_SYNC | GST_CLOCK_FLAG_CAN_DO_PERIODIC_ASYNC); - clock->priv = GST_SYSTEM_CLOCK_GET_PRIVATE (clock); + clock->priv = priv = GST_SYSTEM_CLOCK_GET_PRIVATE (clock); - clock->priv->clock_type = DEFAULT_CLOCK_TYPE; - clock->priv->timer = gst_poll_new_timer (); + priv->clock_type = DEFAULT_CLOCK_TYPE; + priv->timer = gst_poll_new_timer (); + + priv->entries = NULL; + g_cond_init (&priv->entries_changed); #ifdef G_OS_WIN32 - QueryPerformanceFrequency (&clock->priv->frequency); + QueryPerformanceFrequency (&priv->frequency); /* can be 0 if the hardware does not have hardware support */ - if (clock->priv->frequency.QuadPart != 0) + if (priv->frequency.QuadPart != 0) /* we take a base time so that time starts from 0 to ease debugging */ - QueryPerformanceCounter (&clock->priv->start); + QueryPerformanceCounter (&priv->start); #endif /* G_OS_WIN32 */ #if 0 @@ -195,32 +207,34 @@ gst_system_clock_dispose (GObject * object) { GstClock *clock = (GstClock *) object; GstSystemClock *sysclock = GST_SYSTEM_CLOCK_CAST (clock); + GstSystemClockPrivate *priv = sysclock->priv; GList *entries; /* else we have to stop the thread */ GST_OBJECT_LOCK (clock); - sysclock->priv->stopping = TRUE; + priv->stopping = TRUE; /* unschedule all entries */ - for (entries = clock->entries; entries; entries = g_list_next (entries)) { + for (entries = priv->entries; entries; entries = g_list_next (entries)) { GstClockEntry *entry = (GstClockEntry *) entries->data; GST_CAT_DEBUG (GST_CAT_CLOCK, "unscheduling entry %p", entry); SET_ENTRY_STATUS (entry, GST_CLOCK_UNSCHEDULED); } - GST_CLOCK_BROADCAST (clock); + GST_SYSTEM_CLOCK_BROADCAST (clock); gst_system_clock_add_wakeup (sysclock); GST_OBJECT_UNLOCK (clock); - if (sysclock->priv->thread) - g_thread_join (sysclock->priv->thread); - sysclock->priv->thread = NULL; + if (priv->thread) + g_thread_join (priv->thread); + priv->thread = NULL; GST_CAT_DEBUG (GST_CAT_CLOCK, "joined thread"); - g_list_foreach (clock->entries, (GFunc) gst_clock_id_unref, NULL); - g_list_free (clock->entries); - clock->entries = NULL; + g_list_foreach (priv->entries, (GFunc) gst_clock_id_unref, NULL); + g_list_free (priv->entries); + priv->entries = NULL; - gst_poll_free (sysclock->priv->timer); + gst_poll_free (priv->timer); + g_cond_clear (&priv->entries_changed); G_OBJECT_CLASS (parent_class)->dispose (object); @@ -316,7 +330,7 @@ gst_system_clock_remove_wakeup (GstSystemClock * sysclock) while (!gst_poll_read_control (sysclock->priv->timer)) { g_warning ("gstsystemclock: read control failed, trying again\n"); } - GST_CLOCK_BROADCAST (sysclock); + GST_SYSTEM_CLOCK_BROADCAST (sysclock); } GST_CAT_DEBUG (GST_CAT_CLOCK, "wakeup count %d", sysclock->priv->wakeup_count); @@ -350,7 +364,7 @@ static void gst_system_clock_wait_wakeup (GstSystemClock * sysclock) { while (sysclock->priv->wakeup_count > 0) { - GST_CLOCK_WAIT (sysclock); + GST_SYSTEM_CLOCK_WAIT (sysclock); } } @@ -370,38 +384,39 @@ static void gst_system_clock_async_thread (GstClock * clock) { GstSystemClock *sysclock = GST_SYSTEM_CLOCK_CAST (clock); + GstSystemClockPrivate *priv = sysclock->priv; GST_CAT_DEBUG (GST_CAT_CLOCK, "enter system clock thread"); GST_OBJECT_LOCK (clock); /* signal spinup */ - GST_CLOCK_BROADCAST (clock); + GST_SYSTEM_CLOCK_BROADCAST (clock); /* now enter our (almost) infinite loop */ - while (!sysclock->priv->stopping) { + while (!priv->stopping) { GstClockEntry *entry; GstClockTime requested; GstClockReturn res; /* check if something to be done */ - while (clock->entries == NULL) { + while (priv->entries == NULL) { GST_CAT_DEBUG (GST_CAT_CLOCK, "no clock entries, waiting.."); /* wait for work to do */ - GST_CLOCK_WAIT (clock); + GST_SYSTEM_CLOCK_WAIT (clock); GST_CAT_DEBUG (GST_CAT_CLOCK, "got signal"); /* clock was stopping, exit */ - if (sysclock->priv->stopping) + if (priv->stopping) goto exit; } /* see if we have a pending wakeup because the order of the list * changed. */ - if (sysclock->priv->async_wakeup) { + if (priv->async_wakeup) { GST_CAT_DEBUG (GST_CAT_CLOCK, "clear async wakeup"); gst_system_clock_remove_wakeup (sysclock); - sysclock->priv->async_wakeup = FALSE; + priv->async_wakeup = FALSE; } /* pick the next entry */ - entry = clock->entries->data; + entry = priv->entries->data; GST_OBJECT_UNLOCK (clock); requested = entry->time; @@ -436,8 +451,8 @@ gst_system_clock_async_thread (GstClock * clock) /* adjust time now */ entry->time = requested + entry->interval; /* and resort the list now */ - clock->entries = - g_list_sort (clock->entries, gst_clock_id_compare_func); + priv->entries = + g_list_sort (priv->entries, gst_clock_id_compare_func); /* and restart */ continue; } else { @@ -466,12 +481,12 @@ gst_system_clock_async_thread (GstClock * clock) } next_entry: /* we remove the current entry and unref it */ - clock->entries = g_list_remove (clock->entries, entry); + priv->entries = g_list_remove (priv->entries, entry); gst_clock_id_unref ((GstClockID) entry); } exit: /* signal exit */ - GST_CLOCK_BROADCAST (clock); + GST_SYSTEM_CLOCK_BROADCAST (clock); GST_OBJECT_UNLOCK (clock); GST_CAT_DEBUG (GST_CAT_CLOCK, "exit system clock thread"); } @@ -732,18 +747,19 @@ static gboolean gst_system_clock_start_async (GstSystemClock * clock) { GError *error = NULL; + GstSystemClockPrivate *priv = clock->priv; - if (G_LIKELY (clock->priv->thread != NULL)) + if (G_LIKELY (priv->thread != NULL)) return TRUE; /* Thread already running. Nothing to do */ - clock->priv->thread = g_thread_try_new ("GstSystemClock", + priv->thread = g_thread_try_new ("GstSystemClock", (GThreadFunc) gst_system_clock_async_thread, clock, &error); if (G_UNLIKELY (error)) goto no_thread; /* wait for it to spin up */ - GST_CLOCK_WAIT (clock); + GST_SYSTEM_CLOCK_WAIT (clock); return TRUE; @@ -767,9 +783,11 @@ static GstClockReturn gst_system_clock_id_wait_async (GstClock * clock, GstClockEntry * entry) { GstSystemClock *sysclock; + GstSystemClockPrivate *priv; GstClockEntry *head; sysclock = GST_SYSTEM_CLOCK_CAST (clock); + priv = sysclock->priv; GST_CAT_DEBUG (GST_CAT_CLOCK, "adding async entry %p", entry); @@ -781,27 +799,27 @@ gst_system_clock_id_wait_async (GstClock * clock, GstClockEntry * entry) if (G_UNLIKELY (GET_ENTRY_STATUS (entry) == GST_CLOCK_UNSCHEDULED)) goto was_unscheduled; - if (clock->entries) - head = clock->entries->data; + if (priv->entries) + head = priv->entries->data; else head = NULL; /* need to take a ref */ gst_clock_id_ref ((GstClockID) entry); /* insert the entry in sorted order */ - clock->entries = g_list_insert_sorted (clock->entries, entry, + priv->entries = g_list_insert_sorted (priv->entries, entry, gst_clock_id_compare_func); /* only need to send the signal if the entry was added to the * front, else the thread is just waiting for another entry and * will get to this entry automatically. */ - if (clock->entries->data == entry) { + if (priv->entries->data == entry) { GST_CAT_DEBUG (GST_CAT_CLOCK, "async entry added to head %p", head); if (head == NULL) { /* the list was empty before, signal the cond so that the async thread can * start taking a look at the queue */ GST_CAT_DEBUG (GST_CAT_CLOCK, "first entry, sending signal"); - GST_CLOCK_BROADCAST (clock); + GST_SYSTEM_CLOCK_BROADCAST (clock); } else { GstClockReturn status; @@ -812,9 +830,9 @@ gst_system_clock_id_wait_async (GstClock * clock, GstClockEntry * entry) GST_CAT_DEBUG (GST_CAT_CLOCK, "head entry is busy"); /* the async thread was waiting for an entry, unlock the wait so that it * looks at the new head entry instead, we only need to do this once */ - if (!sysclock->priv->async_wakeup) { + if (!priv->async_wakeup) { GST_CAT_DEBUG (GST_CAT_CLOCK, "wakeup async thread"); - sysclock->priv->async_wakeup = TRUE; + priv->async_wakeup = TRUE; gst_system_clock_add_wakeup (sysclock); } } diff --git a/libs/gst/net/gstnetclientclock.c b/libs/gst/net/gstnetclientclock.c index 59b24a9787..691c414a8a 100644 --- a/libs/gst/net/gstnetclientclock.c +++ b/libs/gst/net/gstnetclientclock.c @@ -128,17 +128,18 @@ static void gst_net_client_clock_init (GstNetClientClock * self) { GstClock *clock = GST_CLOCK_CAST (self); + GstNetClientClockPrivate *priv; - self->priv = GST_NET_CLIENT_CLOCK_GET_PRIVATE (self); + self->priv = priv = GST_NET_CLIENT_CLOCK_GET_PRIVATE (self); - self->priv->port = DEFAULT_PORT; - self->priv->address = g_strdup (DEFAULT_ADDRESS); + priv->port = DEFAULT_PORT; + priv->address = g_strdup (DEFAULT_ADDRESS); - clock->timeout = DEFAULT_TIMEOUT; + gst_clock_set_timeout (clock, DEFAULT_TIMEOUT); - self->priv->thread = NULL; + priv->thread = NULL; - self->priv->servaddr = NULL; + priv->servaddr = NULL; } static void @@ -224,19 +225,17 @@ gst_net_client_clock_observe_times (GstNetClientClock * self, clock = GST_CLOCK_CAST (self); - gst_clock_add_observation (GST_CLOCK (self), local_avg, remote, &r_squared); - - GST_CLOCK_SLAVE_LOCK (self); - if (clock->filling) { - current_timeout = 0; - } else { + if (gst_clock_add_observation (GST_CLOCK (self), local_avg, remote, + &r_squared)) { /* geto formula */ current_timeout = (1e-3 / (1 - MIN (r_squared, 0.99999))) * GST_SECOND; - current_timeout = MIN (current_timeout, clock->timeout); + current_timeout = MIN (current_timeout, gst_clock_get_timeout (clock)); + } else { + current_timeout = 0; } + GST_INFO ("next timeout: %" GST_TIME_FORMAT, GST_TIME_ARGS (current_timeout)); self->priv->timeout_expiration = gst_util_get_timestamp () + current_timeout; - GST_CLOCK_SLAVE_UNLOCK (clock); return; @@ -371,7 +370,7 @@ gst_net_client_clock_thread (gpointer data) /* reset timeout (but are expecting a response sooner anyway) */ self->priv->timeout_expiration = - gst_util_get_timestamp () + clock->timeout; + gst_util_get_timestamp () + gst_clock_get_timeout (clock); continue; } diff --git a/tests/check/gst/gstsystemclock.c b/tests/check/gst/gstsystemclock.c index 2207667fab..5c9304cfe1 100644 --- a/tests/check/gst/gstsystemclock.c +++ b/tests/check/gst/gstsystemclock.c @@ -608,7 +608,7 @@ GST_START_TEST (test_async_full) /* register a periodic shot on the master to calibrate the slave */ g_mutex_lock (af_lock); clockid = gst_clock_new_periodic_id (master, - gst_clock_get_time (master), slave->timeout); + gst_clock_get_time (master), gst_clock_get_timeout (slave)); gst_clock_id_wait_async_full (clockid, (GstClockCallback) test_async_full_slave_callback, gst_object_ref (slave), (GDestroyNotify) gst_object_unref); diff --git a/win32/common/libgstreamer.def b/win32/common/libgstreamer.def index cba1a65aa2..42e0af3d08 100644 --- a/win32/common/libgstreamer.def +++ b/win32/common/libgstreamer.def @@ -227,6 +227,7 @@ EXPORTS gst_clock_get_master gst_clock_get_resolution gst_clock_get_time + gst_clock_get_timeout gst_clock_get_type gst_clock_id_compare_func gst_clock_id_get_time @@ -243,6 +244,7 @@ EXPORTS gst_clock_set_calibration gst_clock_set_master gst_clock_set_resolution + gst_clock_set_timeout gst_clock_single_shot_id_reinit gst_clock_type_get_type gst_clock_unadjust_unlocked