6a368ddfb6d3e3c4c657e640a0308ff73f7216c2
[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_GET_LOCK (element),
945       &element->pads_cookie,
946       &element->pads,
947       element,
948       (GstIteratorItemFunction) iterate_pad,
949       (GstIteratorDisposeFunction) gst_object_unref);
950   GST_UNLOCK (element);
951
952   return result;
953 }
954
955 static gint
956 direction_filter (gconstpointer pad, gconstpointer direction)
957 {
958   if (GST_PAD_DIRECTION (pad) == GPOINTER_TO_INT (direction)) {
959     /* pass the ref through */
960     return 0;
961   } else {
962     /* unref */
963     /* FIXME: this is very stupid */
964     gst_object_unref (GST_OBJECT_CAST (pad));
965     return 1;
966   }
967 }
968
969 /**
970  * gst_element_iterate_src_pads:
971  * @element: a #GstElement.
972  *
973  * Retrieves an iterator of @element's source pads. 
974  *
975  * Returns: the #GstIterator of #GstPad. Unref each pad after use.
976  *
977  * MT safe.
978  */
979 GstIterator *
980 gst_element_iterate_src_pads (GstElement * element)
981 {
982   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
983
984   return gst_iterator_filter (gst_element_iterate_pads (element),
985       direction_filter, GINT_TO_POINTER (GST_PAD_SRC));
986 }
987
988 /**
989  * gst_element_iterate_sink_pads:
990  * @element: a #GstElement.
991  *
992  * Retrieves an iterator of @element's sink pads. 
993  *
994  * Returns: the #GstIterator of #GstPad. Unref each pad after use.
995  *
996  * MT safe.
997  */
998 GstIterator *
999 gst_element_iterate_sink_pads (GstElement * element)
1000 {
1001   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1002
1003   return gst_iterator_filter (gst_element_iterate_pads (element),
1004       direction_filter, GINT_TO_POINTER (GST_PAD_SINK));
1005 }
1006
1007 /**
1008  * gst_element_class_add_pad_template:
1009  * @klass: the #GstElementClass to add the pad template to.
1010  * @templ: a #GstPadTemplate to add to the element class.
1011  *
1012  * Adds a padtemplate to an element class. This is mainly used in the _base_init
1013  * functions of classes.
1014  */
1015 void
1016 gst_element_class_add_pad_template (GstElementClass * klass,
1017     GstPadTemplate * templ)
1018 {
1019   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1020   g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1021
1022   /* avoid registering pad templates with the same name */
1023   g_return_if_fail (gst_element_class_get_pad_template (klass,
1024           templ->name_template) == NULL);
1025
1026   klass->padtemplates = g_list_append (klass->padtemplates,
1027       gst_object_ref (templ));
1028   klass->numpadtemplates++;
1029 }
1030
1031 /**
1032  * gst_element_class_set_details:
1033  * @klass: class to set details for
1034  * @details: details to set
1035  *
1036  * Sets the detailed information for a #GstElementClass.
1037  * <note>This function is for use in _base_init functions only.</note>
1038  */
1039 void
1040 gst_element_class_set_details (GstElementClass * klass,
1041     const GstElementDetails * details)
1042 {
1043   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1044   g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
1045
1046   __gst_element_details_copy (&klass->details, details);
1047 }
1048
1049 /**
1050  * gst_element_class_get_pad_template_list:
1051  * @element_class: a #GstElementClass to get pad templates of.
1052  *
1053  * Retrieves a list of the pad templates associated with @element_class. The
1054  * list must not be modified by the calling code.
1055  * <note>If you use this function in the #GInstanceInitFunc of an object class
1056  * that has subclasses, make sure to pass the g_class parameter of the
1057  * #GInstanceInitFunc here.</note>
1058  *
1059  * Returns: the #GList of padtemplates.
1060  */
1061 GList *
1062 gst_element_class_get_pad_template_list (GstElementClass * element_class)
1063 {
1064   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1065
1066   return element_class->padtemplates;
1067 }
1068
1069 /**
1070  * gst_element_class_get_pad_template:
1071  * @element_class: a #GstElementClass to get the pad template of.
1072  * @name: the name of the #GstPadTemplate to get.
1073  *
1074  * Retrieves a padtemplate from @element_class with the given name.
1075  * <note>If you use this function in the #GInstanceInitFunc of an object class
1076  * that has subclasses, make sure to pass the g_class parameter of the
1077  * #GInstanceInitFunc here.</note>
1078  *
1079  * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1080  * No unreferencing is necessary.
1081  */
1082 GstPadTemplate *
1083 gst_element_class_get_pad_template (GstElementClass * element_class,
1084     const gchar * name)
1085 {
1086   GList *padlist;
1087
1088   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1089   g_return_val_if_fail (name != NULL, NULL);
1090
1091   padlist = gst_element_class_get_pad_template_list (element_class);
1092
1093   while (padlist) {
1094     GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1095
1096     if (strcmp (padtempl->name_template, name) == 0)
1097       return padtempl;
1098
1099     padlist = g_list_next (padlist);
1100   }
1101
1102   return NULL;
1103 }
1104
1105 static GstPad *
1106 gst_element_get_random_pad (GstElement * element, GstPadDirection dir)
1107 {
1108   GstPad *result = NULL;
1109   GList *pads;
1110
1111   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
1112
1113   switch (dir) {
1114     case GST_PAD_SRC:
1115       GST_LOCK (element);
1116       pads = element->srcpads;
1117       break;
1118     case GST_PAD_SINK:
1119       GST_LOCK (element);
1120       pads = element->sinkpads;
1121       break;
1122     default:
1123       goto wrong_direction;
1124   }
1125   for (; pads; pads = g_list_next (pads)) {
1126     GstPad *pad = GST_PAD (pads->data);
1127
1128     GST_LOCK (pad);
1129     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
1130         GST_DEBUG_PAD_NAME (pad));
1131
1132     if (GST_PAD_IS_LINKED (pad)) {
1133       GST_UNLOCK (pad);
1134       result = pad;
1135       break;
1136     } else {
1137       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
1138           GST_DEBUG_PAD_NAME (pad));
1139     }
1140     GST_UNLOCK (pad);
1141   }
1142   if (result)
1143     gst_object_ref (result);
1144
1145   GST_UNLOCK (element);
1146
1147   return result;
1148
1149   /* ERROR handling */
1150 wrong_direction:
1151   {
1152     g_warning ("unknown pad direction %d", dir);
1153     return NULL;
1154   }
1155 }
1156
1157 /**
1158  * gst_element_send_event:
1159  * @element: a #GstElement to send the event to.
1160  * @event: the #GstEvent to send to the element.
1161  *
1162  * Sends an event to an element. If the element doesn't
1163  * implement an event handler, the event will be forwarded
1164  * to a random sink pad. This function takes owership of the
1165  * provided event so you should _ref it if you want to reuse
1166  * the event after this call.
1167  *
1168  * Returns: TRUE if the event was handled.
1169  *
1170  * MT safe.
1171  */
1172 gboolean
1173 gst_element_send_event (GstElement * element, GstEvent * event)
1174 {
1175   GstElementClass *oclass;
1176   gboolean result = FALSE;
1177
1178   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1179   g_return_val_if_fail (event != NULL, FALSE);
1180
1181   oclass = GST_ELEMENT_GET_CLASS (element);
1182
1183   if (oclass->send_event) {
1184     result = oclass->send_event (element, event);
1185   } else {
1186     GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1187
1188     if (pad) {
1189       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1190           "pushing event to random pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1191
1192       result = gst_pad_push_event (pad, event);
1193       gst_object_unref (pad);
1194     } else {
1195       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
1196           GST_ELEMENT_NAME (element));
1197     }
1198   }
1199   return result;
1200 }
1201
1202 /**
1203  * gst_element_seek:
1204  * @element: a #GstElement to send the event to.
1205  * @rate: The new playback rate
1206  * @format: The format of the seek values
1207  * @flags: The optional seek flags.
1208  * @cur_type: The type and flags for the new current position
1209  * @cur: The value of the new current position
1210  * @stop_type: The type and flags for the new stop position
1211  * @stop: The value of the new stop position
1212  *
1213  * Sends a seek event to an element.
1214  *
1215  * Returns: %TRUE if the event was handled.
1216  *
1217  * MT safe.
1218  */
1219 gboolean
1220 gst_element_seek (GstElement * element, gdouble rate, GstFormat format,
1221     GstSeekFlags flags, GstSeekType cur_type, gint64 cur,
1222     GstSeekType stop_type, gint64 stop)
1223 {
1224   GstEvent *event;
1225   gboolean result;
1226
1227   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1228
1229   event =
1230       gst_event_new_seek (rate, format, flags, cur_type, cur, stop_type, stop);
1231   result = gst_element_send_event (element, event);
1232
1233   return result;
1234 }
1235
1236 /**
1237  * gst_element_get_query_types:
1238  * @element: a #GstElement to query
1239  *
1240  * Get an array of query types from the element.
1241  * If the element doesn't implement a query types function,
1242  * the query will be forwarded to a random sink pad.
1243  *
1244  * Returns: An array of #GstQueryType elements that should not
1245  * be freed or modified.
1246  *
1247  * MT safe.
1248  */
1249 const GstQueryType *
1250 gst_element_get_query_types (GstElement * element)
1251 {
1252   GstElementClass *oclass;
1253   const GstQueryType *result = NULL;
1254
1255   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1256
1257   oclass = GST_ELEMENT_GET_CLASS (element);
1258
1259   if (oclass->get_query_types) {
1260     result = oclass->get_query_types (element);
1261   } else {
1262     GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1263
1264     if (pad) {
1265       GstPad *peer = gst_pad_get_peer (pad);
1266
1267       if (peer) {
1268         result = gst_pad_get_query_types (peer);
1269
1270         gst_object_unref (peer);
1271       }
1272       gst_object_unref (pad);
1273     }
1274   }
1275   return result;
1276 }
1277
1278 /**
1279  * gst_element_query:
1280  * @element: a #GstElement to perform the query on.
1281  * @query: the #GstQuery.
1282  *
1283  * Performs a query on the given element. If the format is set
1284  * to GST_FORMAT_DEFAULT and this function returns TRUE, the
1285  * format pointer will hold the default format.
1286  * For element that don't implement a query handler, this function
1287  * forwards the query to a random usable sinkpad of this element.
1288  *
1289  * Returns: TRUE if the query could be performed.
1290  *
1291  * MT safe.
1292  */
1293 gboolean
1294 gst_element_query (GstElement * element, GstQuery * query)
1295 {
1296   GstElementClass *oclass;
1297   gboolean result = FALSE;
1298
1299   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1300   g_return_val_if_fail (query != NULL, FALSE);
1301
1302   oclass = GST_ELEMENT_GET_CLASS (element);
1303
1304   if (oclass->query) {
1305     result = oclass->query (element, query);
1306   } else {
1307     GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
1308
1309     if (pad) {
1310       result = gst_pad_query (pad, query);
1311
1312       gst_object_unref (pad);
1313     } else {
1314       pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1315       if (pad) {
1316         GstPad *peer = gst_pad_get_peer (pad);
1317
1318         if (peer) {
1319           result = gst_pad_query (peer, query);
1320
1321           gst_object_unref (peer);
1322         }
1323         gst_object_unref (pad);
1324       }
1325     }
1326   }
1327   return result;
1328 }
1329
1330 /**
1331  * gst_element_post_message:
1332  * @element: a #GstElement posting the message
1333  * @message: a #GstMessage to post
1334  *
1335  * Post a message on the element's #GstBus.
1336  *
1337  * Returns: TRUE if the message was successfully posted.
1338  *
1339  * MT safe.
1340  */
1341 gboolean
1342 gst_element_post_message (GstElement * element, GstMessage * message)
1343 {
1344   GstBus *bus;
1345   gboolean result = FALSE;
1346
1347   GST_DEBUG ("posting message %p ...", message);
1348
1349   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1350   g_return_val_if_fail (message != NULL, FALSE);
1351
1352   GST_LOCK (element);
1353   bus = element->bus;
1354
1355   if (G_UNLIKELY (bus == NULL)) {
1356     GST_DEBUG ("... but I won't because I have no bus");
1357     GST_UNLOCK (element);
1358     gst_message_unref (message);
1359     return FALSE;
1360   }
1361   gst_object_ref (bus);
1362   GST_DEBUG ("... on bus %" GST_PTR_FORMAT, bus);
1363   GST_UNLOCK (element);
1364
1365   result = gst_bus_post (bus, message);
1366   gst_object_unref (bus);
1367
1368   return result;
1369 }
1370
1371 /**
1372  * _gst_element_error_printf:
1373  * @format: the printf-like format to use, or NULL
1374  *
1375  * This function is only used internally by the #gst_element_error macro.
1376  *
1377  * Returns: a newly allocated string, or NULL if the format was NULL or ""
1378  *
1379  * MT safe.
1380  */
1381 gchar *
1382 _gst_element_error_printf (const gchar * format, ...)
1383 {
1384   va_list args;
1385   gchar *buffer;
1386
1387   if (format == NULL)
1388     return NULL;
1389   if (format[0] == 0)
1390     return NULL;
1391
1392   va_start (args, format);
1393   buffer = g_strdup_vprintf (format, args);
1394   va_end (args);
1395   return buffer;
1396 }
1397
1398 /**
1399  * gst_element_message_full:
1400  * @element:  a #GstElement to send message from
1401  * @type:     the #GstMessageType
1402  * @domain:   the GStreamer GError domain this message belongs to
1403  * @code:     the GError code belonging to the domain
1404  * @text:     an allocated text string to be used as a replacement for the
1405  *            default message connected to code, or NULL
1406  * @debug:    an allocated debug message to be used as a replacement for the
1407  *            default debugging information, or NULL
1408  * @file:     the source code file where the error was generated
1409  * @function: the source code function where the error was generated
1410  * @line:     the source code line where the error was generated
1411  *
1412  * Post an error or warning message on the bus from inside an element.
1413  *
1414  * MT safe.
1415  */
1416 void gst_element_message_full
1417     (GstElement * element, GstMessageType type,
1418     GQuark domain, gint code, gchar * text,
1419     gchar * debug, const gchar * file, const gchar * function, gint line)
1420 {
1421   GError *gerror = NULL;
1422   gchar *name;
1423   gchar *sent_text;
1424   gchar *sent_debug;
1425   GstMessage *message = NULL;
1426
1427   /* checks */
1428   GST_DEBUG ("start");
1429   g_return_if_fail (GST_IS_ELEMENT (element));
1430   g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
1431       (type == GST_MESSAGE_WARNING));
1432
1433   /* check if we send the given text or the default error text */
1434   if ((text == NULL) || (text[0] == 0)) {
1435     /* text could have come from g_strdup_printf (""); */
1436     g_free (text);
1437     sent_text = gst_error_get_message (domain, code);
1438   } else
1439     sent_text = text;
1440
1441   /* construct a sent_debug with extra information from source */
1442   if ((debug == NULL) || (debug[0] == 0)) {
1443     /* debug could have come from g_strdup_printf (""); */
1444     sent_debug = NULL;
1445   } else {
1446     name = gst_object_get_path_string (GST_OBJECT (element));
1447     sent_debug = g_strdup_printf ("%s(%d): %s: %s:\n%s",
1448         file, line, function, name, debug ? debug : "");
1449     g_free (name);
1450   }
1451   g_free (debug);
1452
1453   /* create gerror and post message */
1454   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
1455       sent_text);
1456   gerror = g_error_new_literal (domain, code, sent_text);
1457
1458   if (type == GST_MESSAGE_ERROR) {
1459     message = gst_message_new_error (GST_OBJECT (element), gerror, sent_debug);
1460   } else if (type == GST_MESSAGE_WARNING) {
1461     message = gst_message_new_warning (GST_OBJECT (element), gerror,
1462         sent_debug);
1463   } else {
1464     g_assert_not_reached ();
1465   }
1466   gst_element_post_message (element, message);
1467
1468   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted message: %s",
1469       sent_text);
1470
1471   /* cleanup */
1472   g_error_free (gerror);
1473   g_free (sent_debug);
1474   g_free (sent_text);
1475 }
1476
1477 /**
1478  * gst_element_is_locked_state:
1479  * @element: a #GstElement.
1480  *
1481  * Checks if the state of an element is locked.
1482  * If the state of an element is locked, state changes of the parent don't
1483  * affect the element.
1484  * This way you can leave currently unused elements inside bins. Just lock their
1485  * state before changing the state from #GST_STATE_NULL.
1486  *
1487  * Returns: TRUE, if the element's state is locked.
1488  *
1489  * MT safe.
1490  */
1491 gboolean
1492 gst_element_is_locked_state (GstElement * element)
1493 {
1494   gboolean result;
1495
1496   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1497
1498   GST_LOCK (element);
1499   result = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1500   GST_UNLOCK (element);
1501
1502   return result;
1503 }
1504
1505 /**
1506  * gst_element_set_locked_state:
1507  * @element: a #GstElement
1508  * @locked_state: TRUE to lock the element's state
1509  *
1510  * Locks the state of an element, so state changes of the parent don't affect
1511  * this element anymore.
1512  *
1513  * Returns: TRUE if the state was changed, FALSE if bad params were given or
1514  * the element was already in the correct state.
1515  *
1516  * MT safe.
1517  */
1518 gboolean
1519 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
1520 {
1521   gboolean old;
1522
1523   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1524
1525   GST_LOCK (element);
1526   old = GST_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1527
1528   if (G_UNLIKELY (old == locked_state))
1529     goto was_ok;
1530
1531   if (locked_state) {
1532     GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
1533         GST_ELEMENT_NAME (element));
1534     GST_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
1535   } else {
1536     GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
1537         GST_ELEMENT_NAME (element));
1538     GST_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
1539   }
1540   GST_UNLOCK (element);
1541
1542   return TRUE;
1543
1544 was_ok:
1545   GST_UNLOCK (element);
1546
1547   return FALSE;
1548 }
1549
1550 /**
1551  * gst_element_sync_state_with_parent:
1552  * @element: a #GstElement.
1553  *
1554  * Tries to change the state of the element to the same as its parent.
1555  * If this function returns FALSE, the state of element is undefined.
1556  *
1557  * Returns: TRUE, if the element's state could be synced to the parent's state.
1558  */
1559 gboolean
1560 gst_element_sync_state_with_parent (GstElement * element)
1561 {
1562   GstElement *parent;
1563
1564   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1565   parent = GST_ELEMENT (GST_ELEMENT_PARENT (element));
1566   g_return_val_if_fail (GST_IS_BIN (parent), FALSE);
1567
1568   GST_CAT_DEBUG (GST_CAT_STATES, "syncing state of element %s (%s) to %s (%s)",
1569       GST_ELEMENT_NAME (element),
1570       gst_element_state_get_name (GST_STATE (element)),
1571       GST_ELEMENT_NAME (parent),
1572       gst_element_state_get_name (GST_STATE (parent)));
1573
1574   if (gst_element_set_state (element,
1575           GST_STATE (parent)) == GST_STATE_CHANGE_FAILURE) {
1576     return FALSE;
1577   }
1578   return TRUE;
1579 }
1580
1581 /* MT safe */
1582 static GstStateChangeReturn
1583 gst_element_get_state_func (GstElement * element,
1584     GstState * state, GstState * pending, GTimeVal * timeout)
1585 {
1586   GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
1587   GstState old_pending;
1588
1589   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "getting state");
1590
1591   GST_STATE_LOCK (element);
1592   /* we got an error, report immediatly */
1593   if (GST_STATE_NO_PREROLL (element)) {
1594     ret = GST_STATE_CHANGE_NO_PREROLL;
1595     goto done;
1596   }
1597
1598   /* we got an error, report immediatly */
1599   if (GST_STATE_ERROR (element)) {
1600     ret = GST_STATE_CHANGE_FAILURE;
1601     goto done;
1602   }
1603
1604   old_pending = GST_STATE_PENDING (element);
1605   if (old_pending != GST_STATE_VOID_PENDING) {
1606     GTimeVal *timeval, abstimeout;
1607
1608     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "wait for pending");
1609     if (timeout) {
1610       /* make timeout absolute */
1611       g_get_current_time (&abstimeout);
1612       g_time_val_add (&abstimeout,
1613           timeout->tv_sec * G_USEC_PER_SEC + timeout->tv_usec);
1614       timeval = &abstimeout;
1615     } else {
1616       timeval = NULL;
1617     }
1618     /* we have a pending state change, wait for it to complete */
1619     if (!GST_STATE_TIMED_WAIT (element, timeval)) {
1620       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timeout");
1621       /* timeout triggered */
1622       ret = GST_STATE_CHANGE_ASYNC;
1623     } else {
1624       /* could be success or failure */
1625       if (old_pending == GST_STATE (element)) {
1626         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "got success");
1627         ret = GST_STATE_CHANGE_SUCCESS;
1628       } else {
1629         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "got failure");
1630         ret = GST_STATE_CHANGE_FAILURE;
1631       }
1632     }
1633   }
1634   /* if nothing is pending anymore we can return SUCCESS */
1635   if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
1636     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
1637     ret = GST_STATE_CHANGE_SUCCESS;
1638   }
1639
1640 done:
1641   if (state)
1642     *state = GST_STATE (element);
1643   if (pending)
1644     *pending = GST_STATE_PENDING (element);
1645
1646   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1647       "state current: %s, pending: %s, error: %d, no_preroll: %d, result: %d",
1648       gst_element_state_get_name (GST_STATE (element)),
1649       gst_element_state_get_name (GST_STATE_PENDING (element)),
1650       GST_STATE_ERROR (element), GST_STATE_NO_PREROLL (element), ret);
1651
1652   GST_STATE_UNLOCK (element);
1653
1654   return ret;
1655 }
1656
1657 /**
1658  * gst_element_get_state:
1659  * @element: a #GstElement to get the state of.
1660  * @state: a pointer to #GstState to hold the state. Can be NULL.
1661  * @pending: a pointer to #GstState to hold the pending state.
1662  *           Can be NULL.
1663  * @timeout: a #GTimeVal to specify the timeout for an async
1664  *           state change or NULL for infinite timeout.
1665  *
1666  * Gets the state of the element. 
1667  *
1668  * For elements that performed an ASYNC state change, as reported by 
1669  * #gst_element_set_state(), this function will block up to the 
1670  * specified timeout value for the state change to complete. 
1671  * If the element completes the state change or goes into
1672  * an error, this function returns immediatly with a return value of
1673  * GST_STATE_CHANGE_SUCCESS or GST_STATE_CHANGE_FAILURE respectively. 
1674  *
1675  * Returns: GST_STATE_CHANGE_SUCCESS if the element has no more pending state and
1676  *          the last state change succeeded, GST_STATE_CHANGE_ASYNC
1677  *          if the element is still performing a state change or 
1678  *          GST_STATE_CHANGE_FAILURE if the last state change failed.
1679  *
1680  * MT safe.
1681  */
1682 GstStateChangeReturn
1683 gst_element_get_state (GstElement * element,
1684     GstState * state, GstState * pending, GTimeVal * timeout)
1685 {
1686   GstElementClass *oclass;
1687   GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
1688
1689   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
1690
1691   oclass = GST_ELEMENT_GET_CLASS (element);
1692
1693   if (oclass->get_state)
1694     result = (oclass->get_state) (element, state, pending, timeout);
1695
1696   return result;
1697 }
1698
1699 /**
1700  * gst_element_abort_state:
1701  * @element: a #GstElement to abort the state of.
1702  *
1703  * Abort the state change of the element. This function is used
1704  * by elements that do asynchronous state changes and find out 
1705  * something is wrong.
1706  *
1707  * This function should be called with the STATE_LOCK held.
1708  *
1709  * MT safe.
1710  */
1711 void
1712 gst_element_abort_state (GstElement * element)
1713 {
1714   GstState pending;
1715
1716   g_return_if_fail (GST_IS_ELEMENT (element));
1717
1718   pending = GST_STATE_PENDING (element);
1719
1720   if (pending != GST_STATE_VOID_PENDING && !GST_STATE_ERROR (element)) {
1721 #ifndef GST_DISABLE_GST_DEBUG
1722     GstState old_state = GST_STATE (element);
1723 #endif
1724
1725     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1726         "aborting state from %s to %s", gst_element_state_get_name (old_state),
1727         gst_element_state_get_name (pending));
1728
1729     /* flag error */
1730     GST_STATE_ERROR (element) = TRUE;
1731
1732     GST_STATE_BROADCAST (element);
1733   }
1734 }
1735
1736 /**
1737  * gst_element_commit_state:
1738  * @element: a #GstElement to commit the state of.
1739  *
1740  * Commit the state change of the element. This function is used
1741  * by elements that do asynchronous state changes.
1742  *
1743  * This function can only be called with the STATE_LOCK held.
1744  *
1745  * MT safe.
1746  */
1747 void
1748 gst_element_commit_state (GstElement * element)
1749 {
1750   GstState pending;
1751
1752   g_return_if_fail (GST_IS_ELEMENT (element));
1753
1754   pending = GST_STATE_PENDING (element);
1755
1756   if (pending != GST_STATE_VOID_PENDING) {
1757     GstState old_state = GST_STATE (element);
1758     GstMessage *message;
1759
1760     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1761         "committing state from %s to %s",
1762         gst_element_state_get_name (old_state),
1763         gst_element_state_get_name (pending));
1764
1765     GST_STATE (element) = pending;
1766     GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
1767     GST_STATE_ERROR (element) = FALSE;
1768
1769     message = gst_message_new_state_changed (GST_OBJECT (element),
1770         old_state, pending);
1771     gst_element_post_message (element, message);
1772     GST_STATE_BROADCAST (element);
1773   }
1774 }
1775
1776 /**
1777  * gst_element_lost_state:
1778  * @element: a #GstElement the state is lost of
1779  *
1780  * Brings the element to the lost state. The current state of the
1781  * element is copied to the pending state so that any call to
1782  * #gst_element_get_state() will return ASYNC.
1783  * This is mostly used for elements that lost their preroll buffer
1784  * in the PAUSED state after a flush, they become PAUSED again
1785  * if a new preroll buffer is queued.
1786  * This function can only be called when the element is currently
1787  * not in error or an async state change.
1788  *
1789  * This function can only be called with the STATE_LOCK held.
1790  *
1791  * MT safe.
1792  */
1793 void
1794 gst_element_lost_state (GstElement * element)
1795 {
1796   g_return_if_fail (GST_IS_ELEMENT (element));
1797
1798   if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING &&
1799       !GST_STATE_ERROR (element)) {
1800     GstState current_state = GST_STATE (element);
1801     GstMessage *message;
1802
1803     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1804         "lost state of %s", gst_element_state_get_name (current_state));
1805
1806     GST_STATE_PENDING (element) = current_state;
1807     GST_STATE_ERROR (element) = FALSE;
1808
1809     message = gst_message_new_state_changed (GST_OBJECT (element),
1810         current_state, current_state);
1811     gst_element_post_message (element, message);
1812   }
1813 }
1814
1815 /**
1816  * gst_element_set_state:
1817  * @element: a #GstElement to change state of.
1818  * @state: the element's new #GstState.
1819  *
1820  * Sets the state of the element. This function will try to set the
1821  * requested state by going through all the intermediary states and calling
1822  * the class's state change function for each.
1823  *
1824  * Returns: Result of the state change using #GstStateChangeReturn.
1825  *
1826  * MT safe.
1827  */
1828 GstStateChangeReturn
1829 gst_element_set_state (GstElement * element, GstState state)
1830 {
1831   GstElementClass *oclass;
1832   GstState current;
1833   GstStateChangeReturn return_val = GST_STATE_CHANGE_SUCCESS;
1834   GstStateChangeReturn ret;
1835   GstState pending;
1836   GTimeVal tv;
1837
1838   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
1839
1840   GST_DEBUG_OBJECT (element, "set_state to %s",
1841       gst_element_state_get_name (state));
1842   /* get current element state,  need to call the method so that
1843    * we call the virtual method and subclasses can implement their
1844    * own algorithms */
1845   GST_TIME_TO_TIMEVAL (0, tv);
1846   ret = gst_element_get_state (element, &current, &pending, &tv);
1847
1848   /* get the element state lock */
1849   GST_STATE_LOCK (element);
1850   /* this is the state we should go to */
1851   GST_STATE_FINAL (element) = state;
1852   if (ret == GST_STATE_CHANGE_ASYNC) {
1853     /* force next state keeping ASYNC, this is atomic as we hold
1854      * the STATE_LOCK */
1855     gst_element_commit_state (element);
1856     gst_element_lost_state (element);
1857   }
1858
1859   /* start with the current state */
1860   current = GST_STATE (element);
1861
1862   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "setting state from %s to %s",
1863       gst_element_state_get_name (current), gst_element_state_get_name (state));
1864
1865   oclass = GST_ELEMENT_GET_CLASS (element);
1866
1867   /* We always perform at least one state change, even if the 
1868    * current state is equal to the required state. This is needed
1869    * for bins that sync their children. */
1870   do {
1871     GstState pending;
1872
1873     /* calculate the pending state */
1874     if (current < state)
1875       pending = current + 1;
1876     else if (current > state)
1877       pending = current - 1;
1878     else
1879       pending = current;
1880
1881     /* set the pending state variable */
1882     GST_STATE_PENDING (element) = pending;
1883
1884     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1885         "%s: setting state from %s to %s",
1886         (pending != state ? "intermediate" : "final"),
1887         gst_element_state_get_name (current),
1888         gst_element_state_get_name (pending));
1889
1890     /* call the state change function so it can set the state */
1891     if (oclass->change_state)
1892       return_val = (oclass->change_state) (element, GST_STATE_CHANGE (element));
1893     else
1894       return_val = GST_STATE_CHANGE_FAILURE;
1895
1896     /* clear the error and preroll flag, we need to do that after
1897      * calling the virtual change_state function so that it can use the
1898      * old previous value. */
1899     GST_STATE_ERROR (element) = FALSE;
1900     GST_STATE_NO_PREROLL (element) = FALSE;
1901
1902     switch (return_val) {
1903       case GST_STATE_CHANGE_FAILURE:
1904         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1905             "have failed change_state return");
1906         /* state change failure exits the loop */
1907         gst_element_abort_state (element);
1908         goto exit;
1909       case GST_STATE_CHANGE_ASYNC:
1910         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1911             "element will change state async");
1912         /* an async state change exits the loop, we can only
1913          * go to the next state change when this one completes. */
1914         goto exit;
1915       case GST_STATE_CHANGE_SUCCESS:
1916         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1917             "element changed state successfully");
1918         /* we can commit the state now and proceed to the next state */
1919         gst_element_commit_state (element);
1920         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "committed state");
1921         break;
1922       case GST_STATE_CHANGE_NO_PREROLL:
1923         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1924             "element changed state successfully and can't preroll");
1925         /* we can commit the state now and proceed to the next state */
1926         gst_element_commit_state (element);
1927         GST_STATE_NO_PREROLL (element) = TRUE;
1928         GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "committed state");
1929         break;
1930       default:
1931         goto invalid_return;
1932     }
1933     /* get the current state of the element and see if we need to do more
1934      * state changes */
1935     current = GST_STATE (element);
1936   }
1937   while (current != state);
1938
1939 exit:
1940   GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
1941   GST_STATE_UNLOCK (element);
1942
1943   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "exit state change");
1944
1945   return return_val;
1946
1947   /* ERROR */
1948 invalid_return:
1949   {
1950     GST_STATE_FINAL (element) = GST_STATE_VOID_PENDING;
1951     GST_STATE_UNLOCK (element);
1952     /* somebody added a GST_STATE_ and forgot to do stuff here ! */
1953     g_critical ("unknown return value %d from a state change function",
1954         return_val);
1955     return GST_STATE_CHANGE_FAILURE;
1956   }
1957 }
1958
1959 /* gst_iterator_fold functions for pads_activate */
1960
1961 static gboolean
1962 activate_pads (GstPad * pad, GValue * ret, gboolean * active)
1963 {
1964   if (!gst_pad_set_active (pad, *active))
1965     g_value_set_boolean (ret, FALSE);
1966   else if (!*active)
1967     gst_pad_set_caps (pad, NULL);
1968
1969   gst_object_unref (pad);
1970   return TRUE;
1971 }
1972
1973 /* returns false on error or early cutout of the fold, true otherwise */
1974 static gboolean
1975 iterator_fold_with_resync (GstIterator * iter, GstIteratorFoldFunction func,
1976     GValue * ret, gpointer user_data)
1977 {
1978   GstIteratorResult ires;
1979   gboolean res = TRUE;
1980
1981   while (1) {
1982     ires = gst_iterator_fold (iter, func, ret, user_data);
1983
1984     switch (ires) {
1985       case GST_ITERATOR_RESYNC:
1986         gst_iterator_resync (iter);
1987         break;
1988       case GST_ITERATOR_DONE:
1989         res = TRUE;
1990         goto done;
1991       default:
1992         res = FALSE;
1993         goto done;
1994     }
1995   }
1996
1997 done:
1998   return res;
1999 }
2000
2001 /* is called with STATE_LOCK
2002  */
2003 static gboolean
2004 gst_element_pads_activate (GstElement * element, gboolean active)
2005 {
2006   GValue ret = { 0, };
2007   GstIterator *iter;
2008   gboolean fold_ok;
2009
2010   /* no need to unset this later, it's just a boolean */
2011   g_value_init (&ret, G_TYPE_BOOLEAN);
2012   g_value_set_boolean (&ret, TRUE);
2013
2014   iter = gst_element_iterate_src_pads (element);
2015   fold_ok = iterator_fold_with_resync
2016       (iter, (GstIteratorFoldFunction) activate_pads, &ret, &active);
2017   gst_iterator_free (iter);
2018   if (!fold_ok || !g_value_get_boolean (&ret))
2019     return FALSE;
2020
2021   iter = gst_element_iterate_sink_pads (element);
2022   fold_ok = iterator_fold_with_resync
2023       (iter, (GstIteratorFoldFunction) activate_pads, &ret, &active);
2024   gst_iterator_free (iter);
2025   if (!fold_ok || !g_value_get_boolean (&ret))
2026     return FALSE;
2027
2028   return TRUE;
2029 }
2030
2031 /* is called with STATE_LOCK */
2032 static GstStateChangeReturn
2033 gst_element_change_state (GstElement * element, GstStateChange transition)
2034 {
2035   GstState state, pending;
2036   GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
2037
2038   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2039
2040   state = GST_STATE (element);
2041   pending = GST_STATE_PENDING (element);
2042
2043   /* if the element already is in the given state, we just return success */
2044   if (pending == GST_STATE_VOID_PENDING || state == GST_STATE_PENDING (element))
2045     goto was_ok;
2046
2047   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2048       "default handler tries setting state from %s to %s (%04x)",
2049       gst_element_state_get_name (state),
2050       gst_element_state_get_name (pending), transition);
2051
2052   switch (transition) {
2053     case GST_STATE_CHANGE_NULL_TO_READY:
2054       break;
2055     case GST_STATE_CHANGE_READY_TO_PAUSED:
2056       if (!gst_element_pads_activate (element, TRUE)) {
2057         result = GST_STATE_CHANGE_FAILURE;
2058       }
2059       break;
2060     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2061       break;
2062     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2063       break;
2064     case GST_STATE_CHANGE_PAUSED_TO_READY:
2065     case GST_STATE_CHANGE_READY_TO_NULL:
2066       /* deactivate pads in both cases, since they are activated on
2067          ready->paused but the element might not have made it to paused */
2068       if (!gst_element_pads_activate (element, FALSE)) {
2069         result = GST_STATE_CHANGE_FAILURE;
2070       } else {
2071         gst_element_set_base_time (element, 0);
2072       }
2073       break;
2074     default:
2075       /* this will catch real but unhandled state changes;
2076        * can only be caused by:
2077        * - a new state was added
2078        * - somehow the element was asked to jump across an intermediate state
2079        */
2080       g_warning ("Unhandled state change from %s to %s",
2081           gst_element_state_get_name (state),
2082           gst_element_state_get_name (pending));
2083       break;
2084   }
2085   return result;
2086
2087 was_ok:
2088   {
2089     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2090         "element is already in the %s state",
2091         gst_element_state_get_name (state));
2092     if (GST_STATE_NO_PREROLL (element))
2093       return GST_STATE_CHANGE_NO_PREROLL;
2094     else
2095       return GST_STATE_CHANGE_SUCCESS;
2096   }
2097
2098 }
2099
2100 /**
2101  * gst_element_get_factory:
2102  * @element: a #GstElement to request the element factory of.
2103  *
2104  * Retrieves the factory that was used to create this element.
2105  *
2106  * Returns: the #GstElementFactory used for creating this element. 
2107  * no refcounting is needed.
2108  */
2109 GstElementFactory *
2110 gst_element_get_factory (GstElement * element)
2111 {
2112   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2113
2114   return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2115 }
2116
2117 static void
2118 gst_element_dispose (GObject * object)
2119 {
2120   GstElement *element = GST_ELEMENT (object);
2121
2122   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
2123
2124   g_return_if_fail (GST_STATE (element) == GST_STATE_NULL);
2125   g_return_if_fail (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING);
2126
2127   /* first we break all our links with the outside */
2128   while (element->pads) {
2129     gst_element_remove_pad (element, GST_PAD_CAST (element->pads->data));
2130   }
2131   if (G_UNLIKELY (element->pads != 0)) {
2132     g_critical ("could not remove pads from element %s",
2133         GST_STR_NULL (GST_OBJECT_NAME (object)));
2134   }
2135
2136   GST_LOCK (element);
2137   gst_object_replace ((GstObject **) & element->clock, NULL);
2138   gst_object_replace ((GstObject **) & element->bus, NULL);
2139   GST_UNLOCK (element);
2140
2141   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "parent class dispose");
2142
2143   G_OBJECT_CLASS (parent_class)->dispose (object);
2144 }
2145
2146 static void
2147 gst_element_finalize (GObject * object)
2148 {
2149   GstElement *element = GST_ELEMENT (object);
2150
2151   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize");
2152
2153   GST_STATE_LOCK (element);
2154   if (element->state_cond)
2155     g_cond_free (element->state_cond);
2156   element->state_cond = NULL;
2157   GST_STATE_UNLOCK (element);
2158   g_mutex_free (element->state_lock);
2159
2160   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize parent");
2161
2162   G_OBJECT_CLASS (parent_class)->finalize (object);
2163 }
2164
2165 #ifndef GST_DISABLE_LOADSAVE
2166 /**
2167  * gst_element_save_thyself:
2168  * @element: a #GstElement to save.
2169  * @parent: the xml parent node.
2170  *
2171  * Saves the element as part of the given XML structure.
2172  *
2173  * Returns: the new #xmlNodePtr.
2174  */
2175 static xmlNodePtr
2176 gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
2177 {
2178   GList *pads;
2179   GstElementClass *oclass;
2180   GParamSpec **specs, *spec;
2181   guint nspecs;
2182   gint i;
2183   GValue value = { 0, };
2184   GstElement *element;
2185
2186   g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2187
2188   element = GST_ELEMENT (object);
2189
2190   oclass = GST_ELEMENT_GET_CLASS (element);
2191
2192   xmlNewChild (parent, NULL, (xmlChar *) "name",
2193       (xmlChar *) GST_ELEMENT_NAME (element));
2194
2195   if (oclass->elementfactory != NULL) {
2196     GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
2197
2198     xmlNewChild (parent, NULL, (xmlChar *) "type",
2199         (xmlChar *) GST_PLUGIN_FEATURE (factory)->name);
2200   }
2201
2202   /* params */
2203   specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2204
2205   for (i = 0; i < nspecs; i++) {
2206     spec = specs[i];
2207     if (spec->flags & G_PARAM_READABLE) {
2208       xmlNodePtr param;
2209       char *contents;
2210
2211       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
2212
2213       g_object_get_property (G_OBJECT (element), spec->name, &value);
2214       param = xmlNewChild (parent, NULL, (xmlChar *) "param", NULL);
2215       xmlNewChild (param, NULL, (xmlChar *) "name", (xmlChar *) spec->name);
2216
2217       if (G_IS_PARAM_SPEC_STRING (spec))
2218         contents = g_value_dup_string (&value);
2219       else if (G_IS_PARAM_SPEC_ENUM (spec))
2220         contents = g_strdup_printf ("%d", g_value_get_enum (&value));
2221       else if (G_IS_PARAM_SPEC_INT64 (spec))
2222         contents = g_strdup_printf ("%" G_GINT64_FORMAT,
2223             g_value_get_int64 (&value));
2224       else
2225         contents = g_strdup_value_contents (&value);
2226
2227       xmlNewChild (param, NULL, (xmlChar *) "value", (xmlChar *) contents);
2228       g_free (contents);
2229
2230       g_value_unset (&value);
2231     }
2232   }
2233
2234   g_free (specs);
2235
2236   pads = GST_ELEMENT_PADS (element);
2237
2238   while (pads) {
2239     GstPad *pad = GST_PAD (pads->data);
2240
2241     /* figure out if it's a direct pad or a ghostpad */
2242     if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
2243       xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL);
2244
2245       gst_object_save_thyself (GST_OBJECT (pad), padtag);
2246     }
2247     pads = g_list_next (pads);
2248   }
2249
2250   return parent;
2251 }
2252
2253 static void
2254 gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
2255 {
2256   xmlNodePtr children;
2257   GstElement *element;
2258   gchar *name = NULL;
2259   gchar *value = NULL;
2260
2261   element = GST_ELEMENT (object);
2262   g_return_if_fail (element != NULL);
2263
2264   /* parameters */
2265   children = self->xmlChildrenNode;
2266   while (children) {
2267     if (!strcmp ((char *) children->name, "param")) {
2268       xmlNodePtr child = children->xmlChildrenNode;
2269
2270       while (child) {
2271         if (!strcmp ((char *) child->name, "name")) {
2272           name = (gchar *) xmlNodeGetContent (child);
2273         } else if (!strcmp ((char *) child->name, "value")) {
2274           value = (gchar *) xmlNodeGetContent (child);
2275         }
2276         child = child->next;
2277       }
2278       /* FIXME: can this just be g_object_set ? */
2279       gst_util_set_object_arg (G_OBJECT (element), name, value);
2280       /* g_object_set (G_OBJECT (element), name, value, NULL); */
2281       g_free (name);
2282       g_free (value);
2283     }
2284     children = children->next;
2285   }
2286
2287   /* pads */
2288   children = self->xmlChildrenNode;
2289   while (children) {
2290     if (!strcmp ((char *) children->name, "pad")) {
2291       gst_pad_load_and_link (children, GST_OBJECT (element));
2292     }
2293     children = children->next;
2294   }
2295
2296   if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
2297     (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
2298 }
2299 #endif /* GST_DISABLE_LOADSAVE */
2300
2301 static void
2302 gst_element_set_bus_func (GstElement * element, GstBus * bus)
2303 {
2304   g_return_if_fail (GST_IS_ELEMENT (element));
2305
2306   GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
2307
2308   GST_LOCK (element);
2309   gst_object_replace ((GstObject **) & GST_ELEMENT_BUS (element),
2310       GST_OBJECT_CAST (bus));
2311   GST_UNLOCK (element);
2312 }
2313
2314 /**
2315  * gst_element_set_bus:
2316  * @element: a #GstElement to set the bus of.
2317  * @bus: the #GstBus to set.
2318  *
2319  * Sets the bus of the element.  For internal use only, unless you're
2320  * testing elements.
2321  *
2322  * MT safe.
2323  */
2324 void
2325 gst_element_set_bus (GstElement * element, GstBus * bus)
2326 {
2327   GstElementClass *oclass;
2328
2329   g_return_if_fail (GST_IS_ELEMENT (element));
2330
2331   oclass = GST_ELEMENT_GET_CLASS (element);
2332
2333   if (oclass->set_bus)
2334     oclass->set_bus (element, bus);
2335 }
2336
2337 /**
2338  * gst_element_get_bus:
2339  * @element: a #GstElement to get the bus of.
2340  *
2341  * Returns the bus of the element.
2342  *
2343  * Returns: the element's #GstBus. unref after usage.
2344  *
2345  * MT safe.
2346  */
2347 GstBus *
2348 gst_element_get_bus (GstElement * element)
2349 {
2350   GstBus *result = NULL;
2351
2352   g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2353
2354   GST_LOCK (element);
2355   result = GST_ELEMENT_BUS (element);
2356   gst_object_ref (result);
2357   GST_UNLOCK (element);
2358
2359   GST_DEBUG_OBJECT (element, "got bus %" GST_PTR_FORMAT, result);
2360
2361   return result;
2362 }