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