First THREADED backport attempt, focusing on adding locks and making sure the API...
[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  *
5  * gstclock.h: Header for clock subsystem
6  *
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.
11  *
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.
16  *
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.
21  */
22
23 #ifndef __GST_CLOCK_H__
24 #define __GST_CLOCK_H__
25
26 #include <gst/gstobject.h>
27
28 G_BEGIN_DECLS
29
30 /* --- standard type macros --- */
31 #define GST_TYPE_CLOCK                  (gst_clock_get_type ())
32 #define GST_CLOCK(clock)                (G_TYPE_CHECK_INSTANCE_CAST ((clock), GST_TYPE_CLOCK, GstClock))
33 #define GST_IS_CLOCK(clock)             (G_TYPE_CHECK_INSTANCE_TYPE ((clock), GST_TYPE_CLOCK))
34 #define GST_CLOCK_CLASS(cclass)         (G_TYPE_CHECK_CLASS_CAST ((cclass), GST_TYPE_CLOCK, GstClockClass))
35 #define GST_IS_CLOCK_CLASS(cclass)      (G_TYPE_CHECK_CLASS_TYPE ((cclass), GST_TYPE_CLOCK))
36 #define GST_CLOCK_GET_CLASS(clock)      (G_TYPE_INSTANCE_GET_CLASS ((clock), GST_TYPE_CLOCK, GstClockClass))
37 #define GST_CLOCK_CAST(clock)           ((GstClock*)(clock))
38         
39 typedef guint64         GstClockTime;
40 typedef gint64          GstClockTimeDiff;
41 typedef gpointer        GstClockID;
42
43 #define GST_CLOCK_TIME_NONE             ((GstClockTime)-1)
44 #define GST_CLOCK_TIME_IS_VALID(time)   ((time) != GST_CLOCK_TIME_NONE)
45
46 #define GST_SECOND  (G_USEC_PER_SEC * G_GINT64_CONSTANT (1000))
47 #define GST_MSECOND (GST_SECOND / G_GINT64_CONSTANT (1000))
48 #define GST_USECOND (GST_SECOND / G_GINT64_CONSTANT (1000000))
49 #define GST_NSECOND (GST_SECOND / G_GINT64_CONSTANT (1000000000))
50
51 #define GST_CLOCK_DIFF(s, e)            (GstClockTimeDiff)((s) - (e))
52 #define GST_TIMEVAL_TO_TIME(tv)         ((tv).tv_sec * GST_SECOND + (tv).tv_usec * GST_USECOND)
53 #define GST_TIME_TO_TIMEVAL(t,tv)                       \
54 G_STMT_START {                                          \
55   (tv).tv_sec  =  (t) / GST_SECOND;                     \
56   (tv).tv_usec = ((t) - (tv).tv_sec * GST_SECOND) / GST_USECOND;        \
57 } G_STMT_END
58
59 #define GST_TIMESPEC_TO_TIME(ts)                ((ts).tv_sec * GST_SECOND + (ts).tv_nsec * GST_NSECOND)
60 #define GST_TIME_TO_TIMESPEC(t,ts)                      \
61 G_STMT_START {                                          \
62   (ts).tv_sec  =  (t) / GST_SECOND;                     \
63   (ts).tv_usec = ((t) - (ts).tv_sec * GST_SECOND) / GST_NSECOND;        \
64 } G_STMT_END
65
66 /* timestamp debugging macros */
67 #define GST_TIME_FORMAT "u:%02u:%02u.%09u"
68 #define GST_TIME_ARGS(t) \
69         (guint) ((t) / (GST_SECOND * 60 * 60)), \
70         (guint) (((t) / (GST_SECOND * 60)) % 60), \
71         (guint) (((t) / GST_SECOND) % 60), \
72         (guint) ((t) % GST_SECOND)
73
74 #define GST_CLOCK_ENTRY_TRACE_NAME "GstClockEntry"
75
76 typedef struct _GstClockEntry   GstClockEntry;
77 typedef struct _GstClock        GstClock;
78 typedef struct _GstClockClass   GstClockClass;
79
80 /* --- prototype for async callbacks --- */
81 typedef gboolean        (*GstClockCallback)     (GstClock *clock, GstClockTime time, 
82                                                  GstClockID id, gpointer user_data);
83
84 typedef enum
85 {
86   GST_CLOCK_OK          =  0,
87   GST_CLOCK_EARLY       =  1,
88   GST_CLOCK_UNSCHEDULED =  2,
89   GST_CLOCK_BUSY        =  3,
90   GST_CLOCK_BADTIME     =  4,
91   GST_CLOCK_ERROR       =  5,
92   GST_CLOCK_UNSUPPORTED =  6,
93 } GstClockReturn;
94
95 typedef enum {
96   GST_CLOCK_ENTRY_SINGLE,
97   GST_CLOCK_ENTRY_PERIODIC
98 } GstClockEntryType;
99
100 #define GST_CLOCK_ENTRY(entry)          ((GstClockEntry *)(entry))
101 #define GST_CLOCK_ENTRY_CLOCK(entry)    ((entry)->clock)
102 #define GST_CLOCK_ENTRY_TYPE(entry)     ((entry)->type)
103 #define GST_CLOCK_ENTRY_TIME(entry)     ((entry)->time)
104 #define GST_CLOCK_ENTRY_INTERVAL(entry) ((entry)->interval)
105 #define GST_CLOCK_ENTRY_STATUS(entry)   ((entry)->status)
106
107 struct _GstClockEntry {
108   GstAtomicInt           refcount;
109   /*< protected >*/
110   GstClock              *clock;
111   GstClockEntryType      type;
112   GstClockTime           time;
113   GstClockTime           interval;
114   GstClockReturn         status;
115   GstClockCallback       func;
116   gpointer               user_data;
117 };
118
119 typedef enum
120 {
121   GST_CLOCK_FLAG_CAN_DO_SINGLE_SYNC     = (1 << 1),
122   GST_CLOCK_FLAG_CAN_DO_SINGLE_ASYNC    = (1 << 2),
123   GST_CLOCK_FLAG_CAN_DO_PERIODIC_SYNC   = (1 << 3),
124   GST_CLOCK_FLAG_CAN_DO_PERIODIC_ASYNC  = (1 << 4),
125   GST_CLOCK_FLAG_CAN_SET_RESOLUTION     = (1 << 5),
126 } GstClockFlags;
127
128 #define GST_CLOCK_FLAGS(clock)  (GST_CLOCK(clock)->flags)
129
130 #define GST_CLOCK_COND(clock)            (GST_CLOCK_CAST(clock)->entries_changed)
131 #define GST_CLOCK_WAIT(clock)            g_cond_wait(GST_CLOCK_COND(clock),GST_GET_LOCK(clock))
132 #define GST_CLOCK_TIMED_WAIT(clock,tv)   g_cond_timed_wait(GST_CLOCK_COND(clock),GST_GET_LOCK(clock),tv)
133 #define GST_CLOCK_SIGNAL(clock)          g_cond_broadcast(GST_CLOCK_COND(clock))
134
135 struct _GstClock {
136   GstObject      object;
137
138   /*< public >*/
139   GstClockFlags  flags;
140
141   /*< protected >*/ /* with LOCK */
142   GstClockTime   adjust;
143   GstClockTime   last_time;
144   GList         *entries;
145   GCond         *entries_changed;
146
147   /*< private >*/
148   guint64        resolution;
149   gboolean       stats;
150
151   gpointer _gst_reserved[GST_PADDING];
152 };
153
154 struct _GstClockClass {
155   GstObjectClass        parent_class;
156
157   /*< protected >*/
158   /* vtable */
159   guint64               (*change_resolution)    (GstClock *clock, guint64 old_resolution,
160                                                  guint64 new_resolution);
161   guint64               (*get_resolution)       (GstClock *clock);
162
163   GstClockTime          (*get_internal_time)    (GstClock *clock);
164
165   /* waiting on an ID */
166   GstClockReturn        (*wait)                 (GstClock *clock, GstClockEntry *entry);
167   GstClockReturn        (*wait_async)           (GstClock *clock, GstClockEntry *entry);
168   void                  (*unschedule)           (GstClock *clock, GstClockEntry *entry);
169   
170   /*< private >*/
171   gpointer _gst_reserved[GST_PADDING];
172 };
173
174 GType                   gst_clock_get_type              (void);
175
176 guint64                 gst_clock_set_resolution        (GstClock *clock, guint64 resolution);
177 guint64                 gst_clock_get_resolution        (GstClock *clock);
178
179 GstClockTime            gst_clock_get_time              (GstClock *clock);
180 void                    gst_clock_set_time_adjust       (GstClock *clock, GstClockTime adjust);
181
182 GstClockTime            gst_clock_adjust_unlocked       (GstClock *clock, GstClockTime internal);
183
184
185 /* creating IDs that can be used to get notifications */
186 GstClockID              gst_clock_new_single_shot_id    (GstClock *clock, 
187                                                          GstClockTime time); 
188 GstClockID              gst_clock_new_periodic_id       (GstClock *clock, 
189                                                          GstClockTime start_time,
190                                                          GstClockTime interval); 
191
192 /* reference counting */
193 GstClockID              gst_clock_id_ref                (GstClockID id);
194 void                    gst_clock_id_unref              (GstClockID id);
195
196 /* operations on IDs */
197 gint                    gst_clock_id_compare_func       (gconstpointer id1, gconstpointer id2);
198
199 GstClockTime            gst_clock_id_get_time           (GstClockID id);
200 GstClockReturn          gst_clock_id_wait               (GstClockID id, 
201                                                          GstClockTimeDiff *jitter);
202 GstClockReturn          gst_clock_id_wait_async         (GstClockID id, 
203                                                          GstClockCallback func, 
204                                                          gpointer user_data);
205 void                    gst_clock_id_unschedule         (GstClockID id);
206
207 G_END_DECLS
208
209 #endif /* __GST_CLOCK_H__ */