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