mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-03 04:52:28 +00:00
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:
parent
b53dc49d8d
commit
99a61247bc
6 changed files with 176 additions and 80 deletions
26
ChangeLog
26
ChangeLog
|
@ -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),
|
||||||
|
|
210
gst/gstclock.c
210
gst/gstclock.c
|
@ -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:
|
||||||
|
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue