gst/gstelement.c: And free the GStaticRecMutex too
[platform/upstream/gstreamer.git] / gst / gstelement.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2004 Wim Taymans <wim@fluendo.com>
4  *
5  * gstelement.c: The base element, all elements derive from this
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:gstelement
24  * @short_description: Abstract base class for all pipeline elements
25  * @see_also: #GstElementFactory, #GstPad
26  *
27  * GstElement is the base class needed to construct an element that can be
28  * used in a GStreamer pipeline.  As such, it is not a functional entity, and
29  * cannot do anything when placed in a pipeline.
30  * 
31  * The name of a GstElement can be get with gst_element_get_name() and set with
32  * gst_element_set_name().  For speed, GST_ELEMENT_NAME() can be used in the 
33  * core when using the appropriate locking. Do not use this in plug-ins or 
34  * applications in order to retain ABI compatibility.
35  * 
36  * All elements have pads (of the type #GstPad).  These pads link to pads on
37  * other elements.  Buffers flow between these linked pads.
38  * A GstElement has a GList of #GstPad structures for all their input (or sink)
39  * and output (or source) pads.  
40  * Core and plug-in writers can add and remove pads with gst_element_add_pad()
41  * and gst_element_remove_pad().
42  *
43  * A pad of an element can be retrieved by name with gst_element_get_pad().
44  * An iterator of all pads can be retrieved with gst_element_iterate_pads().
45  * 
46  * Elements can be linked through their pads.
47  * If the link is straightforward, use the gst_element_link() 
48  * convenience function to link two elements, or gst_element_link_many() 
49  * for more elements in a row.
50  * Use gst_element_link_filtered() to link two elements constrained by
51  * a specified set of #GstCaps.
52  * For finer control, use gst_element_link_pads() and 
53  * gst_element_link_pads_filtered() to specify the pads to link on 
54  * each element by name.
55  * 
56  * Each element has a state (see #GstState).  You can get and set the state
57  * of an element with gst_element_get_state() and gst_element_set_state().  
58  * You can wait for an element to change it's state with gst_element_wait_state_change().
59  * To get a string representation of a #GstState, use 
60  * gst_element_state_get_name().
61  * 
62  * You can get and set a #GstClock on an element using gst_element_get_clock()
63  * and gst_element_set_clock().  
64  * Some elements can provide a clock for the pipeline if  
65  * gst_element_provides_clock() returns TRUE. With the gst_element_provide_clock()
66  * method one can retrieve the clock provided by such an element.
67  * Not all elements require a clock to operate correctly. If 
68  * gst_element_requires_clock() returns TRUE, a clock should be set on the element
69  * with gst_element_set_clock(). 
70  *
71  * Note that clock slection and distribution is normally handled by the toplevel 
72  * #GstPipeline so the clock functions are only to be used in very specific situations.
73  */
74 #include "gst_private.h"
75 #include <glib.h>
76 #include <stdarg.h>
77 #include <gobject/gvaluecollector.h>
78
79 #include "gstelement.h"
80 #include "gstbus.h"
81 #include "gstmarshal.h"
82 #include "gsterror.h"
83 #include "gstevent.h"
84 #include "gstutils.h"
85 #include "gstinfo.h"
86 #include "gst-i18n-lib.h"
87
88 /* Element signals and args */
89 enum
90 {
91   STATE_CHANGE,
92   NEW_PAD,
93   PAD_REMOVED,
94   NO_MORE_PADS,
95   /* add more above */
96   LAST_SIGNAL
97 };
98
99 enum
100 {
101   ARG_0
102       /* FILL ME */
103 };
104
105 extern void __gst_element_details_clear (GstElementDetails * dp);
106 extern void __gst_element_details_copy (GstElementDetails * dest,
107     const GstElementDetails * src);
108
109 static void gst_element_class_init (GstElementClass * klass);
110 static void gst_element_init (GstElement * element);
111 static void gst_element_base_class_init (gpointer g_class);
112 static void gst_element_base_class_finalize (gpointer g_class);
113
114 static void gst_element_dispose (GObject * object);
115 static void gst_element_finalize (GObject * object);
116
117 static GstStateChangeReturn gst_element_change_state (GstElement * element,
118     GstStateChange transition);
119 static GstStateChangeReturn gst_element_change_state_func (GstElement * element,
120     GstStateChange transition);
121 static GstStateChangeReturn gst_element_get_state_func (GstElement * element,
122     GstState * state, GstState * pending, GTimeVal * timeout);
123 static void gst_element_set_bus_func (GstElement * element, GstBus * bus);
124
125 #ifndef GST_DISABLE_LOADSAVE
126 static xmlNodePtr gst_element_save_thyself (GstObject * object,
127     xmlNodePtr parent);
128 static void gst_element_restore_thyself (GstObject * parent, xmlNodePtr self);
129 #endif
130
131 GType _gst_element_type = 0;
132
133 static GstObjectClass *parent_class = NULL;
134 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
135
136 GType
137 gst_element_get_type (void)
138 {
139   if (!_gst_element_type) {
140     static const GTypeInfo element_info = {
141       sizeof (GstElementClass),
142       gst_element_base_class_init,
143       gst_element_base_class_finalize,
144       (GClassInitFunc) gst_element_class_init,
145       NULL,
146       NULL,
147       sizeof (GstElement),
148       0,
149       (GInstanceInitFunc) gst_element_init,
150       NULL
151     };
152
153     _gst_element_type = g_type_register_static (GST_TYPE_OBJECT, "GstElement",
154         &element_info, G_TYPE_FLAG_ABSTRACT);
155   }
156   return _gst_element_type;
157 }
158
159 static void
160 gst_element_class_init (GstElementClass * klass)
161 {
162   GObjectClass *gobject_class;
163   GstObjectClass *gstobject_class;
164
165   gobject_class = (GObjectClass *) klass;
166   gstobject_class = (GstObjectClass *) klass;
167
168   parent_class = g_type_class_ref (GST_TYPE_OBJECT);
169
170   /**
171    * GstElement::pad-added:
172    * @gstelement: the object which received the signal
173    * @new_pad: the pad that has been added
174    *
175    * a new #GstPad has been added to the element.
176    */
177   gst_element_signals[NEW_PAD] =
178       g_signal_new ("pad-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
179       G_STRUCT_OFFSET (GstElementClass, pad_added), NULL, NULL,
180       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
181   /**
182    * GstElement::pad-removed:
183    * @gstelement: the object which received the signal
184    * @old_pad: the pad that has been removed
185    *
186    * a #GstPad has been removed from the element
187    */
188   gst_element_signals[PAD_REMOVED] =
189       g_signal_new ("pad-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
190       G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
191       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
192   /**
193    * GstElement::no-more-pads:
194    * @gstelement: the object which received the signal
195    *
196    * This signals that the element will not generate more dynamic pads.
197    */
198   gst_element_signals[NO_MORE_PADS] =
199       g_signal_new ("no-more-pads", G_TYPE_FROM_CLASS (klass),
200       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, no_more_pads), NULL,
201       NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
202
203   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
204   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_element_finalize);
205
206 #ifndef GST_DISABLE_LOADSAVE
207   gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
208   gstobject_class->restore_thyself =
209       GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
210 #endif
211
212   klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state_func);
213   klass->get_state = GST_DEBUG_FUNCPTR (gst_element_get_state_func);
214   klass->set_bus = GST_DEBUG_FUNCPTR (gst_element_set_bus_func);
215   klass->numpadtemplates = 0;
216
217   klass->elementfactory = NULL;
218 }
219
220 static void
221 gst_element_base_class_init (gpointer g_class)
222 {
223   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
224
225   memset (&element_class->details, 0, sizeof (GstElementDetails));
226   element_class->padtemplates = NULL;
227 }
228
229 static void
230 gst_element_base_class_finalize (gpointer g_class)
231 {
232   GstElementClass *klass = GST_ELEMENT_CLASS (g_class);
233
234   g_list_foreach (klass->padtemplates, (GFunc) gst_object_unref, NULL);
235   g_list_free (klass->padtemplates);
236   __gst_element_details_clear (&klass->details);
237 }
238
239 static void
240 gst_element_init (GstElement * element)
241 {
242   element->current_state = GST_STATE_NULL;
243   element->pending_state = GST_STATE_VOID_PENDING;
244   element->state_lock = g_new0 (GStaticRecMutex, 1);
245   g_static_rec_mutex_init (element->state_lock);
246   element->state_cond = g_cond_new ();
247 }
248
249 /**
250  * gst_element_default_error:
251  * @object: a #GObject that signalled the error.
252  * @orig: the #GstObject that initiated the error.
253  * @error: the GError.
254  * @debug: an additional debug information string, or NULL.
255  *
256  * A default error signal callback to attach to an element.
257  * The user data passed to the g_signal_connect is ignored.
258  *
259  * The default handler will simply print the error string using g_print.
260  *
261  * MT safe.
262  */
263 void
264 gst_element_default_error (GObject * object, GstObject * source, GError * error,
265     gchar * debug)
266 {
267   gchar *name = gst_object_get_path_string (source);
268
269   g_print (_("ERROR: from element %s: %s\n"), name, error->message);
270   if (debug)
271     g_print (_("Additional debug info:\n%s\n"), debug);
272
273   g_free (name);
274 }
275
276 /**
277  * gst_element_release_request_pad:
278  * @element: a #GstElement to release the request pad of.
279  * @pad: the #GstPad to release.
280  *
281  * Makes the element free the previously requested pad as obtained
282  * with gst_element_get_request_pad().
283  *
284  * MT safe.
285  */
286 void
287 gst_element_release_request_pad (GstElement * element, GstPad * pad)
288 {
289   GstElementClass *oclass;
290
291   g_return_if_fail (GST_IS_ELEMENT (element));
292   g_return_if_fail (GST_IS_PAD (pad));
293
294   oclass = GST_ELEMENT_GET_CLASS (element);
295
296   if (oclass->release_pad)
297     (oclass->release_pad) (element, pad);
298   else
299     gst_element_remove_pad (element, pad);
300 }
301
302 /**
303  * gst_element_requires_clock:
304  * @element: a #GstElement to query
305  *
306  * Query if the element requires a clock.
307  *
308  * Returns: TRUE if the element requires a clock
309  *
310  * MT safe.
311  */
312 gboolean
313 gst_element_requires_clock (GstElement * element)
314 {
315   gboolean result;
316
317   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
318
319   result = (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
320
321   return result;
322 }
323
324 /**
325  * gst_element_provides_clock:
326  * @element: a #GstElement to query
327  *
328  * Query if the element provides a clock.
329  *
330  * Returns: TRUE if the element provides a clock
331  *
332  * MT safe.
333  */
334 gboolean
335 gst_element_provides_clock (GstElement * element)
336 {
337   gboolean result;
338
339   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
340
341   result = (GST_ELEMENT_GET_CLASS (element)->provide_clock != NULL);
342
343   return result;
344 }
345
346 /**
347  * gst_element_provide_clock:
348  * @element: a #GstElement to query
349  *
350  * Get the clock provided by the given element.
351  *
352  * Returns: the GstClock provided by the element or NULL
353  * if no clock could be provided. Unref after usage.
354  *
355  * MT safe.
356  */
357 GstClock *
358 gst_element_provide_clock (GstElement * element)
359 {
360   GstClock *result = NULL;
361   GstElementClass *oclass;
362
363   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
364
365   oclass = GST_ELEMENT_GET_CLASS (element);
366
367   if (oclass->provide_clock)
368     result = oclass->provide_clock (element);
369
370   return result;
371 }
372
373 /**
374  * gst_element_set_clock:
375  * @element: a #GstElement to set the clock for.
376  * @clock: the #GstClock to set for the element.
377  *
378  * Sets the clock for the element. This function increases the
379  * refcount on the clock. Any previously set clock on the object
380  * is unreffed.
381  *
382  * MT safe.
383  */
384 void
385 gst_element_set_clock (GstElement * element, GstClock * clock)
386 {
387   GstElementClass *oclass;
388
389   g_return_if_fail (GST_IS_ELEMENT (element));
390
391   oclass = GST_ELEMENT_GET_CLASS (element);
392
393   if (oclass->set_clock)
394     oclass->set_clock (element, clock);
395
396   GST_LOCK (element);
397   gst_object_replace ((GstObject **) & element->clock, (GstObject *) clock);
398   GST_UNLOCK (element);
399 }
400
401 /**
402  * gst_element_get_clock:
403  * @element: a #GstElement to get the clock of.
404  *
405  * Gets the currently configured clock of the element.
406  *
407  * Returns: the #GstClock of the element. unref after usage.
408  *
409  * MT safe.
410  */
411 GstClock *
412 gst_element_get_clock (GstElement * element)
413 {
414   GstClock *result;
415
416   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
417
418   GST_LOCK (element);
419   if ((result = element->clock))
420     gst_object_ref (result);
421   GST_UNLOCK (element);
422
423   return result;
424 }
425
426 /**
427  * gst_element_set_base_time:
428  * @element: a #GstElement.
429  * @time: the base time to set.
430  *
431  * Set the base time of an element. See @gst_element_get_base_time().
432  *
433  * MT safe.
434  */
435 void
436 gst_element_set_base_time (GstElement * element, GstClockTime time)
437 {
438   g_return_if_fail (GST_IS_ELEMENT (element));
439
440   GST_LOCK (element);
441   element->base_time = time;
442   GST_UNLOCK (element);
443 }
444
445 /**
446  * gst_element_get_base_time:
447  * @element: a #GstElement.
448  *
449  * Returns the base time of the element. The base time is the
450  * absolute time of the clock when this element was last put to
451  * PLAYING. Substracting the base time from the clock time gives
452  * the stream time of the element.
453  *
454  * Returns: the base time of the element.
455  *
456  * MT safe.
457  */
458 GstClockTime
459 gst_element_get_base_time (GstElement * element)
460 {
461   GstClockTime result;
462
463   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
464
465   GST_LOCK (element);
466   result = element->base_time;
467   GST_UNLOCK (element);
468
469   return result;
470 }
471
472 #ifndef GST_DISABLE_INDEX
473 /**
474  * gst_element_is_indexable:
475  * @element: a #GstElement.
476  *
477  * Queries if the element can be indexed.
478  *
479  * Returns: TRUE if the element can be indexed.
480  *
481  * MT safe.
482  */
483 gboolean
484 gst_element_is_indexable (GstElement * element)
485 {
486   gboolean result;
487
488   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
489
490   result = (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
491
492   return result;
493 }
494
495 /**
496  * gst_element_set_index:
497  * @element: a #GstElement.
498  * @index: a #GstIndex.
499  *
500  * Set the specified GstIndex on the element. The refcount of the index
501  * will be increased, any previously set index is unreffed.
502  *
503  * MT safe.
504  */
505 void
506 gst_element_set_index (GstElement * element, GstIndex * index)
507 {
508   GstElementClass *oclass;
509
510   g_return_if_fail (GST_IS_ELEMENT (element));
511   g_return_if_fail (GST_IS_INDEX (index));
512
513   oclass = GST_ELEMENT_GET_CLASS (element);
514
515   if (oclass->set_index)
516     oclass->set_index (element, index);
517 }
518
519 /**
520  * gst_element_get_index:
521  * @element: a #GstElement.
522  *
523  * Gets the index from the element.
524  *
525  * Returns: a #GstIndex or NULL when no index was set on the
526  * element. unref after usage.
527  *
528  * MT safe.
529  */
530 GstIndex *
531 gst_element_get_index (GstElement * element)
532 {
533   GstElementClass *oclass;
534
535   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
536
537   oclass = GST_ELEMENT_GET_CLASS (element);
538
539   if (oclass->get_index)
540     return oclass->get_index (element);
541
542   return NULL;
543 }
544 #endif
545
546 /**
547  * gst_element_add_pad:
548  * @element: a #GstElement to add the pad to.
549  * @pad: the #GstPad to add to the element.
550  *
551  * Adds a pad (link point) to @element. @pad's parent will be set to @element;
552  * see gst_object_set_parent() for refcounting information.
553  *
554  * Pads are not automatically activated so elements should perform the needed
555  * steps to activate the pad in case this pad is added in the PAUSED or PLAYING
556  * state. 
557  *
558  * The pad and the element should be unlocked when calling this function.
559  *
560  * Returns: TRUE if the pad could be added. This function can fail when
561  * passing bad arguments or when a pad with the same name already existed.
562  *
563  * MT safe.
564  */
565 gboolean
566 gst_element_add_pad (GstElement * element, GstPad * pad)
567 {
568   gchar *pad_name;
569
570   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
571   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
572
573   /* locking pad to look at the name */
574   GST_LOCK (pad);
575   pad_name = g_strdup (GST_PAD_NAME (pad));
576   GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'",
577       GST_STR_NULL (pad_name));
578   GST_UNLOCK (pad);
579
580   /* then check to see if there's already a pad by that name here */
581   GST_LOCK (element);
582   if (G_UNLIKELY (!gst_object_check_uniqueness (element->pads, pad_name)))
583     goto name_exists;
584
585   /* try to set the pad's parent */
586   if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (pad),
587               GST_OBJECT_CAST (element))))
588     goto had_parent;
589
590   g_free (pad_name);
591
592   /* add it to the list */
593   switch (gst_pad_get_direction (pad)) {
594     case GST_PAD_SRC:
595       element->srcpads = g_list_prepend (element->srcpads, pad);
596       element->numsrcpads++;
597       break;
598     case GST_PAD_SINK:
599       element->sinkpads = g_list_prepend (element->sinkpads, pad);
600       element->numsinkpads++;
601       break;
602     default:
603       goto no_direction;
604   }
605   element->pads = g_list_prepend (element->pads, pad);
606   element->numpads++;
607   element->pads_cookie++;
608   GST_UNLOCK (element);
609
610   /* emit the NEW_PAD signal */
611   g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
612
613   return TRUE;
614
615   /* ERROR cases */
616 name_exists:
617   {
618     g_critical ("Padname %s is not unique in element %s, not adding",
619         pad_name, GST_ELEMENT_NAME (element));
620     GST_UNLOCK (element);
621     g_free (pad_name);
622     return FALSE;
623   }
624 had_parent:
625   {
626     g_critical
627         ("Pad %s already has parent when trying to add to element %s",
628         pad_name, GST_ELEMENT_NAME (element));
629     GST_UNLOCK (element);
630     g_free (pad_name);
631     return FALSE;
632   }
633 no_direction:
634   {
635     GST_LOCK (pad);
636     g_critical
637         ("Trying to add pad %s to element %s, but it has no direction",
638         GST_OBJECT_NAME (pad), GST_ELEMENT_NAME (element));
639     GST_UNLOCK (pad);
640     GST_UNLOCK (element);
641     return FALSE;
642   }
643 }
644
645 /**
646  * gst_element_remove_pad:
647  * @element: a #GstElement to remove pad from.
648  * @pad: the #GstPad to remove from the element.
649  *
650  * Removes @pad from @element. @pad will be destroyed if it has not been
651  * referenced elsewhere.
652  *
653  * Returns: TRUE if the pad could be removed. Can return FALSE if the
654  * pad is not belonging to the provided element or when wrong parameters
655  * are passed to this function.
656  *
657  * MT safe.
658  */
659 gboolean
660 gst_element_remove_pad (GstElement * element, GstPad * pad)
661 {
662   GstPad *peer;
663
664   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
665   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
666
667   /* locking pad to look at the name and parent */
668   GST_LOCK (pad);
669   GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "removing pad '%s'",
670       GST_STR_NULL (GST_PAD_NAME (pad)));
671
672   if (G_UNLIKELY (GST_PAD_PARENT (pad) != element))
673     goto not_our_pad;
674   GST_UNLOCK (pad);
675
676   /* unlink */
677   if ((peer = gst_pad_get_peer (pad))) {
678     /* window for MT unsafeness, someone else could unlink here
679      * and then we call unlink with wrong pads. The unlink
680      * function would catch this and safely return failed. */
681     if (GST_PAD_IS_SRC (pad))
682       gst_pad_unlink (pad, peer);
683     else
684       gst_pad_unlink (peer, pad);
685
686     gst_object_unref (peer);
687   }
688
689   GST_LOCK (element);
690   /* remove it from the list */
691   switch (gst_pad_get_direction (pad)) {
692     case GST_PAD_SRC:
693       element->srcpads = g_list_remove (element->srcpads, pad);
694       element->numsrcpads--;
695       break;
696     case GST_PAD_SINK:
697       element->sinkpads = g_list_remove (element->sinkpads, pad);
698       element->numsinkpads--;
699       break;
700     default:
701       g_critical ("Removing pad without direction???");
702       break;
703   }
704   element->pads = g_list_remove (element->pads, pad);
705   element->numpads--;
706   element->pads_cookie++;
707   GST_UNLOCK (element);
708
709   g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
710
711   gst_object_unparent (GST_OBJECT (pad));
712
713   return TRUE;
714
715 not_our_pad:
716   {
717     /* FIXME, locking order? */
718     GST_LOCK (element);
719     g_critical ("Padname %s:%s does not belong to element %s when removing",
720         GST_ELEMENT_NAME (GST_PAD_PARENT (pad)), GST_PAD_NAME (pad),
721         GST_ELEMENT_NAME (element));
722     GST_UNLOCK (element);
723     GST_UNLOCK (pad);
724     return FALSE;
725   }
726 }
727
728 /**
729  * gst_element_no_more_pads:
730  * @element: a #GstElement
731  *
732  * Use this function to signal that the element does not expect any more pads
733  * to show up in the current pipeline. This function should be called whenever
734  * pads have been added by the element itself. Elements with GST_PAD_SOMETIMES
735  * pad templates use this in combination with autopluggers to figure out that
736  * the element is done initializing its pads.
737  *
738  * MT safe.
739  */
740 void
741 gst_element_no_more_pads (GstElement * element)
742 {
743   g_return_if_fail (GST_IS_ELEMENT (element));
744
745   g_signal_emit (element, gst_element_signals[NO_MORE_PADS], 0);
746 }
747
748 static gint
749 pad_compare_name (GstPad * pad1, const gchar * name)
750 {
751   gint result;
752
753   GST_LOCK (pad1);
754   result = strcmp (GST_PAD_NAME (pad1), name);
755   GST_UNLOCK (pad1);
756
757   return result;
758 }
759
760 /**
761  * gst_element_get_static_pad:
762  * @element: a #GstElement to find a static pad of.
763  * @name: the name of the static #GstPad to retrieve.
764  *
765  * Retrieves a pad from @element by name. This version only retrieves
766  * already-existing (i.e. 'static') pads.
767  *
768  * Returns: the requested #GstPad if found, otherwise NULL. unref after
769  * usage.
770  *
771  * MT safe.
772  */
773 GstPad *
774 gst_element_get_static_pad (GstElement * element, const gchar * name)
775 {
776   GList *find;
777   GstPad *result = NULL;
778
779   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
780   g_return_val_if_fail (name != NULL, NULL);
781
782   GST_LOCK (element);
783   find =
784       g_list_find_custom (element->pads, name, (GCompareFunc) pad_compare_name);
785   if (find) {
786     result = GST_PAD_CAST (find->data);
787     gst_object_ref (result);
788   }
789
790   if (result == NULL) {
791     GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"",
792         name, GST_ELEMENT_NAME (element));
793   } else {
794     GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
795         GST_ELEMENT_NAME (element), name);
796   }
797   GST_UNLOCK (element);
798
799   return result;
800 }
801
802 static GstPad *
803 gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
804     const gchar * name)
805 {
806   GstPad *newpad = NULL;
807   GstElementClass *oclass;
808
809   oclass = GST_ELEMENT_GET_CLASS (element);
810
811   if (oclass->request_new_pad)
812     newpad = (oclass->request_new_pad) (element, templ, name);
813
814   if (newpad)
815     gst_object_ref (newpad);
816
817   return newpad;
818 }
819
820 /**
821  * gst_element_get_request_pad:
822  * @element: a #GstElement to find a request pad of.
823  * @name: the name of the request #GstPad to retrieve.
824  *
825  * Retrieves a pad from the element by name. This version only retrieves
826  * request pads.
827  *
828  * Returns: requested #GstPad if found, otherwise NULL. Unref after usage.
829  */
830 GstPad *
831 gst_element_get_request_pad (GstElement * element, const gchar * name)
832 {
833   GstPadTemplate *templ = NULL;
834   GstPad *pad;
835   const gchar *req_name = NULL;
836   gboolean templ_found = FALSE;
837   GList *list;
838   gint n;
839   const gchar *data;
840   gchar *str, *endptr = NULL;
841   GstElementClass *class;
842
843   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
844   g_return_val_if_fail (name != NULL, NULL);
845
846   class = GST_ELEMENT_GET_CLASS (element);
847
848   if (strstr (name, "%")) {
849     templ = gst_element_class_get_pad_template (class, name);
850     req_name = NULL;
851     if (templ)
852       templ_found = TRUE;
853   } else {
854     list = gst_element_class_get_pad_template_list (class);
855     while (!templ_found && list) {
856       templ = (GstPadTemplate *) list->data;
857       if (templ->presence == GST_PAD_REQUEST) {
858         /* Because of sanity checks in gst_pad_template_new(), we know that %s
859            and %d, occurring at the end of the name_template, are the only
860            possibilities. */
861         GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
862             templ->name_template);
863         if ((str = strchr (templ->name_template, '%'))
864             && strncmp (templ->name_template, name,
865                 str - templ->name_template) == 0
866             && strlen (name) > str - templ->name_template) {
867           data = name + (str - templ->name_template);
868           if (*(str + 1) == 'd') {
869             /* it's an int */
870             n = (gint) strtol (data, &endptr, 10);
871             if (endptr && *endptr == '\0') {
872               templ_found = TRUE;
873               req_name = name;
874               break;
875             }
876           } else {
877             /* it's a string */
878             templ_found = TRUE;
879             req_name = name;
880             break;
881           }
882         }
883       }
884       list = list->next;
885     }
886   }
887
888   if (!templ_found)
889     return NULL;
890
891   pad = gst_element_request_pad (element, templ, req_name);
892
893   return pad;
894 }
895
896 /**
897  * gst_element_get_pad:
898  * @element: a #GstElement.
899  * @name: the name of the pad to retrieve.
900  *
901  * Retrieves a pad from @element by name. Tries gst_element_get_static_pad()
902  * first, then gst_element_get_request_pad().
903  *
904  * Returns: the #GstPad if found, otherwise %NULL. Unref after usage.
905  */
906 GstPad *
907 gst_element_get_pad (GstElement * element, const gchar * name)
908 {
909   GstPad *pad;
910
911   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
912   g_return_val_if_fail (name != NULL, NULL);
913
914   pad = gst_element_get_static_pad (element, name);
915   if (!pad)
916     pad = gst_element_get_request_pad (element, name);
917
918   return pad;
919 }
920
921 static GstIteratorItem
922 iterate_pad (GstIterator * it, GstPad * pad)
923 {
924   gst_object_ref (pad);
925   return GST_ITERATOR_ITEM_PASS;
926 }
927
928 /**
929  * gst_element_iterate_pads:
930  * @element: a #GstElement to iterate pads of.
931  *
932  * Retrieves an iterattor of @element's pads. The iterator should
933  * be freed after usage.
934  *
935  * Returns: the #GstIterator of #GstPad. Unref each pad after use.
936  *
937  * MT safe.
938  */
939 GstIterator *
940 gst_element_iterate_pads (GstElement * element)
941 {
942   GstIterator *result;
943
944   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
945
946   GST_LOCK (element);
947   gst_object_ref (element);
948   result = gst_iterator_new_list (GST_TYPE_PAD,
949       GST_GET_LOCK (element),
950       &element->pads_cookie,
951       &element->pads,
952       element,
953       (GstIteratorItemFunction) iterate_pad,
954       (GstIteratorDisposeFunction) gst_object_unref);
955   GST_UNLOCK (element);
956
957   return result;
958 }
959
960 static gint
961 direction_filter (gconstpointer pad, gconstpointer direction)
962 {
963   if (GST_PAD_DIRECTION (pad) == GPOINTER_TO_INT (direction)) {
964     /* pass the ref through */
965     return 0;
966   } else {
967     /* unref */
968     /* FIXME: this is very stupid */
969     gst_object_unref (GST_OBJECT_CAST (pad));
970     return 1;
971   }
972 }
973
974 /**
975  * gst_element_iterate_src_pads:
976  * @element: a #GstElement.
977  *
978  * Retrieves an iterator of @element's source pads. 
979  *
980  * Returns: the #GstIterator of #GstPad. Unref each pad after use.
981  *
982  * MT safe.
983  */
984 GstIterator *
985 gst_element_iterate_src_pads (GstElement * element)
986 {
987   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
988
989   return gst_iterator_filter (gst_element_iterate_pads (element),
990       direction_filter, GINT_TO_POINTER (GST_PAD_SRC));
991 }
992
993 /**
994  * gst_element_iterate_sink_pads:
995  * @element: a #GstElement.
996  *
997  * Retrieves an iterator of @element's sink pads. 
998  *
999  * Returns: the #GstIterator of #GstPad. Unref each pad after use.
1000  *
1001  * MT safe.
1002  */
1003 GstIterator *
1004 gst_element_iterate_sink_pads (GstElement * element)
1005 {
1006   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1007
1008   return gst_iterator_filter (gst_element_iterate_pads (element),
1009       direction_filter, GINT_TO_POINTER (GST_PAD_SINK));
1010 }
1011
1012 /**
1013  * gst_element_class_add_pad_template:
1014  * @klass: the #GstElementClass to add the pad template to.
1015  * @templ: a #GstPadTemplate to add to the element class.
1016  *
1017  * Adds a padtemplate to an element class. This is mainly used in the _base_init
1018  * functions of classes.
1019  */
1020 void
1021 gst_element_class_add_pad_template (GstElementClass * klass,
1022     GstPadTemplate * templ)
1023 {
1024   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1025   g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1026
1027   /* avoid registering pad templates with the same name */
1028   g_return_if_fail (gst_element_class_get_pad_template (klass,
1029           templ->name_template) == NULL);
1030
1031   klass->padtemplates = g_list_append (klass->padtemplates,
1032       gst_object_ref (templ));
1033   klass->numpadtemplates++;
1034 }
1035
1036 /**
1037  * gst_element_class_set_details:
1038  * @klass: class to set details for
1039  * @details: details to set
1040  *
1041  * Sets the detailed information for a #GstElementClass.
1042  * <note>This function is for use in _base_init functions only.</note>
1043  */
1044 void
1045 gst_element_class_set_details (GstElementClass * klass,
1046     const GstElementDetails * details)
1047 {
1048   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1049   g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
1050
1051   __gst_element_details_copy (&klass->details, details);
1052 }
1053
1054 /**
1055  * gst_element_class_get_pad_template_list:
1056  * @element_class: a #GstElementClass to get pad templates of.
1057  *
1058  * Retrieves a list of the pad templates associated with @element_class. The
1059  * list must not be modified by the calling code.
1060  * <note>If you use this function in the #GInstanceInitFunc of an object class
1061  * that has subclasses, make sure to pass the g_class parameter of the
1062  * #GInstanceInitFunc here.</note>
1063  *
1064  * Returns: the #GList of padtemplates.
1065  */
1066 GList *
1067 gst_element_class_get_pad_template_list (GstElementClass * element_class)
1068 {
1069   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1070
1071   return element_class->padtemplates;
1072 }
1073
1074 /**
1075  * gst_element_class_get_pad_template:
1076  * @element_class: a #GstElementClass to get the pad template of.
1077  * @name: the name of the #GstPadTemplate to get.
1078  *
1079  * Retrieves a padtemplate from @element_class with the given name.
1080  * <note>If you use this function in the #GInstanceInitFunc of an object class
1081  * that has subclasses, make sure to pass the g_class parameter of the
1082  * #GInstanceInitFunc here.</note>
1083  *
1084  * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1085  * No unreferencing is necessary.
1086  */
1087 GstPadTemplate *
1088 gst_element_class_get_pad_template (GstElementClass * element_class,
1089     const gchar * name)
1090 {
1091   GList *padlist;
1092
1093   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1094   g_return_val_if_fail (name != NULL, NULL);
1095
1096   padlist = gst_element_class_get_pad_template_list (element_class);
1097
1098   while (padlist) {
1099     GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1100
1101     if (strcmp (padtempl->name_template, name) == 0)
1102       return padtempl;
1103
1104     padlist = g_list_next (padlist);
1105   }
1106
1107   return NULL;
1108 }
1109
1110 static GstPad *
1111 gst_element_get_random_pad (GstElement * element, GstPadDirection dir)
1112 {
1113   GstPad *result = NULL;
1114   GList *pads;
1115
1116   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
1117
1118   switch (dir) {
1119     case GST_PAD_SRC:
1120       GST_LOCK (element);
1121       pads = element->srcpads;
1122       break;
1123     case GST_PAD_SINK:
1124       GST_LOCK (element);
1125       pads = element->sinkpads;
1126       break;
1127     default:
1128       goto wrong_direction;
1129   }
1130   for (; pads; pads = g_list_next (pads)) {
1131     GstPad *pad = GST_PAD (pads->data);
1132
1133     GST_LOCK (pad);
1134     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
1135         GST_DEBUG_PAD_NAME (pad));
1136
1137     if (GST_PAD_IS_LINKED (pad)) {
1138       GST_UNLOCK (pad);
1139       result = pad;
1140       break;
1141     } else {
1142       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
1143           GST_DEBUG_PAD_NAME (pad));
1144     }
1145     GST_UNLOCK (pad);
1146   }
1147   if (result)
1148     gst_object_ref (result);
1149
1150   GST_UNLOCK (element);
1151
1152   return result;
1153
1154   /* ERROR handling */
1155 wrong_direction:
1156   {
1157     g_warning ("unknown pad direction %d", dir);
1158     return NULL;
1159   }
1160 }
1161
1162 /**
1163  * gst_element_send_event:
1164  * @element: a #GstElement to send the event to.
1165  * @event: the #GstEvent to send to the element.
1166  *
1167  * Sends an event to an element. If the element doesn't
1168  * implement an event handler, the event will be forwarded
1169  * to a random sink pad. This function takes owership of the
1170  * provided event so you should _ref it if you want to reuse
1171  * the event after this call.
1172  *
1173  * Returns: TRUE if the event was handled.
1174  *
1175  * MT safe.
1176  */
1177 gboolean
1178 gst_element_send_event (GstElement * element, GstEvent * event)
1179 {
1180   GstElementClass *oclass;
1181   gboolean result = FALSE;
1182
1183   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1184   g_return_val_if_fail (event != NULL, FALSE);
1185
1186   oclass = GST_ELEMENT_GET_CLASS (element);
1187
1188   if (oclass->send_event) {
1189     result = oclass->send_event (element, event);
1190   } else {
1191     GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1192
1193     if (pad) {
1194       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1195           "pushing event to random pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1196
1197       result = gst_pad_push_event (pad, event);
1198       gst_object_unref (pad);
1199     } else {
1200       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
1201           GST_ELEMENT_NAME (element));
1202     }
1203   }
1204   return result;
1205 }
1206
1207 /**
1208  * gst_element_seek:
1209  * @element: a #GstElement to send the event to.
1210  * @rate: The new playback rate
1211  * @format: The format of the seek values
1212  * @flags: The optional seek flags.
1213  * @cur_type: The type and flags for the new current position
1214  * @cur: The value of the new current position
1215  * @stop_type: The type and flags for the new stop position
1216  * @stop: The value of the new stop position
1217  *
1218  * Sends a seek event to an element.
1219  *
1220  * Returns: %TRUE if the event was handled.
1221  *
1222  * MT safe.
1223  */
1224 gboolean
1225 gst_element_seek (GstElement * element, gdouble rate, GstFormat format,
1226     GstSeekFlags flags, GstSeekType cur_type, gint64 cur,
1227     GstSeekType stop_type, gint64 stop)
1228 {
1229   GstEvent *event;
1230   gboolean result;
1231
1232   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1233
1234   event =
1235       gst_event_new_seek (rate, format, flags, cur_type, cur, stop_type, stop);
1236   result = gst_element_send_event (element, event);
1237
1238   return result;
1239 }
1240
1241 /**
1242  * gst_element_get_query_types:
1243  * @element: a #GstElement to query
1244  *
1245  * Get an array of query types from the element.
1246  * If the element doesn't implement a query types function,
1247  * the query will be forwarded to a random sink pad.
1248  *
1249  * Returns: An array of #GstQueryType elements that should not
1250  * be freed or modified.
1251  *
1252  * MT safe.
1253  */
1254 const GstQueryType *
1255 gst_element_get_query_types (GstElement * element)
1256 {
1257   GstElementClass *oclass;
1258   const GstQueryType *result = NULL;
1259
1260   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1261
1262   oclass = GST_ELEMENT_GET_CLASS (element);
1263
1264   if (oclass->get_query_types) {
1265     result = oclass->get_query_types (element);
1266   } else {
1267     GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1268
1269     if (pad) {
1270       GstPad *peer = gst_pad_get_peer (pad);
1271
1272       if (peer) {
1273         result = gst_pad_get_query_types (peer);
1274
1275         gst_object_unref (peer);
1276       }
1277       gst_object_unref (pad);
1278     }
1279   }
1280   return result;
1281 }
1282
1283 /**
1284  * gst_element_query:
1285  * @element: a #GstElement to perform the query on.
1286  * @query: the #GstQuery.
1287  *
1288  * Performs a query on the given element. If the format is set
1289  * to GST_FORMAT_DEFAULT and this function returns TRUE, the
1290  * format pointer will hold the default format.
1291  * For element that don't implement a query handler, this function
1292  * forwards the query to a random usable sinkpad of this element.
1293  *
1294  * Returns: TRUE if the query could be performed.
1295  *
1296  * MT safe.
1297  */
1298 gboolean
1299 gst_element_query (GstElement * element, GstQuery * query)
1300 {
1301   GstElementClass *oclass;
1302   gboolean result = FALSE;
1303
1304   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1305   g_return_val_if_fail (query != NULL, FALSE);
1306
1307   oclass = GST_ELEMENT_GET_CLASS (element);
1308
1309   if (oclass->query) {
1310     result = oclass->query (element, query);
1311   } else {
1312     GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
1313
1314     if (pad) {
1315       result = gst_pad_query (pad, query);
1316
1317       gst_object_unref (pad);
1318     } else {
1319       pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1320       if (pad) {
1321         GstPad *peer = gst_pad_get_peer (pad);
1322
1323         if (peer) {
1324           result = gst_pad_query (peer, query);
1325
1326           gst_object_unref (peer);
1327         }
1328         gst_object_unref (pad);
1329       }
1330     }
1331   }
1332   return result;
1333 }
1334
1335 /**
1336  * gst_element_post_message:
1337  * @element: a #GstElement posting the message
1338  * @message: a #GstMessage to post
1339  *
1340  * Post a message on the element's #GstBus. This function takes ownership of the
1341  * message; if you want to access the message after this call, you should add an
1342  * additional reference before calling.
1343  *
1344  * Returns: TRUE if the message was successfully posted.
1345  *
1346  * MT safe.
1347  */
1348 gboolean
1349 gst_element_post_message (GstElement * element, GstMessage * message)
1350 {
1351   GstBus *bus;
1352   gboolean result = FALSE;
1353
1354   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1355   g_return_val_if_fail (message != NULL, FALSE);
1356
1357   GST_LOCK (element);
1358   bus = element->bus;
1359
1360   if (G_UNLIKELY (bus == NULL))
1361     goto no_bus;
1362
1363   gst_object_ref (bus);
1364   GST_UNLOCK (element);
1365
1366   result = gst_bus_post (bus, message);
1367   gst_object_unref (bus);
1368
1369   return result;
1370
1371 no_bus:
1372   {
1373     GST_DEBUG ("not posting message %p: no bus", message);
1374     GST_UNLOCK (element);
1375     gst_message_unref (message);
1376     return FALSE;
1377   }
1378 }
1379
1380 /**
1381  * _gst_element_error_printf:
1382  * @format: the printf-like format to use, or NULL
1383  *
1384  * This function is only used internally by the #gst_element_error macro.
1385  *
1386  * Returns: a newly allocated string, or NULL if the format was NULL or ""
1387  *
1388  * MT safe.
1389  */
1390 gchar *
1391 _gst_element_error_printf (const gchar * format, ...)
1392 {
1393   va_list args;
1394   gchar *buffer;
1395
1396   if (format == NULL)
1397     return NULL;
1398   if (format[0] == 0)
1399     return NULL;
1400
1401   va_start (args, format);
1402   buffer = g_strdup_vprintf (format, args);
1403   va_end (args);
1404   return buffer;
1405 }
1406
1407 /**
1408  * gst_element_message_full:
1409  * @element:  a #GstElement to send message from
1410  * @type:     the #GstMessageType
1411  * @domain:   the GStreamer GError domain this message belongs to
1412  * @code:     the GError code belonging to the domain
1413  * @text:     an allocated text string to be used as a replacement for the
1414  *            default message connected to code, or NULL
1415  * @debug:    an allocated debug message to be used as a replacement for the
1416  *            default debugging information, or NULL
1417  * @file:     the source code file where the error was generated
1418  * @function: the source code function where the error was generated
1419  * @line:     the source code line where the error was generated
1420  *
1421  * Post an error or warning message on the bus from inside an element.
1422  *
1423  * MT safe.
1424  */
1425 void gst_element_message_full
1426     (GstElement * element, GstMessageType type,
1427     GQuark domain, gint code, gchar * text,
1428     gchar * debug, const gchar * file, const gchar * function, gint line)
1429 {
1430   GError *gerror = NULL;
1431   gchar *name;
1432   gchar *sent_text;
1433   gchar *sent_debug;
1434   GstMessage *message = NULL;
1435
1436   /* checks */
1437   GST_DEBUG ("start");
1438   g_return_if_fail (GST_IS_ELEMENT (element));
1439   g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
1440       (type == GST_MESSAGE_WARNING));
1441
1442   /* check if we send the given text or the default error text */
1443   if ((text == NULL) || (text[0] == 0)) {
1444     /* text could have come from g_strdup_printf (""); */
1445     g_free (text);
1446     sent_text = gst_error_get_message (domain, code);
1447   } else
1448     sent_text = text;
1449
1450   /* construct a sent_debug with extra information from source */
1451   if ((debug == NULL) || (debug[0] == 0)) {
1452     /* debug could have come from g_strdup_printf (""); */
1453     sent_debug = NULL;
1454   } else {
1455     name = gst_object_get_path_string (GST_OBJECT (element));
1456     sent_debug = g_strdup_printf ("%s(%d): %s: %s:\n%s",
1457         file, line, function, name, debug ? debug : "");
1458     g_free (name);
1459   }
1460   g_free (debug);
1461
1462   /* create gerror and post message */
1463   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
1464       sent_text);
1465   gerror = g_error_new_literal (domain, code, sent_text);
1466
1467   if (type == GST_MESSAGE_ERROR) {
1468     message = gst_message_new_error (GST_OBJECT (element), gerror, sent_debug);
1469   } else if (type == GST_MESSAGE_WARNING) {
1470     message = gst_message_new_warning (GST_OBJECT (element), gerror,
1471         sent_debug);
1472   } else {
1473     g_assert_not_reached ();
1474   }
1475   gst_element_post_message (element, message);
1476
1477   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted message: %s",
1478       sent_text);
1479
1480   /* cleanup */
1481   g_error_free (gerror);
1482   g_free (sent_debug);
1483   g_free (sent_text);
1484 }
1485
1486 /**
1487  * gst_element_is_locked_state:
1488  * @element: a #GstElement.
1489  *
1490  * Checks if the state of an element is locked.
1491  * If the state of an element is locked, state changes of the parent don't
1492  * affect the element.
1493  * This way you can leave currently unused elements inside bins. Just lock their
1494  * state before changing the state from #GST_STATE_NULL.
1495  *
1496  * Returns: TRUE, if the element's state is locked.
1497  *
1498  * MT safe.
1499  */
1500 gboolean
1501 gst_element_is_locked_state (GstElement * element)
1502 {
1503   gboolean result;
1504
1505   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1506
1507   GST_LOCK (element);
1508   result = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1509   GST_UNLOCK (element);
1510
1511   return result;
1512 }
1513
1514 /**
1515  * gst_element_set_locked_state:
1516  * @element: a #GstElement
1517  * @locked_state: TRUE to lock the element's state
1518  *
1519  * Locks the state of an element, so state changes of the parent don't affect
1520  * this element anymore.
1521  *
1522  * Returns: TRUE if the state was changed, FALSE if bad params were given or
1523  * the element was already in the correct state.
1524  *
1525  * MT safe.
1526  */
1527 gboolean
1528 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
1529 {
1530   gboolean old;
1531
1532   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1533
1534   GST_LOCK (element);
1535   old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1536
1537   if (G_UNLIKELY (old == locked_state))
1538     goto was_ok;
1539
1540   if (locked_state) {
1541     GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
1542         GST_ELEMENT_NAME (element));
1543     GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
1544   } else {
1545     GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
1546         GST_ELEMENT_NAME (element));
1547     GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
1548   }
1549   GST_UNLOCK (element);
1550
1551   return TRUE;
1552
1553 was_ok:
1554   GST_UNLOCK (element);
1555
1556   return FALSE;
1557 }
1558
1559 /**
1560  * gst_element_sync_state_with_parent:
1561  * @element: a #GstElement.
1562  *
1563  * Tries to change the state of the element to the same as its parent.
1564  * If this function returns FALSE, the state of element is undefined.
1565  *
1566  * Returns: TRUE, if the element's state could be synced to the parent's state.
1567  *
1568  * MT safe.
1569  */
1570 gboolean
1571 gst_element_sync_state_with_parent (GstElement * element)
1572 {
1573   GstElement *parent;
1574
1575   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1576
1577   if ((parent = GST_ELEMENT_CAST (gst_element_get_parent (element)))) {
1578     GstState parent_current, parent_pending;
1579     GstStateChangeReturn ret;
1580
1581     GST_STATE_LOCK (parent);
1582     parent_current = GST_STATE (parent);
1583     parent_pending = GST_STATE_PENDING (parent);
1584     GST_STATE_UNLOCK (parent);
1585
1586     GST_CAT_DEBUG (GST_CAT_STATES,
1587         "syncing state of element %s (%s) to %s (%s, %s)",
1588         GST_ELEMENT_NAME (element),
1589         gst_element_state_get_name (GST_STATE (element)),
1590         GST_ELEMENT_NAME (parent), gst_element_state_get_name (parent_current),
1591         gst_element_state_get_name (parent_pending));
1592
1593     ret = gst_element_set_state (element, parent_current);
1594     if (ret == GST_STATE_CHANGE_FAILURE)
1595       goto failed;
1596
1597     gst_object_unref (parent);
1598
1599     return TRUE;
1600   }
1601   return FALSE;
1602
1603   /* ERROR */
1604 failed:
1605   {
1606     return FALSE;
1607   }
1608 }
1609
1610 /* MT safe */
1611 static GstStateChangeReturn
1612 gst_element_get_state_func (GstElement * element,
1613     GstState * state, GstState * pending, GTimeVal * timeout)
1614 {
1615   GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
1616   GstState old_pending;
1617
1618   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "getting state");
1619
1620   GST_STATE_LOCK (element);
1621   /* we got an error, report immediatly */
1622   if (GST_STATE_NO_PREROLL (element)) {
1623     ret = GST_STATE_CHANGE_NO_PREROLL;
1624     goto done;
1625   }
1626
1627   /* we got an error, report immediatly */
1628   if (GST_STATE_ERROR (element)) {
1629     ret = GST_STATE_CHANGE_FAILURE;
1630     goto done;
1631   }
1632
1633   old_pending = GST_STATE_PENDING (element);
1634   if (old_pending != GST_STATE_VOID_PENDING) {
1635     GTimeVal *timeval, abstimeout;
1636
1637     if (timeout) {
1638       glong add = timeout->tv_sec * G_USEC_PER_SEC + timeout->tv_usec;
1639
1640       /* make timeout absolute */
1641       g_get_current_time (&abstimeout);
1642       g_time_val_add (&abstimeout, add);
1643       timeval = &abstimeout;
1644     } else {
1645       timeval = NULL;
1646     }
1647     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "wait for pending");
1648     /* we have a pending state change, wait for it to complete */
1649     if (!GST_STATE_TIMED_WAIT (element, timeval)) {
1650       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timeout");
1651       /* timeout triggered */
1652       ret = GST_STATE_CHANGE_ASYNC;
1653     } else {
1654       /* could be success or failure */
1655       if (old_pending == GST_STATE (element)) {
1656         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "got success");
1657         ret = GST_STATE_CHANGE_SUCCESS;
1658       } else {
1659         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "got failure");
1660         ret = GST_STATE_CHANGE_FAILURE;
1661       }
1662     }
1663   }
1664   /* if nothing is pending anymore we can return SUCCESS */
1665   if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
1666     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
1667     ret = GST_STATE_CHANGE_SUCCESS;
1668   }
1669
1670 done:
1671   if (state)
1672     *state = GST_STATE (element);
1673   if (pending)
1674     *pending = GST_STATE_PENDING (element);
1675
1676   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1677       "state current: %s, pending: %s, error: %d, no_preroll: %d, result: %d",
1678       gst_element_state_get_name (GST_STATE (element)),
1679       gst_element_state_get_name (GST_STATE_PENDING (element)),
1680       GST_STATE_ERROR (element), GST_STATE_NO_PREROLL (element), ret);
1681
1682   GST_STATE_UNLOCK (element);
1683
1684   return ret;
1685 }
1686
1687 /**
1688  * gst_element_get_state:
1689  * @element: a #GstElement to get the state of.
1690  * @state: a pointer to #GstState to hold the state. Can be NULL.
1691  * @pending: a pointer to #GstState to hold the pending state.
1692  *           Can be NULL.
1693  * @timeout: a #GTimeVal to specify the timeout for an async
1694  *           state change or NULL for infinite timeout.
1695  *
1696  * Gets the state of the element. 
1697  *
1698  * For elements that performed an ASYNC state change, as reported by 
1699  * #gst_element_set_state(), this function will block up to the 
1700  * specified timeout value for the state change to complete. 
1701  * If the element completes the state change or goes into
1702  * an error, this function returns immediatly with a return value of
1703  * GST_STATE_CHANGE_SUCCESS or GST_STATE_CHANGE_FAILURE respectively. 
1704  *
1705  * Returns: GST_STATE_CHANGE_SUCCESS if the element has no more pending state and
1706  *          the last state change succeeded, GST_STATE_CHANGE_ASYNC
1707  *          if the element is still performing a state change or 
1708  *          GST_STATE_CHANGE_FAILURE if the last state change failed.
1709  *
1710  * MT safe.
1711  */
1712 GstStateChangeReturn
1713 gst_element_get_state (GstElement * element,
1714     GstState * state, GstState * pending, GTimeVal * timeout)
1715 {
1716   GstElementClass *oclass;
1717   GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
1718
1719   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
1720
1721   oclass = GST_ELEMENT_GET_CLASS (element);
1722
1723   if (oclass->get_state)
1724     result = (oclass->get_state) (element, state, pending, timeout);
1725
1726   return result;
1727 }
1728
1729 /**
1730  * gst_element_abort_state:
1731  * @element: a #GstElement to abort the state of.
1732  *
1733  * Abort the state change of the element. This function is used
1734  * by elements that do asynchronous state changes and find out
1735  * something is wrong.
1736  *
1737  * This function should be called with the STATE_LOCK held.
1738  *
1739  * MT safe.
1740  */
1741 void
1742 gst_element_abort_state (GstElement * element)
1743 {
1744   GstState pending;
1745
1746   g_return_if_fail (GST_IS_ELEMENT (element));
1747
1748   pending = GST_STATE_PENDING (element);
1749
1750   if (pending != GST_STATE_VOID_PENDING && !GST_STATE_ERROR (element)) {
1751 #ifndef GST_DISABLE_GST_DEBUG
1752     GstState old_state = GST_STATE (element);
1753 #endif
1754
1755     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1756         "aborting state from %s to %s", gst_element_state_get_name (old_state),
1757         gst_element_state_get_name (pending));
1758
1759     /* flag error */
1760     GST_STATE_ERROR (element) = TRUE;
1761
1762     GST_STATE_BROADCAST (element);
1763   }
1764 }
1765
1766 /**
1767  * gst_element_commit_state:
1768  * @element: a #GstElement to commit the state of.
1769  *
1770  * Commit the state change of the element. This function is used
1771  * by elements that do asynchronous state changes.
1772  *
1773  * This function can only be called with the STATE_LOCK held.
1774  *
1775  * MT safe.
1776  */
1777 void
1778 gst_element_commit_state (GstElement * element)
1779 {
1780   GstState pending;
1781
1782   g_return_if_fail (GST_IS_ELEMENT (element));
1783
1784   pending = GST_STATE_PENDING (element);
1785
1786   if (pending != GST_STATE_VOID_PENDING) {
1787     GstState old_state = GST_STATE (element);
1788     GstMessage *message;
1789
1790     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1791         "committing state from %s to %s",
1792         gst_element_state_get_name (old_state),
1793         gst_element_state_get_name (pending));
1794
1795     GST_STATE (element) = pending;
1796     GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
1797     GST_STATE_ERROR (element) = FALSE;
1798
1799     message = gst_message_new_state_changed (GST_OBJECT (element),
1800         old_state, pending, pending);
1801     gst_element_post_message (element, message);
1802     GST_STATE_BROADCAST (element);
1803   }
1804 }
1805
1806 /**
1807  * gst_element_lost_state:
1808  * @element: a #GstElement the state is lost of
1809  *
1810  * Brings the element to the lost state. The current state of the
1811  * element is copied to the pending state so that any call to
1812  * #gst_element_get_state() will return ASYNC.
1813  *
1814  * This is mostly used for elements that lost their preroll buffer
1815  * in the PAUSED state after a flush, they become PAUSED again
1816  * if a new preroll buffer is queued.
1817  * This function can only be called when the element is currently
1818  * not in error or an async state change.
1819  *
1820  * This function can only be called with the STATE_LOCK held.
1821  *
1822  * MT safe.
1823  */
1824 void
1825 gst_element_lost_state (GstElement * element)
1826 {
1827   g_return_if_fail (GST_IS_ELEMENT (element));
1828
1829   if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING &&
1830       !GST_STATE_ERROR (element)) {
1831     GstState current_state;
1832     GstMessage *message;
1833
1834     current_state = GST_STATE (element);
1835
1836     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1837         "lost state of %s", gst_element_state_get_name (current_state));
1838
1839     GST_STATE_PENDING (element) = current_state;
1840     GST_STATE_ERROR (element) = FALSE;
1841
1842     message = gst_message_new_state_changed (GST_OBJECT (element),
1843         current_state, current_state, current_state);
1844     gst_element_post_message (element, message);
1845   }
1846 }
1847
1848 /**
1849  * gst_element_set_state:
1850  * @element: a #GstElement to change state of.
1851  * @state: the element's new #GstState.
1852  *
1853  * Sets the state of the element. This function will try to set the
1854  * requested state by going through all the intermediary states and calling
1855  * the class's state change function for each.
1856  *
1857  * Returns: Result of the state change using #GstStateChangeReturn.
1858  *
1859  * MT safe.
1860  */
1861 GstStateChangeReturn
1862 gst_element_set_state (GstElement * element, GstState state)
1863 {
1864   GstState current, old_pending;
1865   GstStateChangeReturn ret;
1866   GstStateChange transition;
1867   GTimeVal tv;
1868
1869   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
1870
1871   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "set_state to %s",
1872       gst_element_state_get_name (state));
1873
1874   /* get current element state,  need to call the method so that
1875    * we call the virtual method and subclasses can implement their
1876    * own algorithms */
1877   GST_TIME_TO_TIMEVAL (0, tv);
1878   ret = gst_element_get_state (element, &current, &old_pending, &tv);
1879
1880   GST_STATE_LOCK (element);
1881
1882   /* this is the (new) state we should go to */
1883   GST_STATE_FINAL (element) = state;
1884   if (ret == GST_STATE_CHANGE_ASYNC) {
1885     /* force next state keeping ASYNC, this is atomic as we hold
1886      * the STATE_LOCK */
1887     gst_element_commit_state (element);
1888     gst_element_lost_state (element);
1889     if (state == GST_STATE_PENDING (element))
1890       goto was_busy;
1891   }
1892
1893   /* fixme, not right */
1894   transition = GST_STATE_CHANGE (element);
1895
1896   ret = gst_element_change_state (element, transition);
1897
1898   GST_STATE_UNLOCK (element);
1899
1900   GST_DEBUG_OBJECT (element, "returned %d", ret);
1901
1902   return ret;
1903
1904 was_busy:
1905   {
1906     GST_STATE_UNLOCK (element);
1907
1908     GST_DEBUG_OBJECT (element, "element was busy with async state change");
1909
1910     return GST_STATE_CHANGE_ASYNC;
1911   }
1912 }
1913
1914 /* with STATE_LOCK */
1915 static GstStateChangeReturn
1916 gst_element_change_state (GstElement * element, GstStateChange transition)
1917 {
1918   GstElementClass *oclass;
1919   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
1920   GstState current, next, final;
1921
1922   oclass = GST_ELEMENT_GET_CLASS (element);
1923
1924   /* start with the current state. */
1925   current = GST_STATE (element);
1926   next = GST_STATE_PENDING (element);
1927   final = GST_STATE_FINAL (element);
1928
1929   /* We always perform at least one state change, even if the
1930    * current state is equal to the required state. This is needed
1931    * for bins that sync their children. */
1932   do {
1933     GstState pending;
1934
1935     /* calculate the pending state */
1936     if (current < final)
1937       pending = current + 1;
1938     else if (current > final)
1939       pending = current - 1;
1940     else
1941       pending = current;
1942
1943     /* set the pending state variable */
1944     GST_STATE_PENDING (element) = pending;
1945
1946     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1947         "%s: setting state from %s to %s",
1948         (pending != final ? "intermediate" : "final"),
1949         gst_element_state_get_name (current),
1950         gst_element_state_get_name (pending));
1951
1952     /* call the state change function so it can set the state */
1953     if (oclass->change_state)
1954       ret = (oclass->change_state) (element, GST_STATE_CHANGE (element));
1955     else
1956       ret = GST_STATE_CHANGE_FAILURE;
1957
1958     /* clear the error and preroll flag, we need to do that after
1959      * calling the virtual change_state function so that it can use the
1960      * old previous value. */
1961     GST_STATE_ERROR (element) = FALSE;
1962     GST_STATE_NO_PREROLL (element) = FALSE;
1963
1964     switch (ret) {
1965       case GST_STATE_CHANGE_FAILURE:
1966         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1967             "have failed change_state return");
1968         /* state change failure exits the loop */
1969         gst_element_abort_state (element);
1970         goto exit;
1971       case GST_STATE_CHANGE_ASYNC:
1972         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1973             "element will change state async");
1974         /* an async state change exits the loop, we can only
1975          * go to the next state change when this one completes. */
1976         goto exit;
1977       case GST_STATE_CHANGE_SUCCESS:
1978         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1979             "element changed state successfully");
1980         /* we can commit the state now and proceed to the next state */
1981         gst_element_commit_state (element);
1982         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "committed state");
1983         break;
1984       case GST_STATE_CHANGE_NO_PREROLL:
1985         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1986             "element changed state successfully and can't preroll");
1987         /* we can commit the state now and proceed to the next state */
1988         gst_element_commit_state (element);
1989         GST_STATE_NO_PREROLL (element) = TRUE;
1990         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "committed state");
1991         break;
1992       default:
1993         ret = GST_STATE_CHANGE_FAILURE;
1994         goto invalid_return;
1995     }
1996     /* get the current state of the element and see if we need to do more
1997      * state changes */
1998     current = GST_STATE (element);
1999   }
2000   while (current != final);
2001
2002 exit:
2003   GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
2004
2005   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "exit state change %d", ret);
2006
2007   return ret;
2008
2009   /* ERROR */
2010 invalid_return:
2011   {
2012     GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
2013     /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2014     g_critical ("unknown return value %d from a state change function", ret);
2015     return ret;
2016   }
2017 }
2018
2019 /* gst_iterator_fold functions for pads_activate */
2020
2021 static gboolean
2022 activate_pads (GstPad * pad, GValue * ret, gboolean * active)
2023 {
2024   if (!gst_pad_set_active (pad, *active))
2025     g_value_set_boolean (ret, FALSE);
2026   else if (!*active)
2027     gst_pad_set_caps (pad, NULL);
2028
2029   gst_object_unref (pad);
2030   return TRUE;
2031 }
2032
2033 /* returns false on error or early cutout of the fold, true otherwise */
2034 static gboolean
2035 iterator_fold_with_resync (GstIterator * iter, GstIteratorFoldFunction func,
2036     GValue * ret, gpointer user_data)
2037 {
2038   GstIteratorResult ires;
2039   gboolean res = TRUE;
2040
2041   while (1) {
2042     ires = gst_iterator_fold (iter, func, ret, user_data);
2043
2044     switch (ires) {
2045       case GST_ITERATOR_RESYNC:
2046         gst_iterator_resync (iter);
2047         break;
2048       case GST_ITERATOR_DONE:
2049         res = TRUE;
2050         goto done;
2051       default:
2052         res = FALSE;
2053         goto done;
2054     }
2055   }
2056
2057 done:
2058   return res;
2059 }
2060
2061 /* is called with STATE_LOCK
2062  */
2063 static gboolean
2064 gst_element_pads_activate (GstElement * element, gboolean active)
2065 {
2066   GValue ret = { 0, };
2067   GstIterator *iter;
2068   gboolean fold_ok;
2069
2070   /* no need to unset this later, it's just a boolean */
2071   g_value_init (&ret, G_TYPE_BOOLEAN);
2072   g_value_set_boolean (&ret, TRUE);
2073
2074   iter = gst_element_iterate_src_pads (element);
2075   fold_ok = iterator_fold_with_resync
2076       (iter, (GstIteratorFoldFunction) activate_pads, &ret, &active);
2077   gst_iterator_free (iter);
2078   if (!fold_ok || !g_value_get_boolean (&ret))
2079     return FALSE;
2080
2081   iter = gst_element_iterate_sink_pads (element);
2082   fold_ok = iterator_fold_with_resync
2083       (iter, (GstIteratorFoldFunction) activate_pads, &ret, &active);
2084   gst_iterator_free (iter);
2085   if (!fold_ok || !g_value_get_boolean (&ret))
2086     return FALSE;
2087
2088   return TRUE;
2089 }
2090
2091 /* is called with STATE_LOCK */
2092 static GstStateChangeReturn
2093 gst_element_change_state_func (GstElement * element, GstStateChange transition)
2094 {
2095   GstState state, next;
2096   GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
2097
2098   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2099
2100   state = GST_STATE (element);
2101   next = GST_STATE_PENDING (element);
2102
2103   /* if the element already is in the given state, we just return success */
2104   if (next == GST_STATE_VOID_PENDING || state == next)
2105     goto was_ok;
2106
2107   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2108       "default handler tries setting state from %s to %s (%04x)",
2109       gst_element_state_get_name (state),
2110       gst_element_state_get_name (next), transition);
2111
2112   switch (transition) {
2113     case GST_STATE_CHANGE_NULL_TO_READY:
2114       break;
2115     case GST_STATE_CHANGE_READY_TO_PAUSED:
2116       if (!gst_element_pads_activate (element, TRUE)) {
2117         result = GST_STATE_CHANGE_FAILURE;
2118       }
2119       break;
2120     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2121       break;
2122     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2123       break;
2124     case GST_STATE_CHANGE_PAUSED_TO_READY:
2125     case GST_STATE_CHANGE_READY_TO_NULL:
2126       /* deactivate pads in both cases, since they are activated on
2127          ready->paused but the element might not have made it to paused */
2128       if (!gst_element_pads_activate (element, FALSE)) {
2129         result = GST_STATE_CHANGE_FAILURE;
2130       } else {
2131         gst_element_set_base_time (element, 0);
2132       }
2133       break;
2134     default:
2135       /* this will catch real but unhandled state changes;
2136        * can only be caused by:
2137        * - a new state was added
2138        * - somehow the element was asked to jump across an intermediate state
2139        */
2140       g_warning ("Unhandled state change from %s to %s",
2141           gst_element_state_get_name (state),
2142           gst_element_state_get_name (next));
2143       break;
2144   }
2145   return result;
2146
2147 was_ok:
2148   {
2149     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2150         "element is already in the %s state",
2151         gst_element_state_get_name (state));
2152     if (GST_STATE_NO_PREROLL (element))
2153       return GST_STATE_CHANGE_NO_PREROLL;
2154     else
2155       return GST_STATE_CHANGE_SUCCESS;
2156   }
2157 }
2158
2159 /**
2160  * gst_element_get_factory:
2161  * @element: a #GstElement to request the element factory of.
2162  *
2163  * Retrieves the factory that was used to create this element.
2164  *
2165  * Returns: the #GstElementFactory used for creating this element. 
2166  * no refcounting is needed.
2167  */
2168 GstElementFactory *
2169 gst_element_get_factory (GstElement * element)
2170 {
2171   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2172
2173   return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2174 }
2175
2176 static void
2177 gst_element_dispose (GObject * object)
2178 {
2179   GstElement *element = GST_ELEMENT (object);
2180
2181   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
2182
2183   g_return_if_fail (GST_STATE (element) == GST_STATE_NULL);
2184   g_return_if_fail (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING);
2185
2186   /* first we break all our links with the outside */
2187   while (element->pads) {
2188     gst_element_remove_pad (element, GST_PAD_CAST (element->pads->data));
2189   }
2190   if (G_UNLIKELY (element->pads != 0)) {
2191     g_critical ("could not remove pads from element %s",
2192         GST_STR_NULL (GST_OBJECT_NAME (object)));
2193   }
2194
2195   GST_LOCK (element);
2196   gst_object_replace ((GstObject **) & element->clock, NULL);
2197   gst_object_replace ((GstObject **) & element->bus, NULL);
2198   GST_UNLOCK (element);
2199
2200   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "parent class dispose");
2201
2202   G_OBJECT_CLASS (parent_class)->dispose (object);
2203 }
2204
2205 static void
2206 gst_element_finalize (GObject * object)
2207 {
2208   GstElement *element = GST_ELEMENT (object);
2209
2210   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize");
2211
2212   GST_STATE_LOCK (element);
2213   if (element->state_cond)
2214     g_cond_free (element->state_cond);
2215   element->state_cond = NULL;
2216   GST_STATE_UNLOCK (element);
2217   g_static_rec_mutex_free (element->state_lock);
2218   g_free (element->state_lock);
2219   element->state_lock = NULL;
2220
2221   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize parent");
2222
2223   G_OBJECT_CLASS (parent_class)->finalize (object);
2224 }
2225
2226 #ifndef GST_DISABLE_LOADSAVE
2227 /**
2228  * gst_element_save_thyself:
2229  * @element: a #GstElement to save.
2230  * @parent: the xml parent node.
2231  *
2232  * Saves the element as part of the given XML structure.
2233  *
2234  * Returns: the new #xmlNodePtr.
2235  */
2236 static xmlNodePtr
2237 gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
2238 {
2239   GList *pads;
2240   GstElementClass *oclass;
2241   GParamSpec **specs, *spec;
2242   guint nspecs;
2243   gint i;
2244   GValue value = { 0, };
2245   GstElement *element;
2246
2247   g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2248
2249   element = GST_ELEMENT (object);
2250
2251   oclass = GST_ELEMENT_GET_CLASS (element);
2252
2253   xmlNewChild (parent, NULL, (xmlChar *) "name",
2254       (xmlChar *) GST_ELEMENT_NAME (element));
2255
2256   if (oclass->elementfactory != NULL) {
2257     GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
2258
2259     xmlNewChild (parent, NULL, (xmlChar *) "type",
2260         (xmlChar *) GST_PLUGIN_FEATURE (factory)->name);
2261   }
2262
2263   /* params */
2264   specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2265
2266   for (i = 0; i < nspecs; i++) {
2267     spec = specs[i];
2268     if (spec->flags & G_PARAM_READABLE) {
2269       xmlNodePtr param;
2270       char *contents;
2271
2272       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
2273
2274       g_object_get_property (G_OBJECT (element), spec->name, &value);
2275       param = xmlNewChild (parent, NULL, (xmlChar *) "param", NULL);
2276       xmlNewChild (param, NULL, (xmlChar *) "name", (xmlChar *) spec->name);
2277
2278       if (G_IS_PARAM_SPEC_STRING (spec))
2279         contents = g_value_dup_string (&value);
2280       else if (G_IS_PARAM_SPEC_ENUM (spec))
2281         contents = g_strdup_printf ("%d", g_value_get_enum (&value));
2282       else if (G_IS_PARAM_SPEC_INT64 (spec))
2283         contents = g_strdup_printf ("%" G_GINT64_FORMAT,
2284             g_value_get_int64 (&value));
2285       else
2286         contents = g_strdup_value_contents (&value);
2287
2288       xmlNewChild (param, NULL, (xmlChar *) "value", (xmlChar *) contents);
2289       g_free (contents);
2290
2291       g_value_unset (&value);
2292     }
2293   }
2294
2295   g_free (specs);
2296
2297   pads = GST_ELEMENT_PADS (element);
2298
2299   while (pads) {
2300     GstPad *pad = GST_PAD (pads->data);
2301
2302     /* figure out if it's a direct pad or a ghostpad */
2303     if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
2304       xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL);
2305
2306       gst_object_save_thyself (GST_OBJECT (pad), padtag);
2307     }
2308     pads = g_list_next (pads);
2309   }
2310
2311   return parent;
2312 }
2313
2314 static void
2315 gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
2316 {
2317   xmlNodePtr children;
2318   GstElement *element;
2319   gchar *name = NULL;
2320   gchar *value = NULL;
2321
2322   element = GST_ELEMENT (object);
2323   g_return_if_fail (element != NULL);
2324
2325   /* parameters */
2326   children = self->xmlChildrenNode;
2327   while (children) {
2328     if (!strcmp ((char *) children->name, "param")) {
2329       xmlNodePtr child = children->xmlChildrenNode;
2330
2331       while (child) {
2332         if (!strcmp ((char *) child->name, "name")) {
2333           name = (gchar *) xmlNodeGetContent (child);
2334         } else if (!strcmp ((char *) child->name, "value")) {
2335           value = (gchar *) xmlNodeGetContent (child);
2336         }
2337         child = child->next;
2338       }
2339       /* FIXME: can this just be g_object_set ? */
2340       gst_util_set_object_arg (G_OBJECT (element), name, value);
2341       /* g_object_set (G_OBJECT (element), name, value, NULL); */
2342       g_free (name);
2343       g_free (value);
2344     }
2345     children = children->next;
2346   }
2347
2348   /* pads */
2349   children = self->xmlChildrenNode;
2350   while (children) {
2351     if (!strcmp ((char *) children->name, "pad")) {
2352       gst_pad_load_and_link (children, GST_OBJECT (element));
2353     }
2354     children = children->next;
2355   }
2356
2357   if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
2358     (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
2359 }
2360 #endif /* GST_DISABLE_LOADSAVE */
2361
2362 static void
2363 gst_element_set_bus_func (GstElement * element, GstBus * bus)
2364 {
2365   g_return_if_fail (GST_IS_ELEMENT (element));
2366
2367   GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
2368
2369   GST_LOCK (element);
2370   gst_object_replace ((GstObject **) & GST_ELEMENT_BUS (element),
2371       GST_OBJECT_CAST (bus));
2372   GST_UNLOCK (element);
2373 }
2374
2375 /**
2376  * gst_element_set_bus:
2377  * @element: a #GstElement to set the bus of.
2378  * @bus: the #GstBus to set.
2379  *
2380  * Sets the bus of the element.  For internal use only, unless you're
2381  * testing elements.
2382  *
2383  * MT safe.
2384  */
2385 void
2386 gst_element_set_bus (GstElement * element, GstBus * bus)
2387 {
2388   GstElementClass *oclass;
2389
2390   g_return_if_fail (GST_IS_ELEMENT (element));
2391
2392   oclass = GST_ELEMENT_GET_CLASS (element);
2393
2394   if (oclass->set_bus)
2395     oclass->set_bus (element, bus);
2396 }
2397
2398 /**
2399  * gst_element_get_bus:
2400  * @element: a #GstElement to get the bus of.
2401  *
2402  * Returns the bus of the element.
2403  *
2404  * Returns: the element's #GstBus. unref after usage.
2405  *
2406  * MT safe.
2407  */
2408 GstBus *
2409 gst_element_get_bus (GstElement * element)
2410 {
2411   GstBus *result = NULL;
2412
2413   g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2414
2415   GST_LOCK (element);
2416   result = GST_ELEMENT_BUS (element);
2417   gst_object_ref (result);
2418   GST_UNLOCK (element);
2419
2420   GST_DEBUG_OBJECT (element, "got bus %" GST_PTR_FORMAT, result);
2421
2422   return result;
2423 }