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; } }
/** * 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); } }
/** * 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); } }
/** * 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; } }
/** * gst_clock_get_resolution * @clock: a #GstClock * * Get the accuracy of the clock. The accuracy of the clock is the granularity * of the values returned by gst_clock_get_time(). * * Returns: the resolution of the clock in units of #GstClockTime. * * MT safe. */ GstClockTime gst_clock_get_resolution (GstClock * clock) { GstClockClass *cclass; g_return_val_if_fail (GST_IS_CLOCK (clock), 0); cclass = GST_CLOCK_GET_CLASS (clock); if (cclass->get_resolution) return cclass->get_resolution (clock); return 1; }
/** * 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; } }
/** * gst_clock_set_resolution * @clock: a #GstClock * @resolution: The resolution to set * * Set the accuracy of the clock. Some clocks have the possibility to operate * with different accuracy at the expense of more resource usage. There is * normally no need to change the default resolution of a clock. The resolution * of a clock can only be changed if the clock has the * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set. * * Returns: the new resolution of the clock. */ GstClockTime gst_clock_set_resolution (GstClock * clock, GstClockTime resolution) { GstClockClass *cclass; g_return_val_if_fail (GST_IS_CLOCK (clock), 0); g_return_val_if_fail (resolution != 0, 0); cclass = GST_CLOCK_GET_CLASS (clock); if (cclass->change_resolution) clock->resolution = cclass->change_resolution (clock, clock->resolution, resolution); return clock->resolution; }
/** * gst_clock_id_unschedule: * @id: The id to unschedule * * Cancel an outstanding request with @id. This can either * be an outstanding async notification or a pending sync notification. * After this call, @id cannot be used anymore to receive sync or * async notifications, you need to create a new #GstClockID. * * MT safe. */ void gst_clock_id_unschedule (GstClockID id) { GstClockEntry *entry; GstClock *clock; GstClockClass *cclass; g_return_if_fail (id != NULL); entry = (GstClockEntry *) id; clock = entry->clock; cclass = GST_CLOCK_GET_CLASS (clock); if (G_LIKELY (cclass->unschedule)) cclass->unschedule (clock, entry); }
/** * gst_clock_id_wait * @id: The #GstClockID to wait on * @jitter: 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_LIKELY (cclass->wait_jitter)) { res = cclass->wait_jitter (clock, entry, jitter); } else { /* check if we have a simple _wait function otherwise. The function without * the jitter arg is less optimal as we need to do an additional _get_time() * which is not atomic with the _wait() and a typical _wait() function does * yet another _get_time() anyway. */ if (G_UNLIKELY (cclass->wait == NULL)) goto not_supported; if (jitter) { GstClockTime now = gst_clock_get_time (clock); /* jitter is the diff against the clock when this entry is scheduled. Negative * values mean that the entry was in time, a positive value means that the * entry was too late. */ *jitter = GST_CLOCK_DIFF (requested, now); } res = cclass->wait (clock, entry); } GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "done waiting entry %p, res: %d", id, res); if (entry->type == GST_CLOCK_ENTRY_PERIODIC) entry->time = requested + entry->interval; if (G_UNLIKELY (clock->stats)) gst_clock_update_stats (clock); 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; } }