gst/gstclock.*: Review docs.

Original commit message from CVS:
* gst/gstclock.c: (gst_clock_entry_new),
(gst_clock_id_compare_func), (gst_clock_id_wait),
(gst_clock_id_wait_async), (gst_clock_id_unschedule),
(gst_clock_init), (gst_clock_get_internal_time),
(gst_clock_set_master), (do_linear_regression),
(gst_clock_add_observation), (gst_clock_set_property):
* gst/gstclock.h:
Review docs.
Small cleanups.
Fix a possible segfault when the window-size is made smaller.
Calculate jitter before performing the clock wait. Ideally
the clock implementation should calculate jitter but we need
API breakage for that.
* gst/gstsystemclock.c: (gst_system_clock_init):
Docs review.
* libs/gst/base/gstbasesink.c: (gst_base_sink_do_sync):
Remove leftover else
* tests/check/gst/gstsystemclock.c: (GST_START_TEST),
(gst_systemclock_suite):
Added check to test GST_CLOCK_DIFF.
This commit is contained in:
Wim Taymans 2006-03-09 11:45:14 +00:00
parent b53dc49d8d
commit 99a61247bc
6 changed files with 176 additions and 80 deletions

View file

@ -1,3 +1,29 @@
2006-03-09 Wim Taymans <wim@fluendo.com>
* gst/gstclock.c: (gst_clock_entry_new),
(gst_clock_id_compare_func), (gst_clock_id_wait),
(gst_clock_id_wait_async), (gst_clock_id_unschedule),
(gst_clock_init), (gst_clock_get_internal_time),
(gst_clock_set_master), (do_linear_regression),
(gst_clock_add_observation), (gst_clock_set_property):
* gst/gstclock.h:
Review docs.
Small cleanups.
Fix a possible segfault when the window-size is made smaller.
Calculate jitter before performing the clock wait. Ideally
the clock implementation should calculate jitter but we need
API breakage for that.
* gst/gstsystemclock.c: (gst_system_clock_init):
Docs review.
* libs/gst/base/gstbasesink.c: (gst_base_sink_do_sync):
Remove leftover else
* tests/check/gst/gstsystemclock.c: (GST_START_TEST),
(gst_systemclock_suite):
Added check to test GST_CLOCK_DIFF.
2006-03-09 Tim-Philipp Müller <tim at centricular dot net> 2006-03-09 Tim-Philipp Müller <tim at centricular dot net>
* libs/gst/base/gsttypefindhelper.c: (helper_find_get_length), * libs/gst/base/gsttypefindhelper.c: (helper_find_get_length),

View file

@ -31,17 +31,15 @@
* base class. * base class.
* *
* The #GstClock returns a monotonically increasing time with the method * The #GstClock returns a monotonically increasing time with the method
* gst_clock_get_time(). Its accuracy and base time depends on the specific * gst_clock_get_time(). Its accuracy and base time depend on the specific
* clock implementation but time is always expessed in nanoseconds. Since the * clock implementation but time is always expressed in nanoseconds. Since the
* baseline of the clock is undefined, the clock time returned is not * baseline of the clock is undefined, the clock time returned is not
* meaningful in itself, what matters are the deltas between two clock times. * meaningful in itself, what matters are the deltas between two clock times.
* *
* The pipeline uses the clock to calculate the stream time. Usually all * The pipeline uses the clock to calculate the stream time. Usually all
* renderers synchronize to the global clock using the buffer timestamps, the * renderers synchronize to the global clock using the buffer timestamps, the
* newsegment events and the element's base time. * newsegment events and the element's base time.
* *
* The time of the clock in itself is not very useful for an application.
*
* A clock implementation can support periodic and single shot clock * A clock implementation can support periodic and single shot clock
* notifications both synchronous and asynchronous. * notifications both synchronous and asynchronous.
* *
@ -56,24 +54,27 @@
* unscheduled a return value of GST_CLOCK_UNSCHEDULED is returned. * unscheduled a return value of GST_CLOCK_UNSCHEDULED is returned.
* *
* Periodic callbacks scheduled async will be repeadedly called automatically * Periodic callbacks scheduled async will be repeadedly called automatically
* until it is unscheduled. To schedule an async periodic callback, * until it is unscheduled. To schedule a sync periodic callback,
* gst_clock_id_wait() should be called repeadedly. * gst_clock_id_wait() should be called repeadedly.
* *
* The async callbacks can happen from any thread, either provided by the core * The async callbacks can happen from any thread, either provided by the core
* or from a streaming thread. The application should be prepared for this. * or from a streaming thread. The application should be prepared for this.
* *
* A #GstClockID that has been unscheduled cannot be used again for any wait * A #GstClockID that has been unscheduled cannot be used again for any wait
* operation. * operation, a new #GstClockID should be created and the old unscheduled one
* should be destroyed wirth gst_clock_id_unref().
* *
* It is possible to perform a blocking wait on the same #GstClockID from * It is possible to perform a blocking wait on the same #GstClockID from
* multiple threads. However, registering the same #GstClockID for multiple * multiple threads. However, registering the same #GstClockID for multiple
* async notifications is not possible, the callback will only be called once. * async notifications is not possible, the callback will only be called for
* the thread registering the entry last.
* *
* None of the wait operations unref the #GstClockID, the owner is responsible * None of the wait operations unref the #GstClockID, the owner is responsible
* for unreffing the ids itself. This holds for both periodic and single shot * for unreffing the ids itself. This holds for both periodic and single shot
* notifications. The reason being that the owner of the #GstClockID has to * notifications. The reason being that the owner of the #GstClockID has to
* keep a handle to the #GstClockID to unblock the wait on FLUSHING events or * keep a handle to the #GstClockID to unblock the wait on FLUSHING events or
* state changes and if we unref it automatically, the handle might be invalid. * state changes and if the entry would be unreffed automatically, the handle
* might become invalid without any notification.
* *
* These clock operations do not operate on the stream time, so the callbacks * These clock operations do not operate on the stream time, so the callbacks
* will also occur when not in PLAYING state as if the clock just keeps on * will also occur when not in PLAYING state as if the clock just keeps on
@ -88,9 +89,16 @@
* plugins that have an internal clock but must operate with another clock * plugins that have an internal clock but must operate with another clock
* selected by the #GstPipeline. They can track the offset and rate difference * selected by the #GstPipeline. They can track the offset and rate difference
* of their internal clock relative to the master clock by using the * of their internal clock relative to the master clock by using the
* gst_clock_get_calibration() function. * gst_clock_get_calibration() function.
* *
* Last reviewed on 2005-10-28 (0.9.4) * The master/slave synchronisation can be tuned with the "timeout", "window-size"
* and "window-threshold" properties. The "timeout" property defines the interval
* to sample the master clock and run the calibration functions.
* "window-size" defines the number of samples to use when calibrating and
* "window-threshold" defines the minimum number of samples before the
* calibration is performed.
*
* Last reviewed on 2006-03-09 (0.10.4)
*/ */
#include <time.h> #include <time.h>
@ -145,7 +153,9 @@ gst_clock_entry_new (GstClock * clock, GstClockTime time,
{ {
GstClockEntry *entry; GstClockEntry *entry;
entry = g_malloc0 (sizeof (GstClockEntry)); /* FIXME, use g_slice, we do this a lot and potentially from
* different threads. */
entry = g_new0 (GstClockEntry, 1);
#ifndef GST_DISABLE_TRACE #ifndef GST_DISABLE_TRACE
gst_alloc_trace_new (_gst_clock_entry_trace, entry); gst_alloc_trace_new (_gst_clock_entry_trace, entry);
#endif #endif
@ -164,9 +174,9 @@ gst_clock_entry_new (GstClock * clock, GstClockTime time,
/** /**
* gst_clock_id_ref: * gst_clock_id_ref:
* @id: The clockid to ref * @id: The #GstClockID to ref
* *
* Increase the refcount of the given clockid. * Increase the refcount of given @id.
* *
* Returns: The same #GstClockID with increased refcount. * Returns: The same #GstClockID with increased refcount.
* *
@ -197,9 +207,9 @@ _gst_clock_id_free (GstClockID id)
/** /**
* gst_clock_id_unref: * gst_clock_id_unref:
* @id: The clockid to unref * @id: The #GstClockID to unref
* *
* Unref the given clockid. When the refcount reaches 0 the * Unref given @id. When the refcount reaches 0 the
* #GstClockID will be freed. * #GstClockID will be freed.
* *
* MT safe. * MT safe.
@ -220,14 +230,14 @@ gst_clock_id_unref (GstClockID id)
/** /**
* gst_clock_new_single_shot_id * gst_clock_new_single_shot_id
* @clock: The clockid to get a single shot notification from * @clock: The #GstClockID to get a single shot notification from
* @time: the requested time * @time: the requested time
* *
* Get an ID from the given clock to trigger a single shot * Get a #GstClockID from @clock to trigger a single shot
* notification at the requested time. The single shot id should be * notification at the requested time. The single shot id should be
* unreffed after usage. * unreffed after usage.
* *
* Returns: An id that can be used to request the time notification. * Returns: A #GstClockID that can be used to request the time notification.
* *
* MT safe. * MT safe.
*/ */
@ -242,16 +252,16 @@ gst_clock_new_single_shot_id (GstClock * clock, GstClockTime time)
/** /**
* gst_clock_new_periodic_id * gst_clock_new_periodic_id
* @clock: The clockid to get a periodic notification id from * @clock: The #GstClockID to get a periodic notification id from
* @start_time: the requested start time * @start_time: the requested start time
* @interval: the requested interval * @interval: the requested interval
* *
* Get an ID from the given clock to trigger a periodic notification. * Get an ID from @clock to trigger a periodic notification.
* The periodeic notifications will be start at time start_time and * The periodeic notifications will be start at time start_time and
* will then be fired with the given interval. The id should be unreffed * will then be fired with the given interval. @id should be unreffed
* after usage. * after usage.
* *
* Returns: An id that can be used to request the time notification. * Returns: A #GstClockID that can be used to request the time notification.
* *
* MT safe. * MT safe.
*/ */
@ -269,10 +279,10 @@ gst_clock_new_periodic_id (GstClock * clock, GstClockTime start_time,
/** /**
* gst_clock_id_compare_func * gst_clock_id_compare_func
* @id1: A clockid * @id1: A #GstClockID
* @id2: A clockid to compare with * @id2: A #GstClockID to compare with
* *
* Compares the two GstClockID instances. This function can be used * Compares the two #GstClockID instances. This function can be used
* as a GCompareFunc when sorting ids. * as a GCompareFunc when sorting ids.
* *
* Returns: negative value if a < b; zero if a = b; positive value if a > b * Returns: negative value if a < b; zero if a = b; positive value if a > b
@ -293,13 +303,12 @@ gst_clock_id_compare_func (gconstpointer id1, gconstpointer id2)
if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) { if (GST_CLOCK_ENTRY_TIME (entry1) < GST_CLOCK_ENTRY_TIME (entry2)) {
return -1; return -1;
} }
return 0;
return entry1 - entry2;
} }
/** /**
* gst_clock_id_get_time * gst_clock_id_get_time
* @id: The clockid to query * @id: The #GstClockID to query
* *
* Get the time of the clock ID * Get the time of the clock ID
* *
@ -318,13 +327,25 @@ gst_clock_id_get_time (GstClockID id)
/** /**
* gst_clock_id_wait * gst_clock_id_wait
* @id: The clockid to wait on * @id: The #GstClockID to wait on
* @jitter: A pointer that will contain the jitter * @jitter: A pointer that will contain the jitter, can be NULL.
* *
* Perform a blocking wait on the given ID. The jitter arg can be * Perform a blocking wait on @id.
* NULL. * @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().
* *
* Returns: the result of the blocking wait. * 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. Negative values means @id was scheduled too late (and this
* function will return #GST_CLOCK_EARLY). Positive values indicate how
* early @id was scheduled.
*
* 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. * MT safe.
*/ */
@ -344,37 +365,39 @@ gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
clock = GST_CLOCK_ENTRY_CLOCK (entry); clock = GST_CLOCK_ENTRY_CLOCK (entry);
/* can't sync on invalid times */
if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested))) if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
goto invalid_time; goto invalid_time;
/* a previously unscheduled entry cannot be scheduled again */
if (G_UNLIKELY (entry->status == GST_CLOCK_UNSCHEDULED)) if (G_UNLIKELY (entry->status == GST_CLOCK_UNSCHEDULED))
goto unscheduled; goto unscheduled;
cclass = GST_CLOCK_GET_CLASS (clock); cclass = GST_CLOCK_GET_CLASS (clock);
if (G_LIKELY (cclass->wait)) { if (G_UNLIKELY (cclass->wait == NULL))
goto not_supported;
GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
id);
res = cclass->wait (clock, entry);
GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
"done waiting entry %p, res: %d", id, res);
if (jitter) { /* jitter is the diff against the clock when this entry is scheduled */
GstClockTime now = gst_clock_get_time (clock); if (jitter) {
GstClockTime now = gst_clock_get_time (clock);
*jitter = now - requested; *jitter = GST_CLOCK_DIFF (requested, now);
}
if (entry->type == GST_CLOCK_ENTRY_PERIODIC) {
entry->time += entry->interval;
}
if (clock->stats) {
gst_clock_update_stats (clock);
}
} else {
res = GST_CLOCK_UNSUPPORTED;
} }
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 += entry->interval;
}
if (clock->stats)
gst_clock_update_stats (clock);
return res; return res;
/* ERRORS */ /* ERRORS */
@ -390,6 +413,11 @@ unscheduled:
"entry was unscheduled return _UNSCHEDULED"); "entry was unscheduled return _UNSCHEDULED");
return GST_CLOCK_UNSCHEDULED; return GST_CLOCK_UNSCHEDULED;
} }
not_supported:
{
GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "clock wait is not supported");
return GST_CLOCK_UNSUPPORTED;
}
} }
/** /**
@ -398,11 +426,11 @@ unscheduled:
* @func: The callback function * @func: The callback function
* @user_data: User data passed in the calback * @user_data: User data passed in the calback
* *
* Register a callback on the given clockid with the given * Register a callback on the given #GstClockID @id with the given
* function and user_data. When passing an id with an invalid * function and user_data. When passing a #GstClockID with an invalid
* time to this function, the callback will be called immediatly * time to this function, the callback will be called immediatly
* with a time set to GST_CLOCK_TIME_NONE. The callback will * with a time set to GST_CLOCK_TIME_NONE. The callback will
* be called when the time of the id has been reached. * be called when the time of @id has been reached.
* *
* Returns: the result of the non blocking wait. * Returns: the result of the non blocking wait.
* *
@ -425,22 +453,24 @@ gst_clock_id_wait_async (GstClockID id,
requested = GST_CLOCK_ENTRY_TIME (entry); requested = GST_CLOCK_ENTRY_TIME (entry);
clock = GST_CLOCK_ENTRY_CLOCK (entry); clock = GST_CLOCK_ENTRY_CLOCK (entry);
/* can't sync on invalid times */
if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested))) if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (requested)))
goto invalid_time; goto invalid_time;
/* a previously unscheduled entry cannot be scheduled again */
if (G_UNLIKELY (entry->status == GST_CLOCK_UNSCHEDULED)) if (G_UNLIKELY (entry->status == GST_CLOCK_UNSCHEDULED))
goto unscheduled; goto unscheduled;
cclass = GST_CLOCK_GET_CLASS (clock); cclass = GST_CLOCK_GET_CLASS (clock);
if (cclass->wait_async) { if (G_UNLIKELY (cclass->wait_async == NULL))
entry->func = func; goto not_supported;
entry->user_data = user_data;
entry->func = func;
entry->user_data = user_data;
res = cclass->wait_async (clock, entry);
res = cclass->wait_async (clock, entry);
} else {
res = GST_CLOCK_UNSUPPORTED;
}
return res; return res;
/* ERRORS */ /* ERRORS */
@ -457,16 +487,21 @@ unscheduled:
"entry was unscheduled return _UNSCHEDULED"); "entry was unscheduled return _UNSCHEDULED");
return GST_CLOCK_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_id_unschedule: * gst_clock_id_unschedule:
* @id: The id to unschedule * @id: The id to unschedule
* *
* Cancel an outstanding request with the given ID. This can either * Cancel an outstanding request with @id. This can either
* be an outstanding async notification or a pending sync notification. * be an outstanding async notification or a pending sync notification.
* After this call, the @id cannot be used anymore to receive sync or * After this call, @id cannot be used anymore to receive sync or
* async notifications, you need to create a new GstClockID. * async notifications, you need to create a new #GstClockID.
* *
* MT safe. * MT safe.
*/ */
@ -484,7 +519,7 @@ gst_clock_id_unschedule (GstClockID id)
cclass = GST_CLOCK_GET_CLASS (clock); cclass = GST_CLOCK_GET_CLASS (clock);
if (cclass->unschedule) if (G_LIKELY (cclass->unschedule))
cclass->unschedule (clock, entry); cclass->unschedule (clock, entry);
} }
@ -573,9 +608,9 @@ gst_clock_init (GstClock * clock)
clock->rate_denominator = 1; clock->rate_denominator = 1;
clock->slave_lock = g_mutex_new (); clock->slave_lock = g_mutex_new ();
clock->filling = TRUE;
clock->window_size = DEFAULT_WINDOW_SIZE; clock->window_size = DEFAULT_WINDOW_SIZE;
clock->window_threshold = DEFAULT_WINDOW_THRESHOLD; clock->window_threshold = DEFAULT_WINDOW_THRESHOLD;
clock->filling = TRUE;
clock->time_index = 0; clock->time_index = 0;
clock->timeout = DEFAULT_TIMEOUT; clock->timeout = DEFAULT_TIMEOUT;
clock->times = g_new0 (GstClockTime, 4 * clock->window_size); clock->times = g_new0 (GstClockTime, 4 * clock->window_size);
@ -716,15 +751,23 @@ gst_clock_get_internal_time (GstClock * clock)
cclass = GST_CLOCK_GET_CLASS (clock); cclass = GST_CLOCK_GET_CLASS (clock);
if (cclass->get_internal_time) { if (G_UNLIKELY (cclass->get_internal_time == NULL))
ret = cclass->get_internal_time (clock); goto not_supported;
} else {
ret = G_GINT64_CONSTANT (0); ret = cclass->get_internal_time (clock);
}
GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT, GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "internal time %" GST_TIME_FORMAT,
GST_TIME_ARGS (ret)); GST_TIME_ARGS (ret));
return 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);
}
} }
/** /**
@ -845,7 +888,7 @@ gst_clock_get_calibration (GstClock * clock, GstClockTime * internal,
} }
/* will be called repeadedly to sample the master and slave clock /* will be called repeadedly to sample the master and slave clock
* to recalibrate the clock */ * to recalibrate the clock */
static gboolean static gboolean
gst_clock_slave_callback (GstClock * master, GstClockTime time, gst_clock_slave_callback (GstClock * master, GstClockTime time,
GstClockID id, GstClock * clock) GstClockID id, GstClock * clock)
@ -880,7 +923,13 @@ gst_clock_slave_callback (GstClock * master, GstClockTime time,
* A clock provider that slaves its clock to a master can get the current * A clock provider that slaves its clock to a master can get the current
* calibration values with gst_clock_get_calibration(). * calibration values with gst_clock_get_calibration().
* *
* Returns: TRUE if the clock is capable of being slaved to a master clock. * @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. * MT safe.
*/ */
@ -919,6 +968,7 @@ gst_clock_set_master (GstClock * clock, GstClock * master)
return TRUE; return TRUE;
/* ERRORS */
not_supported: not_supported:
{ {
GST_DEBUG_OBJECT (clock, "cannot be slaved to a master clock"); GST_DEBUG_OBJECT (clock, "cannot be slaved to a master clock");
@ -1043,7 +1093,7 @@ do_linear_regression (GstClock * clock, GstClockTime * m_num,
sxy += newx4 * newy4 - xbar4 * ybar4; sxy += newx4 * newy4 - xbar4 * ybar4;
} }
if (sxx == 0) if (G_UNLIKELY (sxx == 0))
goto invalid; goto invalid;
*m_num = sxy; *m_num = sxy;
@ -1099,12 +1149,13 @@ gst_clock_add_observation (GstClock * clock, GstClockTime slave,
clock->times[(4 * clock->time_index) + 2] = master; clock->times[(4 * clock->time_index) + 2] = master;
clock->time_index++; clock->time_index++;
if (clock->time_index == clock->window_size) { if (G_UNLIKELY (clock->time_index == clock->window_size)) {
clock->filling = FALSE; clock->filling = FALSE;
clock->time_index = 0; clock->time_index = 0;
} }
if (clock->filling && clock->time_index < clock->window_threshold) if (G_UNLIKELY (clock->filling
&& clock->time_index < clock->window_threshold))
goto filling; goto filling;
if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared)) if (!do_linear_regression (clock, &m_num, &m_denom, &b, &xbase, r_squared))
@ -1161,6 +1212,9 @@ gst_clock_set_property (GObject * object, guint prop_id,
MIN (clock->window_threshold, clock->window_size); MIN (clock->window_threshold, clock->window_size);
clock->times = clock->times =
g_renew (GstClockTime, clock->times, 4 * clock->window_size); g_renew (GstClockTime, clock->times, 4 * clock->window_size);
/* restart calibration */
clock->filling = TRUE;
clock->time_index = 0;
GST_CLOCK_SLAVE_UNLOCK (clock); GST_CLOCK_SLAVE_UNLOCK (clock);
break; break;
case PROP_WINDOW_THRESHOLD: case PROP_WINDOW_THRESHOLD:

View file

@ -112,6 +112,7 @@ typedef gpointer GstClockID;
* @e: the second time * @e: the second time
* *
* Calculate a difference between two clock times as a #GstClockTimeDiff. * Calculate a difference between two clock times as a #GstClockTimeDiff.
* The difference is calculated as @e - @s.
*/ */
#define GST_CLOCK_DIFF(s, e) (GstClockTimeDiff)((e) - (s)) #define GST_CLOCK_DIFF(s, e) (GstClockTimeDiff)((e) - (s))

View file

@ -35,7 +35,7 @@
* async notifications to implement their own callback methods or blocking * async notifications to implement their own callback methods or blocking
* wait operations. * wait operations.
* *
* Last reviewed on 2005-10-28 (0.9.4) * Last reviewed on 2006-03-08 (0.10.4)
*/ */
#include "gst_private.h" #include "gst_private.h"
@ -137,6 +137,7 @@ gst_system_clock_init (GstSystemClock * clock)
GST_OBJECT_UNLOCK (clock); GST_OBJECT_UNLOCK (clock);
return; return;
/* ERRORS */
no_thread: no_thread:
{ {
g_warning ("could not create async clock thread: %s", error->message); g_warning ("could not create async clock thread: %s", error->message);

View file

@ -945,7 +945,6 @@ again:
/* send upstream */ /* send upstream */
gst_pad_push_event (basesink->sinkpad, event); gst_pad_push_event (basesink->sinkpad, event);
} }
} else {
} }
return GST_FLOW_OK; return GST_FLOW_OK;

View file

@ -189,6 +189,20 @@ GST_START_TEST (test_periodic_shot)
gst_clock_id_unref (id); gst_clock_id_unref (id);
} }
GST_END_TEST
GST_START_TEST (test_diff)
{
GstClockTime time1[] =
{ 0, -1, 0, 1, 2 * GST_SECOND, -GST_SECOND, -GST_SECOND };
GstClockTime time2[] =
{ 0, 1, 1, 0, 1 * GST_SECOND, -GST_SECOND, GST_SECOND };
GstClockTimeDiff d[] = { 0, 2, 1, -1, -GST_SECOND, 0, 2 * GST_SECOND };
guint i;
for (i = 0; i < G_N_ELEMENTS (d); i++) {
fail_if (d[i] != GST_CLOCK_DIFF (time1[i], time2[i]));
}
}
GST_END_TEST Suite * gst_systemclock_suite (void) GST_END_TEST Suite * gst_systemclock_suite (void)
{ {
Suite *s = suite_create ("GstSystemClock"); Suite *s = suite_create ("GstSystemClock");
@ -198,6 +212,7 @@ GST_END_TEST Suite * gst_systemclock_suite (void)
tcase_add_test (tc_chain, test_signedness); tcase_add_test (tc_chain, test_signedness);
tcase_add_test (tc_chain, test_single_shot); tcase_add_test (tc_chain, test_single_shot);
tcase_add_test (tc_chain, test_periodic_shot); tcase_add_test (tc_chain, test_periodic_shot);
tcase_add_test (tc_chain, test_diff);
return s; return s;
} }