tests: remove the hacks to workaround the pad-leak
[platform/upstream/gstreamer.git] / gst / gstutils.c
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.c: 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., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23
24 /**
25  * SECTION:gstutils
26  * @short_description: Various utility functions
27  *
28  * When defining own plugins, use the GST_BOILERPLATE ease gobject creation.
29  */
30
31 #include "gst_private.h"
32 #include <stdio.h>
33 #include <string.h>
34
35 #include "gstghostpad.h"
36 #include "gstutils.h"
37 #include "gsterror.h"
38 #include "gstinfo.h"
39 #include "gstparse.h"
40 #include "gstvalue.h"
41 #include "gst-i18n-lib.h"
42
43 /**
44  * gst_util_dump_mem:
45  * @mem: a pointer to the memory to dump
46  * @size: the size of the memory block to dump
47  *
48  * Dumps the memory block into a hex representation. Useful for debugging.
49  */
50 void
51 gst_util_dump_mem (const guchar * mem, guint size)
52 {
53   guint i, j;
54   GString *string = g_string_sized_new (50);
55   GString *chars = g_string_sized_new (18);
56
57   i = j = 0;
58   while (i < size) {
59     if (g_ascii_isprint (mem[i]))
60       g_string_append_c (chars, mem[i]);
61     else
62       g_string_append_c (chars, '.');
63
64     g_string_append_printf (string, "%02x ", mem[i]);
65
66     j++;
67     i++;
68
69     if (j == 16 || i == size) {
70       g_print ("%08x (%p): %-48.48s %-16.16s\n", i - j, mem + i - j,
71           string->str, chars->str);
72       g_string_set_size (string, 0);
73       g_string_set_size (chars, 0);
74       j = 0;
75     }
76   }
77   g_string_free (string, TRUE);
78   g_string_free (chars, TRUE);
79 }
80
81
82 /**
83  * gst_util_set_value_from_string:
84  * @value: the value to set
85  * @value_str: the string to get the value from
86  *
87  * Converts the string to the type of the value and
88  * sets the value with it.
89  *
90  * Note that this function is dangerous as it does not return any indication
91  * if the conversion worked or not.
92  */
93 void
94 gst_util_set_value_from_string (GValue * value, const gchar * value_str)
95 {
96   gboolean res;
97
98   g_return_if_fail (value != NULL);
99   g_return_if_fail (value_str != NULL);
100
101   GST_CAT_DEBUG (GST_CAT_PARAMS, "parsing '%s' to type %s", value_str,
102       g_type_name (G_VALUE_TYPE (value)));
103
104   res = gst_value_deserialize (value, value_str);
105   if (!res && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) {
106     /* backwards compat, all booleans that fail to parse are false */
107     g_value_set_boolean (value, FALSE);
108     res = TRUE;
109   }
110   g_return_if_fail (res);
111 }
112
113 /**
114  * gst_util_set_object_arg:
115  * @object: the object to set the argument of
116  * @name: the name of the argument to set
117  * @value: the string value to set
118  *
119  * Convertes the string value to the type of the objects argument and
120  * sets the argument with it.
121  *
122  * Note that this function silently returns if @object has no property named
123  * @name or when @value cannot be converted to the type of the property.
124  */
125 void
126 gst_util_set_object_arg (GObject * object, const gchar * name,
127     const gchar * value)
128 {
129   GParamSpec *pspec;
130   GType value_type;
131   GValue v = { 0, };
132
133   g_return_if_fail (G_IS_OBJECT (object));
134   g_return_if_fail (name != NULL);
135   g_return_if_fail (value != NULL);
136
137   pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
138   if (!pspec)
139     return;
140
141   value_type = G_PARAM_SPEC_VALUE_TYPE (pspec);
142
143   GST_DEBUG ("pspec->flags is %d, pspec->value_type is %d",
144       pspec->flags, (gint) value_type);
145
146   if (!(pspec->flags & G_PARAM_WRITABLE))
147     return;
148
149   g_value_init (&v, value_type);
150   if (!gst_value_deserialize (&v, value))
151     return;
152
153   g_object_set_property (object, pspec->name, &v);
154   g_value_unset (&v);
155 }
156
157 /* work around error C2520: conversion from unsigned __int64 to double
158  * not implemented, use signed __int64
159  *
160  * These are implemented as functions because on some platforms a 64bit int to
161  * double conversion is not defined/implemented.
162  */
163
164 gdouble
165 gst_util_guint64_to_gdouble (guint64 value)
166 {
167   if (value & G_GINT64_CONSTANT (0x8000000000000000))
168     return (gdouble) ((gint64) value) + (gdouble) 18446744073709551616.;
169   else
170     return (gdouble) ((gint64) value);
171 }
172
173 guint64
174 gst_util_gdouble_to_guint64 (gdouble value)
175 {
176   if (value < (gdouble) 9223372036854775808.)   /* 1 << 63 */
177     return ((guint64) ((gint64) value));
178
179   value -= (gdouble) 18446744073709551616.;
180   return ((guint64) ((gint64) value));
181 }
182
183 /* convenience struct for getting high and low uint32 parts of
184  * a guint64 */
185 typedef union
186 {
187   guint64 ll;
188   struct
189   {
190 #if G_BYTE_ORDER == G_BIG_ENDIAN
191     guint32 high, low;
192 #else
193     guint32 low, high;
194 #endif
195   } l;
196 } GstUInt64;
197
198 /* based on Hacker's Delight p152 */
199 static guint64
200 gst_util_div128_64 (GstUInt64 c1, GstUInt64 c0, guint64 denom)
201 {
202   GstUInt64 q1, q0, rhat;
203   GstUInt64 v, cmp1, cmp2;
204   guint s;
205
206   v.ll = denom;
207
208   /* count number of leading zeroes, we know they must be in the high
209    * part of denom since denom > G_MAXUINT32. */
210   s = v.l.high | (v.l.high >> 1);
211   s |= (s >> 2);
212   s |= (s >> 4);
213   s |= (s >> 8);
214   s = ~(s | (s >> 16));
215   s = s - ((s >> 1) & 0x55555555);
216   s = (s & 0x33333333) + ((s >> 2) & 0x33333333);
217   s = (s + (s >> 4)) & 0x0f0f0f0f;
218   s += (s >> 8);
219   s = (s + (s >> 16)) & 0x3f;
220
221   if (s > 0) {
222     /* normalize divisor and dividend */
223     v.ll <<= s;
224     c1.ll = (c1.ll << s) | (c0.l.high >> (32 - s));
225     c0.ll <<= s;
226   }
227
228   q1.ll = c1.ll / v.l.high;
229   rhat.ll = c1.ll - q1.ll * v.l.high;
230
231   cmp1.l.high = rhat.l.low;
232   cmp1.l.low = c0.l.high;
233   cmp2.ll = q1.ll * v.l.low;
234
235   while (q1.l.high || cmp2.ll > cmp1.ll) {
236     q1.ll--;
237     rhat.ll += v.l.high;
238     if (rhat.l.high)
239       break;
240     cmp1.l.high = rhat.l.low;
241     cmp2.ll -= v.l.low;
242   }
243   c1.l.high = c1.l.low;
244   c1.l.low = c0.l.high;
245   c1.ll -= q1.ll * v.ll;
246   q0.ll = c1.ll / v.l.high;
247   rhat.ll = c1.ll - q0.ll * v.l.high;
248
249   cmp1.l.high = rhat.l.low;
250   cmp1.l.low = c0.l.low;
251   cmp2.ll = q0.ll * v.l.low;
252
253   while (q0.l.high || cmp2.ll > cmp1.ll) {
254     q0.ll--;
255     rhat.ll += v.l.high;
256     if (rhat.l.high)
257       break;
258     cmp1.l.high = rhat.l.low;
259     cmp2.ll -= v.l.low;
260   }
261   q0.l.high += q1.l.low;
262
263   return q0.ll;
264 }
265
266 static guint64
267 gst_util_uint64_scale_int64 (guint64 val, guint64 num, guint64 denom)
268 {
269   GstUInt64 a0, a1, b0, b1, c0, ct, c1, result;
270   GstUInt64 v, n;
271
272   /* prepare input */
273   v.ll = val;
274   n.ll = num;
275
276   /* do 128 bits multiply
277    *                   nh   nl
278    *                *  vh   vl
279    *                ----------
280    * a0 =              vl * nl
281    * a1 =         vl * nh
282    * b0 =         vh * nl
283    * b1 =  + vh * nh
284    *       -------------------
285    * c1,c0
286    */
287   a0.ll = (guint64) v.l.low * n.l.low;
288   a1.ll = (guint64) v.l.low * n.l.high;
289   b0.ll = (guint64) v.l.high * n.l.low;
290   b1.ll = (guint64) v.l.high * n.l.high;
291
292   /* and sum together with carry into 128 bits c1, c0 */
293   c0.l.low = a0.l.low;
294   ct.ll = (guint64) a0.l.high + a1.l.low + b0.l.low;
295   c0.l.high = ct.l.low;
296   c1.ll = (guint64) a1.l.high + b0.l.high + ct.l.high + b1.ll;
297
298   /* if high bits bigger than denom, we overflow */
299   if (c1.ll >= denom)
300     goto overflow;
301
302   /* shortcut for division by 1, c1.ll should be 0 because of the
303    * overflow check above. */
304   if (denom == 1)
305     return c0.ll;
306
307   /* and 128/64 bits division, result fits 64 bits */
308   if (denom <= G_MAXUINT32) {
309     guint32 den = (guint32) denom;
310
311     /* easy case, (c1,c0)128/(den)32 division */
312     c1.l.high %= den;
313     c1.l.high = c1.ll % den;
314     c1.l.low = c0.l.high;
315     c0.l.high = c1.ll % den;
316     result.l.high = c1.ll / den;
317     result.l.low = c0.ll / den;
318   } else {
319     result.ll = gst_util_div128_64 (c1, c0, denom);
320   }
321   return result.ll;
322
323 overflow:
324   {
325     return G_MAXUINT64;
326   }
327 }
328
329 /**
330  * gst_util_uint64_scale:
331  * @val: the number to scale
332  * @num: the numerator of the scale ratio
333  * @denom: the denominator of the scale ratio
334  *
335  * Scale @val by @num / @denom, trying to avoid overflows.
336  *
337  * This function can potentially be very slow if denom > G_MAXUINT32.
338  *
339  * Returns: @val * @num / @denom, trying to avoid overflows.
340  * In the case of an overflow, this function returns G_MAXUINT64.
341  */
342 guint64
343 gst_util_uint64_scale (guint64 val, guint64 num, guint64 denom)
344 {
345   g_return_val_if_fail (denom != 0, G_MAXUINT64);
346
347   if (num == 0)
348     return 0;
349
350   if (num == 1 && denom == 1)
351     return val;
352
353   /* if the denom is high, we need to do a 64 muldiv */
354   if (denom > G_MAXINT32)
355     goto do_int64;
356
357   /* if num and denom are low we can do a 32 bit muldiv */
358   if (num <= G_MAXINT32)
359     goto do_int32;
360
361   /* val and num are high, we need 64 muldiv */
362   if (val > G_MAXINT32)
363     goto do_int64;
364
365   /* val is low and num is high, we can swap them and do 32 muldiv */
366   return gst_util_uint64_scale_int (num, (gint) val, (gint) denom);
367
368 do_int32:
369   return gst_util_uint64_scale_int (val, (gint) num, (gint) denom);
370
371 do_int64:
372   /* to the more heavy implementations... */
373   return gst_util_uint64_scale_int64 (val, num, denom);
374 }
375
376 /**
377  * gst_util_uint64_scale_int:
378  * @val: guint64 (such as a #GstClockTime) to scale.
379  * @num: numerator of the scale factor.
380  * @denom: denominator of the scale factor.
381  *
382  * Scale a guint64 by a factor expressed as a fraction (num/denom), avoiding
383  * overflows and loss of precision.
384  *
385  * @num and @denom must be positive integers. @denom cannot be 0.
386  *
387  * Returns: @val * @num / @denom, avoiding overflow and loss of precision.
388  * In the case of an overflow, this function returns G_MAXUINT64.
389  */
390 guint64
391 gst_util_uint64_scale_int (guint64 val, gint num, gint denom)
392 {
393   GstUInt64 result;
394   GstUInt64 low, high;
395
396   g_return_val_if_fail (denom > 0, G_MAXUINT64);
397   g_return_val_if_fail (num >= 0, G_MAXUINT64);
398
399   if (num == 0)
400     return 0;
401
402   if (num == 1 && denom == 1)
403     return val;
404
405   if (val <= G_MAXUINT32)
406     /* simple case */
407     return val * num / denom;
408
409   /* do 96 bits mult/div */
410   low.ll = val;
411   result.ll = ((guint64) low.l.low) * num;
412   high.ll = ((guint64) low.l.high) * num + (result.l.high);
413
414   low.ll = high.ll / denom;
415   result.l.high = high.ll % denom;
416   result.ll /= denom;
417
418   /* avoid overflow */
419   if (low.ll + result.l.high > G_MAXUINT32)
420     goto overflow;
421
422   result.l.high += low.l.low;
423
424   return result.ll;
425
426 overflow:
427   {
428     return G_MAXUINT64;
429   }
430 }
431
432 /**
433  * gst_util_seqnum_next:
434  *
435  * Return a constantly incrementing sequence number.
436  *
437  * This function is used internally to GStreamer to be able to determine which
438  * events and messages are "the same". For example, elements may set the seqnum
439  * on a segment-done message to be the same as that of the last seek event, to
440  * indicate that event and the message correspond to the same segment.
441  *
442  * Returns: A constantly incrementing 32-bit unsigned integer, which might
443  * overflow back to 0 at some point. Use gst_util_seqnum_compare() to make sure
444  * you handle wraparound correctly.
445  *
446  * Since: 0.10.22
447  */
448 guint32
449 gst_util_seqnum_next (void)
450 {
451   static gint counter = 0;
452   return g_atomic_int_exchange_and_add (&counter, 1);
453 }
454
455 /**
456  * gst_util_seqnum_compare:
457  * @s1: A sequence number.
458  * @s2: Another sequence number.
459  *
460  * Compare two sequence numbers, handling wraparound.
461  * 
462  * The current implementation just returns (gint32)(@s1 - @s2).
463  *
464  * Returns: A negative number if @s1 is before @s2, 0 if they are equal, or a
465  * positive number if @s1 is after @s2.
466  *
467  * Since: 0.10.22
468  */
469 gint32
470 gst_util_seqnum_compare (guint32 s1, guint32 s2)
471 {
472   return (gint32) (s1 - s2);
473 }
474
475 /* -----------------------------------------------------
476  *
477  *  The following code will be moved out of the main
478  * gstreamer library someday.
479  */
480
481 #include "gstpad.h"
482
483 static void
484 string_append_indent (GString * str, gint count)
485 {
486   gint xx;
487
488   for (xx = 0; xx < count; xx++)
489     g_string_append_c (str, ' ');
490 }
491
492 /**
493  * gst_print_pad_caps:
494  * @buf: the buffer to print the caps in
495  * @indent: initial indentation
496  * @pad: the pad to print the caps from
497  *
498  * Write the pad capabilities in a human readable format into
499  * the given GString.
500  */
501 void
502 gst_print_pad_caps (GString * buf, gint indent, GstPad * pad)
503 {
504   GstCaps *caps;
505
506   caps = pad->caps;
507
508   if (!caps) {
509     string_append_indent (buf, indent);
510     g_string_printf (buf, "%s:%s has no capabilities",
511         GST_DEBUG_PAD_NAME (pad));
512   } else {
513     char *s;
514
515     s = gst_caps_to_string (caps);
516     g_string_append (buf, s);
517     g_free (s);
518   }
519 }
520
521 /**
522  * gst_print_element_args:
523  * @buf: the buffer to print the args in
524  * @indent: initial indentation
525  * @element: the element to print the args of
526  *
527  * Print the element argument in a human readable format in the given
528  * GString.
529  */
530 void
531 gst_print_element_args (GString * buf, gint indent, GstElement * element)
532 {
533   guint width;
534   GValue value = { 0, };        /* the important thing is that value.type = 0 */
535   gchar *str = NULL;
536   GParamSpec *spec, **specs, **walk;
537
538   specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (element), NULL);
539
540   width = 0;
541   for (walk = specs; *walk; walk++) {
542     spec = *walk;
543     if (width < strlen (spec->name))
544       width = strlen (spec->name);
545   }
546
547   for (walk = specs; *walk; walk++) {
548     spec = *walk;
549
550     if (spec->flags & G_PARAM_READABLE) {
551       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
552       g_object_get_property (G_OBJECT (element), spec->name, &value);
553       str = g_strdup_value_contents (&value);
554       g_value_unset (&value);
555     } else {
556       str = g_strdup ("Parameter not readable.");
557     }
558
559     string_append_indent (buf, indent);
560     g_string_append (buf, spec->name);
561     string_append_indent (buf, 2 + width - strlen (spec->name));
562     g_string_append (buf, str);
563     g_string_append_c (buf, '\n');
564
565     g_free (str);
566   }
567
568   g_free (specs);
569 }
570
571 /**
572  * gst_element_create_all_pads:
573  * @element: a #GstElement to create pads for
574  *
575  * Creates a pad for each pad template that is always available.
576  * This function is only useful during object intialization of
577  * subclasses of #GstElement.
578  */
579 void
580 gst_element_create_all_pads (GstElement * element)
581 {
582   GList *padlist;
583
584   /* FIXME: lock element */
585
586   padlist =
587       gst_element_class_get_pad_template_list (GST_ELEMENT_CLASS
588       (G_OBJECT_GET_CLASS (element)));
589
590   while (padlist) {
591     GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
592
593     if (padtempl->presence == GST_PAD_ALWAYS) {
594       GstPad *pad;
595
596       pad = gst_pad_new_from_template (padtempl, padtempl->name_template);
597
598       gst_element_add_pad (element, pad);
599     }
600     padlist = padlist->next;
601   }
602 }
603
604 /**
605  * gst_element_get_compatible_pad_template:
606  * @element: a #GstElement to get a compatible pad template for.
607  * @compattempl: the #GstPadTemplate to find a compatible template for.
608  *
609  * Retrieves a pad template from @element that is compatible with @compattempl.
610  * Pads from compatible templates can be linked together.
611  *
612  * Returns: a compatible #GstPadTemplate, or NULL if none was found. No
613  * unreferencing is necessary.
614  */
615 GstPadTemplate *
616 gst_element_get_compatible_pad_template (GstElement * element,
617     GstPadTemplate * compattempl)
618 {
619   GstPadTemplate *newtempl = NULL;
620   GList *padlist;
621   GstElementClass *class;
622
623   g_return_val_if_fail (element != NULL, NULL);
624   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
625   g_return_val_if_fail (compattempl != NULL, NULL);
626
627   class = GST_ELEMENT_GET_CLASS (element);
628
629   padlist = gst_element_class_get_pad_template_list (class);
630
631   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
632       "Looking for a suitable pad template in %s out of %d templates...",
633       GST_ELEMENT_NAME (element), g_list_length (padlist));
634
635   while (padlist) {
636     GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
637     GstCaps *intersection;
638
639     /* Ignore name
640      * Ignore presence
641      * Check direction (must be opposite)
642      * Check caps
643      */
644     GST_CAT_LOG (GST_CAT_CAPS,
645         "checking pad template %s", padtempl->name_template);
646     if (padtempl->direction != compattempl->direction) {
647       GST_CAT_DEBUG (GST_CAT_CAPS,
648           "compatible direction: found %s pad template \"%s\"",
649           padtempl->direction == GST_PAD_SRC ? "src" : "sink",
650           padtempl->name_template);
651
652       GST_CAT_DEBUG (GST_CAT_CAPS,
653           "intersecting %" GST_PTR_FORMAT, GST_PAD_TEMPLATE_CAPS (compattempl));
654       GST_CAT_DEBUG (GST_CAT_CAPS,
655           "..and %" GST_PTR_FORMAT, GST_PAD_TEMPLATE_CAPS (padtempl));
656
657       intersection = gst_caps_intersect (GST_PAD_TEMPLATE_CAPS (compattempl),
658           GST_PAD_TEMPLATE_CAPS (padtempl));
659
660       GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible %" GST_PTR_FORMAT,
661           (intersection ? "" : "not "), intersection);
662
663       if (!gst_caps_is_empty (intersection))
664         newtempl = padtempl;
665       gst_caps_unref (intersection);
666       if (newtempl)
667         break;
668     }
669
670     padlist = g_list_next (padlist);
671   }
672   if (newtempl)
673     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
674         "Returning new pad template %p", newtempl);
675   else
676     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "No compatible pad template found");
677
678   return newtempl;
679 }
680
681 static GstPad *
682 gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
683     const gchar * name)
684 {
685   GstPad *newpad = NULL;
686   GstElementClass *oclass;
687
688   oclass = GST_ELEMENT_GET_CLASS (element);
689
690   if (oclass->request_new_pad)
691     newpad = (oclass->request_new_pad) (element, templ, name);
692
693   if (newpad)
694     gst_object_ref (newpad);
695
696   return newpad;
697 }
698
699
700
701 /**
702  * gst_element_get_pad_from_template:
703  * @element: a #GstElement.
704  * @templ: a #GstPadTemplate belonging to @element.
705  *
706  * Gets a pad from @element described by @templ. If the presence of @templ is
707  * #GST_PAD_REQUEST, requests a new pad. Can return %NULL for #GST_PAD_SOMETIMES
708  * templates.
709  *
710  * Returns: the #GstPad, or NULL if one could not be found or created.
711  */
712 static GstPad *
713 gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ)
714 {
715   GstPad *ret = NULL;
716   GstPadPresence presence;
717
718   /* If this function is ever exported, we need check the validity of `element'
719    * and `templ', and to make sure the template actually belongs to the
720    * element. */
721
722   presence = GST_PAD_TEMPLATE_PRESENCE (templ);
723
724   switch (presence) {
725     case GST_PAD_ALWAYS:
726     case GST_PAD_SOMETIMES:
727       ret = gst_element_get_static_pad (element, templ->name_template);
728       if (!ret && presence == GST_PAD_ALWAYS)
729         g_warning
730             ("Element %s has an ALWAYS template %s, but no pad of the same name",
731             GST_OBJECT_NAME (element), templ->name_template);
732       break;
733
734     case GST_PAD_REQUEST:
735       ret = gst_element_request_pad (element, templ, NULL);
736       break;
737   }
738
739   return ret;
740 }
741
742 /**
743  * gst_element_request_compatible_pad:
744  * @element: a #GstElement.
745  * @templ: the #GstPadTemplate to which the new pad should be able to link.
746  *
747  * Requests a pad from @element. The returned pad should be unlinked and
748  * compatible with @templ. Might return an existing pad, or request a new one.
749  *
750  * Returns: a #GstPad, or %NULL if one could not be found or created.
751  */
752 GstPad *
753 gst_element_request_compatible_pad (GstElement * element,
754     GstPadTemplate * templ)
755 {
756   GstPadTemplate *templ_new;
757   GstPad *pad = NULL;
758
759   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
760   g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
761
762   /* FIXME: should really loop through the templates, testing each for
763    *      compatibility and pad availability. */
764   templ_new = gst_element_get_compatible_pad_template (element, templ);
765   if (templ_new)
766     pad = gst_element_get_pad_from_template (element, templ_new);
767
768   /* This can happen for non-request pads. No need to unref. */
769   if (pad && GST_PAD_PEER (pad))
770     pad = NULL;
771
772   return pad;
773 }
774
775 /**
776  * Checks if the source pad and the sink pad can be linked.
777  * Both @srcpad and @sinkpad must be unlinked and have a parent.
778  */
779 static gboolean
780 gst_pad_check_link (GstPad * srcpad, GstPad * sinkpad)
781 {
782   /* FIXME This function is gross.  It's almost a direct copy of
783    * gst_pad_link_filtered().  Any decent programmer would attempt
784    * to merge the two functions, which I will do some day. --ds
785    */
786
787   /* generic checks */
788   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
789   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
790
791   GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
792       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
793
794   /* FIXME: shouldn't we convert this to g_return_val_if_fail? */
795   if (GST_PAD_PEER (srcpad) != NULL) {
796     GST_CAT_INFO (GST_CAT_PADS, "Source pad %s:%s has a peer, failed",
797         GST_DEBUG_PAD_NAME (srcpad));
798     return FALSE;
799   }
800   if (GST_PAD_PEER (sinkpad) != NULL) {
801     GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has a peer, failed",
802         GST_DEBUG_PAD_NAME (sinkpad));
803     return FALSE;
804   }
805   if (!GST_PAD_IS_SRC (srcpad)) {
806     GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s is not source pad, failed",
807         GST_DEBUG_PAD_NAME (srcpad));
808     return FALSE;
809   }
810   if (!GST_PAD_IS_SINK (sinkpad)) {
811     GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s is not sink pad, failed",
812         GST_DEBUG_PAD_NAME (sinkpad));
813     return FALSE;
814   }
815   if (GST_PAD_PARENT (srcpad) == NULL) {
816     GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s has no parent, failed",
817         GST_DEBUG_PAD_NAME (srcpad));
818     return FALSE;
819   }
820   if (GST_PAD_PARENT (sinkpad) == NULL) {
821     GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has no parent, failed",
822         GST_DEBUG_PAD_NAME (srcpad));
823     return FALSE;
824   }
825
826   return TRUE;
827 }
828
829 /**
830  * gst_element_get_compatible_pad:
831  * @element: a #GstElement in which the pad should be found.
832  * @pad: the #GstPad to find a compatible one for.
833  * @caps: the #GstCaps to use as a filter.
834  *
835  * Looks for an unlinked pad to which the given pad can link. It is not
836  * guaranteed that linking the pads will work, though it should work in most
837  * cases.
838  *
839  * Returns: the #GstPad to which a link can be made, or %NULL if one cannot be
840  * found. gst_object_unref() after usage.
841  */
842 GstPad *
843 gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
844     const GstCaps * caps)
845 {
846   GstIterator *pads;
847   GstPadTemplate *templ;
848   GstCaps *templcaps;
849   GstPad *foundpad = NULL;
850   gboolean done;
851
852   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
853   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
854
855   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
856       "finding pad in %s compatible with %s:%s",
857       GST_ELEMENT_NAME (element), GST_DEBUG_PAD_NAME (pad));
858
859   g_return_val_if_fail (GST_PAD_PEER (pad) == NULL, NULL);
860
861   done = FALSE;
862   /* try to get an existing unlinked pad */
863   pads = gst_element_iterate_pads (element);
864   while (!done) {
865     gpointer padptr;
866
867     switch (gst_iterator_next (pads, &padptr)) {
868       case GST_ITERATOR_OK:
869       {
870         GstPad *peer;
871         GstPad *current;
872
873         current = GST_PAD (padptr);
874
875         GST_CAT_LOG (GST_CAT_ELEMENT_PADS, "examining pad %s:%s",
876             GST_DEBUG_PAD_NAME (current));
877
878         peer = gst_pad_get_peer (current);
879
880         if (peer == NULL && gst_pad_check_link (pad, current)) {
881           GstCaps *temp, *temp2, *intersection;
882
883           /* Now check if the two pads' caps are compatible */
884           temp = gst_pad_get_caps (pad);
885           if (caps) {
886             intersection = gst_caps_intersect (temp, caps);
887             gst_caps_unref (temp);
888           } else {
889             intersection = temp;
890           }
891
892           temp = gst_pad_get_caps (current);
893           temp2 = gst_caps_intersect (temp, intersection);
894           gst_caps_unref (temp);
895           gst_caps_unref (intersection);
896
897           intersection = temp2;
898
899           if (!gst_caps_is_empty (intersection)) {
900             gst_caps_unref (intersection);
901
902             GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
903                 "found existing unlinked compatible pad %s:%s",
904                 GST_DEBUG_PAD_NAME (current));
905             gst_iterator_free (pads);
906
907             return current;
908           } else {
909             GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "incompatible pads");
910           }
911           gst_caps_unref (intersection);
912         } else {
913           GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
914               "already linked or cannot be linked (peer = %p)", peer);
915         }
916         GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unreffing pads");
917
918         gst_object_unref (current);
919         if (peer)
920           gst_object_unref (peer);
921         break;
922       }
923       case GST_ITERATOR_DONE:
924         done = TRUE;
925         break;
926       case GST_ITERATOR_RESYNC:
927         gst_iterator_resync (pads);
928         break;
929       case GST_ITERATOR_ERROR:
930         g_assert_not_reached ();
931         break;
932     }
933   }
934   gst_iterator_free (pads);
935
936   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
937       "Could not find a compatible unlinked always pad to link to %s:%s, now checking request pads",
938       GST_DEBUG_PAD_NAME (pad));
939
940   /* try to create a new one */
941   /* requesting is a little crazy, we need a template. Let's create one */
942   /* FIXME: why not gst_pad_get_pad_template (pad); */
943   templcaps = gst_pad_get_caps (pad);
944
945   templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
946       GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps);
947
948   foundpad = gst_element_request_compatible_pad (element, templ);
949   gst_object_unref (templ);
950
951   if (foundpad) {
952     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
953         "found existing request pad %s:%s", GST_DEBUG_PAD_NAME (foundpad));
954     return foundpad;
955   }
956
957   GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element,
958       "Could not find a compatible pad to link to %s:%s",
959       GST_DEBUG_PAD_NAME (pad));
960   return NULL;
961 }
962
963 /**
964  * gst_element_state_get_name:
965  * @state: a #GstState to get the name of.
966  *
967  * Gets a string representing the given state.
968  *
969  * Returns: a string with the name of the state.
970  */
971 G_CONST_RETURN gchar *
972 gst_element_state_get_name (GstState state)
973 {
974   switch (state) {
975 #ifdef GST_DEBUG_COLOR
976     case GST_STATE_VOID_PENDING:
977       return "VOID_PENDING";
978     case GST_STATE_NULL:
979       return "\033[01;34mNULL\033[00m";
980     case GST_STATE_READY:
981       return "\033[01;31mREADY\033[00m";
982     case GST_STATE_PLAYING:
983       return "\033[01;32mPLAYING\033[00m";
984     case GST_STATE_PAUSED:
985       return "\033[01;33mPAUSED\033[00m";
986     default:
987       /* This is a memory leak */
988       return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state);
989 #else
990     case GST_STATE_VOID_PENDING:
991       return "VOID_PENDING";
992     case GST_STATE_NULL:
993       return "NULL";
994     case GST_STATE_READY:
995       return "READY";
996     case GST_STATE_PLAYING:
997       return "PLAYING";
998     case GST_STATE_PAUSED:
999       return "PAUSED";
1000     default:
1001       /* This is a memory leak */
1002       return g_strdup_printf ("UNKNOWN!(%d)", state);
1003 #endif
1004   }
1005 }
1006
1007 /**
1008  * gst_element_state_change_return_get_name:
1009  * @state_ret: a #GstStateChangeReturn to get the name of.
1010  *
1011  * Gets a string representing the given state change result.
1012  *
1013  * Returns: a string with the name of the state change result.
1014  *
1015  * Since: 0.10.11
1016  */
1017 G_CONST_RETURN gchar *
1018 gst_element_state_change_return_get_name (GstStateChangeReturn state_ret)
1019 {
1020   switch (state_ret) {
1021 #ifdef GST_DEBUG_COLOR
1022     case GST_STATE_CHANGE_FAILURE:
1023       return "\033[01;31mFAILURE\033[00m";
1024     case GST_STATE_CHANGE_SUCCESS:
1025       return "\033[01;32mSUCCESS\033[00m";
1026     case GST_STATE_CHANGE_ASYNC:
1027       return "\033[01;33mASYNC\033[00m";
1028     case GST_STATE_CHANGE_NO_PREROLL:
1029       return "\033[01;34mNO_PREROLL\033[00m";
1030     default:
1031       /* This is a memory leak */
1032       return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state_ret);
1033 #else
1034     case GST_STATE_CHANGE_FAILURE:
1035       return "FAILURE";
1036     case GST_STATE_CHANGE_SUCCESS:
1037       return "SUCCESS";
1038     case GST_STATE_CHANGE_ASYNC:
1039       return "ASYNC";
1040     case GST_STATE_CHANGE_NO_PREROLL:
1041       return "NO PREROLL";
1042     default:
1043       /* This is a memory leak */
1044       return g_strdup_printf ("UNKNOWN!(%d)", state_ret);
1045 #endif
1046   }
1047 }
1048
1049
1050 /**
1051  * gst_element_factory_can_src_caps :
1052  * @factory: factory to query
1053  * @caps: the caps to check
1054  *
1055  * Checks if the factory can source the given capability.
1056  *
1057  * Returns: true if it can src the capabilities
1058  */
1059 gboolean
1060 gst_element_factory_can_src_caps (GstElementFactory * factory,
1061     const GstCaps * caps)
1062 {
1063   GList *templates;
1064
1065   g_return_val_if_fail (factory != NULL, FALSE);
1066   g_return_val_if_fail (caps != NULL, FALSE);
1067
1068   templates = factory->staticpadtemplates;
1069
1070   while (templates) {
1071     GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data;
1072
1073     if (template->direction == GST_PAD_SRC) {
1074       if (gst_caps_is_always_compatible (gst_static_caps_get
1075               (&template->static_caps), caps))
1076         return TRUE;
1077     }
1078     templates = g_list_next (templates);
1079   }
1080
1081   return FALSE;
1082 }
1083
1084 /**
1085  * gst_element_factory_can_sink_caps :
1086  * @factory: factory to query
1087  * @caps: the caps to check
1088  *
1089  * Checks if the factory can sink the given capability.
1090  *
1091  * Returns: true if it can sink the capabilities
1092  */
1093 gboolean
1094 gst_element_factory_can_sink_caps (GstElementFactory * factory,
1095     const GstCaps * caps)
1096 {
1097   GList *templates;
1098
1099   g_return_val_if_fail (factory != NULL, FALSE);
1100   g_return_val_if_fail (caps != NULL, FALSE);
1101
1102   templates = factory->staticpadtemplates;
1103
1104   while (templates) {
1105     GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data;
1106
1107     if (template->direction == GST_PAD_SINK) {
1108       if (gst_caps_is_always_compatible (caps,
1109               gst_static_caps_get (&template->static_caps)))
1110         return TRUE;
1111     }
1112     templates = g_list_next (templates);
1113   }
1114
1115   return FALSE;
1116 }
1117
1118
1119 /* if return val is true, *direct_child is a caller-owned ref on the direct
1120  * child of ancestor that is part of object's ancestry */
1121 static gboolean
1122 object_has_ancestor (GstObject * object, GstObject * ancestor,
1123     GstObject ** direct_child)
1124 {
1125   GstObject *child, *parent;
1126
1127   if (direct_child)
1128     *direct_child = NULL;
1129
1130   child = gst_object_ref (object);
1131   parent = gst_object_get_parent (object);
1132
1133   while (parent) {
1134     if (ancestor == parent) {
1135       if (direct_child)
1136         *direct_child = child;
1137       else
1138         gst_object_unref (child);
1139       gst_object_unref (parent);
1140       return TRUE;
1141     }
1142
1143     gst_object_unref (child);
1144     child = parent;
1145     parent = gst_object_get_parent (parent);
1146   }
1147
1148   gst_object_unref (child);
1149
1150   return FALSE;
1151 }
1152
1153 /* caller owns return */
1154 static GstObject *
1155 find_common_root (GstObject * o1, GstObject * o2)
1156 {
1157   GstObject *top = o1;
1158   GstObject *kid1, *kid2;
1159   GstObject *root = NULL;
1160
1161   while (GST_OBJECT_PARENT (top))
1162     top = GST_OBJECT_PARENT (top);
1163
1164   /* the itsy-bitsy spider... */
1165
1166   if (!object_has_ancestor (o2, top, &kid2))
1167     return NULL;
1168
1169   root = gst_object_ref (top);
1170   while (TRUE) {
1171     if (!object_has_ancestor (o1, kid2, &kid1)) {
1172       gst_object_unref (kid2);
1173       return root;
1174     }
1175     root = kid2;
1176     if (!object_has_ancestor (o2, kid1, &kid2)) {
1177       gst_object_unref (kid1);
1178       return root;
1179     }
1180     root = kid1;
1181   }
1182 }
1183
1184 /* caller does not own return */
1185 static GstPad *
1186 ghost_up (GstElement * e, GstPad * pad)
1187 {
1188   static gint ghost_pad_index = 0;
1189   GstPad *gpad;
1190   gchar *name;
1191   GstObject *parent = GST_OBJECT_PARENT (e);
1192
1193   name = g_strdup_printf ("ghost%d", ghost_pad_index++);
1194   gpad = gst_ghost_pad_new (name, pad);
1195   g_free (name);
1196
1197   if (!gst_element_add_pad ((GstElement *) parent, gpad)) {
1198     g_warning ("Pad named %s already exists in element %s\n",
1199         GST_OBJECT_NAME (gpad), GST_OBJECT_NAME (parent));
1200     gst_object_unref ((GstObject *) gpad);
1201     return NULL;
1202   }
1203
1204   return gpad;
1205 }
1206
1207 static void
1208 remove_pad (gpointer ppad, gpointer unused)
1209 {
1210   GstPad *pad = ppad;
1211
1212   if (!gst_element_remove_pad ((GstElement *) GST_OBJECT_PARENT (pad), pad))
1213     g_warning ("Couldn't remove pad %s from element %s",
1214         GST_OBJECT_NAME (pad), GST_OBJECT_NAME (GST_OBJECT_PARENT (pad)));
1215 }
1216
1217 static gboolean
1218 prepare_link_maybe_ghosting (GstPad ** src, GstPad ** sink,
1219     GSList ** pads_created)
1220 {
1221   GstObject *root;
1222   GstObject *e1, *e2;
1223   GSList *pads_created_local = NULL;
1224
1225   g_assert (pads_created);
1226
1227   e1 = GST_OBJECT_PARENT (*src);
1228   e2 = GST_OBJECT_PARENT (*sink);
1229
1230   if (G_UNLIKELY (e1 == NULL)) {
1231     GST_WARNING ("Trying to ghost a pad that doesn't have a parent: %"
1232         GST_PTR_FORMAT, *src);
1233     return FALSE;
1234   }
1235   if (G_UNLIKELY (e2 == NULL)) {
1236     GST_WARNING ("Trying to ghost a pad that doesn't have a parent: %"
1237         GST_PTR_FORMAT, *sink);
1238     return FALSE;
1239   }
1240
1241   if (GST_OBJECT_PARENT (e1) == GST_OBJECT_PARENT (e2)) {
1242     GST_CAT_INFO (GST_CAT_PADS, "%s and %s in same bin, no need for ghost pads",
1243         GST_OBJECT_NAME (e1), GST_OBJECT_NAME (e2));
1244     return TRUE;
1245   }
1246
1247   GST_CAT_INFO (GST_CAT_PADS, "%s and %s not in same bin, making ghost pads",
1248       GST_OBJECT_NAME (e1), GST_OBJECT_NAME (e2));
1249
1250   /* we need to setup some ghost pads */
1251   root = find_common_root (e1, e2);
1252   if (!root) {
1253     g_warning ("Trying to connect elements that don't share a common "
1254         "ancestor: %s and %s", GST_ELEMENT_NAME (e1), GST_ELEMENT_NAME (e2));
1255     return FALSE;
1256   }
1257
1258   while (GST_OBJECT_PARENT (e1) != root) {
1259     *src = ghost_up ((GstElement *) e1, *src);
1260     if (!*src)
1261       goto cleanup_fail;
1262     e1 = GST_OBJECT_PARENT (*src);
1263     pads_created_local = g_slist_prepend (pads_created_local, *src);
1264   }
1265   while (GST_OBJECT_PARENT (e2) != root) {
1266     *sink = ghost_up ((GstElement *) e2, *sink);
1267     if (!*sink)
1268       goto cleanup_fail;
1269     e2 = GST_OBJECT_PARENT (*sink);
1270     pads_created_local = g_slist_prepend (pads_created_local, *sink);
1271   }
1272
1273   gst_object_unref (root);
1274   *pads_created = g_slist_concat (*pads_created, pads_created_local);
1275   return TRUE;
1276
1277 cleanup_fail:
1278   gst_object_unref (root);
1279   g_slist_foreach (pads_created_local, remove_pad, NULL);
1280   g_slist_free (pads_created_local);
1281   return FALSE;
1282 }
1283
1284 static gboolean
1285 pad_link_maybe_ghosting (GstPad * src, GstPad * sink)
1286 {
1287   GSList *pads_created = NULL;
1288   gboolean ret;
1289
1290   if (!prepare_link_maybe_ghosting (&src, &sink, &pads_created)) {
1291     ret = FALSE;
1292   } else {
1293     ret = (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
1294   }
1295
1296   if (!ret) {
1297     g_slist_foreach (pads_created, remove_pad, NULL);
1298   }
1299   g_slist_free (pads_created);
1300
1301   return ret;
1302 }
1303
1304 /**
1305  * gst_element_link_pads:
1306  * @src: a #GstElement containing the source pad.
1307  * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
1308  * @dest: the #GstElement containing the destination pad.
1309  * @destpadname: the name of the #GstPad in destination element,
1310  * or NULL for any pad.
1311  *
1312  * Links the two named pads of the source and destination elements.
1313  * Side effect is that if one of the pads has no parent, it becomes a
1314  * child of the parent of the other element.  If they have different
1315  * parents, the link fails.
1316  *
1317  * Returns: TRUE if the pads could be linked, FALSE otherwise.
1318  */
1319 gboolean
1320 gst_element_link_pads (GstElement * src, const gchar * srcpadname,
1321     GstElement * dest, const gchar * destpadname)
1322 {
1323   const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
1324   GstPad *srcpad, *destpad;
1325   GstPadTemplate *srctempl, *desttempl;
1326   GstElementClass *srcclass, *destclass;
1327
1328   /* checks */
1329   g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1330   g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1331
1332   srcclass = GST_ELEMENT_GET_CLASS (src);
1333   destclass = GST_ELEMENT_GET_CLASS (dest);
1334
1335   GST_CAT_INFO (GST_CAT_ELEMENT_PADS,
1336       "trying to link element %s:%s to element %s:%s", GST_ELEMENT_NAME (src),
1337       srcpadname ? srcpadname : "(any)", GST_ELEMENT_NAME (dest),
1338       destpadname ? destpadname : "(any)");
1339
1340   /* get a src pad */
1341   if (srcpadname) {
1342     /* name specified, look it up */
1343     if (!(srcpad = gst_element_get_static_pad (src, srcpadname)))
1344       srcpad = gst_element_get_request_pad (src, srcpadname);
1345     if (!srcpad) {
1346       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
1347           GST_ELEMENT_NAME (src), srcpadname);
1348       return FALSE;
1349     } else {
1350       if (!(GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC)) {
1351         GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no src pad",
1352             GST_DEBUG_PAD_NAME (srcpad));
1353         gst_object_unref (srcpad);
1354         return FALSE;
1355       }
1356       if (GST_PAD_PEER (srcpad) != NULL) {
1357         GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
1358             GST_DEBUG_PAD_NAME (srcpad));
1359         gst_object_unref (srcpad);
1360         return FALSE;
1361       }
1362     }
1363     srcpads = NULL;
1364   } else {
1365     /* no name given, get the first available pad */
1366     GST_OBJECT_LOCK (src);
1367     srcpads = GST_ELEMENT_PADS (src);
1368     srcpad = srcpads ? GST_PAD_CAST (srcpads->data) : NULL;
1369     if (srcpad)
1370       gst_object_ref (srcpad);
1371     GST_OBJECT_UNLOCK (src);
1372   }
1373
1374   /* get a destination pad */
1375   if (destpadname) {
1376     /* name specified, look it up */
1377     if (!(destpad = gst_element_get_static_pad (dest, destpadname)))
1378       destpad = gst_element_get_request_pad (dest, destpadname);
1379     if (!destpad) {
1380       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
1381           GST_ELEMENT_NAME (dest), destpadname);
1382       return FALSE;
1383     } else {
1384       if (!(GST_PAD_DIRECTION (destpad) == GST_PAD_SINK)) {
1385         GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no sink pad",
1386             GST_DEBUG_PAD_NAME (destpad));
1387         gst_object_unref (destpad);
1388         return FALSE;
1389       }
1390       if (GST_PAD_PEER (destpad) != NULL) {
1391         GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
1392             GST_DEBUG_PAD_NAME (destpad));
1393         gst_object_unref (destpad);
1394         return FALSE;
1395       }
1396     }
1397     destpads = NULL;
1398   } else {
1399     /* no name given, get the first available pad */
1400     GST_OBJECT_LOCK (dest);
1401     destpads = GST_ELEMENT_PADS (dest);
1402     destpad = destpads ? GST_PAD_CAST (destpads->data) : NULL;
1403     if (destpad)
1404       gst_object_ref (destpad);
1405     GST_OBJECT_UNLOCK (dest);
1406   }
1407
1408   if (srcpadname && destpadname) {
1409     gboolean result;
1410
1411     /* two explicitly specified pads */
1412     result = pad_link_maybe_ghosting (srcpad, destpad);
1413
1414     gst_object_unref (srcpad);
1415     gst_object_unref (destpad);
1416
1417     return result;
1418   }
1419
1420   if (srcpad) {
1421     /* loop through the allowed pads in the source, trying to find a
1422      * compatible destination pad */
1423     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1424         "looping through allowed src and dest pads");
1425     do {
1426       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
1427           GST_DEBUG_PAD_NAME (srcpad));
1428       if ((GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
1429           (GST_PAD_PEER (srcpad) == NULL)) {
1430         GstPad *temp;
1431
1432         if (destpadname) {
1433           temp = destpad;
1434           gst_object_ref (temp);
1435         } else {
1436           temp = gst_element_get_compatible_pad (dest, srcpad, NULL);
1437         }
1438
1439         if (temp && pad_link_maybe_ghosting (srcpad, temp)) {
1440           GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1441               GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
1442           if (destpad)
1443             gst_object_unref (destpad);
1444           gst_object_unref (srcpad);
1445           gst_object_unref (temp);
1446           return TRUE;
1447         }
1448
1449         if (temp) {
1450           gst_object_unref (temp);
1451         }
1452       }
1453       /* find a better way for this mess */
1454       if (srcpads) {
1455         srcpads = g_list_next (srcpads);
1456         if (srcpads) {
1457           gst_object_unref (srcpad);
1458           srcpad = GST_PAD_CAST (srcpads->data);
1459           gst_object_ref (srcpad);
1460         }
1461       }
1462     } while (srcpads);
1463   }
1464   if (srcpadname) {
1465     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s:%s to %s",
1466         GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (dest));
1467     if (destpad)
1468       gst_object_unref (destpad);
1469     destpad = NULL;
1470   }
1471   if (srcpad)
1472     gst_object_unref (srcpad);
1473   srcpad = NULL;
1474
1475   if (destpad) {
1476     /* loop through the existing pads in the destination */
1477     do {
1478       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
1479           GST_DEBUG_PAD_NAME (destpad));
1480       if ((GST_PAD_DIRECTION (destpad) == GST_PAD_SINK) &&
1481           (GST_PAD_PEER (destpad) == NULL)) {
1482         GstPad *temp = gst_element_get_compatible_pad (src, destpad, NULL);
1483
1484         if (temp && pad_link_maybe_ghosting (temp, destpad)) {
1485           GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1486               GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
1487           gst_object_unref (temp);
1488           gst_object_unref (destpad);
1489           return TRUE;
1490         }
1491         if (temp) {
1492           gst_object_unref (temp);
1493         }
1494       }
1495       if (destpads) {
1496         destpads = g_list_next (destpads);
1497         if (destpads) {
1498           gst_object_unref (destpad);
1499           destpad = GST_PAD_CAST (destpads->data);
1500           gst_object_ref (destpad);
1501         }
1502       }
1503     } while (destpads);
1504   }
1505
1506   if (destpadname) {
1507     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s:%s",
1508         GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME (destpad));
1509     gst_object_unref (destpad);
1510     return FALSE;
1511   } else {
1512     if (destpad)
1513       gst_object_unref (destpad);
1514     destpad = NULL;
1515   }
1516
1517   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1518       "we might have request pads on both sides, checking...");
1519   srctempls = gst_element_class_get_pad_template_list (srcclass);
1520   desttempls = gst_element_class_get_pad_template_list (destclass);
1521
1522   if (srctempls && desttempls) {
1523     while (srctempls) {
1524       srctempl = (GstPadTemplate *) srctempls->data;
1525       if (srctempl->presence == GST_PAD_REQUEST) {
1526         for (l = desttempls; l; l = l->next) {
1527           desttempl = (GstPadTemplate *) l->data;
1528           if (desttempl->presence == GST_PAD_REQUEST &&
1529               desttempl->direction != srctempl->direction) {
1530             if (gst_caps_is_always_compatible (gst_pad_template_get_caps
1531                     (srctempl), gst_pad_template_get_caps (desttempl))) {
1532               srcpad =
1533                   gst_element_get_request_pad (src, srctempl->name_template);
1534               destpad =
1535                   gst_element_get_request_pad (dest, desttempl->name_template);
1536               if (srcpad && destpad
1537                   && pad_link_maybe_ghosting (srcpad, destpad)) {
1538                 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1539                     "linked pad %s:%s to pad %s:%s",
1540                     GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1541                 gst_object_unref (srcpad);
1542                 gst_object_unref (destpad);
1543                 return TRUE;
1544               }
1545               /* it failed, so we release the request pads */
1546               if (srcpad)
1547                 gst_element_release_request_pad (src, srcpad);
1548               if (destpad)
1549                 gst_element_release_request_pad (dest, destpad);
1550             }
1551           }
1552         }
1553       }
1554       srctempls = srctempls->next;
1555     }
1556   }
1557
1558   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s",
1559       GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1560   return FALSE;
1561 }
1562
1563 /**
1564  * gst_element_link_pads_filtered:
1565  * @src: a #GstElement containing the source pad.
1566  * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
1567  * @dest: the #GstElement containing the destination pad.
1568  * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
1569  * @filter: the #GstCaps to filter the link, or #NULL for no filter.
1570  *
1571  * Links the two named pads of the source and destination elements. Side effect
1572  * is that if one of the pads has no parent, it becomes a child of the parent of
1573  * the other element. If they have different parents, the link fails. If @caps
1574  * is not #NULL, makes sure that the caps of the link is a subset of @caps.
1575  *
1576  * Returns: TRUE if the pads could be linked, FALSE otherwise.
1577  */
1578 gboolean
1579 gst_element_link_pads_filtered (GstElement * src, const gchar * srcpadname,
1580     GstElement * dest, const gchar * destpadname, GstCaps * filter)
1581 {
1582   /* checks */
1583   g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1584   g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1585   g_return_val_if_fail (filter == NULL || GST_IS_CAPS (filter), FALSE);
1586
1587   if (filter) {
1588     GstElement *capsfilter;
1589     GstObject *parent;
1590     GstState state, pending;
1591
1592     capsfilter = gst_element_factory_make ("capsfilter", NULL);
1593     if (!capsfilter) {
1594       GST_ERROR ("Could not make a capsfilter");
1595       return FALSE;
1596     }
1597
1598     parent = gst_object_get_parent (GST_OBJECT (src));
1599     g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
1600
1601     gst_element_get_state (GST_ELEMENT_CAST (parent), &state, &pending, 0);
1602
1603     if (!gst_bin_add (GST_BIN (parent), capsfilter)) {
1604       GST_ERROR ("Could not add capsfilter");
1605       gst_object_unref (capsfilter);
1606       gst_object_unref (parent);
1607       return FALSE;
1608     }
1609
1610     if (pending != GST_STATE_VOID_PENDING)
1611       state = pending;
1612
1613     gst_element_set_state (capsfilter, state);
1614
1615     gst_object_unref (parent);
1616
1617     g_object_set (capsfilter, "caps", filter, NULL);
1618
1619     if (gst_element_link_pads (src, srcpadname, capsfilter, "sink")
1620         && gst_element_link_pads (capsfilter, "src", dest, destpadname)) {
1621       return TRUE;
1622     } else {
1623       GST_INFO ("Could not link elements");
1624       gst_element_set_state (capsfilter, GST_STATE_NULL);
1625       /* this will unlink and unref as appropriate */
1626       gst_bin_remove (GST_BIN (GST_OBJECT_PARENT (capsfilter)), capsfilter);
1627       return FALSE;
1628     }
1629   } else {
1630     return gst_element_link_pads (src, srcpadname, dest, destpadname);
1631   }
1632 }
1633
1634 /**
1635  * gst_element_link:
1636  * @src: a #GstElement containing the source pad.
1637  * @dest: the #GstElement containing the destination pad.
1638  *
1639  * Links @src to @dest. The link must be from source to
1640  * destination; the other direction will not be tried. The function looks for
1641  * existing pads that aren't linked yet. It will request new pads if necessary.
1642  * Such pads need to be released manualy when unlinking.
1643  * If multiple links are possible, only one is established.
1644  *
1645  * Make sure you have added your elements to a bin or pipeline with
1646  * gst_bin_add() before trying to link them.
1647  *
1648  * Returns: TRUE if the elements could be linked, FALSE otherwise.
1649  */
1650 gboolean
1651 gst_element_link (GstElement * src, GstElement * dest)
1652 {
1653   return gst_element_link_pads_filtered (src, NULL, dest, NULL, NULL);
1654 }
1655
1656 /**
1657  * gst_element_link_many:
1658  * @element_1: the first #GstElement in the link chain.
1659  * @element_2: the second #GstElement in the link chain.
1660  * @...: the NULL-terminated list of elements to link in order.
1661  *
1662  * Chain together a series of elements. Uses gst_element_link().
1663  * Make sure you have added your elements to a bin or pipeline with
1664  * gst_bin_add() before trying to link them.
1665  *
1666  * Returns: TRUE on success, FALSE otherwise.
1667  */
1668 gboolean
1669 gst_element_link_many (GstElement * element_1, GstElement * element_2, ...)
1670 {
1671   gboolean res = TRUE;
1672   va_list args;
1673
1674   g_return_val_if_fail (GST_IS_ELEMENT (element_1), FALSE);
1675   g_return_val_if_fail (GST_IS_ELEMENT (element_2), FALSE);
1676
1677   va_start (args, element_2);
1678
1679   while (element_2) {
1680     if (!gst_element_link (element_1, element_2)) {
1681       res = FALSE;
1682       break;
1683     }
1684
1685     element_1 = element_2;
1686     element_2 = va_arg (args, GstElement *);
1687   }
1688
1689   va_end (args);
1690
1691   return res;
1692 }
1693
1694 /**
1695  * gst_element_link_filtered:
1696  * @src: a #GstElement containing the source pad.
1697  * @dest: the #GstElement containing the destination pad.
1698  * @filter: the #GstCaps to filter the link, or #NULL for no filter.
1699  *
1700  * Links @src to @dest using the given caps as filtercaps.
1701  * The link must be from source to
1702  * destination; the other direction will not be tried. The function looks for
1703  * existing pads that aren't linked yet. It will request new pads if necessary.
1704  * If multiple links are possible, only one is established.
1705  *
1706  * Make sure you have added your elements to a bin or pipeline with
1707  * gst_bin_add() before trying to link them.
1708  *
1709  * Returns: TRUE if the pads could be linked, FALSE otherwise.
1710  */
1711 gboolean
1712 gst_element_link_filtered (GstElement * src, GstElement * dest,
1713     GstCaps * filter)
1714 {
1715   return gst_element_link_pads_filtered (src, NULL, dest, NULL, filter);
1716 }
1717
1718 /**
1719  * gst_element_unlink_pads:
1720  * @src: a #GstElement containing the source pad.
1721  * @srcpadname: the name of the #GstPad in source element.
1722  * @dest: a #GstElement containing the destination pad.
1723  * @destpadname: the name of the #GstPad in destination element.
1724  *
1725  * Unlinks the two named pads of the source and destination elements.
1726  */
1727 void
1728 gst_element_unlink_pads (GstElement * src, const gchar * srcpadname,
1729     GstElement * dest, const gchar * destpadname)
1730 {
1731   GstPad *srcpad, *destpad;
1732   gboolean srcrequest, destrequest;
1733
1734   srcrequest = destrequest = FALSE;
1735
1736   g_return_if_fail (src != NULL);
1737   g_return_if_fail (GST_IS_ELEMENT (src));
1738   g_return_if_fail (srcpadname != NULL);
1739   g_return_if_fail (dest != NULL);
1740   g_return_if_fail (GST_IS_ELEMENT (dest));
1741   g_return_if_fail (destpadname != NULL);
1742
1743   /* obtain the pads requested */
1744   if (!(srcpad = gst_element_get_static_pad (src, srcpadname)))
1745     if ((srcpad = gst_element_get_request_pad (src, srcpadname)))
1746       srcrequest = TRUE;
1747   if (srcpad == NULL) {
1748     GST_WARNING_OBJECT (src, "source element has no pad \"%s\"", srcpadname);
1749     return;
1750   }
1751   if (!(destpad = gst_element_get_static_pad (dest, destpadname)))
1752     if ((destpad = gst_element_get_request_pad (dest, destpadname)))
1753       destrequest = TRUE;
1754   if (destpad == NULL) {
1755     GST_WARNING_OBJECT (dest, "destination element has no pad \"%s\"",
1756         destpadname);
1757     goto free_src;
1758   }
1759
1760   /* we're satisified they can be unlinked, let's do it */
1761   gst_pad_unlink (srcpad, destpad);
1762
1763   if (destrequest)
1764     gst_element_release_request_pad (dest, destpad);
1765   gst_object_unref (destpad);
1766
1767 free_src:
1768   if (srcrequest)
1769     gst_element_release_request_pad (src, srcpad);
1770   gst_object_unref (srcpad);
1771 }
1772
1773 /**
1774  * gst_element_unlink_many:
1775  * @element_1: the first #GstElement in the link chain.
1776  * @element_2: the second #GstElement in the link chain.
1777  * @...: the NULL-terminated list of elements to unlink in order.
1778  *
1779  * Unlinks a series of elements. Uses gst_element_unlink().
1780  */
1781 void
1782 gst_element_unlink_many (GstElement * element_1, GstElement * element_2, ...)
1783 {
1784   va_list args;
1785
1786   g_return_if_fail (element_1 != NULL && element_2 != NULL);
1787   g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));
1788
1789   va_start (args, element_2);
1790
1791   while (element_2) {
1792     gst_element_unlink (element_1, element_2);
1793
1794     element_1 = element_2;
1795     element_2 = va_arg (args, GstElement *);
1796   }
1797
1798   va_end (args);
1799 }
1800
1801 /**
1802  * gst_element_unlink:
1803  * @src: the source #GstElement to unlink.
1804  * @dest: the sink #GstElement to unlink.
1805  *
1806  * Unlinks all source pads of the source element with all sink pads
1807  * of the sink element to which they are linked.
1808  *
1809  * If the link has been made using gst_element_link(), it could have created an
1810  * requestpad, which has to be released using gst_element_release_request_pad().
1811  */
1812 void
1813 gst_element_unlink (GstElement * src, GstElement * dest)
1814 {
1815   GstIterator *pads;
1816   gboolean done = FALSE;
1817
1818   g_return_if_fail (GST_IS_ELEMENT (src));
1819   g_return_if_fail (GST_IS_ELEMENT (dest));
1820
1821   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unlinking \"%s\" and \"%s\"",
1822       GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1823
1824   pads = gst_element_iterate_pads (src);
1825   while (!done) {
1826     gpointer data;
1827
1828     switch (gst_iterator_next (pads, &data)) {
1829       case GST_ITERATOR_OK:
1830       {
1831         GstPad *pad = GST_PAD_CAST (data);
1832
1833         if (GST_PAD_IS_SRC (pad)) {
1834           GstPad *peerpad = gst_pad_get_peer (pad);
1835
1836           /* see if the pad is linked and is really a pad of dest */
1837           if (peerpad) {
1838             GstElement *peerelem;
1839
1840             peerelem = gst_pad_get_parent_element (peerpad);
1841
1842             if (peerelem == dest) {
1843               gst_pad_unlink (pad, peerpad);
1844             }
1845             if (peerelem)
1846               gst_object_unref (peerelem);
1847
1848             gst_object_unref (peerpad);
1849           }
1850         }
1851         gst_object_unref (pad);
1852         break;
1853       }
1854       case GST_ITERATOR_RESYNC:
1855         gst_iterator_resync (pads);
1856         break;
1857       case GST_ITERATOR_DONE:
1858         done = TRUE;
1859         break;
1860       default:
1861         g_assert_not_reached ();
1862         break;
1863     }
1864   }
1865   gst_iterator_free (pads);
1866 }
1867
1868 /**
1869  * gst_element_query_position:
1870  * @element: a #GstElement to invoke the position query on.
1871  * @format: a pointer to the #GstFormat asked for.
1872  *          On return contains the #GstFormat used.
1873  * @cur: A location in which to store the current position, or NULL.
1874  *
1875  * Queries an element for the stream position.
1876  *
1877  * Returns: TRUE if the query could be performed.
1878  */
1879 gboolean
1880 gst_element_query_position (GstElement * element, GstFormat * format,
1881     gint64 * cur)
1882 {
1883   GstQuery *query;
1884   gboolean ret;
1885
1886   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1887   g_return_val_if_fail (format != NULL, FALSE);
1888
1889   query = gst_query_new_position (*format);
1890   ret = gst_element_query (element, query);
1891
1892   if (ret)
1893     gst_query_parse_position (query, format, cur);
1894
1895   gst_query_unref (query);
1896
1897   return ret;
1898 }
1899
1900 /**
1901  * gst_element_query_duration:
1902  * @element: a #GstElement to invoke the duration query on.
1903  * @format: a pointer to the #GstFormat asked for.
1904  *          On return contains the #GstFormat used.
1905  * @duration: A location in which to store the total duration, or NULL.
1906  *
1907  * Queries an element for the total stream duration.
1908  *
1909  * Returns: TRUE if the query could be performed.
1910  */
1911 gboolean
1912 gst_element_query_duration (GstElement * element, GstFormat * format,
1913     gint64 * duration)
1914 {
1915   GstQuery *query;
1916   gboolean ret;
1917
1918   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1919   g_return_val_if_fail (format != NULL, FALSE);
1920
1921   query = gst_query_new_duration (*format);
1922   ret = gst_element_query (element, query);
1923
1924   if (ret)
1925     gst_query_parse_duration (query, format, duration);
1926
1927   gst_query_unref (query);
1928
1929   return ret;
1930 }
1931
1932 /**
1933  * gst_element_query_convert:
1934  * @element: a #GstElement to invoke the convert query on.
1935  * @src_format: a #GstFormat to convert from.
1936  * @src_val: a value to convert.
1937  * @dest_format: a pointer to the #GstFormat to convert to.
1938  * @dest_val: a pointer to the result.
1939  *
1940  * Queries an element to convert @src_val in @src_format to @dest_format.
1941  *
1942  * Returns: TRUE if the query could be performed.
1943  */
1944 gboolean
1945 gst_element_query_convert (GstElement * element, GstFormat src_format,
1946     gint64 src_val, GstFormat * dest_format, gint64 * dest_val)
1947 {
1948   GstQuery *query;
1949   gboolean ret;
1950
1951   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1952   g_return_val_if_fail (dest_format != NULL, FALSE);
1953   g_return_val_if_fail (dest_val != NULL, FALSE);
1954
1955   if (*dest_format == src_format) {
1956     *dest_val = src_val;
1957     return TRUE;
1958   }
1959
1960   query = gst_query_new_convert (src_format, src_val, *dest_format);
1961   ret = gst_element_query (element, query);
1962
1963   if (ret)
1964     gst_query_parse_convert (query, NULL, NULL, dest_format, dest_val);
1965
1966   gst_query_unref (query);
1967
1968   return ret;
1969 }
1970
1971 /**
1972  * gst_element_seek_simple
1973  * @element: a #GstElement to seek on
1974  * @format: a #GstFormat to execute the seek in, such as #GST_FORMAT_TIME
1975  * @seek_flags: seek options; playback applications will usually want to use
1976  *            GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT here
1977  * @seek_pos: position to seek to (relative to the start); if you are doing
1978  *            a seek in #GST_FORMAT_TIME this value is in nanoseconds -
1979  *            multiply with #GST_SECOND to convert seconds to nanoseconds or
1980  *            with #GST_MSECOND to convert milliseconds to nanoseconds.
1981  *
1982  * Simple API to perform a seek on the given element, meaning it just seeks
1983  * to the given position relative to the start of the stream. For more complex
1984  * operations like segment seeks (e.g. for looping) or changing the playback
1985  * rate or seeking relative to the last configured playback segment you should
1986  * use gst_element_seek().
1987  *
1988  * In a completely prerolled PAUSED or PLAYING pipeline, seeking is always
1989  * guaranteed to return %TRUE on a seekable media type or %FALSE when the media
1990  * type is certainly not seekable (such as a live stream).
1991  *
1992  * Some elements allow for seeking in the READY state, in this
1993  * case they will store the seek event and execute it when they are put to
1994  * PAUSED. If the element supports seek in READY, it will always return %TRUE when
1995  * it receives the event in the READY state.
1996  *
1997  * Returns: %TRUE if the seek operation succeeded (the seek might not always be
1998  * executed instantly though)
1999  *
2000  * Since: 0.10.7
2001  */
2002 gboolean
2003 gst_element_seek_simple (GstElement * element, GstFormat format,
2004     GstSeekFlags seek_flags, gint64 seek_pos)
2005 {
2006   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2007   g_return_val_if_fail (seek_pos >= 0, FALSE);
2008
2009   return gst_element_seek (element, 1.0, format, seek_flags,
2010       GST_SEEK_TYPE_SET, seek_pos, GST_SEEK_TYPE_NONE, 0);
2011 }
2012
2013 /**
2014  * gst_pad_use_fixed_caps:
2015  * @pad: the pad to use
2016  *
2017  * A helper function you can use that sets the
2018  * @gst_pad_get_fixed_caps_func as the getcaps function for the
2019  * pad. This way the function will always return the negotiated caps
2020  * or in case the pad is not negotiated, the padtemplate caps.
2021  *
2022  * Use this function on a pad that, once _set_caps() has been called
2023  * on it, cannot be renegotiated to something else.
2024  */
2025 void
2026 gst_pad_use_fixed_caps (GstPad * pad)
2027 {
2028   gst_pad_set_getcaps_function (pad, gst_pad_get_fixed_caps_func);
2029 }
2030
2031 /**
2032  * gst_pad_get_fixed_caps_func:
2033  * @pad: the pad to use
2034  *
2035  * A helper function you can use as a GetCaps function that
2036  * will return the currently negotiated caps or the padtemplate
2037  * when NULL.
2038  *
2039  * Returns: The currently negotiated caps or the padtemplate.
2040  */
2041 GstCaps *
2042 gst_pad_get_fixed_caps_func (GstPad * pad)
2043 {
2044   GstCaps *result;
2045
2046   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2047
2048   GST_OBJECT_LOCK (pad);
2049   if (GST_PAD_CAPS (pad)) {
2050     result = GST_PAD_CAPS (pad);
2051
2052     GST_CAT_DEBUG (GST_CAT_CAPS,
2053         "using pad caps %p %" GST_PTR_FORMAT, result, result);
2054
2055     result = gst_caps_ref (result);
2056   } else if (GST_PAD_PAD_TEMPLATE (pad)) {
2057     GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad);
2058
2059     result = GST_PAD_TEMPLATE_CAPS (templ);
2060     GST_CAT_DEBUG (GST_CAT_CAPS,
2061         "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
2062         result);
2063
2064     result = gst_caps_ref (result);
2065   } else {
2066     GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps");
2067     result = gst_caps_new_empty ();
2068   }
2069   GST_OBJECT_UNLOCK (pad);
2070
2071   return result;
2072 }
2073
2074 /**
2075  * gst_pad_get_parent_element:
2076  * @pad: a pad
2077  *
2078  * Gets the parent of @pad, cast to a #GstElement. If a @pad has no parent or
2079  * its parent is not an element, return NULL.
2080  *
2081  * Returns: The parent of the pad. The caller has a reference on the parent, so
2082  * unref when you're finished with it.
2083  *
2084  * MT safe.
2085  */
2086 GstElement *
2087 gst_pad_get_parent_element (GstPad * pad)
2088 {
2089   GstObject *p;
2090
2091   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2092
2093   p = gst_object_get_parent (GST_OBJECT_CAST (pad));
2094
2095   if (p && !GST_IS_ELEMENT (p)) {
2096     gst_object_unref (p);
2097     p = NULL;
2098   }
2099   return GST_ELEMENT_CAST (p);
2100 }
2101
2102 /**
2103  * gst_object_default_error:
2104  * @source: the #GstObject that initiated the error.
2105  * @error: the GError.
2106  * @debug: an additional debug information string, or NULL.
2107  *
2108  * A default error function.
2109  *
2110  * The default handler will simply print the error string using g_print.
2111  */
2112 void
2113 gst_object_default_error (GstObject * source, GError * error, gchar * debug)
2114 {
2115   gchar *name = gst_object_get_path_string (source);
2116
2117   g_print (_("ERROR: from element %s: %s\n"), name, error->message);
2118   if (debug)
2119     g_print (_("Additional debug info:\n%s\n"), debug);
2120
2121   g_free (name);
2122 }
2123
2124 /**
2125  * gst_bin_add_many:
2126  * @bin: a #GstBin
2127  * @element_1: the #GstElement element to add to the bin
2128  * @...: additional elements to add to the bin
2129  *
2130  * Adds a NULL-terminated list of elements to a bin.  This function is
2131  * equivalent to calling gst_bin_add() for each member of the list. The return
2132  * value of each gst_bin_add() is ignored.
2133  */
2134 void
2135 gst_bin_add_many (GstBin * bin, GstElement * element_1, ...)
2136 {
2137   va_list args;
2138
2139   g_return_if_fail (GST_IS_BIN (bin));
2140   g_return_if_fail (GST_IS_ELEMENT (element_1));
2141
2142   va_start (args, element_1);
2143
2144   while (element_1) {
2145     gst_bin_add (bin, element_1);
2146
2147     element_1 = va_arg (args, GstElement *);
2148   }
2149
2150   va_end (args);
2151 }
2152
2153 /**
2154  * gst_bin_remove_many:
2155  * @bin: a #GstBin
2156  * @element_1: the first #GstElement to remove from the bin
2157  * @...: NULL-terminated list of elements to remove from the bin
2158  *
2159  * Remove a list of elements from a bin. This function is equivalent
2160  * to calling gst_bin_remove() with each member of the list.
2161  */
2162 void
2163 gst_bin_remove_many (GstBin * bin, GstElement * element_1, ...)
2164 {
2165   va_list args;
2166
2167   g_return_if_fail (GST_IS_BIN (bin));
2168   g_return_if_fail (GST_IS_ELEMENT (element_1));
2169
2170   va_start (args, element_1);
2171
2172   while (element_1) {
2173     gst_bin_remove (bin, element_1);
2174
2175     element_1 = va_arg (args, GstElement *);
2176   }
2177
2178   va_end (args);
2179 }
2180
2181 static void
2182 gst_element_populate_std_props (GObjectClass * klass, const gchar * prop_name,
2183     guint arg_id, GParamFlags flags)
2184 {
2185   GQuark prop_id = g_quark_from_string (prop_name);
2186   GParamSpec *pspec;
2187
2188   static GQuark fd_id = 0;
2189   static GQuark blocksize_id;
2190   static GQuark bytesperread_id;
2191   static GQuark dump_id;
2192   static GQuark filesize_id;
2193   static GQuark mmapsize_id;
2194   static GQuark location_id;
2195   static GQuark offset_id;
2196   static GQuark silent_id;
2197   static GQuark touch_id;
2198
2199   if (!fd_id) {
2200     fd_id = g_quark_from_static_string ("fd");
2201     blocksize_id = g_quark_from_static_string ("blocksize");
2202     bytesperread_id = g_quark_from_static_string ("bytesperread");
2203     dump_id = g_quark_from_static_string ("dump");
2204     filesize_id = g_quark_from_static_string ("filesize");
2205     mmapsize_id = g_quark_from_static_string ("mmapsize");
2206     location_id = g_quark_from_static_string ("location");
2207     offset_id = g_quark_from_static_string ("offset");
2208     silent_id = g_quark_from_static_string ("silent");
2209     touch_id = g_quark_from_static_string ("touch");
2210   }
2211
2212   if (prop_id == fd_id) {
2213     pspec = g_param_spec_int ("fd", "File-descriptor",
2214         "File-descriptor for the file being read", 0, G_MAXINT, 0, flags);
2215   } else if (prop_id == blocksize_id) {
2216     pspec = g_param_spec_ulong ("blocksize", "Block Size",
2217         "Block size to read per buffer", 0, G_MAXULONG, 4096, flags);
2218
2219   } else if (prop_id == bytesperread_id) {
2220     pspec = g_param_spec_int ("bytesperread", "Bytes per read",
2221         "Number of bytes to read per buffer", G_MININT, G_MAXINT, 0, flags);
2222
2223   } else if (prop_id == dump_id) {
2224     pspec = g_param_spec_boolean ("dump", "Dump",
2225         "Dump bytes to stdout", FALSE, flags);
2226
2227   } else if (prop_id == filesize_id) {
2228     pspec = g_param_spec_int64 ("filesize", "File Size",
2229         "Size of the file being read", 0, G_MAXINT64, 0, flags);
2230
2231   } else if (prop_id == mmapsize_id) {
2232     pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
2233         "Size in bytes of mmap()d regions", 0, G_MAXULONG, 4 * 1048576, flags);
2234
2235   } else if (prop_id == location_id) {
2236     pspec = g_param_spec_string ("location", "File Location",
2237         "Location of the file to read", NULL, flags);
2238
2239   } else if (prop_id == offset_id) {
2240     pspec = g_param_spec_int64 ("offset", "File Offset",
2241         "Byte offset of current read pointer", 0, G_MAXINT64, 0, flags);
2242
2243   } else if (prop_id == silent_id) {
2244     pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
2245         FALSE, flags);
2246
2247   } else if (prop_id == touch_id) {
2248     pspec = g_param_spec_boolean ("touch", "Touch read data",
2249         "Touch data to force disk read before " "push ()", TRUE, flags);
2250   } else {
2251     g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
2252         prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
2253     pspec = NULL;
2254   }
2255
2256   if (pspec) {
2257     g_object_class_install_property (klass, arg_id, pspec);
2258   }
2259 }
2260
2261 /**
2262  * gst_element_class_install_std_props:
2263  * @klass: the #GstElementClass to add the properties to.
2264  * @first_name: the name of the first property.
2265  * in a NULL terminated
2266  * @...: the id and flags of the first property, followed by
2267  * further 'name', 'id', 'flags' triplets and terminated by NULL.
2268  *
2269  * Adds a list of standardized properties with types to the @klass.
2270  * the id is for the property switch in your get_prop method, and
2271  * the flags determine readability / writeability.
2272  **/
2273 void
2274 gst_element_class_install_std_props (GstElementClass * klass,
2275     const gchar * first_name, ...)
2276 {
2277   const char *name;
2278
2279   va_list args;
2280
2281   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
2282
2283   va_start (args, first_name);
2284
2285   name = first_name;
2286
2287   while (name) {
2288     int arg_id = va_arg (args, int);
2289     int flags = va_arg (args, int);
2290
2291     gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id,
2292         flags);
2293
2294     name = va_arg (args, char *);
2295   }
2296
2297   va_end (args);
2298 }
2299
2300
2301 /**
2302  * gst_buffer_merge:
2303  * @buf1: the first source #GstBuffer to merge.
2304  * @buf2: the second source #GstBuffer to merge.
2305  *
2306  * Create a new buffer that is the concatenation of the two source
2307  * buffers.  The original source buffers will not be modified or
2308  * unref'd.  Make sure you unref the source buffers if they are not used
2309  * anymore afterwards.
2310  *
2311  * If the buffers point to contiguous areas of memory, the buffer
2312  * is created without copying the data.
2313  *
2314  * Returns: the new #GstBuffer which is the concatenation of the source buffers.
2315  */
2316 GstBuffer *
2317 gst_buffer_merge (GstBuffer * buf1, GstBuffer * buf2)
2318 {
2319   GstBuffer *result;
2320
2321   /* we're just a specific case of the more general gst_buffer_span() */
2322   result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
2323
2324   return result;
2325 }
2326
2327 /**
2328  * gst_buffer_join:
2329  * @buf1: the first source #GstBuffer.
2330  * @buf2: the second source #GstBuffer.
2331  *
2332  * Create a new buffer that is the concatenation of the two source
2333  * buffers, and unrefs the original source buffers.
2334  *
2335  * If the buffers point to contiguous areas of memory, the buffer
2336  * is created without copying the data.
2337  *
2338  * This is a convenience function for C programmers. See also 
2339  * gst_buffer_merge(), which does the same thing without 
2340  * unreffing the input parameters. Language bindings without 
2341  * explicit reference counting should not wrap this function.
2342  *
2343  * Returns: the new #GstBuffer which is the concatenation of the source buffers.
2344  */
2345 GstBuffer *
2346 gst_buffer_join (GstBuffer * buf1, GstBuffer * buf2)
2347 {
2348   GstBuffer *result;
2349
2350   result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
2351   gst_buffer_unref (buf1);
2352   gst_buffer_unref (buf2);
2353
2354   return result;
2355 }
2356
2357
2358 /**
2359  * gst_buffer_stamp:
2360  * @dest: buffer to stamp
2361  * @src: buffer to stamp from
2362  *
2363  * Copies additional information (the timestamp, duration, and offset start
2364  * and end) from one buffer to the other.
2365  *
2366  * This function does not copy any buffer flags or caps and is equivalent to
2367  * gst_buffer_copy_metadata(@dest, @src, GST_BUFFER_COPY_TIMESTAMPS).
2368  *
2369  * Deprecated: use gst_buffer_copy_metadata() instead, it provides more
2370  * control.
2371  */
2372 #ifndef GST_REMOVE_DEPRECATED
2373 void
2374 gst_buffer_stamp (GstBuffer * dest, const GstBuffer * src)
2375 {
2376   gst_buffer_copy_metadata (dest, src, GST_BUFFER_COPY_TIMESTAMPS);
2377 }
2378 #endif /* GST_REMOVE_DEPRECATED */
2379
2380 static gboolean
2381 intersect_caps_func (GstPad * pad, GValue * ret, GstPad * orig)
2382 {
2383   /* skip the pad, the request came from */
2384   if (pad != orig) {
2385     GstCaps *peercaps, *existing;
2386
2387     existing = g_value_get_pointer (ret);
2388     peercaps = gst_pad_peer_get_caps (pad);
2389     if (peercaps == NULL)
2390       peercaps = gst_caps_new_any ();
2391     g_value_set_pointer (ret, gst_caps_intersect (existing, peercaps));
2392     gst_caps_unref (existing);
2393     gst_caps_unref (peercaps);
2394   }
2395   gst_object_unref (pad);
2396   return TRUE;
2397 }
2398
2399 /**
2400  * gst_pad_proxy_getcaps:
2401  * @pad: a #GstPad to proxy.
2402  *
2403  * Calls gst_pad_get_allowed_caps() for every other pad belonging to the
2404  * same element as @pad, and returns the intersection of the results.
2405  *
2406  * This function is useful as a default getcaps function for an element
2407  * that can handle any stream format, but requires all its pads to have
2408  * the same caps.  Two such elements are tee and aggregator.
2409  *
2410  * Returns: the intersection of the other pads' allowed caps.
2411  */
2412 GstCaps *
2413 gst_pad_proxy_getcaps (GstPad * pad)
2414 {
2415   GstElement *element;
2416   GstCaps *caps, *intersected;
2417   GstIterator *iter;
2418   GstIteratorResult res;
2419   GValue ret = { 0, };
2420
2421   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2422
2423   GST_CAT_DEBUG (GST_CAT_PADS, "proxying getcaps for %s:%s",
2424       GST_DEBUG_PAD_NAME (pad));
2425
2426   element = gst_pad_get_parent_element (pad);
2427   if (element == NULL)
2428     return NULL;
2429
2430   /* value to hold the return, by default it holds ANY, the ref is taken by
2431    * the GValue. */
2432   g_value_init (&ret, G_TYPE_POINTER);
2433   g_value_set_pointer (&ret, gst_caps_new_any ());
2434
2435   iter = gst_element_iterate_pads (element);
2436   while (1) {
2437     res =
2438         gst_iterator_fold (iter, (GstIteratorFoldFunction) intersect_caps_func,
2439         &ret, pad);
2440     switch (res) {
2441       case GST_ITERATOR_RESYNC:
2442         /* unref any value stored */
2443         if ((caps = g_value_get_pointer (&ret)))
2444           gst_caps_unref (caps);
2445         /* need to reset the result again to ANY */
2446         g_value_set_pointer (&ret, gst_caps_new_any ());
2447         gst_iterator_resync (iter);
2448         break;
2449       case GST_ITERATOR_DONE:
2450         /* all pads iterated, return collected value */
2451         goto done;
2452       default:
2453         /* iterator returned _ERROR or premature end with _OK,
2454          * mark an error and exit */
2455         if ((caps = g_value_get_pointer (&ret)))
2456           gst_caps_unref (caps);
2457         g_value_set_pointer (&ret, NULL);
2458         goto error;
2459     }
2460   }
2461 done:
2462   gst_iterator_free (iter);
2463
2464   gst_object_unref (element);
2465
2466   caps = g_value_get_pointer (&ret);
2467   g_value_unset (&ret);
2468
2469   intersected = gst_caps_intersect (caps, gst_pad_get_pad_template_caps (pad));
2470   gst_caps_unref (caps);
2471
2472   return intersected;
2473
2474   /* ERRORS */
2475 error:
2476   {
2477     g_warning ("Pad list returned error on element %s",
2478         GST_ELEMENT_NAME (element));
2479     gst_iterator_free (iter);
2480     gst_object_unref (element);
2481     return NULL;
2482   }
2483 }
2484
2485 typedef struct
2486 {
2487   GstPad *orig;
2488   GstCaps *caps;
2489 } LinkData;
2490
2491 static gboolean
2492 link_fold_func (GstPad * pad, GValue * ret, LinkData * data)
2493 {
2494   gboolean success = TRUE;
2495
2496   if (pad != data->orig) {
2497     success = gst_pad_set_caps (pad, data->caps);
2498     g_value_set_boolean (ret, success);
2499   }
2500   gst_object_unref (pad);
2501
2502   return success;
2503 }
2504
2505 /**
2506  * gst_pad_proxy_setcaps
2507  * @pad: a #GstPad to proxy from
2508  * @caps: the #GstCaps to link with
2509  *
2510  * Calls gst_pad_set_caps() for every other pad belonging to the
2511  * same element as @pad.  If gst_pad_set_caps() fails on any pad,
2512  * the proxy setcaps fails. May be used only during negotiation.
2513  *
2514  * Returns: TRUE if sucessful
2515  */
2516 gboolean
2517 gst_pad_proxy_setcaps (GstPad * pad, GstCaps * caps)
2518 {
2519   GstElement *element;
2520   GstIterator *iter;
2521   GstIteratorResult res;
2522   GValue ret = { 0, };
2523   LinkData data;
2524
2525   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2526   g_return_val_if_fail (caps != NULL, FALSE);
2527
2528   GST_CAT_DEBUG (GST_CAT_PADS, "proxying pad link for %s:%s",
2529       GST_DEBUG_PAD_NAME (pad));
2530
2531   element = gst_pad_get_parent_element (pad);
2532   if (element == NULL)
2533     return FALSE;
2534
2535   iter = gst_element_iterate_pads (element);
2536
2537   g_value_init (&ret, G_TYPE_BOOLEAN);
2538   g_value_set_boolean (&ret, TRUE);
2539   data.orig = pad;
2540   data.caps = caps;
2541
2542   res = gst_iterator_fold (iter, (GstIteratorFoldFunction) link_fold_func,
2543       &ret, &data);
2544   gst_iterator_free (iter);
2545
2546   if (res != GST_ITERATOR_DONE)
2547     goto pads_changed;
2548
2549   gst_object_unref (element);
2550
2551   /* ok not to unset the gvalue */
2552   return g_value_get_boolean (&ret);
2553
2554   /* ERRORS */
2555 pads_changed:
2556   {
2557     g_warning ("Pad list changed during proxy_pad_link for element %s",
2558         GST_ELEMENT_NAME (element));
2559     gst_object_unref (element);
2560     return FALSE;
2561   }
2562 }
2563
2564 /**
2565  * gst_pad_query_position:
2566  * @pad: a #GstPad to invoke the position query on.
2567  * @format: a pointer to the #GstFormat asked for.
2568  *          On return contains the #GstFormat used.
2569  * @cur: A location in which to store the current position, or NULL.
2570  *
2571  * Queries a pad for the stream position.
2572  *
2573  * Returns: TRUE if the query could be performed.
2574  */
2575 gboolean
2576 gst_pad_query_position (GstPad * pad, GstFormat * format, gint64 * cur)
2577 {
2578   GstQuery *query;
2579   gboolean ret;
2580
2581   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2582   g_return_val_if_fail (format != NULL, FALSE);
2583
2584   query = gst_query_new_position (*format);
2585   ret = gst_pad_query (pad, query);
2586
2587   if (ret)
2588     gst_query_parse_position (query, format, cur);
2589
2590   gst_query_unref (query);
2591
2592   return ret;
2593 }
2594
2595 /**
2596  * gst_pad_query_peer_position:
2597  * @pad: a #GstPad on whose peer to invoke the position query on.
2598  *       Must be a sink pad.
2599  * @format: a pointer to the #GstFormat asked for.
2600  *          On return contains the #GstFormat used.
2601  * @cur: A location in which to store the current position, or NULL.
2602  *
2603  * Queries the peer of a given sink pad for the stream position.
2604  *
2605  * Returns: TRUE if the query could be performed.
2606  */
2607 gboolean
2608 gst_pad_query_peer_position (GstPad * pad, GstFormat * format, gint64 * cur)
2609 {
2610   gboolean ret = FALSE;
2611   GstPad *peer;
2612
2613   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2614   g_return_val_if_fail (GST_PAD_IS_SINK (pad), FALSE);
2615   g_return_val_if_fail (format != NULL, FALSE);
2616
2617   peer = gst_pad_get_peer (pad);
2618   if (peer) {
2619     ret = gst_pad_query_position (peer, format, cur);
2620     gst_object_unref (peer);
2621   }
2622
2623   return ret;
2624 }
2625
2626 /**
2627  * gst_pad_query_duration:
2628  * @pad: a #GstPad to invoke the duration query on.
2629  * @format: a pointer to the #GstFormat asked for.
2630  *          On return contains the #GstFormat used.
2631  * @duration: A location in which to store the total duration, or NULL.
2632  *
2633  * Queries a pad for the total stream duration.
2634  *
2635  * Returns: TRUE if the query could be performed.
2636  */
2637 gboolean
2638 gst_pad_query_duration (GstPad * pad, GstFormat * format, gint64 * duration)
2639 {
2640   GstQuery *query;
2641   gboolean ret;
2642
2643   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2644   g_return_val_if_fail (format != NULL, FALSE);
2645
2646   query = gst_query_new_duration (*format);
2647   ret = gst_pad_query (pad, query);
2648
2649   if (ret)
2650     gst_query_parse_duration (query, format, duration);
2651
2652   gst_query_unref (query);
2653
2654   return ret;
2655 }
2656
2657 /**
2658  * gst_pad_query_peer_duration:
2659  * @pad: a #GstPad on whose peer pad to invoke the duration query on.
2660  *       Must be a sink pad.
2661  * @format: a pointer to the #GstFormat asked for.
2662  *          On return contains the #GstFormat used.
2663  * @duration: A location in which to store the total duration, or NULL.
2664  *
2665  * Queries the peer pad of a given sink pad for the total stream duration.
2666  *
2667  * Returns: TRUE if the query could be performed.
2668  */
2669 gboolean
2670 gst_pad_query_peer_duration (GstPad * pad, GstFormat * format,
2671     gint64 * duration)
2672 {
2673   gboolean ret = FALSE;
2674   GstPad *peer;
2675
2676   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2677   g_return_val_if_fail (GST_PAD_IS_SINK (pad), FALSE);
2678   g_return_val_if_fail (format != NULL, FALSE);
2679
2680   peer = gst_pad_get_peer (pad);
2681   if (peer) {
2682     ret = gst_pad_query_duration (peer, format, duration);
2683     gst_object_unref (peer);
2684   }
2685
2686   return ret;
2687 }
2688
2689 /**
2690  * gst_pad_query_convert:
2691  * @pad: a #GstPad to invoke the convert query on.
2692  * @src_format: a #GstFormat to convert from.
2693  * @src_val: a value to convert.
2694  * @dest_format: a pointer to the #GstFormat to convert to.
2695  * @dest_val: a pointer to the result.
2696  *
2697  * Queries a pad to convert @src_val in @src_format to @dest_format.
2698  *
2699  * Returns: TRUE if the query could be performed.
2700  */
2701 gboolean
2702 gst_pad_query_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
2703     GstFormat * dest_format, gint64 * dest_val)
2704 {
2705   GstQuery *query;
2706   gboolean ret;
2707
2708   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2709   g_return_val_if_fail (dest_format != NULL, FALSE);
2710   g_return_val_if_fail (dest_val != NULL, FALSE);
2711
2712   if (*dest_format == src_format) {
2713     *dest_val = src_val;
2714     return TRUE;
2715   }
2716
2717   query = gst_query_new_convert (src_format, src_val, *dest_format);
2718   ret = gst_pad_query (pad, query);
2719
2720   if (ret)
2721     gst_query_parse_convert (query, NULL, NULL, dest_format, dest_val);
2722
2723   gst_query_unref (query);
2724
2725   return ret;
2726 }
2727
2728 /**
2729  * gst_pad_query_peer_convert:
2730  * @pad: a #GstPad, on whose peer pad to invoke the convert query on.
2731  *       Must be a sink pad.
2732  * @src_format: a #GstFormat to convert from.
2733  * @src_val: a value to convert.
2734  * @dest_format: a pointer to the #GstFormat to convert to.
2735  * @dest_val: a pointer to the result.
2736  *
2737  * Queries the peer pad of a given sink pad to convert @src_val in @src_format
2738  * to @dest_format.
2739  *
2740  * Returns: TRUE if the query could be performed.
2741  */
2742 gboolean
2743 gst_pad_query_peer_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
2744     GstFormat * dest_format, gint64 * dest_val)
2745 {
2746   gboolean ret = FALSE;
2747   GstPad *peer;
2748
2749   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2750   g_return_val_if_fail (GST_PAD_IS_SINK (pad), FALSE);
2751   g_return_val_if_fail (src_val >= 0, FALSE);
2752   g_return_val_if_fail (dest_format != NULL, FALSE);
2753   g_return_val_if_fail (dest_val != NULL, FALSE);
2754
2755   peer = gst_pad_get_peer (pad);
2756   if (peer) {
2757     ret = gst_pad_query_convert (peer, src_format, src_val, dest_format,
2758         dest_val);
2759     gst_object_unref (peer);
2760   }
2761
2762   return ret;
2763 }
2764
2765 /**
2766  * gst_atomic_int_set:
2767  * @atomic_int: pointer to an atomic integer
2768  * @value: value to set
2769  *
2770  * Unconditionally sets the atomic integer to @value.
2771  * 
2772  * Deprecated: Use g_atomic_int_set().
2773  *
2774  */
2775 #ifndef GST_REMOVE_DEPRECATED
2776 void
2777 gst_atomic_int_set (gint * atomic_int, gint value)
2778 {
2779   g_atomic_int_set (atomic_int, value);
2780 }
2781 #endif
2782
2783 /**
2784  * gst_pad_add_data_probe:
2785  * @pad: pad to add the data probe handler to
2786  * @handler: function to call when data is passed over pad
2787  * @data: data to pass along with the handler
2788  *
2789  * Adds a "data probe" to a pad. This function will be called whenever data
2790  * passes through a pad. In this case data means both events and buffers. The
2791  * probe will be called with the data as an argument, meaning @handler should
2792  * have the same callback signature as the #GstPad::have-data signal.
2793  * Note that the data will have a reference count greater than 1, so it will
2794  * be immutable -- you must not change it.
2795  *
2796  * For source pads, the probe will be called after the blocking function, if any
2797  * (see gst_pad_set_blocked_async()), but before looking up the peer to chain
2798  * to. For sink pads, the probe function will be called before configuring the
2799  * sink with new caps, if any, and before calling the pad's chain function.
2800  *
2801  * Your data probe should return TRUE to let the data continue to flow, or FALSE
2802  * to drop it. Dropping data is rarely useful, but occasionally comes in handy
2803  * with events.
2804  *
2805  * Although probes are implemented internally by connecting @handler to the
2806  * have-data signal on the pad, if you want to remove a probe it is insufficient
2807  * to only call g_signal_handler_disconnect on the returned handler id. To
2808  * remove a probe, use the appropriate function, such as
2809  * gst_pad_remove_data_probe().
2810  *
2811  * Returns: The handler id.
2812  */
2813 gulong
2814 gst_pad_add_data_probe (GstPad * pad, GCallback handler, gpointer data)
2815 {
2816   return gst_pad_add_data_probe_full (pad, handler, data, NULL);
2817 }
2818
2819 /**
2820  * gst_pad_add_data_probe_full:
2821  * @pad: pad to add the data probe handler to
2822  * @handler: function to call when data is passed over pad
2823  * @data: data to pass along with the handler
2824  * @notify: function to call when the probe is disconnected, or NULL
2825  *
2826  * Adds a "data probe" to a pad. This function will be called whenever data
2827  * passes through a pad. In this case data means both events and buffers. The
2828  * probe will be called with the data as an argument, meaning @handler should
2829  * have the same callback signature as the #GstPad::have-data signal.
2830  * Note that the data will have a reference count greater than 1, so it will
2831  * be immutable -- you must not change it.
2832  *
2833  * For source pads, the probe will be called after the blocking function, if any
2834  * (see gst_pad_set_blocked_async()), but before looking up the peer to chain
2835  * to. For sink pads, the probe function will be called before configuring the
2836  * sink with new caps, if any, and before calling the pad's chain function.
2837  *
2838  * Your data probe should return TRUE to let the data continue to flow, or FALSE
2839  * to drop it. Dropping data is rarely useful, but occasionally comes in handy
2840  * with events.
2841  *
2842  * Although probes are implemented internally by connecting @handler to the
2843  * have-data signal on the pad, if you want to remove a probe it is insufficient
2844  * to only call g_signal_handler_disconnect on the returned handler id. To
2845  * remove a probe, use the appropriate function, such as
2846  * gst_pad_remove_data_probe().
2847  *
2848  * The @notify function is called when the probe is disconnected and usually
2849  * used to free @data.
2850  *
2851  * Returns: The handler id.
2852  *
2853  * Since: 0.10.20
2854  */
2855 gulong
2856 gst_pad_add_data_probe_full (GstPad * pad, GCallback handler,
2857     gpointer data, GDestroyNotify notify)
2858 {
2859   gulong sigid;
2860
2861   g_return_val_if_fail (GST_IS_PAD (pad), 0);
2862   g_return_val_if_fail (handler != NULL, 0);
2863
2864   GST_OBJECT_LOCK (pad);
2865
2866   /* we only expose a GDestroyNotify in our API because that's less confusing */
2867   sigid = g_signal_connect_data (pad, "have-data", handler, data,
2868       (GClosureNotify) notify, 0);
2869
2870   GST_PAD_DO_EVENT_SIGNALS (pad)++;
2871   GST_PAD_DO_BUFFER_SIGNALS (pad)++;
2872   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
2873       "adding data probe, now %d data, %d event probes",
2874       GST_PAD_DO_BUFFER_SIGNALS (pad), GST_PAD_DO_EVENT_SIGNALS (pad));
2875   GST_OBJECT_UNLOCK (pad);
2876
2877   return sigid;
2878 }
2879
2880 /**
2881  * gst_pad_add_event_probe:
2882  * @pad: pad to add the event probe handler to
2883  * @handler: function to call when events are passed over pad
2884  * @data: data to pass along with the handler
2885  *
2886  * Adds a probe that will be called for all events passing through a pad. See
2887  * gst_pad_add_data_probe() for more information.
2888  *
2889  * Returns: The handler id
2890  */
2891 gulong
2892 gst_pad_add_event_probe (GstPad * pad, GCallback handler, gpointer data)
2893 {
2894   return gst_pad_add_event_probe_full (pad, handler, data, NULL);
2895 }
2896
2897 /**
2898  * gst_pad_add_event_probe_full:
2899  * @pad: pad to add the event probe handler to
2900  * @handler: function to call when events are passed over pad
2901  * @data: data to pass along with the handler, or NULL
2902  * @notify: function to call when probe is disconnected, or NULL
2903  *
2904  * Adds a probe that will be called for all events passing through a pad. See
2905  * gst_pad_add_data_probe() for more information.
2906  *
2907  * The @notify function is called when the probe is disconnected and usually
2908  * used to free @data.
2909  *
2910  * Returns: The handler id
2911  *
2912  * Since: 0.10.20
2913  */
2914 gulong
2915 gst_pad_add_event_probe_full (GstPad * pad, GCallback handler,
2916     gpointer data, GDestroyNotify notify)
2917 {
2918   gulong sigid;
2919
2920   g_return_val_if_fail (GST_IS_PAD (pad), 0);
2921   g_return_val_if_fail (handler != NULL, 0);
2922
2923   GST_OBJECT_LOCK (pad);
2924
2925   /* we only expose a GDestroyNotify in our API because that's less confusing */
2926   sigid = g_signal_connect_data (pad, "have-data::event", handler, data,
2927       (GClosureNotify) notify, 0);
2928
2929   GST_PAD_DO_EVENT_SIGNALS (pad)++;
2930   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "adding event probe, now %d probes",
2931       GST_PAD_DO_EVENT_SIGNALS (pad));
2932   GST_OBJECT_UNLOCK (pad);
2933
2934   return sigid;
2935 }
2936
2937 /**
2938  * gst_pad_add_buffer_probe:
2939  * @pad: pad to add the buffer probe handler to
2940  * @handler: function to call when buffers are passed over pad
2941  * @data: data to pass along with the handler
2942  *
2943  * Adds a probe that will be called for all buffers passing through a pad. See
2944  * gst_pad_add_data_probe() for more information.
2945  *
2946  * Returns: The handler id
2947  */
2948 gulong
2949 gst_pad_add_buffer_probe (GstPad * pad, GCallback handler, gpointer data)
2950 {
2951   return gst_pad_add_buffer_probe_full (pad, handler, data, NULL);
2952 }
2953
2954 /**
2955  * gst_pad_add_buffer_probe_full:
2956  * @pad: pad to add the buffer probe handler to
2957  * @handler: function to call when buffer are passed over pad
2958  * @data: data to pass along with the handler
2959  * @notify: function to call when the probe is disconnected, or NULL
2960  *
2961  * Adds a probe that will be called for all buffers passing through a pad. See
2962  * gst_pad_add_data_probe() for more information.
2963  *
2964  * The @notify function is called when the probe is disconnected and usually
2965  * used to free @data.
2966  *
2967  * Returns: The handler id
2968  *
2969  * Since: 0.10.20
2970  */
2971 gulong
2972 gst_pad_add_buffer_probe_full (GstPad * pad, GCallback handler,
2973     gpointer data, GDestroyNotify notify)
2974 {
2975   gulong sigid;
2976
2977   g_return_val_if_fail (GST_IS_PAD (pad), 0);
2978   g_return_val_if_fail (handler != NULL, 0);
2979
2980   GST_OBJECT_LOCK (pad);
2981
2982   /* we only expose a GDestroyNotify in our API because that's less confusing */
2983   sigid = g_signal_connect_data (pad, "have-data::buffer", handler, data,
2984       (GClosureNotify) notify, 0);
2985
2986   GST_PAD_DO_BUFFER_SIGNALS (pad)++;
2987   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "adding buffer probe, now %d probes",
2988       GST_PAD_DO_BUFFER_SIGNALS (pad));
2989   GST_OBJECT_UNLOCK (pad);
2990
2991   return sigid;
2992 }
2993
2994 /**
2995  * gst_pad_remove_data_probe:
2996  * @pad: pad to remove the data probe handler from
2997  * @handler_id: handler id returned from gst_pad_add_data_probe
2998  *
2999  * Removes a data probe from @pad.
3000  */
3001 void
3002 gst_pad_remove_data_probe (GstPad * pad, guint handler_id)
3003 {
3004   g_return_if_fail (GST_IS_PAD (pad));
3005   g_return_if_fail (handler_id > 0);
3006
3007   GST_OBJECT_LOCK (pad);
3008   g_signal_handler_disconnect (pad, handler_id);
3009   GST_PAD_DO_BUFFER_SIGNALS (pad)--;
3010   GST_PAD_DO_EVENT_SIGNALS (pad)--;
3011   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
3012       "removed data probe, now %d event, %d buffer probes",
3013       GST_PAD_DO_EVENT_SIGNALS (pad), GST_PAD_DO_BUFFER_SIGNALS (pad));
3014   GST_OBJECT_UNLOCK (pad);
3015
3016 }
3017
3018 /**
3019  * gst_pad_remove_event_probe:
3020  * @pad: pad to remove the event probe handler from
3021  * @handler_id: handler id returned from gst_pad_add_event_probe
3022  *
3023  * Removes an event probe from @pad.
3024  */
3025 void
3026 gst_pad_remove_event_probe (GstPad * pad, guint handler_id)
3027 {
3028   g_return_if_fail (GST_IS_PAD (pad));
3029   g_return_if_fail (handler_id > 0);
3030
3031   GST_OBJECT_LOCK (pad);
3032   g_signal_handler_disconnect (pad, handler_id);
3033   GST_PAD_DO_EVENT_SIGNALS (pad)--;
3034   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
3035       "removed event probe, now %d event probes",
3036       GST_PAD_DO_EVENT_SIGNALS (pad));
3037   GST_OBJECT_UNLOCK (pad);
3038 }
3039
3040 /**
3041  * gst_pad_remove_buffer_probe:
3042  * @pad: pad to remove the buffer probe handler from
3043  * @handler_id: handler id returned from gst_pad_add_buffer_probe
3044  *
3045  * Removes a buffer probe from @pad.
3046  */
3047 void
3048 gst_pad_remove_buffer_probe (GstPad * pad, guint handler_id)
3049 {
3050   g_return_if_fail (GST_IS_PAD (pad));
3051   g_return_if_fail (handler_id > 0);
3052
3053   GST_OBJECT_LOCK (pad);
3054   g_signal_handler_disconnect (pad, handler_id);
3055   GST_PAD_DO_BUFFER_SIGNALS (pad)--;
3056   GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
3057       "removed buffer probe, now %d buffer probes",
3058       GST_PAD_DO_BUFFER_SIGNALS (pad));
3059   GST_OBJECT_UNLOCK (pad);
3060
3061 }
3062
3063 /**
3064  * gst_element_found_tags_for_pad:
3065  * @element: element for which to post taglist to bus.
3066  * @pad: pad on which to push tag-event.
3067  * @list: the taglist to post on the bus and create event from.
3068  *
3069  * Posts a message to the bus that new tags were found and pushes the
3070  * tags as event. Takes ownership of the @list.
3071  *
3072  * This is a utility method for elements. Applications should use the
3073  * #GstTagSetter interface.
3074  */
3075 void
3076 gst_element_found_tags_for_pad (GstElement * element,
3077     GstPad * pad, GstTagList * list)
3078 {
3079   g_return_if_fail (element != NULL);
3080   g_return_if_fail (pad != NULL);
3081   g_return_if_fail (list != NULL);
3082
3083   gst_pad_push_event (pad, gst_event_new_tag (gst_tag_list_copy (list)));
3084   /* FIXME 0.11: Set the pad as source to make it possible to detect for
3085    * which pad the tags are actually found.
3086    */
3087   gst_element_post_message (element,
3088       gst_message_new_tag (GST_OBJECT (element), list));
3089 }
3090
3091 static void
3092 push_and_ref (GstPad * pad, GstEvent * event)
3093 {
3094   gst_pad_push_event (pad, gst_event_ref (event));
3095   /* iterator refs pad, we unref when we are done with it */
3096   gst_object_unref (pad);
3097 }
3098
3099 /**
3100  * gst_element_found_tags:
3101  * @element: element for which we found the tags.
3102  * @list: list of tags.
3103  *
3104  * Posts a message to the bus that new tags were found, and pushes an event
3105  * to all sourcepads. Takes ownership of the @list.
3106  *
3107  * This is a utility method for elements. Applications should use the
3108  * #GstTagSetter interface.
3109  */
3110 void
3111 gst_element_found_tags (GstElement * element, GstTagList * list)
3112 {
3113   GstIterator *iter;
3114   GstEvent *event;
3115
3116   g_return_if_fail (element != NULL);
3117   g_return_if_fail (list != NULL);
3118
3119   iter = gst_element_iterate_src_pads (element);
3120   event = gst_event_new_tag (gst_tag_list_copy (list));
3121   gst_iterator_foreach (iter, (GFunc) push_and_ref, event);
3122   gst_iterator_free (iter);
3123   gst_event_unref (event);
3124
3125   gst_element_post_message (element,
3126       gst_message_new_tag (GST_OBJECT (element), list));
3127 }
3128
3129 static GstPad *
3130 element_find_unlinked_pad (GstElement * element, GstPadDirection direction)
3131 {
3132   GstIterator *iter;
3133   GstPad *unlinked_pad = NULL;
3134   gboolean done;
3135
3136   switch (direction) {
3137     case GST_PAD_SRC:
3138       iter = gst_element_iterate_src_pads (element);
3139       break;
3140     case GST_PAD_SINK:
3141       iter = gst_element_iterate_sink_pads (element);
3142       break;
3143     default:
3144       g_return_val_if_reached (NULL);
3145   }
3146
3147   done = FALSE;
3148   while (!done) {
3149     gpointer pad;
3150
3151     switch (gst_iterator_next (iter, &pad)) {
3152       case GST_ITERATOR_OK:{
3153         GstPad *peer;
3154
3155         GST_CAT_LOG (GST_CAT_ELEMENT_PADS, "examining pad %s:%s",
3156             GST_DEBUG_PAD_NAME (pad));
3157
3158         peer = gst_pad_get_peer (GST_PAD (pad));
3159         if (peer == NULL) {
3160           unlinked_pad = pad;
3161           done = TRUE;
3162           GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
3163               "found existing unlinked pad %s:%s",
3164               GST_DEBUG_PAD_NAME (unlinked_pad));
3165         } else {
3166           gst_object_unref (pad);
3167           gst_object_unref (peer);
3168         }
3169         break;
3170       }
3171       case GST_ITERATOR_DONE:
3172         done = TRUE;
3173         break;
3174       case GST_ITERATOR_RESYNC:
3175         gst_iterator_resync (iter);
3176         break;
3177       case GST_ITERATOR_ERROR:
3178         g_return_val_if_reached (NULL);
3179         break;
3180     }
3181   }
3182
3183   gst_iterator_free (iter);
3184
3185   return unlinked_pad;
3186 }
3187
3188 /**
3189  * gst_bin_find_unlinked_pad:
3190  * @bin: bin in which to look for elements with unlinked pads
3191  * @direction: whether to look for an unlinked source or sink pad
3192  *
3193  * Recursively looks for elements with an unlinked pad of the given
3194  * direction within the specified bin and returns an unlinked pad
3195  * if one is found, or NULL otherwise. If a pad is found, the caller
3196  * owns a reference to it and should use gst_object_unref() on the
3197  * pad when it is not needed any longer.
3198  *
3199  * Returns: unlinked pad of the given direction, or NULL.
3200  *
3201  * Since: 0.10.20
3202  */
3203 GstPad *
3204 gst_bin_find_unlinked_pad (GstBin * bin, GstPadDirection direction)
3205 {
3206   GstIterator *iter;
3207   gboolean done;
3208   GstPad *pad = NULL;
3209
3210   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
3211   g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
3212
3213   done = FALSE;
3214   iter = gst_bin_iterate_recurse (bin);
3215   while (!done) {
3216     gpointer element;
3217
3218     switch (gst_iterator_next (iter, &element)) {
3219       case GST_ITERATOR_OK:
3220         pad = element_find_unlinked_pad (GST_ELEMENT (element), direction);
3221         gst_object_unref (element);
3222         if (pad != NULL)
3223           done = TRUE;
3224         break;
3225       case GST_ITERATOR_DONE:
3226         done = TRUE;
3227         break;
3228       case GST_ITERATOR_RESYNC:
3229         gst_iterator_resync (iter);
3230         break;
3231       case GST_ITERATOR_ERROR:
3232         g_return_val_if_reached (NULL);
3233         break;
3234     }
3235   }
3236
3237   gst_iterator_free (iter);
3238
3239   return pad;
3240 }
3241
3242 /**
3243  * gst_bin_find_unconnected_pad:
3244  * @bin: bin in which to look for elements with unlinked pads
3245  * @direction: whether to look for an unlinked source or sink pad
3246  *
3247  * Recursively looks for elements with an unlinked pad of the given
3248  * direction within the specified bin and returns an unlinked pad
3249  * if one is found, or NULL otherwise. If a pad is found, the caller
3250  * owns a reference to it and should use gst_object_unref() on the
3251  * pad when it is not needed any longer.
3252  *
3253  * Returns: unlinked pad of the given direction, or NULL.
3254  *
3255  * Since: 0.10.3
3256  *
3257  * Deprecated: use gst_bin_find_unlinked_pad() instead.
3258  */
3259 #ifndef GST_REMOVE_DEPRECATED
3260 GstPad *
3261 gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction)
3262 {
3263   return gst_bin_find_unlinked_pad (bin, direction);
3264 }
3265 #endif
3266
3267 /**
3268  * gst_parse_bin_from_description:
3269  * @bin_description: command line describing the bin
3270  * @ghost_unlinked_pads: whether to automatically create ghost pads
3271  *     for unlinked source or sink pads within the bin
3272  * @err: where to store the error message in case of an error, or NULL
3273  *
3274  * This is a convenience wrapper around gst_parse_launch() to create a
3275  * #GstBin from a gst-launch-style pipeline description. See
3276  * gst_parse_launch() and the gst-launch man page for details about the
3277  * syntax. Ghost pads on the bin for unlinked source or sink pads
3278  * within the bin can automatically be created (but only a maximum of
3279  * one ghost pad for each direction will be created; if you expect
3280  * multiple unlinked source pads or multiple unlinked sink pads
3281  * and want them all ghosted, you will have to create the ghost pads
3282  * yourself).
3283  *
3284  * Returns: a newly-created bin, or NULL if an error occurred.
3285  *
3286  * Since: 0.10.3
3287  */
3288 GstElement *
3289 gst_parse_bin_from_description (const gchar * bin_description,
3290     gboolean ghost_unlinked_pads, GError ** err)
3291 {
3292   return gst_parse_bin_from_description_full (bin_description,
3293       ghost_unlinked_pads, NULL, 0, err);
3294 }
3295
3296 /**
3297  * gst_parse_bin_from_description_full:
3298  * @bin_description: command line describing the bin
3299  * @ghost_unlinked_pads: whether to automatically create ghost pads
3300  *     for unlinked source or sink pads within the bin
3301  * @context: a parse context allocated with gst_parse_context_new(), or %NULL
3302  * @flags: parsing options, or #GST_PARSE_FLAG_NONE
3303  * @err: where to store the error message in case of an error, or NULL
3304  *
3305  * This is a convenience wrapper around gst_parse_launch() to create a
3306  * #GstBin from a gst-launch-style pipeline description. See
3307  * gst_parse_launch() and the gst-launch man page for details about the
3308  * syntax. Ghost pads on the bin for unlinked source or sink pads
3309  * within the bin can automatically be created (but only a maximum of
3310  * one ghost pad for each direction will be created; if you expect
3311  * multiple unlinked source pads or multiple unlinked sink pads
3312  * and want them all ghosted, you will have to create the ghost pads
3313  * yourself).
3314  *
3315  * Returns: a newly-created bin, or NULL if an error occurred.
3316  *
3317  * Since: 0.10.20
3318  */
3319 GstElement *
3320 gst_parse_bin_from_description_full (const gchar * bin_description,
3321     gboolean ghost_unlinked_pads, GstParseContext * context,
3322     GstParseFlags flags, GError ** err)
3323 {
3324 #ifndef GST_DISABLE_PARSE
3325   GstPad *pad = NULL;
3326   GstBin *bin;
3327   gchar *desc;
3328
3329   g_return_val_if_fail (bin_description != NULL, NULL);
3330   g_return_val_if_fail (err == NULL || *err == NULL, NULL);
3331
3332   GST_DEBUG ("Making bin from description '%s'", bin_description);
3333
3334   /* parse the pipeline to a bin */
3335   desc = g_strdup_printf ("bin.( %s )", bin_description);
3336   bin = (GstBin *) gst_parse_launch_full (desc, context, flags, err);
3337   g_free (desc);
3338
3339   if (bin == NULL || (err && *err != NULL)) {
3340     if (bin)
3341       gst_object_unref (bin);
3342     return NULL;
3343   }
3344
3345   /* find pads and ghost them if necessary */
3346   if (ghost_unlinked_pads) {
3347     if ((pad = gst_bin_find_unlinked_pad (bin, GST_PAD_SRC))) {
3348       gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("src", pad));
3349       gst_object_unref (pad);
3350     }
3351     if ((pad = gst_bin_find_unlinked_pad (bin, GST_PAD_SINK))) {
3352       gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("sink", pad));
3353       gst_object_unref (pad);
3354     }
3355   }
3356
3357   return GST_ELEMENT (bin);
3358 #else
3359   gchar *msg;
3360
3361   GST_WARNING ("Disabled API called");
3362
3363   msg = gst_error_get_message (GST_CORE_ERROR, GST_CORE_ERROR_DISABLED);
3364   g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_DISABLED, "%s", msg);
3365   g_free (msg);
3366
3367   return NULL;
3368 #endif
3369 }
3370
3371 /**
3372  * gst_type_register_static_full:
3373  * @parent_type: The GType of the parent type the newly registered type will 
3374  *   derive from
3375  * @type_name: NULL-terminated string used as the name of the new type
3376  * @class_size: Size of the class structure.
3377  * @base_init: Location of the base initialization function (optional).
3378  * @base_finalize: Location of the base finalization function (optional).
3379  * @class_init: Location of the class initialization function for class types 
3380  *   Location of the default vtable inititalization function for interface 
3381  *   types. (optional)
3382  * @class_finalize: Location of the class finalization function for class types.
3383  *   Location of the default vtable finalization function for interface types. 
3384  *   (optional)
3385  * @class_data: User-supplied data passed to the class init/finalize functions.
3386  * @instance_size: Size of the instance (object) structure (required for 
3387  *   instantiatable types only).
3388  * @n_preallocs: The number of pre-allocated (cached) instances to reserve 
3389  *   memory for (0 indicates no caching). Ignored on recent GLib's.
3390  * @instance_init: Location of the instance initialization function (optional, 
3391  *   for instantiatable types only).
3392  * @value_table: A GTypeValueTable function table for generic handling of 
3393  *   GValues of this type (usually only useful for fundamental types). 
3394  * @flags: #GTypeFlags for this GType. E.g: G_TYPE_FLAG_ABSTRACT
3395  *
3396  * Helper function which constructs a #GTypeInfo structure and registers a 
3397  * GType, but which generates less linker overhead than a static const 
3398  * #GTypeInfo structure. For further details of the parameters, please see
3399  * #GTypeInfo in the GLib documentation.
3400  *
3401  * Registers type_name as the name of a new static type derived from 
3402  * parent_type. The value of flags determines the nature (e.g. abstract or 
3403  * not) of the type. It works by filling a GTypeInfo struct and calling 
3404  * g_type_info_register_static().
3405  *
3406  * Returns: A #GType for the newly-registered type.
3407  *
3408  * Since: 0.10.14
3409  */
3410 GType
3411 gst_type_register_static_full (GType parent_type,
3412     const gchar * type_name,
3413     guint class_size,
3414     GBaseInitFunc base_init,
3415     GBaseFinalizeFunc base_finalize,
3416     GClassInitFunc class_init,
3417     GClassFinalizeFunc class_finalize,
3418     gconstpointer class_data,
3419     guint instance_size,
3420     guint16 n_preallocs,
3421     GInstanceInitFunc instance_init,
3422     const GTypeValueTable * value_table, GTypeFlags flags)
3423 {
3424   GTypeInfo info;
3425
3426   info.class_size = class_size;
3427   info.base_init = base_init;
3428   info.base_finalize = base_finalize;
3429   info.class_init = class_init;
3430   info.class_finalize = class_finalize;
3431   info.class_data = class_data;
3432   info.instance_size = instance_size;
3433   info.n_preallocs = n_preallocs;
3434   info.instance_init = instance_init;
3435   info.value_table = value_table;
3436
3437   return g_type_register_static (parent_type, type_name, &info, flags);
3438 }
3439
3440
3441 /**
3442  * gst_util_get_timestamp:
3443  *
3444  * Get a timestamp as GstClockTime to be used for interval meassurements.
3445  * The timestamp should not be interpreted in any other way.
3446  *
3447  * Returns: the timestamp
3448  *
3449  * Since: 0.10.16
3450  */
3451 GstClockTime
3452 gst_util_get_timestamp (void)
3453 {
3454 #if defined (HAVE_POSIX_TIMERS) && defined(HAVE_MONOTONIC_CLOCK)
3455   struct timespec now;
3456
3457   clock_gettime (CLOCK_MONOTONIC, &now);
3458   return GST_TIMESPEC_TO_TIME (now);
3459 #else
3460   GTimeVal now;
3461
3462   g_get_current_time (&now);
3463   return GST_TIMEVAL_TO_TIME (now);
3464 #endif
3465 }
3466
3467 /**
3468  * gst_util_array_binary_search:
3469  * @array: the sorted input array
3470  * @num_elements: number of elements in the array
3471  * @element_size: size of every element in bytes
3472  * @search_func: function to compare two elements, @search_data will always be passed as second argument
3473  * @mode: search mode that should be used
3474  * @search_data: element that should be found
3475  * @user_data: data to pass to @search_func
3476  *
3477  * Searches inside @array for @search_data by using the comparison function
3478  * @search_func. @array must be sorted ascending.
3479  *
3480  * As @search_data is always passed as second argument to @search_func it's
3481  * not required that @search_data has the same type as the array elements.
3482  *
3483  * The complexity of this search function is O(log (num_elements)).
3484  *
3485  * Returns: The address of the found element or %NULL if nothing was found
3486  *
3487  * Since: 0.10.23
3488  */
3489 gpointer
3490 gst_util_array_binary_search (gpointer array, guint num_elements,
3491     gsize element_size, GCompareDataFunc search_func, GstSearchMode mode,
3492     gconstpointer search_data, gpointer user_data)
3493 {
3494   glong left = 0, right = num_elements - 1, m;
3495   gint ret;
3496   guint8 *data = (guint8 *) array;
3497
3498   g_return_val_if_fail (array != NULL, NULL);
3499   g_return_val_if_fail (element_size > 0, NULL);
3500   g_return_val_if_fail (search_func != NULL, NULL);
3501
3502   /* 0. No elements => return NULL */
3503   if (num_elements == 0)
3504     return NULL;
3505
3506   /* 1. If search_data is before the 0th element return the 0th element */
3507   ret = search_func (data, search_data, user_data);
3508   if ((ret >= 0 && mode == GST_SEARCH_MODE_AFTER) || ret == 0)
3509     return data;
3510   else if (ret > 0)
3511     return NULL;
3512
3513   /* 2. If search_data is after the last element return the last element */
3514   ret =
3515       search_func (data + (num_elements - 1) * element_size, search_data,
3516       user_data);
3517   if ((ret <= 0 && mode == GST_SEARCH_MODE_BEFORE) || ret == 0)
3518     return data + (num_elements - 1) * element_size;
3519   else if (ret < 0)
3520     return NULL;
3521
3522   /* 3. else binary search */
3523   while (TRUE) {
3524     m = left + (right - left) / 2;
3525
3526     ret = search_func (data + m * element_size, search_data, user_data);
3527
3528     if (ret == 0) {
3529       return data + m * element_size;
3530     } else if (ret < 0) {
3531       left = m + 1;
3532     } else {
3533       right = m - 1;
3534     }
3535
3536     /* No exact match found */
3537     if (right < left) {
3538       if (mode == GST_SEARCH_MODE_EXACT) {
3539         return NULL;
3540       } else if (mode == GST_SEARCH_MODE_AFTER) {
3541         if (ret < 0)
3542           return (m < num_elements) ? data + (m + 1) * element_size : NULL;
3543         else
3544           return data + m * element_size;
3545       } else {
3546         if (ret < 0)
3547           return data + m * element_size;
3548         else
3549           return (m > 0) ? data + (m - 1) * element_size : NULL;
3550       }
3551     }
3552   }
3553 }