+
+
+/**
+ * gst_clock_wait_for_sync:
+ * @clock: a GstClock
+ * @timeout: timeout for waiting or %GST_CLOCK_TIME_NONE
+ *
+ * Waits until @clock is synced for reporting the current time. If @timeout
+ * is %GST_CLOCK_TIME_NONE it will wait forever, otherwise it will time out
+ * after @timeout nanoseconds.
+ *
+ * For asynchronous waiting, the GstClock::synced signal can be used.
+ *
+ * This returns immediately with TRUE if GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC
+ * is not set on the clock, or if the clock is already synced.
+ *
+ * Returns: %TRUE if waiting was successful, or %FALSE on timeout
+ *
+ * Since: 1.6
+ */
+gboolean
+gst_clock_wait_for_sync (GstClock * clock, GstClockTime timeout)
+{
+ gboolean timed_out = FALSE;
+
+ g_return_val_if_fail (GST_IS_CLOCK (clock), FALSE);
+
+ GST_OBJECT_LOCK (clock);
+ if (!GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC)
+ || clock->priv->synced) {
+ GST_OBJECT_UNLOCK (clock);
+ return TRUE;
+ }
+
+ if (timeout != GST_CLOCK_TIME_NONE) {
+ gint64 end_time = g_get_monotonic_time () + gst_util_uint64_scale (timeout,
+ G_TIME_SPAN_SECOND, GST_SECOND);
+
+ while (!clock->priv->synced && !timed_out) {
+ timed_out =
+ !g_cond_wait_until (&clock->priv->sync_cond,
+ GST_OBJECT_GET_LOCK (clock), end_time);
+ }
+ } else {
+ timed_out = FALSE;
+ while (!clock->priv->synced) {
+ g_cond_wait (&clock->priv->sync_cond, GST_OBJECT_GET_LOCK (clock));
+ }
+ }
+ GST_OBJECT_UNLOCK (clock);
+
+ return !timed_out;
+}
+
+/**
+ * gst_clock_is_synced:
+ * @clock: a GstClock
+ *
+ * Checks if the clock is currently synced.
+ *
+ * This returns if GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC is not set on the clock.
+ *
+ * Returns: %TRUE if the clock is currently synced
+ *
+ * Since: 1.6
+ */
+gboolean
+gst_clock_is_synced (GstClock * clock)
+{
+ g_return_val_if_fail (GST_IS_CLOCK (clock), TRUE);
+
+ return !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC)
+ || clock->priv->synced;
+}
+
+/**
+ * gst_clock_set_synced:
+ * @clock: a GstClock
+ * @synced: if the clock is synced
+ *
+ * Sets @clock to synced and emits the GstClock::synced signal, and wakes up any
+ * thread waiting in gst_clock_wait_for_sync().
+ *
+ * This function must only be called if GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC
+ * is set on the clock, and is intended to be called by subclasses only.
+ *
+ * Since: 1.6
+ */
+void
+gst_clock_set_synced (GstClock * clock, gboolean synced)
+{
+ g_return_if_fail (GST_IS_CLOCK (clock));
+ g_return_if_fail (GST_OBJECT_FLAG_IS_SET (clock,
+ GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC));
+
+ GST_OBJECT_LOCK (clock);
+ if (clock->priv->synced != ! !synced) {
+ clock->priv->synced = ! !synced;
+ g_cond_signal (&clock->priv->sync_cond);
+ GST_OBJECT_UNLOCK (clock);
+ g_signal_emit (clock, gst_clock_signals[SIGNAL_SYNCED], 0, ! !synced);
+ } else {
+ GST_OBJECT_UNLOCK (clock);
+ }
+}