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