2 * Copyright (C) <2004> Wim Taymans <wim@fluendo.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
27 #include "gstplay-marshal.h"
29 /* generic templates */
30 static GstStaticPadTemplate decoder_bin_sink_template =
31 GST_STATIC_PAD_TEMPLATE ("sink",
36 static GstStaticPadTemplate decoder_bin_src_template =
37 GST_STATIC_PAD_TEMPLATE ("src%d",
42 GST_DEBUG_CATEGORY_STATIC (gst_decode_bin_debug);
43 #define GST_CAT_DEFAULT gst_decode_bin_debug
45 #define GST_TYPE_DECODE_BIN (gst_decode_bin_get_type())
46 #define GST_DECODE_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DECODE_BIN,GstDecodeBin))
47 #define GST_DECODE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DECODE_BIN,GstDecodeBinClass))
48 #define GST_IS_DECODE_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DECODE_BIN))
49 #define GST_IS_DECODE_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DECODE_BIN))
51 typedef struct _GstDecodeBin GstDecodeBin;
52 typedef struct _GstDecodeBinClass GstDecodeBinClass;
56 GstBin bin; /* we extend GstBin */
58 GstElement *typefind; /* this holds the typefind object */
60 gboolean threaded; /* indicating threaded execution is desired */
61 GList *dynamics; /* list of dynamic connections */
63 GList *factories; /* factories we can use for selecting elements */
66 GList *elements; /* elements we added in autoplugging */
68 guint have_type_id; /* signal id for the typefind element */
71 struct _GstDecodeBinClass
73 GstBinClass parent_class;
75 /* signal we fire when a new pad has been decoded into raw audio/video */
76 void (*new_decoded_pad) (GstElement * element, GstPad * pad, gboolean last);
77 /* signal we fire when a pad has been removed */
78 void (*removed_decoded_pad) (GstElement * element, GstPad * pad);
79 /* signal fired when we found a pad that we cannot decode */
80 void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps);
83 #define DEFAULT_THREADED FALSE
95 SIGNAL_NEW_DECODED_PAD,
96 SIGNAL_REMOVED_DECODED_PAD,
102 /* this structure is created for all dynamic pads that could get created
106 gint np_sig_id; /* signal id of new_pad */
107 gint unlink_sig_id; /* signal id of unlinked */
108 gint nmp_sig_id; /* signal id of no_more_pads */
109 GstElement *element; /* the element sending the signal */
110 GstDecodeBin *decode_bin; /* pointer to ourself */
114 static void gst_decode_bin_class_init (GstDecodeBinClass * klass);
115 static void gst_decode_bin_init (GstDecodeBin * decode_bin);
116 static void gst_decode_bin_dispose (GObject * object);
118 static void gst_decode_bin_set_property (GObject * object, guint prop_id,
119 const GValue * value, GParamSpec * spec);
120 static void gst_decode_bin_get_property (GObject * object, guint prop_id,
121 GValue * value, GParamSpec * spec);
122 static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
123 GstStateChange transition);
125 static void type_found (GstElement * typefind, guint probability,
126 GstCaps * caps, GstDecodeBin * decode_bin);
127 static GstElement *try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad,
129 static void close_link (GstElement * element, GstDecodeBin * decode_bin);
130 static void close_pad_link (GstElement * element, GstPad * pad,
131 GstCaps * caps, GstDecodeBin * decode_bin, gboolean more);
132 static void unlinked (GstPad * pad, GstPad * peerpad,
133 GstDecodeBin * decode_bin);
134 static void new_pad (GstElement * element, GstPad * pad, GstDynamic * dynamic);
135 static void no_more_pads (GstElement * element, GstDynamic * dynamic);
137 static GstElementClass *parent_class;
138 static guint gst_decode_bin_signals[LAST_SIGNAL] = { 0 };
140 static GstElementDetails gst_decode_bin_details = {
142 "Generic/Bin/Decoder",
143 "Autoplug and decode to raw media",
144 "Wim Taymans <wim@fluendo.com>"
149 gst_decode_bin_get_type (void)
151 static GType gst_decode_bin_type = 0;
153 if (!gst_decode_bin_type) {
154 static const GTypeInfo gst_decode_bin_info = {
155 sizeof (GstDecodeBinClass),
158 (GClassInitFunc) gst_decode_bin_class_init,
161 sizeof (GstDecodeBin),
163 (GInstanceInitFunc) gst_decode_bin_init,
167 gst_decode_bin_type =
168 g_type_register_static (GST_TYPE_BIN, "GstDecodeBin",
169 &gst_decode_bin_info, 0);
172 return gst_decode_bin_type;
176 gst_decode_bin_class_init (GstDecodeBinClass * klass)
178 GObjectClass *gobject_klass;
179 GstElementClass *gstelement_klass;
180 GstBinClass *gstbin_klass;
182 gobject_klass = (GObjectClass *) klass;
183 gstelement_klass = (GstElementClass *) klass;
184 gstbin_klass = (GstBinClass *) klass;
186 parent_class = g_type_class_ref (gst_bin_get_type ());
188 gobject_klass->set_property = gst_decode_bin_set_property;
189 gobject_klass->get_property = gst_decode_bin_get_property;
191 g_object_class_install_property (gobject_klass, ARG_THREADED,
192 g_param_spec_boolean ("threaded", "Threaded", "Use threads",
193 DEFAULT_THREADED, G_PARAM_READWRITE));
195 gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD] =
196 g_signal_new ("new-decoded-pad", G_TYPE_FROM_CLASS (klass),
198 G_STRUCT_OFFSET (GstDecodeBinClass, new_decoded_pad), NULL, NULL,
199 gst_play_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2, GST_TYPE_PAD,
201 gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD] =
202 g_signal_new ("removed-decoded-pad", G_TYPE_FROM_CLASS (klass),
204 G_STRUCT_OFFSET (GstDecodeBinClass, removed_decoded_pad), NULL, NULL,
205 gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
206 gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE] =
207 g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
208 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, unknown_type),
209 NULL, NULL, gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2,
210 GST_TYPE_PAD, GST_TYPE_CAPS);
212 gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_decode_bin_dispose);
214 gst_element_class_add_pad_template (gstelement_klass,
215 gst_static_pad_template_get (&decoder_bin_sink_template));
216 gst_element_class_add_pad_template (gstelement_klass,
217 gst_static_pad_template_get (&decoder_bin_src_template));
219 gst_element_class_set_details (gstelement_klass, &gst_decode_bin_details);
221 gstelement_klass->change_state =
222 GST_DEBUG_FUNCPTR (gst_decode_bin_change_state);
225 /* check if the bin is dynamic.
227 * If there are no outstanding dynamic connections, the bin is
228 * considered to be non-dynamic.
231 gst_decode_bin_is_dynamic (GstDecodeBin * decode_bin)
233 return decode_bin->dynamics != NULL;
236 /* the filter function for selecting the elements we can use in
239 gst_decode_bin_factory_filter (GstPluginFeature * feature,
240 GstDecodeBin * decode_bin)
245 /* we only care about element factories */
246 if (!GST_IS_ELEMENT_FACTORY (feature))
249 klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
250 /* only demuxers and decoders can play */
251 if (strstr (klass, "Demux") == NULL &&
252 strstr (klass, "Decoder") == NULL && strstr (klass, "Parse") == NULL) {
256 /* only select elements with autoplugging rank */
257 rank = gst_plugin_feature_get_rank (feature);
258 if (rank < GST_RANK_MARGINAL)
264 /* function used to sort element features */
266 compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
269 const gchar *rname1, *rname2;
271 diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
275 rname1 = gst_plugin_feature_get_name (f1);
276 rname2 = gst_plugin_feature_get_name (f2);
278 diff = strcmp (rname2, rname1);
284 print_feature (GstPluginFeature * feature)
288 rname = gst_plugin_feature_get_name (feature);
290 GST_DEBUG ("%s", rname);
294 gst_decode_bin_init (GstDecodeBin * decode_bin)
298 /* first filter out the interesting element factories */
299 factories = gst_registry_pool_feature_filter (
300 (GstPluginFeatureFilter) gst_decode_bin_factory_filter,
303 /* sort them according to their ranks */
304 decode_bin->factories = g_list_sort (factories, (GCompareFunc) compare_ranks);
305 /* do some debugging */
306 g_list_foreach (decode_bin->factories, (GFunc) print_feature, NULL);
308 /* we create the typefind element only once */
309 decode_bin->typefind = gst_element_factory_make ("typefind", "typefind");
310 if (!decode_bin->typefind) {
311 g_warning ("can't find typefind element, decodebin will not work");
315 /* add the typefind element */
316 if (!gst_bin_add (GST_BIN (decode_bin), decode_bin->typefind)) {
317 g_warning ("Could not add typefind element, decodebin will not work");
318 gst_object_unref (decode_bin->typefind);
319 decode_bin->typefind = NULL;
322 /* get the sinkpad */
323 pad = gst_element_get_pad (decode_bin->typefind, "sink");
325 /* ghost the sink pad to ourself */
326 gst_element_add_pad (GST_ELEMENT (decode_bin),
327 gst_ghost_pad_new ("sink", pad));
329 gst_object_unref (pad);
331 /* connect a signal to find out when the typefind element found
333 decode_bin->have_type_id =
334 g_signal_connect (G_OBJECT (decode_bin->typefind), "have_type",
335 G_CALLBACK (type_found), decode_bin);
338 decode_bin->threaded = DEFAULT_THREADED;
339 decode_bin->dynamics = NULL;
342 static void dynamic_free (GstDynamic * dyn);
345 gst_decode_bin_dispose (GObject * object)
347 GstDecodeBin *decode_bin;
349 decode_bin = GST_DECODE_BIN (object);
351 g_list_free (decode_bin->factories);
353 G_OBJECT_CLASS (parent_class)->dispose (object);
357 dynamic_create (GstElement * element, GstDecodeBin * decode_bin)
362 gst_object_ref (element);
363 gst_object_ref (decode_bin);
365 dyn = g_new0 (GstDynamic, 1);
366 dyn->element = element;
367 dyn->decode_bin = decode_bin;
368 dyn->np_sig_id = g_signal_connect (G_OBJECT (element), "pad-added",
369 G_CALLBACK (new_pad), dyn);
370 dyn->nmp_sig_id = g_signal_connect (G_OBJECT (element), "no-more-pads",
371 G_CALLBACK (no_more_pads), dyn);
377 dynamic_free (GstDynamic * dyn)
379 /* disconnect signals */
380 g_signal_handler_disconnect (G_OBJECT (dyn->element), dyn->np_sig_id);
381 g_signal_handler_disconnect (G_OBJECT (dyn->element), dyn->nmp_sig_id);
383 gst_object_unref (dyn->element);
384 gst_object_unref (dyn->decode_bin);
386 dyn->decode_bin = NULL;
390 /* this function runs through the element factories and returns a list
391 * of all elements that are able to sink the given caps
394 find_compatibles (GstDecodeBin * decode_bin, const GstCaps * caps)
397 GList *to_try = NULL;
399 /* loop over all the factories */
400 for (factories = decode_bin->factories; factories;
401 factories = g_list_next (factories)) {
402 GstElementFactory *factory = GST_ELEMENT_FACTORY (factories->data);
403 const GList *templates;
406 /* get the templates from the element factory */
407 templates = gst_element_factory_get_static_pad_templates (factory);
408 for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
409 GstStaticPadTemplate *templ = walk->data;
411 /* we only care about the sink templates */
412 if (templ->direction == GST_PAD_SINK) {
415 /* try to intersect the caps with the caps of the template */
416 intersect = gst_caps_intersect (caps,
417 gst_static_caps_get (&templ->static_caps));
418 /* check if the intersection is empty */
419 if (!gst_caps_is_empty (intersect)) {
420 /* non empty intersection, we can use this element */
421 to_try = g_list_prepend (to_try, factory);
422 gst_caps_unref (intersect);
425 gst_caps_unref (intersect);
429 to_try = g_list_reverse (to_try);
435 mimetype_is_raw (const gchar * mimetype)
437 return g_str_has_prefix (mimetype, "video/x-raw") ||
438 g_str_has_prefix (mimetype, "audio/x-raw") ||
439 g_str_has_prefix (mimetype, "text/plain");
442 /* given a pad and a caps from an element, find the list of elements
443 * that could connect to the pad
445 * If the pad has a raw format, this function will create a ghostpad
446 * for the pad onto the decodebin.
448 * If no compatible elements could be found, this function will signal
449 * the unknown_type signal.
452 close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps,
453 GstDecodeBin * decode_bin, gboolean more)
455 GstStructure *structure;
456 const gchar *mimetype;
460 padname = gst_pad_get_name (pad);
461 diff = strncmp (padname, "current_", 8);
464 /* hack.. ignore current pads */
468 /* the caps is empty, this means the pad has no type, we can only
469 * decide to fire the unknown_type signal. */
470 if (caps == NULL || gst_caps_is_empty (caps))
473 /* the caps is any, this means the pad can be anything and
474 * we don't know yet */
475 if (gst_caps_is_any (caps))
478 GST_LOG_OBJECT (element, "trying to close %" GST_PTR_FORMAT, caps);
480 /* FIXME, iterate over more structures? I guess it is possible that
481 * this pad has some encoded and some raw pads. This code will fail
482 * then if the first structure is not the raw type... */
483 structure = gst_caps_get_structure (caps, 0);
484 mimetype = gst_structure_get_name (structure);
486 /* first see if this is raw. If the type is raw, we can
487 * create a ghostpad for this pad. */
488 if (mimetype_is_raw (mimetype)) {
492 /* make a unique name for this new pad */
493 padname = g_strdup_printf ("src%d", decode_bin->numpads);
494 decode_bin->numpads++;
496 /* make it a ghostpad */
497 ghost = gst_ghost_pad_new (padname, pad);
498 gst_element_add_pad (GST_ELEMENT (decode_bin), ghost);
500 GST_LOG_OBJECT (element, "closed pad %s", padname);
502 /* our own signal with an extra flag that this is the only pad */
503 g_signal_emit (G_OBJECT (decode_bin),
504 gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD], 0, ghost, !more);
510 /* if the caps has many types, we need to delay */
511 if (gst_caps_get_size (caps) != 1)
514 /* continue plugging, first find all compatible elements */
515 to_try = find_compatibles (decode_bin, caps);
517 /* no compatible elements, we cannot go on */
520 try_to_link_1 (decode_bin, pad, to_try);
521 /* can free the list again now */
522 g_list_free (to_try);
528 GST_LOG_OBJECT (pad, "unkown type found, fire signal");
529 g_signal_emit (G_OBJECT (decode_bin),
530 gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);
535 GST_LOG_OBJECT (pad, "type is not known yet, waiting to close link");
540 GST_LOG_OBJECT (pad, "many possible types, waiting to close link");
546 * given a list of element factories, try to link one of the factories
549 * The function returns the element that was successfully linked to the
553 try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad, GList * factories)
556 GstElement *result = NULL;
558 /* loop over the factories */
559 for (walk = factories; walk; walk = g_list_next (walk)) {
560 GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data);
562 GstPadLinkReturn ret;
565 GST_DEBUG_OBJECT (decode_bin, "trying to link %s",
566 gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
568 /* make an element from the factory first */
569 if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
570 /* hmm, strange. Like with all things in live, let's move on.. */
571 GST_WARNING_OBJECT (decode_bin, "could not create an element from %s",
572 gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
576 /* try to link the given pad to a sinkpad */
577 /* FIXME, find the sinkpad by looping over the pads instead of
578 * looking it up by name */
579 if ((sinkpad = gst_element_get_pad (element, "sink")) == NULL) {
580 /* if no pad is found we can't do anything */
581 GST_WARNING_OBJECT (decode_bin, "could not find sinkpad in element");
585 /* now add the element to the bin first */
586 GST_DEBUG_OBJECT (decode_bin, "adding %s", GST_OBJECT_NAME (element));
587 gst_bin_add (GST_BIN (decode_bin), element);
589 /* set to ready first so it is ready */
590 gst_element_set_state (element, GST_STATE_READY);
592 /* keep our own list of elements */
593 decode_bin->elements = g_list_prepend (decode_bin->elements, element);
595 if ((ret = gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) {
596 GST_DEBUG_OBJECT (decode_bin, "link failed on pad %s:%s, reason %d",
597 GST_DEBUG_PAD_NAME (pad), ret);
598 /* get rid of the sinkpad */
599 gst_object_unref (sinkpad);
600 /* this element did not work, remove it again and continue trying
601 * other elements, the element will be disposed. */
602 gst_bin_remove (GST_BIN (decode_bin), element);
605 GstElementFactory *factory;
608 GST_DEBUG_OBJECT (decode_bin, "linked on pad %s:%s",
609 GST_DEBUG_PAD_NAME (pad));
611 /* The link worked, now figure out what it was that we connected */
612 factory = gst_element_get_factory (element);
613 klass = gst_element_factory_get_klass (factory);
615 /* check if we can use threads */
616 if (decode_bin->threaded) {
617 if (strstr (klass, "Demux") != NULL) {
618 /* FIXME, do something with threads here. Not sure that it
619 * really matters here but in general it is better to preroll
620 * on encoded data from the muxer than on raw encoded streams
621 * because that would consume less memory. */
625 /* make sure we catch unlink signals */
626 sig = g_signal_connect (G_OBJECT (pad), "unlinked",
627 G_CALLBACK (unlinked), decode_bin);
629 /* keep a ref to the signal id so that we can disconnect the signal callback */
630 g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (sig));
632 /* now that we added the element we can try to continue autoplugging
633 * on it until we have a raw type */
634 close_link (element, decode_bin);
635 /* change the state of the element to that of the parent */
636 gst_element_set_state (element, GST_STATE_PAUSED);
640 /* get rid of the sinkpad now */
641 gst_object_unref (sinkpad);
652 get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
657 if (pad == NULL || !GST_PAD_IS_SRC (pad)) {
658 GST_DEBUG_OBJECT (decode_bin, "pad NULL or not SRC pad");
662 if (GST_IS_GHOST_PAD (pad)) {
663 GstElement *parent = gst_pad_get_parent (pad);
665 GST_DEBUG_OBJECT (decode_bin, "pad parent %s", GST_ELEMENT_NAME (parent));
667 if (parent == GST_ELEMENT (decode_bin)) {
668 GST_DEBUG_OBJECT (decode_bin, "pad is our ghostpad");
669 gst_object_unref (parent);
672 GST_DEBUG_OBJECT (decode_bin, "pad is ghostpad but not ours");
673 gst_object_unref (parent);
678 GST_DEBUG_OBJECT (decode_bin, "looping over ghostpads");
679 ghostpads = GST_REAL_PAD (pad)->ghostpads;
683 ghostpad = get_our_ghost_pad (decode_bin, GST_PAD (ghostpads->data));
687 ghostpads = g_list_next (ghostpads);
689 GST_DEBUG_OBJECT (decode_bin, "done looping over ghostpads, nothing found");
695 /* remove all downstream elements starting from the given pad.
696 * Also make sure to remove the ghostpad we created for the raw
700 remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
702 GList *int_links, *walk;
703 GstElement *elem = GST_ELEMENT (GST_OBJECT_PARENT (pad));
705 while (GST_OBJECT_PARENT (elem) &&
706 GST_OBJECT_PARENT (elem) != GST_OBJECT (decode_bin))
707 elem = GST_ELEMENT (GST_OBJECT_PARENT (elem));
709 GST_DEBUG_OBJECT (decode_bin, "%s:%s", GST_DEBUG_PAD_NAME (pad));
710 int_links = gst_pad_get_internal_links (pad);
712 /* remove all elements linked to this pad up to the ghostpad
713 * that we created for this stream */
714 for (walk = int_links; walk; walk = g_list_next (walk)) {
719 pad = GST_PAD (walk->data);
720 GST_DEBUG_OBJECT (decode_bin, "inspecting internal pad %s:%s",
721 GST_DEBUG_PAD_NAME (pad));
723 ghostpad = get_our_ghost_pad (decode_bin, pad);
725 GST_DEBUG_OBJECT (decode_bin, "found our ghost pad %s:%s for %s:%s",
726 GST_DEBUG_PAD_NAME (ghostpad), GST_DEBUG_PAD_NAME (pad));
728 g_signal_emit (G_OBJECT (decode_bin),
729 gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD], 0, ghostpad);
731 gst_element_remove_pad (GST_ELEMENT (decode_bin), ghostpad);
734 GST_DEBUG_OBJECT (decode_bin, "not one of our ghostpads");
737 peer = gst_pad_get_peer (pad);
741 GST_DEBUG_OBJECT (decode_bin, "internal pad %s:%s linked to pad %s:%s",
742 GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer));
745 GstElement *parent = gst_pad_get_parent_element (peer);
748 if (parent != GST_ELEMENT (decode_bin)) {
749 GST_DEBUG_OBJECT (decode_bin, "dead end pad %s:%s",
750 GST_DEBUG_PAD_NAME (peer));
752 GST_DEBUG_OBJECT (decode_bin, "recursing element %s on pad %s:%s",
753 GST_ELEMENT_NAME (elem), GST_DEBUG_PAD_NAME (pad));
754 remove_element_chain (decode_bin, peer);
756 gst_object_unref (parent);
759 gst_object_unref (peer);
761 GST_DEBUG_OBJECT (decode_bin, "removing %s", GST_ELEMENT_NAME (elem));
763 g_list_free (int_links);
765 gst_bin_remove (GST_BIN (decode_bin), elem);
768 /* This function will be called when a dynamic pad is created on an element.
769 * We try to continue autoplugging on this new pad. */
771 new_pad (GstElement * element, GstPad * pad, GstDynamic * dynamic)
773 GstDecodeBin *decode_bin = dynamic->decode_bin;
776 /* see if any more pending dynamic connections exist */
777 gboolean more = gst_decode_bin_is_dynamic (decode_bin);
779 caps = gst_pad_get_caps (pad);
780 close_pad_link (element, pad, caps, decode_bin, more);
782 gst_caps_unref (caps);
785 /* this signal is fired when an element signals the no_more_pads signal.
786 * This means that the element will not generate more dynamic pads and
787 * we can remove the element from the list of dynamic elements. When we
788 * have no more dynamic elements in the pipeline, we can fire a no_more_pads
789 * signal ourselves. */
791 no_more_pads (GstElement * element, GstDynamic * dynamic)
793 GstDecodeBin *decode_bin = dynamic->decode_bin;
795 GST_DEBUG_OBJECT (decode_bin, "no more pads on element %s",
796 GST_ELEMENT_NAME (element));
798 /* remove the element from the list of dynamic elements */
799 decode_bin->dynamics = g_list_remove (decode_bin->dynamics, dynamic);
800 dynamic_free (dynamic);
802 /* if we have no more dynamic elements, we have no chance of creating
803 * more pads, so we fire the no_more_pads signal */
804 if (decode_bin->dynamics == NULL) {
805 GST_DEBUG_OBJECT (decode_bin,
806 "no more dynamic elements, signaling no_more_pads");
807 gst_element_no_more_pads (GST_ELEMENT (decode_bin));
809 GST_DEBUG_OBJECT (decode_bin, "we have more dynamic elements");
814 is_our_kid (GstElement * e, GstDecodeBin * decode_bin)
819 parent = (GstElement *) gst_object_get_parent ((GstObject *) e);
820 ret = (parent == (GstElement *) decode_bin);
823 gst_object_unref ((GstObject *) parent);
828 /* This function will be called when a pad is disconnected for some reason */
830 unlinked (GstPad * pad, GstPad * peerpad, GstDecodeBin * decode_bin)
833 GstElement *element, *peer;
836 gst_pad_set_active (pad, GST_ACTIVATE_NONE);
838 element = gst_pad_get_parent_element (pad);
839 peer = gst_pad_get_parent_element (peerpad);
841 if (!is_our_kid (peer, decode_bin))
844 /* remove all elements linked to the peerpad */
845 remove_element_chain (decode_bin, peerpad);
847 /* if an element removes two pads, then we don't want this twice */
848 if (g_list_find (decode_bin->dynamics, element) != NULL)
851 GST_DEBUG_OBJECT (decode_bin, "pad removal while alive - chained?");
853 dyn = dynamic_create (element, decode_bin);
854 /* and add this element to the dynamic elements */
855 decode_bin->dynamics = g_list_prepend (decode_bin->dynamics, dyn);
858 gst_object_unref (element);
859 gst_object_unref (peer);
862 /* this function inspects the given element and tries to connect something
863 * on the srcpads. If there are dynamic pads, it sets up a signal handler to
864 * continue autoplugging when they become available */
866 close_link (GstElement * element, GstDecodeBin * decode_bin)
869 gboolean dynamic = FALSE;
870 GList *to_connect = NULL;
873 GST_DEBUG_OBJECT (decode_bin, "closing links with element %s",
874 GST_ELEMENT_NAME (element));
876 /* loop over all the padtemplates */
877 for (pads = GST_ELEMENT_GET_CLASS (element)->padtemplates; pads;
878 pads = g_list_next (pads)) {
879 GstPadTemplate *templ = GST_PAD_TEMPLATE (pads->data);
880 const gchar *templ_name;
882 /* we are only interested in source pads */
883 if (GST_PAD_TEMPLATE_DIRECTION (templ) != GST_PAD_SRC)
886 templ_name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);
887 GST_DEBUG_OBJECT (decode_bin, "got a source pad template %s", templ_name);
889 /* figure out what kind of pad this is */
890 switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
893 /* get the pad that we need to autoplug */
894 GstPad *pad = gst_element_get_pad (element, templ_name);
897 GST_DEBUG_OBJECT (decode_bin, "got the pad for always template %s",
899 /* here is the pad, we need to autoplug it */
900 to_connect = g_list_prepend (to_connect, pad);
902 /* strange, pad is marked as always but it's not
903 * there. Fix the element */
904 GST_WARNING_OBJECT (decode_bin,
905 "could not get the pad for always template %s", templ_name);
909 case GST_PAD_SOMETIMES:
911 /* try to get the pad to see if it is already created or
913 GstPad *pad = gst_element_get_pad (element, templ_name);
916 GST_DEBUG_OBJECT (decode_bin, "got the pad for sometimes template %s",
918 /* the pad is created, we need to autoplug it */
919 to_connect = g_list_prepend (to_connect, pad);
921 GST_DEBUG_OBJECT (decode_bin,
922 "did not get the sometimes pad of template %s", templ_name);
923 /* we have an element that will create dynamic pads */
928 case GST_PAD_REQUEST:
929 /* ignore request pads */
930 GST_DEBUG_OBJECT (decode_bin, "ignoring request padtemplate %s",
938 GST_DEBUG_OBJECT (decode_bin, "got a dynamic element here");
939 /* ok, this element has dynamic pads, set up the signal handlers to be
940 * notified of them */
942 dyn = dynamic_create (element, decode_bin);
943 /* and add this element to the dynamic elements */
944 decode_bin->dynamics = g_list_prepend (decode_bin->dynamics, dyn);
947 /* Check if this is an element with more than 1 pad. If this element
948 * has more than 1 pad, we need to be carefull not to signal the
949 * no_more_pads signal after connecting the first pad. */
950 more = g_list_length (to_connect) > 1;
952 /* now loop over all the pads we need to connect */
953 for (pads = to_connect; pads; pads = g_list_next (pads)) {
954 GstPad *pad = GST_PAD_CAST (pads->data);
957 /* we have more pads if we have more than 1 pad to connect or
958 * dynamics. If we have only 1 pad and no dynamics, more will be
959 * set to FALSE and the no-more-pads signal will be fired. Note
960 * that this can change after the close_pad_link call. */
961 more |= gst_decode_bin_is_dynamic (decode_bin);
963 GST_DEBUG_OBJECT (decode_bin, "closing pad link for %s",
964 GST_OBJECT_NAME (pad));
966 /* continue autoplugging on the pads */
967 caps = gst_pad_get_caps (pad);
968 close_pad_link (element, pad, caps, decode_bin, more);
970 gst_caps_unref (caps);
972 gst_object_unref (pad);
974 g_list_free (to_connect);
977 /* this is the signal handler for the typefind element have_type signal.
978 * It tries to continue autoplugging on the typefind src pad */
980 type_found (GstElement * typefind, guint probability, GstCaps * caps,
981 GstDecodeBin * decode_bin)
986 GST_DEBUG_OBJECT (decode_bin, "typefind found caps %" GST_PTR_FORMAT, caps);
988 /* autoplug the new pad with the caps that the signal gave us. */
989 pad = gst_element_get_pad (typefind, "src");
990 close_pad_link (typefind, pad, caps, decode_bin, FALSE);
991 gst_object_unref (pad);
993 dynamic = gst_decode_bin_is_dynamic (decode_bin);
994 if (dynamic == FALSE) {
995 GST_DEBUG_OBJECT (decode_bin, "we have no dynamic elements anymore");
996 /* if we have no dynamic elements, we know that no new pads
997 * will be created and we can signal out no_more_pads signal */
998 gst_element_no_more_pads (GST_ELEMENT (decode_bin));
1000 /* more dynamic elements exist that could create new pads */
1001 GST_DEBUG_OBJECT (decode_bin, "we have more dynamic elements");
1006 gst_decode_bin_set_property (GObject * object, guint prop_id,
1007 const GValue * value, GParamSpec * pspec)
1009 GstDecodeBin *decode_bin;
1011 g_return_if_fail (GST_IS_DECODE_BIN (object));
1013 decode_bin = GST_DECODE_BIN (object);
1017 decode_bin->threaded = g_value_get_boolean (value);
1020 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1026 gst_decode_bin_get_property (GObject * object, guint prop_id, GValue * value,
1029 GstDecodeBin *decode_bin;
1031 g_return_if_fail (GST_IS_DECODE_BIN (object));
1033 decode_bin = GST_DECODE_BIN (object);
1037 g_value_set_boolean (value, decode_bin->threaded);
1040 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1045 static GstStateChangeReturn
1046 gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
1048 GstStateChangeReturn ret;
1049 GstDecodeBin *decode_bin;
1052 decode_bin = GST_DECODE_BIN (element);
1055 switch (transition) {
1056 case GST_STATE_CHANGE_NULL_TO_READY:
1057 decode_bin->numpads = 0;
1058 decode_bin->dynamics = NULL;
1060 case GST_STATE_CHANGE_READY_TO_PAUSED:
1061 case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
1066 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
1068 switch (transition) {
1069 case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
1070 case GST_STATE_CHANGE_PAUSED_TO_READY:
1072 case GST_STATE_CHANGE_READY_TO_NULL:
1073 for (dyns = decode_bin->dynamics; dyns; dyns = g_list_next (dyns)) {
1074 GstDynamic *dynamic = (GstDynamic *) dyns->data;
1076 dynamic_free (dynamic);
1078 g_list_free (decode_bin->dynamics);
1079 decode_bin->dynamics = NULL;
1089 plugin_init (GstPlugin * plugin)
1091 GST_DEBUG_CATEGORY_INIT (gst_decode_bin_debug, "decodebin", 0, "decoder bin");
1093 return gst_element_register (plugin, "decodebin", GST_RANK_NONE,
1094 GST_TYPE_DECODE_BIN);
1097 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
1100 "decoder bin", plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN)