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