gst_plugins_base/gst/playback/gstdecodebin.c
changeset 0 0e761a78d257
child 8 4a7fac7dd34a
equal deleted inserted replaced
-1:000000000000 0:0e761a78d257
       
     1 /* GStreamer
       
     2  * Copyright (C) <2004> Wim Taymans <wim.taymans@gmail.com>
       
     3  *
       
     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.
       
     8  *
       
     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.
       
    13  *
       
    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.
       
    18  */
       
    19 
       
    20 #ifdef HAVE_CONFIG_H
       
    21 #include "config.h"
       
    22 #endif
       
    23 
       
    24 #include <gst/gst-i18n-plugin.h>
       
    25 
       
    26 #include <string.h>
       
    27 #include <gst/gst.h>
       
    28 #include <gst/pbutils/pbutils.h>
       
    29 #include <glib_global.h>
       
    30 
       
    31 #include "gstplay-marshal.h"
       
    32 
       
    33 /* generic templates */
       
    34 static GstStaticPadTemplate decoder_bin_sink_template =
       
    35 GST_STATIC_PAD_TEMPLATE ("sink",
       
    36     GST_PAD_SINK,
       
    37     GST_PAD_ALWAYS,
       
    38     GST_STATIC_CAPS_ANY);
       
    39 
       
    40 static GstStaticPadTemplate decoder_bin_src_template =
       
    41 GST_STATIC_PAD_TEMPLATE ("src%d",
       
    42     GST_PAD_SRC,
       
    43     GST_PAD_SOMETIMES,
       
    44     GST_STATIC_CAPS_ANY);
       
    45 
       
    46 GST_DEBUG_CATEGORY_STATIC (gst_decode_bin_debug);
       
    47 #define GST_CAT_DEFAULT gst_decode_bin_debug
       
    48 
       
    49 #define GST_TYPE_DECODE_BIN             (gst_decode_bin_get_type())
       
    50 #define GST_DECODE_BIN(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DECODE_BIN,GstDecodeBin))
       
    51 #define GST_DECODE_BIN_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DECODE_BIN,GstDecodeBinClass))
       
    52 #define GST_IS_DECODE_BIN(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DECODE_BIN))
       
    53 #define GST_IS_DECODE_BIN_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DECODE_BIN))
       
    54 
       
    55 typedef struct _GstDecodeBin GstDecodeBin;
       
    56 typedef struct _GstDecodeBinClass GstDecodeBinClass;
       
    57 
       
    58 struct _GstDecodeBin
       
    59 {
       
    60   GstBin bin;                   /* we extend GstBin */
       
    61 
       
    62   GstElement *typefind;         /* this holds the typefind object */
       
    63   GstElement *fakesink;
       
    64 
       
    65   GList *dynamics;              /* list of dynamic connections */
       
    66 
       
    67   GList *queues;                /* list of demuxer-decoder queues */
       
    68 
       
    69   GList *probes;                /* list of PadProbeData */
       
    70 
       
    71   GList *factories;             /* factories we can use for selecting elements */
       
    72   gint numpads;
       
    73   gint numwaiting;
       
    74 
       
    75   gboolean have_type;
       
    76   guint have_type_id;           /* signal id for the typefind element */
       
    77 
       
    78   gboolean shutting_down;       /* stop pluggin if we're shutting down */
       
    79 
       
    80   GType queue_type;             /* store the GType of queues, to aid in recognising them */
       
    81 
       
    82   GMutex *cb_mutex;             /* Mutex for multi-threaded callbacks, such as removing the fakesink */
       
    83 };
       
    84 
       
    85 struct _GstDecodeBinClass
       
    86 {
       
    87   GstBinClass parent_class;
       
    88 
       
    89   /* signal we fire when a new pad has been decoded into raw audio/video */
       
    90   void (*new_decoded_pad) (GstElement * element, GstPad * pad, gboolean last);
       
    91   /* signal we fire when a pad has been removed */
       
    92   void (*removed_decoded_pad) (GstElement * element, GstPad * pad);
       
    93   /* signal fired when we found a pad that we cannot decode */
       
    94   void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps);
       
    95 };
       
    96 
       
    97 /* signals */
       
    98 enum
       
    99 {
       
   100   SIGNAL_NEW_DECODED_PAD,
       
   101   SIGNAL_REMOVED_DECODED_PAD,
       
   102   SIGNAL_UNKNOWN_TYPE,
       
   103   SIGNAL_REDIRECT,
       
   104   LAST_SIGNAL
       
   105 };
       
   106 
       
   107 
       
   108 typedef struct
       
   109 {
       
   110   GstPad *pad;
       
   111   gulong sigid;
       
   112   gboolean done;
       
   113 } PadProbeData;
       
   114 
       
   115 /* this structure is created for all dynamic pads that could get created
       
   116  * at runtime */
       
   117 typedef struct
       
   118 {
       
   119   GstDecodeBin *decode_bin;     /* pointer to ourself */
       
   120 
       
   121   GstElement *element;          /* the element sending the signal */
       
   122   gint np_sig_id;               /* signal id of new_pad */
       
   123   gint nmp_sig_id;              /* signal id of no_more_pads */
       
   124 
       
   125   GstPad *pad;                  /* the pad sending the signal */
       
   126   gint caps_sig_id;             /* signal id of caps */
       
   127 }
       
   128 GstDynamic;
       
   129 
       
   130 static void gst_decode_bin_class_init (GstDecodeBinClass * klass);
       
   131 static void gst_decode_bin_init (GstDecodeBin * decode_bin);
       
   132 static void gst_decode_bin_dispose (GObject * object);
       
   133 static void gst_decode_bin_finalize (GObject * object);
       
   134 
       
   135 static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
       
   136     GstStateChange transition);
       
   137 
       
   138 static gboolean add_fakesink (GstDecodeBin * decode_bin);
       
   139 static void remove_fakesink (GstDecodeBin * decode_bin);
       
   140 
       
   141 static void dynamic_free (GstDynamic * dyn);
       
   142 static void free_dynamics (GstDecodeBin * decode_bin);
       
   143 static void type_found (GstElement * typefind, guint probability,
       
   144     GstCaps * caps, GstDecodeBin * decode_bin);
       
   145 static GstElement *try_to_link_1 (GstDecodeBin * decode_bin,
       
   146     GstElement * origelement, GstPad * pad, GList * factories);
       
   147 static void close_link (GstElement * element, GstDecodeBin * decode_bin);
       
   148 static void close_pad_link (GstElement * element, GstPad * pad,
       
   149     GstCaps * caps, GstDecodeBin * decode_bin, gboolean more);
       
   150 static void unlinked (GstPad * pad, GstPad * peerpad,
       
   151     GstDecodeBin * decode_bin);
       
   152 static void new_pad (GstElement * element, GstPad * pad, GstDynamic * dynamic);
       
   153 static void no_more_pads (GstElement * element, GstDynamic * dynamic);
       
   154 static void new_caps (GstPad * pad, GParamSpec * unused, GstDynamic * dynamic);
       
   155 
       
   156 static void queue_filled_cb (GstElement * queue, GstDecodeBin * decode_bin);
       
   157 static void queue_underrun_cb (GstElement * queue, GstDecodeBin * decode_bin);
       
   158 
       
   159 static GstElementClass *parent_class;
       
   160 static guint gst_decode_bin_signals[LAST_SIGNAL] = { 0 };
       
   161 
       
   162 static const GstElementDetails gst_decode_bin_details =
       
   163 GST_ELEMENT_DETAILS ("Decoder Bin",
       
   164     "Generic/Bin/Decoder",
       
   165     "Autoplug and decode to raw media",
       
   166     "Wim Taymans <wim.taymans@gmail.com>");
       
   167 
       
   168 
       
   169 static GType
       
   170 gst_decode_bin_get_type (void)
       
   171 {
       
   172   static GType gst_decode_bin_type = 0;
       
   173 
       
   174   if (!gst_decode_bin_type) {
       
   175     static const GTypeInfo gst_decode_bin_info = {
       
   176       sizeof (GstDecodeBinClass),
       
   177       NULL,
       
   178       NULL,
       
   179       (GClassInitFunc) gst_decode_bin_class_init,
       
   180       NULL,
       
   181       NULL,
       
   182       sizeof (GstDecodeBin),
       
   183       0,
       
   184       (GInstanceInitFunc) gst_decode_bin_init,
       
   185       NULL
       
   186     };
       
   187 
       
   188     gst_decode_bin_type =
       
   189         g_type_register_static (GST_TYPE_BIN, "GstDecodeBin",
       
   190         &gst_decode_bin_info, 0);
       
   191   }
       
   192 
       
   193   return gst_decode_bin_type;
       
   194 }
       
   195 
       
   196 static void
       
   197 gst_decode_bin_class_init (GstDecodeBinClass * klass)
       
   198 {
       
   199   GObjectClass *gobject_klass;
       
   200   GstElementClass *gstelement_klass;
       
   201   GstBinClass *gstbin_klass;
       
   202 
       
   203   gobject_klass = (GObjectClass *) klass;
       
   204   gstelement_klass = (GstElementClass *) klass;
       
   205   gstbin_klass = (GstBinClass *) klass;
       
   206 
       
   207   parent_class = g_type_class_peek_parent (klass);
       
   208 
       
   209   gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD] =
       
   210       g_signal_new ("new-decoded-pad", G_TYPE_FROM_CLASS (klass),
       
   211       G_SIGNAL_RUN_LAST,
       
   212       G_STRUCT_OFFSET (GstDecodeBinClass, new_decoded_pad), NULL, NULL,
       
   213       gst_play_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2, GST_TYPE_PAD,
       
   214       G_TYPE_BOOLEAN);
       
   215   gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD] =
       
   216       g_signal_new ("removed-decoded-pad", G_TYPE_FROM_CLASS (klass),
       
   217       G_SIGNAL_RUN_LAST,
       
   218       G_STRUCT_OFFSET (GstDecodeBinClass, removed_decoded_pad), NULL, NULL,
       
   219       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
       
   220   gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE] =
       
   221       g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
       
   222       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, unknown_type),
       
   223       NULL, NULL, gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2,
       
   224       GST_TYPE_PAD, GST_TYPE_CAPS);
       
   225 
       
   226   gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_decode_bin_dispose);
       
   227   gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_decode_bin_finalize);
       
   228 
       
   229   gst_element_class_add_pad_template (gstelement_klass,
       
   230       gst_static_pad_template_get (&decoder_bin_sink_template));
       
   231   gst_element_class_add_pad_template (gstelement_klass,
       
   232       gst_static_pad_template_get (&decoder_bin_src_template));
       
   233 
       
   234   gst_element_class_set_details (gstelement_klass, &gst_decode_bin_details);
       
   235 
       
   236   gstelement_klass->change_state =
       
   237       GST_DEBUG_FUNCPTR (gst_decode_bin_change_state);
       
   238 }
       
   239 
       
   240 /* check if the bin is dynamic.
       
   241  *
       
   242  * If there are no outstanding dynamic connections, the bin is
       
   243  * considered to be non-dynamic.
       
   244  */
       
   245 static gboolean
       
   246 gst_decode_bin_is_dynamic (GstDecodeBin * decode_bin)
       
   247 {
       
   248   return decode_bin->dynamics != NULL;
       
   249 }
       
   250 
       
   251 /* the filter function for selecting the elements we can use in
       
   252  * autoplugging */
       
   253 static gboolean
       
   254 gst_decode_bin_factory_filter (GstPluginFeature * feature,
       
   255     GstDecodeBin * decode_bin)
       
   256 {
       
   257   guint rank;
       
   258   const gchar *klass;
       
   259 
       
   260   /* we only care about element factories */
       
   261   if (!GST_IS_ELEMENT_FACTORY (feature))
       
   262     return FALSE;
       
   263 
       
   264   klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
       
   265   /* only demuxers, decoders and parsers can play */
       
   266   if (strstr (klass, "Demux") == NULL &&
       
   267       strstr (klass, "Decoder") == NULL && strstr (klass, "Parse") == NULL &&
       
   268       strstr (klass, "Depayloader") == NULL) {
       
   269     return FALSE;
       
   270   }
       
   271 
       
   272   /* only select elements with autoplugging rank */
       
   273   rank = gst_plugin_feature_get_rank (feature);
       
   274   if (rank < GST_RANK_MARGINAL)
       
   275     return FALSE;
       
   276 
       
   277   return TRUE;
       
   278 }
       
   279 
       
   280 /* function used to sort element features */
       
   281 static gint
       
   282 compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
       
   283 {
       
   284   gint diff;
       
   285   const gchar *rname1, *rname2;
       
   286 
       
   287   diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
       
   288   if (diff != 0)
       
   289     return diff;
       
   290 
       
   291   rname1 = gst_plugin_feature_get_name (f1);
       
   292   rname2 = gst_plugin_feature_get_name (f2);
       
   293 
       
   294   diff = strcmp (rname2, rname1);
       
   295 
       
   296   return diff;
       
   297 }
       
   298 
       
   299 static void
       
   300 print_feature (GstPluginFeature * feature)
       
   301 {
       
   302   const gchar *rname;
       
   303 
       
   304   rname = gst_plugin_feature_get_name (feature);
       
   305 
       
   306   GST_DEBUG ("%s", rname);
       
   307 }
       
   308 
       
   309 static void
       
   310 gst_decode_bin_init (GstDecodeBin * decode_bin)
       
   311 {
       
   312   GList *factories;
       
   313 
       
   314   decode_bin->cb_mutex = g_mutex_new ();
       
   315 
       
   316   /* first filter out the interesting element factories */
       
   317   factories = gst_default_registry_feature_filter (
       
   318       (GstPluginFeatureFilter) gst_decode_bin_factory_filter,
       
   319       FALSE, decode_bin);
       
   320 
       
   321   /* sort them according to their ranks */
       
   322   decode_bin->factories = g_list_sort (factories, (GCompareFunc) compare_ranks);
       
   323   /* do some debugging */
       
   324   g_list_foreach (decode_bin->factories, (GFunc) print_feature, NULL);
       
   325 
       
   326   /* we create the typefind element only once */
       
   327   decode_bin->typefind = gst_element_factory_make ("typefind", "typefind");
       
   328   if (!decode_bin->typefind) {
       
   329     g_warning ("can't find typefind element, decodebin will not work");
       
   330   } else {
       
   331     GstPad *pad, *gpad;
       
   332 
       
   333     /* add the typefind element */
       
   334     if (!gst_bin_add (GST_BIN (decode_bin), decode_bin->typefind)) {
       
   335       g_warning ("Could not add typefind element, decodebin will not work");
       
   336       gst_object_unref (decode_bin->typefind);
       
   337       decode_bin->typefind = NULL;
       
   338     }
       
   339 
       
   340     /* get the sinkpad */
       
   341     pad = gst_element_get_pad (decode_bin->typefind, "sink");
       
   342 
       
   343     /* ghost the sink pad to ourself */
       
   344     gpad = gst_ghost_pad_new ("sink", pad);
       
   345     gst_pad_set_active (gpad, TRUE);
       
   346     gst_element_add_pad (GST_ELEMENT (decode_bin), gpad);
       
   347 
       
   348     gst_object_unref (pad);
       
   349 
       
   350     /* connect a signal to find out when the typefind element found
       
   351      * a type */
       
   352     decode_bin->have_type_id =
       
   353         g_signal_connect (G_OBJECT (decode_bin->typefind), "have_type",
       
   354         G_CALLBACK (type_found), decode_bin);
       
   355   }
       
   356   add_fakesink (decode_bin);
       
   357 
       
   358   decode_bin->dynamics = NULL;
       
   359   decode_bin->queues = NULL;
       
   360   decode_bin->probes = NULL;
       
   361 }
       
   362 
       
   363 static void
       
   364 gst_decode_bin_dispose (GObject * object)
       
   365 {
       
   366   GstDecodeBin *decode_bin;
       
   367 
       
   368   decode_bin = GST_DECODE_BIN (object);
       
   369 
       
   370   if (decode_bin->factories)
       
   371     gst_plugin_feature_list_free (decode_bin->factories);
       
   372   decode_bin->factories = NULL;
       
   373 
       
   374   G_OBJECT_CLASS (parent_class)->dispose (object);
       
   375 
       
   376   /* our parent dispose might trigger new signals when pads are unlinked
       
   377    * etc. clean up the mess here. */
       
   378   /* FIXME do proper cleanup when going to NULL */
       
   379   free_dynamics (decode_bin);
       
   380 }
       
   381 
       
   382 static void
       
   383 gst_decode_bin_finalize (GObject * object)
       
   384 {
       
   385   GstDecodeBin *decode_bin = GST_DECODE_BIN (object);
       
   386 
       
   387   g_mutex_free (decode_bin->cb_mutex);
       
   388 
       
   389   G_OBJECT_CLASS (parent_class)->finalize (object);
       
   390 }
       
   391 
       
   392 struct DynFind
       
   393 {
       
   394   GstElement *elem;
       
   395   GstPad *pad;
       
   396 };
       
   397 
       
   398 static gint
       
   399 find_dynamic (GstDynamic * dyn, struct DynFind *info)
       
   400 {
       
   401   if (dyn->element == info->elem && dyn->pad == info->pad)
       
   402     return 0;
       
   403   return 1;
       
   404 }
       
   405 
       
   406 /* Add either an element (for dynamic pads/pad-added watching) or a
       
   407  * pad (for delayed caps/notify::caps watching) to the dynamic list,
       
   408  * taking care to ignore repeat entries so we don't end up handling a
       
   409  * pad twice, for example */
       
   410 static void
       
   411 dynamic_add (GstElement * element, GstPad * pad, GstDecodeBin * decode_bin)
       
   412 {
       
   413   GstDynamic *dyn;
       
   414   struct DynFind find_info;
       
   415   GList *found;
       
   416 
       
   417   g_return_if_fail (element != NULL);
       
   418 
       
   419   /* do a search that this entry doesn't already exist */
       
   420   find_info.elem = element;
       
   421   find_info.pad = pad;
       
   422   found = g_list_find_custom (decode_bin->dynamics, &find_info,
       
   423       (GCompareFunc) find_dynamic);
       
   424   if (found != NULL)
       
   425     goto exit;
       
   426 
       
   427   /* take refs */
       
   428   dyn = g_new0 (GstDynamic, 1);
       
   429   dyn->element = gst_object_ref (element);
       
   430   dyn->decode_bin = gst_object_ref (decode_bin);
       
   431   if (pad) {
       
   432     dyn->pad = gst_object_ref (pad);
       
   433     GST_DEBUG_OBJECT (decode_bin, "dynamic create for pad %" GST_PTR_FORMAT,
       
   434         pad);
       
   435     dyn->caps_sig_id = g_signal_connect (G_OBJECT (pad), "notify::caps",
       
   436         G_CALLBACK (new_caps), dyn);
       
   437   } else {
       
   438     GST_DEBUG_OBJECT (decode_bin, "dynamic create for element %"
       
   439         GST_PTR_FORMAT, element);
       
   440     dyn->np_sig_id = g_signal_connect (G_OBJECT (element), "pad-added",
       
   441         G_CALLBACK (new_pad), dyn);
       
   442     dyn->nmp_sig_id = g_signal_connect (G_OBJECT (element), "no-more-pads",
       
   443         G_CALLBACK (no_more_pads), dyn);
       
   444   }
       
   445 
       
   446   /* and add this element to the dynamic elements */
       
   447   decode_bin->dynamics = g_list_prepend (decode_bin->dynamics, dyn);
       
   448 
       
   449   return;
       
   450 exit:
       
   451   if (element) {
       
   452     GST_DEBUG_OBJECT (decode_bin, "Dynamic element already added: %"
       
   453         GST_PTR_FORMAT, element);
       
   454   } else {
       
   455     GST_DEBUG_OBJECT (decode_bin, "Dynamic pad already added: %"
       
   456         GST_PTR_FORMAT, pad);
       
   457   }
       
   458 }
       
   459 
       
   460 static void
       
   461 dynamic_free (GstDynamic * dyn)
       
   462 {
       
   463   GST_DEBUG_OBJECT (dyn->decode_bin, "dynamic free");
       
   464 
       
   465   /* disconnect signals */
       
   466   if (dyn->np_sig_id)
       
   467     g_signal_handler_disconnect (G_OBJECT (dyn->element), dyn->np_sig_id);
       
   468   if (dyn->nmp_sig_id)
       
   469     g_signal_handler_disconnect (G_OBJECT (dyn->element), dyn->nmp_sig_id);
       
   470   if (dyn->caps_sig_id)
       
   471     g_signal_handler_disconnect (G_OBJECT (dyn->pad), dyn->caps_sig_id);
       
   472 
       
   473   if (dyn->pad)
       
   474     gst_object_unref (dyn->pad);
       
   475   dyn->pad = NULL;
       
   476   if (dyn->element)
       
   477     gst_object_unref (dyn->element);
       
   478   dyn->element = NULL;
       
   479 
       
   480   gst_object_unref (dyn->decode_bin);
       
   481   dyn->decode_bin = NULL;
       
   482 
       
   483   g_free (dyn);
       
   484 }
       
   485 
       
   486 static void
       
   487 free_dynamics (GstDecodeBin * decode_bin)
       
   488 {
       
   489   GList *dyns;
       
   490 
       
   491   for (dyns = decode_bin->dynamics; dyns; dyns = g_list_next (dyns)) {
       
   492     GstDynamic *dynamic = (GstDynamic *) dyns->data;
       
   493 
       
   494     dynamic_free (dynamic);
       
   495   }
       
   496   g_list_free (decode_bin->dynamics);
       
   497   decode_bin->dynamics = NULL;
       
   498 }
       
   499 
       
   500 /* this function runs through the element factories and returns a list
       
   501  * of all elements that are able to sink the given caps
       
   502  */
       
   503 static GList *
       
   504 find_compatibles (GstDecodeBin * decode_bin, const GstCaps * caps)
       
   505 {
       
   506   GList *factories;
       
   507   GList *to_try = NULL;
       
   508 
       
   509   /* loop over all the factories */
       
   510   for (factories = decode_bin->factories; factories;
       
   511       factories = g_list_next (factories)) {
       
   512     GstElementFactory *factory = GST_ELEMENT_FACTORY (factories->data);
       
   513     const GList *templates;
       
   514     GList *walk;
       
   515 
       
   516     /* get the templates from the element factory */
       
   517     templates = gst_element_factory_get_static_pad_templates (factory);
       
   518     for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
       
   519       GstStaticPadTemplate *templ = walk->data;
       
   520 
       
   521       /* we only care about the sink templates */
       
   522       if (templ->direction == GST_PAD_SINK) {
       
   523         GstCaps *intersect;
       
   524         GstCaps *tmpl_caps;
       
   525 
       
   526         /* try to intersect the caps with the caps of the template */
       
   527         tmpl_caps = gst_static_caps_get (&templ->static_caps);
       
   528 
       
   529         intersect = gst_caps_intersect (caps, tmpl_caps);
       
   530         gst_caps_unref (tmpl_caps);
       
   531 
       
   532         /* check if the intersection is empty */
       
   533         if (!gst_caps_is_empty (intersect)) {
       
   534           /* non empty intersection, we can use this element */
       
   535           to_try = g_list_prepend (to_try, factory);
       
   536           gst_caps_unref (intersect);
       
   537           break;
       
   538         }
       
   539         gst_caps_unref (intersect);
       
   540       }
       
   541     }
       
   542   }
       
   543   to_try = g_list_reverse (to_try);
       
   544 
       
   545   return to_try;
       
   546 }
       
   547 
       
   548 static gboolean
       
   549 mimetype_is_raw (const gchar * mimetype)
       
   550 {
       
   551   return g_str_has_prefix (mimetype, "video/x-raw") ||
       
   552       g_str_has_prefix (mimetype, "audio/x-raw") ||
       
   553       g_str_has_prefix (mimetype, "text/plain") ||
       
   554       g_str_has_prefix (mimetype, "text/x-pango-markup");
       
   555 }
       
   556 
       
   557 static void
       
   558 free_pad_probes (GstDecodeBin * decode_bin)
       
   559 {
       
   560   GList *tmp;
       
   561 
       
   562   /* Remove pad probes */
       
   563   for (tmp = decode_bin->probes; tmp; tmp = g_list_next (tmp)) {
       
   564     PadProbeData *data = (PadProbeData *) tmp->data;
       
   565 
       
   566     gst_pad_remove_data_probe (data->pad, data->sigid);
       
   567     g_free (data);
       
   568   }
       
   569   g_list_free (decode_bin->probes);
       
   570   decode_bin->probes = NULL;
       
   571 }
       
   572 
       
   573 static gboolean
       
   574 add_fakesink (GstDecodeBin * decode_bin)
       
   575 {
       
   576   if (decode_bin->fakesink != NULL)
       
   577     return TRUE;
       
   578 
       
   579   g_mutex_lock (decode_bin->cb_mutex);
       
   580 
       
   581   decode_bin->fakesink = gst_element_factory_make ("fakesink", "fakesink");
       
   582   if (!decode_bin->fakesink)
       
   583     goto no_fakesink;
       
   584 
       
   585   /* hacky, remove sink flag, we don't want our decodebin to become a sink
       
   586    * just because we add a fakesink element to make us ASYNC */
       
   587   GST_OBJECT_FLAG_UNSET (decode_bin->fakesink, GST_ELEMENT_IS_SINK);
       
   588 
       
   589   /* takes ownership */
       
   590   if (!gst_bin_add (GST_BIN (decode_bin), decode_bin->fakesink)) {
       
   591     g_warning ("Could not add fakesink element, decodebin will not work");
       
   592     gst_object_unref (decode_bin->fakesink);
       
   593     decode_bin->fakesink = NULL;
       
   594   }
       
   595   g_mutex_unlock (decode_bin->cb_mutex);
       
   596   return TRUE;
       
   597 
       
   598   /* ERRORS */
       
   599 no_fakesink:
       
   600   {
       
   601     g_warning ("can't find fakesink element, decodebin will not work");
       
   602     g_mutex_unlock (decode_bin->cb_mutex);
       
   603     return FALSE;
       
   604   }
       
   605 }
       
   606 
       
   607 static void
       
   608 remove_fakesink (GstDecodeBin * decode_bin)
       
   609 {
       
   610   gboolean removed_fakesink = FALSE;
       
   611 
       
   612   if (decode_bin->fakesink == NULL)
       
   613     return;
       
   614 
       
   615   g_mutex_lock (decode_bin->cb_mutex);
       
   616   if (decode_bin->fakesink) {
       
   617     GST_DEBUG_OBJECT (decode_bin, "Removing fakesink and marking state dirty");
       
   618 
       
   619     /* setting the state to NULL is never async */
       
   620     gst_element_set_state (decode_bin->fakesink, GST_STATE_NULL);
       
   621     gst_bin_remove (GST_BIN (decode_bin), decode_bin->fakesink);
       
   622     decode_bin->fakesink = NULL;
       
   623 
       
   624     removed_fakesink = TRUE;
       
   625   }
       
   626   g_mutex_unlock (decode_bin->cb_mutex);
       
   627 
       
   628   if (removed_fakesink) {
       
   629     free_pad_probes (decode_bin);
       
   630   }
       
   631 }
       
   632 
       
   633 /* this should be implemented with _pad_block() */
       
   634 static gboolean
       
   635 pad_probe (GstPad * pad, GstMiniObject * data, GstDecodeBin * decode_bin)
       
   636 {
       
   637   GList *tmp;
       
   638   gboolean alldone = TRUE;
       
   639 
       
   640   for (tmp = decode_bin->probes; tmp; tmp = g_list_next (tmp)) {
       
   641     PadProbeData *pdata = (PadProbeData *) tmp->data;
       
   642 
       
   643     if (pdata->pad == pad) {
       
   644       if (GST_IS_BUFFER (data)) {
       
   645         if (!pdata->done)
       
   646           decode_bin->numwaiting--;
       
   647         pdata->done = TRUE;
       
   648       } else if (GST_IS_EVENT (data) &&
       
   649           ((GST_EVENT_TYPE (data) == GST_EVENT_EOS) ||
       
   650               (GST_EVENT_TYPE (data) == GST_EVENT_TAG) ||
       
   651               (GST_EVENT_TYPE (data) == GST_EVENT_FLUSH_START))) {
       
   652         /* FIXME, what about NEWSEGMENT? really, use _pad_block()... */
       
   653         if (!pdata->done)
       
   654           decode_bin->numwaiting--;
       
   655         pdata->done = TRUE;
       
   656       }
       
   657     }
       
   658 
       
   659     if (!(pdata->done)) {
       
   660       GST_LOG_OBJECT (decode_bin, "Pad probe on pad %" GST_PTR_FORMAT
       
   661           " but pad %" GST_PTR_FORMAT " still needs data.", pad, pdata->pad);
       
   662       alldone = FALSE;
       
   663     }
       
   664   }
       
   665   if (alldone)
       
   666     remove_fakesink (decode_bin);
       
   667   return TRUE;
       
   668 }
       
   669 
       
   670 /* given a pad and a caps from an element, find the list of elements
       
   671  * that could connect to the pad
       
   672  *
       
   673  * If the pad has a raw format, this function will create a ghostpad
       
   674  * for the pad onto the decodebin.
       
   675  *
       
   676  * If no compatible elements could be found, this function will signal
       
   677  * the unknown_type signal.
       
   678  */
       
   679 static void
       
   680 close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps,
       
   681     GstDecodeBin * decode_bin, gboolean more)
       
   682 {
       
   683   GstStructure *structure;
       
   684   const gchar *mimetype;
       
   685   gchar *padname;
       
   686   gint diff;
       
   687 
       
   688   padname = gst_pad_get_name (pad);
       
   689   diff = strncmp (padname, "current_", 8);
       
   690   g_free (padname);
       
   691 
       
   692   /* hack.. ignore current pads */
       
   693   if (!diff)
       
   694     return;
       
   695 
       
   696   /* the caps is empty, this means the pad has no type, we can only
       
   697    * decide to fire the unknown_type signal. */
       
   698   if (caps == NULL || gst_caps_is_empty (caps))
       
   699     goto unknown_type;
       
   700 
       
   701   /* the caps is any, this means the pad can be anything and
       
   702    * we don't know yet */
       
   703   if (gst_caps_is_any (caps))
       
   704     goto dont_know_yet;
       
   705 
       
   706   GST_LOG_OBJECT (element, "trying to close %" GST_PTR_FORMAT, caps);
       
   707 
       
   708   /* FIXME, iterate over more structures? I guess it is possible that
       
   709    * this pad has some encoded and some raw pads. This code will fail
       
   710    * then if the first structure is not the raw type... */
       
   711   structure = gst_caps_get_structure (caps, 0);
       
   712   mimetype = gst_structure_get_name (structure);
       
   713 
       
   714   /* first see if this is raw. If the type is raw, we can
       
   715    * create a ghostpad for this pad. It's possible that the caps are not
       
   716    * fixed. */
       
   717   if (mimetype_is_raw (mimetype)) {
       
   718     gchar *padname;
       
   719     GstPad *ghost;
       
   720     PadProbeData *data;
       
   721 
       
   722     /* make a unique name for this new pad */
       
   723     padname = g_strdup_printf ("src%d", decode_bin->numpads);
       
   724     decode_bin->numpads++;
       
   725 
       
   726     /* make it a ghostpad */
       
   727     ghost = gst_ghost_pad_new (padname, pad);
       
   728     gst_pad_set_active (ghost, TRUE);
       
   729     gst_element_add_pad (GST_ELEMENT (decode_bin), ghost);
       
   730 
       
   731     data = g_new0 (PadProbeData, 1);
       
   732     data->pad = pad;
       
   733     data->done = FALSE;
       
   734 
       
   735     /* FIXME, use _pad_block() */
       
   736     data->sigid = gst_pad_add_data_probe (pad, G_CALLBACK (pad_probe),
       
   737         decode_bin);
       
   738     decode_bin->numwaiting++;
       
   739 
       
   740     decode_bin->probes = g_list_append (decode_bin->probes, data);
       
   741 
       
   742     GST_LOG_OBJECT (element, "closed pad %s", padname);
       
   743 
       
   744     /* our own signal with an extra flag that this is the only pad */
       
   745     GST_DEBUG_OBJECT (decode_bin, "emitting new-decoded-pad");
       
   746     g_signal_emit (G_OBJECT (decode_bin),
       
   747         gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD], 0, ghost, !more);
       
   748     GST_DEBUG_OBJECT (decode_bin, "emitted new-decoded-pad");
       
   749 
       
   750     g_free (padname);
       
   751   } else {
       
   752     GList *to_try;
       
   753 
       
   754     /* if the caps has many types, we need to delay */
       
   755     if (!gst_caps_is_fixed (caps))
       
   756       goto many_types;
       
   757 
       
   758     /* continue plugging, first find all compatible elements */
       
   759     to_try = find_compatibles (decode_bin, caps);
       
   760     if (to_try == NULL)
       
   761       /* no compatible elements, we cannot go on */
       
   762       goto unknown_type;
       
   763 
       
   764     if (try_to_link_1 (decode_bin, element, pad, to_try) == NULL) {
       
   765       g_list_free (to_try);
       
   766       GST_LOG_OBJECT (pad, "none of the allegedly available elements usable");
       
   767       goto unknown_type;
       
   768     }
       
   769 
       
   770     /* can free the list again now */
       
   771     g_list_free (to_try);
       
   772   }
       
   773   return;
       
   774 
       
   775   /* ERRORS */
       
   776 unknown_type:
       
   777   {
       
   778     GST_LOG_OBJECT (pad, "unknown type found, fire signal");
       
   779     g_signal_emit (G_OBJECT (decode_bin),
       
   780         gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);
       
   781 
       
   782     gst_element_post_message (GST_ELEMENT_CAST (decode_bin),
       
   783         gst_missing_decoder_message_new (GST_ELEMENT_CAST (decode_bin), caps));
       
   784 
       
   785     if (element == decode_bin->typefind) {
       
   786       gchar *desc;
       
   787 
       
   788       desc = gst_pb_utils_get_decoder_description (caps);
       
   789       GST_ELEMENT_ERROR (decode_bin, STREAM, CODEC_NOT_FOUND,
       
   790           (_("A %s plugin is required to play this stream, but not installed."),
       
   791               desc),
       
   792           ("No decoder to handle media type '%s'",
       
   793               gst_structure_get_name (gst_caps_get_structure (caps, 0))));
       
   794       g_free (desc);
       
   795     }
       
   796 
       
   797     return;
       
   798   }
       
   799 dont_know_yet:
       
   800   {
       
   801     GST_LOG_OBJECT (pad, "type is not known yet");
       
   802     goto setup_caps_delay;
       
   803   }
       
   804 many_types:
       
   805   {
       
   806     GST_LOG_OBJECT (pad, "many possible types");
       
   807     goto setup_caps_delay;
       
   808   }
       
   809 setup_caps_delay:
       
   810   {
       
   811     GST_LOG_OBJECT (pad, "setting up a delayed link");
       
   812     dynamic_add (element, pad, decode_bin);
       
   813     return;
       
   814   }
       
   815 }
       
   816 
       
   817 /* Decide whether an element is a demuxer based on the
       
   818  * klass and number/type of src pad templates it has */
       
   819 static gboolean
       
   820 is_demuxer_element (GstElement * srcelement)
       
   821 {
       
   822   GstElementFactory *srcfactory;
       
   823   GstElementClass *elemclass;
       
   824   GList *walk;
       
   825   const gchar *klass;
       
   826   gint potential_src_pads = 0;
       
   827 
       
   828   srcfactory = gst_element_get_factory (srcelement);
       
   829   klass = gst_element_factory_get_klass (srcfactory);
       
   830 
       
   831   /* Can't be a demuxer unless it has Demux in the klass name */
       
   832   if (klass == NULL || !strstr (klass, "Demux"))
       
   833     return FALSE;
       
   834 
       
   835   /* Walk the src pad templates and count how many the element
       
   836    * might produce */
       
   837   elemclass = GST_ELEMENT_GET_CLASS (srcelement);
       
   838 
       
   839   walk = gst_element_class_get_pad_template_list (elemclass);
       
   840   while (walk != NULL) {
       
   841     GstPadTemplate *templ;
       
   842 
       
   843     templ = (GstPadTemplate *) walk->data;
       
   844     if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) {
       
   845       switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
       
   846         case GST_PAD_ALWAYS:
       
   847         case GST_PAD_SOMETIMES:
       
   848           if (strstr (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "%"))
       
   849             potential_src_pads += 2;    /* Might make multiple pads */
       
   850           else
       
   851             potential_src_pads += 1;
       
   852           break;
       
   853         case GST_PAD_REQUEST:
       
   854           potential_src_pads += 2;
       
   855           break;
       
   856       }
       
   857     }
       
   858     walk = g_list_next (walk);
       
   859   }
       
   860 
       
   861   if (potential_src_pads < 2)
       
   862     return FALSE;
       
   863 
       
   864   return TRUE;
       
   865 }
       
   866 
       
   867 /*
       
   868  * given a list of element factories, try to link one of the factories
       
   869  * to the given pad.
       
   870  *
       
   871  * The function returns the element that was successfully linked to the
       
   872  * pad.
       
   873  */
       
   874 static GstElement *
       
   875 try_to_link_1 (GstDecodeBin * decode_bin, GstElement * srcelement, GstPad * pad,
       
   876     GList * factories)
       
   877 {
       
   878   GList *walk;
       
   879   GstElement *result = NULL;
       
   880   gboolean isdemux = FALSE;
       
   881   GstPad *queuesinkpad = NULL, *queuesrcpad = NULL;
       
   882   GstElement *queue = NULL;
       
   883   GstPad *usedsrcpad = pad;
       
   884 
       
   885   /* Check if the parent of the src pad is a demuxer */
       
   886   isdemux = is_demuxer_element (srcelement);
       
   887 
       
   888   if (isdemux && factories != NULL) {
       
   889     GstPadLinkReturn dqlink;
       
   890 
       
   891     /* Insert a queue between demuxer and decoder */
       
   892     GST_DEBUG_OBJECT (decode_bin,
       
   893         "Element %s is a demuxer, inserting a queue",
       
   894         GST_OBJECT_NAME (srcelement));
       
   895     queue = gst_element_factory_make ("queue", NULL);
       
   896     decode_bin->queue_type = G_OBJECT_TYPE (queue);
       
   897 
       
   898     g_object_set (G_OBJECT (queue), "max-size-buffers", 0, NULL);
       
   899     g_object_set (G_OBJECT (queue), "max-size-time", G_GINT64_CONSTANT (0),
       
   900         NULL);
       
   901     g_object_set (G_OBJECT (queue), "max-size-bytes", 8192, NULL);
       
   902     gst_bin_add (GST_BIN (decode_bin), queue);
       
   903     gst_element_set_state (queue, GST_STATE_READY);
       
   904     queuesinkpad = gst_element_get_pad (queue, "sink");
       
   905     usedsrcpad = queuesrcpad = gst_element_get_pad (queue, "src");
       
   906 
       
   907     dqlink = gst_pad_link (pad, queuesinkpad);
       
   908     g_return_val_if_fail (dqlink == GST_PAD_LINK_OK, NULL);
       
   909   }
       
   910 
       
   911   /* loop over the factories */
       
   912   for (walk = factories; walk; walk = g_list_next (walk)) {
       
   913     GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data);
       
   914     GstElement *element;
       
   915     GstPadLinkReturn ret;
       
   916     GstPad *sinkpad;
       
   917 
       
   918     GST_DEBUG_OBJECT (decode_bin, "trying to link %s",
       
   919         gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
       
   920 
       
   921     /* make an element from the factory first */
       
   922     if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
       
   923       /* hmm, strange. Like with all things in life, let's move on.. */
       
   924       GST_WARNING_OBJECT (decode_bin, "could not create an element from %s",
       
   925           gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
       
   926       continue;
       
   927     }
       
   928 
       
   929     /* try to link the given pad to a sinkpad */
       
   930     /* FIXME, find the sinkpad by looping over the pads instead of
       
   931      * looking it up by name */
       
   932     if ((sinkpad = gst_element_get_pad (element, "sink")) == NULL) {
       
   933       /* if no pad is found we can't do anything */
       
   934       GST_WARNING_OBJECT (decode_bin, "could not find sinkpad in element");
       
   935       continue;
       
   936     }
       
   937 
       
   938     /* now add the element to the bin first */
       
   939     GST_DEBUG_OBJECT (decode_bin, "adding %s", GST_OBJECT_NAME (element));
       
   940     gst_bin_add (GST_BIN (decode_bin), element);
       
   941 
       
   942     /* set to READY first so it is ready, duh. */
       
   943     if (gst_element_set_state (element,
       
   944             GST_STATE_READY) == GST_STATE_CHANGE_FAILURE) {
       
   945       GST_WARNING_OBJECT (decode_bin, "Couldn't set %s to READY",
       
   946           GST_ELEMENT_NAME (element));
       
   947       /* get rid of the sinkpad */
       
   948       gst_object_unref (sinkpad);
       
   949       /* this element did not work, remove it again and continue trying
       
   950        * other elements, the element will be disposed. */
       
   951       /* FIXME: shouldn't we do this before adding it to the bin so that no
       
   952        * error messages get through to the app? (tpm) */
       
   953       gst_bin_remove (GST_BIN (decode_bin), element);
       
   954       continue;
       
   955     }
       
   956 
       
   957     if ((ret = gst_pad_link (usedsrcpad, sinkpad)) != GST_PAD_LINK_OK) {
       
   958       GST_DEBUG_OBJECT (decode_bin, "link failed on pad %s:%s, reason %d",
       
   959           GST_DEBUG_PAD_NAME (pad), ret);
       
   960       /* get rid of the sinkpad */
       
   961       gst_object_unref (sinkpad);
       
   962       /* this element did not work, remove it again and continue trying
       
   963        * other elements, the element will be disposed. */
       
   964       gst_element_set_state (element, GST_STATE_NULL);
       
   965       gst_bin_remove (GST_BIN (decode_bin), element);
       
   966     } else {
       
   967       guint sig;
       
   968 
       
   969       GST_DEBUG_OBJECT (decode_bin, "linked on pad %s:%s",
       
   970           GST_DEBUG_PAD_NAME (usedsrcpad));
       
   971 
       
   972       /* configure the queue some more */
       
   973       if (queue != NULL) {
       
   974         decode_bin->queues = g_list_append (decode_bin->queues, queue);
       
   975         g_signal_connect (G_OBJECT (queue),
       
   976             "overrun", G_CALLBACK (queue_filled_cb), decode_bin);
       
   977         g_signal_connect (G_OBJECT (queue),
       
   978             "underrun", G_CALLBACK (queue_underrun_cb), decode_bin);
       
   979       }
       
   980 
       
   981       /* The link worked, now figure out what it was that we connected */
       
   982 
       
   983       /* make sure we catch unlink signals */
       
   984       sig = g_signal_connect (G_OBJECT (pad), "unlinked",
       
   985           G_CALLBACK (unlinked), decode_bin);
       
   986 
       
   987       /* now that we added the element we can try to continue autoplugging
       
   988        * on it until we have a raw type */
       
   989       close_link (element, decode_bin);
       
   990 
       
   991       /* change the state of the element to that of the parent */
       
   992       if ((gst_element_set_state (element,
       
   993                   GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE) {
       
   994         GST_WARNING_OBJECT (decode_bin, "Couldn't set %s to PAUSED",
       
   995             GST_ELEMENT_NAME (element));
       
   996         gst_element_set_state (element, GST_STATE_NULL);
       
   997         gst_bin_remove (GST_BIN (decode_bin), element);
       
   998         continue;
       
   999       }
       
  1000 
       
  1001       result = element;
       
  1002 
       
  1003       /* get rid of the sinkpad now */
       
  1004       gst_object_unref (sinkpad);
       
  1005 
       
  1006       /* Set the queue to paused and set the pointer to NULL so we don't
       
  1007        * remove it below */
       
  1008       if (queue != NULL) {
       
  1009         gst_element_set_state (queue, GST_STATE_PAUSED);
       
  1010         queue = NULL;
       
  1011         gst_object_unref (queuesrcpad);
       
  1012         gst_object_unref (queuesinkpad);
       
  1013       }
       
  1014 
       
  1015       /* and exit */
       
  1016       goto done;
       
  1017     }
       
  1018   }
       
  1019 done:
       
  1020   if (queue != NULL) {
       
  1021     /* We didn't successfully connect to the queue */
       
  1022     gst_pad_unlink (pad, queuesinkpad);
       
  1023     gst_element_set_state (queue, GST_STATE_NULL);
       
  1024     gst_object_unref (queuesrcpad);
       
  1025     gst_object_unref (queuesinkpad);
       
  1026     gst_bin_remove (GST_BIN (decode_bin), queue);
       
  1027   }
       
  1028   return result;
       
  1029 }
       
  1030 
       
  1031 static GstPad *
       
  1032 get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
       
  1033 {
       
  1034   GstIterator *pad_it = NULL;
       
  1035   GstPad *db_pad = NULL;
       
  1036   gboolean done = FALSE;
       
  1037 
       
  1038   if (pad == NULL || !GST_PAD_IS_SRC (pad)) {
       
  1039     GST_DEBUG_OBJECT (decode_bin, "pad NULL or not SRC pad");
       
  1040     return NULL;
       
  1041   }
       
  1042 
       
  1043   /* our ghostpads are the sourcepads */
       
  1044   pad_it = gst_element_iterate_src_pads (GST_ELEMENT (decode_bin));
       
  1045   while (!done) {
       
  1046     db_pad = NULL;
       
  1047     switch (gst_iterator_next (pad_it, (gpointer) & db_pad)) {
       
  1048       case GST_ITERATOR_OK:
       
  1049         GST_DEBUG_OBJECT (decode_bin, "looking at pad %s:%s",
       
  1050             GST_DEBUG_PAD_NAME (db_pad));
       
  1051         if (GST_IS_GHOST_PAD (db_pad)) {
       
  1052           GstPad *target_pad = NULL;
       
  1053 
       
  1054           target_pad = gst_ghost_pad_get_target (GST_GHOST_PAD (db_pad));
       
  1055           done = (target_pad == pad);
       
  1056           if (target_pad)
       
  1057             gst_object_unref (target_pad);
       
  1058 
       
  1059           if (done) {
       
  1060             /* Found our ghost pad */
       
  1061             GST_DEBUG_OBJECT (decode_bin, "found ghostpad %s:%s for pad %s:%s",
       
  1062                 GST_DEBUG_PAD_NAME (db_pad), GST_DEBUG_PAD_NAME (pad));
       
  1063             break;
       
  1064           }
       
  1065         }
       
  1066         /* Not the right one */
       
  1067         gst_object_unref (db_pad);
       
  1068         break;
       
  1069       case GST_ITERATOR_RESYNC:
       
  1070         gst_iterator_resync (pad_it);
       
  1071         break;
       
  1072       case GST_ITERATOR_ERROR:
       
  1073         done = TRUE;
       
  1074         break;
       
  1075       case GST_ITERATOR_DONE:
       
  1076         done = TRUE;
       
  1077         break;
       
  1078     }
       
  1079   }
       
  1080   gst_iterator_free (pad_it);
       
  1081 
       
  1082   return db_pad;
       
  1083 }
       
  1084 
       
  1085 /* remove all downstream elements starting from the given pad.
       
  1086  * Also make sure to remove the ghostpad we created for the raw
       
  1087  * decoded stream.
       
  1088  */
       
  1089 static void
       
  1090 remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
       
  1091 {
       
  1092   GList *int_links, *walk;
       
  1093   GstElement *elem = GST_ELEMENT (GST_OBJECT_PARENT (pad));
       
  1094 
       
  1095   while (GST_OBJECT_PARENT (elem) &&
       
  1096       GST_OBJECT_PARENT (elem) != GST_OBJECT (decode_bin))
       
  1097     elem = GST_ELEMENT (GST_OBJECT_PARENT (elem));
       
  1098 
       
  1099   if (G_OBJECT_TYPE (elem) == decode_bin->queue_type) {
       
  1100     GST_DEBUG_OBJECT (decode_bin,
       
  1101         "Encountered demuxer output queue while removing element chain");
       
  1102     decode_bin->queues = g_list_remove (decode_bin->queues, elem);
       
  1103   }
       
  1104 
       
  1105   GST_DEBUG_OBJECT (decode_bin, "%s:%s", GST_DEBUG_PAD_NAME (pad));
       
  1106   int_links = gst_pad_get_internal_links (pad);
       
  1107 
       
  1108   /* remove all elements linked to this pad up to the ghostpad
       
  1109    * that we created for this stream */
       
  1110   for (walk = int_links; walk; walk = g_list_next (walk)) {
       
  1111     GstPad *pad;
       
  1112     GstPad *ghostpad;
       
  1113     GstPad *peer;
       
  1114 
       
  1115     pad = GST_PAD (walk->data);
       
  1116     GST_DEBUG_OBJECT (decode_bin, "inspecting internal pad %s:%s",
       
  1117         GST_DEBUG_PAD_NAME (pad));
       
  1118 
       
  1119     ghostpad = get_our_ghost_pad (decode_bin, pad);
       
  1120     if (ghostpad) {
       
  1121       GST_DEBUG_OBJECT (decode_bin, "found our ghost pad %s:%s for %s:%s",
       
  1122           GST_DEBUG_PAD_NAME (ghostpad), GST_DEBUG_PAD_NAME (pad));
       
  1123 
       
  1124       g_signal_emit (G_OBJECT (decode_bin),
       
  1125           gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD], 0, ghostpad);
       
  1126 
       
  1127       gst_element_remove_pad (GST_ELEMENT (decode_bin), ghostpad);
       
  1128       gst_object_unref (ghostpad);
       
  1129       continue;
       
  1130     } else {
       
  1131       GST_DEBUG_OBJECT (decode_bin, "not one of our ghostpads");
       
  1132     }
       
  1133 
       
  1134     peer = gst_pad_get_peer (pad);
       
  1135     if (peer == NULL)
       
  1136       continue;
       
  1137 
       
  1138     GST_DEBUG_OBJECT (decode_bin, "internal pad %s:%s linked to pad %s:%s",
       
  1139         GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer));
       
  1140 
       
  1141     {
       
  1142       GstObject *parent = gst_pad_get_parent (peer);
       
  1143 
       
  1144       if (parent) {
       
  1145         GstObject *grandparent = gst_object_get_parent (parent);
       
  1146 
       
  1147         if (grandparent != NULL) {
       
  1148           if (GST_ELEMENT (grandparent) != GST_ELEMENT (decode_bin)) {
       
  1149             GST_DEBUG_OBJECT (decode_bin, "dead end pad %s:%s parent %s",
       
  1150                 GST_DEBUG_PAD_NAME (peer), GST_OBJECT_NAME (grandparent));
       
  1151           } else {
       
  1152             GST_DEBUG_OBJECT (decode_bin, "recursing element %s on pad %s:%s",
       
  1153                 GST_ELEMENT_NAME (elem), GST_DEBUG_PAD_NAME (pad));
       
  1154             remove_element_chain (decode_bin, peer);
       
  1155           }
       
  1156           gst_object_unref (grandparent);
       
  1157         }
       
  1158         gst_object_unref (parent);
       
  1159       }
       
  1160     }
       
  1161     gst_object_unref (peer);
       
  1162   }
       
  1163   GST_DEBUG_OBJECT (decode_bin, "removing %s", GST_ELEMENT_NAME (elem));
       
  1164 
       
  1165   g_list_free (int_links);
       
  1166 
       
  1167   gst_element_set_state (elem, GST_STATE_NULL);
       
  1168 
       
  1169   gst_bin_remove (GST_BIN (decode_bin), elem);
       
  1170 }
       
  1171 
       
  1172 /* there are @bytes bytes in @queue, enlarge it
       
  1173  *
       
  1174  * Returns: new max number of bytes in @queue
       
  1175  */
       
  1176 static guint
       
  1177 queue_enlarge (GstElement * queue, guint bytes, GstDecodeBin * decode_bin)
       
  1178 {
       
  1179   /* Increase the queue size by 1Mbyte if it is over 1Mb, else double its current limit
       
  1180    */
       
  1181   if (bytes > 1024 * 1024)
       
  1182     bytes += 1024 * 1024;
       
  1183   else
       
  1184     bytes *= 2;
       
  1185 
       
  1186   GST_DEBUG_OBJECT (decode_bin,
       
  1187       "increasing queue %s max-size-bytes to %d", GST_ELEMENT_NAME (queue),
       
  1188       bytes);
       
  1189   g_object_set (G_OBJECT (queue), "max-size-bytes", bytes, NULL);
       
  1190 
       
  1191   return bytes;
       
  1192 }
       
  1193 
       
  1194 /* this callback is called when our queues fills up or are empty
       
  1195  * We then check the status of all other queues to make sure we
       
  1196  * never have an empty and full queue at the same time since that
       
  1197  * would block dataflow. In the case of a filled queue, we make
       
  1198  * it larger.
       
  1199  */
       
  1200 static void
       
  1201 queue_underrun_cb (GstElement * queue, GstDecodeBin * decode_bin)
       
  1202 {
       
  1203   /* FIXME: we don't really do anything here for now. Ideally we should
       
  1204    * see if some of the queues are filled and increase their values
       
  1205    * in that case.
       
  1206    * Note: be very carefull with thread safety here as this underrun
       
  1207    * signal is done from the streaming thread of queue srcpad which
       
  1208    * is different from the pad_added (where we add the queue to the
       
  1209    * list) and the overrun signals that are signalled from the
       
  1210    * demuxer thread.
       
  1211    */
       
  1212   GST_DEBUG_OBJECT (decode_bin, "got underrun");
       
  1213 }
       
  1214 
       
  1215 /* Make sure we don't have a full queue and empty queue situation */
       
  1216 static void
       
  1217 queue_filled_cb (GstElement * queue, GstDecodeBin * decode_bin)
       
  1218 {
       
  1219   GList *tmp;
       
  1220   gboolean increase = FALSE;
       
  1221   guint bytes;
       
  1222 
       
  1223   /* get current byte level from the queue that is filled */
       
  1224   g_object_get (G_OBJECT (queue), "current-level-bytes", &bytes, NULL);
       
  1225   GST_DEBUG_OBJECT (decode_bin, "One of the queues is full at %d bytes", bytes);
       
  1226 
       
  1227   /* we do not buffer more than 20Mb */
       
  1228   if (bytes > (20 * 1024 * 1024))
       
  1229     goto too_large;
       
  1230 
       
  1231   /* check all other queue to see if one is empty, in that case
       
  1232    * we need to enlarge @queue */
       
  1233   for (tmp = decode_bin->queues; tmp; tmp = g_list_next (tmp)) {
       
  1234     GstElement *aqueue = GST_ELEMENT (tmp->data);
       
  1235     guint levelbytes = 0;
       
  1236 
       
  1237     if (aqueue != queue) {
       
  1238       g_object_get (G_OBJECT (aqueue), "current-level-bytes", &levelbytes,
       
  1239           NULL);
       
  1240       if (levelbytes == 0) {
       
  1241         /* yup, found an empty queue, we can stop the search and
       
  1242          * need to enlarge the queue */
       
  1243         increase = TRUE;
       
  1244         break;
       
  1245       }
       
  1246     }
       
  1247   }
       
  1248 
       
  1249   if (increase) {
       
  1250     /* enlarge @queue */
       
  1251     queue_enlarge (queue, bytes, decode_bin);
       
  1252   } else {
       
  1253     GST_DEBUG_OBJECT (decode_bin,
       
  1254         "Queue is full but other queues are not empty, not doing anything");
       
  1255   }
       
  1256   return;
       
  1257 
       
  1258   /* errors */
       
  1259 too_large:
       
  1260   {
       
  1261     GST_WARNING_OBJECT (decode_bin,
       
  1262         "Queue is bigger than 20Mbytes, something else is going wrong");
       
  1263     return;
       
  1264   }
       
  1265 }
       
  1266 
       
  1267 /* This function will be called when a dynamic pad is created on an element.
       
  1268  * We try to continue autoplugging on this new pad. */
       
  1269 static void
       
  1270 new_pad (GstElement * element, GstPad * pad, GstDynamic * dynamic)
       
  1271 {
       
  1272   GstDecodeBin *decode_bin = dynamic->decode_bin;
       
  1273   GstCaps *caps;
       
  1274   gboolean more;
       
  1275 
       
  1276   GST_OBJECT_LOCK (decode_bin);
       
  1277   if (decode_bin->shutting_down)
       
  1278     goto shutting_down1;
       
  1279   GST_OBJECT_UNLOCK (decode_bin);
       
  1280 
       
  1281   GST_STATE_LOCK (decode_bin);
       
  1282   if (decode_bin->shutting_down)
       
  1283     goto shutting_down2;
       
  1284 
       
  1285   /* see if any more pending dynamic connections exist */
       
  1286   more = gst_decode_bin_is_dynamic (decode_bin);
       
  1287 
       
  1288   caps = gst_pad_get_caps (pad);
       
  1289   close_pad_link (element, pad, caps, decode_bin, more);
       
  1290   if (caps)
       
  1291     gst_caps_unref (caps);
       
  1292   GST_STATE_UNLOCK (decode_bin);
       
  1293 
       
  1294   return;
       
  1295 
       
  1296 shutting_down1:
       
  1297   {
       
  1298     GST_DEBUG_OBJECT (decode_bin, "we are shutting down");
       
  1299     GST_OBJECT_UNLOCK (decode_bin);
       
  1300     return;
       
  1301   }
       
  1302 shutting_down2:
       
  1303   {
       
  1304     GST_DEBUG_OBJECT (decode_bin, "we are shutting down");
       
  1305     GST_STATE_UNLOCK (decode_bin);
       
  1306     return;
       
  1307   }
       
  1308 }
       
  1309 
       
  1310 static void
       
  1311 dynamic_remove (GstDynamic * dynamic)
       
  1312 {
       
  1313   GstDecodeBin *decode_bin = dynamic->decode_bin;
       
  1314 
       
  1315   /* remove the dynamic from the list of dynamics */
       
  1316   decode_bin->dynamics = g_list_remove (decode_bin->dynamics, dynamic);
       
  1317   dynamic_free (dynamic);
       
  1318 
       
  1319   /* if we have no more dynamic elements, we have no chance of creating
       
  1320    * more pads, so we fire the no_more_pads signal */
       
  1321   if (decode_bin->dynamics == NULL) {
       
  1322     if (decode_bin->numwaiting == 0) {
       
  1323       GST_DEBUG_OBJECT (decode_bin,
       
  1324           "no more dynamic elements, removing fakesink");
       
  1325       remove_fakesink (decode_bin);
       
  1326     }
       
  1327     GST_DEBUG_OBJECT (decode_bin,
       
  1328         "no more dynamic elements, signaling no_more_pads");
       
  1329     gst_element_no_more_pads (GST_ELEMENT (decode_bin));
       
  1330   } else {
       
  1331     GST_DEBUG_OBJECT (decode_bin, "we have more dynamic elements");
       
  1332   }
       
  1333 }
       
  1334 
       
  1335 /* this signal is fired when an element signals the no_more_pads signal.
       
  1336  * This means that the element will not generate more dynamic pads and
       
  1337  * we can remove the element from the list of dynamic elements. When we
       
  1338  * have no more dynamic elements in the pipeline, we can fire a no_more_pads
       
  1339  * signal ourselves. */
       
  1340 static void
       
  1341 no_more_pads (GstElement * element, GstDynamic * dynamic)
       
  1342 {
       
  1343   GST_DEBUG_OBJECT (dynamic->decode_bin, "no more pads on element %s",
       
  1344       GST_ELEMENT_NAME (element));
       
  1345 
       
  1346   dynamic_remove (dynamic);
       
  1347 }
       
  1348 
       
  1349 static void
       
  1350 new_caps (GstPad * pad, GParamSpec * unused, GstDynamic * dynamic)
       
  1351 {
       
  1352   GST_DEBUG_OBJECT (dynamic->decode_bin, "delayed link triggered");
       
  1353 
       
  1354   new_pad (dynamic->element, pad, dynamic);
       
  1355 
       
  1356   /* assume it worked and remove the dynamic */
       
  1357   dynamic_remove (dynamic);
       
  1358 
       
  1359   return;
       
  1360 }
       
  1361 
       
  1362 static gboolean
       
  1363 is_our_kid (GstElement * e, GstDecodeBin * decode_bin)
       
  1364 {
       
  1365   gboolean ret;
       
  1366   GstElement *parent;
       
  1367 
       
  1368   parent = (GstElement *) gst_object_get_parent ((GstObject *) e);
       
  1369   ret = (parent == (GstElement *) decode_bin);
       
  1370 
       
  1371   if (parent)
       
  1372     gst_object_unref ((GstObject *) parent);
       
  1373 
       
  1374   return ret;
       
  1375 }
       
  1376 
       
  1377 static gboolean
       
  1378 elem_is_dynamic (GstElement * element, GstDecodeBin * decode_bin)
       
  1379 {
       
  1380   GList *pads;
       
  1381 
       
  1382   /* loop over all the padtemplates */
       
  1383   for (pads = GST_ELEMENT_GET_CLASS (element)->padtemplates; pads;
       
  1384       pads = g_list_next (pads)) {
       
  1385     GstPadTemplate *templ = GST_PAD_TEMPLATE (pads->data);
       
  1386     const gchar *templ_name;
       
  1387 
       
  1388     /* we are only interested in source pads */
       
  1389     if (GST_PAD_TEMPLATE_DIRECTION (templ) != GST_PAD_SRC)
       
  1390       continue;
       
  1391 
       
  1392     templ_name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);
       
  1393     GST_DEBUG_OBJECT (decode_bin, "got a source pad template %s", templ_name);
       
  1394 
       
  1395     /* figure out what kind of pad this is */
       
  1396     switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
       
  1397       case GST_PAD_SOMETIMES:
       
  1398       {
       
  1399         /* try to get the pad to see if it is already created or
       
  1400          * not */
       
  1401         GstPad *pad = gst_element_get_pad (element, templ_name);
       
  1402 
       
  1403         if (pad) {
       
  1404           GST_DEBUG_OBJECT (decode_bin, "got the pad for sometimes template %s",
       
  1405               templ_name);
       
  1406           gst_object_unref (pad);
       
  1407         } else {
       
  1408           GST_DEBUG_OBJECT (decode_bin,
       
  1409               "did not get the sometimes pad of template %s", templ_name);
       
  1410           /* we have an element that will create dynamic pads */
       
  1411           return TRUE;
       
  1412         }
       
  1413         break;
       
  1414       }
       
  1415       default:
       
  1416         /* Don't care about ALWAYS or REQUEST pads */
       
  1417         break;
       
  1418     }
       
  1419   }
       
  1420   return FALSE;
       
  1421 }
       
  1422 
       
  1423 /* This function will be called when a pad is disconnected for some reason */
       
  1424 static void
       
  1425 unlinked (GstPad * pad, GstPad * peerpad, GstDecodeBin * decode_bin)
       
  1426 {
       
  1427   GstElement *element, *peer;
       
  1428 
       
  1429   /* inactivate pad */
       
  1430   gst_pad_set_active (pad, GST_ACTIVATE_NONE);
       
  1431 
       
  1432   peer = gst_pad_get_parent_element (peerpad);
       
  1433 
       
  1434   if (!is_our_kid (peer, decode_bin))
       
  1435     goto exit;
       
  1436 
       
  1437   GST_DEBUG_OBJECT (decode_bin, "pad %s:%s removal while alive - chained?",
       
  1438       GST_DEBUG_PAD_NAME (pad));
       
  1439 
       
  1440   /* remove all elements linked to the peerpad */
       
  1441   remove_element_chain (decode_bin, peerpad);
       
  1442 
       
  1443   /* Re-add as a dynamic element if needed, via close_link */
       
  1444   element = gst_pad_get_parent_element (pad);
       
  1445   if (element) {
       
  1446     if (elem_is_dynamic (element, decode_bin))
       
  1447       dynamic_add (element, NULL, decode_bin);
       
  1448 
       
  1449     gst_object_unref (element);
       
  1450   }
       
  1451 
       
  1452 exit:
       
  1453   gst_object_unref (peer);
       
  1454 }
       
  1455 
       
  1456 /* this function inspects the given element and tries to connect something
       
  1457  * on the srcpads. If there are dynamic pads, it sets up a signal handler to
       
  1458  * continue autoplugging when they become available */
       
  1459 static void
       
  1460 close_link (GstElement * element, GstDecodeBin * decode_bin)
       
  1461 {
       
  1462   GList *pads;
       
  1463   gboolean dynamic = FALSE;
       
  1464   GList *to_connect = NULL;
       
  1465   gboolean more;
       
  1466 
       
  1467   GST_DEBUG_OBJECT (decode_bin, "closing links with element %s",
       
  1468       GST_ELEMENT_NAME (element));
       
  1469 
       
  1470   /* loop over all the padtemplates */
       
  1471   for (pads = GST_ELEMENT_GET_CLASS (element)->padtemplates; pads;
       
  1472       pads = g_list_next (pads)) {
       
  1473     GstPadTemplate *templ = GST_PAD_TEMPLATE (pads->data);
       
  1474     const gchar *templ_name;
       
  1475 
       
  1476     /* we are only interested in source pads */
       
  1477     if (GST_PAD_TEMPLATE_DIRECTION (templ) != GST_PAD_SRC)
       
  1478       continue;
       
  1479 
       
  1480     templ_name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);
       
  1481     GST_DEBUG_OBJECT (decode_bin, "got a source pad template %s", templ_name);
       
  1482 
       
  1483     /* figure out what kind of pad this is */
       
  1484     switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
       
  1485       case GST_PAD_ALWAYS:
       
  1486       {
       
  1487         /* get the pad that we need to autoplug */
       
  1488         GstPad *pad = gst_element_get_pad (element, templ_name);
       
  1489 
       
  1490         if (pad) {
       
  1491           GST_DEBUG_OBJECT (decode_bin, "got the pad for always template %s",
       
  1492               templ_name);
       
  1493           /* here is the pad, we need to autoplug it */
       
  1494           to_connect = g_list_prepend (to_connect, pad);
       
  1495         } else {
       
  1496           /* strange, pad is marked as always but it's not
       
  1497            * there. Fix the element */
       
  1498           GST_WARNING_OBJECT (decode_bin,
       
  1499               "could not get the pad for always template %s", templ_name);
       
  1500         }
       
  1501         break;
       
  1502       }
       
  1503       case GST_PAD_SOMETIMES:
       
  1504       {
       
  1505         /* try to get the pad to see if it is already created or
       
  1506          * not */
       
  1507         GstPad *pad = gst_element_get_pad (element, templ_name);
       
  1508 
       
  1509         if (pad) {
       
  1510           GST_DEBUG_OBJECT (decode_bin, "got the pad for sometimes template %s",
       
  1511               templ_name);
       
  1512           /* the pad is created, we need to autoplug it */
       
  1513           to_connect = g_list_prepend (to_connect, pad);
       
  1514         } else {
       
  1515           GST_DEBUG_OBJECT (decode_bin,
       
  1516               "did not get the sometimes pad of template %s", templ_name);
       
  1517           /* we have an element that will create dynamic pads */
       
  1518           dynamic = TRUE;
       
  1519         }
       
  1520         break;
       
  1521       }
       
  1522       case GST_PAD_REQUEST:
       
  1523         /* ignore request pads */
       
  1524         GST_DEBUG_OBJECT (decode_bin, "ignoring request padtemplate %s",
       
  1525             templ_name);
       
  1526         break;
       
  1527     }
       
  1528   }
       
  1529   if (dynamic) {
       
  1530     GST_DEBUG_OBJECT (decode_bin, "got a dynamic element here");
       
  1531     /* ok, this element has dynamic pads, set up the signal handlers to be
       
  1532      * notified of them */
       
  1533 
       
  1534     dynamic_add (element, NULL, decode_bin);
       
  1535   }
       
  1536 
       
  1537   /* Check if this is an element with more than 1 pad. If this element
       
  1538    * has more than 1 pad, we need to be carefull not to signal the
       
  1539    * no_more_pads signal after connecting the first pad. */
       
  1540   more = g_list_length (to_connect) > 1;
       
  1541 
       
  1542   /* now loop over all the pads we need to connect */
       
  1543   for (pads = to_connect; pads; pads = g_list_next (pads)) {
       
  1544     GstPad *pad = GST_PAD_CAST (pads->data);
       
  1545     GstCaps *caps;
       
  1546 
       
  1547     /* we have more pads if we have more than 1 pad to connect or
       
  1548      * dynamics. If we have only 1 pad and no dynamics, more will be
       
  1549      * set to FALSE and the no-more-pads signal will be fired. Note
       
  1550      * that this can change after the close_pad_link call. */
       
  1551     more |= gst_decode_bin_is_dynamic (decode_bin);
       
  1552 
       
  1553     GST_DEBUG_OBJECT (decode_bin, "closing pad link for %s",
       
  1554         GST_OBJECT_NAME (pad));
       
  1555 
       
  1556     /* continue autoplugging on the pads */
       
  1557     caps = gst_pad_get_caps (pad);
       
  1558     close_pad_link (element, pad, caps, decode_bin, more);
       
  1559     if (caps)
       
  1560       gst_caps_unref (caps);
       
  1561 
       
  1562     gst_object_unref (pad);
       
  1563   }
       
  1564   g_list_free (to_connect);
       
  1565 }
       
  1566 
       
  1567 /* this is the signal handler for the typefind element have_type signal.
       
  1568  * It tries to continue autoplugging on the typefind src pad */
       
  1569 static void
       
  1570 type_found (GstElement * typefind, guint probability, GstCaps * caps,
       
  1571     GstDecodeBin * decode_bin)
       
  1572 {
       
  1573   gboolean dynamic;
       
  1574   GstPad *pad;
       
  1575 
       
  1576   GST_DEBUG_OBJECT (decode_bin, "typefind found caps %" GST_PTR_FORMAT, caps);
       
  1577 
       
  1578   GST_OBJECT_LOCK (decode_bin);
       
  1579   if (decode_bin->shutting_down)
       
  1580     goto shutting_down;
       
  1581   GST_OBJECT_UNLOCK (decode_bin);
       
  1582 
       
  1583   GST_STATE_LOCK (decode_bin);
       
  1584   if (decode_bin->shutting_down)
       
  1585     goto exit;
       
  1586 
       
  1587   /* don't need the typefind anymore if we already found a type, we're not going
       
  1588    * to be able to do anything with it anyway except for generating errors */
       
  1589   if (decode_bin->have_type)
       
  1590     goto exit;
       
  1591 
       
  1592   decode_bin->have_type = TRUE;
       
  1593 
       
  1594   /* special-case text/plain: we only want to accept it as a raw type if it
       
  1595    * comes from a subtitle parser element or a demuxer, but not if it is the
       
  1596    * type of the entire stream, in which case we just want to error out */
       
  1597   if (typefind == decode_bin->typefind &&
       
  1598       gst_structure_has_name (gst_caps_get_structure (caps, 0), "text/plain")) {
       
  1599     gst_element_no_more_pads (GST_ELEMENT (decode_bin));
       
  1600     /* we can't handle this type of stream */
       
  1601     GST_ELEMENT_ERROR (decode_bin, STREAM, WRONG_TYPE,
       
  1602         (_("This appears to be a text file")),
       
  1603         ("decodebin cannot decode plain text files"));
       
  1604     goto exit;
       
  1605   }
       
  1606 
       
  1607   /* autoplug the new pad with the caps that the signal gave us. */
       
  1608   pad = gst_element_get_pad (typefind, "src");
       
  1609   close_pad_link (typefind, pad, caps, decode_bin, FALSE);
       
  1610   gst_object_unref (pad);
       
  1611 
       
  1612   dynamic = gst_decode_bin_is_dynamic (decode_bin);
       
  1613   if (dynamic == FALSE) {
       
  1614     GST_DEBUG_OBJECT (decode_bin, "we have no dynamic elements anymore");
       
  1615     /* if we have no dynamic elements, we know that no new pads
       
  1616      * will be created and we can signal out no_more_pads signal */
       
  1617     gst_element_no_more_pads (GST_ELEMENT (decode_bin));
       
  1618   } else {
       
  1619     /* more dynamic elements exist that could create new pads */
       
  1620     GST_DEBUG_OBJECT (decode_bin, "we have more dynamic elements");
       
  1621   }
       
  1622 
       
  1623 exit:
       
  1624   GST_STATE_UNLOCK (decode_bin);
       
  1625   return;
       
  1626 
       
  1627 shutting_down:
       
  1628   {
       
  1629     GST_DEBUG_OBJECT (decode_bin, "we are shutting down");
       
  1630     GST_OBJECT_UNLOCK (decode_bin);
       
  1631     return;
       
  1632   }
       
  1633 }
       
  1634 
       
  1635 static void
       
  1636 disconnect_unlinked_signals (GstDecodeBin * decode_bin, GstElement * element)
       
  1637 {
       
  1638   GstIterator *pad_it = NULL;
       
  1639   gboolean done = FALSE;
       
  1640 
       
  1641   pad_it = gst_element_iterate_src_pads (element);
       
  1642   while (!done) {
       
  1643     GstPad *pad = NULL;
       
  1644 
       
  1645     switch (gst_iterator_next (pad_it, (gpointer) & pad)) {
       
  1646       case GST_ITERATOR_OK:
       
  1647         g_signal_handlers_disconnect_by_func (pad, (gpointer) unlinked,
       
  1648             decode_bin);
       
  1649         gst_object_unref (pad);
       
  1650         break;
       
  1651       case GST_ITERATOR_RESYNC:
       
  1652         gst_iterator_resync (pad_it);
       
  1653         break;
       
  1654       default:
       
  1655         done = TRUE;
       
  1656         break;
       
  1657     }
       
  1658   }
       
  1659   gst_iterator_free (pad_it);
       
  1660 }
       
  1661 
       
  1662 
       
  1663 static void
       
  1664 cleanup_decodebin (GstDecodeBin * decode_bin)
       
  1665 {
       
  1666   GstIterator *elem_it = NULL, *gpad_it = NULL;
       
  1667   GstPad *typefind_pad = NULL;
       
  1668   gboolean done = FALSE;
       
  1669 
       
  1670   g_return_if_fail (GST_IS_DECODE_BIN (decode_bin));
       
  1671 
       
  1672   GST_DEBUG_OBJECT (decode_bin, "cleaning up decodebin");
       
  1673 
       
  1674   typefind_pad = gst_element_get_pad (decode_bin->typefind, "src");
       
  1675   if (GST_IS_PAD (typefind_pad)) {
       
  1676     g_signal_handlers_block_by_func (typefind_pad, (gpointer) unlinked,
       
  1677         decode_bin);
       
  1678   }
       
  1679 
       
  1680   elem_it = gst_bin_iterate_elements (GST_BIN (decode_bin));
       
  1681   while (!done) {
       
  1682     GstElement *element = NULL;
       
  1683 
       
  1684     switch (gst_iterator_next (elem_it, (gpointer) & element)) {
       
  1685       case GST_ITERATOR_OK:
       
  1686         if (element != decode_bin->typefind && element != decode_bin->fakesink) {
       
  1687           GST_DEBUG_OBJECT (element, "removing autoplugged element");
       
  1688           disconnect_unlinked_signals (decode_bin, element);
       
  1689           gst_element_set_state (element, GST_STATE_NULL);
       
  1690           gst_bin_remove (GST_BIN (decode_bin), element);
       
  1691         }
       
  1692         gst_object_unref (element);
       
  1693         break;
       
  1694       case GST_ITERATOR_RESYNC:
       
  1695         gst_iterator_resync (elem_it);
       
  1696         break;
       
  1697       case GST_ITERATOR_ERROR:
       
  1698         done = TRUE;
       
  1699         break;
       
  1700       case GST_ITERATOR_DONE:
       
  1701         done = TRUE;
       
  1702         break;
       
  1703     }
       
  1704   }
       
  1705   gst_iterator_free (elem_it);
       
  1706 
       
  1707   done = FALSE;
       
  1708   gpad_it = gst_element_iterate_pads (GST_ELEMENT (decode_bin));
       
  1709   while (!done) {
       
  1710     GstPad *pad = NULL;
       
  1711 
       
  1712     switch (gst_iterator_next (gpad_it, (gpointer) & pad)) {
       
  1713       case GST_ITERATOR_OK:
       
  1714         GST_DEBUG_OBJECT (pad, "inspecting pad %s:%s",
       
  1715             GST_DEBUG_PAD_NAME (pad));
       
  1716         if (GST_IS_GHOST_PAD (pad) && GST_PAD_IS_SRC (pad)) {
       
  1717           GST_DEBUG_OBJECT (pad, "removing ghost pad");
       
  1718           gst_element_remove_pad (GST_ELEMENT (decode_bin), pad);
       
  1719         }
       
  1720         gst_object_unref (pad);
       
  1721         break;
       
  1722       case GST_ITERATOR_RESYNC:
       
  1723         gst_iterator_resync (gpad_it);
       
  1724         break;
       
  1725       case GST_ITERATOR_ERROR:
       
  1726         done = TRUE;
       
  1727         break;
       
  1728       case GST_ITERATOR_DONE:
       
  1729         done = TRUE;
       
  1730         break;
       
  1731     }
       
  1732   }
       
  1733   gst_iterator_free (gpad_it);
       
  1734 
       
  1735   if (GST_IS_PAD (typefind_pad)) {
       
  1736     g_signal_handlers_unblock_by_func (typefind_pad, (gpointer) unlinked,
       
  1737         decode_bin);
       
  1738     g_signal_handlers_disconnect_by_func (typefind_pad, (gpointer) unlinked,
       
  1739         decode_bin);
       
  1740     gst_object_unref (typefind_pad);
       
  1741   }
       
  1742 }
       
  1743 
       
  1744 static GstStateChangeReturn
       
  1745 gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
       
  1746 {
       
  1747   GstStateChangeReturn ret;
       
  1748   GstDecodeBin *decode_bin;
       
  1749 
       
  1750   decode_bin = GST_DECODE_BIN (element);
       
  1751 
       
  1752   switch (transition) {
       
  1753     case GST_STATE_CHANGE_NULL_TO_READY:
       
  1754       decode_bin->numpads = 0;
       
  1755       decode_bin->numwaiting = 0;
       
  1756       decode_bin->dynamics = NULL;
       
  1757       if (decode_bin->typefind == NULL)
       
  1758         goto missing_typefind;
       
  1759       break;
       
  1760     case GST_STATE_CHANGE_READY_TO_PAUSED:
       
  1761       GST_OBJECT_LOCK (decode_bin);
       
  1762       decode_bin->shutting_down = FALSE;
       
  1763       decode_bin->have_type = FALSE;
       
  1764       GST_OBJECT_UNLOCK (decode_bin);
       
  1765 
       
  1766       if (!add_fakesink (decode_bin))
       
  1767         goto missing_fakesink;
       
  1768       break;
       
  1769     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
       
  1770     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
       
  1771       break;
       
  1772     case GST_STATE_CHANGE_PAUSED_TO_READY:
       
  1773       GST_OBJECT_LOCK (decode_bin);
       
  1774       decode_bin->shutting_down = TRUE;
       
  1775       GST_OBJECT_UNLOCK (decode_bin);
       
  1776       break;
       
  1777     default:
       
  1778       break;
       
  1779   }
       
  1780 
       
  1781   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
       
  1782   if (ret == GST_STATE_CHANGE_FAILURE)
       
  1783     return ret;
       
  1784 
       
  1785   switch (transition) {
       
  1786     case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
       
  1787       break;
       
  1788     case GST_STATE_CHANGE_PAUSED_TO_READY:
       
  1789     case GST_STATE_CHANGE_READY_TO_NULL:
       
  1790       free_dynamics (decode_bin);
       
  1791       free_pad_probes (decode_bin);
       
  1792       cleanup_decodebin (decode_bin);
       
  1793       break;
       
  1794     default:
       
  1795       break;
       
  1796   }
       
  1797 
       
  1798   return ret;
       
  1799 /* ERRORS */
       
  1800 missing_typefind:
       
  1801   {
       
  1802     gst_element_post_message (element,
       
  1803         gst_missing_element_message_new (element, "typefind"));
       
  1804     GST_ELEMENT_ERROR (element, CORE, MISSING_PLUGIN, (NULL), ("no typefind!"));
       
  1805     return GST_STATE_CHANGE_FAILURE;
       
  1806   }
       
  1807 missing_fakesink:
       
  1808   {
       
  1809     gst_element_post_message (element,
       
  1810         gst_missing_element_message_new (element, "fakesink"));
       
  1811     GST_ELEMENT_ERROR (element, CORE, MISSING_PLUGIN, (NULL), ("no fakesink!"));
       
  1812     return GST_STATE_CHANGE_FAILURE;
       
  1813   }
       
  1814 }
       
  1815 
       
  1816 static gboolean
       
  1817 plugin_init (GstPlugin * plugin)
       
  1818 {
       
  1819   GST_DEBUG_CATEGORY_INIT (gst_decode_bin_debug, "decodebin", 0, "decoder bin");
       
  1820 
       
  1821 #ifdef ENABLE_NLS
       
  1822   GST_DEBUG ("binding text domain %s to locale dir %s", GETTEXT_PACKAGE,
       
  1823       LOCALEDIR);
       
  1824   bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
       
  1825 #endif /* ENABLE_NLS */
       
  1826 
       
  1827   return gst_element_register (plugin, "decodebin", GST_RANK_NONE,
       
  1828       GST_TYPE_DECODE_BIN);
       
  1829 }
       
  1830 
       
  1831 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
       
  1832     GST_VERSION_MINOR,
       
  1833     "decodebin",
       
  1834     "decoder bin", plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME,
       
  1835     GST_PACKAGE_ORIGIN);
       
  1836 
       
  1837 #ifdef __SYMBIAN32__
       
  1838 EXPORT_C 
       
  1839 #endif
       
  1840 GstPluginDesc* _GST_PLUGIN_DESC()
       
  1841 {
       
  1842 	return &gst_plugin_desc;
       
  1843 }
       
  1844