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