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