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