GStreamer consultants will make a lot of money in 2038
[platform/upstream/gstreamer.git] / gst / gstclock.h
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *                    2005 Wim Taymans <wim@fluendo.com>
5  *
6  * gstclock.h: Header for clock subsystem
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 #ifndef __GST_CLOCK_H__
25 #define __GST_CLOCK_H__
26
27 #include <gst/gstobject.h>
28
29 G_BEGIN_DECLS
30
31 /* --- standard type macros --- */
32 #define GST_TYPE_CLOCK                  (gst_clock_get_type ())
33 #define GST_CLOCK(clock)                (G_TYPE_CHECK_INSTANCE_CAST ((clock), GST_TYPE_CLOCK, GstClock))
34 #define GST_IS_CLOCK(clock)             (G_TYPE_CHECK_INSTANCE_TYPE ((clock), GST_TYPE_CLOCK))
35 #define GST_CLOCK_CLASS(cclass)         (G_TYPE_CHECK_CLASS_CAST ((cclass), GST_TYPE_CLOCK, GstClockClass))
36 #define GST_IS_CLOCK_CLASS(cclass)      (G_TYPE_CHECK_CLASS_TYPE ((cclass), GST_TYPE_CLOCK))
37 #define GST_CLOCK_GET_CLASS(clock)      (G_TYPE_INSTANCE_GET_CLASS ((clock), GST_TYPE_CLOCK, GstClockClass))
38 #define GST_CLOCK_CAST(clock)           ((GstClock*)(clock))
39
40 /**
41  * GstClockTime:
42  *
43  * A datatype to hold a time, measured in nanoseconds.
44  */
45 typedef guint64 GstClockTime;
46
47 #define GST_TYPE_CLOCK_TIME G_TYPE_UINT64
48
49 /**
50  * GstClockTimeDiff:
51  *
52  * A datatype to hold a timedifference, measured in nanoseconds.
53  */
54 typedef gint64 GstClockTimeDiff;
55 /**
56  * GstClockID:
57  *
58  * A detatype to hold the handle to an outstanding async clock callback
59  */
60 typedef gpointer GstClockID;
61
62 /**
63  * GST_CLOCK_TIME_NONE:
64  *
65  * Constant to define an undefined clock time
66  */
67 #define GST_CLOCK_TIME_NONE             ((GstClockTime) -1)
68 /**
69  * GST_CLOCK_TIME_IS_VALID:
70  * @time: clock time to validate
71  *
72  * Tests if a given #GstClockTime represents a valid defined time.
73  */
74 #define GST_CLOCK_TIME_IS_VALID(time)   ((time) != GST_CLOCK_TIME_NONE)
75
76 /**
77  * GST_SECOND:
78  *
79  * Constant that defines one GStreamer second
80  */
81 #define GST_SECOND  (G_USEC_PER_SEC * G_GINT64_CONSTANT (1000))
82 /**
83  * GST_MSECOND:
84  *
85  * Constant that defines one GStreamer millisecond
86  */
87 #define GST_MSECOND (GST_SECOND / G_GINT64_CONSTANT (1000))
88 /**
89  * GST_USECOND:
90  *
91  * Constant that defines one GStreamer microsecond
92  */
93 #define GST_USECOND (GST_SECOND / G_GINT64_CONSTANT (1000000))
94 /**
95  * GST_NSECOND:
96  *
97  * Constant that defines one GStreamer nanosecond
98  */
99 #define GST_NSECOND (GST_SECOND / G_GINT64_CONSTANT (1000000000))
100
101 /**
102  * GST_CLOCK_DIFF:
103  * @s: the first time
104  * @e: the second time
105  *
106  * Calculate a difference between two clock times as a #GstClockTimeDiff.
107  */
108 #define GST_CLOCK_DIFF(s, e)            (GstClockTimeDiff)((e) - (s))
109
110 /**
111  * GST_TIMEVAL_TO_TIME:
112  * @tv: the timeval to convert
113  *
114  * Convert a GTimeVal to a #GstClockTime.
115  */
116 #define GST_TIMEVAL_TO_TIME(tv)         ((tv).tv_sec * GST_SECOND + (tv).tv_usec * GST_USECOND)
117
118 /**
119  * GST_TIME_TO_TIMEVAL:
120  * @t: The GstClockTime to convert
121  * @tv: The target timeval
122  *
123  * Note: on 32-bit systems, a timeval has a range of only 2^32 - 1 seconds,
124  * which is about 68 years.  Expect trouble if you want to schedule stuff
125  * in your pipeline for 2038.
126  *
127  * Convert a GstClockTime to a GTimeVal
128  */
129 #define GST_TIME_TO_TIMEVAL(t,tv)                               \
130 G_STMT_START {                                                  \
131   (tv).tv_sec  = ((GstClockTime) (t)) / GST_SECOND;             \
132   (tv).tv_usec = (((GstClockTime) (t)) -                        \
133                   ((GstClockTime) (tv).tv_sec) * GST_SECOND)    \
134                  / GST_USECOND;                                 \
135 } G_STMT_END
136
137 /**
138  * GST_TIMESPEC_TO_TIME:
139  * @ts: the timespec to convert
140  *
141  * Convert a struct timespec (see man pselect) to a #GstClockTime.
142  */
143 #define GST_TIMESPEC_TO_TIME(ts)                ((ts).tv_sec * GST_SECOND + (ts).tv_nsec * GST_NSECOND)
144 /**
145  * GST_TIME_TO_TIMESPEC:
146  * @t: The GstClockTime to convert
147  * @ts: The target timespec
148  *
149  * Convert a #GstClockTime to a struct timespec (see man pselect)
150  */
151 #define GST_TIME_TO_TIMESPEC(t,ts)                      \
152 G_STMT_START {                                          \
153   (ts).tv_sec  =  (t) / GST_SECOND;                     \
154   (ts).tv_nsec = ((t) - (ts).tv_sec * GST_SECOND) / GST_NSECOND;        \
155 } G_STMT_END
156
157 /* timestamp debugging macros */
158 #define GST_TIME_FORMAT "u:%02u:%02u.%09u"
159 #define GST_TIME_ARGS(t) \
160         (guint) (((GstClockTime)(t)) / (GST_SECOND * 60 * 60)), \
161         (guint) ((((GstClockTime)(t)) / (GST_SECOND * 60)) % 60), \
162         (guint) ((((GstClockTime)(t)) / GST_SECOND) % 60), \
163         (guint) (((GstClockTime)(t)) % GST_SECOND)
164
165 /**
166  * GST_CLOCK_ENTRY_TRACE_NAME:
167  *
168  * The name used for tracing clock entry allocations.
169  */
170 #define GST_CLOCK_ENTRY_TRACE_NAME "GstClockEntry"
171
172 typedef struct _GstClockEntry   GstClockEntry;
173 typedef struct _GstClock        GstClock;
174 typedef struct _GstClockClass   GstClockClass;
175
176 /* --- prototype for async callbacks --- */
177 /**
178  * GstClockCallback:
179  * @clock: The clock that triggered the callback
180  * @time: The time it was triggered
181  * @id: The #GstClockID that expired
182  * @user_data: user data passed in the async_wait call
183  *
184  * The function prototype of the callback.
185  *
186  * Returns: %TRUE or %FALSE (currently unused)
187  */
188 typedef gboolean        (*GstClockCallback)     (GstClock *clock, GstClockTime time,
189                                                  GstClockID id, gpointer user_data);
190 /**
191  * GstClockReturn:
192  * @GST_CLOCK_OK: The operation succeded.
193  * @GST_CLOCK_EARLY: The operation was scheduled too late.
194  * @GST_CLOCK_UNSCHEDULED: The clockID was unscheduled
195  * @GST_CLOCK_BUSY: The ClockID is busy
196  * @GST_CLOCK_BADTIME: A bad time was provided to a function.
197  * @GST_CLOCK_ERROR: An error occured
198  * @GST_CLOCK_UNSUPPORTED: Operation is not supported
199  *
200  * The return value of a clock operation.
201  */
202 typedef enum
203 {
204   GST_CLOCK_OK          =  0,
205   GST_CLOCK_EARLY       =  1,
206   GST_CLOCK_UNSCHEDULED =  2,
207   GST_CLOCK_BUSY        =  3,
208   GST_CLOCK_BADTIME     =  4,
209   GST_CLOCK_ERROR       =  5,
210   GST_CLOCK_UNSUPPORTED =  6,
211 } GstClockReturn;
212
213 /**
214  * GstClockEntryType:
215  * @GST_CLOCK_ENTRY_SINGLE: a single shot timeout
216  * @GST_CLOCK_ENTRY_PERIODIC: a periodic timeout request
217  *
218  * The type of the clock entry
219  */
220 typedef enum {
221   GST_CLOCK_ENTRY_SINGLE,
222   GST_CLOCK_ENTRY_PERIODIC
223 } GstClockEntryType;
224
225 /**
226  * GST_CLOCK_ENTRY:
227  * @entry: the entry to cast
228  *
229  * Cast to a clock entry
230  */
231 #define GST_CLOCK_ENTRY(entry)          ((GstClockEntry *)(entry))
232 /**
233  * GST_CLOCK_ENTRY_CLOCK:
234  * @entry: the entry to query
235  *
236  * Get the owner clock of the entry
237  */
238 #define GST_CLOCK_ENTRY_CLOCK(entry)    ((entry)->clock)
239 /**
240  * GST_CLOCK_ENTRY_TYPE:
241  * @entry: the entry to query
242  *
243  * Get the type of the clock entry
244  */
245 #define GST_CLOCK_ENTRY_TYPE(entry)     ((entry)->type)
246 /**
247  * GST_CLOCK_ENTRY_TIME:
248  * @entry: the entry to query
249  *
250  * Get the requested time of this entry
251  */
252 #define GST_CLOCK_ENTRY_TIME(entry)     ((entry)->time)
253 /**
254  * GST_CLOCK_ENTRY_INTERVAL:
255  * @entry: the entry to query
256  *
257  * Get the interval of this periodic entry
258  */
259 #define GST_CLOCK_ENTRY_INTERVAL(entry) ((entry)->interval)
260 /**
261  * GST_CLOCK_ENTRY_STATUS:
262  * @entry: the entry to query
263  *
264  * The status of the entry
265  */
266 #define GST_CLOCK_ENTRY_STATUS(entry)   ((entry)->status)
267
268 /**
269  * GstClockEntry:
270  * @refcount: reference counter (read-only)
271  *
272  * All pending timeouts or periodic notifies are converted into
273  * an entry.
274  */
275 struct _GstClockEntry {
276   gint                  refcount;
277   /*< protected >*/
278   GstClock              *clock;
279   GstClockEntryType      type;
280   GstClockTime           time;
281   GstClockTime           interval;
282   GstClockReturn         status;
283   GstClockCallback       func;
284   gpointer               user_data;
285 };
286
287 /**
288  * GstClockFlags:
289  * @GST_CLOCK_FLAG_CAN_DO_SINGLE_SYNC: clock can do a single sync timeout request
290  * @GST_CLOCK_FLAG_CAN_DO_SINGLE_ASYNC: clock can do a single async timeout request
291  * @GST_CLOCK_FLAG_CAN_DO_PERIODIC_SYNC: clock can do sync periodic timeout requests
292  * @GST_CLOCK_FLAG_CAN_DO_PERIODIC_ASYNC: clock can do async periodic timeout callbacks
293  * @GST_CLOCK_FLAG_CAN_SET_RESOLUTION: clock's resolution can be changed
294  *
295  * The capabilities of this clock
296  */
297 typedef enum {
298   GST_CLOCK_FLAG_CAN_DO_SINGLE_SYNC     = (1 << 1),
299   GST_CLOCK_FLAG_CAN_DO_SINGLE_ASYNC    = (1 << 2),
300   GST_CLOCK_FLAG_CAN_DO_PERIODIC_SYNC   = (1 << 3),
301   GST_CLOCK_FLAG_CAN_DO_PERIODIC_ASYNC  = (1 << 4),
302   GST_CLOCK_FLAG_CAN_SET_RESOLUTION     = (1 << 5),
303 } GstClockFlags;
304
305 /**
306  * GST_CLOCK_FLAGS:
307  * @clock: the clock to query
308  *
309  * Gets the #GstClockFlags clock flags.
310  */
311 #define GST_CLOCK_FLAGS(clock)  (GST_CLOCK(clock)->flags)
312
313 #define GST_CLOCK_COND(clock)            (GST_CLOCK_CAST(clock)->entries_changed)
314 #define GST_CLOCK_WAIT(clock)            g_cond_wait(GST_CLOCK_COND(clock),GST_GET_LOCK(clock))
315 #define GST_CLOCK_TIMED_WAIT(clock,tv)   g_cond_timed_wait(GST_CLOCK_COND(clock),GST_GET_LOCK(clock),tv)
316 #define GST_CLOCK_BROADCAST(clock)       g_cond_broadcast(GST_CLOCK_COND(clock))
317
318 struct _GstClock {
319   GstObject      object;
320
321   /*< public >*/
322   GstClockFlags  flags;
323
324   /*< protected >*/ /* with LOCK */
325   GstClockTime   adjust;
326   GstClockTime   last_time;
327   GList         *entries;
328   GCond         *entries_changed;
329
330   /*< private >*/
331   guint64        resolution;
332   gboolean       stats;
333
334   gpointer _gst_reserved[GST_PADDING];
335 };
336
337 struct _GstClockClass {
338   GstObjectClass        parent_class;
339
340   /*< protected >*/
341   /* vtable */
342   guint64               (*change_resolution)    (GstClock *clock, guint64 old_resolution,
343                                                  guint64 new_resolution);
344   guint64               (*get_resolution)       (GstClock *clock);
345
346   GstClockTime          (*get_internal_time)    (GstClock *clock);
347
348   /* waiting on an ID */
349   GstClockReturn        (*wait)                 (GstClock *clock, GstClockEntry *entry);
350   GstClockReturn        (*wait_async)           (GstClock *clock, GstClockEntry *entry);
351   void                  (*unschedule)           (GstClock *clock, GstClockEntry *entry);
352
353   /*< private >*/
354   gpointer _gst_reserved[GST_PADDING];
355 };
356
357 GType                   gst_clock_get_type              (void);
358
359 guint64                 gst_clock_set_resolution        (GstClock *clock, guint64 resolution);
360 guint64                 gst_clock_get_resolution        (GstClock *clock);
361
362 GstClockTime            gst_clock_get_time              (GstClock *clock);
363 void                    gst_clock_set_time_adjust       (GstClock *clock, GstClockTime adjust);
364
365 GstClockTime            gst_clock_adjust_unlocked       (GstClock *clock, GstClockTime internal);
366
367
368 /* creating IDs that can be used to get notifications */
369 GstClockID              gst_clock_new_single_shot_id    (GstClock *clock,
370                                                          GstClockTime time);
371 GstClockID              gst_clock_new_periodic_id       (GstClock *clock,
372                                                          GstClockTime start_time,
373                                                          GstClockTime interval);
374
375 /* reference counting */
376 GstClockID              gst_clock_id_ref                (GstClockID id);
377 void                    gst_clock_id_unref              (GstClockID id);
378
379 /* operations on IDs */
380 gint                    gst_clock_id_compare_func       (gconstpointer id1, gconstpointer id2);
381
382 GstClockTime            gst_clock_id_get_time           (GstClockID id);
383 GstClockReturn          gst_clock_id_wait               (GstClockID id,
384                                                          GstClockTimeDiff *jitter);
385 GstClockReturn          gst_clock_id_wait_async         (GstClockID id,
386                                                          GstClockCallback func,
387                                                          gpointer user_data);
388 void                    gst_clock_id_unschedule         (GstClockID id);
389
390 G_END_DECLS
391
392 #endif /* __GST_CLOCK_H__ */