2.0 beta init
[framework/multimedia/gstreamer0.10.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  * An existing pad of an element can be retrieved by name with
45  * gst_element_get_static_pad(). A new dynamic pad can be created using
46  * gst_element_request_pad() with a #GstPadTemplate or 
47  * gst_element_get_request_pad() with the template name such as "src_\%d".
48  * An iterator of all pads can be retrieved with gst_element_iterate_pads().
49  *
50  * Elements can be linked through their pads.
51  * If the link is straightforward, use the gst_element_link()
52  * convenience function to link two elements, or gst_element_link_many()
53  * for more elements in a row.
54  * Use gst_element_link_filtered() to link two elements constrained by
55  * a specified set of #GstCaps.
56  * For finer control, use gst_element_link_pads() and
57  * gst_element_link_pads_filtered() to specify the pads to link on
58  * each element by name.
59  *
60  * Each element has a state (see #GstState).  You can get and set the state
61  * of an element with gst_element_get_state() and gst_element_set_state().
62  * Setting a state triggers a #GstStateChange. To get a string representation
63  * of a #GstState, use gst_element_state_get_name().
64  *
65  * You can get and set a #GstClock on an element using gst_element_get_clock()
66  * and gst_element_set_clock().
67  * Some elements can provide a clock for the pipeline if
68  * gst_element_provides_clock() returns %TRUE. With the
69  * gst_element_provide_clock() method one can retrieve the clock provided by
70  * such an element.
71  * Not all elements require a clock to operate correctly. If
72  * gst_element_requires_clock() returns %TRUE, a clock should be set on the
73  * element with gst_element_set_clock().
74  *
75  * Note that clock slection and distribution is normally handled by the
76  * toplevel #GstPipeline so the clock functions are only to be used in very
77  * specific situations.
78  *
79  * Last reviewed on 2009-05-29 (0.10.24)
80  */
81
82 /* FIXME 0.11: suppress warnings for deprecated API such as GStaticRecMutex
83  * with newer GLib versions (>= 2.31.0) */
84 #define GLIB_DISABLE_DEPRECATION_WARNINGS
85 #include "gst_private.h"
86 #include <glib.h>
87 #include <stdarg.h>
88 #include <gobject/gvaluecollector.h>
89
90 #include "gstelement.h"
91 #include "gstelementdetails.h"
92 #include "gstenumtypes.h"
93 #include "gstbus.h"
94 #include "gstmarshal.h"
95 #include "gsterror.h"
96 #include "gstevent.h"
97 #include "gstutils.h"
98 #include "gstinfo.h"
99 #include "gstvalue.h"
100 #include "gst-i18n-lib.h"
101 #include "glib-compat-private.h"
102
103 #include <mm_ta/mm_ta.h>
104
105 /* Element signals and args */
106 enum
107 {
108   PAD_ADDED,
109   PAD_REMOVED,
110   NO_MORE_PADS,
111   /* add more above */
112   LAST_SIGNAL
113 };
114
115 enum
116 {
117   ARG_0
118       /* FILL ME */
119 };
120
121 #ifdef GST_DISABLE_DEPRECATED
122 #if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
123 #include <libxml/parser.h>
124 xmlNodePtr gst_object_save_thyself (const GstObject * object,
125     xmlNodePtr parent);
126 GstObject *gst_object_load_thyself (xmlNodePtr parent);
127 void gst_pad_load_and_link (xmlNodePtr self, GstObject * parent);
128 #endif
129 #endif
130
131 static void gst_element_class_init (GstElementClass * klass);
132 static void gst_element_init (GstElement * element);
133 static void gst_element_base_class_init (gpointer g_class);
134 static void gst_element_base_class_finalize (gpointer g_class);
135
136 static void gst_element_dispose (GObject * object);
137 static void gst_element_finalize (GObject * object);
138
139 static GstStateChangeReturn gst_element_change_state_func (GstElement * element,
140     GstStateChange transition);
141 static GstStateChangeReturn gst_element_get_state_func (GstElement * element,
142     GstState * state, GstState * pending, GstClockTime timeout);
143 static GstStateChangeReturn gst_element_set_state_func (GstElement * element,
144     GstState state);
145 static void gst_element_set_bus_func (GstElement * element, GstBus * bus);
146
147 static gboolean gst_element_default_send_event (GstElement * element,
148     GstEvent * event);
149 static gboolean gst_element_default_query (GstElement * element,
150     GstQuery * query);
151
152 static GstPadTemplate
153     * gst_element_class_get_request_pad_template (GstElementClass *
154     element_class, const gchar * name);
155
156 #if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
157 static xmlNodePtr gst_element_save_thyself (GstObject * object,
158     xmlNodePtr parent);
159 static void gst_element_restore_thyself (GstObject * parent, xmlNodePtr self);
160 #endif
161
162 static GstObjectClass *parent_class = NULL;
163 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
164
165 /* this is used in gstelementfactory.c:gst_element_register() */
166 GQuark _gst_elementclass_factory = 0;
167
168 GType
169 gst_element_get_type (void)
170 {
171   static volatile gsize gst_element_type = 0;
172
173   if (g_once_init_enter (&gst_element_type)) {
174     GType _type;
175     static const GTypeInfo element_info = {
176       sizeof (GstElementClass),
177       gst_element_base_class_init,
178       gst_element_base_class_finalize,
179       (GClassInitFunc) gst_element_class_init,
180       NULL,
181       NULL,
182       sizeof (GstElement),
183       0,
184       (GInstanceInitFunc) gst_element_init,
185       NULL
186     };
187
188     _type = g_type_register_static (GST_TYPE_OBJECT, "GstElement",
189         &element_info, G_TYPE_FLAG_ABSTRACT);
190
191     _gst_elementclass_factory =
192         g_quark_from_static_string ("GST_ELEMENTCLASS_FACTORY");
193     g_once_init_leave (&gst_element_type, _type);
194   }
195   return gst_element_type;
196 }
197
198 static void
199 gst_element_class_init (GstElementClass * klass)
200 {
201   GObjectClass *gobject_class = (GObjectClass *) klass;
202 #if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
203   GstObjectClass *gstobject_class = (GstObjectClass *) klass;
204 #endif
205
206   parent_class = g_type_class_peek_parent (klass);
207
208   /**
209    * GstElement::pad-added:
210    * @gstelement: the object which received the signal
211    * @new_pad: the pad that has been added
212    *
213    * a new #GstPad has been added to the element. Note that this signal will
214    * usually be emitted from the context of the streaming thread. Also keep in
215    * mind that if you add new elements to the pipeline in the signal handler
216    * you will need to set them to the desired target state with
217    * gst_element_set_state() or gst_element_sync_state_with_parent().
218    */
219   gst_element_signals[PAD_ADDED] =
220       g_signal_new ("pad-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
221       G_STRUCT_OFFSET (GstElementClass, pad_added), NULL, NULL,
222       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
223   /**
224    * GstElement::pad-removed:
225    * @gstelement: the object which received the signal
226    * @old_pad: the pad that has been removed
227    *
228    * a #GstPad has been removed from the element
229    */
230   gst_element_signals[PAD_REMOVED] =
231       g_signal_new ("pad-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
232       G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
233       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
234   /**
235    * GstElement::no-more-pads:
236    * @gstelement: the object which received the signal
237    *
238    * This signals that the element will not generate more dynamic pads.
239    * Note that this signal will usually be emitted from the context of
240    * the streaming thread.
241    */
242   gst_element_signals[NO_MORE_PADS] =
243       g_signal_new ("no-more-pads", G_TYPE_FROM_CLASS (klass),
244       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, no_more_pads), NULL,
245       NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
246
247   gobject_class->dispose = gst_element_dispose;
248   gobject_class->finalize = gst_element_finalize;
249
250 #if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
251   gstobject_class->save_thyself =
252       ((gpointer (*)(GstObject * object,
253               gpointer self)) * GST_DEBUG_FUNCPTR (gst_element_save_thyself));
254   gstobject_class->restore_thyself =
255       ((void (*)(GstObject * object,
256               gpointer self)) *GST_DEBUG_FUNCPTR (gst_element_restore_thyself));
257 #endif
258
259   klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state_func);
260   klass->set_state = GST_DEBUG_FUNCPTR (gst_element_set_state_func);
261   klass->get_state = GST_DEBUG_FUNCPTR (gst_element_get_state_func);
262   klass->set_bus = GST_DEBUG_FUNCPTR (gst_element_set_bus_func);
263   klass->query = GST_DEBUG_FUNCPTR (gst_element_default_query);
264   klass->send_event = GST_DEBUG_FUNCPTR (gst_element_default_send_event);
265   klass->numpadtemplates = 0;
266
267   klass->elementfactory = NULL;
268 }
269
270 static void
271 gst_element_base_class_init (gpointer g_class)
272 {
273   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
274
275   /* FIXME 0.11: Copy the element details and instead of clearing the
276    * pad template list copy the list and increase the refcount of
277    * the pad templates by one.
278    *
279    * This will make it possible to add pad templates and set element
280    * details in the class_init functions and is the real GObject way
281    * of doing things.
282    * See http://bugzilla.gnome.org/show_bug.cgi?id=491501
283    */
284   memset (&element_class->details, 0, sizeof (GstElementDetails));
285   element_class->meta_data = NULL;
286   element_class->padtemplates = NULL;
287
288   /* set the factory, see gst_element_register() */
289   element_class->elementfactory =
290       g_type_get_qdata (G_TYPE_FROM_CLASS (element_class),
291       _gst_elementclass_factory);
292   GST_DEBUG ("type %s : factory %p", G_OBJECT_CLASS_NAME (element_class),
293       element_class->elementfactory);
294 }
295
296 static void
297 gst_element_base_class_finalize (gpointer g_class)
298 {
299   GstElementClass *klass = GST_ELEMENT_CLASS (g_class);
300
301   g_list_foreach (klass->padtemplates, (GFunc) gst_object_unref, NULL);
302   g_list_free (klass->padtemplates);
303   __gst_element_details_clear (&klass->details);
304   if (klass->meta_data) {
305     gst_structure_free (klass->meta_data);
306     klass->meta_data = NULL;
307   }
308 }
309
310 static void
311 gst_element_init (GstElement * element)
312 {
313   GST_STATE (element) = GST_STATE_NULL;
314   GST_STATE_TARGET (element) = GST_STATE_NULL;
315   GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
316   GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
317   GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
318
319   /* FIXME 0.11: Store this directly in the instance struct */
320   element->state_lock = g_slice_new (GStaticRecMutex);
321   g_static_rec_mutex_init (element->state_lock);
322   element->state_cond = g_cond_new ();
323 }
324
325 /**
326  * gst_element_release_request_pad:
327  * @element: a #GstElement to release the request pad of.
328  * @pad: the #GstPad to release.
329  *
330  * Makes the element free the previously requested pad as obtained
331  * with gst_element_get_request_pad().
332  *
333  * This does not unref the pad. If the pad was created by using
334  * gst_element_get_request_pad(), gst_element_release_request_pad() needs to be
335  * followed by gst_object_unref() to free the @pad.
336  *
337  * MT safe.
338  */
339 void
340 gst_element_release_request_pad (GstElement * element, GstPad * pad)
341 {
342   GstElementClass *oclass;
343
344   g_return_if_fail (GST_IS_ELEMENT (element));
345   g_return_if_fail (GST_IS_PAD (pad));
346
347   oclass = GST_ELEMENT_GET_CLASS (element);
348
349   /* if the element implements a custom release function we call that, else we
350    * simply remove the pad from the element */
351   if (oclass->release_pad)
352     (oclass->release_pad) (element, pad);
353   else
354     gst_element_remove_pad (element, pad);
355 }
356
357 /**
358  * gst_element_requires_clock:
359  * @element: a #GstElement to query
360  *
361  * Query if the element requires a clock.
362  *
363  * Returns: %TRUE if the element requires a clock
364  *
365  * MT safe.
366  */
367 gboolean
368 gst_element_requires_clock (GstElement * element)
369 {
370   gboolean result;
371
372   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
373
374   result = (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
375
376   return result;
377 }
378
379 /**
380  * gst_element_provides_clock:
381  * @element: a #GstElement to query
382  *
383  * Query if the element provides a clock. A #GstClock provided by an
384  * element can be used as the global #GstClock for the pipeline.
385  * An element that can provide a clock is only required to do so in the PAUSED
386  * state, this means when it is fully negotiated and has allocated the resources
387  * to operate the clock.
388  *
389  * Returns: %TRUE if the element provides a clock
390  *
391  * MT safe.
392  */
393 gboolean
394 gst_element_provides_clock (GstElement * element)
395 {
396   gboolean result;
397
398   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
399
400   result = (GST_ELEMENT_GET_CLASS (element)->provide_clock != NULL);
401
402   return result;
403 }
404
405 /**
406  * gst_element_provide_clock:
407  * @element: a #GstElement to query
408  *
409  * Get the clock provided by the given element.
410  * <note>An element is only required to provide a clock in the PAUSED
411  * state. Some elements can provide a clock in other states.</note>
412  *
413  * Returns: (transfer full): the GstClock provided by the element or %NULL
414  * if no clock could be provided.  Unref after usage.
415  *
416  * MT safe.
417  */
418 GstClock *
419 gst_element_provide_clock (GstElement * element)
420 {
421   GstClock *result = NULL;
422   GstElementClass *oclass;
423
424   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
425
426   oclass = GST_ELEMENT_GET_CLASS (element);
427
428   if (oclass->provide_clock)
429     result = oclass->provide_clock (element);
430
431   return result;
432 }
433
434 /**
435  * gst_element_set_clock:
436  * @element: a #GstElement to set the clock for.
437  * @clock: the #GstClock to set for the element.
438  *
439  * Sets the clock for the element. This function increases the
440  * refcount on the clock. Any previously set clock on the object
441  * is unreffed.
442  *
443  * Returns: %TRUE if the element accepted the clock. An element can refuse a
444  * clock when it, for example, is not able to slave its internal clock to the
445  * @clock or when it requires a specific clock to operate.
446  *
447  * MT safe.
448  */
449 gboolean
450 gst_element_set_clock (GstElement * element, GstClock * clock)
451 {
452   GstElementClass *oclass;
453   gboolean res = TRUE;
454   GstClock **clock_p;
455
456   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
457   g_return_val_if_fail (clock == NULL || GST_IS_CLOCK (clock), FALSE);
458
459   oclass = GST_ELEMENT_GET_CLASS (element);
460
461   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element, "setting clock %p", clock);
462
463   if (oclass->set_clock)
464     res = oclass->set_clock (element, clock);
465
466   if (res) {
467     /* only update the clock pointer if the element accepted the clock */
468     GST_OBJECT_LOCK (element);
469     clock_p = &element->clock;
470     gst_object_replace ((GstObject **) clock_p, (GstObject *) clock);
471     GST_OBJECT_UNLOCK (element);
472   }
473   return res;
474 }
475
476 /**
477  * gst_element_get_clock:
478  * @element: a #GstElement to get the clock of.
479  *
480  * Gets the currently configured clock of the element. This is the clock as was
481  * last set with gst_element_set_clock().
482  *
483  * Returns: (transfer full): the #GstClock of the element. unref after usage.
484  *
485  * MT safe.
486  */
487 GstClock *
488 gst_element_get_clock (GstElement * element)
489 {
490   GstClock *result;
491
492   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
493
494   GST_OBJECT_LOCK (element);
495   if ((result = element->clock))
496     gst_object_ref (result);
497   GST_OBJECT_UNLOCK (element);
498
499   return result;
500 }
501
502 /**
503  * gst_element_set_base_time:
504  * @element: a #GstElement.
505  * @time: the base time to set.
506  *
507  * Set the base time of an element. See gst_element_get_base_time().
508  *
509  * MT safe.
510  */
511 void
512 gst_element_set_base_time (GstElement * element, GstClockTime time)
513 {
514   GstClockTime old;
515
516   g_return_if_fail (GST_IS_ELEMENT (element));
517
518   GST_OBJECT_LOCK (element);
519   old = element->base_time;
520   element->base_time = time;
521   GST_OBJECT_UNLOCK (element);
522
523   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element,
524       "set base_time=%" GST_TIME_FORMAT ", old %" GST_TIME_FORMAT,
525       GST_TIME_ARGS (time), GST_TIME_ARGS (old));
526 }
527
528 /**
529  * gst_element_get_base_time:
530  * @element: a #GstElement.
531  *
532  * Returns the base time of the element. The base time is the
533  * absolute time of the clock when this element was last put to
534  * PLAYING. Subtracting the base time from the clock time gives
535  * the running time of the element.
536  *
537  * Returns: the base time of the element.
538  *
539  * MT safe.
540  */
541 GstClockTime
542 gst_element_get_base_time (GstElement * element)
543 {
544   GstClockTime result;
545
546   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
547
548   GST_OBJECT_LOCK (element);
549   result = element->base_time;
550   GST_OBJECT_UNLOCK (element);
551
552   return result;
553 }
554
555 /**
556  * gst_element_set_start_time:
557  * @element: a #GstElement.
558  * @time: the base time to set.
559  *
560  * Set the start time of an element. The start time of the element is the
561  * running time of the element when it last went to the PAUSED state. In READY
562  * or after a flushing seek, it is set to 0.
563  *
564  * Toplevel elements like #GstPipeline will manage the start_time and
565  * base_time on its children. Setting the start_time to #GST_CLOCK_TIME_NONE
566  * on such a toplevel element will disable the distribution of the base_time to
567  * the children and can be useful if the application manages the base_time
568  * itself, for example if you want to synchronize capture from multiple
569  * pipelines, and you can also ensure that the pipelines have the same clock.
570  *
571  * MT safe.
572  *
573  * Since: 0.10.24
574  */
575 void
576 gst_element_set_start_time (GstElement * element, GstClockTime time)
577 {
578   GstClockTime old;
579
580   g_return_if_fail (GST_IS_ELEMENT (element));
581
582   GST_OBJECT_LOCK (element);
583   old = GST_ELEMENT_START_TIME (element);
584   GST_ELEMENT_START_TIME (element) = time;
585   GST_OBJECT_UNLOCK (element);
586
587   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element,
588       "set start_time=%" GST_TIME_FORMAT ", old %" GST_TIME_FORMAT,
589       GST_TIME_ARGS (time), GST_TIME_ARGS (old));
590 }
591
592 /**
593  * gst_element_get_start_time:
594  * @element: a #GstElement.
595  *
596  * Returns the start time of the element. The start time is the
597  * running time of the clock when this element was last put to PAUSED.
598  *
599  * Usually the start_time is managed by a toplevel element such as
600  * #GstPipeline.
601  *
602  * MT safe.
603  *
604  * Returns: the start time of the element.
605  *
606  * Since: 0.10.24
607  */
608 GstClockTime
609 gst_element_get_start_time (GstElement * element)
610 {
611   GstClockTime result;
612
613   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
614
615   GST_OBJECT_LOCK (element);
616   result = GST_ELEMENT_START_TIME (element);
617   GST_OBJECT_UNLOCK (element);
618
619   return result;
620 }
621
622 /**
623  * gst_element_is_indexable:
624  * @element: a #GstElement.
625  *
626  * Queries if the element can be indexed.
627  *
628  * Returns: TRUE if the element can be indexed.
629  *
630  * MT safe.
631  */
632 gboolean
633 gst_element_is_indexable (GstElement * element)
634 {
635   gboolean result;
636
637   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
638
639   result = (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
640
641   return result;
642 }
643
644 /**
645  * gst_element_set_index:
646  * @element: a #GstElement.
647  * @index: (transfer none): a #GstIndex.
648  *
649  * Set @index on the element. The refcount of the index
650  * will be increased, any previously set index is unreffed.
651  *
652  * MT safe.
653  */
654 void
655 gst_element_set_index (GstElement * element, GstIndex * index)
656 {
657   GstElementClass *oclass;
658
659   g_return_if_fail (GST_IS_ELEMENT (element));
660   g_return_if_fail (index == NULL || GST_IS_INDEX (index));
661
662   oclass = GST_ELEMENT_GET_CLASS (element);
663
664   if (oclass->set_index)
665     oclass->set_index (element, index);
666 }
667
668 /**
669  * gst_element_get_index:
670  * @element: a #GstElement.
671  *
672  * Gets the index from the element.
673  *
674  * Returns: (transfer full): a #GstIndex or %NULL when no index was set on the
675  * element. unref after usage.
676  *
677  * MT safe.
678  */
679 GstIndex *
680 gst_element_get_index (GstElement * element)
681 {
682   GstElementClass *oclass;
683   GstIndex *result = NULL;
684
685   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
686
687   oclass = GST_ELEMENT_GET_CLASS (element);
688
689   if (oclass->get_index)
690     result = oclass->get_index (element);
691
692   return result;
693 }
694
695 /**
696  * gst_element_add_pad:
697  * @element: a #GstElement to add the pad to.
698  * @pad: (transfer full): the #GstPad to add to the element.
699  *
700  * Adds a pad (link point) to @element. @pad's parent will be set to @element;
701  * see gst_object_set_parent() for refcounting information.
702  *
703  * Pads are not automatically activated so elements should perform the needed
704  * steps to activate the pad in case this pad is added in the PAUSED or PLAYING
705  * state. See gst_pad_set_active() for more information about activating pads.
706  *
707  * The pad and the element should be unlocked when calling this function.
708  *
709  * This function will emit the #GstElement::pad-added signal on the element.
710  *
711  * Returns: %TRUE if the pad could be added. This function can fail when
712  * a pad with the same name already existed or the pad already had another
713  * parent.
714  *
715  * MT safe.
716  */
717 gboolean
718 gst_element_add_pad (GstElement * element, GstPad * pad)
719 {
720   gchar *pad_name;
721   gboolean flushing;
722
723   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
724   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
725
726   /* locking pad to look at the name */
727   GST_OBJECT_LOCK (pad);
728   pad_name = g_strdup (GST_PAD_NAME (pad));
729   GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'",
730       GST_STR_NULL (pad_name));
731   flushing = GST_PAD_IS_FLUSHING (pad);
732   GST_OBJECT_UNLOCK (pad);
733
734   /* then check to see if there's already a pad by that name here */
735   GST_OBJECT_LOCK (element);
736   if (G_UNLIKELY (!gst_object_check_uniqueness (element->pads, pad_name)))
737     goto name_exists;
738
739   /* try to set the pad's parent */
740   if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (pad),
741               GST_OBJECT_CAST (element))))
742     goto had_parent;
743
744   /* check for flushing pads */
745   if (flushing && (GST_STATE (element) > GST_STATE_READY ||
746           GST_STATE_NEXT (element) == GST_STATE_PAUSED)) {
747     g_warning ("adding flushing pad '%s' to running element '%s', you need to "
748         "use gst_pad_set_active(pad,TRUE) before adding it.",
749         GST_STR_NULL (pad_name), GST_ELEMENT_NAME (element));
750     /* unset flushing */
751     GST_OBJECT_LOCK (pad);
752     GST_PAD_UNSET_FLUSHING (pad);
753     GST_OBJECT_UNLOCK (pad);
754   }
755
756   g_free (pad_name);
757
758   /* add it to the list */
759   switch (gst_pad_get_direction (pad)) {
760     case GST_PAD_SRC:
761       element->srcpads = g_list_prepend (element->srcpads, pad);
762       element->numsrcpads++;
763       break;
764     case GST_PAD_SINK:
765       element->sinkpads = g_list_prepend (element->sinkpads, pad);
766       element->numsinkpads++;
767       break;
768     default:
769       goto no_direction;
770   }
771   element->pads = g_list_prepend (element->pads, pad);
772   element->numpads++;
773   element->pads_cookie++;
774   GST_OBJECT_UNLOCK (element);
775
776   /* emit the PAD_ADDED signal */
777   g_signal_emit (element, gst_element_signals[PAD_ADDED], 0, pad);
778
779   return TRUE;
780
781   /* ERROR cases */
782 name_exists:
783   {
784     g_critical ("Padname %s is not unique in element %s, not adding",
785         pad_name, GST_ELEMENT_NAME (element));
786     GST_OBJECT_UNLOCK (element);
787     g_free (pad_name);
788     return FALSE;
789   }
790 had_parent:
791   {
792     g_critical
793         ("Pad %s already has parent when trying to add to element %s",
794         pad_name, GST_ELEMENT_NAME (element));
795     GST_OBJECT_UNLOCK (element);
796     g_free (pad_name);
797     return FALSE;
798   }
799 no_direction:
800   {
801     GST_OBJECT_LOCK (pad);
802     g_critical
803         ("Trying to add pad %s to element %s, but it has no direction",
804         GST_OBJECT_NAME (pad), GST_ELEMENT_NAME (element));
805     GST_OBJECT_UNLOCK (pad);
806     GST_OBJECT_UNLOCK (element);
807     return FALSE;
808   }
809 }
810
811 /**
812  * gst_element_remove_pad:
813  * @element: a #GstElement to remove pad from.
814  * @pad: (transfer none): the #GstPad to remove from the element.
815  *
816  * Removes @pad from @element. @pad will be destroyed if it has not been
817  * referenced elsewhere using gst_object_unparent().
818  *
819  * This function is used by plugin developers and should not be used
820  * by applications. Pads that were dynamically requested from elements
821  * with gst_element_get_request_pad() should be released with the
822  * gst_element_release_request_pad() function instead.
823  *
824  * Pads are not automatically deactivated so elements should perform the needed
825  * steps to deactivate the pad in case this pad is removed in the PAUSED or
826  * PLAYING state. See gst_pad_set_active() for more information about
827  * deactivating pads.
828  *
829  * The pad and the element should be unlocked when calling this function.
830  *
831  * This function will emit the #GstElement::pad-removed signal on the element.
832  *
833  * Returns: %TRUE if the pad could be removed. Can return %FALSE if the
834  * pad does not belong to the provided element.
835  *
836  * MT safe.
837  */
838 gboolean
839 gst_element_remove_pad (GstElement * element, GstPad * pad)
840 {
841   GstPad *peer;
842
843   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
844   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
845
846   /* locking pad to look at the name and parent */
847   GST_OBJECT_LOCK (pad);
848   GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "removing pad '%s'",
849       GST_STR_NULL (GST_PAD_NAME (pad)));
850
851   if (G_UNLIKELY (GST_PAD_PARENT (pad) != element))
852     goto not_our_pad;
853   GST_OBJECT_UNLOCK (pad);
854
855   /* unlink */
856   if ((peer = gst_pad_get_peer (pad))) {
857     /* window for MT unsafeness, someone else could unlink here
858      * and then we call unlink with wrong pads. The unlink
859      * function would catch this and safely return failed. */
860     if (GST_PAD_IS_SRC (pad))
861       gst_pad_unlink (pad, peer);
862     else
863       gst_pad_unlink (peer, pad);
864
865     gst_object_unref (peer);
866   }
867
868   GST_OBJECT_LOCK (element);
869   /* remove it from the list */
870   switch (gst_pad_get_direction (pad)) {
871     case GST_PAD_SRC:
872       element->srcpads = g_list_remove (element->srcpads, pad);
873       element->numsrcpads--;
874       break;
875     case GST_PAD_SINK:
876       element->sinkpads = g_list_remove (element->sinkpads, pad);
877       element->numsinkpads--;
878       break;
879     default:
880       g_critical ("Removing pad without direction???");
881       break;
882   }
883   element->pads = g_list_remove (element->pads, pad);
884   element->numpads--;
885   element->pads_cookie++;
886   GST_OBJECT_UNLOCK (element);
887
888   /* emit the PAD_REMOVED signal before unparenting and losing the last ref. */
889   g_signal_emit (element, gst_element_signals[PAD_REMOVED], 0, pad);
890
891   gst_object_unparent (GST_OBJECT_CAST (pad));
892
893   return TRUE;
894
895   /* ERRORS */
896 not_our_pad:
897   {
898     /* FIXME, locking order? */
899     GST_OBJECT_LOCK (element);
900     g_critical ("Padname %s:%s does not belong to element %s when removing",
901         GST_DEBUG_PAD_NAME (pad), GST_ELEMENT_NAME (element));
902     GST_OBJECT_UNLOCK (element);
903     GST_OBJECT_UNLOCK (pad);
904     return FALSE;
905   }
906 }
907
908 /**
909  * gst_element_no_more_pads:
910  * @element: a #GstElement
911  *
912  * Use this function to signal that the element does not expect any more pads
913  * to show up in the current pipeline. This function should be called whenever
914  * pads have been added by the element itself. Elements with #GST_PAD_SOMETIMES
915  * pad templates use this in combination with autopluggers to figure out that
916  * the element is done initializing its pads.
917  *
918  * This function emits the #GstElement::no-more-pads signal.
919  *
920  * MT safe.
921  */
922 void
923 gst_element_no_more_pads (GstElement * element)
924 {
925   g_return_if_fail (GST_IS_ELEMENT (element));
926
927   g_signal_emit (element, gst_element_signals[NO_MORE_PADS], 0);
928 }
929
930 static gint
931 pad_compare_name (GstPad * pad1, const gchar * name)
932 {
933   gint result;
934
935   GST_OBJECT_LOCK (pad1);
936   result = strcmp (GST_PAD_NAME (pad1), name);
937   GST_OBJECT_UNLOCK (pad1);
938
939   return result;
940 }
941
942 /**
943  * gst_element_get_static_pad:
944  * @element: a #GstElement to find a static pad of.
945  * @name: the name of the static #GstPad to retrieve.
946  *
947  * Retrieves a pad from @element by name. This version only retrieves
948  * already-existing (i.e. 'static') pads.
949  *
950  * Returns: (transfer full): the requested #GstPad if found, otherwise %NULL.
951  *     unref after usage.
952  *
953  * MT safe.
954  */
955 GstPad *
956 gst_element_get_static_pad (GstElement * element, const gchar * name)
957 {
958   GList *find;
959   GstPad *result = NULL;
960
961   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
962   g_return_val_if_fail (name != NULL, NULL);
963
964   GST_OBJECT_LOCK (element);
965   find =
966       g_list_find_custom (element->pads, name, (GCompareFunc) pad_compare_name);
967   if (find) {
968     result = GST_PAD_CAST (find->data);
969     gst_object_ref (result);
970   }
971
972   if (result == NULL) {
973     GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"",
974         name, GST_ELEMENT_NAME (element));
975   } else {
976     GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
977         GST_ELEMENT_NAME (element), name);
978   }
979   GST_OBJECT_UNLOCK (element);
980
981   return result;
982 }
983
984 static GstPad *
985 _gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
986     const gchar * name, const GstCaps * caps)
987 {
988   GstPad *newpad = NULL;
989   GstElementClass *oclass;
990
991   oclass = GST_ELEMENT_GET_CLASS (element);
992
993 #ifndef G_DISABLE_CHECKS
994   /* Some sanity checking here */
995   if (name) {
996     GstPad *pad;
997
998     /* Is this the template name? */
999     if (strstr (name, "%") || !strchr (templ->name_template, '%')) {
1000       g_return_val_if_fail (strcmp (name, templ->name_template) == 0, NULL);
1001     } else {
1002       const gchar *str, *data;
1003       gchar *endptr;
1004
1005       /* Otherwise check if it's a valid name for the name template */
1006       str = strchr (templ->name_template, '%');
1007       g_return_val_if_fail (str != NULL, NULL);
1008       g_return_val_if_fail (strncmp (templ->name_template, name,
1009               str - templ->name_template) == 0, NULL);
1010       g_return_val_if_fail (strlen (name) > str - templ->name_template, NULL);
1011
1012       data = name + (str - templ->name_template);
1013
1014       /* Can either be %s or %d or %u, do sanity checking for %d */
1015       if (*(str + 1) == 'd') {
1016         gint64 tmp;
1017
1018         /* it's an int */
1019         tmp = g_ascii_strtoll (data, &endptr, 10);
1020         g_return_val_if_fail (tmp >= G_MININT && tmp <= G_MAXINT
1021             && *endptr == '\0', NULL);
1022       } else if (*(str + 1) == 'u') {
1023         guint64 tmp;
1024
1025         /* it's an int */
1026         tmp = g_ascii_strtoull (data, &endptr, 10);
1027         g_return_val_if_fail (tmp <= G_MAXUINT && *endptr == '\0', NULL);
1028       }
1029     }
1030
1031     pad = gst_element_get_static_pad (element, name);
1032     if (pad) {
1033       gst_object_unref (pad);
1034       /* FIXME 0.11: Change this to g_return_val_if_fail() */
1035       g_critical ("Element %s already has a pad named %s, the behaviour of "
1036           " gst_element_get_request_pad() for existing pads is undefined!",
1037           GST_ELEMENT_NAME (element), name);
1038     }
1039   }
1040 #endif
1041
1042   if (oclass->request_new_pad_full)
1043     newpad = (oclass->request_new_pad_full) (element, templ, name, caps);
1044   else if (oclass->request_new_pad)
1045     newpad = (oclass->request_new_pad) (element, templ, name);
1046
1047   if (newpad)
1048     gst_object_ref (newpad);
1049
1050   return newpad;
1051 }
1052
1053 /**
1054  * gst_element_get_request_pad:
1055  * @element: a #GstElement to find a request pad of.
1056  * @name: the name of the request #GstPad to retrieve.
1057  *
1058  * Retrieves a pad from the element by name (e.g. "src_\%d"). This version only
1059  * retrieves request pads. The pad should be released with
1060  * gst_element_release_request_pad().
1061  *
1062  * This method is slow and will be deprecated in the future. New code should
1063  * use gst_element_request_pad() with the requested template.
1064  *
1065  * Returns: (transfer full): requested #GstPad if found, otherwise %NULL.
1066  *     Release after usage.
1067  */
1068 GstPad *
1069 gst_element_get_request_pad (GstElement * element, const gchar * name)
1070 {
1071   GstPadTemplate *templ = NULL;
1072   GstPad *pad;
1073   const gchar *req_name = NULL;
1074   gboolean templ_found = FALSE;
1075   GList *list;
1076   const gchar *data;
1077   gchar *str, *endptr = NULL;
1078   GstElementClass *class;
1079
1080   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1081   g_return_val_if_fail (name != NULL, NULL);
1082
1083   class = GST_ELEMENT_GET_CLASS (element);
1084
1085   /* if the name contains a %, we assume it's the complete template name. Get
1086    * the template and try to get a pad */
1087   if (strstr (name, "%")) {
1088     templ = gst_element_class_get_request_pad_template (class, name);
1089     req_name = NULL;
1090     if (templ)
1091       templ_found = TRUE;
1092   } else {
1093     /* there is no % in the name, try to find a matching template */
1094     list = class->padtemplates;
1095     while (!templ_found && list) {
1096       templ = (GstPadTemplate *) list->data;
1097       if (templ->presence == GST_PAD_REQUEST) {
1098         GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
1099             templ->name_template);
1100         /* see if we find an exact match */
1101         if (strcmp (name, templ->name_template) == 0) {
1102           templ_found = TRUE;
1103           req_name = name;
1104           break;
1105         }
1106         /* Because of sanity checks in gst_pad_template_new(), we know that %s
1107            and %d and %u, occurring at the end of the name_template, are the only
1108            possibilities. */
1109         else if ((str = strchr (templ->name_template, '%'))
1110             && strncmp (templ->name_template, name,
1111                 str - templ->name_template) == 0
1112             && strlen (name) > str - templ->name_template) {
1113           data = name + (str - templ->name_template);
1114           if (*(str + 1) == 'd') {
1115             glong tmp;
1116
1117             /* it's an int */
1118             tmp = strtol (data, &endptr, 10);
1119             if (tmp != G_MINLONG && tmp != G_MAXLONG && endptr &&
1120                 *endptr == '\0') {
1121               templ_found = TRUE;
1122               req_name = name;
1123               break;
1124             }
1125           } else if (*(str + 1) == 'u') {
1126             gulong tmp;
1127
1128             /* it's an int */
1129             tmp = strtoul (data, &endptr, 10);
1130             if (tmp != G_MAXULONG && endptr && *endptr == '\0') {
1131               templ_found = TRUE;
1132               req_name = name;
1133               break;
1134             }
1135           } else {
1136             /* it's a string */
1137             templ_found = TRUE;
1138             req_name = name;
1139             break;
1140           }
1141         }
1142       }
1143       list = list->next;
1144     }
1145   }
1146
1147   if (!templ_found)
1148     return NULL;
1149
1150   pad = _gst_element_request_pad (element, templ, req_name, NULL);
1151
1152   return pad;
1153 }
1154
1155 /**
1156  * gst_element_request_pad:
1157  * @element: a #GstElement to find a request pad of.
1158  * @templ: a #GstPadTemplate of which we want a pad of.
1159  * @name: (transfer none) (allow-none): the name of the request #GstPad
1160  * to retrieve. Can be %NULL.
1161  * @caps: (transfer none) (allow-none): the caps of the pad we want to
1162  * request. Can be %NULL.
1163  *
1164  * Retrieves a request pad from the element according to the provided template.
1165  * Pad templates can be looked up using
1166  * gst_element_factory_get_static_pad_templates().
1167  *
1168  * If the @caps are specified and the element implements thew new
1169  * request_new_pad_full virtual method, the element will use them to select
1170  * which pad to create.
1171  *
1172  * The pad should be released with gst_element_release_request_pad().
1173  *
1174  * Returns: (transfer full): requested #GstPad if found, otherwise %NULL.
1175  *     Release after usage.
1176  *
1177  * Since: 0.10.32
1178  */
1179 GstPad *
1180 gst_element_request_pad (GstElement * element,
1181     GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
1182 {
1183   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1184   g_return_val_if_fail (templ != NULL, NULL);
1185
1186   return _gst_element_request_pad (element, templ, name, caps);
1187 }
1188
1189 /**
1190  * gst_element_get_pad:
1191  * @element: a #GstElement.
1192  * @name: the name of the pad to retrieve.
1193  *
1194  * Retrieves a pad from @element by name. Tries gst_element_get_static_pad()
1195  * first, then gst_element_get_request_pad().
1196  *
1197  * Deprecated: This function is deprecated as it's unclear if the reference
1198  * to the result pad should be released with gst_object_unref() in case of a static pad
1199  * or gst_element_release_request_pad() in case of a request pad.
1200  * Use gst_element_get_static_pad() or gst_element_get_request_pad() instead.
1201  *
1202  * Returns: (transfer full): the #GstPad if found, otherwise %NULL. Unref or Release after usage,
1203  * depending on the type of the pad.
1204  */
1205 #ifndef GST_REMOVE_DEPRECATED
1206 #ifdef GST_DISABLE_DEPRECATED
1207 GstPad *gst_element_get_pad (GstElement * element, const gchar * name);
1208 #endif
1209 GstPad *
1210 gst_element_get_pad (GstElement * element, const gchar * name)
1211 {
1212   GstPad *pad;
1213
1214   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1215   g_return_val_if_fail (name != NULL, NULL);
1216
1217   pad = gst_element_get_static_pad (element, name);
1218   if (!pad)
1219     pad = gst_element_get_request_pad (element, name);
1220
1221   return pad;
1222 }
1223 #endif /* GST_REMOVE_DEPRECATED */
1224
1225 static GstIteratorItem
1226 iterate_pad (GstIterator * it, GstPad * pad)
1227 {
1228   gst_object_ref (pad);
1229   return GST_ITERATOR_ITEM_PASS;
1230 }
1231
1232 static GstIterator *
1233 gst_element_iterate_pad_list (GstElement * element, GList ** padlist)
1234 {
1235   GstIterator *result;
1236
1237   GST_OBJECT_LOCK (element);
1238   gst_object_ref (element);
1239   result = gst_iterator_new_list (GST_TYPE_PAD,
1240       GST_OBJECT_GET_LOCK (element),
1241       &element->pads_cookie,
1242       padlist,
1243       element,
1244       (GstIteratorItemFunction) iterate_pad,
1245       (GstIteratorDisposeFunction) gst_object_unref);
1246   GST_OBJECT_UNLOCK (element);
1247
1248   return result;
1249 }
1250
1251 /**
1252  * gst_element_iterate_pads:
1253  * @element: a #GstElement to iterate pads of.
1254  *
1255  * Retrieves an iterator of @element's pads. The iterator should
1256  * be freed after usage. Also more specialized iterators exists such as
1257  * gst_element_iterate_src_pads() or gst_element_iterate_sink_pads().
1258  *
1259  * Returns: (transfer full): the #GstIterator of #GstPad. Unref each pad
1260  *     after use.
1261  *
1262  * MT safe.
1263  */
1264 GstIterator *
1265 gst_element_iterate_pads (GstElement * element)
1266 {
1267   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1268
1269   return gst_element_iterate_pad_list (element, &element->pads);
1270 }
1271
1272 /**
1273  * gst_element_iterate_src_pads:
1274  * @element: a #GstElement.
1275  *
1276  * Retrieves an iterator of @element's source pads.
1277  *
1278  * Returns: (transfer full): the #GstIterator of #GstPad. Unref each pad
1279  *     after use.
1280  *
1281  * MT safe.
1282  */
1283 GstIterator *
1284 gst_element_iterate_src_pads (GstElement * element)
1285 {
1286   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1287
1288   return gst_element_iterate_pad_list (element, &element->srcpads);
1289 }
1290
1291 /**
1292  * gst_element_iterate_sink_pads:
1293  * @element: a #GstElement.
1294  *
1295  * Retrieves an iterator of @element's sink pads.
1296  *
1297  * Returns: (transfer full): the #GstIterator of #GstPad. Unref each pad
1298  *     after use.
1299  *
1300  * MT safe.
1301  */
1302 GstIterator *
1303 gst_element_iterate_sink_pads (GstElement * element)
1304 {
1305   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1306
1307   return gst_element_iterate_pad_list (element, &element->sinkpads);
1308 }
1309
1310 /**
1311  * gst_element_class_add_pad_template:
1312  * @klass: the #GstElementClass to add the pad template to.
1313  * @templ: (transfer none): a #GstPadTemplate to add to the element class.
1314  *
1315  * Adds a padtemplate to an element class. This is mainly used in the _base_init
1316  * functions of classes.
1317  */
1318 void
1319 gst_element_class_add_pad_template (GstElementClass * klass,
1320     GstPadTemplate * templ)
1321 {
1322   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1323   g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1324
1325   /* FIXME 0.11: allow replacing the pad templates by
1326    * calling this with the same name as an already existing pad
1327    * template. For this we _must_ _not_ ref the added pad template
1328    * a second time and _must_ document that this function takes
1329    * ownership of the pad template. Otherwise we will leak pad templates
1330    * or the caller unref's the pad template and it disappears */
1331   /* avoid registering pad templates with the same name */
1332   g_return_if_fail (gst_element_class_get_pad_template (klass,
1333           templ->name_template) == NULL);
1334
1335   klass->padtemplates = g_list_append (klass->padtemplates,
1336       gst_object_ref (templ));
1337   klass->numpadtemplates++;
1338 }
1339
1340 /**
1341  * gst_element_class_add_static_pad_template:
1342  * @klass: the #GstElementClass to add the pad template to.
1343  * @templ: (transfer none): a #GstStaticPadTemplate describing the pad
1344  * to add to the element class.
1345  *
1346  * Adds a padtemplate to an element class. This is mainly used in the _base_init
1347  * functions of classes.
1348  *
1349  * Since: 0.10.36
1350  */
1351 void
1352 gst_element_class_add_static_pad_template (GstElementClass * klass,
1353     GstStaticPadTemplate * templ)
1354 {
1355   GstPadTemplate *pt;
1356
1357   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1358
1359   pt = gst_static_pad_template_get (templ);
1360   gst_element_class_add_pad_template (klass, pt);
1361   gst_object_unref (pt);
1362 }
1363
1364 static void
1365 gst_element_class_add_meta_data (GstElementClass * klass,
1366     const gchar * key, const gchar * value)
1367 {
1368   if (!klass->meta_data) {
1369     /* FIXME: use a quark for "metadata" */
1370     klass->meta_data = gst_structure_empty_new ("metadata");
1371   }
1372
1373   gst_structure_set ((GstStructure *) klass->meta_data,
1374       key, G_TYPE_STRING, value, NULL);
1375 }
1376
1377 /**
1378  * gst_element_class_set_documentation_uri:
1379  * @klass: class to set details for
1380  * @uri: uri of element documentation
1381  *
1382  * Set uri pointing to user documentation. Applications can use this to show
1383  * help for e.g. effects to users.
1384  *
1385  * Since: 0.10.31
1386  */
1387 void
1388 gst_element_class_set_documentation_uri (GstElementClass * klass,
1389     const gchar * uri)
1390 {
1391   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1392
1393   gst_element_class_add_meta_data (klass, "doc-uri", uri);
1394 }
1395
1396 /**
1397  * gst_element_class_set_icon_name:
1398  * @klass: class to set details for
1399  * @name: name of an icon
1400  *
1401  * Elements that bridge to certain other products can include an icon of that
1402  * used product. Application can show the icon in menus/selectors to help
1403  * identifying specific elements.
1404  *
1405  * Since: 0.10.31
1406  */
1407 void
1408 gst_element_class_set_icon_name (GstElementClass * klass, const gchar * name)
1409 {
1410   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1411
1412   gst_element_class_add_meta_data (klass, "icon-name", name);
1413 }
1414
1415 /* FIXME-0.11: deprecate and remove gst_element_class_set_details*() */
1416 /**
1417  * gst_element_class_set_details:
1418  * @klass: class to set details for
1419  * @details: details to set
1420  *
1421  * Sets the detailed information for a #GstElementClass.
1422  * <note>This function is for use in _base_init functions only.</note>
1423  *
1424  * The @details are copied.
1425  *
1426  * Deprecated: Use gst_element_class_set_details_simple() instead.
1427  */
1428 #ifndef GST_REMOVE_DEPRECATED
1429 #ifdef GST_DISABLE_DEPRECATED
1430 void gst_element_class_set_details (GstElementClass * klass,
1431     const GstElementDetails * details);
1432 #endif
1433 void
1434 gst_element_class_set_details (GstElementClass * klass,
1435     const GstElementDetails * details)
1436 {
1437   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1438   g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
1439
1440   __gst_element_details_copy (&klass->details, details);
1441 }
1442 #endif
1443
1444 /**
1445  * gst_element_class_set_details_simple:
1446  * @klass: class to set details for
1447  * @longname: The long English name of the element. E.g. "File Sink"
1448  * @classification: String describing the type of element, as an unordered list
1449  * separated with slashes ('/'). See draft-klass.txt of the design docs
1450  * for more details and common types. E.g: "Sink/File"
1451  * @description: Sentence describing the purpose of the element.
1452  * E.g: "Write stream to a file"
1453  * @author: Name and contact details of the author(s). Use \n to separate
1454  * multiple author details. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
1455  *
1456  * Sets the detailed information for a #GstElementClass. Simpler version of
1457  * gst_element_class_set_details() that generates less linker overhead.
1458  * <note>This function is for use in _base_init functions only.</note>
1459  *
1460  * The detail parameter strings are copied into the #GstElementDetails for
1461  * the element class.
1462  *
1463  * Since: 0.10.14
1464  */
1465 void
1466 gst_element_class_set_details_simple (GstElementClass * klass,
1467     const gchar * longname, const gchar * classification,
1468     const gchar * description, const gchar * author)
1469 {
1470   const GstElementDetails details =
1471       GST_ELEMENT_DETAILS ((gchar *) longname, (gchar *) classification,
1472       (gchar *) description, (gchar *) author);
1473
1474   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1475
1476   __gst_element_details_copy (&klass->details, &details);
1477 }
1478
1479 /**
1480  * gst_element_class_get_pad_template_list:
1481  * @element_class: a #GstElementClass to get pad templates of.
1482  *
1483  * Retrieves a list of the pad templates associated with @element_class. The
1484  * list must not be modified by the calling code.
1485  * <note>If you use this function in the #GInstanceInitFunc of an object class
1486  * that has subclasses, make sure to pass the g_class parameter of the
1487  * #GInstanceInitFunc here.</note>
1488  *
1489  * Returns: (transfer none) (element-type Gst.PadTemplate): the #GList of
1490  *     pad templates.
1491  */
1492 GList *
1493 gst_element_class_get_pad_template_list (GstElementClass * element_class)
1494 {
1495   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1496
1497   return element_class->padtemplates;
1498 }
1499
1500 /**
1501  * gst_element_class_get_pad_template:
1502  * @element_class: a #GstElementClass to get the pad template of.
1503  * @name: the name of the #GstPadTemplate to get.
1504  *
1505  * Retrieves a padtemplate from @element_class with the given name.
1506  * <note>If you use this function in the #GInstanceInitFunc of an object class
1507  * that has subclasses, make sure to pass the g_class parameter of the
1508  * #GInstanceInitFunc here.</note>
1509  *
1510  * Returns: (transfer none): the #GstPadTemplate with the given name, or %NULL
1511  *     if none was found. No unreferencing is necessary.
1512  */
1513 GstPadTemplate *
1514 gst_element_class_get_pad_template (GstElementClass *
1515     element_class, const gchar * name)
1516 {
1517   GList *padlist;
1518
1519   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1520   g_return_val_if_fail (name != NULL, NULL);
1521
1522   padlist = element_class->padtemplates;
1523
1524   while (padlist) {
1525     GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1526
1527     if (strcmp (padtempl->name_template, name) == 0)
1528       return padtempl;
1529
1530     padlist = g_list_next (padlist);
1531   }
1532
1533   return NULL;
1534 }
1535
1536 static GstPadTemplate *
1537 gst_element_class_get_request_pad_template (GstElementClass *
1538     element_class, const gchar * name)
1539 {
1540   GstPadTemplate *tmpl;
1541
1542   tmpl = gst_element_class_get_pad_template (element_class, name);
1543   if (tmpl != NULL && tmpl->presence == GST_PAD_REQUEST)
1544     return tmpl;
1545
1546   return NULL;
1547 }
1548
1549 /* get a random pad on element of the given direction.
1550  * The pad is random in a sense that it is the first pad that is (optionaly) linked.
1551  */
1552 static GstPad *
1553 gst_element_get_random_pad (GstElement * element,
1554     gboolean need_linked, GstPadDirection dir)
1555 {
1556   GstPad *result = NULL;
1557   GList *pads;
1558
1559   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
1560
1561   switch (dir) {
1562     case GST_PAD_SRC:
1563       GST_OBJECT_LOCK (element);
1564       pads = element->srcpads;
1565       break;
1566     case GST_PAD_SINK:
1567       GST_OBJECT_LOCK (element);
1568       pads = element->sinkpads;
1569       break;
1570     default:
1571       goto wrong_direction;
1572   }
1573   for (; pads; pads = g_list_next (pads)) {
1574     GstPad *pad = GST_PAD_CAST (pads->data);
1575
1576     GST_OBJECT_LOCK (pad);
1577     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
1578         GST_DEBUG_PAD_NAME (pad));
1579
1580     if (need_linked && !GST_PAD_IS_LINKED (pad)) {
1581       /* if we require a linked pad, and it is not linked, continue the
1582        * search */
1583       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
1584           GST_DEBUG_PAD_NAME (pad));
1585       GST_OBJECT_UNLOCK (pad);
1586       continue;
1587     } else {
1588       /* found a pad, stop search */
1589       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
1590           GST_DEBUG_PAD_NAME (pad));
1591       GST_OBJECT_UNLOCK (pad);
1592       result = pad;
1593       break;
1594     }
1595   }
1596   if (result)
1597     gst_object_ref (result);
1598
1599   GST_OBJECT_UNLOCK (element);
1600
1601   return result;
1602
1603   /* ERROR handling */
1604 wrong_direction:
1605   {
1606     g_warning ("unknown pad direction %d", dir);
1607     return NULL;
1608   }
1609 }
1610
1611 static gboolean
1612 gst_element_default_send_event (GstElement * element, GstEvent * event)
1613 {
1614   gboolean result = FALSE;
1615   GstPad *pad;
1616
1617   pad = GST_EVENT_IS_DOWNSTREAM (event) ?
1618       gst_element_get_random_pad (element, TRUE, GST_PAD_SRC) :
1619       gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
1620
1621   if (pad) {
1622     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1623         "pushing %s event to random %s pad %s:%s",
1624         GST_EVENT_TYPE_NAME (event),
1625         (GST_PAD_DIRECTION (pad) == GST_PAD_SRC ? "src" : "sink"),
1626         GST_DEBUG_PAD_NAME (pad));
1627
1628     result = gst_pad_push_event (pad, event);
1629     gst_object_unref (pad);
1630   } else {
1631     GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "can't send %s event on element %s",
1632         GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
1633     gst_event_unref (event);
1634   }
1635   return result;
1636 }
1637
1638 /**
1639  * gst_element_send_event:
1640  * @element: a #GstElement to send the event to.
1641  * @event: (transfer full): the #GstEvent to send to the element.
1642  *
1643  * Sends an event to an element. If the element doesn't implement an
1644  * event handler, the event will be pushed on a random linked sink pad for
1645  * upstream events or a random linked source pad for downstream events.
1646  *
1647  * This function takes owership of the provided event so you should
1648  * gst_event_ref() it if you want to reuse the event after this call.
1649  *
1650  * Returns: %TRUE if the event was handled.
1651  *
1652  * MT safe.
1653  */
1654 gboolean
1655 gst_element_send_event (GstElement * element, GstEvent * event)
1656 {
1657   GstElementClass *oclass;
1658   gboolean result = FALSE;
1659
1660   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1661   g_return_val_if_fail (event != NULL, FALSE);
1662
1663   oclass = GST_ELEMENT_GET_CLASS (element);
1664
1665   GST_STATE_LOCK (element);
1666   if (oclass->send_event) {
1667     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send %s event on element %s",
1668         GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
1669     result = oclass->send_event (element, event);
1670   } else {
1671     result = gst_element_default_send_event (element, event);
1672   }
1673   GST_STATE_UNLOCK (element);
1674
1675   return result;
1676 }
1677
1678 /**
1679  * gst_element_seek:
1680  * @element: a #GstElement to send the event to.
1681  * @rate: The new playback rate
1682  * @format: The format of the seek values
1683  * @flags: The optional seek flags.
1684  * @cur_type: The type and flags for the new current position
1685  * @cur: The value of the new current position
1686  * @stop_type: The type and flags for the new stop position
1687  * @stop: The value of the new stop position
1688  *
1689  * Sends a seek event to an element. See gst_event_new_seek() for the details of
1690  * the parameters. The seek event is sent to the element using
1691  * gst_element_send_event().
1692  *
1693  * Returns: %TRUE if the event was handled.
1694  *
1695  * MT safe.
1696  */
1697 gboolean
1698 gst_element_seek (GstElement * element, gdouble rate, GstFormat format,
1699     GstSeekFlags flags, GstSeekType cur_type, gint64 cur,
1700     GstSeekType stop_type, gint64 stop)
1701 {
1702   GstEvent *event;
1703   gboolean result;
1704
1705   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1706
1707   event =
1708       gst_event_new_seek (rate, format, flags, cur_type, cur, stop_type, stop);
1709   result = gst_element_send_event (element, event);
1710
1711   return result;
1712 }
1713
1714 /**
1715  * gst_element_get_query_types:
1716  * @element: a #GstElement to query
1717  *
1718  * Get an array of query types from the element.
1719  * If the element doesn't implement a query types function,
1720  * the query will be forwarded to the peer of a random linked sink pad.
1721  *
1722  * Returns: An array of #GstQueryType elements that should not
1723  * be freed or modified.
1724  *
1725  * MT safe.
1726  */
1727 const GstQueryType *
1728 gst_element_get_query_types (GstElement * element)
1729 {
1730   GstElementClass *oclass;
1731   const GstQueryType *result = NULL;
1732
1733   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1734
1735   oclass = GST_ELEMENT_GET_CLASS (element);
1736
1737   if (oclass->get_query_types) {
1738     result = oclass->get_query_types (element);
1739   } else {
1740     GstPad *pad = gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
1741
1742     if (pad) {
1743       GstPad *peer = gst_pad_get_peer (pad);
1744
1745       if (peer) {
1746         result = gst_pad_get_query_types (peer);
1747
1748         gst_object_unref (peer);
1749       }
1750       gst_object_unref (pad);
1751     }
1752   }
1753   return result;
1754 }
1755
1756 static gboolean
1757 gst_element_default_query (GstElement * element, GstQuery * query)
1758 {
1759   gboolean result = FALSE;
1760   GstPad *pad;
1761
1762   pad = gst_element_get_random_pad (element, FALSE, GST_PAD_SRC);
1763   if (pad) {
1764     result = gst_pad_query (pad, query);
1765
1766     gst_object_unref (pad);
1767   } else {
1768     pad = gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
1769     if (pad) {
1770       GstPad *peer = gst_pad_get_peer (pad);
1771
1772       if (peer) {
1773         result = gst_pad_query (peer, query);
1774
1775         gst_object_unref (peer);
1776       }
1777       gst_object_unref (pad);
1778     }
1779   }
1780   return result;
1781 }
1782
1783 /**
1784  * gst_element_query:
1785  * @element: a #GstElement to perform the query on.
1786  * @query: (transfer none): the #GstQuery.
1787  *
1788  * Performs a query on the given element.
1789  *
1790  * For elements that don't implement a query handler, this function
1791  * forwards the query to a random srcpad or to the peer of a
1792  * random linked sinkpad of this element.
1793  *
1794  * Please note that some queries might need a running pipeline to work.
1795  *
1796  * Returns: TRUE if the query could be performed.
1797  *
1798  * MT safe.
1799  */
1800 gboolean
1801 gst_element_query (GstElement * element, GstQuery * query)
1802 {
1803   GstElementClass *oclass;
1804   gboolean result = FALSE;
1805
1806   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1807   g_return_val_if_fail (query != NULL, FALSE);
1808
1809   oclass = GST_ELEMENT_GET_CLASS (element);
1810
1811   if (oclass->query) {
1812     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send query on element %s",
1813         GST_ELEMENT_NAME (element));
1814     result = oclass->query (element, query);
1815   } else {
1816     result = gst_element_default_query (element, query);
1817   }
1818   return result;
1819 }
1820
1821 /**
1822  * gst_element_post_message:
1823  * @element: a #GstElement posting the message
1824  * @message: (transfer full): a #GstMessage to post
1825  *
1826  * Post a message on the element's #GstBus. This function takes ownership of the
1827  * message; if you want to access the message after this call, you should add an
1828  * additional reference before calling.
1829  *
1830  * Returns: %TRUE if the message was successfully posted. The function returns
1831  * %FALSE if the element did not have a bus.
1832  *
1833  * MT safe.
1834  */
1835 gboolean
1836 gst_element_post_message (GstElement * element, GstMessage * message)
1837 {
1838   GstBus *bus;
1839   gboolean result = FALSE;
1840
1841   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1842   g_return_val_if_fail (message != NULL, FALSE);
1843
1844   GST_OBJECT_LOCK (element);
1845   bus = element->bus;
1846
1847   if (G_UNLIKELY (bus == NULL))
1848     goto no_bus;
1849
1850   gst_object_ref (bus);
1851   GST_OBJECT_UNLOCK (element);
1852
1853   /* we release the element lock when posting the message so that any
1854    * (synchronous) message handlers can operate on the element */
1855   result = gst_bus_post (bus, message);
1856   gst_object_unref (bus);
1857
1858   return result;
1859
1860   /* ERRORS */
1861 no_bus:
1862   {
1863     GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element,
1864         "not posting message %p: no bus", message);
1865     GST_OBJECT_UNLOCK (element);
1866     gst_message_unref (message);
1867     return FALSE;
1868   }
1869 }
1870
1871 /**
1872  * _gst_element_error_printf:
1873  * @format: the printf-like format to use, or %NULL
1874  *
1875  * This function is only used internally by the gst_element_error() macro.
1876  *
1877  * Returns: (transfer full): a newly allocated string, or %NULL if the format
1878  *     was %NULL or ""
1879  *
1880  * MT safe.
1881  */
1882 gchar *
1883 _gst_element_error_printf (const gchar * format, ...)
1884 {
1885   va_list args;
1886   gchar *buffer;
1887
1888   if (format == NULL)
1889     return NULL;
1890   if (format[0] == 0)
1891     return NULL;
1892
1893   va_start (args, format);
1894   buffer = g_strdup_vprintf (format, args);
1895   va_end (args);
1896   return buffer;
1897 }
1898
1899 /**
1900  * gst_element_message_full:
1901  * @element:  a #GstElement to send message from
1902  * @type:     the #GstMessageType
1903  * @domain:   the GStreamer GError domain this message belongs to
1904  * @code:     the GError code belonging to the domain
1905  * @text:     (allow-none) (transfer full): an allocated text string to be used
1906  *            as a replacement for the default message connected to code,
1907  *            or %NULL
1908  * @debug:    (allow-none) (transfer full): an allocated debug message to be
1909  *            used as a replacement for the default debugging information,
1910  *            or %NULL
1911  * @file:     the source code file where the error was generated
1912  * @function: the source code function where the error was generated
1913  * @line:     the source code line where the error was generated
1914  *
1915  * Post an error, warning or info message on the bus from inside an element.
1916  *
1917  * @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
1918  * #GST_MESSAGE_INFO.
1919  *
1920  * MT safe.
1921  */
1922 void gst_element_message_full
1923     (GstElement * element, GstMessageType type,
1924     GQuark domain, gint code, gchar * text,
1925     gchar * debug, const gchar * file, const gchar * function, gint line)
1926 {
1927   GError *gerror = NULL;
1928   gchar *name;
1929   gchar *sent_text;
1930   gchar *sent_debug;
1931   gboolean has_debug = TRUE;
1932   GstMessage *message = NULL;
1933
1934   /* checks */
1935   GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element, "start");
1936   g_return_if_fail (GST_IS_ELEMENT (element));
1937   g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
1938       (type == GST_MESSAGE_WARNING) || (type == GST_MESSAGE_INFO));
1939
1940   /* check if we send the given text or the default error text */
1941   if ((text == NULL) || (text[0] == 0)) {
1942     /* text could have come from g_strdup_printf (""); */
1943     g_free (text);
1944     sent_text = gst_error_get_message (domain, code);
1945   } else
1946     sent_text = text;
1947
1948   /* construct a sent_debug with extra information from source */
1949   if ((debug == NULL) || (debug[0] == 0)) {
1950     /* debug could have come from g_strdup_printf (""); */
1951     has_debug = FALSE;
1952   }
1953
1954   name = gst_object_get_path_string (GST_OBJECT_CAST (element));
1955   if (has_debug)
1956     sent_debug = g_strdup_printf ("%s(%d): %s (): %s:\n%s",
1957         file, line, function, name, debug);
1958   else
1959     sent_debug = g_strdup_printf ("%s(%d): %s (): %s",
1960         file, line, function, name);
1961   g_free (name);
1962   g_free (debug);
1963
1964   /* create gerror and post message */
1965   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
1966       sent_text);
1967   gerror = g_error_new_literal (domain, code, sent_text);
1968
1969   switch (type) {
1970     case GST_MESSAGE_ERROR:
1971       message =
1972           gst_message_new_error (GST_OBJECT_CAST (element), gerror, sent_debug);
1973       break;
1974     case GST_MESSAGE_WARNING:
1975       message = gst_message_new_warning (GST_OBJECT_CAST (element), gerror,
1976           sent_debug);
1977       break;
1978     case GST_MESSAGE_INFO:
1979       message = gst_message_new_info (GST_OBJECT_CAST (element), gerror,
1980           sent_debug);
1981       break;
1982     default:
1983       g_assert_not_reached ();
1984       break;
1985   }
1986   gst_element_post_message (element, message);
1987
1988   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted %s message: %s",
1989       (type == GST_MESSAGE_ERROR ? "error" : "warning"), sent_text);
1990
1991   /* cleanup */
1992   g_error_free (gerror);
1993   g_free (sent_debug);
1994   g_free (sent_text);
1995 }
1996
1997 /**
1998  * gst_element_is_locked_state:
1999  * @element: a #GstElement.
2000  *
2001  * Checks if the state of an element is locked.
2002  * If the state of an element is locked, state changes of the parent don't
2003  * affect the element.
2004  * This way you can leave currently unused elements inside bins. Just lock their
2005  * state before changing the state from #GST_STATE_NULL.
2006  *
2007  * MT safe.
2008  *
2009  * Returns: TRUE, if the element's state is locked.
2010  */
2011 gboolean
2012 gst_element_is_locked_state (GstElement * element)
2013 {
2014   gboolean result;
2015
2016   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2017
2018   GST_OBJECT_LOCK (element);
2019   result = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
2020   GST_OBJECT_UNLOCK (element);
2021
2022   return result;
2023 }
2024
2025 /**
2026  * gst_element_set_locked_state:
2027  * @element: a #GstElement
2028  * @locked_state: TRUE to lock the element's state
2029  *
2030  * Locks the state of an element, so state changes of the parent don't affect
2031  * this element anymore.
2032  *
2033  * MT safe.
2034  *
2035  * Returns: TRUE if the state was changed, FALSE if bad parameters were given
2036  * or the elements state-locking needed no change.
2037  */
2038 gboolean
2039 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
2040 {
2041   gboolean old;
2042
2043   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2044
2045   GST_OBJECT_LOCK (element);
2046   old = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
2047
2048   if (G_UNLIKELY (old == locked_state))
2049     goto was_ok;
2050
2051   if (locked_state) {
2052     GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
2053         GST_ELEMENT_NAME (element));
2054     GST_OBJECT_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
2055   } else {
2056     GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
2057         GST_ELEMENT_NAME (element));
2058     GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
2059   }
2060   GST_OBJECT_UNLOCK (element);
2061
2062   return TRUE;
2063
2064 was_ok:
2065   {
2066     GST_CAT_DEBUG (GST_CAT_STATES,
2067         "elements %s was already in locked state %d",
2068         GST_ELEMENT_NAME (element), old);
2069     GST_OBJECT_UNLOCK (element);
2070
2071     return FALSE;
2072   }
2073 }
2074
2075 /**
2076  * gst_element_sync_state_with_parent:
2077  * @element: a #GstElement.
2078  *
2079  * Tries to change the state of the element to the same as its parent.
2080  * If this function returns FALSE, the state of element is undefined.
2081  *
2082  * Returns: TRUE, if the element's state could be synced to the parent's state.
2083  *
2084  * MT safe.
2085  */
2086 gboolean
2087 gst_element_sync_state_with_parent (GstElement * element)
2088 {
2089   GstElement *parent;
2090   GstState target;
2091   GstStateChangeReturn ret;
2092
2093   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2094
2095   if ((parent = GST_ELEMENT_CAST (gst_element_get_parent (element)))) {
2096     GstState parent_current, parent_pending;
2097
2098     GST_OBJECT_LOCK (parent);
2099     parent_current = GST_STATE (parent);
2100     parent_pending = GST_STATE_PENDING (parent);
2101     GST_OBJECT_UNLOCK (parent);
2102
2103     /* set to pending if there is one, else we set it to the current state of
2104      * the parent */
2105     if (parent_pending != GST_STATE_VOID_PENDING)
2106       target = parent_pending;
2107     else
2108       target = parent_current;
2109
2110     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2111         "syncing state (%s) to parent %s %s (%s, %s)",
2112         gst_element_state_get_name (GST_STATE (element)),
2113         GST_ELEMENT_NAME (parent), gst_element_state_get_name (target),
2114         gst_element_state_get_name (parent_current),
2115         gst_element_state_get_name (parent_pending));
2116
2117     ret = gst_element_set_state (element, target);
2118     if (ret == GST_STATE_CHANGE_FAILURE)
2119       goto failed;
2120
2121     gst_object_unref (parent);
2122
2123     return TRUE;
2124   } else {
2125     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "element has no parent");
2126   }
2127   return FALSE;
2128
2129   /* ERROR */
2130 failed:
2131   {
2132     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2133         "syncing state failed (%s)",
2134         gst_element_state_change_return_get_name (ret));
2135     gst_object_unref (parent);
2136     return FALSE;
2137   }
2138 }
2139
2140 /* MT safe */
2141 static GstStateChangeReturn
2142 gst_element_get_state_func (GstElement * element,
2143     GstState * state, GstState * pending, GstClockTime timeout)
2144 {
2145   GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
2146   GstState old_pending;
2147
2148   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "getting state, timeout %"
2149       GST_TIME_FORMAT, GST_TIME_ARGS (timeout));
2150
2151   GST_OBJECT_LOCK (element);
2152   ret = GST_STATE_RETURN (element);
2153   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "RETURN is %s",
2154       gst_element_state_change_return_get_name (ret));
2155
2156   /* we got an error, report immediately */
2157   if (ret == GST_STATE_CHANGE_FAILURE)
2158     goto done;
2159
2160   /* we got no_preroll, report immediately */
2161   if (ret == GST_STATE_CHANGE_NO_PREROLL)
2162     goto done;
2163
2164   /* no need to wait async if we are not async */
2165   if (ret != GST_STATE_CHANGE_ASYNC)
2166     goto done;
2167
2168   old_pending = GST_STATE_PENDING (element);
2169   if (old_pending != GST_STATE_VOID_PENDING) {
2170     GTimeVal *timeval, abstimeout;
2171     guint32 cookie;
2172
2173     if (timeout != GST_CLOCK_TIME_NONE) {
2174       glong add = timeout / 1000;
2175
2176       if (add == 0)
2177         goto done;
2178
2179       /* make timeout absolute */
2180       g_get_current_time (&abstimeout);
2181       g_time_val_add (&abstimeout, add);
2182       timeval = &abstimeout;
2183     } else {
2184       timeval = NULL;
2185     }
2186     /* get cookie to detect state changes during waiting */
2187     cookie = element->state_cookie;
2188
2189     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2190         "waiting for element to commit state");
2191
2192     /* we have a pending state change, wait for it to complete */
2193     if (!GST_STATE_TIMED_WAIT (element, timeval)) {
2194       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timed out");
2195       /* timeout triggered */
2196       ret = GST_STATE_CHANGE_ASYNC;
2197     } else {
2198       if (cookie != element->state_cookie)
2199         goto interrupted;
2200
2201       /* could be success or failure */
2202       if (old_pending == GST_STATE (element)) {
2203         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got success");
2204         ret = GST_STATE_CHANGE_SUCCESS;
2205       } else {
2206         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got failure");
2207         ret = GST_STATE_CHANGE_FAILURE;
2208       }
2209     }
2210     /* if nothing is pending anymore we can return SUCCESS */
2211     if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
2212       GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "nothing pending");
2213       ret = GST_STATE_CHANGE_SUCCESS;
2214     }
2215   }
2216
2217 done:
2218   if (state)
2219     *state = GST_STATE (element);
2220   if (pending)
2221     *pending = GST_STATE_PENDING (element);
2222
2223   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2224       "state current: %s, pending: %s, result: %s",
2225       gst_element_state_get_name (GST_STATE (element)),
2226       gst_element_state_get_name (GST_STATE_PENDING (element)),
2227       gst_element_state_change_return_get_name (ret));
2228   GST_OBJECT_UNLOCK (element);
2229
2230   return ret;
2231
2232 interrupted:
2233   {
2234     if (state)
2235       *state = GST_STATE_VOID_PENDING;
2236     if (pending)
2237       *pending = GST_STATE_VOID_PENDING;
2238
2239     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "interruped");
2240
2241     GST_OBJECT_UNLOCK (element);
2242
2243     return GST_STATE_CHANGE_FAILURE;
2244   }
2245 }
2246
2247 /**
2248  * gst_element_get_state:
2249  * @element: a #GstElement to get the state of.
2250  * @state: (out) (allow-none): a pointer to #GstState to hold the state.
2251  *     Can be %NULL.
2252  * @pending: (out) (allow-none): a pointer to #GstState to hold the pending
2253  *     state. Can be %NULL.
2254  * @timeout: a #GstClockTime to specify the timeout for an async
2255  *           state change or %GST_CLOCK_TIME_NONE for infinite timeout.
2256  *
2257  * Gets the state of the element.
2258  *
2259  * For elements that performed an ASYNC state change, as reported by
2260  * gst_element_set_state(), this function will block up to the
2261  * specified timeout value for the state change to complete.
2262  * If the element completes the state change or goes into
2263  * an error, this function returns immediately with a return value of
2264  * %GST_STATE_CHANGE_SUCCESS or %GST_STATE_CHANGE_FAILURE respectively.
2265  *
2266  * For elements that did not return %GST_STATE_CHANGE_ASYNC, this function
2267  * returns the current and pending state immediately.
2268  *
2269  * This function returns %GST_STATE_CHANGE_NO_PREROLL if the element
2270  * successfully changed its state but is not able to provide data yet.
2271  * This mostly happens for live sources that only produce data in
2272  * %GST_STATE_PLAYING. While the state change return is equivalent to
2273  * %GST_STATE_CHANGE_SUCCESS, it is returned to the application to signal that
2274  * some sink elements might not be able to complete their state change because
2275  * an element is not producing data to complete the preroll. When setting the
2276  * element to playing, the preroll will complete and playback will start.
2277  *
2278  * Returns: %GST_STATE_CHANGE_SUCCESS if the element has no more pending state
2279  *          and the last state change succeeded, %GST_STATE_CHANGE_ASYNC if the
2280  *          element is still performing a state change or
2281  *          %GST_STATE_CHANGE_FAILURE if the last state change failed.
2282  *
2283  * MT safe.
2284  */
2285 GstStateChangeReturn
2286 gst_element_get_state (GstElement * element,
2287     GstState * state, GstState * pending, GstClockTime timeout)
2288 {
2289   GstElementClass *oclass;
2290   GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
2291         unsigned char   szMsg[256];
2292
2293   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2294
2295   oclass = GST_ELEMENT_GET_CLASS (element);
2296
2297         sprintf( szMsg, "gst_element_get_state (%s)", GST_ELEMENT_NAME(element) );
2298         MMTA_ACUM_ITEM_BEGIN(szMsg, FALSE );
2299
2300   if (oclass->get_state)
2301     result = (oclass->get_state) (element, state, pending, timeout);
2302
2303         MMTA_ACUM_ITEM_END( szMsg, FALSE );
2304
2305   return result;
2306 }
2307
2308 /**
2309  * gst_element_abort_state:
2310  * @element: a #GstElement to abort the state of.
2311  *
2312  * Abort the state change of the element. This function is used
2313  * by elements that do asynchronous state changes and find out
2314  * something is wrong.
2315  *
2316  * This function should be called with the STATE_LOCK held.
2317  *
2318  * MT safe.
2319  */
2320 void
2321 gst_element_abort_state (GstElement * element)
2322 {
2323   GstState pending;
2324
2325 #ifndef GST_DISABLE_GST_DEBUG
2326   GstState old_state;
2327 #endif
2328
2329   g_return_if_fail (GST_IS_ELEMENT (element));
2330
2331   GST_OBJECT_LOCK (element);
2332   pending = GST_STATE_PENDING (element);
2333
2334   if (pending == GST_STATE_VOID_PENDING ||
2335       GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
2336     goto nothing_aborted;
2337
2338 #ifndef GST_DISABLE_GST_DEBUG
2339   old_state = GST_STATE (element);
2340
2341   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2342       "aborting state from %s to %s", gst_element_state_get_name (old_state),
2343       gst_element_state_get_name (pending));
2344 #endif
2345
2346   /* flag error */
2347   GST_STATE_RETURN (element) = GST_STATE_CHANGE_FAILURE;
2348
2349   GST_STATE_BROADCAST (element);
2350   GST_OBJECT_UNLOCK (element);
2351
2352   return;
2353
2354 nothing_aborted:
2355   {
2356     GST_OBJECT_UNLOCK (element);
2357     return;
2358   }
2359 }
2360
2361 /* Not static because GstBin has manual state handling too */
2362 void
2363 _priv_gst_element_state_changed (GstElement * element, GstState oldstate,
2364     GstState newstate, GstState pending)
2365 {
2366   GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
2367   GstMessage *message;
2368
2369   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2370       "notifying about state-changed %s to %s (%s pending)",
2371       gst_element_state_get_name (oldstate),
2372       gst_element_state_get_name (newstate),
2373       gst_element_state_get_name (pending));
2374
2375   if (klass->state_changed)
2376     klass->state_changed (element, oldstate, newstate, pending);
2377
2378   message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
2379       oldstate, newstate, pending);
2380   gst_element_post_message (element, message);
2381 }
2382
2383 /**
2384  * gst_element_continue_state:
2385  * @element: a #GstElement to continue the state change of.
2386  * @ret: The previous state return value
2387  *
2388  * Commit the state change of the element and proceed to the next
2389  * pending state if any. This function is used
2390  * by elements that do asynchronous state changes.
2391  * The core will normally call this method automatically when an
2392  * element returned %GST_STATE_CHANGE_SUCCESS from the state change function.
2393  *
2394  * If after calling this method the element still has not reached
2395  * the pending state, the next state change is performed.
2396  *
2397  * This method is used internally and should normally not be called by plugins
2398  * or applications.
2399  *
2400  * Returns: The result of the commit state change.
2401  *
2402  * MT safe.
2403  */
2404 GstStateChangeReturn
2405 gst_element_continue_state (GstElement * element, GstStateChangeReturn ret)
2406 {
2407   GstStateChangeReturn old_ret;
2408   GstState old_state, old_next;
2409   GstState current, next, pending;
2410   GstStateChange transition;
2411
2412   GST_OBJECT_LOCK (element);
2413   old_ret = GST_STATE_RETURN (element);
2414   GST_STATE_RETURN (element) = ret;
2415   pending = GST_STATE_PENDING (element);
2416
2417   /* check if there is something to commit */
2418   if (pending == GST_STATE_VOID_PENDING)
2419     goto nothing_pending;
2420
2421   old_state = GST_STATE (element);
2422   /* this is the state we should go to next */
2423   old_next = GST_STATE_NEXT (element);
2424   /* update current state */
2425   current = GST_STATE (element) = old_next;
2426
2427   /* see if we reached the final state */
2428   if (pending == current)
2429     goto complete;
2430
2431   next = GST_STATE_GET_NEXT (current, pending);
2432   transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2433
2434   GST_STATE_NEXT (element) = next;
2435   /* mark busy */
2436   GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2437   GST_OBJECT_UNLOCK (element);
2438
2439   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2440       "committing state from %s to %s, pending %s, next %s",
2441       gst_element_state_get_name (old_state),
2442       gst_element_state_get_name (old_next),
2443       gst_element_state_get_name (pending), gst_element_state_get_name (next));
2444
2445   _priv_gst_element_state_changed (element, old_state, old_next, pending);
2446
2447   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2448       "continue state change %s to %s, final %s",
2449       gst_element_state_get_name (current),
2450       gst_element_state_get_name (next), gst_element_state_get_name (pending));
2451
2452   ret = gst_element_change_state (element, transition);
2453
2454   return ret;
2455
2456 nothing_pending:
2457   {
2458     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
2459     GST_OBJECT_UNLOCK (element);
2460     return ret;
2461   }
2462 complete:
2463   {
2464     GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2465     GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
2466
2467     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2468         "completed state change to %s", gst_element_state_get_name (pending));
2469     GST_OBJECT_UNLOCK (element);
2470
2471     /* don't post silly messages with the same state. This can happen
2472      * when an element state is changed to what it already was. For bins
2473      * this can be the result of a lost state, which we check with the
2474      * previous return value.
2475      * We do signal the cond though as a _get_state() might be blocking
2476      * on it. */
2477     if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC)
2478       _priv_gst_element_state_changed (element, old_state, old_next,
2479           GST_STATE_VOID_PENDING);
2480
2481     GST_STATE_BROADCAST (element);
2482
2483     return ret;
2484   }
2485 }
2486
2487 /**
2488  * gst_element_lost_state_full:
2489  * @element: a #GstElement the state is lost of
2490  * @new_base_time: if a new base time should be distributed
2491  *
2492  * Brings the element to the lost state. The current state of the
2493  * element is copied to the pending state so that any call to
2494  * gst_element_get_state() will return %GST_STATE_CHANGE_ASYNC.
2495  *
2496  * An ASYNC_START message is posted with indication to distribute a new
2497  * base_time to the element when @new_base_time is %TRUE.
2498  * If the element was PLAYING, it will go to PAUSED. The element
2499  * will be restored to its PLAYING state by the parent pipeline when it
2500  * prerolls again.
2501  *
2502  * This is mostly used for elements that lost their preroll buffer
2503  * in the %GST_STATE_PAUSED or %GST_STATE_PLAYING state after a flush,
2504  * they will go to their pending state again when a new preroll buffer is
2505  * queued. This function can only be called when the element is currently
2506  * not in error or an async state change.
2507  *
2508  * This function is used internally and should normally not be called from
2509  * plugins or applications.
2510  *
2511  * MT safe.
2512  *
2513  * Since: 0.10.24
2514  */
2515 void
2516 gst_element_lost_state_full (GstElement * element, gboolean new_base_time)
2517 {
2518   GstState old_state, new_state;
2519   GstMessage *message;
2520
2521   g_return_if_fail (GST_IS_ELEMENT (element));
2522
2523   GST_OBJECT_LOCK (element);
2524   if (GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
2525     goto nothing_lost;
2526
2527   if (GST_STATE_PENDING (element) != GST_STATE_VOID_PENDING)
2528     goto only_async_start;
2529
2530   old_state = GST_STATE (element);
2531
2532   /* when we were PLAYING, the new state is PAUSED. We will also not
2533    * automatically go to PLAYING but let the parent bin(s) set us to PLAYING
2534    * when we preroll. */
2535   if (old_state > GST_STATE_PAUSED)
2536     new_state = GST_STATE_PAUSED;
2537   else
2538     new_state = old_state;
2539
2540   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2541       "lost state of %s to %s", gst_element_state_get_name (old_state),
2542       gst_element_state_get_name (new_state));
2543
2544   GST_STATE (element) = new_state;
2545   GST_STATE_NEXT (element) = new_state;
2546   GST_STATE_PENDING (element) = new_state;
2547   GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2548   if (new_base_time)
2549     GST_ELEMENT_START_TIME (element) = 0;
2550   GST_OBJECT_UNLOCK (element);
2551
2552   _priv_gst_element_state_changed (element, new_state, new_state, new_state);
2553
2554   message =
2555       gst_message_new_async_start (GST_OBJECT_CAST (element), new_base_time);
2556   gst_element_post_message (element, message);
2557
2558   return;
2559
2560 nothing_lost:
2561   {
2562     GST_OBJECT_UNLOCK (element);
2563     return;
2564   }
2565 only_async_start:
2566   {
2567     GST_OBJECT_UNLOCK (element);
2568
2569     message = gst_message_new_async_start (GST_OBJECT_CAST (element), TRUE);
2570     gst_element_post_message (element, message);
2571     return;
2572   }
2573 }
2574
2575 /**
2576  * gst_element_lost_state:
2577  * @element: a #GstElement the state is lost of
2578  *
2579  * Brings the element to the lost state. This function calls
2580  * gst_element_lost_state_full() with the new_base_time set to %TRUE.
2581  *
2582  * This function is used internally and should normally not be called from
2583  * plugins or applications.
2584  *
2585  * MT safe.
2586  */
2587 void
2588 gst_element_lost_state (GstElement * element)
2589 {
2590   gst_element_lost_state_full (element, TRUE);
2591 }
2592
2593 /**
2594  * gst_element_set_state:
2595  * @element: a #GstElement to change state of.
2596  * @state: the element's new #GstState.
2597  *
2598  * Sets the state of the element. This function will try to set the
2599  * requested state by going through all the intermediary states and calling
2600  * the class's state change function for each.
2601  *
2602  * This function can return #GST_STATE_CHANGE_ASYNC, in which case the
2603  * element will perform the remainder of the state change asynchronously in
2604  * another thread.
2605  * An application can use gst_element_get_state() to wait for the completion
2606  * of the state change or it can wait for a state change message on the bus.
2607  *
2608  * State changes to %GST_STATE_READY or %GST_STATE_NULL never return
2609  * #GST_STATE_CHANGE_ASYNC.
2610  *
2611  * Returns: Result of the state change using #GstStateChangeReturn.
2612  *
2613  * MT safe.
2614  */
2615 GstStateChangeReturn
2616 gst_element_set_state (GstElement * element, GstState state)
2617 {
2618   GstElementClass *oclass;
2619   GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
2620
2621   unsigned char szDebugMsg[256];
2622
2623   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2624
2625   sprintf(szDebugMsg, "set %s state %s to %s", GST_ELEMENT_NAME (element),  gst_element_state_get_name(GST_STATE (element)), gst_element_state_get_name(state) );
2626   MMTA_ACUM_ITEM_BEGIN(szDebugMsg, FALSE);
2627
2628   oclass = GST_ELEMENT_GET_CLASS (element);
2629
2630   if (oclass->set_state)
2631     result = (oclass->set_state) (element, state);
2632
2633   MMTA_ACUM_ITEM_END(szDebugMsg, FALSE);
2634
2635   return result;
2636 }
2637
2638 /*
2639  * default set state function, calculates the next state based
2640  * on current state and calls the change_state function
2641  */
2642 static GstStateChangeReturn
2643 gst_element_set_state_func (GstElement * element, GstState state)
2644 {
2645   GstState current, next, old_pending;
2646   GstStateChangeReturn ret;
2647   GstStateChange transition;
2648   GstStateChangeReturn old_ret;
2649
2650   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2651
2652   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "set_state to %s",
2653       gst_element_state_get_name (state));
2654
2655   /* state lock is taken to protect the set_state() and get_state()
2656    * procedures, it does not lock any variables. */
2657   GST_STATE_LOCK (element);
2658
2659   /* now calculate how to get to the new state */
2660   GST_OBJECT_LOCK (element);
2661   old_ret = GST_STATE_RETURN (element);
2662   /* previous state change returned an error, remove all pending
2663    * and next states */
2664   if (old_ret == GST_STATE_CHANGE_FAILURE) {
2665     GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
2666     GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2667     GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
2668   }
2669
2670   current = GST_STATE (element);
2671   next = GST_STATE_NEXT (element);
2672   old_pending = GST_STATE_PENDING (element);
2673
2674   /* this is the (new) state we should go to. TARGET is the last state we set on
2675    * the element. */
2676   if (state != GST_STATE_TARGET (element)) {
2677     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2678         "setting target state to %s", gst_element_state_get_name (state));
2679     GST_STATE_TARGET (element) = state;
2680     /* increment state cookie so that we can track each state change. We only do
2681      * this if this is actually a new state change. */
2682     element->state_cookie++;
2683   }
2684   GST_STATE_PENDING (element) = state;
2685
2686   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2687       "current %s, old_pending %s, next %s, old return %s",
2688       gst_element_state_get_name (current),
2689       gst_element_state_get_name (old_pending),
2690       gst_element_state_get_name (next),
2691       gst_element_state_change_return_get_name (old_ret));
2692
2693   /* if the element was busy doing a state change, we just update the
2694    * target state, it'll get to it async then. */
2695   if (old_pending != GST_STATE_VOID_PENDING) {
2696     /* upwards state change will happen ASYNC */
2697     if (old_pending <= state)
2698       goto was_busy;
2699     /* element is going to this state already */
2700     else if (next == state)
2701       goto was_busy;
2702     /* element was performing an ASYNC upward state change and
2703      * we request to go downward again. Start from the next pending
2704      * state then. */
2705     else if (next > state
2706         && GST_STATE_RETURN (element) == GST_STATE_CHANGE_ASYNC) {
2707       current = next;
2708     }
2709   }
2710   next = GST_STATE_GET_NEXT (current, state);
2711   /* now we store the next state */
2712   GST_STATE_NEXT (element) = next;
2713   /* mark busy, we need to check that there is actually a state change
2714    * to be done else we could accidentally override SUCCESS/NO_PREROLL and
2715    * the default element change_state function has no way to know what the
2716    * old value was... could consider this a FIXME...*/
2717   if (current != next)
2718     GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2719
2720   transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2721
2722   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2723       "%s: setting state from %s to %s",
2724       (next != state ? "intermediate" : "final"),
2725       gst_element_state_get_name (current), gst_element_state_get_name (next));
2726
2727   /* now signal any waiters, they will error since the cookie was incremented */
2728   GST_STATE_BROADCAST (element);
2729
2730   GST_OBJECT_UNLOCK (element);
2731
2732   ret = gst_element_change_state (element, transition);
2733
2734   GST_STATE_UNLOCK (element);
2735
2736   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "returned %s",
2737       gst_element_state_change_return_get_name (ret));
2738
2739   return ret;
2740
2741 was_busy:
2742   {
2743     GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2744     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2745         "element was busy with async state change");
2746     GST_OBJECT_UNLOCK (element);
2747
2748     GST_STATE_UNLOCK (element);
2749
2750     return GST_STATE_CHANGE_ASYNC;
2751   }
2752 }
2753
2754 /**
2755  * gst_element_change_state:
2756  * @element: a #GstElement
2757  * @transition: the requested transition
2758  *
2759  * Perform @transition on @element.
2760  *
2761  * This function must be called with STATE_LOCK held and is mainly used
2762  * internally.
2763  *
2764  * Returns: the #GstStateChangeReturn of the state transition.
2765  */
2766 GstStateChangeReturn
2767 gst_element_change_state (GstElement * element, GstStateChange transition)
2768 {
2769   GstElementClass *oclass;
2770   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2771
2772   oclass = GST_ELEMENT_GET_CLASS (element);
2773
2774   /* call the state change function so it can set the state */
2775   if (oclass->change_state)
2776     ret = (oclass->change_state) (element, transition);
2777   else
2778     ret = GST_STATE_CHANGE_FAILURE;
2779
2780   switch (ret) {
2781     case GST_STATE_CHANGE_FAILURE:
2782       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2783           "have FAILURE change_state return");
2784       /* state change failure */
2785       gst_element_abort_state (element);
2786       break;
2787     case GST_STATE_CHANGE_ASYNC:
2788     {
2789       GstState target;
2790
2791       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2792           "element will change state ASYNC");
2793
2794       target = GST_STATE_TARGET (element);
2795
2796       if (target > GST_STATE_READY)
2797         goto async;
2798
2799       /* else we just continue the state change downwards */
2800       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2801           "forcing commit state %s <= %s",
2802           gst_element_state_get_name (target),
2803           gst_element_state_get_name (GST_STATE_READY));
2804
2805       ret = gst_element_continue_state (element, GST_STATE_CHANGE_SUCCESS);
2806       break;
2807     }
2808     case GST_STATE_CHANGE_SUCCESS:
2809       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2810           "element changed state SUCCESS");
2811       /* we can commit the state now which will proceeed to
2812        * the next state */
2813       ret = gst_element_continue_state (element, ret);
2814       break;
2815     case GST_STATE_CHANGE_NO_PREROLL:
2816       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2817           "element changed state NO_PREROLL");
2818       /* we can commit the state now which will proceeed to
2819        * the next state */
2820       ret = gst_element_continue_state (element, ret);
2821       break;
2822     default:
2823       goto invalid_return;
2824   }
2825
2826   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit state change %d", ret);
2827
2828   return ret;
2829
2830 async:
2831   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit async state change %d",
2832       ret);
2833
2834   return ret;
2835
2836   /* ERROR */
2837 invalid_return:
2838   {
2839     GST_OBJECT_LOCK (element);
2840     /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2841     g_critical ("%s: unknown return value %d from a state change function",
2842         GST_ELEMENT_NAME (element), ret);
2843
2844     /* we are in error now */
2845     ret = GST_STATE_CHANGE_FAILURE;
2846     GST_STATE_RETURN (element) = ret;
2847     GST_OBJECT_UNLOCK (element);
2848
2849     return ret;
2850   }
2851 }
2852
2853 /* gst_iterator_fold functions for pads_activate
2854  * Stop the iterator if activating one pad failed. */
2855 static gboolean
2856 activate_pads (GstPad * pad, GValue * ret, gboolean * active)
2857 {
2858   gboolean cont = TRUE;
2859
2860   if (!(cont = gst_pad_set_active (pad, *active)))
2861     g_value_set_boolean (ret, FALSE);
2862
2863   /* unref the object that was reffed for us by _fold */
2864   gst_object_unref (pad);
2865   return cont;
2866 }
2867
2868 /* set the caps on the pad to NULL */
2869 static gboolean
2870 clear_caps (GstPad * pad, GValue * ret, gboolean * active)
2871 {
2872   gst_pad_set_caps (pad, NULL);
2873   gst_object_unref (pad);
2874   return TRUE;
2875 }
2876
2877 /* returns false on error or early cutout of the fold, true if all
2878  * pads in @iter were (de)activated successfully. */
2879 static gboolean
2880 iterator_activate_fold_with_resync (GstIterator * iter,
2881     GstIteratorFoldFunction func, gpointer user_data)
2882 {
2883   GstIteratorResult ires;
2884   GValue ret = { 0 };
2885
2886   /* no need to unset this later, it's just a boolean */
2887   g_value_init (&ret, G_TYPE_BOOLEAN);
2888   g_value_set_boolean (&ret, TRUE);
2889
2890   while (1) {
2891     ires = gst_iterator_fold (iter, func, &ret, user_data);
2892     switch (ires) {
2893       case GST_ITERATOR_RESYNC:
2894         /* need to reset the result again */
2895         g_value_set_boolean (&ret, TRUE);
2896         gst_iterator_resync (iter);
2897         break;
2898       case GST_ITERATOR_DONE:
2899         /* all pads iterated, return collected value */
2900         goto done;
2901       default:
2902         /* iterator returned _ERROR or premature end with _OK,
2903          * mark an error and exit */
2904         g_value_set_boolean (&ret, FALSE);
2905         goto done;
2906     }
2907   }
2908 done:
2909   /* return collected value */
2910   return g_value_get_boolean (&ret);
2911 }
2912
2913 /* is called with STATE_LOCK
2914  *
2915  * Pads are activated from source pads to sinkpads.
2916  */
2917 static gboolean
2918 gst_element_pads_activate (GstElement * element, gboolean active)
2919 {
2920   GstIterator *iter;
2921   gboolean res;
2922
2923   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2924       "pads_activate with active %d", active);
2925
2926   iter = gst_element_iterate_src_pads (element);
2927   res =
2928       iterator_activate_fold_with_resync (iter,
2929       (GstIteratorFoldFunction) activate_pads, &active);
2930   gst_iterator_free (iter);
2931   if (G_UNLIKELY (!res))
2932     goto src_failed;
2933
2934   iter = gst_element_iterate_sink_pads (element);
2935   res =
2936       iterator_activate_fold_with_resync (iter,
2937       (GstIteratorFoldFunction) activate_pads, &active);
2938   gst_iterator_free (iter);
2939   if (G_UNLIKELY (!res))
2940     goto sink_failed;
2941
2942   if (!active) {
2943     /* clear the caps on all pads, this should never fail */
2944     iter = gst_element_iterate_pads (element);
2945     res =
2946         iterator_activate_fold_with_resync (iter,
2947         (GstIteratorFoldFunction) clear_caps, &active);
2948     gst_iterator_free (iter);
2949     if (G_UNLIKELY (!res))
2950       goto caps_failed;
2951   }
2952
2953   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2954       "pads_activate successful");
2955
2956   return TRUE;
2957
2958   /* ERRORS */
2959 src_failed:
2960   {
2961     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2962         "source pads_activate failed");
2963     return FALSE;
2964   }
2965 sink_failed:
2966   {
2967     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2968         "sink pads_activate failed");
2969     return FALSE;
2970   }
2971 caps_failed:
2972   {
2973     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2974         "failed to clear caps on pads");
2975     return FALSE;
2976   }
2977 }
2978
2979 /* is called with STATE_LOCK */
2980 static GstStateChangeReturn
2981 gst_element_change_state_func (GstElement * element, GstStateChange transition)
2982 {
2983   GstState state, next;
2984   GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
2985   GstClock **clock_p;
2986
2987   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2988
2989   state = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
2990   next = GST_STATE_TRANSITION_NEXT (transition);
2991
2992   /* if the element already is in the given state, we just return success */
2993   if (next == GST_STATE_VOID_PENDING || state == next)
2994     goto was_ok;
2995
2996   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2997       "default handler tries setting state from %s to %s (%04x)",
2998       gst_element_state_get_name (state),
2999       gst_element_state_get_name (next), transition);
3000
3001   switch (transition) {
3002     case GST_STATE_CHANGE_NULL_TO_READY:
3003       break;
3004     case GST_STATE_CHANGE_READY_TO_PAUSED:
3005       if (!gst_element_pads_activate (element, TRUE)) {
3006         result = GST_STATE_CHANGE_FAILURE;
3007       }
3008       break;
3009     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
3010       break;
3011     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
3012       break;
3013     case GST_STATE_CHANGE_PAUSED_TO_READY:
3014     case GST_STATE_CHANGE_READY_TO_NULL:
3015       /* deactivate pads in both cases, since they are activated on
3016          ready->paused but the element might not have made it to paused */
3017       if (!gst_element_pads_activate (element, FALSE)) {
3018         result = GST_STATE_CHANGE_FAILURE;
3019       } else {
3020         gst_element_set_base_time (element, 0);
3021       }
3022
3023       /* In null state release the reference to the clock */
3024       GST_OBJECT_LOCK (element);
3025       clock_p = &element->clock;
3026       gst_object_replace ((GstObject **) clock_p, NULL);
3027       GST_OBJECT_UNLOCK (element);
3028       break;
3029     default:
3030       /* this will catch real but unhandled state changes;
3031        * can only be caused by:
3032        * - a new state was added
3033        * - somehow the element was asked to jump across an intermediate state
3034        */
3035       g_warning ("Unhandled state change from %s to %s",
3036           gst_element_state_get_name (state),
3037           gst_element_state_get_name (next));
3038       break;
3039   }
3040   return result;
3041
3042 was_ok:
3043   {
3044     GST_OBJECT_LOCK (element);
3045     result = GST_STATE_RETURN (element);
3046     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
3047         "element is already in the %s state",
3048         gst_element_state_get_name (state));
3049     GST_OBJECT_UNLOCK (element);
3050
3051     return result;
3052   }
3053 }
3054
3055 /**
3056  * gst_element_get_factory:
3057  * @element: a #GstElement to request the element factory of.
3058  *
3059  * Retrieves the factory that was used to create this element.
3060  *
3061  * Returns: (transfer none): the #GstElementFactory used for creating this
3062  *     element. no refcounting is needed.
3063  */
3064 GstElementFactory *
3065 gst_element_get_factory (GstElement * element)
3066 {
3067   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3068
3069   return GST_ELEMENT_GET_CLASS (element)->elementfactory;
3070 }
3071
3072 static void
3073 gst_element_dispose (GObject * object)
3074 {
3075   GstElement *element = GST_ELEMENT_CAST (object);
3076   GstClock **clock_p;
3077   GstBus **bus_p;
3078
3079   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
3080
3081   if (GST_STATE (element) != GST_STATE_NULL)
3082     goto not_null;
3083
3084   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
3085       "removing %d pads", g_list_length (element->pads));
3086   /* first we break all our links with the outside */
3087   while (element->pads && element->pads->data) {
3088     /* don't call _remove_pad with NULL */
3089     gst_element_remove_pad (element, GST_PAD_CAST (element->pads->data));
3090   }
3091   if (G_UNLIKELY (element->pads != NULL)) {
3092     g_critical ("could not remove pads from element %s",
3093         GST_STR_NULL (GST_OBJECT_NAME (object)));
3094   }
3095
3096   GST_OBJECT_LOCK (element);
3097   clock_p = &element->clock;
3098   bus_p = &element->bus;
3099   gst_object_replace ((GstObject **) clock_p, NULL);
3100   gst_object_replace ((GstObject **) bus_p, NULL);
3101   GST_OBJECT_UNLOCK (element);
3102
3103   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "parent class dispose");
3104
3105   G_OBJECT_CLASS (parent_class)->dispose (object);
3106
3107   return;
3108
3109   /* ERRORS */
3110 not_null:
3111   {
3112     gboolean is_locked;
3113
3114     is_locked = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
3115     g_critical
3116         ("\nTrying to dispose element %s, but it is in %s%s instead of the NULL"
3117         " state.\n"
3118         "You need to explicitly set elements to the NULL state before\n"
3119         "dropping the final reference, to allow them to clean up.\n"
3120         "This problem may also be caused by a refcounting bug in the\n"
3121         "application or some element.\n",
3122         GST_OBJECT_NAME (element),
3123         gst_element_state_get_name (GST_STATE (element)),
3124         is_locked ? " (locked)" : "");
3125     return;
3126   }
3127 }
3128
3129 static void
3130 gst_element_finalize (GObject * object)
3131 {
3132   GstElement *element = GST_ELEMENT_CAST (object);
3133
3134   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize");
3135
3136   GST_STATE_LOCK (element);
3137   if (element->state_cond)
3138     g_cond_free (element->state_cond);
3139   element->state_cond = NULL;
3140   GST_STATE_UNLOCK (element);
3141   g_static_rec_mutex_free (element->state_lock);
3142   g_slice_free (GStaticRecMutex, element->state_lock);
3143   element->state_lock = NULL;
3144
3145   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize parent");
3146
3147   G_OBJECT_CLASS (parent_class)->finalize (object);
3148 }
3149
3150 #if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
3151 /**
3152  * gst_element_save_thyself:
3153  * @element: a #GstElement to save.
3154  * @parent: the xml parent node.
3155  *
3156  * Saves the element as part of the given XML structure.
3157  *
3158  * Returns: the new #xmlNodePtr.
3159  */
3160 static xmlNodePtr
3161 gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
3162 {
3163   GList *pads;
3164   GstElementClass *oclass;
3165   GParamSpec **specs, *spec;
3166   guint nspecs;
3167   guint i;
3168   GValue value = { 0, };
3169   GstElement *element;
3170
3171   g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
3172
3173   element = GST_ELEMENT_CAST (object);
3174
3175   oclass = GST_ELEMENT_GET_CLASS (element);
3176
3177   xmlNewChild (parent, NULL, (xmlChar *) "name",
3178       (xmlChar *) GST_ELEMENT_NAME (element));
3179
3180   if (oclass->elementfactory != NULL) {
3181     GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
3182
3183     xmlNewChild (parent, NULL, (xmlChar *) "type",
3184         (xmlChar *) GST_PLUGIN_FEATURE (factory)->name);
3185   }
3186
3187   /* params */
3188   specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
3189
3190   for (i = 0; i < nspecs; i++) {
3191     spec = specs[i];
3192     if (spec->flags & G_PARAM_READABLE) {
3193       xmlNodePtr param;
3194       char *contents;
3195
3196       g_value_init (&value, spec->value_type);
3197
3198       g_object_get_property (G_OBJECT (element), spec->name, &value);
3199       param = xmlNewChild (parent, NULL, (xmlChar *) "param", NULL);
3200       xmlNewChild (param, NULL, (xmlChar *) "name", (xmlChar *) spec->name);
3201
3202       if (G_IS_PARAM_SPEC_STRING (spec))
3203         contents = g_value_dup_string (&value);
3204       else if (G_IS_PARAM_SPEC_ENUM (spec))
3205         contents = g_strdup_printf ("%d", g_value_get_enum (&value));
3206       else if (G_IS_PARAM_SPEC_INT64 (spec))
3207         contents = g_strdup_printf ("%" G_GINT64_FORMAT,
3208             g_value_get_int64 (&value));
3209       else if (GST_VALUE_HOLDS_STRUCTURE (&value)) {
3210         if (g_value_get_boxed (&value) != NULL) {
3211           contents = g_strdup_value_contents (&value);
3212         } else {
3213           contents = g_strdup ("NULL");
3214         }
3215       } else
3216         contents = g_strdup_value_contents (&value);
3217
3218       xmlNewChild (param, NULL, (xmlChar *) "value", (xmlChar *) contents);
3219       g_free (contents);
3220
3221       g_value_unset (&value);
3222     }
3223   }
3224
3225   g_free (specs);
3226
3227   pads = g_list_last (GST_ELEMENT_PADS (element));
3228
3229   while (pads) {
3230     GstPad *pad = GST_PAD_CAST (pads->data);
3231
3232     /* figure out if it's a direct pad or a ghostpad */
3233     if (GST_ELEMENT_CAST (GST_OBJECT_PARENT (pad)) == element) {
3234       xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL);
3235
3236       gst_object_save_thyself (GST_OBJECT_CAST (pad), padtag);
3237     }
3238     pads = g_list_previous (pads);
3239   }
3240
3241   return parent;
3242 }
3243
3244 static void
3245 gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
3246 {
3247   xmlNodePtr children;
3248   GstElement *element;
3249   gchar *name = NULL;
3250   gchar *value = NULL;
3251
3252   element = GST_ELEMENT_CAST (object);
3253   g_return_if_fail (element != NULL);
3254
3255   /* parameters */
3256   children = self->xmlChildrenNode;
3257   while (children) {
3258     if (!strcmp ((char *) children->name, "param")) {
3259       xmlNodePtr child = children->xmlChildrenNode;
3260
3261       while (child) {
3262         if (!strcmp ((char *) child->name, "name")) {
3263           name = (gchar *) xmlNodeGetContent (child);
3264         } else if (!strcmp ((char *) child->name, "value")) {
3265           value = (gchar *) xmlNodeGetContent (child);
3266         }
3267         child = child->next;
3268       }
3269       /* FIXME: can this just be g_object_set ? */
3270       gst_util_set_object_arg (G_OBJECT (element), name, value);
3271       /* g_object_set (G_OBJECT (element), name, value, NULL); */
3272       g_free (name);
3273       g_free (value);
3274     }
3275     children = children->next;
3276   }
3277
3278   /* pads */
3279   children = self->xmlChildrenNode;
3280   while (children) {
3281     if (!strcmp ((char *) children->name, "pad")) {
3282       gst_pad_load_and_link (children, GST_OBJECT_CAST (element));
3283     }
3284     children = children->next;
3285   }
3286
3287   if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
3288     (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
3289 }
3290 #endif /* GST_DISABLE_LOADSAVE */
3291
3292 static void
3293 gst_element_set_bus_func (GstElement * element, GstBus * bus)
3294 {
3295   GstBus **bus_p;
3296
3297   g_return_if_fail (GST_IS_ELEMENT (element));
3298
3299   GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
3300
3301   GST_OBJECT_LOCK (element);
3302   bus_p = &GST_ELEMENT_BUS (element);
3303   gst_object_replace ((GstObject **) bus_p, GST_OBJECT_CAST (bus));
3304   GST_OBJECT_UNLOCK (element);
3305 }
3306
3307 /**
3308  * gst_element_set_bus:
3309  * @element: a #GstElement to set the bus of.
3310  * @bus: (transfer none): the #GstBus to set.
3311  *
3312  * Sets the bus of the element. Increases the refcount on the bus.
3313  * For internal use only, unless you're testing elements.
3314  *
3315  * MT safe.
3316  */
3317 void
3318 gst_element_set_bus (GstElement * element, GstBus * bus)
3319 {
3320   GstElementClass *oclass;
3321
3322   g_return_if_fail (GST_IS_ELEMENT (element));
3323
3324   oclass = GST_ELEMENT_GET_CLASS (element);
3325
3326   if (oclass->set_bus)
3327     oclass->set_bus (element, bus);
3328 }
3329
3330 /**
3331  * gst_element_get_bus:
3332  * @element: a #GstElement to get the bus of.
3333  *
3334  * Returns the bus of the element. Note that only a #GstPipeline will provide a
3335  * bus for the application.
3336  *
3337  * Returns: (transfer full): the element's #GstBus. unref after usage.
3338  *
3339  * MT safe.
3340  */
3341 GstBus *
3342 gst_element_get_bus (GstElement * element)
3343 {
3344   GstBus *result = NULL;
3345
3346   g_return_val_if_fail (GST_IS_ELEMENT (element), result);
3347
3348   GST_OBJECT_LOCK (element);
3349   if ((result = GST_ELEMENT_BUS (element)))
3350     gst_object_ref (result);
3351   GST_OBJECT_UNLOCK (element);
3352
3353   GST_CAT_DEBUG_OBJECT (GST_CAT_BUS, element, "got bus %" GST_PTR_FORMAT,
3354       result);
3355
3356   return result;
3357 }