static GstClockReturn _wait (GstClock * clock, GstClockEntry * entry, GstClockTimeDiff * jitter) { GstCpuThrottlingClock *self = GST_CPU_THROTTLING_CLOCK (clock); if (!self->priv->evaluate_wait_time) { if (!(self->priv->sclock)) { GST_ERROR_OBJECT (clock, "Could not find any system clock" " to start the wait time evaluation task"); } else { self->priv->evaluate_wait_time = gst_clock_new_periodic_id (self->priv->sclock, gst_clock_get_time (self->priv->sclock), self->priv->time_between_evals); gst_clock_id_wait_async (self->priv->evaluate_wait_time, (GstClockCallback) gst_transcoder_adjust_wait_time, (gpointer) self, NULL); } } if (G_UNLIKELY (GST_CLOCK_ENTRY_STATUS (entry) == GST_CLOCK_UNSCHEDULED)) return GST_CLOCK_UNSCHEDULED; if (gst_poll_wait (self->priv->timer, self->priv->current_wait_time)) { GST_INFO_OBJECT (self, "Something happened on the poll"); } return GST_CLOCK_ENTRY_STATUS (entry); }
/** * gst_clock_set_master: * @clock: a #GstClock * @master: (allow-none): a master #GstClock * * Set @master as the master clock for @clock. @clock will be automatically * calibrated so that gst_clock_get_time() reports the same time as the * master clock. * * A clock provider that slaves its clock to a master can get the current * calibration values with gst_clock_get_calibration(). * * @master can be %NULL in which case @clock will not be slaved anymore. It will * however keep reporting its time adjusted with the last configured rate * and time offsets. * * Returns: %TRUE if the clock is capable of being slaved to a master clock. * Trying to set a master on a clock without the * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE. * * MT safe. */ 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); GST_OBJECT_LOCK (clock); /* we always allow setting the master to NULL */ if (master && !GST_OBJECT_FLAG_IS_SET (clock, GST_CLOCK_FLAG_CAN_SET_MASTER)) goto not_supported; GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "slaving %p to master clock %p", clock, master); GST_OBJECT_UNLOCK (clock); priv = clock->priv; GST_CLOCK_SLAVE_LOCK (clock); if (priv->clockid) { gst_clock_id_unschedule (priv->clockid); gst_clock_id_unref (priv->clockid); priv->clockid = NULL; } if (master) { priv->filling = TRUE; priv->time_index = 0; /* use the master periodic id to schedule sampling and * clock calibration. */ priv->clockid = gst_clock_new_periodic_id (master, gst_clock_get_time (master), priv->timeout); gst_clock_id_wait_async (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 = &priv->master; gst_object_replace ((GstObject **) master_p, (GstObject *) master); GST_OBJECT_UNLOCK (clock); return TRUE; /* ERRORS */ not_supported: { GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "cannot be slaved to a master clock"); GST_OBJECT_UNLOCK (clock); return FALSE; } }
static void gst_dtls_connection_check_timeout_locked (GstDtlsConnection * self) { GstDtlsConnectionPrivate *priv; struct timeval timeout; gint64 end_time, wait_time; g_return_if_fail (GST_IS_DTLS_CONNECTION (self)); priv = self->priv; if (DTLSv1_get_timeout (priv->ssl, &timeout)) { wait_time = timeout.tv_sec * G_USEC_PER_SEC + timeout.tv_usec; GST_DEBUG_OBJECT (self, "waiting for %" G_GINT64_FORMAT " usec", wait_time); if (wait_time) { GstClock *system_clock = gst_system_clock_obtain (); GstClockID clock_id; #ifndef G_DISABLE_ASSERT GstClockReturn clock_return; #endif end_time = gst_clock_get_time (system_clock) + wait_time * GST_USECOND; clock_id = gst_clock_new_single_shot_id (system_clock, end_time); #ifndef G_DISABLE_ASSERT clock_return = #else (void) #endif gst_clock_id_wait_async (clock_id, schedule_timeout_handling, g_object_ref (self), (GDestroyNotify) g_object_unref); g_assert (clock_return == GST_CLOCK_OK); gst_clock_id_unref (clock_id); gst_object_unref (system_clock); } else { if (self->priv->is_alive && !self->priv->timeout_pending) { self->priv->timeout_pending = TRUE; GST_TRACE_OBJECT (self, "Schedule timeout now"); g_thread_pool_push (self->priv->thread_pool, GINT_TO_POINTER (0xc0ffee), NULL); } } } else { GST_DEBUG_OBJECT (self, "no timeout set"); } }
static gboolean gstreamill_monitor (GstClock *clock, GstClockTime time, GstClockID id, gpointer user_data) { GstClockID nextid; GstClockReturn ret; GstClockTime now; Gstreamill *gstreamill; GSList *list; gstreamill = (Gstreamill *)user_data; g_mutex_lock (&(gstreamill->job_list_mutex)); /* remove stoped job from job list */ clean_job_list (gstreamill); /* stop? */ if (gstreamill->stop && g_slist_length (gstreamill->job_list) == 0) { GST_ERROR ("streamill stopped"); exit (0); } /* check job stat */ if (!gstreamill->stop) { list = gstreamill->job_list; g_slist_foreach (list, job_check_func, gstreamill); } /* log rotate. */ if (gstreamill->daemon) { log_rotate (gstreamill); dvr_clean (gstreamill); } g_mutex_unlock (&(gstreamill->job_list_mutex)); /* register streamill monitor */ now = gst_clock_get_time (gstreamill->system_clock); nextid = gst_clock_new_single_shot_id (gstreamill->system_clock, now + 2000 * GST_MSECOND); ret = gst_clock_id_wait_async (nextid, gstreamill_monitor, gstreamill, NULL); gst_clock_id_unref (nextid); if (ret != GST_CLOCK_OK) { GST_WARNING ("Register gstreamill monitor failure"); return FALSE; } return TRUE; }
/** * gstreamill_start: * @gstreamill: (in): gstreamill to be starting * * start gstreamill * * Returns: 0 on success. */ gint gstreamill_start (Gstreamill *gstreamill) { GstClockID id; GstClockTime t; GstClockReturn ret; /* regist gstreamill monitor */ t = gst_clock_get_time (gstreamill->system_clock) + 5000 * GST_MSECOND; id = gst_clock_new_single_shot_id (gstreamill->system_clock, t); ret = gst_clock_id_wait_async (id, gstreamill_monitor, gstreamill, NULL); gst_clock_id_unref (id); if (ret != GST_CLOCK_OK) { GST_WARNING ("Regist gstreamill monitor failure"); return 1; } return 0; }
static void gst_net_client_clock_finalize (GObject * object) { GstNetClientClock *self = GST_NET_CLIENT_CLOCK (object); GList *l; if (self->priv->synced_id) g_signal_handler_disconnect (self->priv->internal_clock, self->priv->synced_id); self->priv->synced_id = 0; G_LOCK (clocks_lock); for (l = clocks; l; l = l->next) { ClockCache *cache = l->data; if (cache->clock == self->priv->internal_clock) { cache->clocks = g_list_remove (cache->clocks, self); if (cache->clocks) { update_clock_cache (cache); } else { GstClock *sysclock = gst_system_clock_obtain (); GstClockTime time = gst_clock_get_time (sysclock) + 60 * GST_SECOND; cache->remove_id = gst_clock_new_single_shot_id (sysclock, time); gst_clock_id_wait_async (cache->remove_id, remove_clock_cache, cache, NULL); gst_object_unref (sysclock); } break; } } G_UNLOCK (clocks_lock); g_free (self->priv->address); self->priv->address = NULL; if (self->priv->bus != NULL) { gst_object_unref (self->priv->bus); self->priv->bus = NULL; } G_OBJECT_CLASS (gst_net_client_clock_parent_class)->finalize (object); }
/* receive spectral data from element message */ static gboolean message_handler (GstBus * bus, GstMessage * message, gpointer data) { if (message->type == GST_MESSAGE_ELEMENT) { const GstStructure *s = gst_message_get_structure (message); const gchar *name = gst_structure_get_name (s); if (strcmp (name, "spectrum") == 0) { GstElement *spectrum = GST_ELEMENT (GST_MESSAGE_SRC (message)); GstClockTime timestamp, duration; GstClockTime waittime = GST_CLOCK_TIME_NONE; if (gst_structure_get_clock_time (s, "running-time", ×tamp) && gst_structure_get_clock_time (s, "duration", &duration)) { /* wait for middle of buffer */ waittime = timestamp + duration / 2; } else if (gst_structure_get_clock_time (s, "endtime", ×tamp)) { waittime = timestamp; } if (GST_CLOCK_TIME_IS_VALID (waittime)) { GstClockID clock_id; GstClockTime basetime = gst_element_get_base_time (spectrum); gfloat *spect = g_new (gfloat, spect_bands); const GValue *list; const GValue *value; guint i; list = gst_structure_get_value (s, "magnitude"); for (i = 0; i < spect_bands; ++i) { value = gst_value_list_get_value (list, i); spect[i] = height_scale * g_value_get_float (value); } clock_id = gst_clock_new_single_shot_id (sync_clock, waittime + basetime); gst_clock_id_wait_async (clock_id, delayed_spectrum_update, (gpointer) spect); gst_clock_id_unref (clock_id); } } } return TRUE; }
/* * Method: wait_async { |clock, time, clock_entry| ... } * * Registers a block code, which will be called passing references * to the Gst::Clock, the time (in nanoseconds) and the Gst::ClockEntry as * parameters. * * Returns: a return code (see Gst::Clock::Return). */ static VALUE rg_wait_async (VALUE self) { GstClockID id = (GstClockID) RGST_CLOCK_ENTRY (self); if (__callback_get (id) != NULL) rb_raise (rb_eRuntimeError, "An asynch callback is already registred to this entry."); else { struct __callback *e = g_malloc (sizeof (struct __callback)); g_assert (e != NULL); e->id = id; e->callback = rb_block_proc (); __callbacks = g_slist_append (__callbacks, e); return GENUM2RVAL (INT2FIX (gst_clock_id_wait_async (id, __callback_dispatcher, NULL)), GST_TYPE_CLOCK_RETURN); } return Qnil; }
static void gst_imx_v4l2src_af_check_status(GstImxV4l2VideoSrc *v4l2src) { int status; gboolean send_message; GstPhotographyFocusStatus message_status; gboolean schedule_recheck; if (v4l2_g_ctrl(v4l2src, V4L2_CID_AUTO_FOCUS_STATUS, &status) < 0) goto none; switch (status) { case V4L2_AUTO_FOCUS_STATUS_IDLE: default: none: send_message = TRUE; message_status = GST_PHOTOGRAPHY_FOCUS_STATUS_NONE; schedule_recheck = FALSE; break; case V4L2_AUTO_FOCUS_STATUS_BUSY: send_message = FALSE; schedule_recheck = TRUE; break; case V4L2_AUTO_FOCUS_STATUS_REACHED: send_message = TRUE; message_status = GST_PHOTOGRAPHY_FOCUS_STATUS_SUCCESS; schedule_recheck = FALSE; break; case V4L2_AUTO_FOCUS_STATUS_FAILED: send_message = TRUE; message_status = GST_PHOTOGRAPHY_FOCUS_STATUS_FAIL; schedule_recheck = FALSE; break; } if (send_message) { GstStructure *s; GstMessage *m; s = gst_structure_new(GST_PHOTOGRAPHY_AUTOFOCUS_DONE, "status", G_TYPE_INT, message_status, NULL); m = gst_message_new_custom(GST_MESSAGE_ELEMENT, GST_OBJECT(v4l2src), s); if (!gst_element_post_message(GST_ELEMENT(v4l2src), m)) GST_ERROR_OBJECT(v4l2src, "failed to post message"); } if (schedule_recheck) { GstClock *c; GstClockTime t; c = gst_system_clock_obtain(); t = gst_clock_get_time(c) + 50 * GST_MSECOND; v4l2src->af_clock_id = gst_clock_new_single_shot_id(c, t); gst_object_unref(c); if (gst_clock_id_wait_async(v4l2src->af_clock_id, gst_imx_v4l2src_af_status_cb, v4l2src, NULL) != GST_CLOCK_OK) GST_ERROR_OBJECT(v4l2src, "failed to schedule recheck"); } }
static GstFlowReturn _chain (GstPad * pad, GstObject * object, GstBuffer * buffer) { GstBuffer *actual_buf = buffer; GstAggregator *self = GST_AGGREGATOR (object); GstAggregatorPrivate *priv = self->priv; GstAggregatorPad *aggpad = GST_AGGREGATOR_PAD (pad); GstAggregatorClass *aggclass = GST_AGGREGATOR_GET_CLASS (object); GstClockTime timeout = gst_aggregator_get_timeout (self); GstClockTime now; GST_DEBUG_OBJECT (aggpad, "Start chaining a buffer %" GST_PTR_FORMAT, buffer); if (aggpad->priv->timeout_id) { gst_clock_id_unschedule (aggpad->priv->timeout_id); gst_clock_id_unref (aggpad->priv->timeout_id); aggpad->priv->timeout_id = NULL; } g_atomic_int_set (&aggpad->unresponsive, FALSE); PAD_STREAM_LOCK (aggpad); if (g_atomic_int_get (&aggpad->priv->flushing) == TRUE) goto flushing; if (g_atomic_int_get (&aggpad->priv->pending_eos) == TRUE) goto eos; PAD_LOCK_EVENT (aggpad); if (aggpad->buffer) { GST_DEBUG_OBJECT (aggpad, "Waiting for buffer to be consumed"); PAD_WAIT_EVENT (aggpad); } PAD_UNLOCK_EVENT (aggpad); if (g_atomic_int_get (&aggpad->priv->flushing) == TRUE) goto flushing; if (aggclass->clip) { aggclass->clip (self, aggpad, buffer, &actual_buf); } PAD_LOCK_EVENT (aggpad); if (aggpad->buffer) gst_buffer_unref (aggpad->buffer); aggpad->buffer = actual_buf; PAD_UNLOCK_EVENT (aggpad); PAD_STREAM_UNLOCK (aggpad); QUEUE_PUSH (self); if (GST_CLOCK_TIME_IS_VALID (timeout)) { now = gst_clock_get_time (self->clock); aggpad->priv->timeout_id = gst_clock_new_single_shot_id (self->clock, now + timeout); gst_clock_id_wait_async (aggpad->priv->timeout_id, _unresponsive_timeout, gst_object_ref (aggpad), gst_object_unref); } GST_DEBUG_OBJECT (aggpad, "Done chaining"); return priv->flow_return; flushing: PAD_STREAM_UNLOCK (aggpad); gst_buffer_unref (buffer); GST_DEBUG_OBJECT (aggpad, "We are flushing"); return GST_FLOW_FLUSHING; eos: PAD_STREAM_UNLOCK (aggpad); gst_buffer_unref (buffer); GST_DEBUG_OBJECT (pad, "We are EOS already..."); return GST_FLOW_EOS; }
// get spectrum messages and delay them static gboolean on_message(GstBus *bus, GstMessage *message, gpointer data) { base *base_object = data; GstElement *spectrum = GST_ELEMENT(base_object->spectrum_element->obj); gst_object_ref(spectrum); GstElement *message_element = GST_ELEMENT(GST_MESSAGE_SRC(message)); gst_object_ref(message_element); if (message_element == spectrum) { GstClockTime waittime = GST_CLOCK_TIME_NONE; const GstStructure *message_structure = gst_message_get_structure(message); // determine waittime GstClockTime timestamp, duration; if ( gst_structure_get_clock_time(message_structure, "running-time", ×tamp) && gst_structure_get_clock_time(message_structure, "duration", &duration) ) { /* wait for middle of buffer */ waittime = timestamp + duration/2; } else if (gst_structure_get_clock_time(message_structure, "endtime", ×tamp)) { waittime = timestamp; } // delay message if (GST_CLOCK_TIME_IS_VALID(waittime)) { GstClockTime basetime = gst_element_get_base_time(spectrum); GstClockID clock_id = gst_clock_new_single_shot_id(base_object->sync_clock, basetime+waittime); spectrum_message *mess = g_malloc(sizeof(spectrum_message)); // set bands and threshold g_object_get(message_element, "bands", &(mess->bands), "threshold", &(mess->threshold), NULL); // set start and duration GstClockTime streamtime, duration; gst_structure_get_clock_time(message_structure, "stream-time", &streamtime); gst_structure_get_clock_time(message_structure, "duration", &duration); mess->start = (gfloat)streamtime / GST_SECOND; mess->duration = (gfloat)duration / GST_SECOND; // set rate GstPad *sink = gst_element_get_static_pad(GST_ELEMENT(base_object->spectrum_element->obj), "sink"); GstCaps *caps = gst_pad_get_negotiated_caps(sink); gst_object_unref(sink); GstStructure *caps_structure = gst_caps_get_structure(caps, 0); gst_structure_get_int(caps_structure, "rate", &(mess->rate)); gst_caps_unref(caps); // set magnitudes const GValue *list = gst_structure_get_value(message_structure, "magnitude"); PyGILState_STATE gstate = PyGILState_Ensure(); int i; mess->magnitudes = PyList_New(mess->bands); for (i=0; i < (mess->bands); i++) { const GValue *value = gst_value_list_get_value(list, i); gfloat f = g_value_get_float(value); PyList_SetItem(mess->magnitudes, i, Py_BuildValue("f", f)); } PyGILState_Release(gstate); // set gobj GObject *gobj = (base_object->gobj).obj; g_assert(gobj != NULL); g_object_ref(gobj); mess->gobj = gobj; // delay message gst_clock_id_wait_async(clock_id, delayed_spectrum_update, mess); gst_clock_id_unref(clock_id); } } gst_object_unref(spectrum); gst_object_unref(message_element); return TRUE; }