gst/gstelement.c (gst_element_dispose): More helpful message.
[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., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 /**
24  * SECTION:gstelement
25  * @short_description: Abstract base class for all pipeline elements
26  * @see_also: #GstElementFactory, #GstPad
27  *
28  * GstElement is the base class needed to construct an element that can be
29  * used in a GStreamer pipeline.  As such, it is not a functional entity, and
30  * cannot do anything when placed in a pipeline.
31  *
32  * The name of a GstElement can be get with gst_element_get_name() and set with
33  * gst_element_set_name().  For speed, GST_ELEMENT_NAME() can be used in the
34  * core when using the appropriate locking. Do not use this in plug-ins or
35  * applications in order to retain ABI compatibility.
36  *
37  * All elements have pads (of the type #GstPad).  These pads link to pads on
38  * other elements.  Buffers flow between these linked pads.
39  * A GstElement has a GList of #GstPad structures for all their input (or sink)
40  * and output (or source) pads.
41  * Core and plug-in writers can add and remove pads with gst_element_add_pad()
42  * and gst_element_remove_pad().
43  *
44  * A pad of an element can be retrieved by name with gst_element_get_pad().
45  * An iterator of all pads can be retrieved with gst_element_iterate_pads().
46  *
47  * Elements can be linked through their pads.
48  * If the link is straightforward, use the gst_element_link()
49  * convenience function to link two elements, or gst_element_link_many()
50  * for more elements in a row.
51  * Use gst_element_link_filtered() to link two elements constrained by
52  * a specified set of #GstCaps.
53  * For finer control, use gst_element_link_pads() and
54  * gst_element_link_pads_filtered() to specify the pads to link on
55  * each element by name.
56  *
57  * Each element has a state (see #GstState).  You can get and set the state
58  * of an element with gst_element_get_state() and gst_element_set_state().
59  * To get a string representation of a #GstState, use
60  * gst_element_state_get_name().
61  *
62  * You can get and set a #GstClock on an element using gst_element_get_clock()
63  * and gst_element_set_clock().
64  * Some elements can provide a clock for the pipeline if
65  * gst_element_provides_clock() returns TRUE. With the gst_element_provide_clock()
66  * method one can retrieve the clock provided by such an element.
67  * Not all elements require a clock to operate correctly. If
68  * gst_element_requires_clock() returns TRUE, a clock should be set on the
69  * element with gst_element_set_clock().
70  *
71  * Note that clock slection and distribution is normally handled by the
72  * toplevel #GstPipeline so the clock functions are only to be used in very
73  * specific situations.
74  */
75
76 #include "gst_private.h"
77 #include <glib.h>
78 #include <stdarg.h>
79 #include <gobject/gvaluecollector.h>
80
81 #include "gstelement.h"
82 #include "gstbus.h"
83 #include "gstmarshal.h"
84 #include "gsterror.h"
85 #include "gstevent.h"
86 #include "gstutils.h"
87 #include "gstinfo.h"
88 #include "gst-i18n-lib.h"
89
90 /* Element signals and args */
91 enum
92 {
93   NEW_PAD,
94   PAD_REMOVED,
95   NO_MORE_PADS,
96   /* add more above */
97   LAST_SIGNAL
98 };
99
100 enum
101 {
102   ARG_0
103       /* FILL ME */
104 };
105
106 extern void __gst_element_details_clear (GstElementDetails * dp);
107 extern void __gst_element_details_copy (GstElementDetails * dest,
108     const GstElementDetails * src);
109
110 static void gst_element_class_init (GstElementClass * klass);
111 static void gst_element_init (GstElement * element);
112 static void gst_element_base_class_init (gpointer g_class);
113 static void gst_element_base_class_finalize (gpointer g_class);
114
115 static void gst_element_dispose (GObject * object);
116 static void gst_element_finalize (GObject * object);
117
118 static GstStateChangeReturn gst_element_change_state (GstElement * element,
119     GstStateChange transition);
120 static GstStateChangeReturn gst_element_change_state_func (GstElement * element,
121     GstStateChange transition);
122 static GstStateChangeReturn gst_element_change_state_func (GstElement * element,
123     GstStateChange transition);
124 static GstStateChangeReturn gst_element_get_state_func (GstElement * element,
125     GstState * state, GstState * pending, GstClockTime timeout);
126 static void gst_element_set_bus_func (GstElement * element, GstBus * bus);
127
128 #ifndef GST_DISABLE_LOADSAVE
129 static xmlNodePtr gst_element_save_thyself (GstObject * object,
130     xmlNodePtr parent);
131 static void gst_element_restore_thyself (GstObject * parent, xmlNodePtr self);
132 #endif
133
134 static GstObjectClass *parent_class = NULL;
135 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
136
137 GType
138 gst_element_get_type (void)
139 {
140   static GType gst_element_type = 0;
141
142   if (!gst_element_type) {
143     static const GTypeInfo element_info = {
144       sizeof (GstElementClass),
145       gst_element_base_class_init,
146       gst_element_base_class_finalize,
147       (GClassInitFunc) gst_element_class_init,
148       NULL,
149       NULL,
150       sizeof (GstElement),
151       0,
152       (GInstanceInitFunc) gst_element_init,
153       NULL
154     };
155
156     gst_element_type = g_type_register_static (GST_TYPE_OBJECT, "GstElement",
157         &element_info, G_TYPE_FLAG_ABSTRACT);
158   }
159   return gst_element_type;
160 }
161
162 static void
163 gst_element_class_init (GstElementClass * klass)
164 {
165   GObjectClass *gobject_class;
166   GstObjectClass *gstobject_class;
167
168   gobject_class = (GObjectClass *) klass;
169   gstobject_class = (GstObjectClass *) klass;
170
171   parent_class = g_type_class_ref (GST_TYPE_OBJECT);
172
173   /**
174    * GstElement::pad-added:
175    * @gstelement: the object which received the signal
176    * @new_pad: the pad that has been added
177    *
178    * a new #GstPad has been added to the element.
179    */
180   gst_element_signals[NEW_PAD] =
181       g_signal_new ("pad-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
182       G_STRUCT_OFFSET (GstElementClass, pad_added), NULL, NULL,
183       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
184   /**
185    * GstElement::pad-removed:
186    * @gstelement: the object which received the signal
187    * @old_pad: the pad that has been removed
188    *
189    * a #GstPad has been removed from the element
190    */
191   gst_element_signals[PAD_REMOVED] =
192       g_signal_new ("pad-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
193       G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
194       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, G_TYPE_OBJECT);
195   /**
196    * GstElement::no-more-pads:
197    * @gstelement: the object which received the signal
198    *
199    * This signals that the element will not generate more dynamic pads.
200    */
201   gst_element_signals[NO_MORE_PADS] =
202       g_signal_new ("no-more-pads", G_TYPE_FROM_CLASS (klass),
203       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, no_more_pads), NULL,
204       NULL, gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
205
206   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
207   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_element_finalize);
208
209 #ifndef GST_DISABLE_LOADSAVE
210   gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
211   gstobject_class->restore_thyself =
212       GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
213 #endif
214
215   klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state_func);
216   klass->get_state = GST_DEBUG_FUNCPTR (gst_element_get_state_func);
217   klass->set_bus = GST_DEBUG_FUNCPTR (gst_element_set_bus_func);
218   klass->numpadtemplates = 0;
219
220   klass->elementfactory = NULL;
221 }
222
223 static void
224 gst_element_base_class_init (gpointer g_class)
225 {
226   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
227
228   memset (&element_class->details, 0, sizeof (GstElementDetails));
229   element_class->padtemplates = NULL;
230 }
231
232 static void
233 gst_element_base_class_finalize (gpointer g_class)
234 {
235   GstElementClass *klass = GST_ELEMENT_CLASS (g_class);
236
237   g_list_foreach (klass->padtemplates, (GFunc) gst_object_unref, NULL);
238   g_list_free (klass->padtemplates);
239   __gst_element_details_clear (&klass->details);
240 }
241
242 static void
243 gst_element_init (GstElement * element)
244 {
245   GST_STATE (element) = GST_STATE_NULL;
246   GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
247   GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
248   GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
249
250   element->state_lock = g_new0 (GStaticRecMutex, 1);
251   g_static_rec_mutex_init (element->state_lock);
252   element->state_cond = g_cond_new ();
253 }
254
255 /**
256  * gst_element_default_error:
257  * @object: a #GObject that signalled the error.
258  * @orig: the #GstObject that initiated the error.
259  * @error: the GError.
260  * @debug: an additional debug information string, or NULL.
261  *
262  * A default error signal callback to attach to an element.
263  * The user data passed to the g_signal_connect is ignored.
264  *
265  * The default handler will simply print the error string using g_print.
266  *
267  * MT safe.
268  */
269 void
270 gst_element_default_error (GObject * object, GstObject * source, GError * error,
271     gchar * debug)
272 {
273   gchar *name = gst_object_get_path_string (source);
274
275   g_print (_("ERROR: from element %s: %s\n"), name, error->message);
276   if (debug)
277     g_print (_("Additional debug info:\n%s\n"), debug);
278
279   g_free (name);
280 }
281
282 /**
283  * gst_element_release_request_pad:
284  * @element: a #GstElement to release the request pad of.
285  * @pad: the #GstPad to release.
286  *
287  * Makes the element free the previously requested pad as obtained
288  * with gst_element_get_request_pad().
289  *
290  * MT safe.
291  */
292 void
293 gst_element_release_request_pad (GstElement * element, GstPad * pad)
294 {
295   GstElementClass *oclass;
296
297   g_return_if_fail (GST_IS_ELEMENT (element));
298   g_return_if_fail (GST_IS_PAD (pad));
299
300   oclass = GST_ELEMENT_GET_CLASS (element);
301
302   if (oclass->release_pad)
303     (oclass->release_pad) (element, pad);
304   else
305     gst_element_remove_pad (element, pad);
306 }
307
308 /**
309  * gst_element_requires_clock:
310  * @element: a #GstElement to query
311  *
312  * Query if the element requires a clock.
313  *
314  * Returns: TRUE if the element requires a clock
315  *
316  * MT safe.
317  */
318 gboolean
319 gst_element_requires_clock (GstElement * element)
320 {
321   gboolean result;
322
323   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
324
325   result = (GST_ELEMENT_GET_CLASS (element)->set_clock != NULL);
326
327   return result;
328 }
329
330 /**
331  * gst_element_provides_clock:
332  * @element: a #GstElement to query
333  *
334  * Query if the element provides a clock.
335  *
336  * Returns: TRUE if the element provides a clock
337  *
338  * MT safe.
339  */
340 gboolean
341 gst_element_provides_clock (GstElement * element)
342 {
343   gboolean result;
344
345   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
346
347   result = (GST_ELEMENT_GET_CLASS (element)->provide_clock != NULL);
348
349   return result;
350 }
351
352 /**
353  * gst_element_provide_clock:
354  * @element: a #GstElement to query
355  *
356  * Get the clock provided by the given element.
357  *
358  * Returns: the GstClock provided by the element or NULL
359  * if no clock could be provided. Unref after usage.
360  *
361  * MT safe.
362  */
363 GstClock *
364 gst_element_provide_clock (GstElement * element)
365 {
366   GstClock *result = NULL;
367   GstElementClass *oclass;
368
369   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
370
371   oclass = GST_ELEMENT_GET_CLASS (element);
372
373   if (oclass->provide_clock)
374     result = oclass->provide_clock (element);
375
376   return result;
377 }
378
379 /**
380  * gst_element_set_clock:
381  * @element: a #GstElement to set the clock for.
382  * @clock: the #GstClock to set for the element.
383  *
384  * Sets the clock for the element. This function increases the
385  * refcount on the clock. Any previously set clock on the object
386  * is unreffed.
387  *
388  * MT safe.
389  */
390 void
391 gst_element_set_clock (GstElement * element, GstClock * clock)
392 {
393   GstElementClass *oclass;
394
395   g_return_if_fail (GST_IS_ELEMENT (element));
396
397   oclass = GST_ELEMENT_GET_CLASS (element);
398
399   if (oclass->set_clock)
400     oclass->set_clock (element, clock);
401
402   GST_LOCK (element);
403   gst_object_replace ((GstObject **) & element->clock, (GstObject *) clock);
404   GST_UNLOCK (element);
405 }
406
407 /**
408  * gst_element_get_clock:
409  * @element: a #GstElement to get the clock of.
410  *
411  * Gets the currently configured clock of the element.
412  *
413  * Returns: the #GstClock of the element. unref after usage.
414  *
415  * MT safe.
416  */
417 GstClock *
418 gst_element_get_clock (GstElement * element)
419 {
420   GstClock *result;
421
422   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
423
424   GST_LOCK (element);
425   if ((result = element->clock))
426     gst_object_ref (result);
427   GST_UNLOCK (element);
428
429   return result;
430 }
431
432 /**
433  * gst_element_set_base_time:
434  * @element: a #GstElement.
435  * @time: the base time to set.
436  *
437  * Set the base time of an element. See @gst_element_get_base_time().
438  *
439  * MT safe.
440  */
441 void
442 gst_element_set_base_time (GstElement * element, GstClockTime time)
443 {
444   g_return_if_fail (GST_IS_ELEMENT (element));
445
446   GST_LOCK (element);
447   element->base_time = time;
448   GST_UNLOCK (element);
449 }
450
451 /**
452  * gst_element_get_base_time:
453  * @element: a #GstElement.
454  *
455  * Returns the base time of the element. The base time is the
456  * absolute time of the clock when this element was last put to
457  * PLAYING. Substracting the base time from the clock time gives
458  * the stream time of the element.
459  *
460  * Returns: the base time of the element.
461  *
462  * MT safe.
463  */
464 GstClockTime
465 gst_element_get_base_time (GstElement * element)
466 {
467   GstClockTime result;
468
469   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
470
471   GST_LOCK (element);
472   result = element->base_time;
473   GST_UNLOCK (element);
474
475   return result;
476 }
477
478 #ifndef GST_DISABLE_INDEX
479 /**
480  * gst_element_is_indexable:
481  * @element: a #GstElement.
482  *
483  * Queries if the element can be indexed.
484  *
485  * Returns: TRUE if the element can be indexed.
486  *
487  * MT safe.
488  */
489 gboolean
490 gst_element_is_indexable (GstElement * element)
491 {
492   gboolean result;
493
494   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
495
496   result = (GST_ELEMENT_GET_CLASS (element)->set_index != NULL);
497
498   return result;
499 }
500
501 /**
502  * gst_element_set_index:
503  * @element: a #GstElement.
504  * @index: a #GstIndex.
505  *
506  * Set the specified GstIndex on the element. The refcount of the index
507  * will be increased, any previously set index is unreffed.
508  *
509  * MT safe.
510  */
511 void
512 gst_element_set_index (GstElement * element, GstIndex * index)
513 {
514   GstElementClass *oclass;
515
516   g_return_if_fail (GST_IS_ELEMENT (element));
517   g_return_if_fail (GST_IS_INDEX (index));
518
519   oclass = GST_ELEMENT_GET_CLASS (element);
520
521   if (oclass->set_index)
522     oclass->set_index (element, index);
523 }
524
525 /**
526  * gst_element_get_index:
527  * @element: a #GstElement.
528  *
529  * Gets the index from the element.
530  *
531  * Returns: a #GstIndex or NULL when no index was set on the
532  * element. unref after usage.
533  *
534  * MT safe.
535  */
536 GstIndex *
537 gst_element_get_index (GstElement * element)
538 {
539   GstElementClass *oclass;
540
541   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
542
543   oclass = GST_ELEMENT_GET_CLASS (element);
544
545   if (oclass->get_index)
546     return oclass->get_index (element);
547
548   return NULL;
549 }
550 #endif
551
552 /**
553  * gst_element_add_pad:
554  * @element: a #GstElement to add the pad to.
555  * @pad: the #GstPad to add to the element.
556  *
557  * Adds a pad (link point) to @element. @pad's parent will be set to @element;
558  * see gst_object_set_parent() for refcounting information.
559  *
560  * Pads are not automatically activated so elements should perform the needed
561  * steps to activate the pad in case this pad is added in the PAUSED or PLAYING
562  * state.
563  *
564  * The pad and the element should be unlocked when calling this function.
565  *
566  * Returns: TRUE if the pad could be added. This function can fail when
567  * passing bad arguments or when a pad with the same name already existed.
568  *
569  * MT safe.
570  */
571 gboolean
572 gst_element_add_pad (GstElement * element, GstPad * pad)
573 {
574   gchar *pad_name;
575
576   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
577   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
578
579   /* locking pad to look at the name */
580   GST_LOCK (pad);
581   pad_name = g_strdup (GST_PAD_NAME (pad));
582   GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'",
583       GST_STR_NULL (pad_name));
584   GST_UNLOCK (pad);
585
586   /* then check to see if there's already a pad by that name here */
587   GST_LOCK (element);
588   if (G_UNLIKELY (!gst_object_check_uniqueness (element->pads, pad_name)))
589     goto name_exists;
590
591   /* try to set the pad's parent */
592   if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (pad),
593               GST_OBJECT_CAST (element))))
594     goto had_parent;
595
596   g_free (pad_name);
597
598   /* add it to the list */
599   switch (gst_pad_get_direction (pad)) {
600     case GST_PAD_SRC:
601       element->srcpads = g_list_prepend (element->srcpads, pad);
602       element->numsrcpads++;
603       break;
604     case GST_PAD_SINK:
605       element->sinkpads = g_list_prepend (element->sinkpads, pad);
606       element->numsinkpads++;
607       break;
608     default:
609       goto no_direction;
610   }
611   element->pads = g_list_prepend (element->pads, pad);
612   element->numpads++;
613   element->pads_cookie++;
614   GST_UNLOCK (element);
615
616   /* emit the NEW_PAD signal */
617   g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad);
618
619   return TRUE;
620
621   /* ERROR cases */
622 name_exists:
623   {
624     g_critical ("Padname %s is not unique in element %s, not adding",
625         pad_name, GST_ELEMENT_NAME (element));
626     GST_UNLOCK (element);
627     g_free (pad_name);
628     return FALSE;
629   }
630 had_parent:
631   {
632     g_critical
633         ("Pad %s already has parent when trying to add to element %s",
634         pad_name, GST_ELEMENT_NAME (element));
635     GST_UNLOCK (element);
636     g_free (pad_name);
637     return FALSE;
638   }
639 no_direction:
640   {
641     GST_LOCK (pad);
642     g_critical
643         ("Trying to add pad %s to element %s, but it has no direction",
644         GST_OBJECT_NAME (pad), GST_ELEMENT_NAME (element));
645     GST_UNLOCK (pad);
646     GST_UNLOCK (element);
647     return FALSE;
648   }
649 }
650
651 /**
652  * gst_element_remove_pad:
653  * @element: a #GstElement to remove pad from.
654  * @pad: the #GstPad to remove from the element.
655  *
656  * Removes @pad from @element. @pad will be destroyed if it has not been
657  * referenced elsewhere.
658  *
659  * Returns: TRUE if the pad could be removed. Can return FALSE if the
660  * pad is not belonging to the provided element or when wrong parameters
661  * are passed to this function.
662  *
663  * MT safe.
664  */
665 gboolean
666 gst_element_remove_pad (GstElement * element, GstPad * pad)
667 {
668   GstPad *peer;
669
670   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
671   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
672
673   /* locking pad to look at the name and parent */
674   GST_LOCK (pad);
675   GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "removing pad '%s'",
676       GST_STR_NULL (GST_PAD_NAME (pad)));
677
678   if (G_UNLIKELY (GST_PAD_PARENT (pad) != element))
679     goto not_our_pad;
680   GST_UNLOCK (pad);
681
682   /* unlink */
683   if ((peer = gst_pad_get_peer (pad))) {
684     /* window for MT unsafeness, someone else could unlink here
685      * and then we call unlink with wrong pads. The unlink
686      * function would catch this and safely return failed. */
687     if (GST_PAD_IS_SRC (pad))
688       gst_pad_unlink (pad, peer);
689     else
690       gst_pad_unlink (peer, pad);
691
692     gst_object_unref (peer);
693   }
694
695   GST_LOCK (element);
696   /* remove it from the list */
697   switch (gst_pad_get_direction (pad)) {
698     case GST_PAD_SRC:
699       element->srcpads = g_list_remove (element->srcpads, pad);
700       element->numsrcpads--;
701       break;
702     case GST_PAD_SINK:
703       element->sinkpads = g_list_remove (element->sinkpads, pad);
704       element->numsinkpads--;
705       break;
706     default:
707       g_critical ("Removing pad without direction???");
708       break;
709   }
710   element->pads = g_list_remove (element->pads, pad);
711   element->numpads--;
712   element->pads_cookie++;
713   GST_UNLOCK (element);
714
715   g_signal_emit (G_OBJECT (element), gst_element_signals[PAD_REMOVED], 0, pad);
716
717   gst_object_unparent (GST_OBJECT (pad));
718
719   return TRUE;
720
721 not_our_pad:
722   {
723     /* FIXME, locking order? */
724     GST_LOCK (element);
725     g_critical ("Padname %s:%s does not belong to element %s when removing",
726         GST_ELEMENT_NAME (GST_PAD_PARENT (pad)), GST_PAD_NAME (pad),
727         GST_ELEMENT_NAME (element));
728     GST_UNLOCK (element);
729     GST_UNLOCK (pad);
730     return FALSE;
731   }
732 }
733
734 /**
735  * gst_element_no_more_pads:
736  * @element: a #GstElement
737  *
738  * Use this function to signal that the element does not expect any more pads
739  * to show up in the current pipeline. This function should be called whenever
740  * pads have been added by the element itself. Elements with GST_PAD_SOMETIMES
741  * pad templates use this in combination with autopluggers to figure out that
742  * the element is done initializing its pads.
743  *
744  * MT safe.
745  */
746 void
747 gst_element_no_more_pads (GstElement * element)
748 {
749   g_return_if_fail (GST_IS_ELEMENT (element));
750
751   g_signal_emit (element, gst_element_signals[NO_MORE_PADS], 0);
752 }
753
754 static gint
755 pad_compare_name (GstPad * pad1, const gchar * name)
756 {
757   gint result;
758
759   GST_LOCK (pad1);
760   result = strcmp (GST_PAD_NAME (pad1), name);
761   GST_UNLOCK (pad1);
762
763   return result;
764 }
765
766 /**
767  * gst_element_get_static_pad:
768  * @element: a #GstElement to find a static pad of.
769  * @name: the name of the static #GstPad to retrieve.
770  *
771  * Retrieves a pad from @element by name. This version only retrieves
772  * already-existing (i.e. 'static') pads.
773  *
774  * Returns: the requested #GstPad if found, otherwise NULL. unref after
775  * usage.
776  *
777  * MT safe.
778  */
779 GstPad *
780 gst_element_get_static_pad (GstElement * element, const gchar * name)
781 {
782   GList *find;
783   GstPad *result = NULL;
784
785   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
786   g_return_val_if_fail (name != NULL, NULL);
787
788   GST_LOCK (element);
789   find =
790       g_list_find_custom (element->pads, name, (GCompareFunc) pad_compare_name);
791   if (find) {
792     result = GST_PAD_CAST (find->data);
793     gst_object_ref (result);
794   }
795
796   if (result == NULL) {
797     GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"",
798         name, GST_ELEMENT_NAME (element));
799   } else {
800     GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
801         GST_ELEMENT_NAME (element), name);
802   }
803   GST_UNLOCK (element);
804
805   return result;
806 }
807
808 static GstPad *
809 gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
810     const gchar * name)
811 {
812   GstPad *newpad = NULL;
813   GstElementClass *oclass;
814
815   oclass = GST_ELEMENT_GET_CLASS (element);
816
817   if (oclass->request_new_pad)
818     newpad = (oclass->request_new_pad) (element, templ, name);
819
820   if (newpad)
821     gst_object_ref (newpad);
822
823   return newpad;
824 }
825
826 /**
827  * gst_element_get_request_pad:
828  * @element: a #GstElement to find a request pad of.
829  * @name: the name of the request #GstPad to retrieve.
830  *
831  * Retrieves a pad from the element by name. This version only retrieves
832  * request pads.
833  *
834  * Returns: requested #GstPad if found, otherwise NULL. Unref after usage.
835  */
836 GstPad *
837 gst_element_get_request_pad (GstElement * element, const gchar * name)
838 {
839   GstPadTemplate *templ = NULL;
840   GstPad *pad;
841   const gchar *req_name = NULL;
842   gboolean templ_found = FALSE;
843   GList *list;
844   gint n;
845   const gchar *data;
846   gchar *str, *endptr = NULL;
847   GstElementClass *class;
848
849   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
850   g_return_val_if_fail (name != NULL, NULL);
851
852   class = GST_ELEMENT_GET_CLASS (element);
853
854   if (strstr (name, "%")) {
855     templ = gst_element_class_get_pad_template (class, name);
856     req_name = NULL;
857     if (templ)
858       templ_found = TRUE;
859   } else {
860     list = gst_element_class_get_pad_template_list (class);
861     while (!templ_found && list) {
862       templ = (GstPadTemplate *) list->data;
863       if (templ->presence == GST_PAD_REQUEST) {
864         /* Because of sanity checks in gst_pad_template_new(), we know that %s
865            and %d, occurring at the end of the name_template, are the only
866            possibilities. */
867         GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
868             templ->name_template);
869         if ((str = strchr (templ->name_template, '%'))
870             && strncmp (templ->name_template, name,
871                 str - templ->name_template) == 0
872             && strlen (name) > str - templ->name_template) {
873           data = name + (str - templ->name_template);
874           if (*(str + 1) == 'd') {
875             /* it's an int */
876             n = (gint) strtol (data, &endptr, 10);
877             if (endptr && *endptr == '\0') {
878               templ_found = TRUE;
879               req_name = name;
880               break;
881             }
882           } else {
883             /* it's a string */
884             templ_found = TRUE;
885             req_name = name;
886             break;
887           }
888         }
889       }
890       list = list->next;
891     }
892   }
893
894   if (!templ_found)
895     return NULL;
896
897   pad = gst_element_request_pad (element, templ, req_name);
898
899   return pad;
900 }
901
902 /**
903  * gst_element_get_pad:
904  * @element: a #GstElement.
905  * @name: the name of the pad to retrieve.
906  *
907  * Retrieves a pad from @element by name. Tries gst_element_get_static_pad()
908  * first, then gst_element_get_request_pad().
909  *
910  * Returns: the #GstPad if found, otherwise %NULL. Unref after usage.
911  */
912 GstPad *
913 gst_element_get_pad (GstElement * element, const gchar * name)
914 {
915   GstPad *pad;
916
917   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
918   g_return_val_if_fail (name != NULL, NULL);
919
920   pad = gst_element_get_static_pad (element, name);
921   if (!pad)
922     pad = gst_element_get_request_pad (element, name);
923
924   return pad;
925 }
926
927 static GstIteratorItem
928 iterate_pad (GstIterator * it, GstPad * pad)
929 {
930   gst_object_ref (pad);
931   return GST_ITERATOR_ITEM_PASS;
932 }
933
934 static GstIterator *
935 gst_element_iterate_pad_list (GstElement * element, GList ** padlist)
936 {
937   GstIterator *result;
938
939   GST_LOCK (element);
940   gst_object_ref (element);
941   result = gst_iterator_new_list (GST_TYPE_PAD,
942       GST_GET_LOCK (element),
943       &element->pads_cookie,
944       padlist,
945       element,
946       (GstIteratorItemFunction) iterate_pad,
947       (GstIteratorDisposeFunction) gst_object_unref);
948   GST_UNLOCK (element);
949
950   return result;
951 }
952
953 /**
954  * gst_element_iterate_pads:
955  * @element: a #GstElement to iterate pads of.
956  *
957  * Retrieves an iterattor of @element's pads. The iterator should
958  * be freed after usage.
959  *
960  * Returns: the #GstIterator of #GstPad. Unref each pad after use.
961  *
962  * MT safe.
963  */
964 GstIterator *
965 gst_element_iterate_pads (GstElement * element)
966 {
967   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
968
969   return gst_element_iterate_pad_list (element, &element->pads);
970 }
971
972 /**
973  * gst_element_iterate_src_pads:
974  * @element: a #GstElement.
975  *
976  * Retrieves an iterator of @element's source pads.
977  *
978  * Returns: the #GstIterator of #GstPad. Unref each pad after use.
979  *
980  * MT safe.
981  */
982 GstIterator *
983 gst_element_iterate_src_pads (GstElement * element)
984 {
985   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
986
987   return gst_element_iterate_pad_list (element, &element->srcpads);
988 }
989
990 /**
991  * gst_element_iterate_sink_pads:
992  * @element: a #GstElement.
993  *
994  * Retrieves an iterator of @element's sink pads.
995  *
996  * Returns: the #GstIterator of #GstPad. Unref each pad after use.
997  *
998  * MT safe.
999  */
1000 GstIterator *
1001 gst_element_iterate_sink_pads (GstElement * element)
1002 {
1003   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1004
1005   return gst_element_iterate_pad_list (element, &element->sinkpads);
1006 }
1007
1008 /**
1009  * gst_element_class_add_pad_template:
1010  * @klass: the #GstElementClass to add the pad template to.
1011  * @templ: a #GstPadTemplate to add to the element class.
1012  *
1013  * Adds a padtemplate to an element class. This is mainly used in the _base_init
1014  * functions of classes.
1015  */
1016 void
1017 gst_element_class_add_pad_template (GstElementClass * klass,
1018     GstPadTemplate * templ)
1019 {
1020   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1021   g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
1022
1023   /* avoid registering pad templates with the same name */
1024   g_return_if_fail (gst_element_class_get_pad_template (klass,
1025           templ->name_template) == NULL);
1026
1027   klass->padtemplates = g_list_append (klass->padtemplates,
1028       gst_object_ref (templ));
1029   klass->numpadtemplates++;
1030 }
1031
1032 /**
1033  * gst_element_class_set_details:
1034  * @klass: class to set details for
1035  * @details: details to set
1036  *
1037  * Sets the detailed information for a #GstElementClass.
1038  * <note>This function is for use in _base_init functions only.</note>
1039  */
1040 void
1041 gst_element_class_set_details (GstElementClass * klass,
1042     const GstElementDetails * details)
1043 {
1044   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
1045   g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
1046
1047   __gst_element_details_copy (&klass->details, details);
1048 }
1049
1050 /**
1051  * gst_element_class_get_pad_template_list:
1052  * @element_class: a #GstElementClass to get pad templates of.
1053  *
1054  * Retrieves a list of the pad templates associated with @element_class. The
1055  * list must not be modified by the calling code.
1056  * <note>If you use this function in the #GInstanceInitFunc of an object class
1057  * that has subclasses, make sure to pass the g_class parameter of the
1058  * #GInstanceInitFunc here.</note>
1059  *
1060  * Returns: the #GList of padtemplates.
1061  */
1062 GList *
1063 gst_element_class_get_pad_template_list (GstElementClass * element_class)
1064 {
1065   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1066
1067   return element_class->padtemplates;
1068 }
1069
1070 /**
1071  * gst_element_class_get_pad_template:
1072  * @element_class: a #GstElementClass to get the pad template of.
1073  * @name: the name of the #GstPadTemplate to get.
1074  *
1075  * Retrieves a padtemplate from @element_class with the given name.
1076  * <note>If you use this function in the #GInstanceInitFunc of an object class
1077  * that has subclasses, make sure to pass the g_class parameter of the
1078  * #GInstanceInitFunc here.</note>
1079  *
1080  * Returns: the #GstPadTemplate with the given name, or NULL if none was found.
1081  * No unreferencing is necessary.
1082  */
1083 GstPadTemplate *
1084 gst_element_class_get_pad_template (GstElementClass * element_class,
1085     const gchar * name)
1086 {
1087   GList *padlist;
1088
1089   g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
1090   g_return_val_if_fail (name != NULL, NULL);
1091
1092   padlist = gst_element_class_get_pad_template_list (element_class);
1093
1094   while (padlist) {
1095     GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
1096
1097     if (strcmp (padtempl->name_template, name) == 0)
1098       return padtempl;
1099
1100     padlist = g_list_next (padlist);
1101   }
1102
1103   return NULL;
1104 }
1105
1106 static GstPad *
1107 gst_element_get_random_pad (GstElement * element, GstPadDirection dir)
1108 {
1109   GstPad *result = NULL;
1110   GList *pads;
1111
1112   GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
1113
1114   switch (dir) {
1115     case GST_PAD_SRC:
1116       GST_LOCK (element);
1117       pads = element->srcpads;
1118       break;
1119     case GST_PAD_SINK:
1120       GST_LOCK (element);
1121       pads = element->sinkpads;
1122       break;
1123     default:
1124       goto wrong_direction;
1125   }
1126   for (; pads; pads = g_list_next (pads)) {
1127     GstPad *pad = GST_PAD (pads->data);
1128
1129     GST_LOCK (pad);
1130     GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
1131         GST_DEBUG_PAD_NAME (pad));
1132
1133     if (GST_PAD_IS_LINKED (pad)) {
1134       GST_UNLOCK (pad);
1135       result = pad;
1136       break;
1137     } else {
1138       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
1139           GST_DEBUG_PAD_NAME (pad));
1140     }
1141     GST_UNLOCK (pad);
1142   }
1143   if (result)
1144     gst_object_ref (result);
1145
1146   GST_UNLOCK (element);
1147
1148   return result;
1149
1150   /* ERROR handling */
1151 wrong_direction:
1152   {
1153     g_warning ("unknown pad direction %d", dir);
1154     return NULL;
1155   }
1156 }
1157
1158 /**
1159  * gst_element_send_event:
1160  * @element: a #GstElement to send the event to.
1161  * @event: the #GstEvent to send to the element.
1162  *
1163  * Sends an event to an element. If the element doesn't
1164  * implement an event handler, the event will be forwarded
1165  * to a random sink pad. This function takes owership of the
1166  * provided event so you should _ref it if you want to reuse
1167  * the event after this call.
1168  *
1169  * Returns: TRUE if the event was handled.
1170  *
1171  * MT safe.
1172  */
1173 gboolean
1174 gst_element_send_event (GstElement * element, GstEvent * event)
1175 {
1176   GstElementClass *oclass;
1177   gboolean result = FALSE;
1178
1179   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1180   g_return_val_if_fail (event != NULL, FALSE);
1181
1182   oclass = GST_ELEMENT_GET_CLASS (element);
1183
1184   if (oclass->send_event) {
1185     result = oclass->send_event (element, event);
1186   } else {
1187     GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1188
1189     if (pad) {
1190       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
1191           "pushing event to random pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1192
1193       result = gst_pad_push_event (pad, event);
1194       gst_object_unref (pad);
1195     } else {
1196       GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "can't send event on element %s",
1197           GST_ELEMENT_NAME (element));
1198     }
1199   }
1200   return result;
1201 }
1202
1203 /**
1204  * gst_element_seek:
1205  * @element: a #GstElement to send the event to.
1206  * @rate: The new playback rate
1207  * @format: The format of the seek values
1208  * @flags: The optional seek flags.
1209  * @cur_type: The type and flags for the new current position
1210  * @cur: The value of the new current position
1211  * @stop_type: The type and flags for the new stop position
1212  * @stop: The value of the new stop position
1213  *
1214  * Sends a seek event to an element.
1215  *
1216  * Returns: %TRUE if the event was handled.
1217  *
1218  * MT safe.
1219  */
1220 gboolean
1221 gst_element_seek (GstElement * element, gdouble rate, GstFormat format,
1222     GstSeekFlags flags, GstSeekType cur_type, gint64 cur,
1223     GstSeekType stop_type, gint64 stop)
1224 {
1225   GstEvent *event;
1226   gboolean result;
1227
1228   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1229
1230   event =
1231       gst_event_new_seek (rate, format, flags, cur_type, cur, stop_type, stop);
1232   result = gst_element_send_event (element, event);
1233
1234   return result;
1235 }
1236
1237 /**
1238  * gst_element_get_query_types:
1239  * @element: a #GstElement to query
1240  *
1241  * Get an array of query types from the element.
1242  * If the element doesn't implement a query types function,
1243  * the query will be forwarded to a random sink pad.
1244  *
1245  * Returns: An array of #GstQueryType elements that should not
1246  * be freed or modified.
1247  *
1248  * MT safe.
1249  */
1250 const GstQueryType *
1251 gst_element_get_query_types (GstElement * element)
1252 {
1253   GstElementClass *oclass;
1254   const GstQueryType *result = NULL;
1255
1256   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
1257
1258   oclass = GST_ELEMENT_GET_CLASS (element);
1259
1260   if (oclass->get_query_types) {
1261     result = oclass->get_query_types (element);
1262   } else {
1263     GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1264
1265     if (pad) {
1266       GstPad *peer = gst_pad_get_peer (pad);
1267
1268       if (peer) {
1269         result = gst_pad_get_query_types (peer);
1270
1271         gst_object_unref (peer);
1272       }
1273       gst_object_unref (pad);
1274     }
1275   }
1276   return result;
1277 }
1278
1279 /**
1280  * gst_element_query:
1281  * @element: a #GstElement to perform the query on.
1282  * @query: the #GstQuery.
1283  *
1284  * Performs a query on the given element. If the format is set
1285  * to GST_FORMAT_DEFAULT and this function returns TRUE, the
1286  * format pointer will hold the default format.
1287  * For element that don't implement a query handler, this function
1288  * forwards the query to a random usable sinkpad of this element.
1289  *
1290  * Returns: TRUE if the query could be performed.
1291  *
1292  * MT safe.
1293  */
1294 gboolean
1295 gst_element_query (GstElement * element, GstQuery * query)
1296 {
1297   GstElementClass *oclass;
1298   gboolean result = FALSE;
1299
1300   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1301   g_return_val_if_fail (query != NULL, FALSE);
1302
1303   oclass = GST_ELEMENT_GET_CLASS (element);
1304
1305   if (oclass->query) {
1306     result = oclass->query (element, query);
1307   } else {
1308     GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
1309
1310     if (pad) {
1311       result = gst_pad_query (pad, query);
1312
1313       gst_object_unref (pad);
1314     } else {
1315       pad = gst_element_get_random_pad (element, GST_PAD_SINK);
1316       if (pad) {
1317         GstPad *peer = gst_pad_get_peer (pad);
1318
1319         if (peer) {
1320           result = gst_pad_query (peer, query);
1321
1322           gst_object_unref (peer);
1323         }
1324         gst_object_unref (pad);
1325       }
1326     }
1327   }
1328   return result;
1329 }
1330
1331 /**
1332  * gst_element_post_message:
1333  * @element: a #GstElement posting the message
1334  * @message: a #GstMessage to post
1335  *
1336  * Post a message on the element's #GstBus. This function takes ownership of the
1337  * message; if you want to access the message after this call, you should add an
1338  * additional reference before calling.
1339  *
1340  * Returns: TRUE if the message was successfully posted.
1341  *
1342  * MT safe.
1343  */
1344 gboolean
1345 gst_element_post_message (GstElement * element, GstMessage * message)
1346 {
1347   GstBus *bus;
1348   gboolean result = FALSE;
1349
1350   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1351   g_return_val_if_fail (message != NULL, FALSE);
1352
1353   GST_LOCK (element);
1354   bus = element->bus;
1355
1356   if (G_UNLIKELY (bus == NULL))
1357     goto no_bus;
1358
1359   gst_object_ref (bus);
1360   GST_UNLOCK (element);
1361
1362   result = gst_bus_post (bus, message);
1363   gst_object_unref (bus);
1364
1365   return result;
1366
1367 no_bus:
1368   {
1369     GST_DEBUG ("not posting message %p: no bus", message);
1370     GST_UNLOCK (element);
1371     gst_message_unref (message);
1372     return FALSE;
1373   }
1374 }
1375
1376 /**
1377  * _gst_element_error_printf:
1378  * @format: the printf-like format to use, or NULL
1379  *
1380  * This function is only used internally by the #gst_element_error macro.
1381  *
1382  * Returns: a newly allocated string, or NULL if the format was NULL or ""
1383  *
1384  * MT safe.
1385  */
1386 gchar *
1387 _gst_element_error_printf (const gchar * format, ...)
1388 {
1389   va_list args;
1390   gchar *buffer;
1391
1392   if (format == NULL)
1393     return NULL;
1394   if (format[0] == 0)
1395     return NULL;
1396
1397   va_start (args, format);
1398   buffer = g_strdup_vprintf (format, args);
1399   va_end (args);
1400   return buffer;
1401 }
1402
1403 /**
1404  * gst_element_message_full:
1405  * @element:  a #GstElement to send message from
1406  * @type:     the #GstMessageType
1407  * @domain:   the GStreamer GError domain this message belongs to
1408  * @code:     the GError code belonging to the domain
1409  * @text:     an allocated text string to be used as a replacement for the
1410  *            default message connected to code, or NULL
1411  * @debug:    an allocated debug message to be used as a replacement for the
1412  *            default debugging information, or NULL
1413  * @file:     the source code file where the error was generated
1414  * @function: the source code function where the error was generated
1415  * @line:     the source code line where the error was generated
1416  *
1417  * Post an error or warning message on the bus from inside an element.
1418  *
1419  * MT safe.
1420  */
1421 void gst_element_message_full
1422     (GstElement * element, GstMessageType type,
1423     GQuark domain, gint code, gchar * text,
1424     gchar * debug, const gchar * file, const gchar * function, gint line)
1425 {
1426   GError *gerror = NULL;
1427   gchar *name;
1428   gchar *sent_text;
1429   gchar *sent_debug;
1430   GstMessage *message = NULL;
1431
1432   /* checks */
1433   GST_DEBUG ("start");
1434   g_return_if_fail (GST_IS_ELEMENT (element));
1435   g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
1436       (type == GST_MESSAGE_WARNING));
1437
1438   /* check if we send the given text or the default error text */
1439   if ((text == NULL) || (text[0] == 0)) {
1440     /* text could have come from g_strdup_printf (""); */
1441     g_free (text);
1442     sent_text = gst_error_get_message (domain, code);
1443   } else
1444     sent_text = text;
1445
1446   /* construct a sent_debug with extra information from source */
1447   if ((debug == NULL) || (debug[0] == 0)) {
1448     /* debug could have come from g_strdup_printf (""); */
1449     sent_debug = NULL;
1450   } else {
1451     name = gst_object_get_path_string (GST_OBJECT (element));
1452     sent_debug = g_strdup_printf ("%s(%d): %s: %s:\n%s",
1453         file, line, function, name, debug ? debug : "");
1454     g_free (name);
1455   }
1456   g_free (debug);
1457
1458   /* create gerror and post message */
1459   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
1460       sent_text);
1461   gerror = g_error_new_literal (domain, code, sent_text);
1462
1463   if (type == GST_MESSAGE_ERROR) {
1464     message = gst_message_new_error (GST_OBJECT (element), gerror, sent_debug);
1465   } else if (type == GST_MESSAGE_WARNING) {
1466     message = gst_message_new_warning (GST_OBJECT (element), gerror,
1467         sent_debug);
1468   } else {
1469     g_assert_not_reached ();
1470   }
1471   gst_element_post_message (element, message);
1472
1473   GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted message: %s",
1474       sent_text);
1475
1476   /* cleanup */
1477   g_error_free (gerror);
1478   g_free (sent_debug);
1479   g_free (sent_text);
1480 }
1481
1482 /**
1483  * gst_element_is_locked_state:
1484  * @element: a #GstElement.
1485  *
1486  * Checks if the state of an element is locked.
1487  * If the state of an element is locked, state changes of the parent don't
1488  * affect the element.
1489  * This way you can leave currently unused elements inside bins. Just lock their
1490  * state before changing the state from #GST_STATE_NULL.
1491  *
1492  * Returns: TRUE, if the element's state is locked.
1493  *
1494  * MT safe.
1495  */
1496 gboolean
1497 gst_element_is_locked_state (GstElement * element)
1498 {
1499   gboolean result;
1500
1501   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1502
1503   GST_LOCK (element);
1504   result = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1505   GST_UNLOCK (element);
1506
1507   return result;
1508 }
1509
1510 /**
1511  * gst_element_set_locked_state:
1512  * @element: a #GstElement
1513  * @locked_state: TRUE to lock the element's state
1514  *
1515  * Locks the state of an element, so state changes of the parent don't affect
1516  * this element anymore.
1517  *
1518  * Returns: TRUE if the state was changed, FALSE if bad params were given or
1519  * the element was already in the correct state.
1520  *
1521  * MT safe.
1522  */
1523 gboolean
1524 gst_element_set_locked_state (GstElement * element, gboolean locked_state)
1525 {
1526   gboolean old;
1527
1528   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1529
1530   GST_LOCK (element);
1531   old = GST_OBJECT_FLAG_IS_SET (element, GST_ELEMENT_LOCKED_STATE);
1532
1533   if (G_UNLIKELY (old == locked_state))
1534     goto was_ok;
1535
1536   if (locked_state) {
1537     GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
1538         GST_ELEMENT_NAME (element));
1539     GST_OBJECT_FLAG_SET (element, GST_ELEMENT_LOCKED_STATE);
1540   } else {
1541     GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
1542         GST_ELEMENT_NAME (element));
1543     GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_LOCKED_STATE);
1544   }
1545   GST_UNLOCK (element);
1546
1547   return TRUE;
1548
1549 was_ok:
1550   GST_UNLOCK (element);
1551
1552   return FALSE;
1553 }
1554
1555 /**
1556  * gst_element_sync_state_with_parent:
1557  * @element: a #GstElement.
1558  *
1559  * Tries to change the state of the element to the same as its parent.
1560  * If this function returns FALSE, the state of element is undefined.
1561  *
1562  * Returns: TRUE, if the element's state could be synced to the parent's state.
1563  *
1564  * MT safe.
1565  */
1566 gboolean
1567 gst_element_sync_state_with_parent (GstElement * element)
1568 {
1569   GstElement *parent;
1570
1571   g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
1572
1573   if ((parent = GST_ELEMENT_CAST (gst_element_get_parent (element)))) {
1574     GstState parent_current, parent_pending;
1575     GstStateChangeReturn ret;
1576
1577     GST_STATE_LOCK (parent);
1578     parent_current = GST_STATE (parent);
1579     parent_pending = GST_STATE_PENDING (parent);
1580     GST_STATE_UNLOCK (parent);
1581
1582     GST_CAT_DEBUG (GST_CAT_STATES,
1583         "syncing state of element %s (%s) to %s (%s, %s)",
1584         GST_ELEMENT_NAME (element),
1585         gst_element_state_get_name (GST_STATE (element)),
1586         GST_ELEMENT_NAME (parent), gst_element_state_get_name (parent_current),
1587         gst_element_state_get_name (parent_pending));
1588
1589     ret = gst_element_set_state (element, parent_current);
1590     if (ret == GST_STATE_CHANGE_FAILURE)
1591       goto failed;
1592
1593     gst_object_unref (parent);
1594
1595     return TRUE;
1596   }
1597   return FALSE;
1598
1599   /* ERROR */
1600 failed:
1601   {
1602     return FALSE;
1603   }
1604 }
1605
1606 /* MT safe */
1607 static GstStateChangeReturn
1608 gst_element_get_state_func (GstElement * element,
1609     GstState * state, GstState * pending, GstClockTime timeout)
1610 {
1611   GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
1612   GstState old_pending;
1613
1614   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "getting state");
1615
1616   GST_STATE_LOCK (element);
1617   ret = GST_STATE_RETURN (element);
1618
1619   /* we got an error, report immediatly */
1620   if (ret == GST_STATE_CHANGE_FAILURE)
1621     goto done;
1622
1623   /* we got no_preroll, report immediatly */
1624   if (ret == GST_STATE_CHANGE_NO_PREROLL)
1625     goto done;
1626
1627   /* no need to wait async if we are not async */
1628   if (ret != GST_STATE_CHANGE_ASYNC)
1629     goto done;
1630
1631   old_pending = GST_STATE_PENDING (element);
1632   if (old_pending != GST_STATE_VOID_PENDING) {
1633     GTimeVal *timeval, abstimeout;
1634
1635     if (timeout != GST_CLOCK_TIME_NONE) {
1636       glong add = timeout / 1000;
1637
1638       if (add == 0)
1639         goto done;
1640
1641       /* make timeout absolute */
1642       g_get_current_time (&abstimeout);
1643       g_time_val_add (&abstimeout, add);
1644       timeval = &abstimeout;
1645     } else {
1646       timeval = NULL;
1647     }
1648     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1649         "waiting for element to commit state");
1650     /* we have a pending state change, wait for it to complete */
1651     if (!GST_STATE_TIMED_WAIT (element, timeval)) {
1652       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timed out");
1653       /* timeout triggered */
1654       ret = GST_STATE_CHANGE_ASYNC;
1655     } else {
1656       /* could be success or failure */
1657       if (old_pending == GST_STATE (element)) {
1658         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got success");
1659         ret = GST_STATE_CHANGE_SUCCESS;
1660       } else {
1661         GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got failure");
1662         ret = GST_STATE_CHANGE_FAILURE;
1663       }
1664     }
1665   }
1666   /* if nothing is pending anymore we can return SUCCESS */
1667   if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
1668     GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "nothing pending");
1669     ret = GST_STATE_CHANGE_SUCCESS;
1670   }
1671
1672 done:
1673   if (state)
1674     *state = GST_STATE (element);
1675   if (pending)
1676     *pending = GST_STATE_PENDING (element);
1677
1678   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1679       "state current: %s, pending: %s, result: %d",
1680       gst_element_state_get_name (GST_STATE (element)),
1681       gst_element_state_get_name (GST_STATE_PENDING (element)), ret);
1682
1683   GST_STATE_UNLOCK (element);
1684
1685   return ret;
1686 }
1687
1688 /**
1689  * gst_element_get_state:
1690  * @element: a #GstElement to get the state of.
1691  * @state: a pointer to #GstState to hold the state. Can be NULL.
1692  * @pending: a pointer to #GstState to hold the pending state.
1693  *           Can be NULL.
1694  * @timeout: a #GstClockTime to specify the timeout for an async
1695  *           state change or GST_CLOCK_TIME_NONE for infinite timeout.
1696  *
1697  * Gets the state of the element.
1698  *
1699  * For elements that performed an ASYNC state change, as reported by
1700  * #gst_element_set_state(), this function will block up to the
1701  * specified timeout value for the state change to complete.
1702  * If the element completes the state change or goes into
1703  * an error, this function returns immediatly with a return value of
1704  * GST_STATE_CHANGE_SUCCESS or GST_STATE_CHANGE_FAILURE respectively.
1705  *
1706  * For elements that did not return ASYNC, this function returns the
1707  * current and pending state immediatly.
1708  *
1709  * Returns: GST_STATE_CHANGE_SUCCESS if the element has no more pending state and
1710  *          the last state change succeeded, GST_STATE_CHANGE_ASYNC
1711  *          if the element is still performing a state change or
1712  *          GST_STATE_CHANGE_FAILURE if the last state change failed.
1713  *
1714  * MT safe.
1715  */
1716 GstStateChangeReturn
1717 gst_element_get_state (GstElement * element,
1718     GstState * state, GstState * pending, GstClockTime timeout)
1719 {
1720   GstElementClass *oclass;
1721   GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
1722
1723   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
1724
1725   oclass = GST_ELEMENT_GET_CLASS (element);
1726
1727   if (oclass->get_state)
1728     result = (oclass->get_state) (element, state, pending, timeout);
1729
1730   return result;
1731 }
1732
1733 /**
1734  * gst_element_abort_state:
1735  * @element: a #GstElement to abort the state of.
1736  *
1737  * Abort the state change of the element. This function is used
1738  * by elements that do asynchronous state changes and find out
1739  * something is wrong.
1740  *
1741  * This function should be called with the STATE_LOCK held.
1742  *
1743  * MT safe.
1744  */
1745 void
1746 gst_element_abort_state (GstElement * element)
1747 {
1748   GstState pending;
1749
1750   g_return_if_fail (GST_IS_ELEMENT (element));
1751
1752   pending = GST_STATE_PENDING (element);
1753
1754   if (pending != GST_STATE_VOID_PENDING &&
1755       GST_STATE_RETURN (element) != GST_STATE_CHANGE_FAILURE) {
1756 #ifndef GST_DISABLE_GST_DEBUG
1757     GstState old_state = GST_STATE (element);
1758 #endif
1759     GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
1760         "aborting state from %s to %s", gst_element_state_get_name (old_state),
1761         gst_element_state_get_name (pending));
1762
1763     /* flag error */
1764     GST_STATE_RETURN (element) = GST_STATE_CHANGE_FAILURE;
1765
1766     GST_STATE_BROADCAST (element);
1767   }
1768 }
1769
1770 /**
1771  * gst_element_commit_state:
1772  * @element: a #GstElement to commit the state of.
1773  *
1774  * Commit the state change of the element. This function is used
1775  * by elements that do asynchronous state changes.
1776  * The core will normally call this method automatically when an
1777  * element returned SUCCESS from the state change function.
1778  * Elements that return ASYNC from the change_state function should
1779  * eventually call this method from the streaming thread to signal
1780  * successfull state change completion.
1781  *
1782  * If after calling this method the element still has not reached
1783  * the pending state, the next state change is performed.
1784  *
1785  * This function can only be called with the STATE_LOCK held.
1786  *
1787  * Returns: The result of the commit state change.
1788  *
1789  * MT safe.
1790  */
1791 GstStateChangeReturn
1792 gst_element_commit_state (GstElement * element)
1793 {
1794   GstState pending;
1795   GstStateChangeReturn ret;
1796
1797   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
1798
1799   ret = GST_STATE_CHANGE_SUCCESS;
1800
1801   pending = GST_STATE_PENDING (element);
1802
1803   /* check if there is something to commit */
1804   if (pending != GST_STATE_VOID_PENDING) {
1805     GstState old_state;
1806     GstState current, next;
1807     GstMessage *message;
1808
1809     GST_LOCK (element);
1810     GST_OBJECT_FLAG_SET (element, GST_ELEMENT_CHANGING_STATE);
1811     GST_UNLOCK (element);
1812
1813     old_state = GST_STATE (element);
1814     /* this is the state we should go to next */
1815     next = GST_STATE_NEXT (element);
1816     /* update current state */
1817     current = GST_STATE (element) = next;
1818
1819     /* see if we reached the final state */
1820     if (pending == next) {
1821       pending = GST_STATE_VOID_PENDING;
1822       GST_STATE_PENDING (element) = pending;
1823       GST_STATE_NEXT (element) = pending;
1824       ret = GST_STATE_CHANGE_SUCCESS;
1825     } else {
1826       /* not there yet, will get there ASYNC */
1827       ret = GST_STATE_CHANGE_ASYNC;
1828     }
1829
1830     GST_STATE_RETURN (element) = ret;
1831
1832     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1833         "committing state from %s to %s, pending %s",
1834         gst_element_state_get_name (old_state),
1835         gst_element_state_get_name (next),
1836         gst_element_state_get_name (pending));
1837
1838     message = gst_message_new_state_changed (GST_OBJECT (element),
1839         old_state, next, pending);
1840     gst_element_post_message (element, message);
1841
1842     if (pending != GST_STATE_VOID_PENDING) {
1843       GstStateChange transition;
1844
1845       /* calc new next state */
1846       next = GST_STATE_GET_NEXT (current, pending);
1847
1848       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1849           "continue state change %s to %s, final %s",
1850           gst_element_state_get_name (current),
1851           gst_element_state_get_name (next),
1852           gst_element_state_get_name (pending));
1853
1854       /* create transition */
1855       transition = GST_STATE_TRANSITION (current, next);
1856
1857       /* perform next transition */
1858       ret = gst_element_change_state (element, transition);
1859     } else {
1860       GST_STATE_BROADCAST (element);
1861     }
1862     GST_LOCK (element);
1863     GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_CHANGING_STATE);
1864     GST_UNLOCK (element);
1865   }
1866   return ret;
1867 }
1868
1869 /**
1870  * gst_element_lost_state:
1871  * @element: a #GstElement the state is lost of
1872  *
1873  * Brings the element to the lost state. The current state of the
1874  * element is copied to the pending state so that any call to
1875  * #gst_element_get_state() will return ASYNC.
1876  *
1877  * This is mostly used for elements that lost their preroll buffer
1878  * in the PAUSED state after a flush, they become PAUSED again
1879  * if a new preroll buffer is queued.
1880  * This function can only be called when the element is currently
1881  * not in error or an async state change.
1882  *
1883  * This function can only be called with the STATE_LOCK held.
1884  *
1885  * MT safe.
1886  */
1887 void
1888 gst_element_lost_state (GstElement * element)
1889 {
1890   g_return_if_fail (GST_IS_ELEMENT (element));
1891
1892   if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING &&
1893       GST_STATE_RETURN (element) != GST_STATE_CHANGE_FAILURE) {
1894     GstState current_state;
1895     GstMessage *message;
1896
1897     current_state = GST_STATE (element);
1898
1899     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1900         "lost state of %s", gst_element_state_get_name (current_state));
1901
1902     GST_STATE_NEXT (element) = current_state;
1903     GST_STATE_PENDING (element) = current_state;
1904     GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
1905
1906     message = gst_message_new_state_changed (GST_OBJECT (element),
1907         current_state, current_state, current_state);
1908     gst_element_post_message (element, message);
1909   }
1910 }
1911
1912 /**
1913  * gst_element_set_state:
1914  * @element: a #GstElement to change state of.
1915  * @state: the element's new #GstState.
1916  *
1917  * Sets the state of the element. This function will try to set the
1918  * requested state by going through all the intermediary states and calling
1919  * the class's state change function for each.
1920  *
1921  * This function can return GST_STATE_CHANGE_ASYNC, in which case the
1922  * element will perform the remainder of the state change asynchronously.
1923  * An application can use gst_element_get_state() to wait for the completion
1924  * of the state change or it can wait for a state change message on the bus.
1925  *
1926  * Returns: Result of the state change using #GstStateChangeReturn.
1927  *
1928  * MT safe.
1929  */
1930 GstStateChangeReturn
1931 gst_element_set_state (GstElement * element, GstState state)
1932 {
1933   GstState current, next, old_pending;
1934   GstStateChangeReturn ret;
1935   GstStateChange transition;
1936   GstStateChangeReturn old_ret;
1937
1938   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
1939
1940   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "set_state to %s",
1941       gst_element_state_get_name (state));
1942
1943   GST_STATE_LOCK (element);
1944
1945   GST_LOCK (element);
1946   GST_OBJECT_FLAG_SET (element, GST_ELEMENT_CHANGING_STATE);
1947   GST_UNLOCK (element);
1948
1949   old_ret = GST_STATE_RETURN (element);
1950   /* previous state change returned an error, remove all pending
1951    * and next states */
1952   if (old_ret == GST_STATE_CHANGE_FAILURE) {
1953     GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
1954     GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
1955     GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
1956   }
1957
1958   current = GST_STATE (element);
1959   next = GST_STATE_NEXT (element);
1960   old_pending = GST_STATE_PENDING (element);
1961
1962   /* this is the (new) state we should go to */
1963   GST_STATE_PENDING (element) = state;
1964
1965   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1966       "current %s, old_pending %s, next %s, old return %d",
1967       gst_element_state_get_name (current),
1968       gst_element_state_get_name (old_pending),
1969       gst_element_state_get_name (next), old_ret);
1970
1971   /* if the element was busy doing a state change, we just update the
1972    * target state, it'll get to it async then. */
1973   if (old_pending != GST_STATE_VOID_PENDING) {
1974     /* upwards state change will happen ASYNC */
1975     if (old_pending <= state)
1976       goto was_busy;
1977     /* element is going to this state already */
1978     else if (next == state)
1979       goto was_busy;
1980     /* element was performing an ASYNC upward state change and
1981      * we request to go downward again. Start from the next pending
1982      * state then. */
1983     else if (next > state
1984         && GST_STATE_RETURN (element) == GST_STATE_CHANGE_ASYNC) {
1985       current = next;
1986     }
1987   }
1988   next = GST_STATE_GET_NEXT (current, state);
1989
1990   GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
1991       "%s: setting state from %s to %s",
1992       (next != state ? "intermediate" : "final"),
1993       gst_element_state_get_name (current), gst_element_state_get_name (next));
1994
1995   transition = GST_STATE_TRANSITION (current, next);
1996
1997   ret = gst_element_change_state (element, transition);
1998
1999   GST_LOCK (element);
2000   GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_CHANGING_STATE);
2001   GST_UNLOCK (element);
2002   GST_STATE_UNLOCK (element);
2003
2004   GST_DEBUG_OBJECT (element, "returned %d", ret);
2005
2006   return ret;
2007
2008 was_busy:
2009   {
2010     GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
2011     GST_LOCK (element);
2012     GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_CHANGING_STATE);
2013     GST_UNLOCK (element);
2014     GST_STATE_UNLOCK (element);
2015
2016     GST_DEBUG_OBJECT (element, "element was busy with async state change");
2017
2018     return GST_STATE_CHANGE_ASYNC;
2019   }
2020
2021 }
2022
2023 /* with STATE_LOCK */
2024 static GstStateChangeReturn
2025 gst_element_change_state (GstElement * element, GstStateChange transition)
2026 {
2027   GstElementClass *oclass;
2028   GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
2029   GstState current;
2030   GstState next;
2031
2032   oclass = GST_ELEMENT_GET_CLASS (element);
2033
2034   /* start with the current state. */
2035   current = GST_STATE_TRANSITION_CURRENT (transition);
2036   next = GST_STATE_TRANSITION_NEXT (transition);
2037
2038   /* now we store the next state */
2039   GST_STATE_NEXT (element) = next;
2040
2041   /* call the state change function so it can set the state */
2042   if (oclass->change_state)
2043     ret = (oclass->change_state) (element, transition);
2044   else
2045     ret = GST_STATE_CHANGE_FAILURE;
2046
2047   switch (ret) {
2048     case GST_STATE_CHANGE_FAILURE:
2049       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2050           "have FAILURE change_state return");
2051       /* state change failure */
2052       gst_element_abort_state (element);
2053       break;
2054     case GST_STATE_CHANGE_ASYNC:
2055       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2056           "element will change state ASYNC");
2057
2058       /* if we go upwards, we give the app a change to wait for
2059        * completion */
2060       if (current < next)
2061         goto exit;
2062
2063       /* else we just continue the state change downwards */
2064       GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
2065           "forcing commit state %s < %s",
2066           gst_element_state_get_name (current),
2067           gst_element_state_get_name (next));
2068
2069       GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
2070
2071       ret = gst_element_commit_state (element);
2072       break;
2073     case GST_STATE_CHANGE_SUCCESS:
2074       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2075           "element changed state SUCCESS");
2076       /* we can commit the state now which will proceeed to
2077        * the next state */
2078       ret = gst_element_commit_state (element);
2079       break;
2080     case GST_STATE_CHANGE_NO_PREROLL:
2081       GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2082           "element changed state NO_PREROLL");
2083       /* we can commit the state now which will proceeed to
2084        * the next state */
2085       gst_element_commit_state (element);
2086       ret = GST_STATE_CHANGE_NO_PREROLL;
2087       break;
2088     default:
2089       ret = GST_STATE_CHANGE_FAILURE;
2090       goto invalid_return;
2091   }
2092
2093 exit:
2094   GST_STATE_RETURN (element) = ret;
2095
2096   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit state change %d", ret);
2097
2098   return ret;
2099
2100   /* ERROR */
2101 invalid_return:
2102   {
2103     GST_STATE_RETURN (element) = ret;
2104     /* somebody added a GST_STATE_ and forgot to do stuff here ! */
2105     g_critical ("unknown return value %d from a state change function", ret);
2106     return ret;
2107   }
2108 }
2109
2110 /* gst_iterator_fold functions for pads_activate */
2111
2112 static gboolean
2113 activate_pads (GstPad * pad, GValue * ret, gboolean * active)
2114 {
2115   if (!gst_pad_set_active (pad, *active))
2116     g_value_set_boolean (ret, FALSE);
2117   else if (!*active)
2118     gst_pad_set_caps (pad, NULL);
2119
2120   gst_object_unref (pad);
2121   return TRUE;
2122 }
2123
2124 /* returns false on error or early cutout of the fold, true otherwise */
2125 static gboolean
2126 iterator_fold_with_resync (GstIterator * iter, GstIteratorFoldFunction func,
2127     GValue * ret, gpointer user_data)
2128 {
2129   GstIteratorResult ires;
2130   gboolean res = TRUE;
2131
2132   while (1) {
2133     ires = gst_iterator_fold (iter, func, ret, user_data);
2134
2135     switch (ires) {
2136       case GST_ITERATOR_RESYNC:
2137         gst_iterator_resync (iter);
2138         break;
2139       case GST_ITERATOR_DONE:
2140         res = TRUE;
2141         goto done;
2142       default:
2143         res = FALSE;
2144         goto done;
2145     }
2146   }
2147
2148 done:
2149   return res;
2150 }
2151
2152 /* is called with STATE_LOCK
2153  */
2154 static gboolean
2155 gst_element_pads_activate (GstElement * element, gboolean active)
2156 {
2157   GValue ret = { 0, };
2158   GstIterator *iter;
2159   gboolean fold_ok;
2160
2161   GST_DEBUG_OBJECT (element, "pads_activate with active %d", active);
2162   /* no need to unset this later, it's just a boolean */
2163   g_value_init (&ret, G_TYPE_BOOLEAN);
2164   g_value_set_boolean (&ret, TRUE);
2165
2166   iter = gst_element_iterate_src_pads (element);
2167   fold_ok = iterator_fold_with_resync
2168       (iter, (GstIteratorFoldFunction) activate_pads, &ret, &active);
2169   gst_iterator_free (iter);
2170   if (!fold_ok || !g_value_get_boolean (&ret)) {
2171     GST_DEBUG_OBJECT (element, "pads_activate failed");
2172     return FALSE;
2173   }
2174
2175   iter = gst_element_iterate_sink_pads (element);
2176   fold_ok = iterator_fold_with_resync
2177       (iter, (GstIteratorFoldFunction) activate_pads, &ret, &active);
2178   gst_iterator_free (iter);
2179   if (!fold_ok || !g_value_get_boolean (&ret)) {
2180     GST_DEBUG_OBJECT (element, "pads_activate failed");
2181     return FALSE;
2182   }
2183
2184   GST_DEBUG_OBJECT (element, "pads_activate successful");
2185   return TRUE;
2186 }
2187
2188 /* is called with STATE_LOCK */
2189 static GstStateChangeReturn
2190 gst_element_change_state_func (GstElement * element, GstStateChange transition)
2191 {
2192   GstState state, next;
2193   GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
2194
2195   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
2196
2197   state = GST_STATE_TRANSITION_CURRENT (transition);
2198   next = GST_STATE_TRANSITION_NEXT (transition);
2199
2200   /* if the element already is in the given state, we just return success */
2201   if (next == GST_STATE_VOID_PENDING || state == next)
2202     goto was_ok;
2203
2204   GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
2205       "default handler tries setting state from %s to %s (%04x)",
2206       gst_element_state_get_name (state),
2207       gst_element_state_get_name (next), transition);
2208
2209   switch (transition) {
2210     case GST_STATE_CHANGE_NULL_TO_READY:
2211       break;
2212     case GST_STATE_CHANGE_READY_TO_PAUSED:
2213       if (!gst_element_pads_activate (element, TRUE)) {
2214         result = GST_STATE_CHANGE_FAILURE;
2215       }
2216       break;
2217     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
2218       break;
2219     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
2220       break;
2221     case GST_STATE_CHANGE_PAUSED_TO_READY:
2222     case GST_STATE_CHANGE_READY_TO_NULL:
2223       /* deactivate pads in both cases, since they are activated on
2224          ready->paused but the element might not have made it to paused */
2225       if (!gst_element_pads_activate (element, FALSE)) {
2226         result = GST_STATE_CHANGE_FAILURE;
2227       } else {
2228         gst_element_set_base_time (element, 0);
2229       }
2230       break;
2231     default:
2232       /* this will catch real but unhandled state changes;
2233        * can only be caused by:
2234        * - a new state was added
2235        * - somehow the element was asked to jump across an intermediate state
2236        */
2237       g_warning ("Unhandled state change from %s to %s",
2238           gst_element_state_get_name (state),
2239           gst_element_state_get_name (next));
2240       break;
2241   }
2242   return result;
2243
2244 was_ok:
2245   {
2246     GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2247         "element is already in the %s state",
2248         gst_element_state_get_name (state));
2249     return GST_STATE_RETURN (element);
2250   }
2251 }
2252
2253 /**
2254  * gst_element_get_factory:
2255  * @element: a #GstElement to request the element factory of.
2256  *
2257  * Retrieves the factory that was used to create this element.
2258  *
2259  * Returns: the #GstElementFactory used for creating this element.
2260  * no refcounting is needed.
2261  */
2262 GstElementFactory *
2263 gst_element_get_factory (GstElement * element)
2264 {
2265   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
2266
2267   return GST_ELEMENT_GET_CLASS (element)->elementfactory;
2268 }
2269
2270 static void
2271 gst_element_dispose (GObject * object)
2272 {
2273   GstElement *element = GST_ELEMENT (object);
2274
2275   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "dispose");
2276
2277   if (GST_STATE (element) != GST_STATE_NULL) {
2278     g_critical
2279         ("\nTrying to dispose element %s, but it is not in the NULL state.\n"
2280         "You need to explicitly set elements to the NULL state before\n"
2281         "dropping the final reference, to allow them to clean up.\n",
2282         GST_OBJECT_NAME (element));
2283     return;
2284   }
2285   g_return_if_fail (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING);
2286
2287   /* first we break all our links with the outside */
2288   while (element->pads) {
2289     gst_element_remove_pad (element, GST_PAD_CAST (element->pads->data));
2290   }
2291   if (G_UNLIKELY (element->pads != 0)) {
2292     g_critical ("could not remove pads from element %s",
2293         GST_STR_NULL (GST_OBJECT_NAME (object)));
2294   }
2295
2296   GST_LOCK (element);
2297   gst_object_replace ((GstObject **) & element->clock, NULL);
2298   gst_object_replace ((GstObject **) & element->bus, NULL);
2299   GST_UNLOCK (element);
2300
2301   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "parent class dispose");
2302
2303   G_OBJECT_CLASS (parent_class)->dispose (object);
2304 }
2305
2306 static void
2307 gst_element_finalize (GObject * object)
2308 {
2309   GstElement *element = GST_ELEMENT (object);
2310
2311   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize");
2312
2313   GST_STATE_LOCK (element);
2314   if (element->state_cond)
2315     g_cond_free (element->state_cond);
2316   element->state_cond = NULL;
2317   GST_STATE_UNLOCK (element);
2318   g_static_rec_mutex_free (element->state_lock);
2319   g_free (element->state_lock);
2320   element->state_lock = NULL;
2321
2322   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize parent");
2323
2324   G_OBJECT_CLASS (parent_class)->finalize (object);
2325 }
2326
2327 #ifndef GST_DISABLE_LOADSAVE
2328 /**
2329  * gst_element_save_thyself:
2330  * @element: a #GstElement to save.
2331  * @parent: the xml parent node.
2332  *
2333  * Saves the element as part of the given XML structure.
2334  *
2335  * Returns: the new #xmlNodePtr.
2336  */
2337 static xmlNodePtr
2338 gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
2339 {
2340   GList *pads;
2341   GstElementClass *oclass;
2342   GParamSpec **specs, *spec;
2343   guint nspecs;
2344   guint i;
2345   GValue value = { 0, };
2346   GstElement *element;
2347
2348   g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
2349
2350   element = GST_ELEMENT (object);
2351
2352   oclass = GST_ELEMENT_GET_CLASS (element);
2353
2354   xmlNewChild (parent, NULL, (xmlChar *) "name",
2355       (xmlChar *) GST_ELEMENT_NAME (element));
2356
2357   if (oclass->elementfactory != NULL) {
2358     GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
2359
2360     xmlNewChild (parent, NULL, (xmlChar *) "type",
2361         (xmlChar *) GST_PLUGIN_FEATURE (factory)->name);
2362   }
2363
2364   /* params */
2365   specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
2366
2367   for (i = 0; i < nspecs; i++) {
2368     spec = specs[i];
2369     if (spec->flags & G_PARAM_READABLE) {
2370       xmlNodePtr param;
2371       char *contents;
2372
2373       g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (spec));
2374
2375       g_object_get_property (G_OBJECT (element), spec->name, &value);
2376       param = xmlNewChild (parent, NULL, (xmlChar *) "param", NULL);
2377       xmlNewChild (param, NULL, (xmlChar *) "name", (xmlChar *) spec->name);
2378
2379       if (G_IS_PARAM_SPEC_STRING (spec))
2380         contents = g_value_dup_string (&value);
2381       else if (G_IS_PARAM_SPEC_ENUM (spec))
2382         contents = g_strdup_printf ("%d", g_value_get_enum (&value));
2383       else if (G_IS_PARAM_SPEC_INT64 (spec))
2384         contents = g_strdup_printf ("%" G_GINT64_FORMAT,
2385             g_value_get_int64 (&value));
2386       else
2387         contents = g_strdup_value_contents (&value);
2388
2389       xmlNewChild (param, NULL, (xmlChar *) "value", (xmlChar *) contents);
2390       g_free (contents);
2391
2392       g_value_unset (&value);
2393     }
2394   }
2395
2396   g_free (specs);
2397
2398   pads = GST_ELEMENT_PADS (element);
2399
2400   while (pads) {
2401     GstPad *pad = GST_PAD (pads->data);
2402
2403     /* figure out if it's a direct pad or a ghostpad */
2404     if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) {
2405       xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL);
2406
2407       gst_object_save_thyself (GST_OBJECT (pad), padtag);
2408     }
2409     pads = g_list_next (pads);
2410   }
2411
2412   return parent;
2413 }
2414
2415 static void
2416 gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
2417 {
2418   xmlNodePtr children;
2419   GstElement *element;
2420   gchar *name = NULL;
2421   gchar *value = NULL;
2422
2423   element = GST_ELEMENT (object);
2424   g_return_if_fail (element != NULL);
2425
2426   /* parameters */
2427   children = self->xmlChildrenNode;
2428   while (children) {
2429     if (!strcmp ((char *) children->name, "param")) {
2430       xmlNodePtr child = children->xmlChildrenNode;
2431
2432       while (child) {
2433         if (!strcmp ((char *) child->name, "name")) {
2434           name = (gchar *) xmlNodeGetContent (child);
2435         } else if (!strcmp ((char *) child->name, "value")) {
2436           value = (gchar *) xmlNodeGetContent (child);
2437         }
2438         child = child->next;
2439       }
2440       /* FIXME: can this just be g_object_set ? */
2441       gst_util_set_object_arg (G_OBJECT (element), name, value);
2442       /* g_object_set (G_OBJECT (element), name, value, NULL); */
2443       g_free (name);
2444       g_free (value);
2445     }
2446     children = children->next;
2447   }
2448
2449   /* pads */
2450   children = self->xmlChildrenNode;
2451   while (children) {
2452     if (!strcmp ((char *) children->name, "pad")) {
2453       gst_pad_load_and_link (children, GST_OBJECT (element));
2454     }
2455     children = children->next;
2456   }
2457
2458   if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
2459     (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
2460 }
2461 #endif /* GST_DISABLE_LOADSAVE */
2462
2463 static void
2464 gst_element_set_bus_func (GstElement * element, GstBus * bus)
2465 {
2466   g_return_if_fail (GST_IS_ELEMENT (element));
2467
2468   GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
2469
2470   GST_LOCK (element);
2471   gst_object_replace ((GstObject **) & GST_ELEMENT_BUS (element),
2472       GST_OBJECT_CAST (bus));
2473   GST_UNLOCK (element);
2474 }
2475
2476 /**
2477  * gst_element_set_bus:
2478  * @element: a #GstElement to set the bus of.
2479  * @bus: the #GstBus to set.
2480  *
2481  * Sets the bus of the element.  For internal use only, unless you're
2482  * testing elements.
2483  *
2484  * MT safe.
2485  */
2486 void
2487 gst_element_set_bus (GstElement * element, GstBus * bus)
2488 {
2489   GstElementClass *oclass;
2490
2491   g_return_if_fail (GST_IS_ELEMENT (element));
2492
2493   oclass = GST_ELEMENT_GET_CLASS (element);
2494
2495   if (oclass->set_bus)
2496     oclass->set_bus (element, bus);
2497 }
2498
2499 /**
2500  * gst_element_get_bus:
2501  * @element: a #GstElement to get the bus of.
2502  *
2503  * Returns the bus of the element.
2504  *
2505  * Returns: the element's #GstBus. unref after usage.
2506  *
2507  * MT safe.
2508  */
2509 GstBus *
2510 gst_element_get_bus (GstElement * element)
2511 {
2512   GstBus *result = NULL;
2513
2514   g_return_val_if_fail (GST_IS_ELEMENT (element), result);
2515
2516   GST_LOCK (element);
2517   result = GST_ELEMENT_BUS (element);
2518   gst_object_ref (result);
2519   GST_UNLOCK (element);
2520
2521   GST_DEBUG_OBJECT (element, "got bus %" GST_PTR_FORMAT, result);
2522
2523   return result;
2524 }