Exemple #1
0
/**
 * gst_clock_get_internal_time
 * @clock: a #GstClock to query
 *
 * Gets the current internal time of the given clock. The time is returned
 * unadjusted for the offset and the rate.
 *
 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
 * given invalid input.
 *
 * MT safe.
 */
GstClockTime
gst_clock_get_internal_time (GstClock * clock)
{
  GstClockTime ret;
  GstClockClass *cclass;

  g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);

  cclass = GST_CLOCK_GET_CLASS (clock);

  if (G_UNLIKELY (cclass->get_internal_time == NULL))
    goto not_supported;

  ret = cclass->get_internal_time (clock);

  GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
      GST_TIME_ARGS (ret));

  return ret;

  /* ERRORS */
not_supported:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
        "internal time not supported, return 0");
    return G_GINT64_CONSTANT (0);
  }
}
static GstClockReturn
gst_test_clock_wait_async (GstClock * clock, GstClockEntry * entry)
{
  GstTestClock *test_clock = GST_TEST_CLOCK (clock);

  GST_OBJECT_LOCK (test_clock);

  if (GST_CLOCK_ENTRY_STATUS (entry) == GST_CLOCK_UNSCHEDULED)
    goto was_unscheduled;

  GST_CAT_DEBUG_OBJECT (GST_CAT_TEST_CLOCK, test_clock,
      "requesting asynchronous clock notification at %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_CLOCK_ENTRY_TIME (entry)));

  gst_test_clock_add_entry (test_clock, entry, NULL);

  GST_OBJECT_UNLOCK (test_clock);

  return GST_CLOCK_OK;

  /* ERRORS */
was_unscheduled:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_TEST_CLOCK, test_clock,
        "entry was unscheduled");
    GST_OBJECT_UNLOCK (test_clock);
    return GST_CLOCK_UNSCHEDULED;
  }
}
Exemple #3
0
EXPORT_C
#endif

GstClockReturn
gst_clock_id_wait_async (GstClockID id,
    GstClockCallback func, gpointer user_data)
{
  GstClockEntry *entry;
  GstClock *clock;
  GstClockReturn res;
  GstClockClass *cclass;
  GstClockTime requested;

  g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
  g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);

  entry = (GstClockEntry *) id;
  requested = GST_CLOCK_ENTRY_TIME (entry);
  clock = GST_CLOCK_ENTRY_CLOCK (entry);

  /* can't sync on invalid times */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
    goto invalid_time;

  /* a previously unscheduled entry cannot be scheduled again */
  if (G_UNLIKELY (entry->status == GST_CLOCK_UNSCHEDULED))
    goto unscheduled;

  cclass = GST_CLOCK_GET_CLASS (clock);

  if (G_UNLIKELY (cclass->wait_async == NULL))
    goto not_supported;

  entry->func = func;
  entry->user_data = user_data;

  res = cclass->wait_async (clock, entry);

  return res;

  /* ERRORS */
invalid_time:
  {
    (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
    GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
        "invalid time requested, returning _BADTIME");
    return GST_CLOCK_BADTIME;
  }
unscheduled:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
        "entry was unscheduled return _UNSCHEDULED");
    return GST_CLOCK_UNSCHEDULED;
  }
not_supported:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
    return GST_CLOCK_UNSUPPORTED;
  }
}
Exemple #4
0
/**
 * gst_object_set_parent:
 * @object: a #GstObject
 * @parent: new parent of object
 *
 * Sets the parent of @object to @parent. The object's reference count will
 * be incremented, and any floating reference will be removed (see gst_object_ref_sink()).
 *
 * Returns: TRUE if @parent could be set or FALSE when @object
 * already had a parent or @object and @parent are the same.
 *
 * MT safe. Grabs and releases @object's LOCK.
 */
gboolean
gst_object_set_parent (GstObject * object, GstObject * parent)
{
  g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
  g_return_val_if_fail (GST_IS_OBJECT (parent), FALSE);
  g_return_val_if_fail (object != parent, FALSE);

  GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
      "set parent (ref and sink)");

  GST_OBJECT_LOCK (object);
  if (G_UNLIKELY (object->parent != NULL))
    goto had_parent;

  object->parent = parent;
  gst_object_ref_sink (object);
  GST_OBJECT_UNLOCK (object);

  /* FIXME, this does not work, the deep notify takes the lock from the parent
   * object and deadlocks when the parent holds its lock when calling this
   * function (like _element_add_pad()) */
  /* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */

  return TRUE;

  /* ERROR handling */
had_parent:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
        "set parent failed, object already had a parent");
    GST_OBJECT_UNLOCK (object);
    return FALSE;
  }
}
Exemple #5
0
/**
 * gst_clock_get_internal_time:
 * @clock: a #GstClock to query
 *
 * Gets the current internal time of the given clock. The time is returned
 * unadjusted for the offset and the rate.
 *
 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when
 * given invalid input.
 *
 * MT safe.
 */
GstClockTime
gst_clock_get_internal_time (GstClock * clock)
{
  GstClockTime ret;
  GstClockClass *cclass;

  g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);

  if (G_UNLIKELY (GST_OBJECT_FLAG_IS_SET (clock,
              GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC) && !clock->priv->synced))
    GST_CAT_WARNING_OBJECT (GST_CAT_CLOCK, clock,
        "clocked is not synchronized yet");

  cclass = GST_CLOCK_GET_CLASS (clock);

  if (G_UNLIKELY (cclass->get_internal_time == NULL))
    goto not_supported;

  ret = cclass->get_internal_time (clock);

  GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
      GST_TIME_ARGS (ret));

  return ret;

  /* ERRORS */
not_supported:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
        "internal time not supported, return 0");
    return G_GINT64_CONSTANT (0);
  }
}
Exemple #6
0
static void
gst_spot_src_init (GstSpotSrc * spot, GstSpotSrcClass * g_class)
{
  GError *err;
  spot->read_position = 0;

  /* its childish to use static global variables */
  ugly_spot = GST_SPOT_SRC (spot);

  GST_SPOT_SRC_URI (spot) = g_strdup (DEFAULT_URI);

  GST_SPOT_SRC_BUFFER_TIME (spot) = BUFFER_TIME_DEFAULT;

  GST_SPOT_SRC_ADAPTER_MUTEX (spot) = g_mutex_new ();
  GST_SPOT_SRC_ADAPTER_COND (spot) = g_cond_new ();
  GST_SPOT_SRC_ADAPTER (spot) = gst_adapter_new ();

  /* initiate format to default format */
  GST_SPOT_SRC_FORMAT (spot) = g_malloc0 (sizeof (sp_audioformat));
  GST_SPOT_SRC_FORMAT (spot)->sample_rate = SPOTIFY_DEFAULT_SAMPLE_RATE;
  GST_SPOT_SRC_FORMAT (spot)->channels = SPOTIFY_DEFAULT_NUMBER_CHANNELS;
  GST_SPOT_SRC_FORMAT (spot)->sample_type = SP_SAMPLETYPE_INT16_NATIVE_ENDIAN;

  /* initiate state varables */
  spot->spot_works = NULL;
  spot->play_token_lost = FALSE;
  spot->end_of_track = FALSE;
  spot->unlock_state = FALSE;

  /* initiate user settings */
  spot->user = g_strdup (DEFAULT_USER);
  spot->pass = g_strdup (DEFAULT_PASS);
  spot->uri = g_strdup (DEFAULT_URI);
  spot->logged_in = FALSE;

  /* intiate worker thread and its state variables */
  spot->keep_spotify_thread = TRUE;
  spot->spotify_thread_initiated = FALSE;
  spot->process_events_mutex = g_mutex_new ();
  spot->process_events_cond = g_cond_new ();
  spot->process_events_thread = g_thread_create ((GThreadFunc)spotify_thread_func, spot, TRUE, &err);

  if (spot->process_events_thread == NULL) {
     GST_CAT_ERROR_OBJECT (gst_spot_src_debug_threads, spot,"G_thread_create failed: %s!", err->message );
     g_error_free (err) ;
  }

  /* make sure spotify thread is up and running, before continuing. */
  GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_threads, spot, "Broadcast process_events_cond");
  g_cond_broadcast (spot->process_events_cond);
  while (!spot->spotify_thread_initiated) {
    /* ugly but hey it yields right. */
    usleep (40);
    GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_threads, spot, "Broadcast process_events_cond, in loop");
    g_cond_broadcast (spot->process_events_cond);
  }
}
/**
 * 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;
  }
}
/**
 * gst_clock_id_wait:
 * @id: The #GstClockID to wait on
 * @jitter: (out) (allow-none): a pointer that will contain the jitter,
 *     can be %NULL.
 *
 * Perform a blocking wait on @id. 
 * @id should have been created with gst_clock_new_single_shot_id()
 * or gst_clock_new_periodic_id() and should not have been unscheduled
 * with a call to gst_clock_id_unschedule(). 
 *
 * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK
 * or #GST_CLOCK_EARLY, it will contain the difference
 * against the clock and the time of @id when this method was
 * called. 
 * Positive values indicate how late @id was relative to the clock
 * (in which case this function will return #GST_CLOCK_EARLY). 
 * Negative values indicate how much time was spent waiting on the clock 
 * before this function returned.
 *
 * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned
 * if the current clock time is past the time of @id, #GST_CLOCK_OK if 
 * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was 
 * unscheduled with gst_clock_id_unschedule().
 *
 * MT safe.
 */
GstClockReturn
gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
{
  GstClockEntry *entry;
  GstClock *clock;
  GstClockReturn res;
  GstClockTime requested;
  GstClockClass *cclass;

  g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);

  entry = (GstClockEntry *) id;
  requested = GST_CLOCK_ENTRY_TIME (entry);

  clock = GST_CLOCK_ENTRY_CLOCK (entry);

  /* can't sync on invalid times */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
    goto invalid_time;

  cclass = GST_CLOCK_GET_CLASS (clock);

  GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);

  /* if we have a wait_jitter function, use that */
  if (G_UNLIKELY (cclass->wait == NULL))
    goto not_supported;

  res = cclass->wait (clock, entry, jitter);

  GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
      "done waiting entry %p, res: %d (%s)", id, res,
      gst_clock_return_get_name (res));

  if (entry->type == GST_CLOCK_ENTRY_PERIODIC)
    entry->time = requested + entry->interval;

  return res;

  /* ERRORS */
invalid_time:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
        "invalid time requested, returning _BADTIME");
    return GST_CLOCK_BADTIME;
  }
not_supported:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
    return GST_CLOCK_UNSUPPORTED;
  }
}
static void
default_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
{
  GST_LOG_OBJECT (pool, "released buffer %p %d", buffer,
      GST_MINI_OBJECT_FLAGS (buffer));

  /* memory should be untouched */
  if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY)))
    goto memory_tagged;

  /* size should have been reset. This is not a catch all, pool with
   * size requirement per memory should do their own check. */
  if (G_UNLIKELY (gst_buffer_get_size (buffer) != pool->priv->size))
    goto size_changed;

  /* all memory should be exclusive to this buffer (and thus be writable) */
  if (G_UNLIKELY (!gst_buffer_is_all_memory_writable (buffer)))
    goto not_writable;

  /* keep it around in our queue */
  gst_atomic_queue_push (pool->priv->queue, buffer);
  gst_poll_write_control (pool->priv->poll);

  return;

memory_tagged:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, pool,
        "discarding buffer %p: memory tag set", buffer);
    goto discard;
  }
size_changed:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, pool,
        "discarding buffer %p: size %" G_GSIZE_FORMAT " != %u",
        buffer, gst_buffer_get_size (buffer), pool->priv->size);
    goto discard;
  }
not_writable:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, pool,
        "discarding buffer %p: memory not writable", buffer);
    goto discard;
  }
discard:
  {
    do_free_buffer (pool, buffer);
    return;
  }
}
Exemple #10
0
static gboolean
gst_dshowvideodec_sink_event (GstPad * pad, GstEvent * event)
{
  gboolean ret = TRUE;
  GstDshowVideoDec *vdec = (GstDshowVideoDec *) gst_pad_get_parent (pad);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_FLUSH_STOP:
      gst_dshowvideodec_flush (vdec);
      ret = gst_pad_event_default (pad, event);
      break;
    case GST_EVENT_NEWSEGMENT:
    {
      GstFormat format;
      gdouble rate;
      gint64 start, stop, time;
      gboolean update;

      gst_event_parse_new_segment (event, &update, &rate, &format, &start,
          &stop, &time);

      /* save the new segment in our local current segment */
      gst_segment_set_newsegment (vdec->segment, update, rate, format, start,
          stop, time);

      GST_CAT_DEBUG_OBJECT (dshowvideodec_debug, vdec,
          "new segment received => start=%" GST_TIME_FORMAT " stop=%"
          GST_TIME_FORMAT, GST_TIME_ARGS (vdec->segment->start),
          GST_TIME_ARGS (vdec->segment->stop));

      if (update) {
        GST_CAT_DEBUG_OBJECT (dshowvideodec_debug, vdec,
            "closing current segment flushing..");
        gst_dshowvideodec_flush (vdec);
      }

      ret = gst_pad_event_default (pad, event);
      break;
    }
    default:
      ret = gst_pad_event_default (pad, event);
      break;
  }

  gst_object_unref (vdec);

  return ret;
}
/**
 * gst_clock_id_wait_async:
 * @id: a #GstClockID to wait on
 * @func: The callback function
 * @user_data: User data passed in the callback
 * @destroy_data: #GDestroyNotify for user_data
 *
 * Register a callback on the given #GstClockID @id with the given
 * function and user_data. When passing a #GstClockID with an invalid
 * time to this function, the callback will be called immediately
 * with  a time set to GST_CLOCK_TIME_NONE. The callback will
 * be called when the time of @id has been reached.
 *
 * The callback @func can be invoked from any thread, either provided by the
 * core or from a streaming thread. The application should be prepared for this.
 *
 * Returns: the result of the non blocking wait.
 *
 * MT safe.
 */
GstClockReturn
gst_clock_id_wait_async (GstClockID id,
    GstClockCallback func, gpointer user_data, GDestroyNotify destroy_data)
{
  GstClockEntry *entry;
  GstClock *clock;
  GstClockReturn res;
  GstClockClass *cclass;
  GstClockTime requested;

  g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR);
  g_return_val_if_fail (func != NULL, GST_CLOCK_ERROR);

  entry = (GstClockEntry *) id;
  requested = GST_CLOCK_ENTRY_TIME (entry);
  clock = GST_CLOCK_ENTRY_CLOCK (entry);

  /* can't sync on invalid times */
  if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
    goto invalid_time;

  cclass = GST_CLOCK_GET_CLASS (clock);

  if (G_UNLIKELY (cclass->wait_async == NULL))
    goto not_supported;

  entry->func = func;
  entry->user_data = user_data;
  entry->destroy_data = destroy_data;

  res = cclass->wait_async (clock, entry);

  return res;

  /* ERRORS */
invalid_time:
  {
    (func) (clock, GST_CLOCK_TIME_NONE, id, user_data);
    GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
        "invalid time requested, returning _BADTIME");
    return GST_CLOCK_BADTIME;
  }
not_supported:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
    return GST_CLOCK_UNSUPPORTED;
  }
}
Exemple #12
0
EXPORT_C
#endif

void
gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
    external, GstClockTime rate_num, GstClockTime rate_denom)
{
  g_return_if_fail (GST_IS_CLOCK (clock));
  g_return_if_fail (rate_num >= 0);
  g_return_if_fail (rate_denom > 0);
  g_return_if_fail (internal <= gst_clock_get_internal_time (clock));

  GST_OBJECT_LOCK (clock);
  GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
      "internal %" GST_TIME_FORMAT " external %" GST_TIME_FORMAT " %"
      G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
      GST_TIME_ARGS (external), rate_num, rate_denom,
      gst_guint64_to_gdouble (rate_num / rate_denom));

  clock->internal_calibration = internal;
  clock->external_calibration = external;
  clock->rate_numerator = rate_num;
  clock->rate_denominator = rate_denom;
  GST_OBJECT_UNLOCK (clock);
}
Exemple #13
0
static void
spotify_cb_notify_main_thread (sp_session *spotify_session)
{
  GST_CAT_LOG_OBJECT (gst_spot_src_debug_cb, ugly_spot, "Notify_main_thread callback");
  GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_threads, ugly_spot, "Broadcast process_events_cond");
  g_cond_broadcast (ugly_spot->process_events_cond);
}
static GstClockID
gst_clock_entry_new (GstClock * clock, GstClockTime time,
    GstClockTime interval, GstClockEntryType type)
{
  GstClockEntry *entry;

  entry = g_slice_new (GstClockEntry);
#ifndef GST_DISABLE_TRACE
  _gst_alloc_trace_new (_gst_clock_entry_trace, entry);
#endif
  GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
      "created entry %p, time %" GST_TIME_FORMAT, entry, GST_TIME_ARGS (time));

  entry->refcount = 1;
  entry->clock = clock;
  entry->type = type;
  entry->time = time;
  entry->interval = interval;
  entry->status = GST_CLOCK_OK;
  entry->func = NULL;
  entry->user_data = NULL;
  entry->destroy_data = NULL;
  entry->unscheduled = FALSE;
  entry->woken_up = FALSE;

  return (GstClockID) entry;
}
void GSTGLAPI
_gst_gl_debug_callback (GLenum source, GLenum type, GLuint id, GLenum severity,
    GLsizei length, const gchar * message, gpointer user_data)
{
  GstGLContext *context = user_data;
  const gchar *severity_str = _debug_severity_to_string (severity);
  const gchar *source_str = _debug_source_to_string (source);
  const gchar *type_str = _debug_type_to_string (type);

  _init_debug ();

  switch (type) {
    case GL_DEBUG_TYPE_ERROR:
    case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOUR:
      GST_ERROR_OBJECT (context, "%s: GL %s from %s id:%u, %s", severity_str,
          type_str, source_str, id, message);
      break;
    case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOUR:
    case GL_DEBUG_TYPE_PORTABILITY:
      GST_FIXME_OBJECT (context, "%s: GL %s from %s id:%u, %s", severity_str,
          type_str, source_str, id, message);
      break;
    case GL_DEBUG_TYPE_PERFORMANCE:
      GST_CAT_DEBUG_OBJECT (gst_performance, context, "%s: GL %s from %s id:%u,"
          " %s", severity_str, type_str, source_str, id, message);
      break;
    default:
      GST_DEBUG_OBJECT (context, "%s: GL %s from %s id:%u, %s", severity_str,
          type_str, source_str, id, message);
      break;
  }
}
Exemple #16
0
static void
gst_spot_src_finalize (GObject * object)
{
  GstSpotSrc *spot;

  spot = GST_SPOT_SRC (object);

  /* make thread quit */
  g_mutex_lock (spot->process_events_mutex);
  spot->keep_spotify_thread = FALSE;
  GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_threads, spot, "Broadcast process_events_cond");
  g_cond_broadcast (spot->process_events_cond);
  g_mutex_unlock (spot->process_events_mutex);
  g_thread_join (spot->process_events_thread);
  
  /* free user variables */
  g_free (spot->user);
  g_free (spot->pass);
  g_free (spot->uri);

  g_free (spot->format);
  g_list_free (spot->spot_works);

  g_cond_free (spot->process_events_cond);
  g_mutex_free (spot->process_events_mutex);

  g_mutex_free (GST_SPOT_SRC_ADAPTER_MUTEX (spot));
  g_cond_free (GST_SPOT_SRC_ADAPTER_COND (spot));
  g_object_unref (GST_SPOT_SRC_ADAPTER (spot));

  G_OBJECT_CLASS (parent_class)->finalize (object);

}
/**
 * gst_clock_set_calibration:
 * @clock: a #GstClock to calibrate
 * @internal: a reference internal time
 * @external: a reference external time
 * @rate_num: the numerator of the rate of the clock relative to its
 *            internal time 
 * @rate_denom: the denominator of the rate of the clock
 *
 * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of
 * the clock. Values bigger than 1/1 make the clock go faster.
 *
 * @internal and @external are calibration parameters that arrange that
 * gst_clock_get_time() should have been @external at internal time @internal.
 * This internal time should not be in the future; that is, it should be less
 * than the value of gst_clock_get_internal_time() when this function is called.
 *
 * Subsequent calls to gst_clock_get_time() will return clock times computed as
 * follows:
 *
 * <programlisting>
 *   time = (internal_time - internal) * rate_num / rate_denom + external
 * </programlisting>
 *
 * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it
 * tries to do the integer arithmetic as precisely as possible.
 *
 * Note that gst_clock_get_time() always returns increasing values so when you
 * move the clock backwards, gst_clock_get_time() will report the previous value
 * until the clock catches up.
 *
 * MT safe.
 */
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 " %"
      G_GUINT64_FORMAT "/%" G_GUINT64_FORMAT " = %f", GST_TIME_ARGS (internal),
      GST_TIME_ARGS (external), rate_num, rate_denom,
      gst_guint64_to_gdouble (rate_num) / gst_guint64_to_gdouble (rate_denom));

  priv->internal_calibration = internal;
  priv->external_calibration = external;
  priv->rate_numerator = rate_num;
  priv->rate_denominator = rate_denom;
  write_sequnlock (clock);
}
static GstFlowReturn
gst_dshowaudiodec_chain (GstPad * pad, GstBuffer * buffer)
{
  GstDshowAudioDec *adec = (GstDshowAudioDec *) gst_pad_get_parent (pad);
  bool discont = FALSE;

  if (!adec->setup) {
    /* we are not set up */
    GST_WARNING_OBJECT (adec, "Decoder not set up, failing");
    adec->last_ret = GST_FLOW_WRONG_STATE;
    goto beach;
  }

  if (GST_FLOW_IS_FATAL (adec->last_ret)) {
    GST_DEBUG_OBJECT (adec, "last decoding iteration generated a fatal error "
        "%s", gst_flow_get_name (adec->last_ret));
    goto beach;
  }

  GST_CAT_DEBUG_OBJECT (dshowaudiodec_debug, adec, "chain (size %d)=> pts %"
      GST_TIME_FORMAT " stop %" GST_TIME_FORMAT,
      GST_BUFFER_SIZE (buffer), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer) +
          GST_BUFFER_DURATION (buffer)));

  /* if the incoming buffer has discont flag set => flush decoder data */
  if (buffer && GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
    GST_CAT_DEBUG_OBJECT (dshowaudiodec_debug, adec,
        "this buffer has a DISCONT flag (%" GST_TIME_FORMAT "), flushing",
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
    gst_dshowaudiodec_flush (adec);
    discont = TRUE;
  }

  /* push the buffer to the directshow decoder */
  adec->fakesrc->GetOutputPin()->PushBuffer (
      GST_BUFFER_DATA (buffer), GST_BUFFER_TIMESTAMP (buffer),
      GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer),
      GST_BUFFER_SIZE (buffer), (bool)discont);

beach:
  gst_buffer_unref (buffer);
  gst_object_unref (adec);
  return adec->last_ret;
}
Exemple #19
0
static void
spotify_cb_end_of_track (sp_session *session)
{
  GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_cb, ugly_spot, "End_of_track callback");
  g_mutex_lock (GST_SPOT_SRC_ADAPTER_MUTEX (ugly_spot));
  ugly_spot->end_of_track = TRUE;
  g_cond_broadcast (GST_SPOT_SRC_ADAPTER_COND (ugly_spot));
  g_mutex_unlock (GST_SPOT_SRC_ADAPTER_MUTEX (ugly_spot));
}
Exemple #20
0
EXPORT_C
#endif

gboolean
gst_object_set_parent (GstObject * object, GstObject * parent)
{
  g_return_val_if_fail (GST_IS_OBJECT (object), FALSE);
  g_return_val_if_fail (GST_IS_OBJECT (parent), FALSE);
  g_return_val_if_fail (object != parent, FALSE);

  GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
      "set parent (ref and sink)");

  GST_OBJECT_LOCK (object);
  if (G_UNLIKELY (object->parent != NULL))
    goto had_parent;

  /* sink object, we don't call our own function because we don't
   * need to release/acquire the lock needlessly or touch the refcount
   * in the floating case. */
  object->parent = parent;
  if (G_LIKELY (GST_OBJECT_IS_FLOATING (object))) {
    GST_CAT_LOG_OBJECT (GST_CAT_REFCOUNTING, object, "unsetting floating flag");
    GST_OBJECT_FLAG_UNSET (object, GST_OBJECT_FLOATING);
    GST_OBJECT_UNLOCK (object);
  } else {
    GST_OBJECT_UNLOCK (object);
    gst_object_ref (object);
  }

  g_signal_emit (object, gst_object_signals[PARENT_SET], 0, parent);

  return TRUE;

  /* ERROR handling */
had_parent:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, object,
        "set parent failed, object already had a parent");
    GST_OBJECT_UNLOCK (object);
    return FALSE;
  }
}
static GstFlowReturn
gst_dshowvideodec_chain (GstPad * pad, GstBuffer * buffer)
{
  GstDshowVideoDec *vdec = (GstDshowVideoDec *) gst_pad_get_parent (pad);
  bool discont = FALSE;
  GstClockTime stop;

  if (!vdec->setup) {
    /* we are not setup */
    GST_WARNING_OBJECT (vdec, "Decoder not set up, failing");
    vdec->last_ret = GST_FLOW_FLUSHING;
    goto beach;
  }

  if (GST_FLOW_IS_FATAL (vdec->last_ret)) {
    GST_DEBUG_OBJECT (vdec, "last decoding iteration generated a fatal error "
        "%s", gst_flow_get_name (vdec->last_ret));
    goto beach;
  }

  /* check if duration is valid and use duration only when it's valid
     /* because dshow is not decoding frames having stop smaller than start */
  if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
    stop = GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer);
  } else {
    stop = GST_BUFFER_TIMESTAMP (buffer);
  }

  GST_CAT_LOG_OBJECT (dshowvideodec_debug, vdec,
      "chain (size %d)=> pts %" GST_TIME_FORMAT " stop %" GST_TIME_FORMAT,
      GST_BUFFER_SIZE (buffer), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
      GST_TIME_ARGS (stop));

  /* if the incoming buffer has discont flag set => flush decoder data */
  if (buffer && GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) {
    GST_CAT_DEBUG_OBJECT (dshowvideodec_debug, vdec,
        "this buffer has a DISCONT flag (%" GST_TIME_FORMAT "), flushing",
        GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)));
    gst_dshowvideodec_flush (vdec);
    discont = TRUE;
  }

  /* push the buffer to the directshow decoder */
  vdec->fakesrc->GetOutputPin()->PushBuffer(
      GST_BUFFER_DATA (buffer), GST_BUFFER_TIMESTAMP (buffer), stop,
      GST_BUFFER_SIZE (buffer), discont);

beach:
  gst_buffer_unref (buffer);
  gst_object_unref (vdec);

  return vdec->last_ret;
}
static GstFlowReturn
gst_video_scale_transform_frame (GstVideoFilter * filter,
                                 GstVideoFrame * in_frame, GstVideoFrame * out_frame)
{
    GstVideoScale *videoscale = GST_VIDEO_SCALE_CAST (filter);
    GstFlowReturn ret = GST_FLOW_OK;

    GST_CAT_DEBUG_OBJECT (CAT_PERFORMANCE, filter, "doing video scaling");

    gst_video_converter_frame (videoscale->convert, in_frame, out_frame);

    return ret;
}
static void
gst_pipeline_dispose (GObject * object)
{
  GstPipeline *pipeline = GST_PIPELINE (object);
  GstClock **clock_p = &pipeline->fixed_clock;

  GST_CAT_DEBUG_OBJECT (GST_CAT_REFCOUNTING, pipeline, "dispose");

  /* clear and unref any fixed clock */
  gst_object_replace ((GstObject **) clock_p, NULL);

  G_OBJECT_CLASS (parent_class)->dispose (object);
}
static GstClockReturn
gst_test_clock_wait (GstClock * clock,
    GstClockEntry * entry, GstClockTimeDiff * jitter)
{
  GstTestClock *test_clock = GST_TEST_CLOCK (clock);
  GstTestClockPrivate *priv = GST_TEST_CLOCK_GET_PRIVATE (test_clock);

  GST_OBJECT_LOCK (test_clock);

  GST_CAT_DEBUG_OBJECT (GST_CAT_TEST_CLOCK, test_clock,
      "requesting synchronous clock notification at %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_CLOCK_ENTRY_TIME (entry)));

  if (GST_CLOCK_ENTRY_STATUS (entry) == GST_CLOCK_UNSCHEDULED)
    goto was_unscheduled;

  if (gst_test_clock_lookup_entry_context (test_clock, entry) == NULL)
    gst_test_clock_add_entry (test_clock, entry, jitter);

  GST_CLOCK_ENTRY_STATUS (entry) = GST_CLOCK_BUSY;

  while (GST_CLOCK_ENTRY_STATUS (entry) == GST_CLOCK_BUSY)
    g_cond_wait (&priv->entry_processed_cond, GST_OBJECT_GET_LOCK (test_clock));

  GST_OBJECT_UNLOCK (test_clock);

  return GST_CLOCK_ENTRY_STATUS (entry);

  /* ERRORS */
was_unscheduled:
  {
    GST_CAT_DEBUG_OBJECT (GST_CAT_TEST_CLOCK, test_clock,
        "entry was unscheduled");
    GST_OBJECT_UNLOCK (test_clock);
    return GST_CLOCK_UNSCHEDULED;
  }
}
Exemple #25
0
static int
spotify_cb_music_delivery (sp_session *spotify_session, const sp_audioformat *format,const void *frames, int num_frames)
{
  GstBuffer *buffer;
  guint sample_rate = format->sample_rate;
  guint channels = format->channels;
  guint bufsize = num_frames * sizeof (int16_t) * channels;
  guint availible;

  GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_cb, ugly_spot, "Music_delivery callback");

  GST_SPOT_SRC_FORMAT (ugly_spot)->sample_rate = sample_rate;
  GST_SPOT_SRC_FORMAT (ugly_spot)->channels = channels;
  GST_SPOT_SRC_FORMAT (ugly_spot)->sample_type = format->sample_type;

  GST_CAT_LOG_OBJECT (gst_spot_src_debug_audio, ugly_spot, "Start %p with %d frames with size=%d", frames, num_frames, bufsize);

  if (num_frames == 0) {
    /* we have a seek */
    return 0;
  }

  buffer = gst_buffer_new_and_alloc (bufsize);

  memcpy (GST_BUFFER_DATA (buffer), (guint8*)frames, bufsize);

  g_mutex_lock (GST_SPOT_SRC_ADAPTER_MUTEX (ugly_spot));
  availible = gst_adapter_available (GST_SPOT_SRC_ADAPTER (ugly_spot));
  GST_CAT_LOG_OBJECT (gst_spot_src_debug_audio, ugly_spot, "Availiable before push = %d", availible);
  /* see if we have buffertime of audio */
  if (availible >= (GST_SPOT_SRC_BUFFER_TIME (ugly_spot)/1000000) * sample_rate * 4) {
    GST_CAT_LOG_OBJECT (gst_spot_src_debug_audio, ugly_spot, "Return 0, adapter is full = %d", availible);
    gst_buffer_unref (buffer);
    /* data is available broadcast read thread */
    g_cond_broadcast (GST_SPOT_SRC_ADAPTER_COND (ugly_spot));
    g_mutex_unlock (GST_SPOT_SRC_ADAPTER_MUTEX (ugly_spot));
    return 0;
  }

  gst_adapter_push (GST_SPOT_SRC_ADAPTER (ugly_spot), buffer);
  availible = gst_adapter_available (GST_SPOT_SRC_ADAPTER (ugly_spot));
  GST_CAT_LOG_OBJECT (gst_spot_src_debug_audio, ugly_spot, "Availiable after push = %d", availible);
  /* data is available broadcast read thread */
  g_cond_broadcast (GST_SPOT_SRC_ADAPTER_COND (ugly_spot));
  g_mutex_unlock (GST_SPOT_SRC_ADAPTER_MUTEX (ugly_spot));
  GST_CAT_LOG_OBJECT (gst_spot_src_debug_audio, ugly_spot, "Return num_frames=%d", num_frames);
  return num_frames;
}
static void
gst_test_clock_unschedule (GstClock * clock, GstClockEntry * entry)
{
  GstTestClock *test_clock = GST_TEST_CLOCK (clock);

  GST_OBJECT_LOCK (test_clock);

  GST_CAT_DEBUG_OBJECT (GST_CAT_TEST_CLOCK, test_clock,
      "unscheduling requested clock notification at %" GST_TIME_FORMAT,
      GST_TIME_ARGS (GST_CLOCK_ENTRY_TIME (entry)));

  GST_CLOCK_ENTRY_STATUS (entry) = GST_CLOCK_UNSCHEDULED;
  gst_test_clock_remove_entry (test_clock, entry);

  GST_OBJECT_UNLOCK (test_clock);
}
static GstFlowReturn
gst_video_convert_transform_frame (GstVideoFilter * filter,
    GstVideoFrame * in_frame, GstVideoFrame * out_frame)
{
  GstVideoConvert *space;

  space = GST_VIDEO_CONVERT_CAST (filter);

  GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, filter,
      "doing colorspace conversion from %s -> to %s",
      GST_VIDEO_INFO_NAME (&filter->in_info),
      GST_VIDEO_INFO_NAME (&filter->out_info));

  gst_video_converter_frame (space->convert, in_frame, out_frame);

  return GST_FLOW_OK;
}
Exemple #28
0
static void
spotify_cb_logged_in (sp_session *spotify_session, sp_error error)
{
  if (SP_ERROR_OK != error) {
    GST_CAT_ERROR_OBJECT (gst_spot_src_debug_cb, ugly_spot, "Failed to log in to Spotify: %s", sp_error_message (error));
    return;
  }

  sp_user *me = sp_session_user (spotify_session);
  const char *my_name = (sp_user_is_loaded (me) ?
                         sp_user_display_name (me) :
                         sp_user_canonical_name (me));
  GST_CAT_DEBUG_OBJECT (gst_spot_src_debug_cb, ugly_spot, "Logged_in callback, user=%s", my_name);
  /* set default bitrate to audiofility */
  sp_session_preferred_bitrate(spotify_session, SP_BITRATE_320k);
  GST_SPOT_SRC_LOGGED_IN (ugly_spot) = TRUE;
}
Exemple #29
0
/* 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;
}
Exemple #30
0
EXPORT_C
#endif

GstClockTime
gst_clock_get_time (GstClock * clock)
{
  GstClockTime ret;

  g_return_val_if_fail (GST_IS_CLOCK (clock), GST_CLOCK_TIME_NONE);

  ret = gst_clock_get_internal_time (clock);

  GST_OBJECT_LOCK (clock);
  /* this will scale for rate and offset */
  ret = gst_clock_adjust_unlocked (clock, ret);
  GST_OBJECT_UNLOCK (clock);

  GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "adjusted time %" GST_TIME_FORMAT,
      GST_TIME_ARGS (ret));

  return ret;
}