gstelement: add gst_element_class_add_pad_template_from_static
[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 /**
1335  * gst_element_class_add_static_pad_template:
1336  * @klass: the #GstElementClass to add the pad template to.
1337  * @templ: (transfer none): a #GstStaticPadTemplate describing the pad
1338  * to add to the element class.
1339  *
1340  * Adds a padtemplate to an element class. This is mainly used in the _base_init
1341  * functions of classes.
1342  *
1343  * Since: 0.10.36
1344  */
1345 void
1346 gst_element_class_add_static_pad_template (GstElementClass * klass,
1347     GstStaticPadTemplate * templ)
1349   GstPadTemplate *pt;
1351   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1353   pt = gst_static_pad_template_get (templ);
1354   gst_element_class_add_pad_template (klass, pt);
1355   gst_object_unref (pt);
1358 static void
1359 gst_element_class_add_meta_data (GstElementClass * klass,
1360     const gchar * key, const gchar * value)
1362   if (!klass->meta_data) {
1363     /* FIXME: use a quark for "metadata" */
1364     klass->meta_data = gst_structure_empty_new ("metadata");
1365   }
1367   gst_structure_set ((GstStructure *) klass->meta_data,
1368       key, G_TYPE_STRING, value, NULL);
1371 /**
1372  * gst_element_class_set_documentation_uri:
1373  * @klass: class to set details for
1374  * @uri: uri of element documentation
1375  *
1376  * Set uri pointing to user documentation. Applications can use this to show
1377  * help for e.g. effects to users.
1378  *
1379  * Since: 0.10.31
1380  */
1381 void
1382 gst_element_class_set_documentation_uri (GstElementClass * klass,
1383     const gchar * uri)
1385   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1387   gst_element_class_add_meta_data (klass, "doc-uri", uri);
1390 /**
1391  * gst_element_class_set_icon_name:
1392  * @klass: class to set details for
1393  * @name: name of an icon
1394  *
1395  * Elements that bridge to certain other products can include an icon of that
1396  * used product. Application can show the icon in menus/selectors to help
1397  * identifying specific elements.
1398  *
1399  * Since: 0.10.31
1400  */
1401 void
1402 gst_element_class_set_icon_name (GstElementClass * klass, const gchar * name)
1404   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1406   gst_element_class_add_meta_data (klass, "icon-name", name);
1409 /* FIXME-0.11: deprecate and remove gst_element_class_set_details*() */
1410 /**
1411  * gst_element_class_set_details:
1412  * @klass: class to set details for
1413  * @details: details to set
1414  *
1415  * Sets the detailed information for a #GstElementClass.
1416  * <note>This function is for use in _base_init functions only.</note>
1417  *
1418  * The @details are copied.
1419  *
1420  * Deprecated: Use gst_element_class_set_details_simple() instead.
1421  */
1422 #ifndef GST_REMOVE_DEPRECATED
1423 #ifdef GST_DISABLE_DEPRECATED
1424 void gst_element_class_set_details (GstElementClass * klass,
1425     const GstElementDetails * details);
1426 #endif
1427 void
1428 gst_element_class_set_details (GstElementClass * klass,
1429     const GstElementDetails * details)
1431   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1432   g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
1434   __gst_element_details_copy (&klass->details, details);
1436 #endif
1438 /**
1439  * gst_element_class_set_details_simple:
1440  * @klass: class to set details for
1441  * @longname: The long English name of the element. E.g. "File Sink"
1442  * @classification: String describing the type of element, as an unordered list
1443  * separated with slashes ('/'). See draft-klass.txt of the design docs
1444  * for more details and common types. E.g: "Sink/File"
1445  * @description: Sentence describing the purpose of the element.
1446  * E.g: "Write stream to a file"
1447  * @author: Name and contact details of the author(s). Use \n to separate
1448  * multiple author details. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
1449  *
1450  * Sets the detailed information for a #GstElementClass. Simpler version of
1451  * gst_element_class_set_details() that generates less linker overhead.
1452  * <note>This function is for use in _base_init functions only.</note>
1453  *
1454  * The detail parameter strings are copied into the #GstElementDetails for
1455  * the element class.
1456  *
1457  * Since: 0.10.14
1458  */
1459 void
1460 gst_element_class_set_details_simple (GstElementClass * klass,
1461     const gchar * longname, const gchar * classification,
1462     const gchar * description, const gchar * author)
1464   const GstElementDetails details =
1465       GST_ELEMENT_DETAILS ((gchar *) longname, (gchar *) classification,
1466       (gchar *) description, (gchar *) author);
1468   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1470   __gst_element_details_copy (&klass->details, &details);
1473 /**
1474  * gst_element_class_get_pad_template_list:
1475  * @element_class: a #GstElementClass to get pad templates of.
1476  *
1477  * Retrieves a list of the pad templates associated with @element_class. The
1478  * list must not be modified by the calling code.
1479  * <note>If you use this function in the #GInstanceInitFunc of an object class
1480  * that has subclasses, make sure to pass the g_class parameter of the
1481  * #GInstanceInitFunc here.</note>
1482  *
1483  * Returns: (transfer none) (element-type Gst.PadTemplate): the #GList of
1484  *     pad templates.
1485  */
1486 GList *
1487 gst_element_class_get_pad_template_list (GstElementClass * element_class)
1489   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1491   return element_class->padtemplates;
1494 /**
1495  * gst_element_class_get_pad_template:
1496  * @element_class: a #GstElementClass to get the pad template of.
1497  * @name: the name of the #GstPadTemplate to get.
1498  *
1499  * Retrieves a padtemplate from @element_class with the given name.
1500  * <note>If you use this function in the #GInstanceInitFunc of an object class
1501  * that has subclasses, make sure to pass the g_class parameter of the
1502  * #GInstanceInitFunc here.</note>
1503  *
1504  * Returns: (transfer none): the #GstPadTemplate with the given name, or %NULL
1505  *     if none was found. No unreferencing is necessary.
1506  */
1507 GstPadTemplate *
1508 gst_element_class_get_pad_template (GstElementClass *
1509     element_class, const gchar * name)
1511   GList *padlist;
1513   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1514   g_return_val_if_fail (name != NULL, NULL);
1516   padlist = element_class->padtemplates;
1518   while (padlist) {
1519     GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1521     if (strcmp (padtempl->name_template, name) == 0)
1522       return padtempl;
1524     padlist = g_list_next (padlist);
1525   }
1527   return NULL;
1530 static GstPadTemplate *
1531 gst_element_class_get_request_pad_template (GstElementClass *
1532     element_class, const gchar * name)
1534   GstPadTemplate *tmpl;
1536   tmpl = gst_element_class_get_pad_template (element_class, name);
1537   if (tmpl != NULL && tmpl->presence == GST_PAD_REQUEST)
1538     return tmpl;
1540   return NULL;
1543 /* get a random pad on element of the given direction.
1544  * The pad is random in a sense that it is the first pad that is (optionaly) linked.
1545  */
1546 static GstPad *
1547 gst_element_get_random_pad (GstElement * element,
1548     gboolean need_linked, GstPadDirection dir)
1550   GstPad *result = NULL;
1551   GList *pads;
1553   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
1555   switch (dir) {
1556     case GST_PAD_SRC:
1557       GST_OBJECT_LOCK (element);
1558       pads = element->srcpads;
1559       break;
1560     case GST_PAD_SINK:
1561       GST_OBJECT_LOCK (element);
1562       pads = element->sinkpads;
1563       break;
1564     default:
1565       goto wrong_direction;
1566   }
1567   for (; pads; pads = g_list_next (pads)) {
1568     GstPad *pad = GST_PAD_CAST (pads->data);
1570     GST_OBJECT_LOCK (pad);
1571     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
1572         GST_DEBUG_PAD_NAME (pad));
1574     if (need_linked && !GST_PAD_IS_LINKED (pad)) {
1575       /* if we require a linked pad, and it is not linked, continue the
1576        * search */
1577       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
1578           GST_DEBUG_PAD_NAME (pad));
1579       GST_OBJECT_UNLOCK (pad);
1580       continue;
1581     } else {
1582       /* found a pad, stop search */
1583       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
1584           GST_DEBUG_PAD_NAME (pad));
1585       GST_OBJECT_UNLOCK (pad);
1586       result = pad;
1587       break;
1588     }
1589   }
1590   if (result)
1591     gst_object_ref (result);
1593   GST_OBJECT_UNLOCK (element);
1595   return result;
1597   /* ERROR handling */
1598 wrong_direction:
1599   {
1600     g_warning ("unknown pad direction %d", dir);
1601     return NULL;
1602   }
1605 static gboolean
1606 gst_element_default_send_event (GstElement * element, GstEvent * event)
1608   gboolean result = FALSE;
1609   GstPad *pad;
1611   pad = GST_EVENT_IS_DOWNSTREAM (event) ?
1612       gst_element_get_random_pad (element, TRUE, GST_PAD_SRC) :
1613       gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
1615   if (pad) {
1616     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1617         "pushing %s event to random %s pad %s:%s",
1618         GST_EVENT_TYPE_NAME (event),
1619         (GST_PAD_DIRECTION (pad) == GST_PAD_SRC ? "src" : "sink"),
1620         GST_DEBUG_PAD_NAME (pad));
1622     result = gst_pad_push_event (pad, event);
1623     gst_object_unref (pad);
1624   } else {
1625     GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "can't send %s event on element %s",
1626         GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
1627     gst_event_unref (event);
1628   }
1629   return result;
1632 /**
1633  * gst_element_send_event:
1634  * @element: a #GstElement to send the event to.
1635  * @event: (transfer full): the #GstEvent to send to the element.
1636  *
1637  * Sends an event to an element. If the element doesn't implement an
1638  * event handler, the event will be pushed on a random linked sink pad for
1639  * upstream events or a random linked source pad for downstream events.
1640  *
1641  * This function takes owership of the provided event so you should
1642  * gst_event_ref() it if you want to reuse the event after this call.
1643  *
1644  * Returns: %TRUE if the event was handled.
1645  *
1646  * MT safe.
1647  */
1648 gboolean
1649 gst_element_send_event (GstElement * element, GstEvent * event)
1651   GstElementClass *oclass;
1652   gboolean result = FALSE;
1654   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1655   g_return_val_if_fail (event != NULL, FALSE);
1657   oclass = GST_ELEMENT_GET_CLASS (element);
1659   GST_STATE_LOCK (element);
1660   if (oclass->send_event) {
1661     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send %s event on element %s",
1662         GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
1663     result = oclass->send_event (element, event);
1664   } else {
1665     result = gst_element_default_send_event (element, event);
1666   }
1667   GST_STATE_UNLOCK (element);
1669   return result;
1672 /**
1673  * gst_element_seek:
1674  * @element: a #GstElement to send the event to.
1675  * @rate: The new playback rate
1676  * @format: The format of the seek values
1677  * @flags: The optional seek flags.
1678  * @cur_type: The type and flags for the new current position
1679  * @cur: The value of the new current position
1680  * @stop_type: The type and flags for the new stop position
1681  * @stop: The value of the new stop position
1682  *
1683  * Sends a seek event to an element. See gst_event_new_seek() for the details of
1684  * the parameters. The seek event is sent to the element using
1685  * gst_element_send_event().
1686  *
1687  * Returns: %TRUE if the event was handled.
1688  *
1689  * MT safe.
1690  */
1691 gboolean
1692 gst_element_seek (GstElement * element, gdouble rate, GstFormat format,
1693     GstSeekFlags flags, GstSeekType cur_type, gint64 cur,
1694     GstSeekType stop_type, gint64 stop)
1696   GstEvent *event;
1697   gboolean result;
1699   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1701   event =
1702       gst_event_new_seek (rate, format, flags, cur_type, cur, stop_type, stop);
1703   result = gst_element_send_event (element, event);
1705   return result;
1708 /**
1709  * gst_element_get_query_types:
1710  * @element: a #GstElement to query
1711  *
1712  * Get an array of query types from the element.
1713  * If the element doesn't implement a query types function,
1714  * the query will be forwarded to the peer of a random linked sink pad.
1715  *
1716  * Returns: An array of #GstQueryType elements that should not
1717  * be freed or modified.
1718  *
1719  * MT safe.
1720  */
1721 const GstQueryType *
1722 gst_element_get_query_types (GstElement * element)
1724   GstElementClass *oclass;
1725   const GstQueryType *result = NULL;
1727   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1729   oclass = GST_ELEMENT_GET_CLASS (element);
1731   if (oclass->get_query_types) {
1732     result = oclass->get_query_types (element);
1733   } else {
1734     GstPad *pad = gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
1736     if (pad) {
1737       GstPad *peer = gst_pad_get_peer (pad);
1739       if (peer) {
1740         result = gst_pad_get_query_types (peer);
1742         gst_object_unref (peer);
1743       }
1744       gst_object_unref (pad);
1745     }
1746   }
1747   return result;
1750 static gboolean
1751 gst_element_default_query (GstElement * element, GstQuery * query)
1753   gboolean result = FALSE;
1754   GstPad *pad;
1756   pad = gst_element_get_random_pad (element, FALSE, GST_PAD_SRC);
1757   if (pad) {
1758     result = gst_pad_query (pad, query);
1760     gst_object_unref (pad);
1761   } else {
1762     pad = gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
1763     if (pad) {
1764       GstPad *peer = gst_pad_get_peer (pad);
1766       if (peer) {
1767         result = gst_pad_query (peer, query);
1769         gst_object_unref (peer);
1770       }
1771       gst_object_unref (pad);
1772     }
1773   }
1774   return result;
1777 /**
1778  * gst_element_query:
1779  * @element: a #GstElement to perform the query on.
1780  * @query: (transfer none): the #GstQuery.
1781  *
1782  * Performs a query on the given element.
1783  *
1784  * For elements that don't implement a query handler, this function
1785  * forwards the query to a random srcpad or to the peer of a
1786  * random linked sinkpad of this element.
1787  *
1788  * Please note that some queries might need a running pipeline to work.
1789  *
1790  * Returns: TRUE if the query could be performed.
1791  *
1792  * MT safe.
1793  */
1794 gboolean
1795 gst_element_query (GstElement * element, GstQuery * query)
1797   GstElementClass *oclass;
1798   gboolean result = FALSE;
1800   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1801   g_return_val_if_fail (query != NULL, FALSE);
1803   oclass = GST_ELEMENT_GET_CLASS (element);
1805   if (oclass->query) {
1806     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send query on element %s",
1807         GST_ELEMENT_NAME (element));
1808     result = oclass->query (element, query);
1809   } else {
1810     result = gst_element_default_query (element, query);
1811   }
1812   return result;
1815 /**
1816  * gst_element_post_message:
1817  * @element: a #GstElement posting the message
1818  * @message: (transfer full): a #GstMessage to post
1819  *
1820  * Post a message on the element's #GstBus. This function takes ownership of the
1821  * message; if you want to access the message after this call, you should add an
1822  * additional reference before calling.
1823  *
1824  * Returns: %TRUE if the message was successfully posted. The function returns
1825  * %FALSE if the element did not have a bus.
1826  *
1827  * MT safe.
1828  */
1829 gboolean
1830 gst_element_post_message (GstElement * element, GstMessage * message)
1832   GstBus *bus;
1833   gboolean result = FALSE;
1835   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1836   g_return_val_if_fail (message != NULL, FALSE);
1838   GST_OBJECT_LOCK (element);
1839   bus = element->bus;
1841   if (G_UNLIKELY (bus == NULL))
1842     goto no_bus;
1844   gst_object_ref (bus);
1845   GST_OBJECT_UNLOCK (element);
1847   /* we release the element lock when posting the message so that any
1848    * (synchronous) message handlers can operate on the element */
1849   result = gst_bus_post (bus, message);
1850   gst_object_unref (bus);
1852   return result;
1854   /* ERRORS */
1855 no_bus:
1856   {
1857     GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element,
1858         "not posting message %p: no bus", message);
1859     GST_OBJECT_UNLOCK (element);
1860     gst_message_unref (message);
1861     return FALSE;
1862   }
1865 /**
1866  * _gst_element_error_printf:
1867  * @format: the printf-like format to use, or %NULL
1868  *
1869  * This function is only used internally by the gst_element_error() macro.
1870  *
1871  * Returns: (transfer full): a newly allocated string, or %NULL if the format
1872  *     was %NULL or ""
1873  *
1874  * MT safe.
1875  */
1876 gchar *
1877 _gst_element_error_printf (const gchar * format, ...)
1879   va_list args;
1880   gchar *buffer;
1882   if (format == NULL)
1883     return NULL;
1884   if (format[0] == 0)
1885     return NULL;
1887   va_start (args, format);
1888   buffer = g_strdup_vprintf (format, args);
1889   va_end (args);
1890   return buffer;
1893 /**
1894  * gst_element_message_full:
1895  * @element:  a #GstElement to send message from
1896  * @type:     the #GstMessageType
1897  * @domain:   the GStreamer GError domain this message belongs to
1898  * @code:     the GError code belonging to the domain
1899  * @text:     (allow-none) (transfer full): an allocated text string to be used
1900  *            as a replacement for the default message connected to code,
1901  *            or %NULL
1902  * @debug:    (allow-none) (transfer full): an allocated debug message to be
1903  *            used as a replacement for the default debugging information,
1904  *            or %NULL
1905  * @file:     the source code file where the error was generated
1906  * @function: the source code function where the error was generated
1907  * @line:     the source code line where the error was generated
1908  *
1909  * Post an error, warning or info message on the bus from inside an element.
1910  *
1911  * @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
1912  * #GST_MESSAGE_INFO.
1913  *
1914  * MT safe.
1915  */
1916 void gst_element_message_full
1917     (GstElement * element, GstMessageType type,
1918     GQuark domain, gint code, gchar * text,
1919     gchar * debug, const gchar * file, const gchar * function, gint line)
1921   GError *gerror = NULL;
1922   gchar *name;
1923   gchar *sent_text;
1924   gchar *sent_debug;
1925   gboolean has_debug = TRUE;
1926   GstMessage *message = NULL;
1928   /* checks */
1929   GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element, "start");
1930   g_return_if_fail (GST_IS_ELEMENT (element));
1931   g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
1932       (type == GST_MESSAGE_WARNING) || (type == GST_MESSAGE_INFO));
1934   /* check if we send the given text or the default error text */
1935   if ((text == NULL) || (text[0] == 0)) {
1936     /* text could have come from g_strdup_printf (""); */
1937     g_free (text);
1938     sent_text = gst_error_get_message (domain, code);
1939   } else
1940     sent_text = text;
1942   /* construct a sent_debug with extra information from source */
1943   if ((debug == NULL) || (debug[0] == 0)) {
1944     /* debug could have come from g_strdup_printf (""); */
1945     has_debug = FALSE;
1946   }
1948   name = gst_object_get_path_string (GST_OBJECT_CAST (element));
1949   if (has_debug)
1950     sent_debug = g_strdup_printf ("%s(%d): %s (): %s:\n%s",
1951         file, line, function, name, debug);
1952   else
1953     sent_debug = g_strdup_printf ("%s(%d): %s (): %s",
1954         file, line, function, name);
1955   g_free (name);
1956   g_free (debug);
1958   /* create gerror and post message */
1959   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
1960       sent_text);
1961   gerror = g_error_new_literal (domain, code, sent_text);
1963   switch (type) {
1964     case GST_MESSAGE_ERROR:
1965       message =
1966           gst_message_new_error (GST_OBJECT_CAST (element), gerror, sent_debug);
1967       break;
1968     case GST_MESSAGE_WARNING:
1969       message = gst_message_new_warning (GST_OBJECT_CAST (element), gerror,
1970           sent_debug);
1971       break;
1972     case GST_MESSAGE_INFO:
1973       message = gst_message_new_info (GST_OBJECT_CAST (element), gerror,
1974           sent_debug);
1975       break;
1976     default:
1977       g_assert_not_reached ();
1978       break;
1979   }
1980   gst_element_post_message (element, message);
1982   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted %s message: %s",
1983       (type == GST_MESSAGE_ERROR ? "error" : "warning"), sent_text);
1985   /* cleanup */
1986   g_error_free (gerror);
1987   g_free (sent_debug);
1988   g_free (sent_text);
1991 /**
1992  * gst_element_is_locked_state:
1993  * @element: a #GstElement.
1994  *
1995  * Checks if the state of an element is locked.
1996  * If the state of an element is locked, state changes of the parent don't
1997  * affect the element.
1998  * This way you can leave currently unused elements inside bins. Just lock their
1999  * state before changing the state from #GST_STATE_NULL.
2000  *
2001  * MT safe.
2002  *
2003  * Returns: TRUE, if the element's state is locked.
2004  */
2005 gboolean
2006 gst_element_is_locked_state (GstElement * element)
2008   gboolean result;
2010   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2012   GST_OBJECT_LOCK (element);
2013   result = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
2014   GST_OBJECT_UNLOCK (element);
2016   return result;
2019 /**
2020  * gst_element_set_locked_state:
2021  * @element: a #GstElement
2022  * @locked_state: TRUE to lock the element's state
2023  *
2024  * Locks the state of an element, so state changes of the parent don't affect
2025  * this element anymore.
2026  *
2027  * MT safe.
2028  *
2029  * Returns: TRUE if the state was changed, FALSE if bad parameters were given
2030  * or the elements state-locking needed no change.
2031  */
2032 gboolean
2033 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
2035   gboolean old;
2037   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2039   GST_OBJECT_LOCK (element);
2040   old = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
2042   if (G_UNLIKELY (old == locked_state))
2043     goto was_ok;
2045   if (locked_state) {
2046     GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
2047         GST_ELEMENT_NAME (element));
2048     GST_OBJECT_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
2049   } else {
2050     GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
2051         GST_ELEMENT_NAME (element));
2052     GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
2053   }
2054   GST_OBJECT_UNLOCK (element);
2056   return TRUE;
2058 was_ok:
2059   {
2060     GST_CAT_DEBUG (GST_CAT_STATES,
2061         "elements %s was already in locked state %d",
2062         GST_ELEMENT_NAME (element), old);
2063     GST_OBJECT_UNLOCK (element);
2065     return FALSE;
2066   }
2069 /**
2070  * gst_element_sync_state_with_parent:
2071  * @element: a #GstElement.
2072  *
2073  * Tries to change the state of the element to the same as its parent.
2074  * If this function returns FALSE, the state of element is undefined.
2075  *
2076  * Returns: TRUE, if the element's state could be synced to the parent's state.
2077  *
2078  * MT safe.
2079  */
2080 gboolean
2081 gst_element_sync_state_with_parent (GstElement * element)
2083   GstElement *parent;
2084   GstState target;
2085   GstStateChangeReturn ret;
2087   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2089   if ((parent = GST_ELEMENT_CAST (gst_element_get_parent (element)))) {
2090     GstState parent_current, parent_pending;
2092     GST_OBJECT_LOCK (parent);
2093     parent_current = GST_STATE (parent);
2094     parent_pending = GST_STATE_PENDING (parent);
2095     GST_OBJECT_UNLOCK (parent);
2097     /* set to pending if there is one, else we set it to the current state of
2098      * the parent */
2099     if (parent_pending != GST_STATE_VOID_PENDING)
2100       target = parent_pending;
2101     else
2102       target = parent_current;
2104     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2105         "syncing state (%s) to parent %s %s (%s, %s)",
2106         gst_element_state_get_name (GST_STATE (element)),
2107         GST_ELEMENT_NAME (parent), gst_element_state_get_name (target),
2108         gst_element_state_get_name (parent_current),
2109         gst_element_state_get_name (parent_pending));
2111     ret = gst_element_set_state (element, target);
2112     if (ret == GST_STATE_CHANGE_FAILURE)
2113       goto failed;
2115     gst_object_unref (parent);
2117     return TRUE;
2118   } else {
2119     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "element has no parent");
2120   }
2121   return FALSE;
2123   /* ERROR */
2124 failed:
2125   {
2126     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2127         "syncing state failed (%s)",
2128         gst_element_state_change_return_get_name (ret));
2129     gst_object_unref (parent);
2130     return FALSE;
2131   }
2134 /* MT safe */
2135 static GstStateChangeReturn
2136 gst_element_get_state_func (GstElement * element,
2137     GstState * state, GstState * pending, GstClockTime timeout)
2139   GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
2140   GstState old_pending;
2142   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "getting state, timeout %"
2143       GST_TIME_FORMAT, GST_TIME_ARGS (timeout));
2145   GST_OBJECT_LOCK (element);
2146   ret = GST_STATE_RETURN (element);
2147   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "RETURN is %s",
2148       gst_element_state_change_return_get_name (ret));
2150   /* we got an error, report immediately */
2151   if (ret == GST_STATE_CHANGE_FAILURE)
2152     goto done;
2154   /* we got no_preroll, report immediately */
2155   if (ret == GST_STATE_CHANGE_NO_PREROLL)
2156     goto done;
2158   /* no need to wait async if we are not async */
2159   if (ret != GST_STATE_CHANGE_ASYNC)
2160     goto done;
2162   old_pending = GST_STATE_PENDING (element);
2163   if (old_pending != GST_STATE_VOID_PENDING) {
2164     GTimeVal *timeval, abstimeout;
2165     guint32 cookie;
2167     if (timeout != GST_CLOCK_TIME_NONE) {
2168       glong add = timeout / 1000;
2170       if (add == 0)
2171         goto done;
2173       /* make timeout absolute */
2174       g_get_current_time (&abstimeout);
2175       g_time_val_add (&abstimeout, add);
2176       timeval = &abstimeout;
2177     } else {
2178       timeval = NULL;
2179     }
2180     /* get cookie to detect state changes during waiting */
2181     cookie = element->state_cookie;
2183     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2184         "waiting for element to commit state");
2186     /* we have a pending state change, wait for it to complete */
2187     if (!GST_STATE_TIMED_WAIT (element, timeval)) {
2188       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timed out");
2189       /* timeout triggered */
2190       ret = GST_STATE_CHANGE_ASYNC;
2191     } else {
2192       if (cookie != element->state_cookie)
2193         goto interrupted;
2195       /* could be success or failure */
2196       if (old_pending == GST_STATE (element)) {
2197         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got success");
2198         ret = GST_STATE_CHANGE_SUCCESS;
2199       } else {
2200         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got failure");
2201         ret = GST_STATE_CHANGE_FAILURE;
2202       }
2203     }
2204     /* if nothing is pending anymore we can return SUCCESS */
2205     if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
2206       GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "nothing pending");
2207       ret = GST_STATE_CHANGE_SUCCESS;
2208     }
2209   }
2211 done:
2212   if (state)
2213     *state = GST_STATE (element);
2214   if (pending)
2215     *pending = GST_STATE_PENDING (element);
2217   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2218       "state current: %s, pending: %s, result: %s",
2219       gst_element_state_get_name (GST_STATE (element)),
2220       gst_element_state_get_name (GST_STATE_PENDING (element)),
2221       gst_element_state_change_return_get_name (ret));
2222   GST_OBJECT_UNLOCK (element);
2224   return ret;
2226 interrupted:
2227   {
2228     if (state)
2229       *state = GST_STATE_VOID_PENDING;
2230     if (pending)
2231       *pending = GST_STATE_VOID_PENDING;
2233     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "interruped");
2235     GST_OBJECT_UNLOCK (element);
2237     return GST_STATE_CHANGE_FAILURE;
2238   }
2241 /**
2242  * gst_element_get_state:
2243  * @element: a #GstElement to get the state of.
2244  * @state: (out) (allow-none): a pointer to #GstState to hold the state.
2245  *     Can be %NULL.
2246  * @pending: (out) (allow-none): a pointer to #GstState to hold the pending
2247  *     state. Can be %NULL.
2248  * @timeout: a #GstClockTime to specify the timeout for an async
2249  *           state change or %GST_CLOCK_TIME_NONE for infinite timeout.
2250  *
2251  * Gets the state of the element.
2252  *
2253  * For elements that performed an ASYNC state change, as reported by
2254  * gst_element_set_state(), this function will block up to the
2255  * specified timeout value for the state change to complete.
2256  * If the element completes the state change or goes into
2257  * an error, this function returns immediately with a return value of
2258  * %GST_STATE_CHANGE_SUCCESS or %GST_STATE_CHANGE_FAILURE respectively.
2259  *
2260  * For elements that did not return %GST_STATE_CHANGE_ASYNC, this function
2261  * returns the current and pending state immediately.
2262  *
2263  * This function returns %GST_STATE_CHANGE_NO_PREROLL if the element
2264  * successfully changed its state but is not able to provide data yet.
2265  * This mostly happens for live sources that only produce data in
2266  * %GST_STATE_PLAYING. While the state change return is equivalent to
2267  * %GST_STATE_CHANGE_SUCCESS, it is returned to the application to signal that
2268  * some sink elements might not be able to complete their state change because
2269  * an element is not producing data to complete the preroll. When setting the
2270  * element to playing, the preroll will complete and playback will start.
2271  *
2272  * Returns: %GST_STATE_CHANGE_SUCCESS if the element has no more pending state
2273  *          and the last state change succeeded, %GST_STATE_CHANGE_ASYNC if the
2274  *          element is still performing a state change or
2275  *          %GST_STATE_CHANGE_FAILURE if the last state change failed.
2276  *
2277  * MT safe.
2278  */
2279 GstStateChangeReturn
2280 gst_element_get_state (GstElement * element,
2281     GstState * state, GstState * pending, GstClockTime timeout)
2283   GstElementClass *oclass;
2284   GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
2286   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2288   oclass = GST_ELEMENT_GET_CLASS (element);
2290   if (oclass->get_state)
2291     result = (oclass->get_state) (element, state, pending, timeout);
2293   return result;
2296 /**
2297  * gst_element_abort_state:
2298  * @element: a #GstElement to abort the state of.
2299  *
2300  * Abort the state change of the element. This function is used
2301  * by elements that do asynchronous state changes and find out
2302  * something is wrong.
2303  *
2304  * This function should be called with the STATE_LOCK held.
2305  *
2306  * MT safe.
2307  */
2308 void
2309 gst_element_abort_state (GstElement * element)
2311   GstState pending;
2313 #ifndef GST_DISABLE_GST_DEBUG
2314   GstState old_state;
2315 #endif
2317   g_return_if_fail (GST_IS_ELEMENT (element));
2319   GST_OBJECT_LOCK (element);
2320   pending = GST_STATE_PENDING (element);
2322   if (pending == GST_STATE_VOID_PENDING ||
2323       GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
2324     goto nothing_aborted;
2326 #ifndef GST_DISABLE_GST_DEBUG
2327   old_state = GST_STATE (element);
2329   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2330       "aborting state from %s to %s", gst_element_state_get_name (old_state),
2331       gst_element_state_get_name (pending));
2332 #endif
2334   /* flag error */
2335   GST_STATE_RETURN (element) = GST_STATE_CHANGE_FAILURE;
2337   GST_STATE_BROADCAST (element);
2338   GST_OBJECT_UNLOCK (element);
2340   return;
2342 nothing_aborted:
2343   {
2344     GST_OBJECT_UNLOCK (element);
2345     return;
2346   }
2349 /* Not static because GstBin has manual state handling too */
2350 void
2351 _priv_gst_element_state_changed (GstElement * element, GstState oldstate,
2352     GstState newstate, GstState pending)
2354   GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
2355   GstMessage *message;
2357   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2358       "notifying about state-changed %s to %s (%s pending)",
2359       gst_element_state_get_name (oldstate),
2360       gst_element_state_get_name (newstate),
2361       gst_element_state_get_name (pending));
2363   if (klass->state_changed)
2364     klass->state_changed (element, oldstate, newstate, pending);
2366   message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
2367       oldstate, newstate, pending);
2368   gst_element_post_message (element, message);
2371 /**
2372  * gst_element_continue_state:
2373  * @element: a #GstElement to continue the state change of.
2374  * @ret: The previous state return value
2375  *
2376  * Commit the state change of the element and proceed to the next
2377  * pending state if any. This function is used
2378  * by elements that do asynchronous state changes.
2379  * The core will normally call this method automatically when an
2380  * element returned %GST_STATE_CHANGE_SUCCESS from the state change function.
2381  *
2382  * If after calling this method the element still has not reached
2383  * the pending state, the next state change is performed.
2384  *
2385  * This method is used internally and should normally not be called by plugins
2386  * or applications.
2387  *
2388  * Returns: The result of the commit state change.
2389  *
2390  * MT safe.
2391  */
2392 GstStateChangeReturn
2393 gst_element_continue_state (GstElement * element, GstStateChangeReturn ret)
2395   GstStateChangeReturn old_ret;
2396   GstState old_state, old_next;
2397   GstState current, next, pending;
2398   GstStateChange transition;
2400   GST_OBJECT_LOCK (element);
2401   old_ret = GST_STATE_RETURN (element);
2402   GST_STATE_RETURN (element) = ret;
2403   pending = GST_STATE_PENDING (element);
2405   /* check if there is something to commit */
2406   if (pending == GST_STATE_VOID_PENDING)
2407     goto nothing_pending;
2409   old_state = GST_STATE (element);
2410   /* this is the state we should go to next */
2411   old_next = GST_STATE_NEXT (element);
2412   /* update current state */
2413   current = GST_STATE (element) = old_next;
2415   /* see if we reached the final state */
2416   if (pending == current)
2417     goto complete;
2419   next = GST_STATE_GET_NEXT (current, pending);
2420   transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2422   GST_STATE_NEXT (element) = next;
2423   /* mark busy */
2424   GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2425   GST_OBJECT_UNLOCK (element);
2427   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2428       "committing state from %s to %s, pending %s, next %s",
2429       gst_element_state_get_name (old_state),
2430       gst_element_state_get_name (old_next),
2431       gst_element_state_get_name (pending), gst_element_state_get_name (next));
2433   _priv_gst_element_state_changed (element, old_state, old_next, pending);
2435   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2436       "continue state change %s to %s, final %s",
2437       gst_element_state_get_name (current),
2438       gst_element_state_get_name (next), gst_element_state_get_name (pending));
2440   ret = gst_element_change_state (element, transition);
2442   return ret;
2444 nothing_pending:
2445   {
2446     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
2447     GST_OBJECT_UNLOCK (element);
2448     return ret;
2449   }
2450 complete:
2451   {
2452     GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2453     GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
2455     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2456         "completed state change to %s", gst_element_state_get_name (pending));
2457     GST_OBJECT_UNLOCK (element);
2459     /* don't post silly messages with the same state. This can happen
2460      * when an element state is changed to what it already was. For bins
2461      * this can be the result of a lost state, which we check with the
2462      * previous return value.
2463      * We do signal the cond though as a _get_state() might be blocking
2464      * on it. */
2465     if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC)
2466       _priv_gst_element_state_changed (element, old_state, old_next,
2467           GST_STATE_VOID_PENDING);
2469     GST_STATE_BROADCAST (element);
2471     return ret;
2472   }
2475 /**
2476  * gst_element_lost_state_full:
2477  * @element: a #GstElement the state is lost of
2478  * @new_base_time: if a new base time should be distributed
2479  *
2480  * Brings the element to the lost state. The current state of the
2481  * element is copied to the pending state so that any call to
2482  * gst_element_get_state() will return %GST_STATE_CHANGE_ASYNC.
2483  *
2484  * An ASYNC_START message is posted with indication to distribute a new
2485  * base_time to the element when @new_base_time is %TRUE.
2486  * If the element was PLAYING, it will go to PAUSED. The element
2487  * will be restored to its PLAYING state by the parent pipeline when it
2488  * prerolls again.
2489  *
2490  * This is mostly used for elements that lost their preroll buffer
2491  * in the %GST_STATE_PAUSED or %GST_STATE_PLAYING state after a flush,
2492  * they will go to their pending state again when a new preroll buffer is
2493  * queued. This function can only be called when the element is currently
2494  * not in error or an async state change.
2495  *
2496  * This function is used internally and should normally not be called from
2497  * plugins or applications.
2498  *
2499  * MT safe.
2500  *
2501  * Since: 0.10.24
2502  */
2503 void
2504 gst_element_lost_state_full (GstElement * element, gboolean new_base_time)
2506   GstState old_state, new_state;
2507   GstMessage *message;
2509   g_return_if_fail (GST_IS_ELEMENT (element));
2511   GST_OBJECT_LOCK (element);
2512   if (GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
2513     goto nothing_lost;
2515   if (GST_STATE_PENDING (element) != GST_STATE_VOID_PENDING)
2516     goto only_async_start;
2518   old_state = GST_STATE (element);
2520   /* when we were PLAYING, the new state is PAUSED. We will also not
2521    * automatically go to PLAYING but let the parent bin(s) set us to PLAYING
2522    * when we preroll. */
2523   if (old_state > GST_STATE_PAUSED)
2524     new_state = GST_STATE_PAUSED;
2525   else
2526     new_state = old_state;
2528   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2529       "lost state of %s to %s", gst_element_state_get_name (old_state),
2530       gst_element_state_get_name (new_state));
2532   GST_STATE (element) = new_state;
2533   GST_STATE_NEXT (element) = new_state;
2534   GST_STATE_PENDING (element) = new_state;
2535   GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2536   if (new_base_time)
2537     GST_ELEMENT_START_TIME (element) = 0;
2538   GST_OBJECT_UNLOCK (element);
2540   _priv_gst_element_state_changed (element, new_state, new_state, new_state);
2542   message =
2543       gst_message_new_async_start (GST_OBJECT_CAST (element), new_base_time);
2544   gst_element_post_message (element, message);
2546   return;
2548 nothing_lost:
2549   {
2550     GST_OBJECT_UNLOCK (element);
2551     return;
2552   }
2553 only_async_start:
2554   {
2555     GST_OBJECT_UNLOCK (element);
2557     message = gst_message_new_async_start (GST_OBJECT_CAST (element), TRUE);
2558     gst_element_post_message (element, message);
2559     return;
2560   }
2563 /**
2564  * gst_element_lost_state:
2565  * @element: a #GstElement the state is lost of
2566  *
2567  * Brings the element to the lost state. This function calls
2568  * gst_element_lost_state_full() with the new_base_time set to %TRUE.
2569  *
2570  * This function is used internally and should normally not be called from
2571  * plugins or applications.
2572  *
2573  * MT safe.
2574  */
2575 void
2576 gst_element_lost_state (GstElement * element)
2578   gst_element_lost_state_full (element, TRUE);
2581 /**
2582  * gst_element_set_state:
2583  * @element: a #GstElement to change state of.
2584  * @state: the element's new #GstState.
2585  *
2586  * Sets the state of the element. This function will try to set the
2587  * requested state by going through all the intermediary states and calling
2588  * the class's state change function for each.
2589  *
2590  * This function can return #GST_STATE_CHANGE_ASYNC, in which case the
2591  * element will perform the remainder of the state change asynchronously in
2592  * another thread.
2593  * An application can use gst_element_get_state() to wait for the completion
2594  * of the state change or it can wait for a state change message on the bus.
2595  *
2596  * State changes to %GST_STATE_READY or %GST_STATE_NULL never return
2597  * #GST_STATE_CHANGE_ASYNC.
2598  *
2599  * Returns: Result of the state change using #GstStateChangeReturn.
2600  *
2601  * MT safe.
2602  */
2603 GstStateChangeReturn
2604 gst_element_set_state (GstElement * element, GstState state)
2606   GstElementClass *oclass;
2607   GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
2609   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2611   oclass = GST_ELEMENT_GET_CLASS (element);
2613   if (oclass->set_state)
2614     result = (oclass->set_state) (element, state);
2616   return result;
2619 /*
2620  * default set state function, calculates the next state based
2621  * on current state and calls the change_state function
2622  */
2623 static GstStateChangeReturn
2624 gst_element_set_state_func (GstElement * element, GstState state)
2626   GstState current, next, old_pending;
2627   GstStateChangeReturn ret;
2628   GstStateChange transition;
2629   GstStateChangeReturn old_ret;
2631   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2633   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "set_state to %s",
2634       gst_element_state_get_name (state));
2636   /* state lock is taken to protect the set_state() and get_state()
2637    * procedures, it does not lock any variables. */
2638   GST_STATE_LOCK (element);
2640   /* now calculate how to get to the new state */
2641   GST_OBJECT_LOCK (element);
2642   old_ret = GST_STATE_RETURN (element);
2643   /* previous state change returned an error, remove all pending
2644    * and next states */
2645   if (old_ret == GST_STATE_CHANGE_FAILURE) {
2646     GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
2647     GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2648     GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
2649   }
2651   current = GST_STATE (element);
2652   next = GST_STATE_NEXT (element);
2653   old_pending = GST_STATE_PENDING (element);
2655   /* this is the (new) state we should go to. TARGET is the last state we set on
2656    * the element. */
2657   if (state != GST_STATE_TARGET (element)) {
2658     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2659         "setting target state to %s", gst_element_state_get_name (state));
2660     GST_STATE_TARGET (element) = state;
2661     /* increment state cookie so that we can track each state change. We only do
2662      * this if this is actually a new state change. */
2663     element->state_cookie++;
2664   }
2665   GST_STATE_PENDING (element) = state;
2667   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2668       "current %s, old_pending %s, next %s, old return %s",
2669       gst_element_state_get_name (current),
2670       gst_element_state_get_name (old_pending),
2671       gst_element_state_get_name (next),
2672       gst_element_state_change_return_get_name (old_ret));
2674   /* if the element was busy doing a state change, we just update the
2675    * target state, it'll get to it async then. */
2676   if (old_pending != GST_STATE_VOID_PENDING) {
2677     /* upwards state change will happen ASYNC */
2678     if (old_pending <= state)
2679       goto was_busy;
2680     /* element is going to this state already */
2681     else if (next == state)
2682       goto was_busy;
2683     /* element was performing an ASYNC upward state change and
2684      * we request to go downward again. Start from the next pending
2685      * state then. */
2686     else if (next > state
2687         && GST_STATE_RETURN (element) == GST_STATE_CHANGE_ASYNC) {
2688       current = next;
2689     }
2690   }
2691   next = GST_STATE_GET_NEXT (current, state);
2692   /* now we store the next state */
2693   GST_STATE_NEXT (element) = next;
2694   /* mark busy, we need to check that there is actually a state change
2695    * to be done else we could accidentally override SUCCESS/NO_PREROLL and
2696    * the default element change_state function has no way to know what the
2697    * old value was... could consider this a FIXME...*/
2698   if (current != next)
2699     GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2701   transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2703   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2704       "%s: setting state from %s to %s",
2705       (next != state ? "intermediate" : "final"),
2706       gst_element_state_get_name (current), gst_element_state_get_name (next));
2708   /* now signal any waiters, they will error since the cookie was incremented */
2709   GST_STATE_BROADCAST (element);
2711   GST_OBJECT_UNLOCK (element);
2713   ret = gst_element_change_state (element, transition);
2715   GST_STATE_UNLOCK (element);
2717   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "returned %s",
2718       gst_element_state_change_return_get_name (ret));
2720   return ret;
2722 was_busy:
2723   {
2724     GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2725     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2726         "element was busy with async state change");
2727     GST_OBJECT_UNLOCK (element);
2729     GST_STATE_UNLOCK (element);
2731     return GST_STATE_CHANGE_ASYNC;
2732   }
2735 /**
2736  * gst_element_change_state:
2737  * @element: a #GstElement
2738  * @transition: the requested transition
2739  *
2740  * Perform @transition on @element.
2741  *
2742  * This function must be called with STATE_LOCK held and is mainly used
2743  * internally.
2744  *
2745  * Returns: the #GstStateChangeReturn of the state transition.
2746  */
2747 GstStateChangeReturn
2748 gst_element_change_state (GstElement * element, GstStateChange transition)
2750   GstElementClass *oclass;
2751   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2753   oclass = GST_ELEMENT_GET_CLASS (element);
2755   /* call the state change function so it can set the state */
2756   if (oclass->change_state)
2757     ret = (oclass->change_state) (element, transition);
2758   else
2759     ret = GST_STATE_CHANGE_FAILURE;
2761   switch (ret) {
2762     case GST_STATE_CHANGE_FAILURE:
2763       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2764           "have FAILURE change_state return");
2765       /* state change failure */
2766       gst_element_abort_state (element);
2767       break;
2768     case GST_STATE_CHANGE_ASYNC:
2769     {
2770       GstState target;
2772       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2773           "element will change state ASYNC");
2775       target = GST_STATE_TARGET (element);
2777       if (target > GST_STATE_READY)
2778         goto async;
2780       /* else we just continue the state change downwards */
2781       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2782           "forcing commit state %s <= %s",
2783           gst_element_state_get_name (target),
2784           gst_element_state_get_name (GST_STATE_READY));
2786       ret = gst_element_continue_state (element, GST_STATE_CHANGE_SUCCESS);
2787       break;
2788     }
2789     case GST_STATE_CHANGE_SUCCESS:
2790       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2791           "element changed state SUCCESS");
2792       /* we can commit the state now which will proceeed to
2793        * the next state */
2794       ret = gst_element_continue_state (element, ret);
2795       break;
2796     case GST_STATE_CHANGE_NO_PREROLL:
2797       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2798           "element changed state NO_PREROLL");
2799       /* we can commit the state now which will proceeed to
2800        * the next state */
2801       ret = gst_element_continue_state (element, ret);
2802       break;
2803     default:
2804       goto invalid_return;
2805   }
2807   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit state change %d", ret);
2809   return ret;
2811 async:
2812   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit async state change %d",
2813       ret);
2815   return ret;
2817   /* ERROR */
2818 invalid_return:
2819   {
2820     GST_OBJECT_LOCK (element);
2821     /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2822     g_critical ("%s: unknown return value %d from a state change function",
2823         GST_ELEMENT_NAME (element), ret);
2825     /* we are in error now */
2826     ret = GST_STATE_CHANGE_FAILURE;
2827     GST_STATE_RETURN (element) = ret;
2828     GST_OBJECT_UNLOCK (element);
2830     return ret;
2831   }
2834 /* gst_iterator_fold functions for pads_activate
2835  * Stop the iterator if activating one pad failed. */
2836 static gboolean
2837 activate_pads (GstPad * pad, GValue * ret, gboolean * active)
2839   gboolean cont = TRUE;
2841   if (!(cont = gst_pad_set_active (pad, *active)))
2842     g_value_set_boolean (ret, FALSE);
2844   /* unref the object that was reffed for us by _fold */
2845   gst_object_unref (pad);
2846   return cont;
2849 /* set the caps on the pad to NULL */
2850 static gboolean
2851 clear_caps (GstPad * pad, GValue * ret, gboolean * active)
2853   gst_pad_set_caps (pad, NULL);
2854   gst_object_unref (pad);
2855   return TRUE;
2858 /* returns false on error or early cutout of the fold, true if all
2859  * pads in @iter were (de)activated successfully. */
2860 static gboolean
2861 iterator_activate_fold_with_resync (GstIterator * iter,
2862     GstIteratorFoldFunction func, gpointer user_data)
2864   GstIteratorResult ires;
2865   GValue ret = { 0 };
2867   /* no need to unset this later, it's just a boolean */
2868   g_value_init (&ret, G_TYPE_BOOLEAN);
2869   g_value_set_boolean (&ret, TRUE);
2871   while (1) {
2872     ires = gst_iterator_fold (iter, func, &ret, user_data);
2873     switch (ires) {
2874       case GST_ITERATOR_RESYNC:
2875         /* need to reset the result again */
2876         g_value_set_boolean (&ret, TRUE);
2877         gst_iterator_resync (iter);
2878         break;
2879       case GST_ITERATOR_DONE:
2880         /* all pads iterated, return collected value */
2881         goto done;
2882       default:
2883         /* iterator returned _ERROR or premature end with _OK,
2884          * mark an error and exit */
2885         g_value_set_boolean (&ret, FALSE);
2886         goto done;
2887     }
2888   }
2889 done:
2890   /* return collected value */
2891   return g_value_get_boolean (&ret);
2894 /* is called with STATE_LOCK
2895  *
2896  * Pads are activated from source pads to sinkpads.
2897  */
2898 static gboolean
2899 gst_element_pads_activate (GstElement * element, gboolean active)
2901   GstIterator *iter;
2902   gboolean res;
2904   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2905       "pads_activate with active %d", active);
2907   iter = gst_element_iterate_src_pads (element);
2908   res =
2909       iterator_activate_fold_with_resync (iter,
2910       (GstIteratorFoldFunction) activate_pads, &active);
2911   gst_iterator_free (iter);
2912   if (G_UNLIKELY (!res))
2913     goto src_failed;
2915   iter = gst_element_iterate_sink_pads (element);
2916   res =
2917       iterator_activate_fold_with_resync (iter,
2918       (GstIteratorFoldFunction) activate_pads, &active);
2919   gst_iterator_free (iter);
2920   if (G_UNLIKELY (!res))
2921     goto sink_failed;
2923   if (!active) {
2924     /* clear the caps on all pads, this should never fail */
2925     iter = gst_element_iterate_pads (element);
2926     res =
2927         iterator_activate_fold_with_resync (iter,
2928         (GstIteratorFoldFunction) clear_caps, &active);
2929     gst_iterator_free (iter);
2930     if (G_UNLIKELY (!res))
2931       goto caps_failed;
2932   }
2934   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2935       "pads_activate successful");
2937   return TRUE;
2939   /* ERRORS */
2940 src_failed:
2941   {
2942     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2943         "source pads_activate failed");
2944     return FALSE;
2945   }
2946 sink_failed:
2947   {
2948     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2949         "sink pads_activate failed");
2950     return FALSE;
2951   }
2952 caps_failed:
2953   {
2954     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2955         "failed to clear caps on pads");
2956     return FALSE;
2957   }
2960 /* is called with STATE_LOCK */
2961 static GstStateChangeReturn
2962 gst_element_change_state_func (GstElement * element, GstStateChange transition)
2964   GstState state, next;
2965   GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
2966   GstClock **clock_p;
2968   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2970   state = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
2971   next = GST_STATE_TRANSITION_NEXT (transition);
2973   /* if the element already is in the given state, we just return success */
2974   if (next == GST_STATE_VOID_PENDING || state == next)
2975     goto was_ok;
2977   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2978       "default handler tries setting state from %s to %s (%04x)",
2979       gst_element_state_get_name (state),
2980       gst_element_state_get_name (next), transition);
2982   switch (transition) {
2983     case GST_STATE_CHANGE_NULL_TO_READY:
2984       break;
2985     case GST_STATE_CHANGE_READY_TO_PAUSED:
2986       if (!gst_element_pads_activate (element, TRUE)) {
2987         result = GST_STATE_CHANGE_FAILURE;
2988       }
2989       break;
2990     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2991       break;
2992     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2993       break;
2994     case GST_STATE_CHANGE_PAUSED_TO_READY:
2995     case GST_STATE_CHANGE_READY_TO_NULL:
2996       /* deactivate pads in both cases, since they are activated on
2997          ready->paused but the element might not have made it to paused */
2998       if (!gst_element_pads_activate (element, FALSE)) {
2999         result = GST_STATE_CHANGE_FAILURE;
3000       } else {
3001         gst_element_set_base_time (element, 0);
3002       }
3004       /* In null state release the reference to the clock */
3005       GST_OBJECT_LOCK (element);
3006       clock_p = &element->clock;
3007       gst_object_replace ((GstObject **) clock_p, NULL);
3008       GST_OBJECT_UNLOCK (element);
3009       break;
3010     default:
3011       /* this will catch real but unhandled state changes;
3012        * can only be caused by:
3013        * - a new state was added
3014        * - somehow the element was asked to jump across an intermediate state
3015        */
3016       g_warning ("Unhandled state change from %s to %s",
3017           gst_element_state_get_name (state),
3018           gst_element_state_get_name (next));
3019       break;
3020   }
3021   return result;
3023 was_ok:
3024   {
3025     GST_OBJECT_LOCK (element);
3026     result = GST_STATE_RETURN (element);
3027     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
3028         "element is already in the %s state",
3029         gst_element_state_get_name (state));
3030     GST_OBJECT_UNLOCK (element);
3032     return result;
3033   }
3036 /**
3037  * gst_element_get_factory:
3038  * @element: a #GstElement to request the element factory of.
3039  *
3040  * Retrieves the factory that was used to create this element.
3041  *
3042  * Returns: (transfer none): the #GstElementFactory used for creating this
3043  *     element. no refcounting is needed.
3044  */
3045 GstElementFactory *
3046 gst_element_get_factory (GstElement * element)
3048   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3050   return GST_ELEMENT_GET_CLASS (element)->elementfactory;
3053 static void
3054 gst_element_dispose (GObject * object)
3056   GstElement *element = GST_ELEMENT_CAST (object);
3057   GstClock **clock_p;
3058   GstBus **bus_p;
3060   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
3062   if (GST_STATE (element) != GST_STATE_NULL)
3063     goto not_null;
3065   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
3066       "removing %d pads", g_list_length (element->pads));
3067   /* first we break all our links with the outside */
3068   while (element->pads && element->pads->data) {
3069     /* don't call _remove_pad with NULL */
3070     gst_element_remove_pad (element, GST_PAD_CAST (element->pads->data));
3071   }
3072   if (G_UNLIKELY (element->pads != NULL)) {
3073     g_critical ("could not remove pads from element %s",
3074         GST_STR_NULL (GST_OBJECT_NAME (object)));
3075   }
3077   GST_OBJECT_LOCK (element);
3078   clock_p = &element->clock;
3079   bus_p = &element->bus;
3080   gst_object_replace ((GstObject **) clock_p, NULL);
3081   gst_object_replace ((GstObject **) bus_p, NULL);
3082   GST_OBJECT_UNLOCK (element);
3084   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "parent class dispose");
3086   G_OBJECT_CLASS (parent_class)->dispose (object);
3088   return;
3090   /* ERRORS */
3091 not_null:
3092   {
3093     gboolean is_locked;
3095     is_locked = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
3096     g_critical
3097         ("\nTrying to dispose element %s, but it is in %s%s instead of the NULL"
3098         " state.\n"
3099         "You need to explicitly set elements to the NULL state before\n"
3100         "dropping the final reference, to allow them to clean up.\n"
3101         "This problem may also be caused by a refcounting bug in the\n"
3102         "application or some element.\n",
3103         GST_OBJECT_NAME (element),
3104         gst_element_state_get_name (GST_STATE (element)),
3105         is_locked ? " (locked)" : "");
3106     return;
3107   }
3110 static void
3111 gst_element_finalize (GObject * object)
3113   GstElement *element = GST_ELEMENT_CAST (object);
3115   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize");
3117   GST_STATE_LOCK (element);
3118   if (element->state_cond)
3119     g_cond_free (element->state_cond);
3120   element->state_cond = NULL;
3121   GST_STATE_UNLOCK (element);
3122   g_static_rec_mutex_free (element->state_lock);
3123   g_slice_free (GStaticRecMutex, element->state_lock);
3124   element->state_lock = NULL;
3126   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize parent");
3128   G_OBJECT_CLASS (parent_class)->finalize (object);
3131 #if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
3132 /**
3133  * gst_element_save_thyself:
3134  * @element: a #GstElement to save.
3135  * @parent: the xml parent node.
3136  *
3137  * Saves the element as part of the given XML structure.
3138  *
3139  * Returns: the new #xmlNodePtr.
3140  */
3141 static xmlNodePtr
3142 gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
3144   GList *pads;
3145   GstElementClass *oclass;
3146   GParamSpec **specs, *spec;
3147   guint nspecs;
3148   guint i;
3149   GValue value = { 0, };
3150   GstElement *element;
3152   g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
3154   element = GST_ELEMENT_CAST (object);
3156   oclass = GST_ELEMENT_GET_CLASS (element);
3158   xmlNewChild (parent, NULL, (xmlChar *) "name",
3159       (xmlChar *) GST_ELEMENT_NAME (element));
3161   if (oclass->elementfactory != NULL) {
3162     GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
3164     xmlNewChild (parent, NULL, (xmlChar *) "type",
3165         (xmlChar *) GST_PLUGIN_FEATURE (factory)->name);
3166   }
3168   /* params */
3169   specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
3171   for (i = 0; i < nspecs; i++) {
3172     spec = specs[i];
3173     if (spec->flags & G_PARAM_READABLE) {
3174       xmlNodePtr param;
3175       char *contents;
3177       g_value_init (&value, spec->value_type);
3179       g_object_get_property (G_OBJECT (element), spec->name, &value);
3180       param = xmlNewChild (parent, NULL, (xmlChar *) "param", NULL);
3181       xmlNewChild (param, NULL, (xmlChar *) "name", (xmlChar *) spec->name);
3183       if (G_IS_PARAM_SPEC_STRING (spec))
3184         contents = g_value_dup_string (&value);
3185       else if (G_IS_PARAM_SPEC_ENUM (spec))
3186         contents = g_strdup_printf ("%d", g_value_get_enum (&value));
3187       else if (G_IS_PARAM_SPEC_INT64 (spec))
3188         contents = g_strdup_printf ("%" G_GINT64_FORMAT,
3189             g_value_get_int64 (&value));
3190       else if (GST_VALUE_HOLDS_STRUCTURE (&value)) {
3191         if (g_value_get_boxed (&value) != NULL) {
3192           contents = g_strdup_value_contents (&value);
3193         } else {
3194           contents = g_strdup ("NULL");
3195         }
3196       } else
3197         contents = g_strdup_value_contents (&value);
3199       xmlNewChild (param, NULL, (xmlChar *) "value", (xmlChar *) contents);
3200       g_free (contents);
3202       g_value_unset (&value);
3203     }
3204   }
3206   g_free (specs);
3208   pads = g_list_last (GST_ELEMENT_PADS (element));
3210   while (pads) {
3211     GstPad *pad = GST_PAD_CAST (pads->data);
3213     /* figure out if it's a direct pad or a ghostpad */
3214     if (GST_ELEMENT_CAST (GST_OBJECT_PARENT (pad)) == element) {
3215       xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL);
3217       gst_object_save_thyself (GST_OBJECT_CAST (pad), padtag);
3218     }
3219     pads = g_list_previous (pads);
3220   }
3222   return parent;
3225 static void
3226 gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
3228   xmlNodePtr children;
3229   GstElement *element;
3230   gchar *name = NULL;
3231   gchar *value = NULL;
3233   element = GST_ELEMENT_CAST (object);
3234   g_return_if_fail (element != NULL);
3236   /* parameters */
3237   children = self->xmlChildrenNode;
3238   while (children) {
3239     if (!strcmp ((char *) children->name, "param")) {
3240       xmlNodePtr child = children->xmlChildrenNode;
3242       while (child) {
3243         if (!strcmp ((char *) child->name, "name")) {
3244           name = (gchar *) xmlNodeGetContent (child);
3245         } else if (!strcmp ((char *) child->name, "value")) {
3246           value = (gchar *) xmlNodeGetContent (child);
3247         }
3248         child = child->next;
3249       }
3250       /* FIXME: can this just be g_object_set ? */
3251       gst_util_set_object_arg (G_OBJECT (element), name, value);
3252       /* g_object_set (G_OBJECT (element), name, value, NULL); */
3253       g_free (name);
3254       g_free (value);
3255     }
3256     children = children->next;
3257   }
3259   /* pads */
3260   children = self->xmlChildrenNode;
3261   while (children) {
3262     if (!strcmp ((char *) children->name, "pad")) {
3263       gst_pad_load_and_link (children, GST_OBJECT_CAST (element));
3264     }
3265     children = children->next;
3266   }
3268   if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
3269     (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
3271 #endif /* GST_DISABLE_LOADSAVE */
3273 static void
3274 gst_element_set_bus_func (GstElement * element, GstBus * bus)
3276   GstBus **bus_p;
3278   g_return_if_fail (GST_IS_ELEMENT (element));
3280   GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
3282   GST_OBJECT_LOCK (element);
3283   bus_p = &GST_ELEMENT_BUS (element);
3284   gst_object_replace ((GstObject **) bus_p, GST_OBJECT_CAST (bus));
3285   GST_OBJECT_UNLOCK (element);
3288 /**
3289  * gst_element_set_bus:
3290  * @element: a #GstElement to set the bus of.
3291  * @bus: (transfer none): the #GstBus to set.
3292  *
3293  * Sets the bus of the element. Increases the refcount on the bus.
3294  * For internal use only, unless you're testing elements.
3295  *
3296  * MT safe.
3297  */
3298 void
3299 gst_element_set_bus (GstElement * element, GstBus * bus)
3301   GstElementClass *oclass;
3303   g_return_if_fail (GST_IS_ELEMENT (element));
3305   oclass = GST_ELEMENT_GET_CLASS (element);
3307   if (oclass->set_bus)
3308     oclass->set_bus (element, bus);
3311 /**
3312  * gst_element_get_bus:
3313  * @element: a #GstElement to get the bus of.
3314  *
3315  * Returns the bus of the element. Note that only a #GstPipeline will provide a
3316  * bus for the application.
3317  *
3318  * Returns: (transfer full): the element's #GstBus. unref after usage.
3319  *
3320  * MT safe.
3321  */
3322 GstBus *
3323 gst_element_get_bus (GstElement * element)
3325   GstBus *result = NULL;
3327   g_return_val_if_fail (GST_IS_ELEMENT (element), result);
3329   GST_OBJECT_LOCK (element);
3330   if ((result = GST_ELEMENT_BUS (element)))
3331     gst_object_ref (result);
3332   GST_OBJECT_UNLOCK (element);
3334   GST_CAT_DEBUG_OBJECT (GST_CAT_BUS, element, "got bus %" GST_PTR_FORMAT,
3335       result);
3337   return result;