gst/base/gstbasesink.c: Only error is an error.
[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  *
5  * gstutils.c: Utility functions: gtk_get_property stuff, etc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22 /**
23  * SECTION:gstutils
24  * @short_description: Various utility functions
25  *
26  * When defining own plugins, use the GST_BOILERPLATE ease gobject creation.
27  */
28
29 #include <stdio.h>
30 #include <string.h>
31
32 #include "gst_private.h"
33 #include "gstghostpad.h"
34 #include "gstutils.h"
35 #include "gsturitype.h"
36 #include "gstinfo.h"
37 #include "gst-i18n-lib.h"
38
39
40 /**
41  * gst_util_dump_mem:
42  * @mem: a pointer to the memory to dump
43  * @size: the size of the memory block to dump
44  *
45  * Dumps the memory block into a hex representation. Useful for debugging.
46  */
47 void
48 gst_util_dump_mem (const guchar * mem, guint size)
49 {
50   guint i, j;
51   GString *string = g_string_sized_new (50);
52   GString *chars = g_string_sized_new (18);
53
54   i = j = 0;
55   while (i < size) {
56     if (g_ascii_isprint (mem[i]))
57       g_string_append_printf (chars, "%c", mem[i]);
58     else
59       g_string_append_printf (chars, ".");
60
61     g_string_append_printf (string, "%02x ", mem[i]);
62
63     j++;
64     i++;
65
66     if (j == 16 || i == size) {
67       g_print ("%08x (%p): %-48.48s %-16.16s\n", i - j, mem + i - j,
68           string->str, chars->str);
69       g_string_set_size (string, 0);
70       g_string_set_size (chars, 0);
71       j = 0;
72     }
73   }
74   g_string_free (string, TRUE);
75   g_string_free (chars, TRUE);
76 }
77
78
79 /**
80  * gst_util_set_value_from_string:
81  * @value: the value to set
82  * @value_str: the string to get the value from
83  *
84  * Converts the string to the type of the value and
85  * sets the value with it.
86  */
87 void
88 gst_util_set_value_from_string (GValue * value, const gchar * value_str)
89 {
90   gint sscanf_ret;
91
92   g_return_if_fail (value != NULL);
93   g_return_if_fail (value_str != NULL);
94
95   GST_CAT_DEBUG (GST_CAT_PARAMS, "parsing '%s' to type %s", value_str,
96       g_type_name (G_VALUE_TYPE (value)));
97
98   switch (G_VALUE_TYPE (value)) {
99     case G_TYPE_STRING:
100       g_value_set_string (value, g_strdup (value_str));
101       break;
102     case G_TYPE_ENUM:
103     case G_TYPE_INT:{
104       gint i;
105
106       sscanf_ret = sscanf (value_str, "%d", &i);
107       g_return_if_fail (sscanf_ret == 1);
108       g_value_set_int (value, i);
109       break;
110     }
111     case G_TYPE_UINT:{
112       guint i;
113
114       sscanf_ret = sscanf (value_str, "%u", &i);
115       g_return_if_fail (sscanf_ret == 1);
116       g_value_set_uint (value, i);
117       break;
118     }
119     case G_TYPE_LONG:{
120       glong i;
121
122       sscanf_ret = sscanf (value_str, "%ld", &i);
123       g_return_if_fail (sscanf_ret == 1);
124       g_value_set_long (value, i);
125       break;
126     }
127     case G_TYPE_ULONG:{
128       gulong i;
129
130       sscanf_ret = sscanf (value_str, "%lu", &i);
131       g_return_if_fail (sscanf_ret == 1);
132       g_value_set_ulong (value, i);
133       break;
134     }
135     case G_TYPE_BOOLEAN:{
136       gboolean i = FALSE;
137
138       if (!g_ascii_strncasecmp ("true", value_str, 4))
139         i = TRUE;
140       g_value_set_boolean (value, i);
141       break;
142     }
143     case G_TYPE_CHAR:{
144       gchar i;
145
146       sscanf_ret = sscanf (value_str, "%c", &i);
147       g_return_if_fail (sscanf_ret == 1);
148       g_value_set_char (value, i);
149       break;
150     }
151     case G_TYPE_UCHAR:{
152       guchar i;
153
154       sscanf_ret = sscanf (value_str, "%c", &i);
155       g_return_if_fail (sscanf_ret == 1);
156       g_value_set_uchar (value, i);
157       break;
158     }
159     case G_TYPE_FLOAT:{
160       gfloat i;
161
162       sscanf_ret = sscanf (value_str, "%f", &i);
163       g_return_if_fail (sscanf_ret == 1);
164       g_value_set_float (value, i);
165       break;
166     }
167     case G_TYPE_DOUBLE:{
168       gfloat i;
169
170       sscanf_ret = sscanf (value_str, "%g", &i);
171       g_return_if_fail (sscanf_ret == 1);
172       g_value_set_double (value, (gdouble) i);
173       break;
174     }
175     default:
176       break;
177   }
178 }
179
180 /**
181  * gst_util_set_object_arg:
182  * @object: the object to set the argument of
183  * @name: the name of the argument to set
184  * @value: the string value to set
185  *
186  * Convertes the string value to the type of the objects argument and
187  * sets the argument with it.
188  */
189 void
190 gst_util_set_object_arg (GObject * object, const gchar * name,
191     const gchar * value)
192 {
193   gboolean sscanf_ret;
194
195   if (name && value) {
196     GParamSpec *paramspec;
197
198     paramspec =
199         g_object_class_find_property (G_OBJECT_GET_CLASS (object), name);
200
201     if (!paramspec) {
202       return;
203     }
204
205     GST_DEBUG ("paramspec->flags is %d, paramspec->value_type is %d",
206         paramspec->flags, (gint) paramspec->value_type);
207
208     if (paramspec->flags & G_PARAM_WRITABLE) {
209       switch (paramspec->value_type) {
210         case G_TYPE_STRING:
211           g_object_set (G_OBJECT (object), name, value, NULL);
212           break;
213         case G_TYPE_ENUM:
214         case G_TYPE_INT:{
215           gint i;
216
217           sscanf_ret = sscanf (value, "%d", &i);
218           g_return_if_fail (sscanf_ret == 1);
219           g_object_set (G_OBJECT (object), name, i, NULL);
220           break;
221         }
222         case G_TYPE_UINT:{
223           guint i;
224
225           sscanf_ret = sscanf (value, "%u", &i);
226           g_return_if_fail (sscanf_ret == 1);
227           g_object_set (G_OBJECT (object), name, i, NULL);
228           break;
229         }
230         case G_TYPE_LONG:{
231           glong i;
232
233           sscanf_ret = sscanf (value, "%ld", &i);
234           g_return_if_fail (sscanf_ret == 1);
235           g_object_set (G_OBJECT (object), name, i, NULL);
236           break;
237         }
238         case G_TYPE_ULONG:{
239           gulong i;
240
241           sscanf_ret = sscanf (value, "%lu", &i);
242           g_return_if_fail (sscanf_ret == 1);
243           g_object_set (G_OBJECT (object), name, i, NULL);
244           break;
245         }
246         case G_TYPE_BOOLEAN:{
247           gboolean i = FALSE;
248
249           if (!g_ascii_strncasecmp ("true", value, 4))
250             i = TRUE;
251           g_object_set (G_OBJECT (object), name, i, NULL);
252           break;
253         }
254         case G_TYPE_CHAR:{
255           gchar i;
256
257           sscanf_ret = sscanf (value, "%c", &i);
258           g_return_if_fail (sscanf_ret == 1);
259           g_object_set (G_OBJECT (object), name, i, NULL);
260           break;
261         }
262         case G_TYPE_UCHAR:{
263           guchar i;
264
265           sscanf_ret = sscanf (value, "%c", &i);
266           g_return_if_fail (sscanf_ret == 1);
267           g_object_set (G_OBJECT (object), name, i, NULL);
268           break;
269         }
270         case G_TYPE_FLOAT:{
271           gfloat i;
272
273           sscanf_ret = sscanf (value, "%f", &i);
274           g_return_if_fail (sscanf_ret == 1);
275           g_object_set (G_OBJECT (object), name, i, NULL);
276           break;
277         }
278         case G_TYPE_DOUBLE:{
279           gfloat i;
280
281           sscanf_ret = sscanf (value, "%g", &i);
282           g_return_if_fail (sscanf_ret == 1);
283           g_object_set (G_OBJECT (object), name, (gdouble) i, NULL);
284           break;
285         }
286         default:
287           if (G_IS_PARAM_SPEC_ENUM (paramspec)) {
288             gint i;
289
290             sscanf_ret = sscanf (value, "%d", &i);
291             g_return_if_fail (sscanf_ret == 1);
292             g_object_set (G_OBJECT (object), name, i, NULL);
293           } else if (paramspec->value_type == GST_TYPE_URI) {
294             g_object_set (G_OBJECT (object), name, value, NULL);
295           }
296           break;
297       }
298     }
299   }
300 }
301
302 /**
303  * gst_util_uint64_scale:
304  * @val: the number to scale
305  * @num: the numerator of the scale ratio
306  * @denom: the denominator of the scale ratio
307  *
308  * Scale @val by @num / @denom, trying to avoid overflows.
309  *
310  * Returns: @val * @num / @denom, trying to avoid overflows.
311  */
312 guint64
313 gst_util_uint64_scale (guint64 val, guint64 num, guint64 denom)
314 {
315   /* implement me with fixed point, if you care */
316   return val * (((double) num) / denom);
317 }
318
319 /* -----------------------------------------------------
320  *
321  *  The following code will be moved out of the main
322  * gstreamer library someday.
323  */
324
325 #include "gstpad.h"
326
327 static void
328 string_append_indent (GString * str, gint count)
329 {
330   gint xx;
331
332   for (xx = 0; xx < count; xx++)
333     g_string_append_c (str, ' ');
334 }
335
336 /**
337  * gst_print_pad_caps:
338  * @buf: the buffer to print the caps in
339  * @indent: initial indentation
340  * @pad: the pad to print the caps from
341  *
342  * Write the pad capabilities in a human readable format into
343  * the given GString.
344  */
345 void
346 gst_print_pad_caps (GString * buf, gint indent, GstPad * pad)
347 {
348   GstCaps *caps;
349
350   caps = pad->caps;
351
352   if (!caps) {
353     string_append_indent (buf, indent);
354     g_string_printf (buf, "%s:%s has no capabilities",
355         GST_DEBUG_PAD_NAME (pad));
356   } else {
357     char *s;
358
359     s = gst_caps_to_string (caps);
360     g_string_append (buf, s);
361     g_free (s);
362   }
363 }
364
365 /**
366  * gst_print_element_args:
367  * @buf: the buffer to print the args in
368  * @indent: initial indentation
369  * @element: the element to print the args of
370  *
371  * Print the element argument in a human readable format in the given
372  * GString.
373  */
374 void
375 gst_print_element_args (GString * buf, gint indent, GstElement * element)
376 {
377   guint width;
378   GValue value = { 0, };        /* the important thing is that value.type = 0 */
379   gchar *str = NULL;
380   GParamSpec *spec, **specs, **walk;
381
382   specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (element), NULL);
383
384   width = 0;
385   for (walk = specs; *walk; walk++) {
386     spec = *walk;
387     if (width < strlen (spec->name))
388       width = strlen (spec->name);
389   }
390
391   for (walk = specs; *walk; walk++) {
392     spec = *walk;
393
394     if (spec->flags & G_PARAM_READABLE) {
395       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
396       g_object_get_property (G_OBJECT (element), spec->name, &value);
397       str = g_strdup_value_contents (&value);
398       g_value_unset (&value);
399     } else {
400       str = g_strdup ("Parameter not readable.");
401     }
402
403     string_append_indent (buf, indent);
404     g_string_append (buf, spec->name);
405     string_append_indent (buf, 2 + width - strlen (spec->name));
406     g_string_append (buf, str);
407     g_string_append_c (buf, '\n');
408
409     g_free (str);
410   }
411
412   g_free (specs);
413 }
414
415 /**
416  * gst_element_create_all_pads:
417  * @element: a #GstElement to create pads for
418  *
419  * Creates a pad for each pad template that is always available.
420  * This function is only useful during object intialization of
421  * subclasses of #GstElement.
422  */
423 void
424 gst_element_create_all_pads (GstElement * element)
425 {
426   GList *padlist;
427
428   /* FIXME: lock element */
429
430   padlist =
431       gst_element_class_get_pad_template_list (GST_ELEMENT_CLASS
432       (G_OBJECT_GET_CLASS (element)));
433
434   while (padlist) {
435     GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
436
437     if (padtempl->presence == GST_PAD_ALWAYS) {
438       GstPad *pad;
439
440       pad = gst_pad_new_from_template (padtempl, padtempl->name_template);
441
442       gst_element_add_pad (element, pad);
443     }
444     padlist = padlist->next;
445   }
446 }
447
448 /**
449  * gst_element_get_compatible_pad_template:
450  * @element: a #GstElement to get a compatible pad template for.
451  * @compattempl: the #GstPadTemplate to find a compatible template for.
452  *
453  * Retrieves a pad template from @element that is compatible with @compattempl.
454  * Pads from compatible templates can be linked together.
455  *
456  * Returns: a compatible #GstPadTemplate, or NULL if none was found. No
457  * unreferencing is necessary.
458  */
459 GstPadTemplate *
460 gst_element_get_compatible_pad_template (GstElement * element,
461     GstPadTemplate * compattempl)
462 {
463   GstPadTemplate *newtempl = NULL;
464   GList *padlist;
465   GstElementClass *class;
466
467   g_return_val_if_fail (element != NULL, NULL);
468   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
469   g_return_val_if_fail (compattempl != NULL, NULL);
470
471   class = GST_ELEMENT_GET_CLASS (element);
472
473   padlist = gst_element_class_get_pad_template_list (class);
474
475   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
476       "Looking for a suitable pad template in %s out of %d templates...",
477       GST_ELEMENT_NAME (element), g_list_length (padlist));
478
479   while (padlist) {
480     GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
481     GstCaps *intersection;
482
483     /* Ignore name
484      * Ignore presence
485      * Check direction (must be opposite)
486      * Check caps
487      */
488     GST_CAT_LOG (GST_CAT_CAPS,
489         "checking pad template %s", padtempl->name_template);
490     if (padtempl->direction != compattempl->direction) {
491       GST_CAT_DEBUG (GST_CAT_CAPS,
492           "compatible direction: found %s pad template \"%s\"",
493           padtempl->direction == GST_PAD_SRC ? "src" : "sink",
494           padtempl->name_template);
495
496       GST_CAT_DEBUG (GST_CAT_CAPS,
497           "intersecting %" GST_PTR_FORMAT, GST_PAD_TEMPLATE_CAPS (compattempl));
498       GST_CAT_DEBUG (GST_CAT_CAPS,
499           "..and %" GST_PTR_FORMAT, GST_PAD_TEMPLATE_CAPS (padtempl));
500
501       intersection = gst_caps_intersect (GST_PAD_TEMPLATE_CAPS (compattempl),
502           GST_PAD_TEMPLATE_CAPS (padtempl));
503
504       GST_CAT_DEBUG (GST_CAT_CAPS, "caps are %scompatible %" GST_PTR_FORMAT,
505           (intersection ? "" : "not "), intersection);
506
507       if (!gst_caps_is_empty (intersection))
508         newtempl = padtempl;
509       gst_caps_unref (intersection);
510       if (newtempl)
511         break;
512     }
513
514     padlist = g_list_next (padlist);
515   }
516   if (newtempl)
517     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
518         "Returning new pad template %p", newtempl);
519   else
520     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "No compatible pad template found");
521
522   return newtempl;
523 }
524
525 static GstPad *
526 gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
527     const gchar * name)
528 {
529   GstPad *newpad = NULL;
530   GstElementClass *oclass;
531
532   oclass = GST_ELEMENT_GET_CLASS (element);
533
534   if (oclass->request_new_pad)
535     newpad = (oclass->request_new_pad) (element, templ, name);
536
537   if (newpad)
538     gst_object_ref (newpad);
539
540   return newpad;
541 }
542
543
544
545 /**
546  * gst_element_get_pad_from_template:
547  * @element: a #GstElement.
548  * @templ: a #GstPadTemplate belonging to @element.
549  *
550  * Gets a pad from @element described by @templ. If the presence of @templ is
551  * #GST_PAD_REQUEST, requests a new pad. Can return %NULL for #GST_PAD_SOMETIMES
552  * templates.
553  *
554  * Returns: the #GstPad, or NULL if one could not be found or created.
555  */
556 static GstPad *
557 gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ)
558 {
559   GstPad *ret = NULL;
560   GstPadPresence presence;
561
562   /* If this function is ever exported, we need check the validity of `element'
563    * and `templ', and to make sure the template actually belongs to the
564    * element. */
565
566   presence = GST_PAD_TEMPLATE_PRESENCE (templ);
567
568   switch (presence) {
569     case GST_PAD_ALWAYS:
570     case GST_PAD_SOMETIMES:
571       ret = gst_element_get_static_pad (element, templ->name_template);
572       if (!ret && presence == GST_PAD_ALWAYS)
573         g_warning
574             ("Element %s has an ALWAYS template %s, but no pad of the same name",
575             GST_OBJECT_NAME (element), templ->name_template);
576       break;
577
578     case GST_PAD_REQUEST:
579       ret = gst_element_request_pad (element, templ, NULL);
580       break;
581   }
582
583   return ret;
584 }
585
586 /**
587  * gst_element_request_compatible_pad:
588  * @element: a #GstElement.
589  * @templ: the #GstPadTemplate to which the new pad should be able to link.
590  *
591  * Requests a pad from @element. The returned pad should be unlinked and
592  * compatible with @templ. Might return an existing pad, or request a new one.
593  *
594  * Returns: a #GstPad, or %NULL if one could not be found or created.
595  */
596 GstPad *
597 gst_element_request_compatible_pad (GstElement * element,
598     GstPadTemplate * templ)
599 {
600   GstPadTemplate *templ_new;
601   GstPad *pad = NULL;
602
603   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
604   g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
605
606   /* FIXME: should really loop through the templates, testing each for
607    *      compatibility and pad availability. */
608   templ_new = gst_element_get_compatible_pad_template (element, templ);
609   if (templ_new)
610     pad = gst_element_get_pad_from_template (element, templ_new);
611
612   /* This can happen for non-request pads. No need to unref. */
613   if (pad && GST_PAD_PEER (pad))
614     pad = NULL;
615
616   return pad;
617 }
618
619 /**
620  * gst_element_get_compatible_pad:
621  * @element: a #GstElement in which the pad should be found.
622  * @pad: the #GstPad to find a compatible one for.
623  * @caps: the #GstCaps to use as a filter.
624  *
625  * Looks for an unlinked pad to which the given pad can link. It is not
626  * guaranteed that linking the pads will work, though it should work in most
627  * cases.
628  *
629  * Returns: the #GstPad to which a link can be made, or %NULL if one cannot be
630  * found.
631  */
632 GstPad *
633 gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
634     const GstCaps * caps)
635 {
636   GstIterator *pads;
637   GstPadTemplate *templ;
638   GstCaps *templcaps;
639   GstPad *foundpad = NULL;
640   gboolean done;
641
642   /* FIXME check for caps compatibility */
643
644   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
645   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
646
647   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
648       "finding pad in %s compatible with %s:%s",
649       GST_ELEMENT_NAME (element), GST_DEBUG_PAD_NAME (pad));
650
651   g_return_val_if_fail (GST_PAD_PEER (pad) == NULL, NULL);
652
653   done = FALSE;
654   /* try to get an existing unlinked pad */
655   pads = gst_element_iterate_pads (element);
656   while (!done) {
657     gpointer padptr;
658
659     switch (gst_iterator_next (pads, &padptr)) {
660       case GST_ITERATOR_OK:
661       {
662         GstPad *peer;
663         GstPad *current;
664
665         current = GST_PAD (padptr);
666
667         GST_CAT_LOG (GST_CAT_ELEMENT_PADS, "examining pad %s:%s",
668             GST_DEBUG_PAD_NAME (current));
669
670         peer = gst_pad_get_peer (current);
671
672         if (peer == NULL && gst_pad_can_link (pad, current)) {
673
674           GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
675               "found existing unlinked pad %s:%s",
676               GST_DEBUG_PAD_NAME (current));
677
678           gst_iterator_free (pads);
679
680           return current;
681         } else {
682           GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unreffing pads");
683
684           gst_object_unref (current);
685           if (peer)
686             gst_object_unref (peer);
687         }
688         break;
689       }
690       case GST_ITERATOR_DONE:
691         done = TRUE;
692         break;
693       case GST_ITERATOR_RESYNC:
694         gst_iterator_resync (pads);
695         break;
696       case GST_ITERATOR_ERROR:
697         g_assert_not_reached ();
698         break;
699     }
700   }
701   gst_iterator_free (pads);
702
703   /* try to create a new one */
704   /* requesting is a little crazy, we need a template. Let's create one */
705   templcaps = gst_pad_get_caps (pad);
706
707   templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
708       GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps);
709   foundpad = gst_element_request_compatible_pad (element, templ);
710   gst_object_unref (templ);
711
712   if (foundpad) {
713     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
714         "found existing request pad %s:%s", GST_DEBUG_PAD_NAME (foundpad));
715     return foundpad;
716   }
717
718   GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element,
719       "Could not find a compatible pad to link to %s:%s",
720       GST_DEBUG_PAD_NAME (pad));
721   return NULL;
722 }
723
724 /**
725  * gst_element_state_get_name:
726  * @state: a #GstState to get the name of.
727  *
728  * Gets a string representing the given state.
729  *
730  * Returns: a string with the name of the state.
731  */
732 const gchar *
733 gst_element_state_get_name (GstState state)
734 {
735   switch (state) {
736 #ifdef GST_DEBUG_COLOR
737     case GST_STATE_VOID_PENDING:
738       return "VOID_PENDING";
739       break;
740     case GST_STATE_NULL:
741       return "\033[01;34mNULL\033[00m";
742       break;
743     case GST_STATE_READY:
744       return "\033[01;31mREADY\033[00m";
745       break;
746     case GST_STATE_PLAYING:
747       return "\033[01;32mPLAYING\033[00m";
748       break;
749     case GST_STATE_PAUSED:
750       return "\033[01;33mPAUSED\033[00m";
751       break;
752     default:
753       /* This is a memory leak */
754       return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state);
755 #else
756     case GST_STATE_VOID_PENDING:
757       return "VOID_PENDING";
758       break;
759     case GST_STATE_NULL:
760       return "NULL";
761       break;
762     case GST_STATE_READY:
763       return "READY";
764       break;
765     case GST_STATE_PLAYING:
766       return "PLAYING";
767       break;
768     case GST_STATE_PAUSED:
769       return "PAUSED";
770       break;
771     default:
772       return g_strdup_printf ("UNKNOWN!(%d)", state);
773 #endif
774   }
775   return "";
776 }
777
778 /**
779  * gst_element_factory_can_src_caps :
780  * @factory: factory to query
781  * @caps: the caps to check
782  *
783  * Checks if the factory can source the given capability.
784  *
785  * Returns: true if it can src the capabilities
786  */
787 gboolean
788 gst_element_factory_can_src_caps (GstElementFactory * factory,
789     const GstCaps * caps)
790 {
791   GList *templates;
792
793   g_return_val_if_fail (factory != NULL, FALSE);
794   g_return_val_if_fail (caps != NULL, FALSE);
795
796   templates = factory->staticpadtemplates;
797
798   while (templates) {
799     GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data;
800
801     if (template->direction == GST_PAD_SRC) {
802       if (gst_caps_is_always_compatible (gst_static_caps_get (&template->
803                   static_caps), caps))
804         return TRUE;
805     }
806     templates = g_list_next (templates);
807   }
808
809   return FALSE;
810 }
811
812 /**
813  * gst_element_factory_can_sink_caps :
814  * @factory: factory to query
815  * @caps: the caps to check
816  *
817  * Checks if the factory can sink the given capability.
818  *
819  * Returns: true if it can sink the capabilities
820  */
821 gboolean
822 gst_element_factory_can_sink_caps (GstElementFactory * factory,
823     const GstCaps * caps)
824 {
825   GList *templates;
826
827   g_return_val_if_fail (factory != NULL, FALSE);
828   g_return_val_if_fail (caps != NULL, FALSE);
829
830   templates = factory->staticpadtemplates;
831
832   while (templates) {
833     GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data;
834
835     if (template->direction == GST_PAD_SINK) {
836       if (gst_caps_is_always_compatible (caps,
837               gst_static_caps_get (&template->static_caps)))
838         return TRUE;
839     }
840     templates = g_list_next (templates);
841   }
842
843   return FALSE;
844 }
845
846
847 /* if return val is true, *direct_child is a caller-owned ref on the direct
848  * child of ancestor that is part of object's ancestry */
849 static gboolean
850 object_has_ancestor (GstObject * object, GstObject * ancestor,
851     GstObject ** direct_child)
852 {
853   GstObject *child, *parent;
854
855   if (direct_child)
856     *direct_child = NULL;
857
858   child = gst_object_ref (object);
859   parent = gst_object_get_parent (object);
860
861   while (parent) {
862     if (ancestor == parent) {
863       if (direct_child)
864         *direct_child = child;
865       else
866         gst_object_unref (child);
867       gst_object_unref (parent);
868       return TRUE;
869     }
870
871     gst_object_unref (child);
872     child = parent;
873     parent = gst_object_get_parent (parent);
874   }
875
876   gst_object_unref (child);
877
878   return FALSE;
879 }
880
881 /* caller owns return */
882 static GstObject *
883 find_common_root (GstObject * o1, GstObject * o2)
884 {
885   GstObject *top = o1;
886   GstObject *kid1, *kid2;
887   GstObject *root = NULL;
888
889   while (GST_OBJECT_PARENT (top))
890     top = GST_OBJECT_PARENT (top);
891
892   /* the itsy-bitsy spider... */
893
894   if (!object_has_ancestor (o2, top, &kid2))
895     return NULL;
896
897   root = gst_object_ref (top);
898   while (TRUE) {
899     if (!object_has_ancestor (o1, kid2, &kid1)) {
900       gst_object_unref (kid2);
901       return root;
902     }
903     root = kid2;
904     if (!object_has_ancestor (o2, kid1, &kid2)) {
905       gst_object_unref (kid1);
906       return root;
907     }
908     root = kid1;
909   }
910 }
911
912 /* caller does not own return */
913 static GstPad *
914 ghost_up (GstElement * e, GstPad * pad)
915 {
916   static gint ghost_pad_index = 0;
917   GstPad *gpad;
918   gchar *name;
919   GstObject *parent = GST_OBJECT_PARENT (e);
920
921   name = g_strdup_printf ("ghost%d", ghost_pad_index++);
922   gpad = gst_ghost_pad_new (name, pad);
923   g_free (name);
924
925   if (!gst_element_add_pad ((GstElement *) parent, gpad)) {
926     g_warning ("Pad named %s already exists in element %s\n",
927         GST_OBJECT_NAME (gpad), GST_OBJECT_NAME (parent));
928     gst_object_unref ((GstObject *) gpad);
929     return NULL;
930   }
931
932   return gpad;
933 }
934
935 static void
936 remove_pad (gpointer ppad, gpointer unused)
937 {
938   GstPad *pad = ppad;
939
940   if (!gst_element_remove_pad ((GstElement *) GST_OBJECT_PARENT (pad), pad))
941     g_warning ("Couldn't remove pad %s from element %s",
942         GST_OBJECT_NAME (pad), GST_OBJECT_NAME (GST_OBJECT_PARENT (pad)));
943 }
944
945 static gboolean
946 prepare_link_maybe_ghosting (GstPad ** src, GstPad ** sink,
947     GSList ** pads_created)
948 {
949   GstObject *root;
950   GstObject *e1, *e2;
951   GSList *pads_created_local = NULL;
952
953   g_assert (pads_created);
954
955   e1 = GST_OBJECT_PARENT (*src);
956   e2 = GST_OBJECT_PARENT (*sink);
957
958   if (GST_OBJECT_PARENT (e1) == GST_OBJECT_PARENT (e2)) {
959     GST_CAT_INFO (GST_CAT_PADS, "%s and %s in same bin, no need for ghost pads",
960         GST_OBJECT_NAME (e1), GST_OBJECT_NAME (e2));
961     return TRUE;
962   }
963
964   GST_CAT_INFO (GST_CAT_PADS, "%s and %s not in same bin, making ghost pads",
965       GST_OBJECT_NAME (e1), GST_OBJECT_NAME (e2));
966
967   /* we need to setup some ghost pads */
968   root = find_common_root (e1, e2);
969   if (!root) {
970     g_warning
971         ("Trying to connect elements that don't share a common ancestor: %s and %s\n",
972         GST_ELEMENT_NAME (e1), GST_ELEMENT_NAME (e2));
973     return FALSE;
974   }
975
976   while (GST_OBJECT_PARENT (e1) != root) {
977     *src = ghost_up ((GstElement *) e1, *src);
978     if (!*src)
979       goto cleanup_fail;
980     e1 = GST_OBJECT_PARENT (*src);
981     pads_created_local = g_slist_prepend (pads_created_local, *src);
982   }
983   while (GST_OBJECT_PARENT (e2) != root) {
984     *sink = ghost_up ((GstElement *) e2, *sink);
985     if (!*sink)
986       goto cleanup_fail;
987     e2 = GST_OBJECT_PARENT (*sink);
988     pads_created_local = g_slist_prepend (pads_created_local, *sink);
989   }
990
991   gst_object_unref (root);
992   *pads_created = g_slist_concat (*pads_created, pads_created_local);
993   return TRUE;
994
995 cleanup_fail:
996   gst_object_unref (root);
997   g_slist_foreach (pads_created_local, remove_pad, NULL);
998   g_slist_free (pads_created_local);
999   return FALSE;
1000 }
1001
1002 static gboolean
1003 pad_link_maybe_ghosting (GstPad * src, GstPad * sink)
1004 {
1005   GSList *pads_created = NULL;
1006   gboolean ret;
1007
1008   if (!prepare_link_maybe_ghosting (&src, &sink, &pads_created)) {
1009     ret = FALSE;
1010   } else {
1011     ret = (gst_pad_link (src, sink) == GST_PAD_LINK_OK);
1012   }
1013
1014   if (!ret) {
1015     g_slist_foreach (pads_created, remove_pad, NULL);
1016   }
1017   g_slist_free (pads_created);
1018
1019   return ret;
1020 }
1021
1022 /**
1023  * gst_element_link_pads:
1024  * @src: a #GstElement containing the source pad.
1025  * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
1026  * @dest: the #GstElement containing the destination pad.
1027  * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
1028  *
1029  * Links the two named pads of the source and destination elements.
1030  * Side effect is that if one of the pads has no parent, it becomes a
1031  * child of the parent of the other element.  If they have different
1032  * parents, the link fails.
1033  *
1034  * Returns: TRUE if the pads could be linked, FALSE otherwise.
1035  */
1036 gboolean
1037 gst_element_link_pads (GstElement * src, const gchar * srcpadname,
1038     GstElement * dest, const gchar * destpadname)
1039 {
1040   const GList *srcpads, *destpads, *srctempls, *desttempls, *l;
1041   GstPad *srcpad, *destpad;
1042   GstPadTemplate *srctempl, *desttempl;
1043   GstElementClass *srcclass, *destclass;
1044
1045   /* checks */
1046   g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1047   g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1048
1049   srcclass = GST_ELEMENT_GET_CLASS (src);
1050   destclass = GST_ELEMENT_GET_CLASS (dest);
1051
1052   GST_CAT_INFO (GST_CAT_ELEMENT_PADS,
1053       "trying to link element %s:%s to element %s:%s", GST_ELEMENT_NAME (src),
1054       srcpadname ? srcpadname : "(any)", GST_ELEMENT_NAME (dest),
1055       destpadname ? destpadname : "(any)");
1056
1057   /* now get the pads we're trying to link and a list of all remaining pads */
1058   if (srcpadname) {
1059     srcpad = gst_element_get_pad (src, srcpadname);
1060     if (!srcpad) {
1061       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
1062           GST_ELEMENT_NAME (src), srcpadname);
1063       return FALSE;
1064     } else {
1065       if (!(GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC)) {
1066         GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no src pad",
1067             GST_DEBUG_PAD_NAME (srcpad));
1068         gst_object_unref (srcpad);
1069         return FALSE;
1070       }
1071       if (GST_PAD_PEER (srcpad) != NULL) {
1072         GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
1073             GST_DEBUG_PAD_NAME (srcpad));
1074         gst_object_unref (srcpad);
1075         return FALSE;
1076       }
1077     }
1078     srcpads = NULL;
1079   } else {
1080     GST_LOCK (src);
1081     srcpads = GST_ELEMENT_PADS (src);
1082     srcpad = srcpads ? GST_PAD_CAST (srcpads->data) : NULL;
1083     if (srcpad)
1084       gst_object_ref (srcpad);
1085     GST_UNLOCK (src);
1086   }
1087   if (destpadname) {
1088     destpad = gst_element_get_pad (dest, destpadname);
1089     if (!destpad) {
1090       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s",
1091           GST_ELEMENT_NAME (dest), destpadname);
1092       return FALSE;
1093     } else {
1094       if (!(GST_PAD_DIRECTION (destpad) == GST_PAD_SINK)) {
1095         GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is no sink pad",
1096             GST_DEBUG_PAD_NAME (destpad));
1097         gst_object_unref (destpad);
1098         return FALSE;
1099       }
1100       if (GST_PAD_PEER (destpad) != NULL) {
1101         GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
1102             GST_DEBUG_PAD_NAME (destpad));
1103         gst_object_unref (destpad);
1104         return FALSE;
1105       }
1106     }
1107     destpads = NULL;
1108   } else {
1109     GST_LOCK (dest);
1110     destpads = GST_ELEMENT_PADS (dest);
1111     destpad = destpads ? GST_PAD_CAST (destpads->data) : NULL;
1112     if (destpad)
1113       gst_object_ref (destpad);
1114     GST_UNLOCK (dest);
1115   }
1116
1117   if (srcpadname && destpadname) {
1118     gboolean result;
1119
1120     /* two explicitly specified pads */
1121     result = pad_link_maybe_ghosting (srcpad, destpad);
1122
1123     gst_object_unref (srcpad);
1124     gst_object_unref (destpad);
1125
1126     return result;
1127   }
1128   if (srcpad) {
1129     /* loop through the allowed pads in the source, trying to find a
1130      * compatible destination pad */
1131     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1132         "looping through allowed src and dest pads");
1133     do {
1134       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying src pad %s:%s",
1135           GST_DEBUG_PAD_NAME (srcpad));
1136       if ((GST_PAD_DIRECTION (srcpad) == GST_PAD_SRC) &&
1137           (GST_PAD_PEER (srcpad) == NULL)) {
1138         GstPad *temp;
1139
1140         if (destpadname) {
1141           temp = destpad;
1142           gst_object_ref (temp);
1143         } else {
1144           temp = gst_element_get_compatible_pad (dest, srcpad, NULL);
1145         }
1146
1147         if (temp && pad_link_maybe_ghosting (srcpad, temp)) {
1148           GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1149               GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (temp));
1150           if (destpad)
1151             gst_object_unref (destpad);
1152           gst_object_unref (srcpad);
1153           gst_object_unref (temp);
1154           return TRUE;
1155         }
1156
1157         if (temp) {
1158           gst_object_unref (temp);
1159         }
1160       }
1161       /* find a better way for this mess */
1162       if (srcpads) {
1163         srcpads = g_list_next (srcpads);
1164         if (srcpads) {
1165           gst_object_unref (srcpad);
1166           srcpad = GST_PAD_CAST (srcpads->data);
1167           gst_object_ref (srcpad);
1168         }
1169       }
1170     } while (srcpads);
1171   }
1172   if (srcpadname) {
1173     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s:%s to %s",
1174         GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (dest));
1175     gst_object_unref (srcpad);
1176     if (destpad)
1177       gst_object_unref (destpad);
1178     return FALSE;
1179   } else {
1180     if (srcpad)
1181       gst_object_unref (srcpad);
1182     srcpad = NULL;
1183   }
1184   if (destpad) {
1185     /* loop through the existing pads in the destination */
1186     do {
1187       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "trying dest pad %s:%s",
1188           GST_DEBUG_PAD_NAME (destpad));
1189       if ((GST_PAD_DIRECTION (destpad) == GST_PAD_SINK) &&
1190           (GST_PAD_PEER (destpad) == NULL)) {
1191         GstPad *temp = gst_element_get_compatible_pad (src, destpad, NULL);
1192
1193         if (temp && pad_link_maybe_ghosting (temp, destpad)) {
1194           GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "linked pad %s:%s to pad %s:%s",
1195               GST_DEBUG_PAD_NAME (temp), GST_DEBUG_PAD_NAME (destpad));
1196           gst_object_unref (temp);
1197           gst_object_unref (destpad);
1198           if (srcpad)
1199             gst_object_unref (srcpad);
1200           return TRUE;
1201         }
1202         if (temp) {
1203           gst_object_unref (temp);
1204         }
1205       }
1206       if (destpads) {
1207         destpads = g_list_next (destpads);
1208         if (destpads) {
1209           gst_object_unref (destpad);
1210           destpad = GST_PAD_CAST (destpads->data);
1211           gst_object_ref (destpad);
1212         }
1213       }
1214     } while (destpads);
1215   }
1216   if (destpadname) {
1217     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s:%s",
1218         GST_ELEMENT_NAME (src), GST_DEBUG_PAD_NAME (destpad));
1219     gst_object_unref (destpad);
1220     if (srcpad)
1221       gst_object_unref (srcpad);
1222     return FALSE;
1223   } else {
1224     gst_object_unref (destpad);
1225     if (srcpad)
1226       gst_object_unref (srcpad);
1227     srcpad = NULL;
1228     destpad = NULL;
1229   }
1230
1231   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1232       "we might have request pads on both sides, checking...");
1233   srctempls = gst_element_class_get_pad_template_list (srcclass);
1234   desttempls = gst_element_class_get_pad_template_list (destclass);
1235
1236   if (srctempls && desttempls) {
1237     while (srctempls) {
1238       srctempl = (GstPadTemplate *) srctempls->data;
1239       if (srctempl->presence == GST_PAD_REQUEST) {
1240         for (l = desttempls; l; l = l->next) {
1241           desttempl = (GstPadTemplate *) l->data;
1242           if (desttempl->presence == GST_PAD_REQUEST &&
1243               desttempl->direction != srctempl->direction) {
1244             if (gst_caps_is_always_compatible (gst_pad_template_get_caps
1245                     (srctempl), gst_pad_template_get_caps (desttempl))) {
1246               srcpad =
1247                   gst_element_get_request_pad (src, srctempl->name_template);
1248               destpad =
1249                   gst_element_get_request_pad (dest, desttempl->name_template);
1250               if (pad_link_maybe_ghosting (srcpad, destpad)) {
1251                 GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1252                     "linked pad %s:%s to pad %s:%s",
1253                     GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
1254                 gst_object_unref (srcpad);
1255                 gst_object_unref (destpad);
1256                 return TRUE;
1257               }
1258               /* it failed, so we release the request pads */
1259               gst_element_release_request_pad (src, srcpad);
1260               gst_element_release_request_pad (dest, destpad);
1261             }
1262           }
1263         }
1264       }
1265       srctempls = srctempls->next;
1266     }
1267   }
1268
1269   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no link possible from %s to %s",
1270       GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1271   return FALSE;
1272 }
1273
1274 /**
1275  * gst_element_link_pads_filtered:
1276  * @src: a #GstElement containing the source pad.
1277  * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
1278  * @dest: the #GstElement containing the destination pad.
1279  * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
1280  * @filter: the #GstCaps to filter the link, or #NULL for no filter.
1281  *
1282  * Links the two named pads of the source and destination elements. Side effect
1283  * is that if one of the pads has no parent, it becomes a child of the parent of
1284  * the other element. If they have different parents, the link fails. If @caps
1285  * is not #NULL, makes sure that the caps of the link is a subset of @caps.
1286  *
1287  * Returns: TRUE if the pads could be linked, FALSE otherwise.
1288  */
1289 gboolean
1290 gst_element_link_pads_filtered (GstElement * src, const gchar * srcpadname,
1291     GstElement * dest, const gchar * destpadname, GstCaps * filter)
1292 {
1293   /* checks */
1294   g_return_val_if_fail (GST_IS_ELEMENT (src), FALSE);
1295   g_return_val_if_fail (GST_IS_ELEMENT (dest), FALSE);
1296   g_return_val_if_fail (filter == NULL || GST_IS_CAPS (filter), FALSE);
1297
1298   if (filter) {
1299     GstElement *capsfilter;
1300     GstObject *parent;
1301     GstState state, pending;
1302     GTimeVal tv;
1303
1304     capsfilter = gst_element_factory_make ("capsfilter", NULL);
1305     if (!capsfilter) {
1306       GST_ERROR ("Could not make a capsfilter");
1307       return FALSE;
1308     }
1309
1310     parent = gst_object_get_parent (GST_OBJECT (src));
1311     g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
1312
1313     GST_TIME_TO_TIMEVAL (0, tv);
1314     gst_element_get_state (GST_ELEMENT_CAST (parent), &state, &pending, &tv);
1315
1316     if (!gst_bin_add (GST_BIN (parent), capsfilter)) {
1317       GST_ERROR ("Could not add capsfilter");
1318       gst_object_unref (capsfilter);
1319       gst_object_unref (parent);
1320       return FALSE;
1321     }
1322
1323     if (pending != GST_STATE_VOID_PENDING)
1324       state = pending;
1325
1326     gst_element_set_state (capsfilter, state);
1327
1328     gst_object_unref (parent);
1329
1330     g_object_set (capsfilter, "caps", filter, NULL);
1331
1332     if (gst_element_link_pads (src, srcpadname, capsfilter, "sink")
1333         && gst_element_link_pads (capsfilter, "src", dest, destpadname)) {
1334       return TRUE;
1335     } else {
1336       GST_INFO ("Could not link elements");
1337       gst_bin_remove (GST_BIN (GST_OBJECT_PARENT (capsfilter)), capsfilter);
1338       /* will unref and unlink as appropriate */
1339       return FALSE;
1340     }
1341   } else {
1342     return gst_element_link_pads (src, srcpadname, dest, destpadname);
1343   }
1344 }
1345
1346 /**
1347  * gst_element_link:
1348  * @src: a #GstElement containing the source pad.
1349  * @dest: the #GstElement containing the destination pad.
1350  *
1351  * Links @src to @dest. The link must be from source to
1352  * destination; the other direction will not be tried. The function looks for
1353  * existing pads that aren't linked yet. It will request new pads if necessary.
1354  * If multiple links are possible, only one is established.
1355  *
1356  * Returns: TRUE if the elements could be linked, FALSE otherwise.
1357  */
1358 gboolean
1359 gst_element_link (GstElement * src, GstElement * dest)
1360 {
1361   return gst_element_link_pads_filtered (src, NULL, dest, NULL, NULL);
1362 }
1363
1364 /**
1365  * gst_element_link_many:
1366  * @element_1: the first #GstElement in the link chain.
1367  * @element_2: the second #GstElement in the link chain.
1368  * @...: the NULL-terminated list of elements to link in order.
1369  *
1370  * Chain together a series of elements. Uses gst_element_link().
1371  *
1372  * Returns: TRUE on success, FALSE otherwise.
1373  */
1374 gboolean
1375 gst_element_link_many (GstElement * element_1, GstElement * element_2, ...)
1376 {
1377   va_list args;
1378
1379   g_return_val_if_fail (GST_IS_ELEMENT (element_1), FALSE);
1380   g_return_val_if_fail (GST_IS_ELEMENT (element_2), FALSE);
1381
1382   va_start (args, element_2);
1383
1384   while (element_2) {
1385     if (!gst_element_link (element_1, element_2))
1386       return FALSE;
1387
1388     element_1 = element_2;
1389     element_2 = va_arg (args, GstElement *);
1390   }
1391
1392   va_end (args);
1393
1394   return TRUE;
1395 }
1396
1397 /**
1398  * gst_element_link_filtered:
1399  * @src: a #GstElement containing the source pad.
1400  * @dest: the #GstElement containing the destination pad.
1401  * @filter: the #GstCaps to filter the link, or #NULL for no filter.
1402  *
1403  * Links @src to @dest using the given caps as filtercaps.
1404  * The link must be from source to
1405  * destination; the other direction will not be tried. The function looks for
1406  * existing pads that aren't linked yet. It will request new pads if necessary.
1407  * If multiple links are possible, only one is established.
1408  *
1409  * Returns: TRUE if the pads could be linked, FALSE otherwise.
1410  */
1411 gboolean
1412 gst_element_link_filtered (GstElement * src, GstElement * dest,
1413     GstCaps * filter)
1414 {
1415   return gst_element_link_pads_filtered (src, NULL, dest, NULL, filter);
1416 }
1417
1418 /**
1419  * gst_element_unlink_pads:
1420  * @src: a #GstElement containing the source pad.
1421  * @srcpadname: the name of the #GstPad in source element.
1422  * @dest: a #GstElement containing the destination pad.
1423  * @destpadname: the name of the #GstPad in destination element.
1424  *
1425  * Unlinks the two named pads of the source and destination elements.
1426  */
1427 void
1428 gst_element_unlink_pads (GstElement * src, const gchar * srcpadname,
1429     GstElement * dest, const gchar * destpadname)
1430 {
1431   GstPad *srcpad, *destpad;
1432
1433   g_return_if_fail (src != NULL);
1434   g_return_if_fail (GST_IS_ELEMENT (src));
1435   g_return_if_fail (srcpadname != NULL);
1436   g_return_if_fail (dest != NULL);
1437   g_return_if_fail (GST_IS_ELEMENT (dest));
1438   g_return_if_fail (destpadname != NULL);
1439
1440   /* obtain the pads requested */
1441   srcpad = gst_element_get_pad (src, srcpadname);
1442   if (srcpad == NULL) {
1443     GST_WARNING_OBJECT (src, "source element has no pad \"%s\"", srcpadname);
1444     return;
1445   }
1446   destpad = gst_element_get_pad (dest, destpadname);
1447   if (srcpad == NULL) {
1448     GST_WARNING_OBJECT (dest, "destination element has no pad \"%s\"",
1449         destpadname);
1450     return;
1451   }
1452
1453   /* we're satisified they can be unlinked, let's do it */
1454   gst_pad_unlink (srcpad, destpad);
1455 }
1456
1457 /**
1458  * gst_element_unlink_many:
1459  * @element_1: the first #GstElement in the link chain.
1460  * @element_2: the second #GstElement in the link chain.
1461  * @...: the NULL-terminated list of elements to unlink in order.
1462  *
1463  * Unlinks a series of elements. Uses gst_element_unlink().
1464  */
1465 void
1466 gst_element_unlink_many (GstElement * element_1, GstElement * element_2, ...)
1467 {
1468   va_list args;
1469
1470   g_return_if_fail (element_1 != NULL && element_2 != NULL);
1471   g_return_if_fail (GST_IS_ELEMENT (element_1) && GST_IS_ELEMENT (element_2));
1472
1473   va_start (args, element_2);
1474
1475   while (element_2) {
1476     gst_element_unlink (element_1, element_2);
1477
1478     element_1 = element_2;
1479     element_2 = va_arg (args, GstElement *);
1480   }
1481
1482   va_end (args);
1483 }
1484
1485 /**
1486  * gst_element_unlink:
1487  * @src: the source #GstElement to unlink.
1488  * @dest: the sink #GstElement to unlink.
1489  *
1490  * Unlinks all source pads of the source element with all sink pads
1491  * of the sink element to which they are linked.
1492  */
1493 void
1494 gst_element_unlink (GstElement * src, GstElement * dest)
1495 {
1496   GstIterator *pads;
1497   gboolean done = FALSE;
1498
1499   g_return_if_fail (GST_IS_ELEMENT (src));
1500   g_return_if_fail (GST_IS_ELEMENT (dest));
1501
1502   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unlinking \"%s\" and \"%s\"",
1503       GST_ELEMENT_NAME (src), GST_ELEMENT_NAME (dest));
1504
1505   pads = gst_element_iterate_pads (src);
1506   while (!done) {
1507     gpointer data;
1508
1509     switch (gst_iterator_next (pads, &data)) {
1510       case GST_ITERATOR_OK:
1511       {
1512         GstPad *pad = GST_PAD_CAST (data);
1513
1514         if (GST_PAD_IS_SRC (pad)) {
1515           GstPad *peerpad = gst_pad_get_peer (pad);
1516
1517           /* see if the pad is connected and is really a pad
1518            * of dest */
1519           if (peerpad) {
1520             GstElement *peerelem;
1521
1522             peerelem = gst_pad_get_parent_element (peerpad);
1523
1524             if (peerelem == dest) {
1525               gst_pad_unlink (pad, peerpad);
1526             }
1527             if (peerelem)
1528               gst_object_unref (peerelem);
1529
1530             gst_object_unref (peerpad);
1531           }
1532         }
1533         gst_object_unref (pad);
1534         break;
1535       }
1536       case GST_ITERATOR_RESYNC:
1537         gst_iterator_resync (pads);
1538         break;
1539       case GST_ITERATOR_DONE:
1540         done = TRUE;
1541         break;
1542       default:
1543         g_assert_not_reached ();
1544         break;
1545     }
1546   }
1547 }
1548
1549 gboolean
1550 gst_element_query_position (GstElement * element, GstFormat * format,
1551     gint64 * cur, gint64 * end)
1552 {
1553   GstQuery *query;
1554   gboolean ret;
1555
1556   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1557   g_return_val_if_fail (format != NULL, FALSE);
1558
1559   query = gst_query_new_position (*format);
1560   ret = gst_element_query (element, query);
1561
1562   if (ret)
1563     gst_query_parse_position (query, format, cur, end);
1564
1565   gst_query_unref (query);
1566
1567   return ret;
1568 }
1569
1570 gboolean
1571 gst_element_query_convert (GstElement * element, GstFormat src_format,
1572     gint64 src_val, GstFormat * dest_fmt, gint64 * dest_val)
1573 {
1574   GstQuery *query;
1575   gboolean ret;
1576
1577   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1578   g_return_val_if_fail (dest_fmt != NULL, FALSE);
1579   g_return_val_if_fail (dest_val != NULL, FALSE);
1580
1581   if (*dest_fmt == src_format) {
1582     *dest_val = src_val;
1583     return TRUE;
1584   }
1585
1586   query = gst_query_new_convert (src_format, src_val, *dest_fmt);
1587   ret = gst_element_query (element, query);
1588
1589   if (ret)
1590     gst_query_parse_convert (query, NULL, NULL, dest_fmt, dest_val);
1591
1592   gst_query_unref (query);
1593
1594   return ret;
1595 }
1596
1597
1598 /**
1599  * gst_pad_can_link:
1600  * @srcpad: the source #GstPad to link.
1601  * @sinkpad: the sink #GstPad to link.
1602  *
1603  * Checks if the source pad and the sink pad can be linked.
1604  * Both @srcpad and @sinkpad must be unlinked.
1605  *
1606  * Returns: TRUE if the pads can be linked, FALSE otherwise.
1607  */
1608 gboolean
1609 gst_pad_can_link (GstPad * srcpad, GstPad * sinkpad)
1610 {
1611   /* FIXME This function is gross.  It's almost a direct copy of
1612    * gst_pad_link_filtered().  Any decent programmer would attempt
1613    * to merge the two functions, which I will do some day. --ds
1614    */
1615
1616   /* generic checks */
1617   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
1618   g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE);
1619
1620   GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s",
1621       GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
1622
1623   /* FIXME: shouldn't we convert this to g_return_val_if_fail? */
1624   if (GST_PAD_PEER (srcpad) != NULL) {
1625     GST_CAT_INFO (GST_CAT_PADS, "Source pad %s:%s has a peer, failed",
1626         GST_DEBUG_PAD_NAME (srcpad));
1627     return FALSE;
1628   }
1629   if (GST_PAD_PEER (sinkpad) != NULL) {
1630     GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has a peer, failed",
1631         GST_DEBUG_PAD_NAME (sinkpad));
1632     return FALSE;
1633   }
1634   if (!GST_PAD_IS_SRC (srcpad)) {
1635     GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s is not source pad, failed",
1636         GST_DEBUG_PAD_NAME (srcpad));
1637     return FALSE;
1638   }
1639   if (!GST_PAD_IS_SINK (sinkpad)) {
1640     GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s is not sink pad, failed",
1641         GST_DEBUG_PAD_NAME (sinkpad));
1642     return FALSE;
1643   }
1644   if (GST_PAD_PARENT (srcpad) == NULL) {
1645     GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s has no parent, failed",
1646         GST_DEBUG_PAD_NAME (srcpad));
1647     return FALSE;
1648   }
1649   if (GST_PAD_PARENT (sinkpad) == NULL) {
1650     GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has no parent, failed",
1651         GST_DEBUG_PAD_NAME (srcpad));
1652     return FALSE;
1653   }
1654
1655   return TRUE;
1656 }
1657
1658 /**
1659  * gst_pad_use_fixed_caps:
1660  * @pad: the pad to use
1661  *
1662  * A helper function you can use that sets the 
1663  * @gst_pad_get_fixed_caps_func as the gstcaps function for the
1664  * pad. This way the function will always return the negotiated caps
1665  * or in case the pad is not negotiated, the padtemplate caps.
1666  *
1667  * Use this function on a pad that, once _set_caps() has been called
1668  * on it, it cannot be renegotiated to something else.
1669  */
1670 void
1671 gst_pad_use_fixed_caps (GstPad * pad)
1672 {
1673   gst_pad_set_getcaps_function (pad, gst_pad_get_fixed_caps_func);
1674 }
1675
1676 /**
1677  * gst_pad_get_fixed_caps_func:
1678  * @pad: the pad to use
1679  *
1680  * A helper function you can use as a GetCaps function that
1681  * will return the currently negotiated caps or the padtemplate
1682  * when NULL.
1683  *
1684  * Returns: The currently negotiated caps or the padtemplate.
1685  */
1686 GstCaps *
1687 gst_pad_get_fixed_caps_func (GstPad * pad)
1688 {
1689   GstCaps *result;
1690
1691   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1692
1693   if (GST_PAD_CAPS (pad)) {
1694     result = GST_PAD_CAPS (pad);
1695
1696     GST_CAT_DEBUG (GST_CAT_CAPS,
1697         "using pad caps %p %" GST_PTR_FORMAT, result, result);
1698
1699     result = gst_caps_ref (result);
1700     goto done;
1701   }
1702   if (GST_PAD_PAD_TEMPLATE (pad)) {
1703     GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad);
1704
1705     result = GST_PAD_TEMPLATE_CAPS (templ);
1706     GST_CAT_DEBUG (GST_CAT_CAPS,
1707         "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
1708         result);
1709
1710     result = gst_caps_ref (result);
1711     goto done;
1712   }
1713   GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps");
1714   result = gst_caps_new_empty ();
1715
1716 done:
1717   return result;
1718 }
1719
1720 /**
1721  * gst_pad_get_parent_element:
1722  * @pad: a pad
1723  *
1724  * Gets the parent of @pad, cast to a #GstElement. If a @pad has no parent or
1725  * its parent is not an element, return NULL.
1726  *
1727  * Returns: The parent of the pad. The caller has a reference on the parent, so
1728  * unref when you're finished with it.
1729  *
1730  * MT safe.
1731  */
1732 GstElement *
1733 gst_pad_get_parent_element (GstPad * pad)
1734 {
1735   GstObject *p;
1736
1737   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
1738
1739   p = gst_object_get_parent (GST_OBJECT_CAST (pad));
1740
1741   if (p && !GST_IS_ELEMENT (p)) {
1742     gst_object_unref (p);
1743     p = NULL;
1744   }
1745   return GST_ELEMENT_CAST (p);
1746 }
1747
1748 /**
1749  * gst_flow_get_name:
1750  * @ret: a #GstFlowReturn to get the name of.
1751  *
1752  * Gets a string representing the given flow return.
1753  *
1754  * Returns: a string with the name of the flow return.
1755  */
1756 G_CONST_RETURN gchar *
1757 gst_flow_get_name (GstFlowReturn ret)
1758 {
1759   switch (ret) {
1760     case GST_FLOW_RESEND:
1761       return "RESEND_BUFFER";
1762     case GST_FLOW_OK:
1763       return "OK";
1764       /* expected failures */
1765     case GST_FLOW_NOT_LINKED:
1766       return "NOT_LINKED";
1767     case GST_FLOW_WRONG_STATE:
1768       return "WRONG_STATE";
1769       /* error cases */
1770     case GST_FLOW_UNEXPECTED:
1771       return "UNEXPECTED";
1772     case GST_FLOW_NOT_NEGOTIATED:
1773       return "NOT_NEGOTIATED";
1774     case GST_FLOW_ERROR:
1775       return "ERROR";
1776     case GST_FLOW_NOT_SUPPORTED:
1777       return "NOT_SUPPORTED";
1778     default:
1779       return "UNKNOWN error";
1780   }
1781 }
1782
1783 /**
1784  * gst_object_default_error:
1785  * @source: the #GstObject that initiated the error.
1786  * @error: the GError.
1787  * @debug: an additional debug information string, or NULL.
1788  *
1789  * A default error function.
1790  *
1791  * The default handler will simply print the error string using g_print.
1792  */
1793 void
1794 gst_object_default_error (GstObject * source, GError * error, gchar * debug)
1795 {
1796   gchar *name = gst_object_get_path_string (source);
1797
1798   g_print (_("ERROR: from element %s: %s\n"), name, error->message);
1799   if (debug)
1800     g_print (_("Additional debug info:\n%s\n"), debug);
1801
1802   g_free (name);
1803 }
1804
1805 /**
1806  * gst_bin_add_many:
1807  * @bin: the bin to add the elements to
1808  * @element_1: the first element to add to the bin
1809  * @...: additional elements to add to the bin
1810  *
1811  * Adds a NULL-terminated list of elements to a bin.  This function is
1812  * equivalent to calling gst_bin_add() for each member of the list.
1813  */
1814 void
1815 gst_bin_add_many (GstBin * bin, GstElement * element_1, ...)
1816 {
1817   va_list args;
1818
1819   g_return_if_fail (GST_IS_BIN (bin));
1820   g_return_if_fail (GST_IS_ELEMENT (element_1));
1821
1822   va_start (args, element_1);
1823
1824   while (element_1) {
1825     gst_bin_add (bin, element_1);
1826
1827     element_1 = va_arg (args, GstElement *);
1828   }
1829
1830   va_end (args);
1831 }
1832
1833 /**
1834  * gst_bin_remove_many:
1835  * @bin: the bin to remove the elements from
1836  * @element_1: the first element to remove from the bin
1837  * @...: NULL-terminated list of elements to remove from the bin
1838  *
1839  * Remove a list of elements from a bin. This function is equivalent
1840  * to calling gst_bin_remove() with each member of the list.
1841  */
1842 void
1843 gst_bin_remove_many (GstBin * bin, GstElement * element_1, ...)
1844 {
1845   va_list args;
1846
1847   g_return_if_fail (GST_IS_BIN (bin));
1848   g_return_if_fail (GST_IS_ELEMENT (element_1));
1849
1850   va_start (args, element_1);
1851
1852   while (element_1) {
1853     gst_bin_remove (bin, element_1);
1854
1855     element_1 = va_arg (args, GstElement *);
1856   }
1857
1858   va_end (args);
1859 }
1860
1861 static void
1862 get_state_func (GstElement * element, gpointer unused)
1863 {
1864   GstStateChangeReturn ret = GST_STATE_CHANGE_ASYNC;
1865
1866   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1867       "new thread waiting on state change");
1868
1869   /* wait indefinitely */
1870   while (ret == GST_STATE_CHANGE_ASYNC)
1871     ret = gst_element_get_state (element, NULL, NULL, NULL);
1872
1873   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1874       "thread done waiting on state change");
1875
1876   gst_object_unref (element);
1877 }
1878
1879 /**
1880  * gst_bin_watch_for_state_change:
1881  * @bin: the bin to watch for state changes
1882  *
1883  * Spawns a thread calling gst_element_get_state on @bin with infinite timeout.
1884  *
1885  * In practice this is done because if a bin returns %GST_STATE_CHANGE_ASYNC
1886  * from a state change, it will not commit its state until someone calls
1887  * gst_element_get_state() on it. Thus having another thread checking the bin's
1888  * state will ensure that a state-changed message gets posted on the bus
1889  * eventually.
1890  *
1891  * This function is admittedly a bit of a hack. Bins should always post
1892  * messages. However this behavior was broken out into this function to avoid
1893  * spawning threads when scrubbing, when the bin's state is changing quickly and
1894  * asynchronously.
1895  */
1896 void
1897 gst_bin_watch_for_state_change (GstBin * bin)
1898 {
1899   static GThreadPool *pool = NULL;
1900   static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
1901
1902   g_static_mutex_lock (&mutex);
1903   if (pool == NULL)
1904     pool = g_thread_pool_new ((GFunc) get_state_func, NULL, -1, FALSE, NULL);
1905   g_static_mutex_unlock (&mutex);
1906
1907   g_thread_pool_push (pool, gst_object_ref (bin), NULL);
1908 }
1909
1910 struct _GstAsyncThreadData
1911 {
1912   GstElement *element;
1913   GstState state;
1914 };
1915
1916 static void
1917 set_state_async_thread_func (struct _GstAsyncThreadData *data, gpointer unused)
1918 {
1919   GstState current, pending;
1920   GstStateChangeReturn ret = GST_STATE_CHANGE_ASYNC;
1921
1922   GST_CAT_INFO_OBJECT (GST_CAT_STATES, data->element,
1923       "new thread ensuring state change to %s",
1924       gst_element_state_get_name (data->state));
1925
1926   while (TRUE) {
1927     /* wait indefinitely */
1928     ret = gst_element_get_state (data->element, &current, &pending, NULL);
1929     GST_CAT_INFO_OBJECT (GST_CAT_STATES, data->element,
1930         "get_state returned %d, current %s, pending %s", ret,
1931         gst_element_state_get_name (current),
1932         gst_element_state_get_name (pending));
1933
1934     /* can only be SUCCESS or FAILURE */
1935     if (ret == GST_STATE_CHANGE_FAILURE) {
1936       /* we can only break, hopefully an error message was posted as well */
1937       GST_CAT_INFO_OBJECT (GST_CAT_STATES, data->element,
1938           "FAILURE during state change");
1939       break;
1940     } else if (ret == GST_STATE_CHANGE_SUCCESS) {
1941       if (current == data->state) {
1942         GST_CAT_INFO_OBJECT (GST_CAT_STATES, data->element,
1943             "successfully reached final state");
1944         break;
1945       }
1946       GST_CAT_INFO_OBJECT (GST_CAT_STATES, data->element,
1947           "setting target state %s again",
1948           gst_element_state_get_name (data->state));
1949       gst_element_set_state (data->element, data->state);
1950     } else {
1951       g_assert_not_reached ();
1952     }
1953   }
1954
1955   GST_CAT_INFO_OBJECT (GST_CAT_STATES, data->element,
1956       "thread done waiting on state change");
1957
1958   gst_object_unref (data->element);
1959   g_free (data);
1960 }
1961
1962 /**
1963  * gst_element_set_state_async:
1964  * @element: a #GstElement to change state of
1965  * @state: the element's new #GstState
1966  *
1967  * Sets the state of the element. This function will try to set the
1968  * requested state by going through all the intermediary states and calling
1969  * the class's state change function for each.  If the state change returns
1970  * #GST_STATE_CHANGE_ASYNC at any time, a thread will be started to
1971  * monitor the state change and make sure the element is brought to the
1972  * requested state.
1973  *
1974  * Returns: Result of the state change using #GstStateChangeReturn.
1975  *
1976  * MT safe.
1977  */
1978 GstStateChangeReturn
1979 gst_element_set_state_async (GstElement * element, GstState state)
1980 {
1981   GstStateChangeReturn ret;
1982   struct _GstAsyncThreadData *data;
1983
1984   ret = gst_element_set_state (element, state);
1985   if (ret == GST_STATE_CHANGE_ASYNC) {
1986     static GThreadPool *pool = NULL;
1987     static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
1988
1989     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1990         "starting new thread to ensure state change to %s",
1991         gst_element_state_get_name (state));
1992     g_static_mutex_lock (&mutex);
1993     if (pool == NULL)
1994       pool = g_thread_pool_new ((GFunc) set_state_async_thread_func,
1995           NULL, -1, FALSE, NULL);
1996     g_static_mutex_unlock (&mutex);
1997
1998     data = g_new0 (struct _GstAsyncThreadData, 1);
1999
2000     gst_object_ref (element);
2001     data->element = element;
2002     data->state = state;
2003     g_thread_pool_push (pool, data, NULL);
2004   }
2005
2006   return ret;
2007 }
2008
2009 static void
2010 gst_element_populate_std_props (GObjectClass * klass, const gchar * prop_name,
2011     guint arg_id, GParamFlags flags)
2012 {
2013   GQuark prop_id = g_quark_from_string (prop_name);
2014   GParamSpec *pspec;
2015
2016   static GQuark fd_id = 0;
2017   static GQuark blocksize_id;
2018   static GQuark bytesperread_id;
2019   static GQuark dump_id;
2020   static GQuark filesize_id;
2021   static GQuark mmapsize_id;
2022   static GQuark location_id;
2023   static GQuark offset_id;
2024   static GQuark silent_id;
2025   static GQuark touch_id;
2026
2027   if (!fd_id) {
2028     fd_id = g_quark_from_static_string ("fd");
2029     blocksize_id = g_quark_from_static_string ("blocksize");
2030     bytesperread_id = g_quark_from_static_string ("bytesperread");
2031     dump_id = g_quark_from_static_string ("dump");
2032     filesize_id = g_quark_from_static_string ("filesize");
2033     mmapsize_id = g_quark_from_static_string ("mmapsize");
2034     location_id = g_quark_from_static_string ("location");
2035     offset_id = g_quark_from_static_string ("offset");
2036     silent_id = g_quark_from_static_string ("silent");
2037     touch_id = g_quark_from_static_string ("touch");
2038   }
2039
2040   if (prop_id == fd_id) {
2041     pspec = g_param_spec_int ("fd", "File-descriptor",
2042         "File-descriptor for the file being read", 0, G_MAXINT, 0, flags);
2043   } else if (prop_id == blocksize_id) {
2044     pspec = g_param_spec_ulong ("blocksize", "Block Size",
2045         "Block size to read per buffer", 0, G_MAXULONG, 4096, flags);
2046
2047   } else if (prop_id == bytesperread_id) {
2048     pspec = g_param_spec_int ("bytesperread", "Bytes per read",
2049         "Number of bytes to read per buffer", G_MININT, G_MAXINT, 0, flags);
2050
2051   } else if (prop_id == dump_id) {
2052     pspec = g_param_spec_boolean ("dump", "Dump",
2053         "Dump bytes to stdout", FALSE, flags);
2054
2055   } else if (prop_id == filesize_id) {
2056     pspec = g_param_spec_int64 ("filesize", "File Size",
2057         "Size of the file being read", 0, G_MAXINT64, 0, flags);
2058
2059   } else if (prop_id == mmapsize_id) {
2060     pspec = g_param_spec_ulong ("mmapsize", "mmap() Block Size",
2061         "Size in bytes of mmap()d regions", 0, G_MAXULONG, 4 * 1048576, flags);
2062
2063   } else if (prop_id == location_id) {
2064     pspec = g_param_spec_string ("location", "File Location",
2065         "Location of the file to read", NULL, flags);
2066
2067   } else if (prop_id == offset_id) {
2068     pspec = g_param_spec_int64 ("offset", "File Offset",
2069         "Byte offset of current read pointer", 0, G_MAXINT64, 0, flags);
2070
2071   } else if (prop_id == silent_id) {
2072     pspec = g_param_spec_boolean ("silent", "Silent", "Don't produce events",
2073         FALSE, flags);
2074
2075   } else if (prop_id == touch_id) {
2076     pspec = g_param_spec_boolean ("touch", "Touch read data",
2077         "Touch data to force disk read before " "push ()", TRUE, flags);
2078   } else {
2079     g_warning ("Unknown - 'standard' property '%s' id %d from klass %s",
2080         prop_name, arg_id, g_type_name (G_OBJECT_CLASS_TYPE (klass)));
2081     pspec = NULL;
2082   }
2083
2084   if (pspec) {
2085     g_object_class_install_property (klass, arg_id, pspec);
2086   }
2087 }
2088
2089 /**
2090  * gst_element_class_install_std_props:
2091  * @klass: the #GstElementClass to add the properties to.
2092  * @first_name: the name of the first property.
2093  * in a NULL terminated
2094  * @...: the id and flags of the first property, followed by
2095  * further 'name', 'id', 'flags' triplets and terminated by NULL.
2096  *
2097  * Adds a list of standardized properties with types to the @klass.
2098  * the id is for the property switch in your get_prop method, and
2099  * the flags determine readability / writeability.
2100  **/
2101 void
2102 gst_element_class_install_std_props (GstElementClass * klass,
2103     const gchar * first_name, ...)
2104 {
2105   const char *name;
2106
2107   va_list args;
2108
2109   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
2110
2111   va_start (args, first_name);
2112
2113   name = first_name;
2114
2115   while (name) {
2116     int arg_id = va_arg (args, int);
2117     int flags = va_arg (args, int);
2118
2119     gst_element_populate_std_props ((GObjectClass *) klass, name, arg_id,
2120         flags);
2121
2122     name = va_arg (args, char *);
2123   }
2124
2125   va_end (args);
2126 }
2127
2128
2129 /**
2130  * gst_buffer_merge:
2131  * @buf1: a first source #GstBuffer to merge.
2132  * @buf2: the second source #GstBuffer to merge.
2133  *
2134  * Create a new buffer that is the concatenation of the two source
2135  * buffers.  The original source buffers will not be modified or
2136  * unref'd.  Make sure you unref the source buffers if they are not used
2137  * anymore afterwards.
2138  *
2139  * If the buffers point to contiguous areas of memory, the buffer
2140  * is created without copying the data.
2141  *
2142  * Returns: the new #GstBuffer that's the concatenation of the source buffers.
2143  */
2144 GstBuffer *
2145 gst_buffer_merge (GstBuffer * buf1, GstBuffer * buf2)
2146 {
2147   GstBuffer *result;
2148
2149   /* we're just a specific case of the more general gst_buffer_span() */
2150   result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
2151
2152   return result;
2153 }
2154
2155 /**
2156  * gst_buffer_join:
2157  * @buf1: a first source #GstBuffer to join.
2158  * @buf2: the second source #GstBuffer to join.
2159  *
2160  * Create a new buffer that is the concatenation of the two source
2161  * buffers, and takes ownership of the original source buffers.
2162  *
2163  * If the buffers point to contiguous areas of memory, the buffer
2164  * is created without copying the data.
2165  *
2166  * Returns: the new #GstBuffer that's the concatenation of the source buffers.
2167  */
2168 GstBuffer *
2169 gst_buffer_join (GstBuffer * buf1, GstBuffer * buf2)
2170 {
2171   GstBuffer *result;
2172
2173   result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
2174   gst_buffer_unref (buf1);
2175   gst_buffer_unref (buf2);
2176
2177   return result;
2178 }
2179
2180
2181 /**
2182  * gst_buffer_stamp:
2183  * @dest: buffer to stamp
2184  * @src: buffer to stamp from
2185  *
2186  * Copies additional information (timestamps and offsets) from one buffer to
2187  * the other.
2188  */
2189 void
2190 gst_buffer_stamp (GstBuffer * dest, const GstBuffer * src)
2191 {
2192   g_return_if_fail (dest != NULL);
2193   g_return_if_fail (src != NULL);
2194
2195   GST_BUFFER_TIMESTAMP (dest) = GST_BUFFER_TIMESTAMP (src);
2196   GST_BUFFER_DURATION (dest) = GST_BUFFER_DURATION (src);
2197   GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET (src);
2198   GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_END (src);
2199 }
2200
2201 static gboolean
2202 intersect_caps_func (GstPad * pad, GValue * ret, GstPad * orig)
2203 {
2204   if (pad != orig) {
2205     GstCaps *peercaps, *existing;
2206
2207     existing = g_value_get_pointer (ret);
2208     peercaps = gst_pad_peer_get_caps (pad);
2209     if (peercaps == NULL)
2210       peercaps = gst_caps_new_any ();
2211     g_value_set_pointer (ret, gst_caps_intersect (existing, peercaps));
2212     gst_caps_unref (existing);
2213     gst_caps_unref (peercaps);
2214   }
2215   gst_object_unref (pad);
2216   return TRUE;
2217 }
2218
2219 /**
2220  * gst_pad_proxy_getcaps:
2221  * @pad: a #GstPad to proxy.
2222  *
2223  * Calls gst_pad_get_allowed_caps() for every other pad belonging to the
2224  * same element as @pad, and returns the intersection of the results.
2225  *
2226  * This function is useful as a default getcaps function for an element
2227  * that can handle any stream format, but requires all its pads to have
2228  * the same caps.  Two such elements are tee and aggregator.
2229  *
2230  * Returns: the intersection of the other pads' allowed caps.
2231  */
2232 GstCaps *
2233 gst_pad_proxy_getcaps (GstPad * pad)
2234 {
2235   GstElement *element;
2236   GstCaps *caps, *intersected;
2237   GstIterator *iter;
2238   GstIteratorResult res;
2239   GValue ret = { 0, };
2240
2241   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
2242
2243   GST_DEBUG ("proxying getcaps for %s:%s", GST_DEBUG_PAD_NAME (pad));
2244
2245   element = gst_pad_get_parent_element (pad);
2246   if (element == NULL)
2247     return NULL;
2248
2249   iter = gst_element_iterate_pads (element);
2250
2251   g_value_init (&ret, G_TYPE_POINTER);
2252   g_value_set_pointer (&ret, gst_caps_new_any ());
2253
2254   res = gst_iterator_fold (iter, (GstIteratorFoldFunction) intersect_caps_func,
2255       &ret, pad);
2256   gst_iterator_free (iter);
2257
2258   if (res != GST_ITERATOR_DONE)
2259     goto pads_changed;
2260
2261   gst_object_unref (element);
2262
2263   caps = g_value_get_pointer (&ret);
2264   g_value_unset (&ret);
2265
2266   intersected = gst_caps_intersect (caps, gst_pad_get_pad_template_caps (pad));
2267   gst_caps_unref (caps);
2268
2269   return intersected;
2270
2271   /* ERRORS */
2272 pads_changed:
2273   {
2274     g_warning ("Pad list changed during capsnego for element %s",
2275         GST_ELEMENT_NAME (element));
2276     gst_object_unref (element);
2277     return NULL;
2278   }
2279 }
2280
2281 typedef struct
2282 {
2283   GstPad *orig;
2284   GstCaps *caps;
2285 } LinkData;
2286
2287 static gboolean
2288 link_fold_func (GstPad * pad, GValue * ret, LinkData * data)
2289 {
2290   gboolean success = TRUE;
2291
2292   if (pad != data->orig) {
2293     success = gst_pad_set_caps (pad, data->caps);
2294     g_value_set_boolean (ret, success);
2295   }
2296   gst_object_unref (pad);
2297
2298   return success;
2299 }
2300
2301 /**
2302  * gst_pad_proxy_setcaps
2303  * @pad: a #GstPad to proxy from
2304  * @caps: the #GstCaps to link with
2305  *
2306  * Calls gst_pad_set_caps() for every other pad belonging to the
2307  * same element as @pad.  If gst_pad_set_caps() fails on any pad,
2308  * the proxy setcaps fails. May be used only during negotiation.
2309  *
2310  * Returns: TRUE if sucessful
2311  */
2312 gboolean
2313 gst_pad_proxy_setcaps (GstPad * pad, GstCaps * caps)
2314 {
2315   GstElement *element;
2316   GstIterator *iter;
2317   GstIteratorResult res;
2318   GValue ret = { 0, };
2319   LinkData data;
2320
2321   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2322   g_return_val_if_fail (caps != NULL, FALSE);
2323
2324   GST_DEBUG ("proxying pad link for %s:%s", GST_DEBUG_PAD_NAME (pad));
2325
2326   element = gst_pad_get_parent_element (pad);
2327   if (element == NULL)
2328     return FALSE;
2329
2330   iter = gst_element_iterate_pads (element);
2331
2332   g_value_init (&ret, G_TYPE_BOOLEAN);
2333   g_value_set_boolean (&ret, TRUE);
2334   data.orig = pad;
2335   data.caps = caps;
2336
2337   res = gst_iterator_fold (iter, (GstIteratorFoldFunction) link_fold_func,
2338       &ret, &data);
2339   gst_iterator_free (iter);
2340
2341   if (res != GST_ITERATOR_DONE)
2342     goto pads_changed;
2343
2344   gst_object_unref (element);
2345
2346   /* ok not to unset the gvalue */
2347   return g_value_get_boolean (&ret);
2348
2349   /* ERRORS */
2350 pads_changed:
2351   {
2352     g_warning ("Pad list changed during proxy_pad_link for element %s",
2353         GST_ELEMENT_NAME (element));
2354     gst_object_unref (element);
2355     return FALSE;
2356   }
2357 }
2358
2359 /**
2360  * gst_pad_query_position:
2361  * @pad: a #GstPad to invoke the position query on.
2362  * @format: a pointer to the #GstFormat asked for.
2363  *          On return contains the #GstFormat used.
2364  * @cur: A location in which to store the current position, or NULL.
2365  * @end: A location in which to store the end position (length), or NULL.
2366  *
2367  * Queries a pad for the stream position and length.
2368  *
2369  * Returns: TRUE if the query could be performed.
2370  */
2371 gboolean
2372 gst_pad_query_position (GstPad * pad, GstFormat * format, gint64 * cur,
2373     gint64 * end)
2374 {
2375   GstQuery *query;
2376   gboolean ret;
2377
2378   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2379   g_return_val_if_fail (format != NULL, FALSE);
2380
2381   query = gst_query_new_position (*format);
2382   ret = gst_pad_query (pad, query);
2383
2384   if (ret)
2385     gst_query_parse_position (query, format, cur, end);
2386
2387   gst_query_unref (query);
2388
2389   return ret;
2390 }
2391
2392 /**
2393  * gst_pad_query_convert:
2394  * @pad: a #GstPad to invoke the convert query on.
2395  * @src_format: a #GstFormat to convert from.
2396  * @src_val: a value to convert.
2397  * @dest_format: a pointer to the #GstFormat to convert to. 
2398  * @dest_val: a pointer to the result.
2399  *
2400  * Queries a pad to convert @src_val in @src_format to @dest_format.
2401  *
2402  * Returns: TRUE if the query could be performed.
2403  */
2404 gboolean
2405 gst_pad_query_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
2406     GstFormat * dest_format, gint64 * dest_val)
2407 {
2408   GstQuery *query;
2409   gboolean ret;
2410
2411   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
2412   g_return_val_if_fail (dest_format != NULL, FALSE);
2413   g_return_val_if_fail (dest_val != NULL, FALSE);
2414
2415   if (*dest_format == src_format) {
2416     *dest_val = src_val;
2417     return TRUE;
2418   }
2419
2420   query = gst_query_new_convert (src_format, src_val, *dest_format);
2421   ret = gst_pad_query (pad, query);
2422
2423   if (ret)
2424     gst_query_parse_convert (query, NULL, NULL, dest_format, dest_val);
2425
2426   gst_query_unref (query);
2427
2428   return ret;
2429 }
2430
2431 /**
2432  * gst_atomic_int_set:
2433  * @atomic_int: pointer to an atomic integer
2434  * @value: value to set
2435  *
2436  * Unconditionally sets the atomic integer to @value.
2437  */
2438 void
2439 gst_atomic_int_set (gint * atomic_int, gint value)
2440 {
2441   int ignore;
2442
2443   *atomic_int = value;
2444   /* read acts as a memory barrier */
2445   ignore = g_atomic_int_get (atomic_int);
2446 }
2447
2448 /**
2449  * gst_pad_add_data_probe:
2450  * @pad: pad to add the data probe handler to
2451  * @handler: function to call when data is passed over pad
2452  * @data: data to pass along with the handler
2453  *
2454  * Adds a "data probe" to a pad. This function will be called whenever data
2455  * passes through a pad. In this case data means both events and buffers. The
2456  * probe will be called with the data as an argument. Note that the data will
2457  * have a reference count greater than 1, so it will be immutable -- you must
2458  * not change it.
2459  *
2460  * For source pads, the probe will be called after the blocking function, if any
2461  * (see gst_pad_set_blocked_async()), but before looking up the peer to chain
2462  * to. For sink pads, the probe function will be called before configuring the
2463  * sink with new caps, if any, and before calling the pad's chain function.
2464  *
2465  * Your data probe should return TRUE to let the data continue to flow, or FALSE
2466  * to drop it. Dropping data is rarely useful, but occasionally comes in handy
2467  * with events.
2468  *
2469  * Although probes are implemented internally by connecting @handler to the
2470  * have-data signal on the pad, if you want to remove a probe it is insufficient
2471  * to only call g_signal_handler_disconnect on the returned handler id. To
2472  * remove a probe, use the appropriate function, such as
2473  * gst_pad_remove_data_probe().
2474  *
2475  * Returns: The handler id.
2476  */
2477 gulong
2478 gst_pad_add_data_probe (GstPad * pad, GCallback handler, gpointer data)
2479 {
2480   gulong sigid;
2481
2482   g_return_val_if_fail (GST_IS_PAD (pad), 0);
2483   g_return_val_if_fail (handler != NULL, 0);
2484
2485   GST_LOCK (pad);
2486   sigid = g_signal_connect (pad, "have-data", handler, data);
2487   GST_PAD_DO_EVENT_SIGNALS (pad)++;
2488   GST_PAD_DO_BUFFER_SIGNALS (pad)++;
2489   GST_DEBUG ("adding data probe to pad %s:%s, now %d data, %d event probes",
2490       GST_DEBUG_PAD_NAME (pad),
2491       GST_PAD_DO_BUFFER_SIGNALS (pad), GST_PAD_DO_EVENT_SIGNALS (pad));
2492   GST_UNLOCK (pad);
2493
2494   return sigid;
2495 }
2496
2497 /**
2498  * gst_pad_add_event_probe:
2499  * @pad: pad to add the event probe handler to
2500  * @handler: function to call when data is passed over pad
2501  * @data: data to pass along with the handler
2502  *
2503  * Adds a probe that will be called for all events passing through a pad. See
2504  * gst_pad_add_data_probe() for more information.
2505  *
2506  * Returns: The handler id
2507  */
2508 gulong
2509 gst_pad_add_event_probe (GstPad * pad, GCallback handler, gpointer data)
2510 {
2511   gulong sigid;
2512
2513   g_return_val_if_fail (GST_IS_PAD (pad), 0);
2514   g_return_val_if_fail (handler != NULL, 0);
2515
2516   GST_LOCK (pad);
2517   sigid = g_signal_connect (pad, "have-data::event", handler, data);
2518   GST_PAD_DO_EVENT_SIGNALS (pad)++;
2519   GST_DEBUG ("adding event probe to pad %s:%s, now %d probes",
2520       GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_EVENT_SIGNALS (pad));
2521   GST_UNLOCK (pad);
2522
2523   return sigid;
2524 }
2525
2526 /**
2527  * gst_pad_add_buffer_probe:
2528  * @pad: pad to add the buffer probe handler to
2529  * @handler: function to call when data is passed over pad
2530  * @data: data to pass along with the handler
2531  *
2532  * Adds a probe that will be called for all buffers passing through a pad. See
2533  * gst_pad_add_data_probe() for more information.
2534  *
2535  * Returns: The handler id
2536  */
2537 gulong
2538 gst_pad_add_buffer_probe (GstPad * pad, GCallback handler, gpointer data)
2539 {
2540   gulong sigid;
2541
2542   g_return_val_if_fail (GST_IS_PAD (pad), 0);
2543   g_return_val_if_fail (handler != NULL, 0);
2544
2545   GST_LOCK (pad);
2546   sigid = g_signal_connect (pad, "have-data::buffer", handler, data);
2547   GST_PAD_DO_BUFFER_SIGNALS (pad)++;
2548   GST_DEBUG ("adding buffer probe to pad %s:%s, now %d probes",
2549       GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_BUFFER_SIGNALS (pad));
2550   GST_UNLOCK (pad);
2551
2552   return sigid;
2553 }
2554
2555 /**
2556  * gst_pad_remove_data_probe:
2557  * @pad: pad to remove the data probe handler from
2558  * @handler_id: handler id returned from gst_pad_add_data_probe
2559  *
2560  * Removes a data probe from @pad.
2561  */
2562 void
2563 gst_pad_remove_data_probe (GstPad * pad, guint handler_id)
2564 {
2565   g_return_if_fail (GST_IS_PAD (pad));
2566   g_return_if_fail (handler_id > 0);
2567
2568   GST_LOCK (pad);
2569   g_signal_handler_disconnect (pad, handler_id);
2570   GST_PAD_DO_BUFFER_SIGNALS (pad)--;
2571   GST_PAD_DO_EVENT_SIGNALS (pad)--;
2572   GST_DEBUG
2573       ("removed data probe from pad %s:%s, now %d event, %d buffer probes",
2574       GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_EVENT_SIGNALS (pad),
2575       GST_PAD_DO_BUFFER_SIGNALS (pad));
2576   GST_UNLOCK (pad);
2577 }
2578
2579 /**
2580  * gst_pad_remove_event_probe:
2581  * @pad: pad to remove the event probe handler from
2582  * @handler_id: handler id returned from gst_pad_add_event_probe
2583  *
2584  * Removes an event probe from @pad.
2585  */
2586 void
2587 gst_pad_remove_event_probe (GstPad * pad, guint handler_id)
2588 {
2589   g_return_if_fail (GST_IS_PAD (pad));
2590   g_return_if_fail (handler_id > 0);
2591
2592   GST_LOCK (pad);
2593   g_signal_handler_disconnect (pad, handler_id);
2594   GST_PAD_DO_EVENT_SIGNALS (pad)--;
2595   GST_DEBUG ("removed event probe from pad %s:%s, now %d event probes",
2596       GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_EVENT_SIGNALS (pad));
2597   GST_UNLOCK (pad);
2598 }
2599
2600 /**
2601  * gst_pad_remove_buffer_probe:
2602  * @pad: pad to remove the buffer probe handler from
2603  * @handler_id: handler id returned from gst_pad_add_buffer_probe
2604  *
2605  * Removes a buffer probe from @pad.
2606  */
2607 void
2608 gst_pad_remove_buffer_probe (GstPad * pad, guint handler_id)
2609 {
2610   g_return_if_fail (GST_IS_PAD (pad));
2611   g_return_if_fail (handler_id > 0);
2612
2613   GST_LOCK (pad);
2614   g_signal_handler_disconnect (pad, handler_id);
2615   GST_PAD_DO_BUFFER_SIGNALS (pad)--;
2616   GST_DEBUG ("removed buffer probe from pad %s:%s, now %d buffer probes",
2617       GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_BUFFER_SIGNALS (pad));
2618   GST_UNLOCK (pad);
2619 }
2620
2621 /**
2622  * gst_element_found_tags_for_pad:
2623  * @element: element for which to post taglist to bus.
2624  * @pad: pad on which to push tag-event.
2625  * @list: the taglist to post on the bus and create event from.
2626  *
2627  * Posts a message to the bus that new tags were found and pushes the
2628  * tags as event. Takes ownership of the taglist.
2629  */
2630 void
2631 gst_element_found_tags_for_pad (GstElement * element,
2632     GstPad * pad, GstTagList * list)
2633 {
2634   g_return_if_fail (element != NULL);
2635   g_return_if_fail (pad != NULL);
2636   g_return_if_fail (list != NULL);
2637
2638   gst_pad_push_event (pad, gst_event_new_tag (gst_tag_list_copy (list)));
2639   gst_element_post_message (element,
2640       gst_message_new_tag (GST_OBJECT (element), list));
2641 }
2642
2643 static void
2644 push_and_ref (GstPad * pad, GstEvent * event)
2645 {
2646   gst_pad_push_event (pad, gst_event_ref (event));
2647 }
2648
2649 /**
2650  * gst_element_found_tags:
2651  * @element: element for which we found the tags.
2652  * @list: list of tags.
2653  *
2654  * Posts a message to the bus that new tags were found, and pushes an event
2655  * to all sourcepads. Takes ownership of the taglist.
2656  */
2657 void
2658 gst_element_found_tags (GstElement * element, GstTagList * list)
2659 {
2660   GstIterator *iter;
2661   GstEvent *event;
2662
2663   g_return_if_fail (element != NULL);
2664   g_return_if_fail (list != NULL);
2665
2666   iter = gst_element_iterate_src_pads (element);
2667   event = gst_event_new_tag (gst_tag_list_copy (list));
2668   gst_iterator_foreach (iter, (GFunc) push_and_ref, event);
2669   gst_iterator_free (iter);
2670   gst_event_unref (event);
2671
2672   gst_element_post_message (element,
2673       gst_message_new_tag (GST_OBJECT (element), list));
2674 }