Move dataurisrc element from -bad
[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 gboolean
924 gst_element_is_valid_request_template_name (const gchar * templ_name,
925     const gchar * name)
926 {
927   gchar *endptr;
928   const gchar *templ_name_ptr, *name_ptr;
929   gboolean next_specifier;
930   guint templ_postfix_len = 0, name_postfix_len = 0;
931
932   g_return_val_if_fail (templ_name != NULL, FALSE);
933   g_return_val_if_fail (name != NULL, FALSE);
934
935   /* Is this the template name? */
936   if (strcmp (templ_name, name) == 0)
937     return TRUE;
938
939   /* otherwise check all the specifiers */
940   do {
941     /* Because of sanity checks in gst_pad_template_new(), we know that %s
942      * and %d and %u, occurring at the template_name */
943     templ_name_ptr = strchr (templ_name, '%');
944
945     /* check characters ahead of the specifier */
946     if (!templ_name_ptr || strlen (name) <= templ_name_ptr - templ_name
947         || strncmp (templ_name, name, templ_name_ptr - templ_name) != 0) {
948       return FALSE;
949     }
950
951     /* %s is not allowed for multiple specifiers, just a single specifier can be
952      * accepted in gst_pad_template_new() and can not be mixed with other
953      * specifier '%u' and '%d' */
954     if (*(templ_name_ptr + 1) == 's' && g_strcmp0 (templ_name, name) == 0) {
955       return TRUE;
956     }
957
958     name_ptr = name + (templ_name_ptr - templ_name);
959
960     /* search next specifier, each of specifier should be separated by '_' */
961     templ_name = strchr (templ_name_ptr, '_');
962     name = strchr (name_ptr, '_');
963
964     /* don't match the number of specifiers */
965     if ((templ_name && !name) || (!templ_name && name))
966       return FALSE;
967
968     if (templ_name && name)
969       next_specifier = TRUE;
970     else
971       next_specifier = FALSE;
972
973     /* check characters followed by the specifier */
974     if (*(templ_name_ptr + 2) != '\0' && *(templ_name_ptr + 2) != '_') {
975       if (next_specifier) {
976         templ_postfix_len = templ_name - (templ_name_ptr + 2);
977         name_postfix_len = name - name_ptr;
978       } else {
979         templ_postfix_len = strlen (templ_name_ptr + 2);
980         name_postfix_len = strlen (name_ptr);
981       }
982
983       if (strncmp (templ_name_ptr + 2,
984               name_ptr + name_postfix_len - templ_postfix_len,
985               templ_postfix_len) != 0) {
986         return FALSE;
987       }
988     }
989
990     /* verify the specifier */
991     if (*(name_ptr) == '%') {
992       guint len;
993
994       len = (next_specifier) ? name - name_ptr : strlen (name_ptr);
995
996       if (strncmp (name_ptr, templ_name_ptr, len) != 0)
997         return FALSE;
998
999     } else {
1000       const gchar *specifier;
1001       gchar *target = NULL;
1002
1003       /* extract specifier when it has postfix characters */
1004       if (name_postfix_len > templ_postfix_len) {
1005         target = g_strndup (name_ptr, name_postfix_len - templ_postfix_len);
1006       }
1007       specifier = target ? target : name_ptr;
1008
1009       if (*(templ_name_ptr + 1) == 'd') {
1010         gint64 tmp;
1011
1012         /* it's an int */
1013         tmp = g_ascii_strtoll (specifier, &endptr, 10);
1014         if (tmp < G_MININT || tmp > G_MAXINT || (*endptr != '\0'
1015                 && *endptr != '_'))
1016           return FALSE;
1017       } else if (*(templ_name_ptr + 1) == 'u') {
1018         guint64 tmp;
1019
1020         /* it's an int */
1021         tmp = g_ascii_strtoull (specifier, &endptr, 10);
1022         if (tmp > G_MAXUINT || (*endptr != '\0' && *endptr != '_'))
1023           return FALSE;
1024       }
1025
1026       g_free (target);
1027     }
1028
1029     /* otherwise we increment these from NULL to 1 */
1030     if (next_specifier) {
1031       templ_name++;
1032       name++;
1033     }
1034   } while (next_specifier);
1035
1036   return TRUE;
1037 }
1038
1039 static GstPad *
1040 _gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
1041     const gchar * name, const GstCaps * caps)
1042 {
1043   GstPad *newpad = NULL;
1044   GstElementClass *oclass;
1045
1046   oclass = GST_ELEMENT_GET_CLASS (element);
1047
1048 #ifndef G_DISABLE_CHECKS
1049   /* Some sanity checking here */
1050   if (name) {
1051     GstPad *pad;
1052
1053     g_return_val_if_fail (gst_element_is_valid_request_template_name
1054         (templ->name_template, name), NULL);
1055
1056     pad = gst_element_get_static_pad (element, name);
1057     if (pad) {
1058       gst_object_unref (pad);
1059       /* FIXME 2.0: Change this to g_return_val_if_fail() */
1060       g_critical ("Element %s already has a pad named %s, the behaviour of "
1061           " gst_element_get_request_pad() for existing pads is undefined!",
1062           GST_ELEMENT_NAME (element), name);
1063     }
1064   }
1065 #endif
1066
1067   if (oclass->request_new_pad)
1068     newpad = (oclass->request_new_pad) (element, templ, name, caps);
1069
1070   if (newpad)
1071     gst_object_ref (newpad);
1072
1073   return newpad;
1074 }
1075
1076 /**
1077  * gst_element_get_request_pad:
1078  * @element: a #GstElement to find a request pad of.
1079  * @name: the name of the request #GstPad to retrieve.
1080  *
1081  * Retrieves a pad from the element by name (e.g. "src_\%d"). This version only
1082  * retrieves request pads. The pad should be released with
1083  * gst_element_release_request_pad().
1084  *
1085  * This method is slower than manually getting the pad template and calling
1086  * gst_element_request_pad() if the pads should have a specific name (e.g.
1087  * @name is "src_1" instead of "src_\%u").
1088  *
1089  * Returns: (transfer full) (nullable): requested #GstPad if found,
1090  *     otherwise %NULL.  Release after usage.
1091  */
1092 GstPad *
1093 gst_element_get_request_pad (GstElement * element, const gchar * name)
1094 {
1095   GstPadTemplate *templ = NULL;
1096   GstPad *pad;
1097   const gchar *req_name = NULL;
1098   gboolean templ_found = FALSE;
1099   GList *list;
1100   GstElementClass *class;
1101
1102   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1103   g_return_val_if_fail (name != NULL, NULL);
1104
1105   class = GST_ELEMENT_GET_CLASS (element);
1106
1107   templ = gst_element_class_get_request_pad_template (class, name);
1108   if (templ) {
1109     req_name = strstr (name, "%") ? NULL : name;
1110     templ_found = TRUE;
1111   } else {
1112     /* there is no % in the name, try to find a matching template */
1113     list = class->padtemplates;
1114     while (!templ_found && list) {
1115       templ = (GstPadTemplate *) list->data;
1116       if (templ->presence == GST_PAD_REQUEST) {
1117         GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
1118             templ->name_template);
1119         if (gst_element_is_valid_request_template_name (templ->name_template,
1120                 name)) {
1121           templ_found = TRUE;
1122           req_name = name;
1123           break;
1124         }
1125       }
1126       list = list->next;
1127     }
1128   }
1129
1130   if (!templ_found)
1131     return NULL;
1132
1133   pad = _gst_element_request_pad (element, templ, req_name, NULL);
1134
1135   return pad;
1136 }
1137
1138 /**
1139  * gst_element_request_pad: (virtual request_new_pad)
1140  * @element: a #GstElement to find a request pad of.
1141  * @templ: a #GstPadTemplate of which we want a pad of.
1142  * @name: (transfer none) (allow-none): the name of the request #GstPad
1143  * to retrieve. Can be %NULL.
1144  * @caps: (transfer none) (allow-none): the caps of the pad we want to
1145  * request. Can be %NULL.
1146  *
1147  * Retrieves a request pad from the element according to the provided template.
1148  * Pad templates can be looked up using
1149  * gst_element_factory_get_static_pad_templates().
1150  *
1151  * The pad should be released with gst_element_release_request_pad().
1152  *
1153  * Returns: (transfer full) (nullable): requested #GstPad if found,
1154  *     otherwise %NULL.  Release after usage.
1155  */
1156 GstPad *
1157 gst_element_request_pad (GstElement * element,
1158     GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
1159 {
1160   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1161   g_return_val_if_fail (templ != NULL, NULL);
1162   g_return_val_if_fail (templ->presence == GST_PAD_REQUEST, NULL);
1163
1164   return _gst_element_request_pad (element, templ, name, caps);
1165 }
1166
1167 static GstIterator *
1168 gst_element_iterate_pad_list (GstElement * element, GList ** padlist)
1169 {
1170   GstIterator *result;
1171
1172   GST_OBJECT_LOCK (element);
1173   result = gst_iterator_new_list (GST_TYPE_PAD,
1174       GST_OBJECT_GET_LOCK (element),
1175       &element->pads_cookie, padlist, (GObject *) element, NULL);
1176   GST_OBJECT_UNLOCK (element);
1177
1178   return result;
1179 }
1180
1181 /**
1182  * gst_element_iterate_pads:
1183  * @element: a #GstElement to iterate pads of.
1184  *
1185  * Retrieves an iterator of @element's pads. The iterator should
1186  * be freed after usage. Also more specialized iterators exists such as
1187  * gst_element_iterate_src_pads() or gst_element_iterate_sink_pads().
1188  *
1189  * The order of pads returned by the iterator will be the order in which
1190  * the pads were added to the element.
1191  *
1192  * Returns: (transfer full): the #GstIterator of #GstPad.
1193  *
1194  * MT safe.
1195  */
1196 GstIterator *
1197 gst_element_iterate_pads (GstElement * element)
1198 {
1199   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1200
1201   return gst_element_iterate_pad_list (element, &element->pads);
1202 }
1203
1204 /**
1205  * gst_element_iterate_src_pads:
1206  * @element: a #GstElement.
1207  *
1208  * Retrieves an iterator of @element's source pads.
1209  *
1210  * The order of pads returned by the iterator will be the order in which
1211  * the pads were added to the element.
1212  *
1213  * Returns: (transfer full): the #GstIterator of #GstPad.
1214  *
1215  * MT safe.
1216  */
1217 GstIterator *
1218 gst_element_iterate_src_pads (GstElement * element)
1219 {
1220   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1221
1222   return gst_element_iterate_pad_list (element, &element->srcpads);
1223 }
1224
1225 /**
1226  * gst_element_iterate_sink_pads:
1227  * @element: a #GstElement.
1228  *
1229  * Retrieves an iterator of @element's sink pads.
1230  *
1231  * The order of pads returned by the iterator will be the order in which
1232  * the pads were added to the element.
1233  *
1234  * Returns: (transfer full): the #GstIterator of #GstPad.
1235  *
1236  * MT safe.
1237  */
1238 GstIterator *
1239 gst_element_iterate_sink_pads (GstElement * element)
1240 {
1241   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1242
1243   return gst_element_iterate_pad_list (element, &element->sinkpads);
1244 }
1245
1246 /**
1247  * gst_element_class_add_pad_template:
1248  * @klass: the #GstElementClass to add the pad template to.
1249  * @templ: (transfer full): a #GstPadTemplate to add to the element class.
1250  *
1251  * Adds a padtemplate to an element class. This is mainly used in the _class_init
1252  * functions of classes. If a pad template with the same name as an already
1253  * existing one is added the old one is replaced by the new one.
1254  *
1255  */
1256 void
1257 gst_element_class_add_pad_template (GstElementClass * klass,
1258     GstPadTemplate * templ)
1259 {
1260   GList *template_list = klass->padtemplates;
1261
1262   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1263   g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1264
1265   /* If we already have a pad template with the same name replace the
1266    * old one. */
1267   while (template_list) {
1268     GstPadTemplate *padtempl = (GstPadTemplate *) template_list->data;
1269
1270     /* Found pad with the same name, replace and return */
1271     if (strcmp (templ->name_template, padtempl->name_template) == 0) {
1272       gst_object_unref (padtempl);
1273       template_list->data = templ;
1274       return;
1275     }
1276     template_list = g_list_next (template_list);
1277   }
1278
1279   /* Take ownership of the floating ref */
1280   gst_object_ref_sink (templ);
1281
1282   klass->padtemplates = g_list_append (klass->padtemplates, templ);
1283   klass->numpadtemplates++;
1284 }
1285
1286 /**
1287  * gst_element_class_add_static_pad_template:
1288  * @klass: the #GstElementClass to add the pad template to.
1289  * @static_templ: #GstStaticPadTemplate to add as pad template to the element class.
1290  *
1291  * Adds a pad template to an element class based on the static pad template
1292  * @templ. This is mainly used in the _class_init functions of element
1293  * implementations. If a pad template with the same name already exists,
1294  * the old one is replaced by the new one.
1295  *
1296  * Since: 1.8
1297  */
1298 void
1299 gst_element_class_add_static_pad_template (GstElementClass * klass,
1300     GstStaticPadTemplate * static_templ)
1301 {
1302   gst_element_class_add_pad_template (klass,
1303       gst_static_pad_template_get (static_templ));
1304 }
1305
1306 /**
1307  * gst_element_class_add_metadata:
1308  * @klass: class to set metadata for
1309  * @key: the key to set
1310  * @value: the value to set
1311  *
1312  * Set @key with @value as metadata in @klass.
1313  */
1314 void
1315 gst_element_class_add_metadata (GstElementClass * klass,
1316     const gchar * key, const gchar * value)
1317 {
1318   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1319   g_return_if_fail (key != NULL);
1320   g_return_if_fail (value != NULL);
1321
1322   gst_structure_set ((GstStructure *) klass->metadata,
1323       key, G_TYPE_STRING, value, NULL);
1324 }
1325
1326 /**
1327  * gst_element_class_add_static_metadata:
1328  * @klass: class to set metadata for
1329  * @key: the key to set
1330  * @value: the value to set
1331  *
1332  * Set @key with @value as metadata in @klass.
1333  *
1334  * Same as gst_element_class_add_metadata(), but @value must be a static string
1335  * or an inlined string, as it will not be copied. (GStreamer plugins will
1336  * be made resident once loaded, so this function can be used even from
1337  * dynamically loaded plugins.)
1338  */
1339 void
1340 gst_element_class_add_static_metadata (GstElementClass * klass,
1341     const gchar * key, const gchar * value)
1342 {
1343   GValue val = G_VALUE_INIT;
1344
1345   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1346   g_return_if_fail (key != NULL);
1347   g_return_if_fail (value != NULL);
1348
1349   g_value_init (&val, G_TYPE_STRING);
1350   g_value_set_static_string (&val, value);
1351   gst_structure_take_value ((GstStructure *) klass->metadata, key, &val);
1352 }
1353
1354 /**
1355  * gst_element_class_set_metadata:
1356  * @klass: class to set metadata for
1357  * @longname: The long English name of the element. E.g. "File Sink"
1358  * @classification: String describing the type of element, as an unordered list
1359  * separated with slashes ('/'). See draft-klass.txt of the design docs
1360  * for more details and common types. E.g: "Sink/File"
1361  * @description: Sentence describing the purpose of the element.
1362  * E.g: "Write stream to a file"
1363  * @author: Name and contact details of the author(s). Use \n to separate
1364  * multiple author metadata. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
1365  *
1366  * Sets the detailed information for a #GstElementClass.
1367  * <note>This function is for use in _class_init functions only.</note>
1368  */
1369 void
1370 gst_element_class_set_metadata (GstElementClass * klass,
1371     const gchar * longname, const gchar * classification,
1372     const gchar * description, const gchar * author)
1373 {
1374   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1375   g_return_if_fail (longname != NULL && *longname != '\0');
1376   g_return_if_fail (classification != NULL && *classification != '\0');
1377   g_return_if_fail (description != NULL && *description != '\0');
1378   g_return_if_fail (author != NULL && *author != '\0');
1379
1380   gst_structure_id_set ((GstStructure *) klass->metadata,
1381       GST_QUARK (ELEMENT_METADATA_LONGNAME), G_TYPE_STRING, longname,
1382       GST_QUARK (ELEMENT_METADATA_KLASS), G_TYPE_STRING, classification,
1383       GST_QUARK (ELEMENT_METADATA_DESCRIPTION), G_TYPE_STRING, description,
1384       GST_QUARK (ELEMENT_METADATA_AUTHOR), G_TYPE_STRING, author, NULL);
1385 }
1386
1387 /**
1388  * gst_element_class_set_static_metadata:
1389  * @klass: class to set metadata for
1390  * @longname: The long English name of the element. E.g. "File Sink"
1391  * @classification: String describing the type of element, as an unordered list
1392  * separated with slashes ('/'). See draft-klass.txt of the design docs
1393  * for more details and common types. E.g: "Sink/File"
1394  * @description: Sentence describing the purpose of the element.
1395  * E.g: "Write stream to a file"
1396  * @author: Name and contact details of the author(s). Use \n to separate
1397  * multiple author metadata. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
1398  *
1399  * Sets the detailed information for a #GstElementClass.
1400  * <note>This function is for use in _class_init functions only.</note>
1401  *
1402  * Same as gst_element_class_set_metadata(), but @longname, @classification,
1403  * @description, and @author must be static strings or inlined strings, as
1404  * they will not be copied. (GStreamer plugins will be made resident once
1405  * loaded, so this function can be used even from dynamically loaded plugins.)
1406  */
1407 void
1408 gst_element_class_set_static_metadata (GstElementClass * klass,
1409     const gchar * longname, const gchar * classification,
1410     const gchar * description, const gchar * author)
1411 {
1412   GstStructure *s = (GstStructure *) klass->metadata;
1413   GValue val = G_VALUE_INIT;
1414
1415   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1416   g_return_if_fail (longname != NULL && *longname != '\0');
1417   g_return_if_fail (classification != NULL && *classification != '\0');
1418   g_return_if_fail (description != NULL && *description != '\0');
1419   g_return_if_fail (author != NULL && *author != '\0');
1420
1421   g_value_init (&val, G_TYPE_STRING);
1422
1423   g_value_set_static_string (&val, longname);
1424   gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_LONGNAME), &val);
1425
1426   g_value_set_static_string (&val, classification);
1427   gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_KLASS), &val);
1428
1429   g_value_set_static_string (&val, description);
1430   gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_DESCRIPTION),
1431       &val);
1432
1433   g_value_set_static_string (&val, author);
1434   gst_structure_id_take_value (s, GST_QUARK (ELEMENT_METADATA_AUTHOR), &val);
1435 }
1436
1437 /**
1438  * gst_element_class_get_metadata:
1439  * @klass: class to get metadata for
1440  * @key: the key to get
1441  *
1442  * Get metadata with @key in @klass.
1443  *
1444  * Returns: the metadata for @key.
1445  */
1446 const gchar *
1447 gst_element_class_get_metadata (GstElementClass * klass, const gchar * key)
1448 {
1449   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (klass), NULL);
1450   g_return_val_if_fail (key != NULL, NULL);
1451
1452   return gst_structure_get_string ((GstStructure *) klass->metadata, key);
1453 }
1454
1455 /**
1456  * gst_element_class_get_pad_template_list:
1457  * @element_class: a #GstElementClass to get pad templates of.
1458  *
1459  * Retrieves a list of the pad templates associated with @element_class. The
1460  * list must not be modified by the calling code.
1461  * <note>If you use this function in the #GInstanceInitFunc of an object class
1462  * that has subclasses, make sure to pass the g_class parameter of the
1463  * #GInstanceInitFunc here.</note>
1464  *
1465  * Returns: (transfer none) (element-type Gst.PadTemplate): the #GList of
1466  *     pad templates.
1467  */
1468 GList *
1469 gst_element_class_get_pad_template_list (GstElementClass * element_class)
1470 {
1471   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1472
1473   return element_class->padtemplates;
1474 }
1475
1476 /**
1477  * gst_element_class_get_pad_template:
1478  * @element_class: a #GstElementClass to get the pad template of.
1479  * @name: the name of the #GstPadTemplate to get.
1480  *
1481  * Retrieves a padtemplate from @element_class with the given name.
1482  * <note>If you use this function in the #GInstanceInitFunc of an object class
1483  * that has subclasses, make sure to pass the g_class parameter of the
1484  * #GInstanceInitFunc here.</note>
1485  *
1486  * Returns: (transfer none) (nullable): the #GstPadTemplate with the
1487  *     given name, or %NULL if none was found. No unreferencing is
1488  *     necessary.
1489  */
1490 GstPadTemplate *
1491 gst_element_class_get_pad_template (GstElementClass *
1492     element_class, const gchar * name)
1493 {
1494   GList *padlist;
1495
1496   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1497   g_return_val_if_fail (name != NULL, NULL);
1498
1499   padlist = element_class->padtemplates;
1500
1501   while (padlist) {
1502     GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1503
1504     if (strcmp (padtempl->name_template, name) == 0)
1505       return padtempl;
1506
1507     padlist = g_list_next (padlist);
1508   }
1509
1510   return NULL;
1511 }
1512
1513 static GstPadTemplate *
1514 gst_element_class_get_request_pad_template (GstElementClass *
1515     element_class, const gchar * name)
1516 {
1517   GstPadTemplate *tmpl;
1518
1519   tmpl = gst_element_class_get_pad_template (element_class, name);
1520   if (tmpl != NULL && tmpl->presence == GST_PAD_REQUEST)
1521     return tmpl;
1522
1523   return NULL;
1524 }
1525
1526 /* get a random pad on element of the given direction.
1527  * The pad is random in a sense that it is the first pad that is (optionaly) linked.
1528  */
1529 static GstPad *
1530 gst_element_get_random_pad (GstElement * element,
1531     gboolean need_linked, GstPadDirection dir)
1532 {
1533   GstPad *result = NULL;
1534   GList *pads;
1535
1536   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
1537
1538   switch (dir) {
1539     case GST_PAD_SRC:
1540       GST_OBJECT_LOCK (element);
1541       pads = element->srcpads;
1542       break;
1543     case GST_PAD_SINK:
1544       GST_OBJECT_LOCK (element);
1545       pads = element->sinkpads;
1546       break;
1547     default:
1548       goto wrong_direction;
1549   }
1550   for (; pads; pads = g_list_next (pads)) {
1551     GstPad *pad = GST_PAD_CAST (pads->data);
1552
1553     GST_OBJECT_LOCK (pad);
1554     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
1555         GST_DEBUG_PAD_NAME (pad));
1556
1557     if (need_linked && !GST_PAD_IS_LINKED (pad)) {
1558       /* if we require a linked pad, and it is not linked, continue the
1559        * search */
1560       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
1561           GST_DEBUG_PAD_NAME (pad));
1562       GST_OBJECT_UNLOCK (pad);
1563       continue;
1564     } else {
1565       /* found a pad, stop search */
1566       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
1567           GST_DEBUG_PAD_NAME (pad));
1568       GST_OBJECT_UNLOCK (pad);
1569       result = pad;
1570       break;
1571     }
1572   }
1573   if (result)
1574     gst_object_ref (result);
1575
1576   GST_OBJECT_UNLOCK (element);
1577
1578   return result;
1579
1580   /* ERROR handling */
1581 wrong_direction:
1582   {
1583     g_warning ("unknown pad direction %d", dir);
1584     return NULL;
1585   }
1586 }
1587
1588 static gboolean
1589 gst_element_default_send_event (GstElement * element, GstEvent * event)
1590 {
1591   gboolean result = FALSE;
1592   GstPad *pad;
1593
1594   pad = GST_EVENT_IS_DOWNSTREAM (event) ?
1595       gst_element_get_random_pad (element, TRUE, GST_PAD_SINK) :
1596       gst_element_get_random_pad (element, TRUE, GST_PAD_SRC);
1597
1598   if (pad) {
1599     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1600         "pushing %s event to random %s pad %s:%s",
1601         GST_EVENT_TYPE_NAME (event),
1602         (GST_PAD_DIRECTION (pad) == GST_PAD_SRC ? "src" : "sink"),
1603         GST_DEBUG_PAD_NAME (pad));
1604
1605     result = gst_pad_send_event (pad, event);
1606     gst_object_unref (pad);
1607   } else {
1608     GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "can't send %s event on element %s",
1609         GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
1610     gst_event_unref (event);
1611   }
1612   return result;
1613 }
1614
1615 /**
1616  * gst_element_send_event:
1617  * @element: a #GstElement to send the event to.
1618  * @event: (transfer full): the #GstEvent to send to the element.
1619  *
1620  * Sends an event to an element. If the element doesn't implement an
1621  * event handler, the event will be pushed on a random linked sink pad for
1622  * downstream events or a random linked source pad for upstream events.
1623  *
1624  * This function takes ownership of the provided event so you should
1625  * gst_event_ref() it if you want to reuse the event after this call.
1626  *
1627  * MT safe.
1628  *
1629  * Returns: %TRUE if the event was handled. Events that trigger a preroll (such
1630  * as flushing seeks and steps) will emit %GST_MESSAGE_ASYNC_DONE.
1631  */
1632 gboolean
1633 gst_element_send_event (GstElement * element, GstEvent * event)
1634 {
1635   GstElementClass *oclass;
1636   gboolean result = FALSE;
1637
1638   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1639   g_return_val_if_fail (event != NULL, FALSE);
1640
1641   oclass = GST_ELEMENT_GET_CLASS (element);
1642
1643   GST_STATE_LOCK (element);
1644   if (oclass->send_event) {
1645     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send %s event on element %s",
1646         GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
1647     result = oclass->send_event (element, event);
1648   } else {
1649     gst_event_unref (event);
1650   }
1651   GST_STATE_UNLOCK (element);
1652
1653   return result;
1654 }
1655
1656 /**
1657  * gst_element_seek:
1658  * @element: a #GstElement to send the event to.
1659  * @rate: The new playback rate
1660  * @format: The format of the seek values
1661  * @flags: The optional seek flags.
1662  * @start_type: The type and flags for the new start position
1663  * @start: The value of the new start position
1664  * @stop_type: The type and flags for the new stop position
1665  * @stop: The value of the new stop position
1666  *
1667  * Sends a seek event to an element. See gst_event_new_seek() for the details of
1668  * the parameters. The seek event is sent to the element using
1669  * gst_element_send_event().
1670  *
1671  * MT safe.
1672  *
1673  * Returns: %TRUE if the event was handled. Flushing seeks will trigger a
1674  * preroll, which will emit %GST_MESSAGE_ASYNC_DONE.
1675  */
1676 gboolean
1677 gst_element_seek (GstElement * element, gdouble rate, GstFormat format,
1678     GstSeekFlags flags, GstSeekType start_type, gint64 start,
1679     GstSeekType stop_type, gint64 stop)
1680 {
1681   GstEvent *event;
1682   gboolean result;
1683
1684   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1685
1686   event =
1687       gst_event_new_seek (rate, format, flags, start_type, start, stop_type,
1688       stop);
1689   result = gst_element_send_event (element, event);
1690
1691   return result;
1692 }
1693
1694 static gboolean
1695 gst_element_default_query (GstElement * element, GstQuery * query)
1696 {
1697   gboolean result = FALSE;
1698   GstPad *pad;
1699
1700   pad = gst_element_get_random_pad (element, FALSE, GST_PAD_SRC);
1701   if (pad) {
1702     result = gst_pad_query (pad, query);
1703
1704     gst_object_unref (pad);
1705   } else {
1706     pad = gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
1707     if (pad) {
1708       GstPad *peer = gst_pad_get_peer (pad);
1709
1710       if (peer) {
1711         result = gst_pad_query (peer, query);
1712
1713         gst_object_unref (peer);
1714       }
1715       gst_object_unref (pad);
1716     }
1717   }
1718   return result;
1719 }
1720
1721 /**
1722  * gst_element_query:
1723  * @element: a #GstElement to perform the query on.
1724  * @query: (transfer none): the #GstQuery.
1725  *
1726  * Performs a query on the given element.
1727  *
1728  * For elements that don't implement a query handler, this function
1729  * forwards the query to a random srcpad or to the peer of a
1730  * random linked sinkpad of this element.
1731  *
1732  * Please note that some queries might need a running pipeline to work.
1733  *
1734  * Returns: %TRUE if the query could be performed.
1735  *
1736  * MT safe.
1737  */
1738 gboolean
1739 gst_element_query (GstElement * element, GstQuery * query)
1740 {
1741   GstElementClass *klass;
1742   gboolean res = FALSE;
1743
1744   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1745   g_return_val_if_fail (query != NULL, FALSE);
1746
1747   GST_TRACER_ELEMENT_QUERY_PRE (element, query);
1748
1749   klass = GST_ELEMENT_GET_CLASS (element);
1750   if (klass->query) {
1751     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send query on element %s",
1752         GST_ELEMENT_NAME (element));
1753     res = klass->query (element, query);
1754   }
1755
1756   GST_TRACER_ELEMENT_QUERY_POST (element, query, res);
1757   return res;
1758 }
1759
1760 static gboolean
1761 gst_element_post_message_default (GstElement * element, GstMessage * message)
1762 {
1763   GstBus *bus;
1764   gboolean result = FALSE;
1765
1766   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1767   g_return_val_if_fail (message != NULL, FALSE);
1768
1769   GST_OBJECT_LOCK (element);
1770   bus = element->bus;
1771
1772   if (G_UNLIKELY (bus == NULL))
1773     goto no_bus;
1774
1775   gst_object_ref (bus);
1776   GST_OBJECT_UNLOCK (element);
1777
1778   /* we release the element lock when posting the message so that any
1779    * (synchronous) message handlers can operate on the element */
1780   result = gst_bus_post (bus, message);
1781   gst_object_unref (bus);
1782
1783   return result;
1784
1785   /* ERRORS */
1786 no_bus:
1787   {
1788     GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element,
1789         "not posting message %p: no bus", message);
1790     GST_OBJECT_UNLOCK (element);
1791     gst_message_unref (message);
1792     return FALSE;
1793   }
1794 }
1795
1796 /**
1797  * gst_element_post_message:
1798  * @element: a #GstElement posting the message
1799  * @message: (transfer full): a #GstMessage to post
1800  *
1801  * Post a message on the element's #GstBus. This function takes ownership of the
1802  * message; if you want to access the message after this call, you should add an
1803  * additional reference before calling.
1804  *
1805  * Returns: %TRUE if the message was successfully posted. The function returns
1806  * %FALSE if the element did not have a bus.
1807  *
1808  * MT safe.
1809  */
1810 gboolean
1811 gst_element_post_message (GstElement * element, GstMessage * message)
1812 {
1813   GstElementClass *klass;
1814   gboolean res = FALSE;
1815
1816   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1817   g_return_val_if_fail (message != NULL, FALSE);
1818
1819   GST_TRACER_ELEMENT_POST_MESSAGE_PRE (element, message);
1820
1821   klass = GST_ELEMENT_GET_CLASS (element);
1822   if (klass->post_message)
1823     res = klass->post_message (element, message);
1824   else
1825     gst_message_unref (message);
1826
1827   GST_TRACER_ELEMENT_POST_MESSAGE_POST (element, res);
1828   return res;
1829 }
1830
1831 /**
1832  * _gst_element_error_printf:
1833  * @format: (allow-none): the printf-like format to use, or %NULL
1834  *
1835  * This function is only used internally by the gst_element_error() macro.
1836  *
1837  * Returns: (transfer full) (nullable): a newly allocated string, or
1838  *     %NULL if the format was %NULL or ""
1839  *
1840  * MT safe.
1841  */
1842 gchar *
1843 _gst_element_error_printf (const gchar * format, ...)
1844 {
1845   va_list args;
1846   gchar *buffer;
1847   int len;
1848
1849   if (format == NULL)
1850     return NULL;
1851   if (format[0] == 0)
1852     return NULL;
1853
1854   va_start (args, format);
1855
1856   len = __gst_vasprintf (&buffer, format, args);
1857
1858   va_end (args);
1859
1860   if (len < 0)
1861     buffer = NULL;
1862
1863   return buffer;
1864 }
1865
1866 /**
1867  * gst_element_message_full_with_details:
1868  * @element:  a #GstElement to send message from
1869  * @type:     the #GstMessageType
1870  * @domain:   the GStreamer GError domain this message belongs to
1871  * @code:     the GError code belonging to the domain
1872  * @text:     (allow-none) (transfer full): an allocated text string to be used
1873  *            as a replacement for the default message connected to code,
1874  *            or %NULL
1875  * @debug:    (allow-none) (transfer full): an allocated debug message to be
1876  *            used as a replacement for the default debugging information,
1877  *            or %NULL
1878  * @file:     the source code file where the error was generated
1879  * @function: the source code function where the error was generated
1880  * @line:     the source code line where the error was generated
1881  * @structure:(transfer full): optional details structure
1882  *
1883  * Post an error, warning or info message on the bus from inside an element.
1884  *
1885  * @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
1886  * #GST_MESSAGE_INFO.
1887  *
1888  * Since: 1.10
1889  */
1890 void gst_element_message_full_with_details
1891     (GstElement * element, GstMessageType type,
1892     GQuark domain, gint code, gchar * text,
1893     gchar * debug, const gchar * file, const gchar * function, gint line,
1894     GstStructure * structure)
1895 {
1896   GError *gerror = NULL;
1897   gchar *name;
1898   gchar *sent_text;
1899   gchar *sent_debug;
1900   gboolean has_debug = TRUE;
1901   GstMessage *message = NULL;
1902
1903   /* checks */
1904   GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element, "start");
1905   g_return_if_fail (GST_IS_ELEMENT (element));
1906   g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
1907       (type == GST_MESSAGE_WARNING) || (type == GST_MESSAGE_INFO));
1908
1909   /* check if we send the given text or the default error text */
1910   if ((text == NULL) || (text[0] == 0)) {
1911     /* text could have come from g_strdup_printf (""); */
1912     g_free (text);
1913     sent_text = gst_error_get_message (domain, code);
1914   } else
1915     sent_text = text;
1916
1917   /* construct a sent_debug with extra information from source */
1918   if ((debug == NULL) || (debug[0] == 0)) {
1919     /* debug could have come from g_strdup_printf (""); */
1920     has_debug = FALSE;
1921   }
1922
1923   name = gst_object_get_path_string (GST_OBJECT_CAST (element));
1924   if (has_debug)
1925     sent_debug = g_strdup_printf ("%s(%d): %s (): %s:\n%s",
1926         file, line, function, name, debug);
1927   else
1928     sent_debug = g_strdup_printf ("%s(%d): %s (): %s",
1929         file, line, function, name);
1930   g_free (name);
1931   g_free (debug);
1932
1933   /* create gerror and post message */
1934   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
1935       sent_text);
1936   gerror = g_error_new_literal (domain, code, sent_text);
1937
1938   switch (type) {
1939     case GST_MESSAGE_ERROR:
1940       message =
1941           gst_message_new_error_with_details (GST_OBJECT_CAST (element), gerror,
1942           sent_debug, structure);
1943       break;
1944     case GST_MESSAGE_WARNING:
1945       message =
1946           gst_message_new_warning_with_details (GST_OBJECT_CAST (element),
1947           gerror, sent_debug, structure);
1948       break;
1949     case GST_MESSAGE_INFO:
1950       message =
1951           gst_message_new_info_with_details (GST_OBJECT_CAST (element), gerror,
1952           sent_debug, structure);
1953       break;
1954     default:
1955       g_assert_not_reached ();
1956       break;
1957   }
1958
1959   gst_element_post_message (element, message);
1960
1961   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted %s message: %s",
1962       (type == GST_MESSAGE_ERROR ? "error" : "warning"), sent_text);
1963
1964   /* cleanup */
1965   g_error_free (gerror);
1966   g_free (sent_debug);
1967   g_free (sent_text);
1968 }
1969
1970 /**
1971  * gst_element_message_full:
1972  * @element:  a #GstElement to send message from
1973  * @type:     the #GstMessageType
1974  * @domain:   the GStreamer GError domain this message belongs to
1975  * @code:     the GError code belonging to the domain
1976  * @text:     (allow-none) (transfer full): an allocated text string to be used
1977  *            as a replacement for the default message connected to code,
1978  *            or %NULL
1979  * @debug:    (allow-none) (transfer full): an allocated debug message to be
1980  *            used as a replacement for the default debugging information,
1981  *            or %NULL
1982  * @file:     the source code file where the error was generated
1983  * @function: the source code function where the error was generated
1984  * @line:     the source code line where the error was generated
1985  *
1986  * Post an error, warning or info message on the bus from inside an element.
1987  *
1988  * @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
1989  * #GST_MESSAGE_INFO.
1990  *
1991  * MT safe.
1992  */
1993 void gst_element_message_full
1994     (GstElement * element, GstMessageType type,
1995     GQuark domain, gint code, gchar * text,
1996     gchar * debug, const gchar * file, const gchar * function, gint line)
1997 {
1998   gst_element_message_full_with_details (element, type, domain, code, text,
1999       debug, file, function, line, NULL);
2000 }
2001
2002 /**
2003  * gst_element_is_locked_state:
2004  * @element: a #GstElement.
2005  *
2006  * Checks if the state of an element is locked.
2007  * If the state of an element is locked, state changes of the parent don't
2008  * affect the element.
2009  * This way you can leave currently unused elements inside bins. Just lock their
2010  * state before changing the state from #GST_STATE_NULL.
2011  *
2012  * MT safe.
2013  *
2014  * Returns: %TRUE, if the element's state is locked.
2015  */
2016 gboolean
2017 gst_element_is_locked_state (GstElement * element)
2018 {
2019   gboolean result;
2020
2021   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2022
2023   GST_OBJECT_LOCK (element);
2024   result = GST_ELEMENT_IS_LOCKED_STATE (element);
2025   GST_OBJECT_UNLOCK (element);
2026
2027   return result;
2028 }
2029
2030 /**
2031  * gst_element_set_locked_state:
2032  * @element: a #GstElement
2033  * @locked_state: %TRUE to lock the element's state
2034  *
2035  * Locks the state of an element, so state changes of the parent don't affect
2036  * this element anymore.
2037  *
2038  * MT safe.
2039  *
2040  * Returns: %TRUE if the state was changed, %FALSE if bad parameters were given
2041  * or the elements state-locking needed no change.
2042  */
2043 gboolean
2044 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
2045 {
2046   gboolean old;
2047
2048   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2049
2050   GST_OBJECT_LOCK (element);
2051   old = GST_ELEMENT_IS_LOCKED_STATE (element);
2052
2053   if (G_UNLIKELY (old == locked_state))
2054     goto was_ok;
2055
2056   if (locked_state) {
2057     GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
2058         GST_ELEMENT_NAME (element));
2059     GST_OBJECT_FLAG_SET (element, GST_ELEMENT_FLAG_LOCKED_STATE);
2060   } else {
2061     GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
2062         GST_ELEMENT_NAME (element));
2063     GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_FLAG_LOCKED_STATE);
2064   }
2065   GST_OBJECT_UNLOCK (element);
2066
2067   return TRUE;
2068
2069 was_ok:
2070   {
2071     GST_CAT_DEBUG (GST_CAT_STATES,
2072         "elements %s was already in locked state %d",
2073         GST_ELEMENT_NAME (element), old);
2074     GST_OBJECT_UNLOCK (element);
2075
2076     return FALSE;
2077   }
2078 }
2079
2080 /**
2081  * gst_element_sync_state_with_parent:
2082  * @element: a #GstElement.
2083  *
2084  * Tries to change the state of the element to the same as its parent.
2085  * If this function returns %FALSE, the state of element is undefined.
2086  *
2087  * Returns: %TRUE, if the element's state could be synced to the parent's state.
2088  *
2089  * MT safe.
2090  */
2091 gboolean
2092 gst_element_sync_state_with_parent (GstElement * element)
2093 {
2094   GstElement *parent;
2095   GstState target;
2096   GstStateChangeReturn ret;
2097
2098   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
2099
2100   if ((parent = GST_ELEMENT_CAST (gst_element_get_parent (element)))) {
2101     GstState parent_current, parent_pending;
2102
2103     GST_OBJECT_LOCK (parent);
2104     parent_current = GST_STATE (parent);
2105     parent_pending = GST_STATE_PENDING (parent);
2106     GST_OBJECT_UNLOCK (parent);
2107
2108     /* set to pending if there is one, else we set it to the current state of
2109      * the parent */
2110     if (parent_pending != GST_STATE_VOID_PENDING)
2111       target = parent_pending;
2112     else
2113       target = parent_current;
2114
2115     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2116         "syncing state (%s) to parent %s %s (%s, %s)",
2117         gst_element_state_get_name (GST_STATE (element)),
2118         GST_ELEMENT_NAME (parent), gst_element_state_get_name (target),
2119         gst_element_state_get_name (parent_current),
2120         gst_element_state_get_name (parent_pending));
2121
2122     ret = gst_element_set_state (element, target);
2123     if (ret == GST_STATE_CHANGE_FAILURE)
2124       goto failed;
2125
2126     gst_object_unref (parent);
2127
2128     return TRUE;
2129   } else {
2130     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "element has no parent");
2131   }
2132   return FALSE;
2133
2134   /* ERROR */
2135 failed:
2136   {
2137     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2138         "syncing state failed (%s)",
2139         gst_element_state_change_return_get_name (ret));
2140     gst_object_unref (parent);
2141     return FALSE;
2142   }
2143 }
2144
2145 /* MT safe */
2146 static GstStateChangeReturn
2147 gst_element_get_state_func (GstElement * element,
2148     GstState * state, GstState * pending, GstClockTime timeout)
2149 {
2150   GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
2151   GstState old_pending;
2152
2153   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "getting state, timeout %"
2154       GST_TIME_FORMAT, GST_TIME_ARGS (timeout));
2155
2156   GST_OBJECT_LOCK (element);
2157   ret = GST_STATE_RETURN (element);
2158   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "RETURN is %s",
2159       gst_element_state_change_return_get_name (ret));
2160
2161   /* we got an error, report immediately */
2162   if (ret == GST_STATE_CHANGE_FAILURE)
2163     goto done;
2164
2165   /* we got no_preroll, report immediately */
2166   if (ret == GST_STATE_CHANGE_NO_PREROLL)
2167     goto done;
2168
2169   /* no need to wait async if we are not async */
2170   if (ret != GST_STATE_CHANGE_ASYNC)
2171     goto done;
2172
2173   old_pending = GST_STATE_PENDING (element);
2174   if (old_pending != GST_STATE_VOID_PENDING) {
2175     gboolean signaled;
2176     guint32 cookie;
2177
2178     /* get cookie to detect state changes during waiting */
2179     cookie = element->state_cookie;
2180
2181     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2182         "waiting for element to commit state");
2183
2184     /* we have a pending state change, wait for it to complete */
2185     if (timeout != GST_CLOCK_TIME_NONE) {
2186       gint64 end_time;
2187       /* make timeout absolute */
2188       end_time = g_get_monotonic_time () + (timeout / 1000);
2189       signaled = GST_STATE_WAIT_UNTIL (element, end_time);
2190     } else {
2191       GST_STATE_WAIT (element);
2192       signaled = TRUE;
2193     }
2194
2195     if (!signaled) {
2196       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timed out");
2197       /* timeout triggered */
2198       ret = GST_STATE_CHANGE_ASYNC;
2199     } else {
2200       if (cookie != element->state_cookie)
2201         goto interrupted;
2202
2203       /* could be success or failure */
2204       if (old_pending == GST_STATE (element)) {
2205         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got success");
2206         ret = GST_STATE_CHANGE_SUCCESS;
2207       } else {
2208         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got failure");
2209         ret = GST_STATE_CHANGE_FAILURE;
2210       }
2211     }
2212     /* if nothing is pending anymore we can return SUCCESS */
2213     if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
2214       GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "nothing pending");
2215       ret = GST_STATE_CHANGE_SUCCESS;
2216     }
2217   }
2218
2219 done:
2220   if (state)
2221     *state = GST_STATE (element);
2222   if (pending)
2223     *pending = GST_STATE_PENDING (element);
2224
2225   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2226       "state current: %s, pending: %s, result: %s",
2227       gst_element_state_get_name (GST_STATE (element)),
2228       gst_element_state_get_name (GST_STATE_PENDING (element)),
2229       gst_element_state_change_return_get_name (ret));
2230   GST_OBJECT_UNLOCK (element);
2231
2232   return ret;
2233
2234 interrupted:
2235   {
2236     if (state)
2237       *state = GST_STATE_VOID_PENDING;
2238     if (pending)
2239       *pending = GST_STATE_VOID_PENDING;
2240
2241     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "interruped");
2242
2243     GST_OBJECT_UNLOCK (element);
2244
2245     return GST_STATE_CHANGE_FAILURE;
2246   }
2247 }
2248
2249 /**
2250  * gst_element_get_state:
2251  * @element: a #GstElement to get the state of.
2252  * @state: (out) (allow-none): a pointer to #GstState to hold the state.
2253  *     Can be %NULL.
2254  * @pending: (out) (allow-none): a pointer to #GstState to hold the pending
2255  *     state. Can be %NULL.
2256  * @timeout: a #GstClockTime to specify the timeout for an async
2257  *           state change or %GST_CLOCK_TIME_NONE for infinite timeout.
2258  *
2259  * Gets the state of the element.
2260  *
2261  * For elements that performed an ASYNC state change, as reported by
2262  * gst_element_set_state(), this function will block up to the
2263  * specified timeout value for the state change to complete.
2264  * If the element completes the state change or goes into
2265  * an error, this function returns immediately with a return value of
2266  * %GST_STATE_CHANGE_SUCCESS or %GST_STATE_CHANGE_FAILURE respectively.
2267  *
2268  * For elements that did not return %GST_STATE_CHANGE_ASYNC, this function
2269  * returns the current and pending state immediately.
2270  *
2271  * This function returns %GST_STATE_CHANGE_NO_PREROLL if the element
2272  * successfully changed its state but is not able to provide data yet.
2273  * This mostly happens for live sources that only produce data in
2274  * %GST_STATE_PLAYING. While the state change return is equivalent to
2275  * %GST_STATE_CHANGE_SUCCESS, it is returned to the application to signal that
2276  * some sink elements might not be able to complete their state change because
2277  * an element is not producing data to complete the preroll. When setting the
2278  * element to playing, the preroll will complete and playback will start.
2279  *
2280  * Returns: %GST_STATE_CHANGE_SUCCESS if the element has no more pending state
2281  *          and the last state change succeeded, %GST_STATE_CHANGE_ASYNC if the
2282  *          element is still performing a state change or
2283  *          %GST_STATE_CHANGE_FAILURE if the last state change failed.
2284  *
2285  * MT safe.
2286  */
2287 GstStateChangeReturn
2288 gst_element_get_state (GstElement * element,
2289     GstState * state, GstState * pending, GstClockTime timeout)
2290 {
2291   GstElementClass *oclass;
2292   GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
2293
2294   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2295
2296   oclass = GST_ELEMENT_GET_CLASS (element);
2297
2298   if (oclass->get_state)
2299     result = (oclass->get_state) (element, state, pending, timeout);
2300
2301   return result;
2302 }
2303
2304 /**
2305  * gst_element_abort_state:
2306  * @element: a #GstElement to abort the state of.
2307  *
2308  * Abort the state change of the element. This function is used
2309  * by elements that do asynchronous state changes and find out
2310  * something is wrong.
2311  *
2312  * This function should be called with the STATE_LOCK held.
2313  *
2314  * MT safe.
2315  */
2316 void
2317 gst_element_abort_state (GstElement * element)
2318 {
2319   GstState pending;
2320
2321 #ifndef GST_DISABLE_GST_DEBUG
2322   GstState old_state;
2323 #endif
2324
2325   g_return_if_fail (GST_IS_ELEMENT (element));
2326
2327   GST_OBJECT_LOCK (element);
2328   pending = GST_STATE_PENDING (element);
2329
2330   if (pending == GST_STATE_VOID_PENDING ||
2331       GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
2332     goto nothing_aborted;
2333
2334 #ifndef GST_DISABLE_GST_DEBUG
2335   old_state = GST_STATE (element);
2336
2337   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2338       "aborting state from %s to %s", gst_element_state_get_name (old_state),
2339       gst_element_state_get_name (pending));
2340 #endif
2341
2342   /* flag error */
2343   GST_STATE_RETURN (element) = GST_STATE_CHANGE_FAILURE;
2344
2345   GST_STATE_BROADCAST (element);
2346   GST_OBJECT_UNLOCK (element);
2347
2348   return;
2349
2350 nothing_aborted:
2351   {
2352     GST_OBJECT_UNLOCK (element);
2353     return;
2354   }
2355 }
2356
2357 /* Not static because GstBin has manual state handling too */
2358 void
2359 _priv_gst_element_state_changed (GstElement * element, GstState oldstate,
2360     GstState newstate, GstState pending)
2361 {
2362   GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
2363   GstMessage *message;
2364
2365   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2366       "notifying about state-changed %s to %s (%s pending)",
2367       gst_element_state_get_name (oldstate),
2368       gst_element_state_get_name (newstate),
2369       gst_element_state_get_name (pending));
2370
2371   if (klass->state_changed)
2372     klass->state_changed (element, oldstate, newstate, pending);
2373
2374   message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
2375       oldstate, newstate, pending);
2376   gst_element_post_message (element, message);
2377 }
2378
2379 /**
2380  * gst_element_continue_state:
2381  * @element: a #GstElement to continue the state change of.
2382  * @ret: The previous state return value
2383  *
2384  * Commit the state change of the element and proceed to the next
2385  * pending state if any. This function is used
2386  * by elements that do asynchronous state changes.
2387  * The core will normally call this method automatically when an
2388  * element returned %GST_STATE_CHANGE_SUCCESS from the state change function.
2389  *
2390  * If after calling this method the element still has not reached
2391  * the pending state, the next state change is performed.
2392  *
2393  * This method is used internally and should normally not be called by plugins
2394  * or applications.
2395  *
2396  * Returns: The result of the commit state change.
2397  *
2398  * MT safe.
2399  */
2400 GstStateChangeReturn
2401 gst_element_continue_state (GstElement * element, GstStateChangeReturn ret)
2402 {
2403   GstStateChangeReturn old_ret;
2404   GstState old_state, old_next;
2405   GstState current, next, pending;
2406   GstStateChange transition;
2407
2408   GST_OBJECT_LOCK (element);
2409   old_ret = GST_STATE_RETURN (element);
2410   GST_STATE_RETURN (element) = ret;
2411   pending = GST_STATE_PENDING (element);
2412
2413   /* check if there is something to commit */
2414   if (pending == GST_STATE_VOID_PENDING)
2415     goto nothing_pending;
2416
2417   old_state = GST_STATE (element);
2418   /* this is the state we should go to next */
2419   old_next = GST_STATE_NEXT (element);
2420   /* update current state */
2421   current = GST_STATE (element) = old_next;
2422
2423   /* see if we reached the final state */
2424   if (pending == current)
2425     goto complete;
2426
2427   next = GST_STATE_GET_NEXT (current, pending);
2428   transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2429
2430   GST_STATE_NEXT (element) = next;
2431   /* mark busy */
2432   GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2433   GST_OBJECT_UNLOCK (element);
2434
2435   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2436       "committing state from %s to %s, pending %s, next %s",
2437       gst_element_state_get_name (old_state),
2438       gst_element_state_get_name (old_next),
2439       gst_element_state_get_name (pending), gst_element_state_get_name (next));
2440
2441   _priv_gst_element_state_changed (element, old_state, old_next, pending);
2442
2443   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2444       "continue state change %s to %s, final %s",
2445       gst_element_state_get_name (current),
2446       gst_element_state_get_name (next), gst_element_state_get_name (pending));
2447
2448   ret = gst_element_change_state (element, transition);
2449
2450   return ret;
2451
2452 nothing_pending:
2453   {
2454     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
2455     GST_OBJECT_UNLOCK (element);
2456     return ret;
2457   }
2458 complete:
2459   {
2460     GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2461     GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
2462
2463     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2464         "completed state change to %s", gst_element_state_get_name (pending));
2465     GST_OBJECT_UNLOCK (element);
2466
2467     /* don't post silly messages with the same state. This can happen
2468      * when an element state is changed to what it already was. For bins
2469      * this can be the result of a lost state, which we check with the
2470      * previous return value.
2471      * We do signal the cond though as a _get_state() might be blocking
2472      * on it. */
2473     if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC)
2474       _priv_gst_element_state_changed (element, old_state, old_next,
2475           GST_STATE_VOID_PENDING);
2476
2477     GST_STATE_BROADCAST (element);
2478
2479     return ret;
2480   }
2481 }
2482
2483 /**
2484  * gst_element_lost_state:
2485  * @element: a #GstElement the state is lost of
2486  *
2487  * Brings the element to the lost state. The current state of the
2488  * element is copied to the pending state so that any call to
2489  * gst_element_get_state() will return %GST_STATE_CHANGE_ASYNC.
2490  *
2491  * An ASYNC_START message is posted. If the element was PLAYING, it will
2492  * go to PAUSED. The element will be restored to its PLAYING state by
2493  * the parent pipeline when it prerolls again.
2494  *
2495  * This is mostly used for elements that lost their preroll buffer
2496  * in the %GST_STATE_PAUSED or %GST_STATE_PLAYING state after a flush,
2497  * they will go to their pending state again when a new preroll buffer is
2498  * queued. This function can only be called when the element is currently
2499  * not in error or an async state change.
2500  *
2501  * This function is used internally and should normally not be called from
2502  * plugins or applications.
2503  */
2504 void
2505 gst_element_lost_state (GstElement * element)
2506 {
2507   GstState old_state, new_state;
2508   GstMessage *message;
2509
2510   g_return_if_fail (GST_IS_ELEMENT (element));
2511
2512   GST_OBJECT_LOCK (element);
2513   if (GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
2514     goto nothing_lost;
2515
2516   if (GST_STATE_PENDING (element) != GST_STATE_VOID_PENDING)
2517     goto only_async_start;
2518
2519   old_state = GST_STATE (element);
2520
2521   /* when we were PLAYING, the new state is PAUSED. We will also not
2522    * automatically go to PLAYING but let the parent bin(s) set us to PLAYING
2523    * when we preroll. */
2524   if (old_state > GST_STATE_PAUSED)
2525     new_state = GST_STATE_PAUSED;
2526   else
2527     new_state = old_state;
2528
2529   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2530       "lost state of %s to %s", gst_element_state_get_name (old_state),
2531       gst_element_state_get_name (new_state));
2532
2533   GST_STATE (element) = new_state;
2534   GST_STATE_NEXT (element) = new_state;
2535   GST_STATE_PENDING (element) = new_state;
2536   GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2537   GST_OBJECT_UNLOCK (element);
2538
2539   _priv_gst_element_state_changed (element, new_state, new_state, new_state);
2540
2541   message = gst_message_new_async_start (GST_OBJECT_CAST (element));
2542   gst_element_post_message (element, message);
2543
2544   return;
2545
2546 nothing_lost:
2547   {
2548     GST_OBJECT_UNLOCK (element);
2549     return;
2550   }
2551 only_async_start:
2552   {
2553     GST_OBJECT_UNLOCK (element);
2554
2555     message = gst_message_new_async_start (GST_OBJECT_CAST (element));
2556     gst_element_post_message (element, message);
2557     return;
2558   }
2559 }
2560
2561 /**
2562  * gst_element_set_state:
2563  * @element: a #GstElement to change state of.
2564  * @state: the element's new #GstState.
2565  *
2566  * Sets the state of the element. This function will try to set the
2567  * requested state by going through all the intermediary states and calling
2568  * the class's state change function for each.
2569  *
2570  * This function can return #GST_STATE_CHANGE_ASYNC, in which case the
2571  * element will perform the remainder of the state change asynchronously in
2572  * another thread.
2573  * An application can use gst_element_get_state() to wait for the completion
2574  * of the state change or it can wait for a %GST_MESSAGE_ASYNC_DONE or
2575  * %GST_MESSAGE_STATE_CHANGED on the bus.
2576  *
2577  * State changes to %GST_STATE_READY or %GST_STATE_NULL never return
2578  * #GST_STATE_CHANGE_ASYNC.
2579  *
2580  * Returns: Result of the state change using #GstStateChangeReturn.
2581  *
2582  * MT safe.
2583  */
2584 GstStateChangeReturn
2585 gst_element_set_state (GstElement * element, GstState state)
2586 {
2587   GstElementClass *oclass;
2588   GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
2589
2590   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2591
2592   oclass = GST_ELEMENT_GET_CLASS (element);
2593
2594   if (oclass->set_state)
2595     result = (oclass->set_state) (element, state);
2596
2597   return result;
2598 }
2599
2600 /*
2601  * default set state function, calculates the next state based
2602  * on current state and calls the change_state function
2603  */
2604 static GstStateChangeReturn
2605 gst_element_set_state_func (GstElement * element, GstState state)
2606 {
2607   GstState current, next, old_pending;
2608   GstStateChangeReturn ret;
2609   GstStateChange transition;
2610   GstStateChangeReturn old_ret;
2611
2612   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2613
2614   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "set_state to %s",
2615       gst_element_state_get_name (state));
2616
2617   /* state lock is taken to protect the set_state() and get_state()
2618    * procedures, it does not lock any variables. */
2619   GST_STATE_LOCK (element);
2620
2621   /* now calculate how to get to the new state */
2622   GST_OBJECT_LOCK (element);
2623   old_ret = GST_STATE_RETURN (element);
2624   /* previous state change returned an error, remove all pending
2625    * and next states */
2626   if (old_ret == GST_STATE_CHANGE_FAILURE) {
2627     GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
2628     GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
2629     GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
2630   }
2631
2632   current = GST_STATE (element);
2633   next = GST_STATE_NEXT (element);
2634   old_pending = GST_STATE_PENDING (element);
2635
2636   /* this is the (new) state we should go to. TARGET is the last state we set on
2637    * the element. */
2638   if (state != GST_STATE_TARGET (element)) {
2639     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2640         "setting target state to %s", gst_element_state_get_name (state));
2641     GST_STATE_TARGET (element) = state;
2642     /* increment state cookie so that we can track each state change. We only do
2643      * this if this is actually a new state change. */
2644     element->state_cookie++;
2645   }
2646   GST_STATE_PENDING (element) = state;
2647
2648   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2649       "current %s, old_pending %s, next %s, old return %s",
2650       gst_element_state_get_name (current),
2651       gst_element_state_get_name (old_pending),
2652       gst_element_state_get_name (next),
2653       gst_element_state_change_return_get_name (old_ret));
2654
2655   /* if the element was busy doing a state change, we just update the
2656    * target state, it'll get to it async then. */
2657   if (old_pending != GST_STATE_VOID_PENDING) {
2658     /* upwards state change will happen ASYNC */
2659     if (old_pending <= state)
2660       goto was_busy;
2661     /* element is going to this state already */
2662     else if (next == state)
2663       goto was_busy;
2664     /* element was performing an ASYNC upward state change and
2665      * we request to go downward again. Start from the next pending
2666      * state then. */
2667     else if (next > state
2668         && GST_STATE_RETURN (element) == GST_STATE_CHANGE_ASYNC) {
2669       current = next;
2670     }
2671   }
2672   next = GST_STATE_GET_NEXT (current, state);
2673   /* now we store the next state */
2674   GST_STATE_NEXT (element) = next;
2675   /* mark busy, we need to check that there is actually a state change
2676    * to be done else we could accidentally override SUCCESS/NO_PREROLL and
2677    * the default element change_state function has no way to know what the
2678    * old value was... could consider this a FIXME...*/
2679   if (current != next)
2680     GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2681
2682   transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2683
2684   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2685       "%s: setting state from %s to %s",
2686       (next != state ? "intermediate" : "final"),
2687       gst_element_state_get_name (current), gst_element_state_get_name (next));
2688
2689   /* now signal any waiters, they will error since the cookie was incremented */
2690   GST_STATE_BROADCAST (element);
2691
2692   GST_OBJECT_UNLOCK (element);
2693
2694   ret = gst_element_change_state (element, transition);
2695
2696   GST_STATE_UNLOCK (element);
2697
2698   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "returned %s",
2699       gst_element_state_change_return_get_name (ret));
2700
2701   return ret;
2702
2703 was_busy:
2704   {
2705     GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2706     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2707         "element was busy with async state change");
2708     GST_OBJECT_UNLOCK (element);
2709
2710     GST_STATE_UNLOCK (element);
2711
2712     return GST_STATE_CHANGE_ASYNC;
2713   }
2714 }
2715
2716 /**
2717  * gst_element_change_state:
2718  * @element: a #GstElement
2719  * @transition: the requested transition
2720  *
2721  * Perform @transition on @element.
2722  *
2723  * This function must be called with STATE_LOCK held and is mainly used
2724  * internally.
2725  *
2726  * Returns: the #GstStateChangeReturn of the state transition.
2727  */
2728 GstStateChangeReturn
2729 gst_element_change_state (GstElement * element, GstStateChange transition)
2730 {
2731   GstElementClass *oclass;
2732   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2733
2734   oclass = GST_ELEMENT_GET_CLASS (element);
2735
2736   GST_TRACER_ELEMENT_CHANGE_STATE_PRE (element, transition);
2737
2738   /* call the state change function so it can set the state */
2739   if (oclass->change_state)
2740     ret = (oclass->change_state) (element, transition);
2741   else
2742     ret = GST_STATE_CHANGE_FAILURE;
2743
2744   GST_TRACER_ELEMENT_CHANGE_STATE_POST (element, transition, ret);
2745
2746   switch (ret) {
2747     case GST_STATE_CHANGE_FAILURE:
2748       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2749           "have FAILURE change_state return");
2750       /* state change failure */
2751       gst_element_abort_state (element);
2752       break;
2753     case GST_STATE_CHANGE_ASYNC:
2754     {
2755       GstState target;
2756
2757       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2758           "element will change state ASYNC");
2759
2760       target = GST_STATE_TARGET (element);
2761
2762       if (target > GST_STATE_READY)
2763         goto async;
2764
2765       /* else we just continue the state change downwards */
2766       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2767           "forcing commit state %s <= %s",
2768           gst_element_state_get_name (target),
2769           gst_element_state_get_name (GST_STATE_READY));
2770
2771       ret = gst_element_continue_state (element, GST_STATE_CHANGE_SUCCESS);
2772       break;
2773     }
2774     case GST_STATE_CHANGE_SUCCESS:
2775       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2776           "element changed state SUCCESS");
2777       /* we can commit the state now which will proceeed to
2778        * the next state */
2779       ret = gst_element_continue_state (element, ret);
2780       break;
2781     case GST_STATE_CHANGE_NO_PREROLL:
2782       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2783           "element changed state NO_PREROLL");
2784       /* we can commit the state now which will proceeed to
2785        * the next state */
2786       ret = gst_element_continue_state (element, ret);
2787       break;
2788     default:
2789       goto invalid_return;
2790   }
2791
2792   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit state change %d", ret);
2793
2794   return ret;
2795
2796 async:
2797   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit async state change %d",
2798       ret);
2799
2800   return ret;
2801
2802   /* ERROR */
2803 invalid_return:
2804   {
2805     GST_OBJECT_LOCK (element);
2806     /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2807     g_critical ("%s: unknown return value %d from a state change function",
2808         GST_ELEMENT_NAME (element), ret);
2809
2810     /* we are in error now */
2811     ret = GST_STATE_CHANGE_FAILURE;
2812     GST_STATE_RETURN (element) = ret;
2813     GST_OBJECT_UNLOCK (element);
2814
2815     return ret;
2816   }
2817 }
2818
2819 /* gst_iterator_fold functions for pads_activate
2820  * Stop the iterator if activating one pad failed, but only if that pad
2821  * has not been removed from the element. */
2822 static gboolean
2823 activate_pads (const GValue * vpad, GValue * ret, gboolean * active)
2824 {
2825   GstPad *pad = g_value_get_object (vpad);
2826   gboolean cont = TRUE;
2827
2828   if (!gst_pad_set_active (pad, *active)) {
2829     if (GST_PAD_PARENT (pad) != NULL) {
2830       cont = FALSE;
2831       g_value_set_boolean (ret, FALSE);
2832     }
2833   }
2834
2835   return cont;
2836 }
2837
2838 /* returns false on error or early cutout of the fold, true if all
2839  * pads in @iter were (de)activated successfully. */
2840 static gboolean
2841 iterator_activate_fold_with_resync (GstIterator * iter,
2842     GstIteratorFoldFunction func, gpointer user_data)
2843 {
2844   GstIteratorResult ires;
2845   GValue ret = { 0 };
2846
2847   /* no need to unset this later, it's just a boolean */
2848   g_value_init (&ret, G_TYPE_BOOLEAN);
2849   g_value_set_boolean (&ret, TRUE);
2850
2851   while (1) {
2852     ires = gst_iterator_fold (iter, func, &ret, user_data);
2853     switch (ires) {
2854       case GST_ITERATOR_RESYNC:
2855         /* need to reset the result again */
2856         g_value_set_boolean (&ret, TRUE);
2857         gst_iterator_resync (iter);
2858         break;
2859       case GST_ITERATOR_DONE:
2860         /* all pads iterated, return collected value */
2861         goto done;
2862       default:
2863         /* iterator returned _ERROR or premature end with _OK,
2864          * mark an error and exit */
2865         g_value_set_boolean (&ret, FALSE);
2866         goto done;
2867     }
2868   }
2869 done:
2870   /* return collected value */
2871   return g_value_get_boolean (&ret);
2872 }
2873
2874 /* is called with STATE_LOCK
2875  *
2876  * Pads are activated from source pads to sinkpads.
2877  */
2878 static gboolean
2879 gst_element_pads_activate (GstElement * element, gboolean active)
2880 {
2881   GstIterator *iter;
2882   gboolean res;
2883
2884   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2885       "%s pads", active ? "activate" : "deactivate");
2886
2887   iter = gst_element_iterate_src_pads (element);
2888   res =
2889       iterator_activate_fold_with_resync (iter,
2890       (GstIteratorFoldFunction) activate_pads, &active);
2891   gst_iterator_free (iter);
2892   if (G_UNLIKELY (!res))
2893     goto src_failed;
2894
2895   iter = gst_element_iterate_sink_pads (element);
2896   res =
2897       iterator_activate_fold_with_resync (iter,
2898       (GstIteratorFoldFunction) activate_pads, &active);
2899   gst_iterator_free (iter);
2900   if (G_UNLIKELY (!res))
2901     goto sink_failed;
2902
2903   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2904       "pad %sactivation successful", active ? "" : "de");
2905
2906   return TRUE;
2907
2908   /* ERRORS */
2909 src_failed:
2910   {
2911     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2912         "pad %sactivation failed", active ? "" : "de");
2913     return FALSE;
2914   }
2915 sink_failed:
2916   {
2917     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
2918         "sink pads_activate failed");
2919     return FALSE;
2920   }
2921 }
2922
2923 /* is called with STATE_LOCK */
2924 static GstStateChangeReturn
2925 gst_element_change_state_func (GstElement * element, GstStateChange transition)
2926 {
2927   GstState state, next;
2928   GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
2929
2930   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2931
2932   state = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
2933   next = GST_STATE_TRANSITION_NEXT (transition);
2934
2935   /* if the element already is in the given state, we just return success */
2936   if (next == GST_STATE_VOID_PENDING || state == next)
2937     goto was_ok;
2938
2939   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2940       "default handler tries setting state from %s to %s (%04x)",
2941       gst_element_state_get_name (state),
2942       gst_element_state_get_name (next), transition);
2943
2944   switch (transition) {
2945     case GST_STATE_CHANGE_NULL_TO_READY:
2946       break;
2947     case GST_STATE_CHANGE_READY_TO_PAUSED:
2948       if (!gst_element_pads_activate (element, TRUE)) {
2949         result = GST_STATE_CHANGE_FAILURE;
2950       }
2951       break;
2952     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2953       break;
2954     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2955       break;
2956     case GST_STATE_CHANGE_PAUSED_TO_READY:
2957     case GST_STATE_CHANGE_READY_TO_NULL:{
2958       GList *l;
2959
2960       /* deactivate pads in both cases, since they are activated on
2961          ready->paused but the element might not have made it to paused */
2962       if (!gst_element_pads_activate (element, FALSE)) {
2963         result = GST_STATE_CHANGE_FAILURE;
2964       }
2965
2966       /* Remove all non-persistent contexts */
2967       GST_OBJECT_LOCK (element);
2968       for (l = element->contexts; l;) {
2969         GstContext *context = l->data;
2970
2971         if (!gst_context_is_persistent (context)) {
2972           GList *next;
2973
2974           gst_context_unref (context);
2975           next = l->next;
2976           element->contexts = g_list_delete_link (element->contexts, l);
2977           l = next;
2978         } else {
2979           l = l->next;
2980         }
2981       }
2982       GST_OBJECT_UNLOCK (element);
2983       break;
2984     }
2985     default:
2986       /* this will catch real but unhandled state changes;
2987        * can only be caused by:
2988        * - a new state was added
2989        * - somehow the element was asked to jump across an intermediate state
2990        */
2991       g_warning ("Unhandled state change from %s to %s",
2992           gst_element_state_get_name (state),
2993           gst_element_state_get_name (next));
2994       break;
2995   }
2996   return result;
2997
2998 was_ok:
2999   {
3000     GST_OBJECT_LOCK (element);
3001     result = GST_STATE_RETURN (element);
3002     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
3003         "element is already in the %s state",
3004         gst_element_state_get_name (state));
3005     GST_OBJECT_UNLOCK (element);
3006
3007     return result;
3008   }
3009 }
3010
3011 /**
3012  * gst_element_get_factory:
3013  * @element: a #GstElement to request the element factory of.
3014  *
3015  * Retrieves the factory that was used to create this element.
3016  *
3017  * Returns: (transfer none): the #GstElementFactory used for creating this
3018  *     element. no refcounting is needed.
3019  */
3020 GstElementFactory *
3021 gst_element_get_factory (GstElement * element)
3022 {
3023   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3024
3025   return GST_ELEMENT_GET_CLASS (element)->elementfactory;
3026 }
3027
3028 static void
3029 gst_element_dispose (GObject * object)
3030 {
3031   GstElement *element = GST_ELEMENT_CAST (object);
3032   GstClock **clock_p;
3033   GstBus **bus_p;
3034   GstElementClass *oclass;
3035   GList *walk;
3036
3037   oclass = GST_ELEMENT_GET_CLASS (element);
3038
3039   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p dispose", element);
3040
3041   if (GST_STATE (element) != GST_STATE_NULL)
3042     goto not_null;
3043
3044   /* start by releasing all request pads, this might also remove some dynamic
3045    * pads */
3046   walk = element->pads;
3047   while (walk) {
3048     GstPad *pad = GST_PAD_CAST (walk->data);
3049
3050     walk = walk->next;
3051
3052     if (oclass->release_pad && GST_PAD_PAD_TEMPLATE (pad) &&
3053         GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad))
3054         == GST_PAD_REQUEST) {
3055       GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
3056           "removing request pad %s:%s", GST_DEBUG_PAD_NAME (pad));
3057       oclass->release_pad (element, pad);
3058
3059       /* in case the release_pad function removed the next pad too */
3060       if (walk && g_list_position (element->pads, walk) == -1)
3061         walk = element->pads;
3062     }
3063   }
3064   /* remove the remaining pads */
3065   while (element->pads) {
3066     GstPad *pad = GST_PAD_CAST (element->pads->data);
3067     GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
3068         "removing pad %s:%s", GST_DEBUG_PAD_NAME (pad));
3069     if (!gst_element_remove_pad (element, pad)) {
3070       /* only happens when someone unparented our pad.. */
3071       g_critical ("failed to remove pad %s:%s", GST_DEBUG_PAD_NAME (pad));
3072       break;
3073     }
3074   }
3075
3076   GST_OBJECT_LOCK (element);
3077   clock_p = &element->clock;
3078   bus_p = &element->bus;
3079   gst_object_replace ((GstObject **) clock_p, NULL);
3080   gst_object_replace ((GstObject **) bus_p, NULL);
3081   g_list_free_full (element->contexts, (GDestroyNotify) gst_context_unref);
3082   GST_OBJECT_UNLOCK (element);
3083
3084   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p parent class dispose",
3085       element);
3086
3087   G_OBJECT_CLASS (parent_class)->dispose (object);
3088
3089   return;
3090
3091   /* ERRORS */
3092 not_null:
3093   {
3094     gboolean is_locked;
3095
3096     is_locked = GST_ELEMENT_IS_LOCKED_STATE (element);
3097     g_critical
3098         ("\nTrying to dispose element %s, but it is in %s%s instead of the NULL"
3099         " state.\n"
3100         "You need to explicitly set elements to the NULL state before\n"
3101         "dropping the final reference, to allow them to clean up.\n"
3102         "This problem may also be caused by a refcounting bug in the\n"
3103         "application or some element.\n",
3104         GST_OBJECT_NAME (element),
3105         gst_element_state_get_name (GST_STATE (element)),
3106         is_locked ? " (locked)" : "");
3107     return;
3108   }
3109 }
3110
3111 static void
3112 gst_element_finalize (GObject * object)
3113 {
3114   GstElement *element = GST_ELEMENT_CAST (object);
3115
3116   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p finalize", element);
3117
3118   g_cond_clear (&element->state_cond);
3119   g_rec_mutex_clear (&element->state_lock);
3120
3121   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p finalize parent",
3122       element);
3123
3124   G_OBJECT_CLASS (parent_class)->finalize (object);
3125 }
3126
3127 static void
3128 gst_element_set_bus_func (GstElement * element, GstBus * bus)
3129 {
3130   GstBus **bus_p;
3131
3132   g_return_if_fail (GST_IS_ELEMENT (element));
3133
3134   GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
3135
3136   GST_OBJECT_LOCK (element);
3137   bus_p = &GST_ELEMENT_BUS (element);
3138   gst_object_replace ((GstObject **) bus_p, GST_OBJECT_CAST (bus));
3139   GST_OBJECT_UNLOCK (element);
3140 }
3141
3142 /**
3143  * gst_element_set_bus:
3144  * @element: a #GstElement to set the bus of.
3145  * @bus: (transfer none): the #GstBus to set.
3146  *
3147  * Sets the bus of the element. Increases the refcount on the bus.
3148  * For internal use only, unless you're testing elements.
3149  *
3150  * MT safe.
3151  */
3152 void
3153 gst_element_set_bus (GstElement * element, GstBus * bus)
3154 {
3155   GstElementClass *oclass;
3156
3157   g_return_if_fail (GST_IS_ELEMENT (element));
3158
3159   oclass = GST_ELEMENT_GET_CLASS (element);
3160
3161   if (oclass->set_bus)
3162     oclass->set_bus (element, bus);
3163 }
3164
3165 /**
3166  * gst_element_get_bus:
3167  * @element: a #GstElement to get the bus of.
3168  *
3169  * Returns the bus of the element. Note that only a #GstPipeline will provide a
3170  * bus for the application.
3171  *
3172  * Returns: (transfer full): the element's #GstBus. unref after usage.
3173  *
3174  * MT safe.
3175  */
3176 GstBus *
3177 gst_element_get_bus (GstElement * element)
3178 {
3179   GstBus *result = NULL;
3180
3181   g_return_val_if_fail (GST_IS_ELEMENT (element), result);
3182
3183   GST_OBJECT_LOCK (element);
3184   if ((result = GST_ELEMENT_BUS (element)))
3185     gst_object_ref (result);
3186   GST_OBJECT_UNLOCK (element);
3187
3188   GST_CAT_DEBUG_OBJECT (GST_CAT_BUS, element, "got bus %" GST_PTR_FORMAT,
3189       result);
3190
3191   return result;
3192 }
3193
3194 static void
3195 gst_element_set_context_default (GstElement * element, GstContext * context)
3196 {
3197   const gchar *context_type;
3198   GList *l;
3199
3200   g_return_if_fail (GST_IS_CONTEXT (context));
3201   context_type = gst_context_get_context_type (context);
3202   g_return_if_fail (context_type != NULL);
3203
3204   GST_OBJECT_LOCK (element);
3205   for (l = element->contexts; l; l = l->next) {
3206     GstContext *tmp = l->data;
3207     const gchar *tmp_type = gst_context_get_context_type (tmp);
3208
3209     /* Always store newest context but never replace
3210      * a persistent one by a non-persistent one */
3211     if (g_strcmp0 (context_type, tmp_type) == 0 &&
3212         (gst_context_is_persistent (context) ||
3213             !gst_context_is_persistent (tmp))) {
3214       gst_context_replace ((GstContext **) & l->data, context);
3215       break;
3216     }
3217   }
3218   /* Not found? Add */
3219   if (l == NULL) {
3220     element->contexts =
3221         g_list_prepend (element->contexts, gst_context_ref (context));
3222   }
3223   GST_OBJECT_UNLOCK (element);
3224 }
3225
3226 /**
3227  * gst_element_set_context:
3228  * @element: a #GstElement to set the context of.
3229  * @context: (transfer none): the #GstContext to set.
3230  *
3231  * Sets the context of the element. Increases the refcount of the context.
3232  *
3233  * MT safe.
3234  */
3235 void
3236 gst_element_set_context (GstElement * element, GstContext * context)
3237 {
3238   GstElementClass *oclass;
3239
3240   g_return_if_fail (GST_IS_ELEMENT (element));
3241   g_return_if_fail (GST_IS_CONTEXT (context));
3242
3243   oclass = GST_ELEMENT_GET_CLASS (element);
3244
3245   GST_CAT_DEBUG_OBJECT (GST_CAT_CONTEXT, element,
3246       "set context %p %" GST_PTR_FORMAT, context,
3247       gst_context_get_structure (context));
3248
3249   if (oclass->set_context)
3250     oclass->set_context (element, context);
3251 }
3252
3253 /**
3254  * gst_element_get_contexts:
3255  * @element: a #GstElement to set the context of.
3256  *
3257  * Gets the contexts set on the element.
3258  *
3259  * MT safe.
3260  *
3261  * Returns: (element-type Gst.Context) (transfer full): List of #GstContext
3262  *
3263  * Since: 1.8
3264  */
3265 GList *
3266 gst_element_get_contexts (GstElement * element)
3267 {
3268   GList *ret;
3269
3270   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3271
3272   GST_OBJECT_LOCK (element);
3273   ret = g_list_copy_deep (element->contexts, (GCopyFunc) gst_context_ref, NULL);
3274   GST_OBJECT_UNLOCK (element);
3275
3276   return ret;
3277 }
3278
3279 static gint
3280 _match_context_type (GstContext * c1, const gchar * context_type)
3281 {
3282   const gchar *c1_type;
3283
3284   c1_type = gst_context_get_context_type (c1);
3285
3286   return g_strcmp0 (c1_type, context_type);
3287 }
3288
3289 /**
3290  * gst_element_get_context_unlocked:
3291  * @element: a #GstElement to get the context of.
3292  * @context_type: a name of a context to retrieve
3293  *
3294  * Gets the context with @context_type set on the element or NULL.
3295  *
3296  * Returns: (transfer full): A #GstContext or NULL
3297  *
3298  * Since: 1.8
3299  */
3300 GstContext *
3301 gst_element_get_context_unlocked (GstElement * element,
3302     const gchar * context_type)
3303 {
3304   GstContext *ret = NULL;
3305   GList *node;
3306
3307   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3308
3309   node =
3310       g_list_find_custom (element->contexts, context_type,
3311       (GCompareFunc) _match_context_type);
3312   if (node && node->data)
3313     ret = gst_context_ref (node->data);
3314
3315   return ret;
3316 }
3317
3318 /**
3319  * gst_element_get_context:
3320  * @element: a #GstElement to get the context of.
3321  * @context_type: a name of a context to retrieve
3322  *
3323  * Gets the context with @context_type set on the element or NULL.
3324  *
3325  * MT safe.
3326  *
3327  * Returns: (transfer full): A #GstContext or NULL
3328  *
3329  * Since: 1.8
3330  */
3331 GstContext *
3332 gst_element_get_context (GstElement * element, const gchar * context_type)
3333 {
3334   GstContext *ret = NULL;
3335
3336   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
3337
3338   GST_OBJECT_LOCK (element);
3339   ret = gst_element_get_context_unlocked (element, context_type);
3340   GST_OBJECT_UNLOCK (element);
3341
3342   return ret;
3343 }
3344
3345 static void
3346 gst_element_property_post_notify_msg (GstElement * element, GObject * obj,
3347     GParamSpec * pspec, gboolean include_value)
3348 {
3349   GValue val = G_VALUE_INIT;
3350   GValue *v;
3351
3352   GST_LOG_OBJECT (element, "property '%s' of object %" GST_PTR_FORMAT " has "
3353       "changed, posting message with%s value", pspec->name, obj,
3354       include_value ? "" : "out");
3355
3356   if (include_value && (pspec->flags & G_PARAM_READABLE) != 0) {
3357     g_value_init (&val, pspec->value_type);
3358     g_object_get_property (obj, pspec->name, &val);
3359     v = &val;
3360   } else {
3361     v = NULL;
3362   }
3363   gst_element_post_message (element,
3364       gst_message_new_property_notify (GST_OBJECT_CAST (obj), pspec->name, v));
3365 }
3366
3367 static void
3368 gst_element_property_deep_notify_cb (GstElement * element, GObject * prop_obj,
3369     GParamSpec * pspec, gpointer user_data)
3370 {
3371   gboolean include_value = GPOINTER_TO_INT (user_data);
3372
3373   gst_element_property_post_notify_msg (element, prop_obj, pspec,
3374       include_value);
3375 }
3376
3377 static void
3378 gst_element_property_notify_cb (GObject * obj, GParamSpec * pspec,
3379     gpointer user_data)
3380 {
3381   gboolean include_value = GPOINTER_TO_INT (user_data);
3382
3383   gst_element_property_post_notify_msg (GST_ELEMENT_CAST (obj), obj, pspec,
3384       include_value);
3385 }
3386
3387 /**
3388  * gst_element_add_property_notify_watch:
3389  * @element: a #GstElement to watch for property changes
3390  * @property_name: (allow-none): name of property to watch for changes, or
3391  *     NULL to watch all properties
3392  * @include_value: whether to include the new property value in the message
3393  *
3394  * Returns: a watch id, which can be used in connection with
3395  *     gst_element_remove_property_notify_watch() to remove the watch again.
3396  *
3397  * Since: 1.10
3398  */
3399 gulong
3400 gst_element_add_property_notify_watch (GstElement * element,
3401     const gchar * property_name, gboolean include_value)
3402 {
3403   const gchar *sep;
3404   gchar *signal_name;
3405   gulong id;
3406
3407   g_return_val_if_fail (GST_IS_ELEMENT (element), 0);
3408
3409   sep = (property_name != NULL) ? "::" : NULL;
3410   signal_name = g_strconcat ("notify", sep, property_name, NULL);
3411   id = g_signal_connect (element, signal_name,
3412       G_CALLBACK (gst_element_property_notify_cb),
3413       GINT_TO_POINTER (include_value));
3414   g_free (signal_name);
3415
3416   return id;
3417 }
3418
3419 /**
3420  * gst_element_add_property_deep_notify_watch:
3421  * @element: a #GstElement to watch (recursively) for property changes
3422  * @property_name: (allow-none): name of property to watch for changes, or
3423  *     NULL to watch all properties
3424  * @include_value: whether to include the new property value in the message
3425  *
3426  * Returns: a watch id, which can be used in connection with
3427  *     gst_element_remove_property_notify_watch() to remove the watch again.
3428  *
3429  * Since: 1.10
3430  */
3431 gulong
3432 gst_element_add_property_deep_notify_watch (GstElement * element,
3433     const gchar * property_name, gboolean include_value)
3434 {
3435   const gchar *sep;
3436   gchar *signal_name;
3437   gulong id;
3438
3439   g_return_val_if_fail (GST_IS_ELEMENT (element), 0);
3440
3441   sep = (property_name != NULL) ? "::" : NULL;
3442   signal_name = g_strconcat ("deep-notify", sep, property_name, NULL);
3443   id = g_signal_connect (element, signal_name,
3444       G_CALLBACK (gst_element_property_deep_notify_cb),
3445       GINT_TO_POINTER (include_value));
3446   g_free (signal_name);
3447
3448   return id;
3449 }
3450
3451 /**
3452  * gst_element_remove_property_notify_watch:
3453  * @element: a #GstElement being watched for property changes
3454  * @watch_id: watch id to remove
3455  *
3456  * Since: 1.10
3457  */
3458 void
3459 gst_element_remove_property_notify_watch (GstElement * element, gulong watch_id)
3460 {
3461   g_signal_handler_disconnect (element, watch_id);
3462 }
3463
3464 typedef struct
3465 {
3466   GstElement *element;
3467   GstElementCallAsyncFunc func;
3468   gpointer user_data;
3469   GDestroyNotify destroy_notify;
3470 } GstElementCallAsyncData;
3471
3472 static void
3473 gst_element_call_async_func (gpointer data, gpointer user_data)
3474 {
3475   GstElementCallAsyncData *async_data = data;
3476
3477   async_data->func (async_data->element, async_data->user_data);
3478   if (async_data->destroy_notify)
3479     async_data->destroy_notify (async_data->user_data);
3480   gst_object_unref (async_data->element);
3481   g_free (async_data);
3482 }
3483
3484 /**
3485  * gst_element_call_async:
3486  * @element: a #GstElement
3487  * @func: Function to call asynchronously from another thread
3488  * @user_data: Data to pass to @func
3489  * @destroy_notify: GDestroyNotify for @user_data
3490  *
3491  * Calls @func from another thread and passes @user_data to it. This is to be
3492  * used for cases when a state change has to be performed from a streaming
3493  * thread, directly via gst_element_set_state() or indirectly e.g. via SEEK
3494  * events.
3495  *
3496  * Calling those functions directly from the streaming thread will cause
3497  * deadlocks in many situations, as they might involve waiting for the
3498  * streaming thread to shut down from this very streaming thread.
3499  *
3500  * MT safe.
3501  *
3502  * Since: 1.10
3503  */
3504 void
3505 gst_element_call_async (GstElement * element, GstElementCallAsyncFunc func,
3506     gpointer user_data, GDestroyNotify destroy_notify)
3507 {
3508   GstElementCallAsyncData *async_data;
3509
3510   g_return_if_fail (GST_IS_ELEMENT (element));
3511
3512   async_data = g_new0 (GstElementCallAsyncData, 1);
3513   async_data->element = gst_object_ref (element);
3514   async_data->func = func;
3515   async_data->user_data = user_data;
3516   async_data->destroy_notify = destroy_notify;
3517
3518   g_thread_pool_push (gst_element_pool, async_data, NULL);
3519 }
3520
3521 void
3522 _priv_gst_element_cleanup (void)
3523 {
3524   if (gst_element_pool) {
3525     g_thread_pool_free (gst_element_pool, FALSE, TRUE);
3526     gst_element_setup_thread_pool ();
3527   }
3528 }
3529
3530 GstStructure *
3531 gst_make_element_message_details (const char *name, ...)
3532 {
3533   GstStructure *structure;
3534   va_list varargs;
3535
3536   if (name == NULL)
3537     return NULL;
3538
3539   va_start (varargs, name);
3540   structure = gst_structure_new_valist ("details", name, varargs);
3541   va_end (varargs);
3542
3543   return structure;
3544 }