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