gstutils: Add helpers to get/set array properties
[platform/upstream/gstreamer.git] / gst / gstutils.h
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *                    2002 Thomas Vander Stichele <thomas@apestaart.org>
5  *
6  * gstutils.h: Header for various utility functions
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., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23
24
25 #ifndef __GST_UTILS_H__
26 #define __GST_UTILS_H__
27
28 #include <glib.h>
29 #include <gst/gstconfig.h>
30 #include <gst/gstbin.h>
31 #include <gst/gstparse.h>
32
33 G_BEGIN_DECLS
34
35 void            gst_util_set_value_from_string  (GValue *value, const gchar *value_str);
36 void            gst_util_set_object_arg         (GObject *object, const gchar *name, const gchar *value);
37 gboolean        gst_util_set_object_array       (GObject * object, const gchar * name,
38                                                  const GValueArray * array);
39 gboolean        gst_util_get_object_array       (GObject * object, const gchar * name,
40                                                  GValueArray ** array);
41 void            gst_util_dump_mem               (const guchar *mem, guint size);
42
43 guint64         gst_util_gdouble_to_guint64     (gdouble value)  G_GNUC_CONST;
44 gdouble         gst_util_guint64_to_gdouble     (guint64 value)  G_GNUC_CONST;
45
46 /**
47  * gst_guint64_to_gdouble:
48  * @value: the #guint64 value to convert
49  *
50  * Convert @value to a gdouble.
51  *
52  * Returns: @value converted to a #gdouble.
53  */
54
55 /**
56  * gst_gdouble_to_guint64:
57  * @value: the #gdouble value to convert
58  *
59  * Convert @value to a guint64.
60  *
61  * Returns: @value converted to a #guint64.
62  */
63 #ifdef WIN32
64 #define         gst_gdouble_to_guint64(value)   gst_util_gdouble_to_guint64(value)
65 #define         gst_guint64_to_gdouble(value)   gst_util_guint64_to_gdouble(value)
66 #else
67 #define         gst_gdouble_to_guint64(value)   ((guint64) (value))
68 #define         gst_guint64_to_gdouble(value)   ((gdouble) (value))
69 #endif
70
71 guint64         gst_util_uint64_scale           (guint64 val, guint64 num, guint64 denom);
72 guint64         gst_util_uint64_scale_round     (guint64 val, guint64 num, guint64 denom);
73 guint64         gst_util_uint64_scale_ceil      (guint64 val, guint64 num, guint64 denom);
74
75 guint64         gst_util_uint64_scale_int       (guint64 val, gint num, gint denom);
76 guint64         gst_util_uint64_scale_int_round (guint64 val, gint num, gint denom);
77 guint64         gst_util_uint64_scale_int_ceil  (guint64 val, gint num, gint denom);
78
79 guint32         gst_util_seqnum_next            (void);
80 gint32          gst_util_seqnum_compare         (guint32 s1, guint32 s2);
81
82 guint           gst_util_group_id_next          (void);
83
84 /**
85  * GST_CALL_PARENT:
86  * @parent_class_cast: the name of the class cast macro for the parent type
87  * @name: name of the function to call
88  * @args: arguments enclosed in '( )'
89  *
90  * Just call the parent handler.  This assumes that there is a variable
91  * named parent_class that points to the (duh!) parent class.  Note that
92  * this macro is not to be used with things that return something, use
93  * the _WITH_DEFAULT version for that
94  */
95 #define GST_CALL_PARENT(parent_class_cast, name, args)                  \
96         ((parent_class_cast(parent_class)->name != NULL) ?              \
97          parent_class_cast(parent_class)->name args : (void) 0)
98
99 /**
100  * GST_CALL_PARENT_WITH_DEFAULT:
101  * @parent_class_cast: the name of the class cast macro for the parent type
102  * @name: name of the function to call
103  * @args: arguments enclosed in '( )'
104  * @def_return: default result
105  *
106  * Same as GST_CALL_PARENT(), but in case there is no implementation, it
107  * evaluates to @def_return.
108  */
109 #define GST_CALL_PARENT_WITH_DEFAULT(parent_class_cast, name, args, def_return)\
110         ((parent_class_cast(parent_class)->name != NULL) ?              \
111          parent_class_cast(parent_class)->name args : def_return)
112
113 /* Define PUT and GET functions for unaligned memory */
114 #define _GST_GET(__data, __idx, __size, __shift) \
115     (((guint##__size) (((const guint8 *) (__data))[__idx])) << (__shift))
116
117 #define _GST_PUT(__data, __idx, __size, __shift, __num) \
118     (((guint8 *) (__data))[__idx] = (((guint##__size) (__num)) >> (__shift)) & 0xff)
119
120 #ifndef __GTK_DOC_IGNORE__
121 #if GST_HAVE_UNALIGNED_ACCESS
122 static inline guint16 __gst_fast_read16(const guint8 *v) {
123   return *(const guint16*)(const void*)(v);
124 }
125 static inline guint32 __gst_fast_read32(const guint8 *v) {
126   return *(const guint32*)(const void*)(v);
127 }
128 static inline guint64 __gst_fast_read64(const guint8 *v) {
129   return *(const guint64*)(const void*)(v);
130 }
131 static inline guint16 __gst_fast_read_swap16(const guint8 *v) {
132   return GUINT16_SWAP_LE_BE(*(const guint16*)(const void*)(v));
133 }
134 static inline guint32 __gst_fast_read_swap32(const guint8 *v) {
135   return GUINT32_SWAP_LE_BE(*(const guint32*)(const void*)(v));
136 }
137 static inline guint64 __gst_fast_read_swap64(const guint8 *v) {
138   return GUINT64_SWAP_LE_BE(*(const guint64*)(const void*)(v));
139 }
140 # define _GST_FAST_READ(s, d) __gst_fast_read##s((const guint8 *)(d))
141 # define _GST_FAST_READ_SWAP(s, d) __gst_fast_read_swap##s((const guint8 *)(d))
142
143 static inline void __gst_fast_write16 (guint8 *p, guint16 v) {
144   *(guint16*)(void*)(p) = v;
145 }
146 static inline void __gst_fast_write32 (guint8 *p, guint32 v) {
147   *(guint32*)(void*)(p) = v;
148 }
149 static inline void __gst_fast_write64 (guint8 *p, guint64 v) {
150   *(guint64*)(void*)(p) = v;
151 }
152 static inline void __gst_fast_write_swap16 (guint8 *p, guint16 v) {
153   *(guint16*)(void*)(p) = GUINT16_SWAP_LE_BE (v);
154 }
155 static inline void __gst_fast_write_swap32 (guint8 *p, guint32 v) {
156   *(guint32*)(void*)(p) = GUINT32_SWAP_LE_BE (v);
157 }
158 static inline void __gst_fast_write_swap64 (guint8 *p, guint64 v) {
159   *(guint64*)(void*)(p) = GUINT64_SWAP_LE_BE (v);
160 }
161 # define _GST_FAST_WRITE(s, d, v) __gst_fast_write##s((guint8 *)(d), (v))
162 # define _GST_FAST_WRITE_SWAP(s, d, v) __gst_fast_write_swap##s((guint8 *)(d), (v))
163 #endif
164 #endif
165
166
167 /**
168  * GST_READ_UINT64_BE:
169  * @data: memory location
170  *
171  * Read a 64 bit unsigned integer value in big endian format from the memory buffer.
172  */
173
174 /**
175  * GST_READ_UINT64_LE:
176  * @data: memory location
177  *
178  * Read a 64 bit unsigned integer value in little endian format from the memory buffer.
179  */
180 #if GST_HAVE_UNALIGNED_ACCESS
181 # if (G_BYTE_ORDER == G_BIG_ENDIAN)
182 #  define GST_READ_UINT64_BE(data)      _GST_FAST_READ (64, data)
183 #  define GST_READ_UINT64_LE(data)      _GST_FAST_READ_SWAP (64, data)
184 # else
185 #  define GST_READ_UINT64_BE(data)      _GST_FAST_READ_SWAP (64, data)
186 #  define GST_READ_UINT64_LE(data)      _GST_FAST_READ (64, data)
187 # endif
188 #else
189 #define _GST_READ_UINT64_BE(data)       (_GST_GET (data, 0, 64, 56) | \
190                                          _GST_GET (data, 1, 64, 48) | \
191                                          _GST_GET (data, 2, 64, 40) | \
192                                          _GST_GET (data, 3, 64, 32) | \
193                                          _GST_GET (data, 4, 64, 24) | \
194                                          _GST_GET (data, 5, 64, 16) | \
195                                          _GST_GET (data, 6, 64,  8) | \
196                                          _GST_GET (data, 7, 64,  0))
197
198 #define _GST_READ_UINT64_LE(data)       (_GST_GET (data, 7, 64, 56) | \
199                                          _GST_GET (data, 6, 64, 48) | \
200                                          _GST_GET (data, 5, 64, 40) | \
201                                          _GST_GET (data, 4, 64, 32) | \
202                                          _GST_GET (data, 3, 64, 24) | \
203                                          _GST_GET (data, 2, 64, 16) | \
204                                          _GST_GET (data, 1, 64,  8) | \
205                                          _GST_GET (data, 0, 64,  0))
206
207 #define GST_READ_UINT64_BE(data) __gst_slow_read64_be((const guint8 *)(data))
208 static inline guint64 __gst_slow_read64_be (const guint8 * data) {
209   return _GST_READ_UINT64_BE (data);
210 }
211 #define GST_READ_UINT64_LE(data) __gst_slow_read64_le((const guint8 *)(data))
212 static inline guint64 __gst_slow_read64_le (const guint8 * data) {
213   return _GST_READ_UINT64_LE (data);
214 }
215 #endif
216
217 /**
218  * GST_READ_UINT32_BE:
219  * @data: memory location
220  *
221  * Read a 32 bit unsigned integer value in big endian format from the memory buffer.
222  */
223
224 /**
225  * GST_READ_UINT32_LE:
226  * @data: memory location
227  *
228  * Read a 32 bit unsigned integer value in little endian format from the memory buffer.
229  */
230 #if GST_HAVE_UNALIGNED_ACCESS
231 # if (G_BYTE_ORDER == G_BIG_ENDIAN)
232 #  define GST_READ_UINT32_BE(data)      _GST_FAST_READ (32, data)
233 #  define GST_READ_UINT32_LE(data)      _GST_FAST_READ_SWAP (32, data)
234 # else
235 #  define GST_READ_UINT32_BE(data)      _GST_FAST_READ_SWAP (32, data)
236 #  define GST_READ_UINT32_LE(data)      _GST_FAST_READ (32, data)
237 # endif
238 #else
239 #define _GST_READ_UINT32_BE(data)       (_GST_GET (data, 0, 32, 24) | \
240                                          _GST_GET (data, 1, 32, 16) | \
241                                          _GST_GET (data, 2, 32,  8) | \
242                                          _GST_GET (data, 3, 32,  0))
243
244 #define _GST_READ_UINT32_LE(data)       (_GST_GET (data, 3, 32, 24) | \
245                                          _GST_GET (data, 2, 32, 16) | \
246                                          _GST_GET (data, 1, 32,  8) | \
247                                          _GST_GET (data, 0, 32,  0))
248
249 #define GST_READ_UINT32_BE(data) __gst_slow_read32_be((const guint8 *)(data))
250 static inline guint32 __gst_slow_read32_be (const guint8 * data) {
251   return _GST_READ_UINT32_BE (data);
252 }
253 #define GST_READ_UINT32_LE(data) __gst_slow_read32_le((const guint8 *)(data))
254 static inline guint32 __gst_slow_read32_le (const guint8 * data) {
255   return _GST_READ_UINT32_LE (data);
256 }
257 #endif
258
259 /**
260  * GST_READ_UINT24_BE:
261  * @data: memory location
262  *
263  * Read a 24 bit unsigned integer value in big endian format from the memory buffer.
264  */
265 #define _GST_READ_UINT24_BE(data)       (_GST_GET (data, 0, 32, 16) | \
266                                          _GST_GET (data, 1, 32,  8) | \
267                                          _GST_GET (data, 2, 32,  0))
268
269 #define GST_READ_UINT24_BE(data) __gst_slow_read24_be((const guint8 *)(data))
270 static inline guint32 __gst_slow_read24_be (const guint8 * data) {
271   return _GST_READ_UINT24_BE (data);
272 }
273
274 /**
275  * GST_READ_UINT24_LE:
276  * @data: memory location
277  *
278  * Read a 24 bit unsigned integer value in little endian format from the memory buffer.
279  */
280 #define _GST_READ_UINT24_LE(data)       (_GST_GET (data, 2, 32, 16) | \
281                                          _GST_GET (data, 1, 32,  8) | \
282                                          _GST_GET (data, 0, 32,  0))
283
284 #define GST_READ_UINT24_LE(data) __gst_slow_read24_le((const guint8 *)(data))
285 static inline guint32 __gst_slow_read24_le (const guint8 * data) {
286   return _GST_READ_UINT24_LE (data);
287 }
288
289 /**
290  * GST_READ_UINT16_BE:
291  * @data: memory location
292  *
293  * Read a 16 bit unsigned integer value in big endian format from the memory buffer.
294  */
295 /**
296  * GST_READ_UINT16_LE:
297  * @data: memory location
298  *
299  * Read a 16 bit unsigned integer value in little endian format from the memory buffer.
300  */
301 #if GST_HAVE_UNALIGNED_ACCESS
302 # if (G_BYTE_ORDER == G_BIG_ENDIAN)
303 #  define GST_READ_UINT16_BE(data)      _GST_FAST_READ (16, data)
304 #  define GST_READ_UINT16_LE(data)      _GST_FAST_READ_SWAP (16, data)
305 # else
306 #  define GST_READ_UINT16_BE(data)      _GST_FAST_READ_SWAP (16, data)
307 #  define GST_READ_UINT16_LE(data)      _GST_FAST_READ (16, data)
308 # endif
309 #else
310 #define _GST_READ_UINT16_BE(data)       (_GST_GET (data, 0, 16,  8) | \
311                                          _GST_GET (data, 1, 16,  0))
312
313 #define _GST_READ_UINT16_LE(data)       (_GST_GET (data, 1, 16,  8) | \
314                                          _GST_GET (data, 0, 16,  0))
315
316 #define GST_READ_UINT16_BE(data) __gst_slow_read16_be((const guint8 *)(data))
317 static inline guint16 __gst_slow_read16_be (const guint8 * data) {
318   return _GST_READ_UINT16_BE (data);
319 }
320 #define GST_READ_UINT16_LE(data) __gst_slow_read16_le((const guint8 *)(data))
321 static inline guint16 __gst_slow_read16_le (const guint8 * data) {
322   return _GST_READ_UINT16_LE (data);
323 }
324 #endif
325
326 /**
327  * GST_READ_UINT8:
328  * @data: memory location
329  *
330  * Read an 8 bit unsigned integer value from the memory buffer.
331  */
332 #define GST_READ_UINT8(data)            (_GST_GET (data, 0,  8,  0))
333
334 /**
335  * GST_WRITE_UINT64_BE:
336  * @data: memory location
337  * @val: value to store
338  *
339  * Store a 64 bit unsigned integer value in big endian format into the memory buffer.
340  */
341 /**
342  * GST_WRITE_UINT64_LE:
343  * @data: memory location
344  * @val: value to store
345  *
346  * Store a 64 bit unsigned integer value in little endian format into the memory buffer.
347  */
348 #if GST_HAVE_UNALIGNED_ACCESS
349 # if (G_BYTE_ORDER == G_BIG_ENDIAN)
350 #  define GST_WRITE_UINT64_BE(data,val) _GST_FAST_WRITE(64,data,val)
351 #  define GST_WRITE_UINT64_LE(data,val) _GST_FAST_WRITE_SWAP(64,data,val)
352 # else
353 #  define GST_WRITE_UINT64_BE(data,val) _GST_FAST_WRITE_SWAP(64,data,val)
354 #  define GST_WRITE_UINT64_LE(data,val) _GST_FAST_WRITE(64,data,val)
355 # endif
356 #else
357 #define GST_WRITE_UINT64_BE(data,val)   do { \
358                                           gpointer __put_data = data; \
359                                           guint64 __put_val = val; \
360                                           _GST_PUT (__put_data, 0, 64, 56, __put_val); \
361                                           _GST_PUT (__put_data, 1, 64, 48, __put_val); \
362                                           _GST_PUT (__put_data, 2, 64, 40, __put_val); \
363                                           _GST_PUT (__put_data, 3, 64, 32, __put_val); \
364                                           _GST_PUT (__put_data, 4, 64, 24, __put_val); \
365                                           _GST_PUT (__put_data, 5, 64, 16, __put_val); \
366                                           _GST_PUT (__put_data, 6, 64,  8, __put_val); \
367                                           _GST_PUT (__put_data, 7, 64,  0, __put_val); \
368                                         } while (0)
369
370 #define GST_WRITE_UINT64_LE(data,val)   do { \
371                                           gpointer __put_data = data; \
372                                           guint64 __put_val = val; \
373                                           _GST_PUT (__put_data, 0, 64,  0, __put_val); \
374                                           _GST_PUT (__put_data, 1, 64,  8, __put_val); \
375                                           _GST_PUT (__put_data, 2, 64, 16, __put_val); \
376                                           _GST_PUT (__put_data, 3, 64, 24, __put_val); \
377                                           _GST_PUT (__put_data, 4, 64, 32, __put_val); \
378                                           _GST_PUT (__put_data, 5, 64, 40, __put_val); \
379                                           _GST_PUT (__put_data, 6, 64, 48, __put_val); \
380                                           _GST_PUT (__put_data, 7, 64, 56, __put_val); \
381                                         } while (0)
382 #endif /* !GST_HAVE_UNALIGNED_ACCESS */
383
384 /**
385  * GST_WRITE_UINT32_BE:
386  * @data: memory location
387  * @val: value to store
388  *
389  * Store a 32 bit unsigned integer value in big endian format into the memory buffer.
390  */
391 /**
392  * GST_WRITE_UINT32_LE:
393  * @data: memory location
394  * @val: value to store
395  *
396  * Store a 32 bit unsigned integer value in little endian format into the memory buffer.
397  */
398 #if GST_HAVE_UNALIGNED_ACCESS
399 # if (G_BYTE_ORDER == G_BIG_ENDIAN)
400 #  define GST_WRITE_UINT32_BE(data,val) _GST_FAST_WRITE(32,data,val)
401 #  define GST_WRITE_UINT32_LE(data,val) _GST_FAST_WRITE_SWAP(32,data,val)
402 # else
403 #  define GST_WRITE_UINT32_BE(data,val) _GST_FAST_WRITE_SWAP(32,data,val)
404 #  define GST_WRITE_UINT32_LE(data,val) _GST_FAST_WRITE(32,data,val)
405 # endif
406 #else
407 #define GST_WRITE_UINT32_BE(data,val)   do { \
408                                           gpointer __put_data = data; \
409                                           guint32 __put_val = val; \
410                                           _GST_PUT (__put_data, 0, 32, 24, __put_val); \
411                                           _GST_PUT (__put_data, 1, 32, 16, __put_val); \
412                                           _GST_PUT (__put_data, 2, 32,  8, __put_val); \
413                                           _GST_PUT (__put_data, 3, 32,  0, __put_val); \
414                                         } while (0)
415
416 #define GST_WRITE_UINT32_LE(data,val)   do { \
417                                           gpointer __put_data = data; \
418                                           guint32 __put_val = val; \
419                                           _GST_PUT (__put_data, 0, 32,  0, __put_val); \
420                                           _GST_PUT (__put_data, 1, 32,  8, __put_val); \
421                                           _GST_PUT (__put_data, 2, 32, 16, __put_val); \
422                                           _GST_PUT (__put_data, 3, 32, 24, __put_val); \
423                                         } while (0)
424 #endif /* !GST_HAVE_UNALIGNED_ACCESS */
425
426 /**
427  * GST_WRITE_UINT24_BE:
428  * @data: memory location
429  * @num: value to store
430  *
431  * Store a 24 bit unsigned integer value in big endian format into the memory buffer.
432  */
433 #define GST_WRITE_UINT24_BE(data, num)  do { \
434                                           gpointer __put_data = data; \
435                                           guint32 __put_val = num; \
436                                           _GST_PUT (__put_data, 0, 32,  16, __put_val); \
437                                           _GST_PUT (__put_data, 1, 32,  8, __put_val); \
438                                           _GST_PUT (__put_data, 2, 32,  0, __put_val); \
439                                         } while (0)
440
441 /**
442  * GST_WRITE_UINT24_LE:
443  * @data: memory location
444  * @num: value to store
445  *
446  * Store a 24 bit unsigned integer value in little endian format into the memory buffer.
447  */
448 #define GST_WRITE_UINT24_LE(data, num)  do { \
449                                           gpointer __put_data = data; \
450                                           guint32 __put_val = num; \
451                                           _GST_PUT (__put_data, 0, 32,  0, __put_val); \
452                                           _GST_PUT (__put_data, 1, 32,  8, __put_val); \
453                                           _GST_PUT (__put_data, 2, 32,  16, __put_val); \
454                                         } while (0)
455
456 /**
457  * GST_WRITE_UINT16_BE:
458  * @data: memory location
459  * @val: value to store
460  *
461  * Store a 16 bit unsigned integer value in big endian format into the memory buffer.
462  */
463 /**
464  * GST_WRITE_UINT16_LE:
465  * @data: memory location
466  * @val: value to store
467  *
468  * Store a 16 bit unsigned integer value in little endian format into the memory buffer.
469  */
470 #if GST_HAVE_UNALIGNED_ACCESS
471 # if (G_BYTE_ORDER == G_BIG_ENDIAN)
472 #  define GST_WRITE_UINT16_BE(data,val) _GST_FAST_WRITE(16,data,val)
473 #  define GST_WRITE_UINT16_LE(data,val) _GST_FAST_WRITE_SWAP(16,data,val)
474 # else
475 #  define GST_WRITE_UINT16_BE(data,val) _GST_FAST_WRITE_SWAP(16,data,val)
476 #  define GST_WRITE_UINT16_LE(data,val) _GST_FAST_WRITE(16,data,val)
477 # endif
478 #else
479 #define GST_WRITE_UINT16_BE(data,val)   do { \
480                                           gpointer __put_data = data; \
481                                           guint16 __put_val = val; \
482                                           _GST_PUT (__put_data, 0, 16,  8, __put_val); \
483                                           _GST_PUT (__put_data, 1, 16,  0, __put_val); \
484                                         } while (0)
485
486 #define GST_WRITE_UINT16_LE(data,val)   do { \
487                                           gpointer __put_data = data; \
488                                           guint16 __put_val = val; \
489                                           _GST_PUT (__put_data, 0, 16,  0, __put_val); \
490                                           _GST_PUT (__put_data, 1, 16,  8, __put_val); \
491                                         } while (0)
492 #endif /* !GST_HAVE_UNALIGNED_ACCESS */
493
494 /**
495  * GST_WRITE_UINT8:
496  * @data: memory location
497  * @num: value to store
498  *
499  * Store an 8 bit unsigned integer value into the memory buffer.
500  */
501 #define GST_WRITE_UINT8(data, num)      do { \
502                                           _GST_PUT (data, 0,  8,  0, num); \
503                                         } while (0)
504
505 /* Float endianness conversion macros */
506
507 /* FIXME: Remove this once we depend on a GLib version with this */
508 #ifndef GFLOAT_FROM_LE
509 /**
510  * GFLOAT_SWAP_LE_BE:
511  * @in: input value
512  *
513  * Swap byte order of a 32-bit floating point value (float).
514  *
515  * Returns: @in byte-swapped.
516  */
517 static inline gfloat
518 GFLOAT_SWAP_LE_BE(gfloat in)
519 {
520   union
521   {
522     guint32 i;
523     gfloat f;
524   } u;
525
526   u.f = in;
527   u.i = GUINT32_SWAP_LE_BE (u.i);
528   return u.f;
529 }
530
531 /**
532  * GDOUBLE_SWAP_LE_BE:
533  * @in: input value
534  *
535  * Swap byte order of a 64-bit floating point value (double).
536  *
537  * Returns: @in byte-swapped.
538  */
539 static inline gdouble
540 GDOUBLE_SWAP_LE_BE(gdouble in)
541 {
542   union
543   {
544     guint64 i;
545     gdouble d;
546   } u;
547
548   u.d = in;
549   u.i = GUINT64_SWAP_LE_BE (u.i);
550   return u.d;
551 }
552
553 /**
554  * GDOUBLE_TO_LE:
555  * @val: value
556  *
557  * Convert 64-bit floating point value (double) from native byte order into
558  * little endian byte order.
559  */
560 /**
561  * GDOUBLE_TO_BE:
562  * @val: value
563  *
564  * Convert 64-bit floating point value (double) from native byte order into
565  * big endian byte order.
566  */
567 /**
568  * GDOUBLE_FROM_LE:
569  * @val: value
570  *
571  * Convert 64-bit floating point value (double) from little endian byte order
572  * into native byte order.
573  */
574 /**
575  * GDOUBLE_FROM_BE:
576  * @val: value
577  *
578  * Convert 64-bit floating point value (double) from big endian byte order
579  * into native byte order.
580  */
581
582 /**
583  * GFLOAT_TO_LE:
584  * @val: value
585  *
586  * Convert 32-bit floating point value (float) from native byte order into
587  * little endian byte order.
588  */
589 /**
590  * GFLOAT_TO_BE:
591  * @val: value
592  *
593  * Convert 32-bit floating point value (float) from native byte order into
594  * big endian byte order.
595  */
596 /**
597  * GFLOAT_FROM_LE:
598  * @val: value
599  *
600  * Convert 32-bit floating point value (float) from little endian byte order
601  * into native byte order.
602  */
603 /**
604  * GFLOAT_FROM_BE:
605  * @val: value
606  *
607  * Convert 32-bit floating point value (float) from big endian byte order
608  * into native byte order.
609  */
610
611 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
612 #define GFLOAT_TO_LE(val)    ((gfloat) (val))
613 #define GFLOAT_TO_BE(val)    (GFLOAT_SWAP_LE_BE (val))
614 #define GDOUBLE_TO_LE(val)   ((gdouble) (val))
615 #define GDOUBLE_TO_BE(val)   (GDOUBLE_SWAP_LE_BE (val))
616
617 #elif G_BYTE_ORDER == G_BIG_ENDIAN
618 #define GFLOAT_TO_LE(val)    (GFLOAT_SWAP_LE_BE (val))
619 #define GFLOAT_TO_BE(val)    ((gfloat) (val))
620 #define GDOUBLE_TO_LE(val)   (GDOUBLE_SWAP_LE_BE (val))
621 #define GDOUBLE_TO_BE(val)   ((gdouble) (val))
622
623 #else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
624 #error unknown ENDIAN type
625 #endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
626
627 #define GFLOAT_FROM_LE(val)  (GFLOAT_TO_LE (val))
628 #define GFLOAT_FROM_BE(val)  (GFLOAT_TO_BE (val))
629 #define GDOUBLE_FROM_LE(val) (GDOUBLE_TO_LE (val))
630 #define GDOUBLE_FROM_BE(val) (GDOUBLE_TO_BE (val))
631
632 #endif /* !defined(GFLOAT_FROM_LE) */
633
634 /**
635  * GST_READ_FLOAT_LE:
636  * @data: memory location
637  *
638  * Read a 32 bit float value in little endian format from the memory buffer.
639  *
640  * Returns: The floating point value read from @data
641  */
642 static inline gfloat
643 GST_READ_FLOAT_LE(const guint8 *data)
644 {
645   union
646   {
647     guint32 i;
648     gfloat f;
649   } u;
650
651   u.i = GST_READ_UINT32_LE (data);
652   return u.f;
653 }
654
655 /**
656  * GST_READ_FLOAT_BE:
657  * @data: memory location
658  *
659  * Read a 32 bit float value in big endian format from the memory buffer.
660  *
661  * Returns: The floating point value read from @data
662  */
663 static inline gfloat
664 GST_READ_FLOAT_BE(const guint8 *data)
665 {
666   union
667   {
668     guint32 i;
669     gfloat f;
670   } u;
671
672   u.i = GST_READ_UINT32_BE (data);
673   return u.f;
674 }
675
676 /**
677  * GST_READ_DOUBLE_LE:
678  * @data: memory location
679  *
680  * Read a 64 bit double value in little endian format from the memory buffer.
681  *
682  * Returns: The double-precision floating point value read from @data
683  */
684 static inline gdouble
685 GST_READ_DOUBLE_LE(const guint8 *data)
686 {
687   union
688   {
689     guint64 i;
690     gdouble d;
691   } u;
692
693   u.i = GST_READ_UINT64_LE (data);
694   return u.d;
695 }
696
697 /**
698  * GST_READ_DOUBLE_BE:
699  * @data: memory location
700  *
701  * Read a 64 bit double value in big endian format from the memory buffer.
702  *
703  * Returns: The double-precision floating point value read from @data
704  */
705 static inline gdouble
706 GST_READ_DOUBLE_BE(const guint8 *data)
707 {
708   union
709   {
710     guint64 i;
711     gdouble d;
712   } u;
713
714   u.i = GST_READ_UINT64_BE (data);
715   return u.d;
716 }
717
718 /**
719  * GST_WRITE_FLOAT_LE:
720  * @data: memory location
721  * @num: value to store
722  *
723  * Store a 32 bit float value in little endian format into the memory buffer.
724  */
725 static inline void
726 GST_WRITE_FLOAT_LE(guint8 *data, gfloat num)
727 {
728   union
729   {
730     guint32 i;
731     gfloat f;
732   } u;
733
734   u.f = num;
735   GST_WRITE_UINT32_LE (data, u.i);
736 }
737
738 /**
739  * GST_WRITE_FLOAT_BE:
740  * @data: memory location
741  * @num: value to store
742  *
743  * Store a 32 bit float value in big endian format into the memory buffer.
744  */
745 static inline void
746 GST_WRITE_FLOAT_BE(guint8 *data, gfloat num)
747 {
748   union
749   {
750     guint32 i;
751     gfloat f;
752   } u;
753
754   u.f = num;
755   GST_WRITE_UINT32_BE (data, u.i);
756 }
757
758 /**
759  * GST_WRITE_DOUBLE_LE:
760  * @data: memory location
761  * @num: value to store
762  *
763  * Store a 64 bit double value in little endian format into the memory buffer.
764  */
765 static inline void
766 GST_WRITE_DOUBLE_LE(guint8 *data, gdouble num)
767 {
768   union
769   {
770     guint64 i;
771     gdouble d;
772   } u;
773
774   u.d = num;
775   GST_WRITE_UINT64_LE (data, u.i);
776 }
777
778 /**
779  * GST_WRITE_DOUBLE_BE:
780  * @data: memory location
781  * @num: value to store
782  *
783  * Store a 64 bit double value in big endian format into the memory buffer.
784  */
785 static inline void
786 GST_WRITE_DOUBLE_BE(guint8 *data, gdouble num)
787 {
788   union
789   {
790     guint64 i;
791     gdouble d;
792   } u;
793
794   u.d = num;
795   GST_WRITE_UINT64_BE (data, u.i);
796 }
797
798 /* Miscellaneous utility macros */
799
800 /**
801  * GST_ROUND_UP_2:
802  * @num: integer value to round up
803  *
804  * Rounds an integer value up to the next multiple of 2.
805  */
806 #define GST_ROUND_UP_2(num)  (((num)+1)&~1)
807 /**
808  * GST_ROUND_UP_4:
809  * @num: integer value to round up
810  *
811  * Rounds an integer value up to the next multiple of 4.
812  */
813 #define GST_ROUND_UP_4(num)  (((num)+3)&~3)
814 /**
815  * GST_ROUND_UP_8:
816  * @num: integer value to round up
817  *
818  * Rounds an integer value up to the next multiple of 8.
819  */
820 #define GST_ROUND_UP_8(num)  (((num)+7)&~7)
821 /**
822  * GST_ROUND_UP_16:
823  * @num: integer value to round up
824  *
825  * Rounds an integer value up to the next multiple of 16.
826  */
827 #define GST_ROUND_UP_16(num) (((num)+15)&~15)
828 /**
829  * GST_ROUND_UP_32:
830  * @num: integer value to round up
831  *
832  * Rounds an integer value up to the next multiple of 32.
833  */
834 #define GST_ROUND_UP_32(num) (((num)+31)&~31)
835 /**
836  * GST_ROUND_UP_64:
837  * @num: integer value to round up
838  *
839  * Rounds an integer value up to the next multiple of 64.
840  */
841 #define GST_ROUND_UP_64(num) (((num)+63)&~63)
842 /**
843  * GST_ROUND_UP_128:
844  * @num: integer value to round up
845  *
846  * Rounds an integer value up to the next multiple of 128.
847  * Since: 1.4
848  */
849 #define GST_ROUND_UP_128(num) (((num)+127)&~127)
850 /**
851  * GST_ROUND_UP_N:
852  * @num: integrer value to round up
853  * @align: a power of two to round up to
854  *
855  * Rounds an integer value up to the next multiple of @align. @align MUST be a
856  * power of two.
857  */
858 #define GST_ROUND_UP_N(num,align) ((((num) + ((align) - 1)) & ~((align) - 1)))
859
860
861 /**
862  * GST_ROUND_DOWN_2:
863  * @num: integer value to round down
864  *
865  * Rounds an integer value down to the next multiple of 2.
866  */
867 #define GST_ROUND_DOWN_2(num)  ((num)&(~1))
868 /**
869  * GST_ROUND_DOWN_4:
870  * @num: integer value to round down
871  *
872  * Rounds an integer value down to the next multiple of 4.
873  */
874 #define GST_ROUND_DOWN_4(num)  ((num)&(~3))
875 /**
876  * GST_ROUND_DOWN_8:
877  * @num: integer value to round down
878  *
879  * Rounds an integer value down to the next multiple of 8.
880  */
881 #define GST_ROUND_DOWN_8(num)  ((num)&(~7))
882 /**
883  * GST_ROUND_DOWN_16:
884  * @num: integer value to round down
885  *
886  * Rounds an integer value down to the next multiple of 16.
887  */
888 #define GST_ROUND_DOWN_16(num) ((num)&(~15))
889 /**
890  * GST_ROUND_DOWN_32:
891  * @num: integer value to round down
892  *
893  * Rounds an integer value down to the next multiple of 32.
894  */
895 #define GST_ROUND_DOWN_32(num) ((num)&(~31))
896 /**
897  * GST_ROUND_DOWN_64:
898  * @num: integer value to round down
899  *
900  * Rounds an integer value down to the next multiple of 64.
901  */
902 #define GST_ROUND_DOWN_64(num) ((num)&(~63))
903 /**
904  * GST_ROUND_DOWN_128:
905  * @num: integer value to round down
906  *
907  * Rounds an integer value down to the next multiple of 128.
908  * Since: 1.4
909  */
910 #define GST_ROUND_DOWN_128(num) ((num)&(~127))
911 /**
912  * GST_ROUND_DOWN_N:
913  * @num: integrer value to round down
914  * @align: a power of two to round down to
915  *
916  * Rounds an integer value down to the next multiple of @align. @align MUST be a
917  * power of two.
918  */
919 #define GST_ROUND_DOWN_N(num,align) (((num) & ~((align) - 1)))
920
921
922 void                    gst_object_default_error        (GstObject    * source,
923                                                          const GError * error,
924                                                          const gchar  * debug);
925
926 /* element functions */
927 void                    gst_element_create_all_pads     (GstElement *element);
928 GstPad*                 gst_element_get_compatible_pad  (GstElement *element, GstPad *pad,
929                                                          GstCaps *caps);
930
931 GstPadTemplate*         gst_element_get_compatible_pad_template (GstElement *element, GstPadTemplate *compattempl);
932
933 const gchar*            gst_element_state_get_name      (GstState state);
934 const gchar *           gst_element_state_change_return_get_name (GstStateChangeReturn state_ret);
935
936 gboolean                gst_element_link                (GstElement *src, GstElement *dest);
937 gboolean                gst_element_link_many           (GstElement *element_1,
938                                                          GstElement *element_2, ...) G_GNUC_NULL_TERMINATED;
939 gboolean                gst_element_link_filtered       (GstElement * src,
940                                                          GstElement * dest,
941                                                          GstCaps *filter);
942 void                    gst_element_unlink              (GstElement *src, GstElement *dest);
943 void                    gst_element_unlink_many         (GstElement *element_1,
944                                                          GstElement *element_2, ...) G_GNUC_NULL_TERMINATED;
945
946 gboolean                gst_element_link_pads           (GstElement *src, const gchar *srcpadname,
947                                                          GstElement *dest, const gchar *destpadname);
948 gboolean                gst_element_link_pads_full      (GstElement *src, const gchar *srcpadname,
949                                                          GstElement *dest, const gchar *destpadname,
950                                                          GstPadLinkCheck flags);
951 void                    gst_element_unlink_pads         (GstElement *src, const gchar *srcpadname,
952                                                          GstElement *dest, const gchar *destpadname);
953
954 gboolean                gst_element_link_pads_filtered  (GstElement * src, const gchar * srcpadname,
955                                                          GstElement * dest, const gchar * destpadname,
956                                                          GstCaps *filter);
957
958 gboolean                gst_element_seek_simple         (GstElement   *element,
959                                                          GstFormat     format,
960                                                          GstSeekFlags  seek_flags,
961                                                          gint64        seek_pos);
962
963 /* util elementfactory functions */
964 gboolean gst_element_factory_can_sink_all_caps (GstElementFactory *factory, const GstCaps *caps);
965 gboolean gst_element_factory_can_src_all_caps  (GstElementFactory *factory, const GstCaps *caps);
966 gboolean gst_element_factory_can_sink_any_caps (GstElementFactory *factory, const GstCaps *caps);
967 gboolean gst_element_factory_can_src_any_caps  (GstElementFactory *factory, const GstCaps *caps);
968
969 /* util query functions */
970 gboolean                gst_element_query_position      (GstElement *element, GstFormat format, gint64 *cur);
971 gboolean                gst_element_query_duration      (GstElement *element, GstFormat format, gint64 *duration);
972 gboolean                gst_element_query_convert       (GstElement *element, GstFormat src_format, gint64 src_val,
973                                                          GstFormat dest_format, gint64 *dest_val);
974
975 /* pad functions */
976 void                    gst_pad_use_fixed_caps          (GstPad *pad);
977 GstElement*             gst_pad_get_parent_element      (GstPad *pad);
978
979 /* util query functions */
980 gboolean                gst_pad_proxy_query_accept_caps (GstPad *pad, GstQuery *query);
981 gboolean                gst_pad_proxy_query_caps        (GstPad *pad, GstQuery *query);
982
983 gboolean                gst_pad_query_position          (GstPad *pad, GstFormat format, gint64 *cur);
984 gboolean                gst_pad_query_duration          (GstPad *pad, GstFormat format, gint64 *duration);
985 gboolean                gst_pad_query_convert           (GstPad *pad, GstFormat src_format, gint64 src_val,
986                                                          GstFormat dest_format, gint64 *dest_val);
987 GstCaps *               gst_pad_query_caps              (GstPad *pad, GstCaps *filter);
988 gboolean                gst_pad_query_accept_caps       (GstPad *pad, GstCaps *caps);
989
990 gboolean                gst_pad_link_maybe_ghosting      (GstPad            *src,
991                                                           GstPad            *sink);
992 gboolean                gst_pad_link_maybe_ghosting_full (GstPad            *src,
993                                                           GstPad            *sink,
994                                                           GstPadLinkCheck   flags);
995
996 gboolean                gst_pad_peer_query_position     (GstPad *pad, GstFormat format, gint64 *cur);
997 gboolean                gst_pad_peer_query_duration     (GstPad *pad, GstFormat format, gint64 *duration);
998 gboolean                gst_pad_peer_query_convert      (GstPad *pad, GstFormat src_format, gint64 src_val,
999                                                          GstFormat dest_format, gint64 *dest_val);
1000 GstCaps *               gst_pad_peer_query_caps         (GstPad * pad, GstCaps *filter);
1001 gboolean                gst_pad_peer_query_accept_caps  (GstPad * pad, GstCaps *caps);
1002
1003 gchar *                 gst_pad_create_stream_id               (GstPad * pad, GstElement * parent, const gchar *stream_id) G_GNUC_MALLOC;
1004 gchar *                 gst_pad_create_stream_id_printf        (GstPad * pad, GstElement * parent, const gchar *stream_id, ...) G_GNUC_PRINTF (3, 4) G_GNUC_MALLOC;
1005 gchar *                 gst_pad_create_stream_id_printf_valist (GstPad * pad, GstElement * parent, const gchar *stream_id, va_list var_args) G_GNUC_PRINTF (3, 0) G_GNUC_MALLOC;
1006
1007 gchar *                 gst_pad_get_stream_id           (GstPad * pad);
1008 GstStream *             gst_pad_get_stream              (GstPad * pad);
1009
1010 /* bin functions */
1011 void                    gst_bin_add_many                (GstBin *bin, GstElement *element_1, ...) G_GNUC_NULL_TERMINATED;
1012 void                    gst_bin_remove_many             (GstBin *bin, GstElement *element_1, ...) G_GNUC_NULL_TERMINATED;
1013 GstPad *                gst_bin_find_unlinked_pad       (GstBin *bin, GstPadDirection direction);
1014
1015 gboolean                gst_bin_sync_children_states    (GstBin *bin);
1016
1017 /* parse utility functions */
1018 GstElement *            gst_parse_bin_from_description      (const gchar     * bin_description,
1019                                                              gboolean          ghost_unlinked_pads,
1020                                                              GError         ** err);
1021
1022 GstElement *            gst_parse_bin_from_description_full (const gchar     * bin_description,
1023                                                              gboolean          ghost_unlinked_pads,
1024                                                              GstParseContext * context,
1025                                                              GstParseFlags     flags,
1026                                                              GError         ** err);
1027
1028 GstClockTime            gst_util_get_timestamp          (void);
1029
1030 /**
1031  * GstSearchMode:
1032  * @GST_SEARCH_MODE_EXACT : Only search for exact matches.
1033  * @GST_SEARCH_MODE_BEFORE: Search for an exact match or the element just before.
1034  * @GST_SEARCH_MODE_AFTER : Search for an exact match or the element just after.
1035  *
1036  * The different search modes.
1037  */
1038 typedef enum {
1039   GST_SEARCH_MODE_EXACT = 0,
1040   GST_SEARCH_MODE_BEFORE,
1041   GST_SEARCH_MODE_AFTER
1042 } GstSearchMode;
1043
1044 gpointer      gst_util_array_binary_search      (gpointer array, guint num_elements,
1045                                                  gsize element_size, GCompareDataFunc search_func,
1046                                                  GstSearchMode mode, gconstpointer search_data,
1047                                                  gpointer user_data);
1048
1049 /* fraction operations */
1050 gint          gst_util_greatest_common_divisor  (gint a, gint b);
1051 gint64        gst_util_greatest_common_divisor_int64 (gint64 a, gint64 b);
1052
1053 void          gst_util_fraction_to_double       (gint src_n, gint src_d, gdouble *dest);
1054 void          gst_util_double_to_fraction       (gdouble src, gint *dest_n, gint *dest_d);
1055
1056 gboolean      gst_util_fraction_multiply        (gint a_n, gint a_d, gint b_n, gint b_d,
1057                                                  gint *res_n, gint *res_d);
1058 gboolean      gst_util_fraction_add             (gint a_n, gint a_d, gint b_n, gint b_d,
1059                                                  gint *res_n, gint *res_d);
1060 gint          gst_util_fraction_compare         (gint a_n, gint a_d, gint b_n, gint b_d);
1061
1062 gboolean      gst_calculate_linear_regression   (const GstClockTime * xy,
1063                                                  GstClockTime * temp, guint n,
1064                                                  GstClockTime * m_num, GstClockTime * m_denom,
1065                                                  GstClockTime * b, GstClockTime * xbase,
1066                                                  gdouble * r_squared);
1067
1068
1069 G_END_DECLS
1070
1071 #endif /* __GST_UTILS_H__ */