Improve _adjust_unlocked() so that it overflows less.

Original commit message from CVS:
* docs/gst/gstreamer-sections.txt:
* gst/gstclock.c: (gst_clock_adjust_unlocked),
(gst_clock_unadjust_unlocked), (gst_clock_set_calibration):
* gst/gstclock.h:
Improve _adjust_unlocked() so that it overflows less.
Add gst_clock_unadjust_unlocked to convert from external time to
internal time based on calibration.
Add some more debug.
API: GstClock::gst_clock_unadjust_unlocked()
This commit is contained in:
Wim Taymans 2007-04-05 10:06:20 +00:00
parent 94e18e2256
commit a78857c296
4 changed files with 97 additions and 8 deletions

View file

@ -1,3 +1,15 @@
2007-04-05 Wim Taymans <wim@fluendo.com>
* docs/gst/gstreamer-sections.txt:
* gst/gstclock.c: (gst_clock_adjust_unlocked),
(gst_clock_unadjust_unlocked), (gst_clock_set_calibration):
* gst/gstclock.h:
Improve _adjust_unlocked() so that it overflows less.
Add gst_clock_unadjust_unlocked to convert from external time to
internal time based on calibration.
Add some more debug.
API: GstClock::gst_clock_unadjust_unlocked()
2007-04-03 Wim Taymans <wim@fluendo.com> 2007-04-03 Wim Taymans <wim@fluendo.com>
Patch by: Tommi Myöhänen <ext-tommi dot myohanen at nokia dot com> Patch by: Tommi Myöhänen <ext-tommi dot myohanen at nokia dot com>

View file

@ -339,6 +339,7 @@ gst_clock_new_single_shot_id
gst_clock_new_periodic_id gst_clock_new_periodic_id
gst_clock_get_internal_time gst_clock_get_internal_time
gst_clock_adjust_unlocked gst_clock_adjust_unlocked
gst_clock_unadjust_unlocked
gst_clock_get_calibration gst_clock_get_calibration
gst_clock_set_calibration gst_clock_set_calibration
gst_clock_id_get_time gst_clock_id_get_time

View file

@ -733,23 +733,47 @@ gst_clock_get_resolution (GstClock * clock)
* @clock: a #GstClock to use * @clock: a #GstClock to use
* @internal: a clock time * @internal: a clock time
* *
* Converts the given @internal clock time to the real time, adjusting for the * Converts the given @internal clock time to the external time, adjusting for the
* rate and reference time set with gst_clock_set_calibration() and making sure * rate and reference time set with gst_clock_set_calibration() and making sure
* that the returned time is increasing. This function should be called with the * that the returned time is increasing. This function should be called with the
* clock's OBJECT_LOCK held and is mainly used by clock subclasses. * clock's OBJECT_LOCK held and is mainly used by clock subclasses.
* *
* Returns: the converted time of the clock. * This function is te reverse of gst_clock_unadjust_unlocked().
* *
* MT safe. * Returns: the converted time of the clock.
*/ */
GstClockTime GstClockTime
gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal) gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
{ {
GstClockTime ret; GstClockTime ret, cinternal, cexternal, cnum, cdenom;
ret = gst_util_uint64_scale (internal - clock->internal_calibration, /* get calibration values for readability */
clock->rate_numerator, clock->rate_denominator); cinternal = clock->internal_calibration;
ret += clock->external_calibration; cexternal = clock->external_calibration;
cnum = clock->rate_numerator;
cdenom = clock->rate_denominator;
/* avoid divide by 0 */
if (cdenom == 0)
cnum = cdenom = 1;
/* The formula is (internal - cinternal) * cnum / cdenom + cexternal
*
* Since we do math on unsigned 64-bit ints we have to special case for
* interal < cinternal to get the sign right. this case is not very common,
* though.
*/
if (G_LIKELY (internal >= cinternal)) {
ret = gst_util_uint64_scale (internal - cinternal, cnum, cdenom);
ret += cexternal;
} else {
ret = gst_util_uint64_scale (cinternal - internal, cnum, cdenom);
/* clamp to 0 */
if (cexternal > ret)
ret = cexternal - ret;
else
ret = 0;
}
/* make sure the time is increasing */ /* make sure the time is increasing */
clock->last_time = MAX (ret, clock->last_time); clock->last_time = MAX (ret, clock->last_time);
@ -757,6 +781,51 @@ gst_clock_adjust_unlocked (GstClock * clock, GstClockTime internal)
return clock->last_time; return clock->last_time;
} }
/**
* gst_clock_unadjust_unlocked
* @clock: a #GstClock to use
* @external: an external clock time
*
* Converts the given @external clock time to the internal time of @clock,
* using the rate and reference time set with gst_clock_set_calibration().
* This function should be called with the clock's OBJECT_LOCK held and
* is mainly used by clock subclasses.
*
* This function is te reverse of gst_clock_adjust_unlocked().
*
* Returns: the internal time of the clock corresponding to @external.
*
* Since: 0.10.13
*/
GstClockTime
gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external)
{
GstClockTime ret, cinternal, cexternal, cnum, cdenom;
/* get calibration values for readability */
cinternal = clock->internal_calibration;
cexternal = clock->external_calibration;
cnum = clock->rate_numerator;
cdenom = clock->rate_denominator;
/* avoid divide by 0 */
if (cnum == 0)
cnum = cdenom = 1;
/* The formula is (external - cexternal) * cdenom / cnum + cinternal */
if (external >= cexternal) {
ret = gst_util_uint64_scale (external - cexternal, cdenom, cnum);
ret += cinternal;
} else {
ret = gst_util_uint64_scale (cexternal - external, cdenom, cnum);
if (cinternal > ret)
ret = cinternal - ret;
else
ret = 0;
}
return ret;
}
/** /**
* gst_clock_get_internal_time * gst_clock_get_internal_time
* @clock: a #GstClock to query * @clock: a #GstClock to query
@ -874,6 +943,12 @@ gst_clock_set_calibration (GstClock * clock, GstClockTime internal, GstClockTime
g_return_if_fail (internal <= gst_clock_get_internal_time (clock)); g_return_if_fail (internal <= gst_clock_get_internal_time (clock));
GST_OBJECT_LOCK (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->internal_calibration = internal;
clock->external_calibration = external; clock->external_calibration = external;
clock->rate_numerator = rate_num; clock->rate_numerator = rate_num;

View file

@ -477,9 +477,10 @@ gboolean gst_clock_add_observation (GstClock *clock, GstClockTime slave,
GstClockTime master, gdouble *r_squared); GstClockTime master, gdouble *r_squared);
/* getting and adjusting internal time */ /* getting and adjusting internal/external time */
GstClockTime gst_clock_get_internal_time (GstClock *clock); GstClockTime gst_clock_get_internal_time (GstClock *clock);
GstClockTime gst_clock_adjust_unlocked (GstClock *clock, GstClockTime internal); GstClockTime gst_clock_adjust_unlocked (GstClock *clock, GstClockTime internal);
GstClockTime gst_clock_unadjust_unlocked (GstClock * clock, GstClockTime external);
/* creating IDs that can be used to get notifications */ /* creating IDs that can be used to get notifications */