message: new API for additional custom data to error messages
[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_with_details:
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  * @structure:(transfer full): optional details structure
1837  *
1838  * Post an error, warning or info message on the bus from inside an element.
1839  *
1840  * @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
1841  * #GST_MESSAGE_INFO.
1842  *
1843  * Since: 1.10
1844  *
1845  * MT safe.
1846  */
1847 void gst_element_message_full_with_details
1848     (GstElement * element, GstMessageType type,
1849     GQuark domain, gint code, gchar * text,
1850     gchar * debug, const gchar * file, const gchar * function, gint line,
1851     GstStructure * structure)
1852 {
1853   GError *gerror = NULL;
1854   gchar *name;
1855   gchar *sent_text;
1856   gchar *sent_debug;
1857   gboolean has_debug = TRUE;
1858   GstMessage *message = NULL;
1859
1860   /* checks */
1861   GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element, "start");
1862   g_return_if_fail (GST_IS_ELEMENT (element));
1863   g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
1864       (type == GST_MESSAGE_WARNING) || (type == GST_MESSAGE_INFO));
1865
1866   /* check if we send the given text or the default error text */
1867   if ((text == NULL) || (text[0] == 0)) {
1868     /* text could have come from g_strdup_printf (""); */
1869     g_free (text);
1870     sent_text = gst_error_get_message (domain, code);
1871   } else
1872     sent_text = text;
1873
1874   /* construct a sent_debug with extra information from source */
1875   if ((debug == NULL) || (debug[0] == 0)) {
1876     /* debug could have come from g_strdup_printf (""); */
1877     has_debug = FALSE;
1878   }
1879
1880   name = gst_object_get_path_string (GST_OBJECT_CAST (element));
1881   if (has_debug)
1882     sent_debug = g_strdup_printf ("%s(%d): %s (): %s:\n%s",
1883         file, line, function, name, debug);
1884   else
1885     sent_debug = g_strdup_printf ("%s(%d): %s (): %s",
1886         file, line, function, name);
1887   g_free (name);
1888   g_free (debug);
1889
1890   /* create gerror and post message */
1891   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
1892       sent_text);
1893   gerror = g_error_new_literal (domain, code, sent_text);
1894
1895   switch (type) {
1896     case GST_MESSAGE_ERROR:
1897       message =
1898           gst_message_new_error_with_details (GST_OBJECT_CAST (element), gerror,
1899           sent_debug, structure);
1900       break;
1901     case GST_MESSAGE_WARNING:
1902       message =
1903           gst_message_new_warning_with_details (GST_OBJECT_CAST (element),
1904           gerror, sent_debug, structure);
1905       break;
1906     case GST_MESSAGE_INFO:
1907       message =
1908           gst_message_new_info_with_details (GST_OBJECT_CAST (element), gerror,
1909           sent_debug, structure);
1910       break;
1911     default:
1912       g_assert_not_reached ();
1913       break;
1914   }
1915
1916   gst_element_post_message (element, message);
1917
1918   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted %s message: %s",
1919       (type == GST_MESSAGE_ERROR ? "error" : "warning"), sent_text);
1920
1921   /* cleanup */
1922   g_error_free (gerror);
1923   g_free (sent_debug);
1924   g_free (sent_text);
1925 }
1926
1927 /**
1928  * gst_element_message_full:
1929  * @element:  a #GstElement to send message from
1930  * @type:     the #GstMessageType
1931  * @domain:   the GStreamer GError domain this message belongs to
1932  * @code:     the GError code belonging to the domain
1933  * @text:     (allow-none) (transfer full): an allocated text string to be used
1934  *            as a replacement for the default message connected to code,
1935  *            or %NULL
1936  * @debug:    (allow-none) (transfer full): an allocated debug message to be
1937  *            used as a replacement for the default debugging information,
1938  *            or %NULL
1939  * @file:     the source code file where the error was generated
1940  * @function: the source code function where the error was generated
1941  * @line:     the source code line where the error was generated
1942  *
1943  * Post an error, warning or info message on the bus from inside an element.
1944  *
1945  * @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
1946  * #GST_MESSAGE_INFO.
1947  *
1948  * MT safe.
1949  */
1950 void gst_element_message_full
1951     (GstElement * element, GstMessageType type,
1952     GQuark domain, gint code, gchar * text,
1953     gchar * debug, const gchar * file, const gchar * function, gint line)
1954 {
1955   gst_element_message_full_with_details (element, type, domain, code, text,
1956       debug, file, function, line, NULL);
1957 }
1958
1959 /**
1960  * gst_element_is_locked_state:
1961  * @element: a #GstElement.
1962  *
1963  * Checks if the state of an element is locked.
1964  * If the state of an element is locked, state changes of the parent don't
1965  * affect the element.
1966  * This way you can leave currently unused elements inside bins. Just lock their
1967  * state before changing the state from #GST_STATE_NULL.
1968  *
1969  * MT safe.
1970  *
1971  * Returns: %TRUE, if the element's state is locked.
1972  */
1973 gboolean
1974 gst_element_is_locked_state (GstElement * element)
1975 {
1976   gboolean result;
1977
1978   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1979
1980   GST_OBJECT_LOCK (element);
1981   result = GST_ELEMENT_IS_LOCKED_STATE (element);
1982   GST_OBJECT_UNLOCK (element);
1983
1984   return result;
1985 }
1986
1987 /**
1988  * gst_element_set_locked_state:
1989  * @element: a #GstElement
1990  * @locked_state: %TRUE to lock the element's state
1991  *
1992  * Locks the state of an element, so state changes of the parent don't affect
1993  * this element anymore.
1994  *
1995  * MT safe.
1996  *
1997  * Returns: %TRUE if the state was changed, %FALSE if bad parameters were given
1998  * or the elements state-locking needed no change.
1999  */
2000 gboolean
2001 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
2002 {
2003   gboolean old;
2004
2005   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2006
2007   GST_OBJECT_LOCK (element);
2008   old = GST_ELEMENT_IS_LOCKED_STATE (element);
2009
2010   if (G_UNLIKELY (old == locked_state))
2011     goto was_ok;
2012
2013   if (locked_state) {
2014     GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
2015         GST_ELEMENT_NAME (element));
2016     GST_OBJECT_FLAG_SET (element, GST_ELEMENT_FLAG_LOCKED_STATE);
2017   } else {
2018     GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
2019         GST_ELEMENT_NAME (element));
2020     GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_FLAG_LOCKED_STATE);
2021   }
2022   GST_OBJECT_UNLOCK (element);
2023
2024   return TRUE;
2025
2026 was_ok:
2027   {
2028     GST_CAT_DEBUG (GST_CAT_STATES,
2029         "elements %s was already in locked state %d",
2030         GST_ELEMENT_NAME (element), old);
2031     GST_OBJECT_UNLOCK (element);
2032
2033     return FALSE;
2034   }
2035 }
2036
2037 /**
2038  * gst_element_sync_state_with_parent:
2039  * @element: a #GstElement.
2040  *
2041  * Tries to change the state of the element to the same as its parent.
2042  * If this function returns %FALSE, the state of element is undefined.
2043  *
2044  * Returns: %TRUE, if the element's state could be synced to the parent's state.
2045  *
2046  * MT safe.
2047  */
2048 gboolean
2049 gst_element_sync_state_with_parent (GstElement * element)
2050 {
2051   GstElement *parent;
2052   GstState target;
2053   GstStateChangeReturn ret;
2054
2055   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2056
2057   if ((parent = GST_ELEMENT_CAST (gst_element_get_parent (element)))) {
2058     GstState parent_current, parent_pending;
2059
2060     GST_OBJECT_LOCK (parent);
2061     parent_current = GST_STATE (parent);
2062     parent_pending = GST_STATE_PENDING (parent);
2063     GST_OBJECT_UNLOCK (parent);
2064
2065     /* set to pending if there is one, else we set it to the current state of
2066      * the parent */
2067     if (parent_pending != GST_STATE_VOID_PENDING)
2068       target = parent_pending;
2069     else
2070       target = parent_current;
2071
2072     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2073         "syncing state (%s) to parent %s %s (%s, %s)",
2074         gst_element_state_get_name (GST_STATE (element)),
2075         GST_ELEMENT_NAME (parent), gst_element_state_get_name (target),
2076         gst_element_state_get_name (parent_current),
2077         gst_element_state_get_name (parent_pending));
2078
2079     ret = gst_element_set_state (element, target);
2080     if (ret == GST_STATE_CHANGE_FAILURE)
2081       goto failed;
2082
2083     gst_object_unref (parent);
2084
2085     return TRUE;
2086   } else {
2087     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "element has no parent");
2088   }
2089   return FALSE;
2090
2091   /* ERROR */
2092 failed:
2093   {
2094     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2095         "syncing state failed (%s)",
2096         gst_element_state_change_return_get_name (ret));
2097     gst_object_unref (parent);
2098     return FALSE;
2099   }
2100 }
2101
2102 /* MT safe */
2103 static GstStateChangeReturn
2104 gst_element_get_state_func (GstElement * element,
2105     GstState * state, GstState * pending, GstClockTime timeout)
2106 {
2107   GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
2108   GstState old_pending;
2109
2110   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "getting state, timeout %"
2111       GST_TIME_FORMAT, GST_TIME_ARGS (timeout));
2112
2113   GST_OBJECT_LOCK (element);
2114   ret = GST_STATE_RETURN (element);
2115   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "RETURN is %s",
2116       gst_element_state_change_return_get_name (ret));
2117
2118   /* we got an error, report immediately */
2119   if (ret == GST_STATE_CHANGE_FAILURE)
2120     goto done;
2121
2122   /* we got no_preroll, report immediately */
2123   if (ret == GST_STATE_CHANGE_NO_PREROLL)
2124     goto done;
2125
2126   /* no need to wait async if we are not async */
2127   if (ret != GST_STATE_CHANGE_ASYNC)
2128     goto done;
2129
2130   old_pending = GST_STATE_PENDING (element);
2131   if (old_pending != GST_STATE_VOID_PENDING) {
2132     gboolean signaled;
2133     guint32 cookie;
2134
2135     /* get cookie to detect state changes during waiting */
2136     cookie = element->state_cookie;
2137
2138     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2139         "waiting for element to commit state");
2140
2141     /* we have a pending state change, wait for it to complete */
2142     if (timeout != GST_CLOCK_TIME_NONE) {
2143       gint64 end_time;
2144       /* make timeout absolute */
2145       end_time = g_get_monotonic_time () + (timeout / 1000);
2146       signaled = GST_STATE_WAIT_UNTIL (element, end_time);
2147     } else {
2148       GST_STATE_WAIT (element);
2149       signaled = TRUE;
2150     }
2151
2152     if (!signaled) {
2153       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timed out");
2154       /* timeout triggered */
2155       ret = GST_STATE_CHANGE_ASYNC;
2156     } else {
2157       if (cookie != element->state_cookie)
2158         goto interrupted;
2159
2160       /* could be success or failure */
2161       if (old_pending == GST_STATE (element)) {
2162         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got success");
2163         ret = GST_STATE_CHANGE_SUCCESS;
2164       } else {
2165         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got failure");
2166         ret = GST_STATE_CHANGE_FAILURE;
2167       }
2168     }
2169     /* if nothing is pending anymore we can return SUCCESS */
2170     if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
2171       GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "nothing pending");
2172       ret = GST_STATE_CHANGE_SUCCESS;
2173     }
2174   }
2175
2176 done:
2177   if (state)
2178     *state = GST_STATE (element);
2179   if (pending)
2180     *pending = GST_STATE_PENDING (element);
2181
2182   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2183       "state current: %s, pending: %s, result: %s",
2184       gst_element_state_get_name (GST_STATE (element)),
2185       gst_element_state_get_name (GST_STATE_PENDING (element)),
2186       gst_element_state_change_return_get_name (ret));
2187   GST_OBJECT_UNLOCK (element);
2188
2189   return ret;
2190
2191 interrupted:
2192   {
2193     if (state)
2194       *state = GST_STATE_VOID_PENDING;
2195     if (pending)
2196       *pending = GST_STATE_VOID_PENDING;
2197
2198     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "interruped");
2199
2200     GST_OBJECT_UNLOCK (element);
2201
2202     return GST_STATE_CHANGE_FAILURE;
2203   }
2204 }
2205
2206 /**
2207  * gst_element_get_state:
2208  * @element: a #GstElement to get the state of.
2209  * @state: (out) (allow-none): a pointer to #GstState to hold the state.
2210  *     Can be %NULL.
2211  * @pending: (out) (allow-none): a pointer to #GstState to hold the pending
2212  *     state. Can be %NULL.
2213  * @timeout: a #GstClockTime to specify the timeout for an async
2214  *           state change or %GST_CLOCK_TIME_NONE for infinite timeout.
2215  *
2216  * Gets the state of the element.
2217  *
2218  * For elements that performed an ASYNC state change, as reported by
2219  * gst_element_set_state(), this function will block up to the
2220  * specified timeout value for the state change to complete.
2221  * If the element completes the state change or goes into
2222  * an error, this function returns immediately with a return value of
2223  * %GST_STATE_CHANGE_SUCCESS or %GST_STATE_CHANGE_FAILURE respectively.
2224  *
2225  * For elements that did not return %GST_STATE_CHANGE_ASYNC, this function
2226  * returns the current and pending state immediately.
2227  *
2228  * This function returns %GST_STATE_CHANGE_NO_PREROLL if the element
2229  * successfully changed its state but is not able to provide data yet.
2230  * This mostly happens for live sources that only produce data in
2231  * %GST_STATE_PLAYING. While the state change return is equivalent to
2232  * %GST_STATE_CHANGE_SUCCESS, it is returned to the application to signal that
2233  * some sink elements might not be able to complete their state change because
2234  * an element is not producing data to complete the preroll. When setting the
2235  * element to playing, the preroll will complete and playback will start.
2236  *
2237  * Returns: %GST_STATE_CHANGE_SUCCESS if the element has no more pending state
2238  *          and the last state change succeeded, %GST_STATE_CHANGE_ASYNC if the
2239  *          element is still performing a state change or
2240  *          %GST_STATE_CHANGE_FAILURE if the last state change failed.
2241  *
2242  * MT safe.
2243  */
2244 GstStateChangeReturn
2245 gst_element_get_state (GstElement * element,
2246     GstState * state, GstState * pending, GstClockTime timeout)
2247 {
2248   GstElementClass *oclass;
2249   GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
2250
2251   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2252
2253   oclass = GST_ELEMENT_GET_CLASS (element);
2254
2255   if (oclass->get_state)
2256     result = (oclass->get_state) (element, state, pending, timeout);
2257
2258   return result;
2259 }
2260
2261 /**
2262  * gst_element_abort_state:
2263  * @element: a #GstElement to abort the state of.
2264  *
2265  * Abort the state change of the element. This function is used
2266  * by elements that do asynchronous state changes and find out
2267  * something is wrong.
2268  *
2269  * This function should be called with the STATE_LOCK held.
2270  *
2271  * MT safe.
2272  */
2273 void
2274 gst_element_abort_state (GstElement * element)
2275 {
2276   GstState pending;
2277
2278 #ifndef GST_DISABLE_GST_DEBUG
2279   GstState old_state;
2280 #endif
2281
2282   g_return_if_fail (GST_IS_ELEMENT (element));
2283
2284   GST_OBJECT_LOCK (element);
2285   pending = GST_STATE_PENDING (element);
2286
2287   if (pending == GST_STATE_VOID_PENDING ||
2288       GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
2289     goto nothing_aborted;
2290
2291 #ifndef GST_DISABLE_GST_DEBUG
2292   old_state = GST_STATE (element);
2293
2294   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2295       "aborting state from %s to %s", gst_element_state_get_name (old_state),
2296       gst_element_state_get_name (pending));
2297 #endif
2298
2299   /* flag error */
2300   GST_STATE_RETURN (element) = GST_STATE_CHANGE_FAILURE;
2301
2302   GST_STATE_BROADCAST (element);
2303   GST_OBJECT_UNLOCK (element);
2304
2305   return;
2306
2307 nothing_aborted:
2308   {
2309     GST_OBJECT_UNLOCK (element);
2310     return;
2311   }
2312 }
2313
2314 /* Not static because GstBin has manual state handling too */
2315 void
2316 _priv_gst_element_state_changed (GstElement * element, GstState oldstate,
2317     GstState newstate, GstState pending)
2318 {
2319   GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
2320   GstMessage *message;
2321
2322   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2323       "notifying about state-changed %s to %s (%s pending)",
2324       gst_element_state_get_name (oldstate),
2325       gst_element_state_get_name (newstate),
2326       gst_element_state_get_name (pending));
2327
2328   if (klass->state_changed)
2329     klass->state_changed (element, oldstate, newstate, pending);
2330
2331   message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
2332       oldstate, newstate, pending);
2333   gst_element_post_message (element, message);
2334 }
2335
2336 /**
2337  * gst_element_continue_state:
2338  * @element: a #GstElement to continue the state change of.
2339  * @ret: The previous state return value
2340  *
2341  * Commit the state change of the element and proceed to the next
2342  * pending state if any. This function is used
2343  * by elements that do asynchronous state changes.
2344  * The core will normally call this method automatically when an
2345  * element returned %GST_STATE_CHANGE_SUCCESS from the state change function.
2346  *
2347  * If after calling this method the element still has not reached
2348  * the pending state, the next state change is performed.
2349  *
2350  * This method is used internally and should normally not be called by plugins
2351  * or applications.
2352  *
2353  * Returns: The result of the commit state change.
2354  *
2355  * MT safe.
2356  */
2357 GstStateChangeReturn
2358 gst_element_continue_state (GstElement * element, GstStateChangeReturn ret)
2359 {
2360   GstStateChangeReturn old_ret;
2361   GstState old_state, old_next;
2362   GstState current, next, pending;
2363   GstStateChange transition;
2364
2365   GST_OBJECT_LOCK (element);
2366   old_ret = GST_STATE_RETURN (element);
2367   GST_STATE_RETURN (element) = ret;
2368   pending = GST_STATE_PENDING (element);
2369
2370   /* check if there is something to commit */
2371   if (pending == GST_STATE_VOID_PENDING)
2372     goto nothing_pending;
2373
2374   old_state = GST_STATE (element);
2375   /* this is the state we should go to next */
2376   old_next = GST_STATE_NEXT (element);
2377   /* update current state */
2378   current = GST_STATE (element) = old_next;
2379
2380   /* see if we reached the final state */
2381   if (pending == current)
2382     goto complete;
2383
2384   next = GST_STATE_GET_NEXT (current, pending);
2385   transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2386
2387   GST_STATE_NEXT (element) = next;
2388   /* mark busy */
2389   GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2390   GST_OBJECT_UNLOCK (element);
2391
2392   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2393       "committing state from %s to %s, pending %s, next %s",
2394       gst_element_state_get_name (old_state),
2395       gst_element_state_get_name (old_next),
2396       gst_element_state_get_name (pending), gst_element_state_get_name (next));
2397
2398   _priv_gst_element_state_changed (element, old_state, old_next, pending);
2399
2400   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2401       "continue state change %s to %s, final %s",
2402       gst_element_state_get_name (current),
2403       gst_element_state_get_name (next), gst_element_state_get_name (pending));
2404
2405   ret = gst_element_change_state (element, transition);
2406
2407   return ret;
2408
2409 nothing_pending:
2410   {
2411     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
2412     GST_OBJECT_UNLOCK (element);
2413     return ret;
2414   }
2415 complete:
2416   {
2417     GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2418     GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
2419
2420     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2421         "completed state change to %s", gst_element_state_get_name (pending));
2422     GST_OBJECT_UNLOCK (element);
2423
2424     /* don't post silly messages with the same state. This can happen
2425      * when an element state is changed to what it already was. For bins
2426      * this can be the result of a lost state, which we check with the
2427      * previous return value.
2428      * We do signal the cond though as a _get_state() might be blocking
2429      * on it. */
2430     if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC)
2431       _priv_gst_element_state_changed (element, old_state, old_next,
2432           GST_STATE_VOID_PENDING);
2433
2434     GST_STATE_BROADCAST (element);
2435
2436     return ret;
2437   }
2438 }
2439
2440 /**
2441  * gst_element_lost_state:
2442  * @element: a #GstElement the state is lost of
2443  *
2444  * Brings the element to the lost state. The current state of the
2445  * element is copied to the pending state so that any call to
2446  * gst_element_get_state() will return %GST_STATE_CHANGE_ASYNC.
2447  *
2448  * An ASYNC_START message is posted. If the element was PLAYING, it will
2449  * go to PAUSED. The element will be restored to its PLAYING state by
2450  * the parent pipeline when it prerolls again.
2451  *
2452  * This is mostly used for elements that lost their preroll buffer
2453  * in the %GST_STATE_PAUSED or %GST_STATE_PLAYING state after a flush,
2454  * they will go to their pending state again when a new preroll buffer is
2455  * queued. This function can only be called when the element is currently
2456  * not in error or an async state change.
2457  *
2458  * This function is used internally and should normally not be called from
2459  * plugins or applications.
2460  */
2461 void
2462 gst_element_lost_state (GstElement * element)
2463 {
2464   GstState old_state, new_state;
2465   GstMessage *message;
2466
2467   g_return_if_fail (GST_IS_ELEMENT (element));
2468
2469   GST_OBJECT_LOCK (element);
2470   if (GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
2471     goto nothing_lost;
2472
2473   if (GST_STATE_PENDING (element) != GST_STATE_VOID_PENDING)
2474     goto only_async_start;
2475
2476   old_state = GST_STATE (element);
2477
2478   /* when we were PLAYING, the new state is PAUSED. We will also not
2479    * automatically go to PLAYING but let the parent bin(s) set us to PLAYING
2480    * when we preroll. */
2481   if (old_state > GST_STATE_PAUSED)
2482     new_state = GST_STATE_PAUSED;
2483   else
2484     new_state = old_state;
2485
2486   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2487       "lost state of %s to %s", gst_element_state_get_name (old_state),
2488       gst_element_state_get_name (new_state));
2489
2490   GST_STATE (element) = new_state;
2491   GST_STATE_NEXT (element) = new_state;
2492   GST_STATE_PENDING (element) = new_state;
2493   GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2494   GST_OBJECT_UNLOCK (element);
2495
2496   _priv_gst_element_state_changed (element, new_state, new_state, new_state);
2497
2498   message = gst_message_new_async_start (GST_OBJECT_CAST (element));
2499   gst_element_post_message (element, message);
2500
2501   return;
2502
2503 nothing_lost:
2504   {
2505     GST_OBJECT_UNLOCK (element);
2506     return;
2507   }
2508 only_async_start:
2509   {
2510     GST_OBJECT_UNLOCK (element);
2511
2512     message = gst_message_new_async_start (GST_OBJECT_CAST (element));
2513     gst_element_post_message (element, message);
2514     return;
2515   }
2516 }
2517
2518 /**
2519  * gst_element_set_state:
2520  * @element: a #GstElement to change state of.
2521  * @state: the element's new #GstState.
2522  *
2523  * Sets the state of the element. This function will try to set the
2524  * requested state by going through all the intermediary states and calling
2525  * the class's state change function for each.
2526  *
2527  * This function can return #GST_STATE_CHANGE_ASYNC, in which case the
2528  * element will perform the remainder of the state change asynchronously in
2529  * another thread.
2530  * An application can use gst_element_get_state() to wait for the completion
2531  * of the state change or it can wait for a %GST_MESSAGE_ASYNC_DONE or
2532  * %GST_MESSAGE_STATE_CHANGED on the bus.
2533  *
2534  * State changes to %GST_STATE_READY or %GST_STATE_NULL never return
2535  * #GST_STATE_CHANGE_ASYNC.
2536  *
2537  * Returns: Result of the state change using #GstStateChangeReturn.
2538  *
2539  * MT safe.
2540  */
2541 GstStateChangeReturn
2542 gst_element_set_state (GstElement * element, GstState state)
2543 {
2544   GstElementClass *oclass;
2545   GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
2546
2547   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2548
2549   oclass = GST_ELEMENT_GET_CLASS (element);
2550
2551   if (oclass->set_state)
2552     result = (oclass->set_state) (element, state);
2553
2554   return result;
2555 }
2556
2557 /*
2558  * default set state function, calculates the next state based
2559  * on current state and calls the change_state function
2560  */
2561 static GstStateChangeReturn
2562 gst_element_set_state_func (GstElement * element, GstState state)
2563 {
2564   GstState current, next, old_pending;
2565   GstStateChangeReturn ret;
2566   GstStateChange transition;
2567   GstStateChangeReturn old_ret;
2568
2569   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2570
2571   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "set_state to %s",
2572       gst_element_state_get_name (state));
2573
2574   /* state lock is taken to protect the set_state() and get_state()
2575    * procedures, it does not lock any variables. */
2576   GST_STATE_LOCK (element);
2577
2578   /* now calculate how to get to the new state */
2579   GST_OBJECT_LOCK (element);
2580   old_ret = GST_STATE_RETURN (element);
2581   /* previous state change returned an error, remove all pending
2582    * and next states */
2583   if (old_ret == GST_STATE_CHANGE_FAILURE) {
2584     GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
2585     GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2586     GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
2587   }
2588
2589   current = GST_STATE (element);
2590   next = GST_STATE_NEXT (element);
2591   old_pending = GST_STATE_PENDING (element);
2592
2593   /* this is the (new) state we should go to. TARGET is the last state we set on
2594    * the element. */
2595   if (state != GST_STATE_TARGET (element)) {
2596     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2597         "setting target state to %s", gst_element_state_get_name (state));
2598     GST_STATE_TARGET (element) = state;
2599     /* increment state cookie so that we can track each state change. We only do
2600      * this if this is actually a new state change. */
2601     element->state_cookie++;
2602   }
2603   GST_STATE_PENDING (element) = state;
2604
2605   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2606       "current %s, old_pending %s, next %s, old return %s",
2607       gst_element_state_get_name (current),
2608       gst_element_state_get_name (old_pending),
2609       gst_element_state_get_name (next),
2610       gst_element_state_change_return_get_name (old_ret));
2611
2612   /* if the element was busy doing a state change, we just update the
2613    * target state, it'll get to it async then. */
2614   if (old_pending != GST_STATE_VOID_PENDING) {
2615     /* upwards state change will happen ASYNC */
2616     if (old_pending <= state)
2617       goto was_busy;
2618     /* element is going to this state already */
2619     else if (next == state)
2620       goto was_busy;
2621     /* element was performing an ASYNC upward state change and
2622      * we request to go downward again. Start from the next pending
2623      * state then. */
2624     else if (next > state
2625         && GST_STATE_RETURN (element) == GST_STATE_CHANGE_ASYNC) {
2626       current = next;
2627     }
2628   }
2629   next = GST_STATE_GET_NEXT (current, state);
2630   /* now we store the next state */
2631   GST_STATE_NEXT (element) = next;
2632   /* mark busy, we need to check that there is actually a state change
2633    * to be done else we could accidentally override SUCCESS/NO_PREROLL and
2634    * the default element change_state function has no way to know what the
2635    * old value was... could consider this a FIXME...*/
2636   if (current != next)
2637     GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2638
2639   transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2640
2641   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2642       "%s: setting state from %s to %s",
2643       (next != state ? "intermediate" : "final"),
2644       gst_element_state_get_name (current), gst_element_state_get_name (next));
2645
2646   /* now signal any waiters, they will error since the cookie was incremented */
2647   GST_STATE_BROADCAST (element);
2648
2649   GST_OBJECT_UNLOCK (element);
2650
2651   ret = gst_element_change_state (element, transition);
2652
2653   GST_STATE_UNLOCK (element);
2654
2655   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "returned %s",
2656       gst_element_state_change_return_get_name (ret));
2657
2658   return ret;
2659
2660 was_busy:
2661   {
2662     GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2663     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2664         "element was busy with async state change");
2665     GST_OBJECT_UNLOCK (element);
2666
2667     GST_STATE_UNLOCK (element);
2668
2669     return GST_STATE_CHANGE_ASYNC;
2670   }
2671 }
2672
2673 /**
2674  * gst_element_change_state:
2675  * @element: a #GstElement
2676  * @transition: the requested transition
2677  *
2678  * Perform @transition on @element.
2679  *
2680  * This function must be called with STATE_LOCK held and is mainly used
2681  * internally.
2682  *
2683  * Returns: the #GstStateChangeReturn of the state transition.
2684  */
2685 GstStateChangeReturn
2686 gst_element_change_state (GstElement * element, GstStateChange transition)
2687 {
2688   GstElementClass *oclass;
2689   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2690
2691   oclass = GST_ELEMENT_GET_CLASS (element);
2692
2693   GST_TRACER_ELEMENT_CHANGE_STATE_PRE (element, transition);
2694
2695   /* call the state change function so it can set the state */
2696   if (oclass->change_state)
2697     ret = (oclass->change_state) (element, transition);
2698   else
2699     ret = GST_STATE_CHANGE_FAILURE;
2700
2701   GST_TRACER_ELEMENT_CHANGE_STATE_POST (element, transition, ret);
2702
2703   switch (ret) {
2704     case GST_STATE_CHANGE_FAILURE:
2705       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2706           "have FAILURE change_state return");
2707       /* state change failure */
2708       gst_element_abort_state (element);
2709       break;
2710     case GST_STATE_CHANGE_ASYNC:
2711     {
2712       GstState target;
2713
2714       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2715           "element will change state ASYNC");
2716
2717       target = GST_STATE_TARGET (element);
2718
2719       if (target > GST_STATE_READY)
2720         goto async;
2721
2722       /* else we just continue the state change downwards */
2723       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2724           "forcing commit state %s <= %s",
2725           gst_element_state_get_name (target),
2726           gst_element_state_get_name (GST_STATE_READY));
2727
2728       ret = gst_element_continue_state (element, GST_STATE_CHANGE_SUCCESS);
2729       break;
2730     }
2731     case GST_STATE_CHANGE_SUCCESS:
2732       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2733           "element changed state SUCCESS");
2734       /* we can commit the state now which will proceeed to
2735        * the next state */
2736       ret = gst_element_continue_state (element, ret);
2737       break;
2738     case GST_STATE_CHANGE_NO_PREROLL:
2739       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2740           "element changed state NO_PREROLL");
2741       /* we can commit the state now which will proceeed to
2742        * the next state */
2743       ret = gst_element_continue_state (element, ret);
2744       break;
2745     default:
2746       goto invalid_return;
2747   }
2748
2749   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit state change %d", ret);
2750
2751   return ret;
2752
2753 async:
2754   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit async state change %d",
2755       ret);
2756
2757   return ret;
2758
2759   /* ERROR */
2760 invalid_return:
2761   {
2762     GST_OBJECT_LOCK (element);
2763     /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2764     g_critical ("%s: unknown return value %d from a state change function",
2765         GST_ELEMENT_NAME (element), ret);
2766
2767     /* we are in error now */
2768     ret = GST_STATE_CHANGE_FAILURE;
2769     GST_STATE_RETURN (element) = ret;
2770     GST_OBJECT_UNLOCK (element);
2771
2772     return ret;
2773   }
2774 }
2775
2776 /* gst_iterator_fold functions for pads_activate
2777  * Stop the iterator if activating one pad failed, but only if that pad
2778  * has not been removed from the element. */
2779 static gboolean
2780 activate_pads (const GValue * vpad, GValue * ret, gboolean * active)
2781 {
2782   GstPad *pad = g_value_get_object (vpad);
2783   gboolean cont = TRUE;
2784
2785   if (!gst_pad_set_active (pad, *active)) {
2786     if (GST_PAD_PARENT (pad) != NULL) {
2787       cont = FALSE;
2788       g_value_set_boolean (ret, FALSE);
2789     }
2790   }
2791
2792   return cont;
2793 }
2794
2795 /* returns false on error or early cutout of the fold, true if all
2796  * pads in @iter were (de)activated successfully. */
2797 static gboolean
2798 iterator_activate_fold_with_resync (GstIterator * iter,
2799     GstIteratorFoldFunction func, gpointer user_data)
2800 {
2801   GstIteratorResult ires;
2802   GValue ret = { 0 };
2803
2804   /* no need to unset this later, it's just a boolean */
2805   g_value_init (&ret, G_TYPE_BOOLEAN);
2806   g_value_set_boolean (&ret, TRUE);
2807
2808   while (1) {
2809     ires = gst_iterator_fold (iter, func, &ret, user_data);
2810     switch (ires) {
2811       case GST_ITERATOR_RESYNC:
2812         /* need to reset the result again */
2813         g_value_set_boolean (&ret, TRUE);
2814         gst_iterator_resync (iter);
2815         break;
2816       case GST_ITERATOR_DONE:
2817         /* all pads iterated, return collected value */
2818         goto done;
2819       default:
2820         /* iterator returned _ERROR or premature end with _OK,
2821          * mark an error and exit */
2822         g_value_set_boolean (&ret, FALSE);
2823         goto done;
2824     }
2825   }
2826 done:
2827   /* return collected value */
2828   return g_value_get_boolean (&ret);
2829 }
2830
2831 /* is called with STATE_LOCK
2832  *
2833  * Pads are activated from source pads to sinkpads.
2834  */
2835 static gboolean
2836 gst_element_pads_activate (GstElement * element, gboolean active)
2837 {
2838   GstIterator *iter;
2839   gboolean res;
2840
2841   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2842       "%s pads", active ? "activate" : "deactivate");
2843
2844   iter = gst_element_iterate_src_pads (element);
2845   res =
2846       iterator_activate_fold_with_resync (iter,
2847       (GstIteratorFoldFunction) activate_pads, &active);
2848   gst_iterator_free (iter);
2849   if (G_UNLIKELY (!res))
2850     goto src_failed;
2851
2852   iter = gst_element_iterate_sink_pads (element);
2853   res =
2854       iterator_activate_fold_with_resync (iter,
2855       (GstIteratorFoldFunction) activate_pads, &active);
2856   gst_iterator_free (iter);
2857   if (G_UNLIKELY (!res))
2858     goto sink_failed;
2859
2860   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2861       "pad %sactivation successful", active ? "" : "de");
2862
2863   return TRUE;
2864
2865   /* ERRORS */
2866 src_failed:
2867   {
2868     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2869         "pad %sactivation failed", active ? "" : "de");
2870     return FALSE;
2871   }
2872 sink_failed:
2873   {
2874     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2875         "sink pads_activate failed");
2876     return FALSE;
2877   }
2878 }
2879
2880 /* is called with STATE_LOCK */
2881 static GstStateChangeReturn
2882 gst_element_change_state_func (GstElement * element, GstStateChange transition)
2883 {
2884   GstState state, next;
2885   GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
2886
2887   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2888
2889   state = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
2890   next = GST_STATE_TRANSITION_NEXT (transition);
2891
2892   /* if the element already is in the given state, we just return success */
2893   if (next == GST_STATE_VOID_PENDING || state == next)
2894     goto was_ok;
2895
2896   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2897       "default handler tries setting state from %s to %s (%04x)",
2898       gst_element_state_get_name (state),
2899       gst_element_state_get_name (next), transition);
2900
2901   switch (transition) {
2902     case GST_STATE_CHANGE_NULL_TO_READY:
2903       break;
2904     case GST_STATE_CHANGE_READY_TO_PAUSED:
2905       if (!gst_element_pads_activate (element, TRUE)) {
2906         result = GST_STATE_CHANGE_FAILURE;
2907       }
2908       break;
2909     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2910       break;
2911     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2912       break;
2913     case GST_STATE_CHANGE_PAUSED_TO_READY:
2914     case GST_STATE_CHANGE_READY_TO_NULL:{
2915       GList *l;
2916
2917       /* deactivate pads in both cases, since they are activated on
2918          ready->paused but the element might not have made it to paused */
2919       if (!gst_element_pads_activate (element, FALSE)) {
2920         result = GST_STATE_CHANGE_FAILURE;
2921       }
2922
2923       /* Remove all non-persistent contexts */
2924       GST_OBJECT_LOCK (element);
2925       for (l = element->contexts; l;) {
2926         GstContext *context = l->data;
2927
2928         if (!gst_context_is_persistent (context)) {
2929           GList *next;
2930
2931           gst_context_unref (context);
2932           next = l->next;
2933           element->contexts = g_list_delete_link (element->contexts, l);
2934           l = next;
2935         } else {
2936           l = l->next;
2937         }
2938       }
2939       GST_OBJECT_UNLOCK (element);
2940       break;
2941     }
2942     default:
2943       /* this will catch real but unhandled state changes;
2944        * can only be caused by:
2945        * - a new state was added
2946        * - somehow the element was asked to jump across an intermediate state
2947        */
2948       g_warning ("Unhandled state change from %s to %s",
2949           gst_element_state_get_name (state),
2950           gst_element_state_get_name (next));
2951       break;
2952   }
2953   return result;
2954
2955 was_ok:
2956   {
2957     GST_OBJECT_LOCK (element);
2958     result = GST_STATE_RETURN (element);
2959     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2960         "element is already in the %s state",
2961         gst_element_state_get_name (state));
2962     GST_OBJECT_UNLOCK (element);
2963
2964     return result;
2965   }
2966 }
2967
2968 /**
2969  * gst_element_get_factory:
2970  * @element: a #GstElement to request the element factory of.
2971  *
2972  * Retrieves the factory that was used to create this element.
2973  *
2974  * Returns: (transfer none): the #GstElementFactory used for creating this
2975  *     element. no refcounting is needed.
2976  */
2977 GstElementFactory *
2978 gst_element_get_factory (GstElement * element)
2979 {
2980   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2981
2982   return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2983 }
2984
2985 static void
2986 gst_element_dispose (GObject * object)
2987 {
2988   GstElement *element = GST_ELEMENT_CAST (object);
2989   GstClock **clock_p;
2990   GstBus **bus_p;
2991   GstElementClass *oclass;
2992   GList *walk;
2993
2994   oclass = GST_ELEMENT_GET_CLASS (element);
2995
2996   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p dispose", element);
2997
2998   if (GST_STATE (element) != GST_STATE_NULL)
2999     goto not_null;
3000
3001   /* start by releasing all request pads, this might also remove some dynamic
3002    * pads */
3003   walk = element->pads;
3004   while (walk) {
3005     GstPad *pad = GST_PAD_CAST (walk->data);
3006
3007     walk = walk->next;
3008
3009     if (oclass->release_pad && GST_PAD_PAD_TEMPLATE (pad) &&
3010         GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad))
3011         == GST_PAD_REQUEST) {
3012       GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
3013           "removing request pad %s:%s", GST_DEBUG_PAD_NAME (pad));
3014       oclass->release_pad (element, pad);
3015
3016       /* in case the release_pad function removed the next pad too */
3017       if (walk && g_list_position (element->pads, walk) == -1)
3018         walk = element->pads;
3019     }
3020   }
3021   /* remove the remaining pads */
3022   while (element->pads) {
3023     GstPad *pad = GST_PAD_CAST (element->pads->data);
3024     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
3025         "removing pad %s:%s", GST_DEBUG_PAD_NAME (pad));
3026     if (!gst_element_remove_pad (element, pad)) {
3027       /* only happens when someone unparented our pad.. */
3028       g_critical ("failed to remove pad %s:%s", GST_DEBUG_PAD_NAME (pad));
3029       break;
3030     }
3031   }
3032
3033   GST_OBJECT_LOCK (element);
3034   clock_p = &element->clock;
3035   bus_p = &element->bus;
3036   gst_object_replace ((GstObject **) clock_p, NULL);
3037   gst_object_replace ((GstObject **) bus_p, NULL);
3038   g_list_free_full (element->contexts, (GDestroyNotify) gst_context_unref);
3039   GST_OBJECT_UNLOCK (element);
3040
3041   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p parent class dispose",
3042       element);
3043
3044   G_OBJECT_CLASS (parent_class)->dispose (object);
3045
3046   return;
3047
3048   /* ERRORS */
3049 not_null:
3050   {
3051     gboolean is_locked;
3052
3053     is_locked = GST_ELEMENT_IS_LOCKED_STATE (element);
3054     g_critical
3055         ("\nTrying to dispose element %s, but it is in %s%s instead of the NULL"
3056         " state.\n"
3057         "You need to explicitly set elements to the NULL state before\n"
3058         "dropping the final reference, to allow them to clean up.\n"
3059         "This problem may also be caused by a refcounting bug in the\n"
3060         "application or some element.\n",
3061         GST_OBJECT_NAME (element),
3062         gst_element_state_get_name (GST_STATE (element)),
3063         is_locked ? " (locked)" : "");
3064     return;
3065   }
3066 }
3067
3068 static void
3069 gst_element_finalize (GObject * object)
3070 {
3071   GstElement *element = GST_ELEMENT_CAST (object);
3072
3073   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p finalize", element);
3074
3075   g_cond_clear (&element->state_cond);
3076   g_rec_mutex_clear (&element->state_lock);
3077
3078   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p finalize parent",
3079       element);
3080
3081   G_OBJECT_CLASS (parent_class)->finalize (object);
3082 }
3083
3084 static void
3085 gst_element_set_bus_func (GstElement * element, GstBus * bus)
3086 {
3087   GstBus **bus_p;
3088
3089   g_return_if_fail (GST_IS_ELEMENT (element));
3090
3091   GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
3092
3093   GST_OBJECT_LOCK (element);
3094   bus_p = &GST_ELEMENT_BUS (element);
3095   gst_object_replace ((GstObject **) bus_p, GST_OBJECT_CAST (bus));
3096   GST_OBJECT_UNLOCK (element);
3097 }
3098
3099 /**
3100  * gst_element_set_bus:
3101  * @element: a #GstElement to set the bus of.
3102  * @bus: (transfer none): the #GstBus to set.
3103  *
3104  * Sets the bus of the element. Increases the refcount on the bus.
3105  * For internal use only, unless you're testing elements.
3106  *
3107  * MT safe.
3108  */
3109 void
3110 gst_element_set_bus (GstElement * element, GstBus * bus)
3111 {
3112   GstElementClass *oclass;
3113
3114   g_return_if_fail (GST_IS_ELEMENT (element));
3115
3116   oclass = GST_ELEMENT_GET_CLASS (element);
3117
3118   if (oclass->set_bus)
3119     oclass->set_bus (element, bus);
3120 }
3121
3122 /**
3123  * gst_element_get_bus:
3124  * @element: a #GstElement to get the bus of.
3125  *
3126  * Returns the bus of the element. Note that only a #GstPipeline will provide a
3127  * bus for the application.
3128  *
3129  * Returns: (transfer full): the element's #GstBus. unref after usage.
3130  *
3131  * MT safe.
3132  */
3133 GstBus *
3134 gst_element_get_bus (GstElement * element)
3135 {
3136   GstBus *result = NULL;
3137
3138   g_return_val_if_fail (GST_IS_ELEMENT (element), result);
3139
3140   GST_OBJECT_LOCK (element);
3141   if ((result = GST_ELEMENT_BUS (element)))
3142     gst_object_ref (result);
3143   GST_OBJECT_UNLOCK (element);
3144
3145   GST_CAT_DEBUG_OBJECT (GST_CAT_BUS, element, "got bus %" GST_PTR_FORMAT,
3146       result);
3147
3148   return result;
3149 }
3150
3151 static void
3152 gst_element_set_context_default (GstElement * element, GstContext * context)
3153 {
3154   const gchar *context_type;
3155   GList *l;
3156
3157   GST_OBJECT_LOCK (element);
3158   context_type = gst_context_get_context_type (context);
3159   for (l = element->contexts; l; l = l->next) {
3160     GstContext *tmp = l->data;
3161     const gchar *tmp_type = gst_context_get_context_type (tmp);
3162
3163     /* Always store newest context but never replace
3164      * a persistent one by a non-persistent one */
3165     if (strcmp (context_type, tmp_type) == 0 &&
3166         (gst_context_is_persistent (context) ||
3167             !gst_context_is_persistent (tmp))) {
3168       gst_context_replace ((GstContext **) & l->data, context);
3169       break;
3170     }
3171   }
3172   /* Not found? Add */
3173   if (l == NULL) {
3174     element->contexts =
3175         g_list_prepend (element->contexts, gst_context_ref (context));
3176   }
3177   GST_OBJECT_UNLOCK (element);
3178 }
3179
3180 /**
3181  * gst_element_set_context:
3182  * @element: a #GstElement to set the context of.
3183  * @context: (transfer none): the #GstContext to set.
3184  *
3185  * Sets the context of the element. Increases the refcount of the context.
3186  *
3187  * MT safe.
3188  */
3189 void
3190 gst_element_set_context (GstElement * element, GstContext * context)
3191 {
3192   GstElementClass *oclass;
3193
3194   g_return_if_fail (GST_IS_ELEMENT (element));
3195
3196   oclass = GST_ELEMENT_GET_CLASS (element);
3197
3198   GST_CAT_DEBUG_OBJECT (GST_CAT_CONTEXT, element,
3199       "set context %p %" GST_PTR_FORMAT, context,
3200       gst_context_get_structure (context));
3201
3202   if (oclass->set_context)
3203     oclass->set_context (element, context);
3204 }
3205
3206 /**
3207  * gst_element_get_contexts:
3208  * @element: a #GstElement to set the context of.
3209  *
3210  * Gets the contexts set on the element.
3211  *
3212  * MT safe.
3213  *
3214  * Returns: (element-type Gst.Context) (transfer full): List of #GstContext
3215  *
3216  * Since: 1.8
3217  */
3218 GList *
3219 gst_element_get_contexts (GstElement * element)
3220 {
3221   GList *ret;
3222
3223   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3224
3225   GST_OBJECT_LOCK (element);
3226   ret = g_list_copy_deep (element->contexts, (GCopyFunc) gst_context_ref, NULL);
3227   GST_OBJECT_UNLOCK (element);
3228
3229   return ret;
3230 }
3231
3232 static gint
3233 _match_context_type (GstContext * c1, const gchar * context_type)
3234 {
3235   const gchar *c1_type;
3236
3237   c1_type = gst_context_get_context_type (c1);
3238
3239   return g_strcmp0 (c1_type, context_type);
3240 }
3241
3242 /**
3243  * gst_element_get_context_unlocked:
3244  * @element: a #GstElement to get the context of.
3245  * @context_type: a name of a context to retrieve
3246  *
3247  * Gets the context with @context_type set on the element or NULL.
3248  *
3249  * Returns: (transfer full): A #GstContext or NULL
3250  *
3251  * Since: 1.8
3252  */
3253 GstContext *
3254 gst_element_get_context_unlocked (GstElement * element,
3255     const gchar * context_type)
3256 {
3257   GstContext *ret = NULL;
3258   GList *node;
3259
3260   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3261
3262   node =
3263       g_list_find_custom (element->contexts, context_type,
3264       (GCompareFunc) _match_context_type);
3265   if (node && node->data)
3266     ret = gst_context_ref (node->data);
3267
3268   return ret;
3269 }
3270
3271 /**
3272  * gst_element_get_context:
3273  * @element: a #GstElement to get the context of.
3274  * @context_type: a name of a context to retrieve
3275  *
3276  * Gets the context with @context_type set on the element or NULL.
3277  *
3278  * MT safe.
3279  *
3280  * Returns: (transfer full): A #GstContext or NULL
3281  *
3282  * Since: 1.8
3283  */
3284 GstContext *
3285 gst_element_get_context (GstElement * element, const gchar * context_type)
3286 {
3287   GstContext *ret = NULL;
3288
3289   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3290
3291   GST_OBJECT_LOCK (element);
3292   ret = gst_element_get_context_unlocked (element, context_type);
3293   GST_OBJECT_UNLOCK (element);
3294
3295   return ret;
3296 }
3297
3298 static void
3299 gst_element_property_post_notify_msg (GstElement * element, GObject * obj,
3300     GParamSpec * pspec, gboolean include_value)
3301 {
3302   GValue val = G_VALUE_INIT;
3303   GValue *v;
3304
3305   GST_LOG_OBJECT (element, "property '%s' of object %" GST_PTR_FORMAT " has "
3306       "changed, posting message with%s value", pspec->name, obj,
3307       include_value ? "" : "out");
3308
3309   if (include_value && (pspec->flags & G_PARAM_READABLE) != 0) {
3310     g_value_init (&val, pspec->value_type);
3311     g_object_get_property (obj, pspec->name, &val);
3312     v = &val;
3313   } else {
3314     v = NULL;
3315   }
3316   gst_element_post_message (element,
3317       gst_message_new_property_notify (GST_OBJECT_CAST (obj), pspec->name, v));
3318 }
3319
3320 static void
3321 gst_element_property_deep_notify_cb (GstElement * element, GObject * prop_obj,
3322     GParamSpec * pspec, gpointer user_data)
3323 {
3324   gboolean include_value = GPOINTER_TO_INT (user_data);
3325
3326   gst_element_property_post_notify_msg (element, prop_obj, pspec,
3327       include_value);
3328 }
3329
3330 static void
3331 gst_element_property_notify_cb (GObject * obj, GParamSpec * pspec,
3332     gpointer user_data)
3333 {
3334   gboolean include_value = GPOINTER_TO_INT (user_data);
3335
3336   gst_element_property_post_notify_msg (GST_ELEMENT_CAST (obj), obj, pspec,
3337       include_value);
3338 }
3339
3340 /**
3341  * gst_element_add_property_notify_watch:
3342  * @element: a #GstElement to watch for property changes
3343  * @property_name: (allow-none): name of property to watch for changes, or
3344  *     NULL to watch all properties
3345  * @include_value: whether to include the new property value in the message
3346  *
3347  * Returns: a watch id, which can be used in connection with
3348  *     gst_element_remove_property_notify_watch() to remove the watch again.
3349  *
3350  * Since: 1.10
3351  */
3352 gulong
3353 gst_element_add_property_notify_watch (GstElement * element,
3354     const gchar * property_name, gboolean include_value)
3355 {
3356   const gchar *sep;
3357   gchar *signal_name;
3358   gulong id;
3359
3360   g_return_val_if_fail (GST_IS_ELEMENT (element), 0);
3361
3362   sep = (property_name != NULL) ? "::" : NULL;
3363   signal_name = g_strconcat ("notify", sep, property_name, NULL);
3364   id = g_signal_connect (element, signal_name,
3365       G_CALLBACK (gst_element_property_notify_cb),
3366       GINT_TO_POINTER (include_value));
3367   g_free (signal_name);
3368
3369   return id;
3370 }
3371
3372 /**
3373  * gst_element_add_property_deep_notify_watch:
3374  * @element: a #GstElement to watch (recursively) for property changes
3375  * @property_name: (allow-none): name of property to watch for changes, or
3376  *     NULL to watch all properties
3377  * @include_value: whether to include the new property value in the message
3378  *
3379  * Returns: a watch id, which can be used in connection with
3380  *     gst_element_remove_property_notify_watch() to remove the watch again.
3381  *
3382  * Since: 1.10
3383  */
3384 gulong
3385 gst_element_add_property_deep_notify_watch (GstElement * element,
3386     const gchar * property_name, gboolean include_value)
3387 {
3388   const gchar *sep;
3389   gchar *signal_name;
3390   gulong id;
3391
3392   g_return_val_if_fail (GST_IS_ELEMENT (element), 0);
3393
3394   sep = (property_name != NULL) ? "::" : NULL;
3395   signal_name = g_strconcat ("deep-notify", sep, property_name, NULL);
3396   id = g_signal_connect (element, signal_name,
3397       G_CALLBACK (gst_element_property_deep_notify_cb),
3398       GINT_TO_POINTER (include_value));
3399   g_free (signal_name);
3400
3401   return id;
3402 }
3403
3404 /**
3405  * gst_element_remove_property_notify_watch:
3406  * @element: a #GstElement being watched for property changes
3407  * @watch_id: watch id to remove
3408  *
3409  * Since: 1.10
3410  */
3411 void
3412 gst_element_remove_property_notify_watch (GstElement * element, gulong watch_id)
3413 {
3414   g_signal_handler_disconnect (element, watch_id);
3415 }
3416
3417 typedef struct
3418 {
3419   GstElement *element;
3420   GstElementCallAsyncFunc func;
3421   gpointer user_data;
3422   GDestroyNotify destroy_notify;
3423 } GstElementCallAsyncData;
3424
3425 static void
3426 gst_element_call_async_func (gpointer data, gpointer user_data)
3427 {
3428   GstElementCallAsyncData *async_data = data;
3429
3430   async_data->func (async_data->element, async_data->user_data);
3431   if (async_data->destroy_notify)
3432     async_data->destroy_notify (async_data->user_data);
3433   gst_object_unref (async_data->element);
3434   g_free (async_data);
3435 }
3436
3437 /**
3438  * gst_element_call_async:
3439  * @element: a #GstElement
3440  * @func: Function to call asynchronously from another thread
3441  * @user_data: Data to pass to @func
3442  * @destroy_notify: GDestroyNotify for @user_data
3443  *
3444  * Calls @func from another thread and passes @user_data to it. This is to be
3445  * used for cases when a state change has to be performed from a streaming
3446  * thread, directly via gst_element_set_state() or indirectly e.g. via SEEK
3447  * events.
3448  *
3449  * Calling those functions directly from the streaming thread will cause
3450  * deadlocks in many situations, as they might involve waiting for the
3451  * streaming thread to shut down from this very streaming thread.
3452  *
3453  * MT safe.
3454  *
3455  * Since: 1.10
3456  */
3457 void
3458 gst_element_call_async (GstElement * element, GstElementCallAsyncFunc func,
3459     gpointer user_data, GDestroyNotify destroy_notify)
3460 {
3461   GstElementCallAsyncData *async_data;
3462
3463   g_return_if_fail (GST_IS_ELEMENT (element));
3464
3465   async_data = g_new0 (GstElementCallAsyncData, 1);
3466   async_data->element = gst_object_ref (element);
3467   async_data->func = func;
3468   async_data->user_data = user_data;
3469   async_data->destroy_notify = destroy_notify;
3470
3471   g_thread_pool_push (gst_element_pool, async_data, NULL);
3472 }
3473
3474 void
3475 _priv_gst_element_cleanup (void)
3476 {
3477   if (gst_element_pool) {
3478     g_thread_pool_free (gst_element_pool, FALSE, TRUE);
3479     gst_element_setup_thread_pool ();
3480   }
3481 }
3482
3483 GstStructure *
3484 gst_element_message_details_new (const char *name, ...)
3485 {
3486   GstStructure *structure;
3487   va_list varargs;
3488
3489   if (name == NULL)
3490     return NULL;
3491
3492   va_start (varargs, name);
3493   structure = gst_structure_new_valist ("details", name, varargs);
3494   va_end (varargs);
3495
3496   return structure;
3497 }