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