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");
  }
}
Exemple #4
0
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;
}
Exemple #5
0
/**
 * 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", &timestamp) &&
          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", &timestamp)) {
        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;
}
Exemple #8
0
/*
 * 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;
}
Exemple #9
0
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", &timestamp)
			&& 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", &timestamp))
		{
			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;
}