static gboolean test_async_full_slave_callback (GstClock * master, GstClockTime time, GstClockID id, GstClock * clock) { GstClockTime stime, mtime; gdouble r_squared; /* notify the test case that we started */ GST_INFO ("callback started"); g_mutex_lock (&af_lock); g_cond_signal (&af_cond); /* wait for the test case to unref "clock" and signal */ GST_INFO ("waiting for test case to signal"); g_cond_wait (&af_cond, &af_lock); stime = gst_clock_get_internal_time (clock); mtime = gst_clock_get_time (master); gst_clock_add_observation (clock, stime, mtime, &r_squared); g_cond_signal (&af_cond); g_mutex_unlock (&af_lock); GST_INFO ("callback finished"); return TRUE; }
/* will be called repeatedly to sample the master and slave clock * to recalibrate the clock */ static gboolean gst_clock_slave_callback (GstClock * master, GstClockTime time, GstClockID id, GstClock * clock) { GstClockTime stime, mtime; gdouble r_squared; stime = gst_clock_get_internal_time (clock); mtime = gst_clock_get_time (master); GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "master %" GST_TIME_FORMAT ", slave %" GST_TIME_FORMAT, GST_TIME_ARGS (mtime), GST_TIME_ARGS (stime)); gst_clock_add_observation (clock, stime, mtime, &r_squared); /* FIXME, we can use the r_squared value to adjust the timeout * value of the clockid */ return TRUE; }
static void gst_net_client_clock_observe_times (GstNetClientClock * self, GstClockTime local_1, GstClockTime remote, GstClockTime local_2) { GstClockTime current_timeout; GstClockTime local_avg; gdouble r_squared; GstClock *clock; if (local_2 < local_1) goto bogus_observation; local_avg = (local_2 + local_1) / 2; clock = GST_CLOCK_CAST (self); 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, 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; return; bogus_observation: { GST_WARNING_OBJECT (self, "time packet receive time < send time (%" GST_TIME_FORMAT " < %" GST_TIME_FORMAT ")", GST_TIME_ARGS (local_1), GST_TIME_ARGS (local_2)); return; } }
static void gst_net_client_clock_observe_times (GstNetClientClock * self, GstClockTime local_1, GstClockTime remote, GstClockTime local_2) { GstClockTime local_avg; gdouble r_squared; GstClock *clock; if (local_2 < local_1) goto bogus_observation; local_avg = (local_2 + local_1) / 2; 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) { self->current_timeout = 0; } else { /* geto formula */ self->current_timeout = (1e-3 / (1 - MIN (r_squared, 0.99999))) * GST_SECOND; self->current_timeout = MIN (self->current_timeout, clock->timeout); } GST_CLOCK_SLAVE_UNLOCK (clock); return; bogus_observation: { GST_WARNING_OBJECT (self, "time packet receive time < send time (%" GST_TIME_FORMAT " < %" GST_TIME_FORMAT ")", GST_TIME_ARGS (local_1), GST_TIME_ARGS (local_2)); return; } }