2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
5 * gstclock.c: Clock subsystem for maintaining time sync
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
25 //#define GST_DEBUG_ENABLED
26 #include "gst_private.h"
28 #include "gstelement.h"
32 static GstClock *the_system_clock = NULL;
36 * @name: the name of the new clock
38 * create a new clock element
40 * Returns: the new clock element
43 gst_clock_new (gchar *name)
45 GstClock *clock = (GstClock *) g_malloc(sizeof(GstClock));
47 clock->name = g_strdup (name);
48 clock->sinkobjects = NULL;
49 clock->sinkmutex = g_mutex_new ();
50 clock->lock = g_mutex_new ();
51 g_mutex_lock (clock->sinkmutex);
54 clock->num_locked = 0;
55 clock->locking = FALSE;
61 gst_clock_get_system(void)
63 if (the_system_clock == NULL) {
64 the_system_clock = gst_clock_new ("system_clock");
65 gst_clock_reset (the_system_clock);
67 return the_system_clock;
71 gst_clock_register (GstClock *clock, GstObject *obj)
73 if ((GST_ELEMENT(obj))->numsrcpads == 0) {
74 GST_DEBUG (0,"gst_clock: setting registered sink object 0x%p\n", obj);
75 clock->sinkobjects = g_list_append (clock->sinkobjects, obj);
81 gst_clock_set (GstClock *clock, GstClockTime time)
86 gettimeofday (&tfnow, (struct timezone *)NULL);
87 now = tfnow.tv_sec*1000000LL+tfnow.tv_usec;
88 g_mutex_lock (clock->lock);
89 clock->start_time = now - time;
90 g_mutex_unlock (clock->lock);
91 GST_DEBUG (0,"gst_clock: setting clock to %llu %llu %llu\n", time, now, clock->start_time);
95 gst_clock_current_diff (GstClock *clock, GstClockTime time)
100 gettimeofday (&tfnow, (struct timezone *)NULL);
101 g_mutex_lock (clock->lock);
102 now = ((guint64)tfnow.tv_sec*1000000LL+tfnow.tv_usec) - (guint64)clock->start_time;
103 g_mutex_unlock (clock->lock);
105 return GST_CLOCK_DIFF (time, now);
109 gst_clock_reset (GstClock *clock)
111 struct timeval tfnow;
113 gettimeofday (&tfnow, (struct timezone *)NULL);
114 g_mutex_lock (clock->lock);
115 clock->start_time = ((guint64)tfnow.tv_sec)*1000000LL+tfnow.tv_usec;
116 clock->current_time = clock->start_time;
118 GST_DEBUG (0,"gst_clock: setting start clock %llu\n", clock->start_time);
119 g_mutex_unlock (clock->lock);
123 gst_clock_wait (GstClock *clock, GstClockTime time, GstObject *obj)
125 struct timeval tfnow;
127 GstClockTimeDiff diff;
130 gettimeofday (&tfnow, (struct timezone *)NULL);
131 g_mutex_lock (clock->lock);
132 now = tfnow.tv_sec*1000000LL+tfnow.tv_usec - clock->start_time;
134 diff = GST_CLOCK_DIFF (time, now);
135 // if we are not behind wait a bit
136 GST_DEBUG (0,"gst_clock: %s waiting for time %08llu %08llu %08lld\n", gst_element_get_name(GST_ELEMENT(obj)), time, now, diff);
138 g_mutex_unlock (clock->lock);
140 tfnow.tv_usec = (diff % 1000000);
141 tfnow.tv_sec = diff / 1000000;
142 // FIXME, this piece of code does not work with egcs optimisations on, had to use the following line
144 select(0, NULL, NULL, NULL, &tfnow);
146 else GST_DEBUG (0,"gst_clock: %s waiting %u %llu %llu %llu seconds\n", gst_element_get_name(GST_ELEMENT(obj)),
147 (int)tfnow.tv_sec, now, diff, time);
149 GST_DEBUG (0,"gst_clock: %s waiting for time %08llu %08llu %08lld done \n", gst_element_get_name(GST_ELEMENT(obj)), time, now, diff);