gst-gmyth/decodebin2/gstdecodebin2.c
author melunko
Fri Sep 14 21:35:12 2007 +0100 (2007-09-14)
branchtrunk
changeset 844 8081f181cba6
parent 787 e42706ada231
permissions -rw-r--r--
[svn r850] nuvdemux package changelog updated
     1 /* GStreamer
     2  * Copyright (C) <2006> Edward Hervey <edward@fluendo.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 /**
    21  * SECTION:element-decodebin2
    22  * @short_description: Next-generation automatic decoding bin
    23  *
    24  * #GstBin that auto-magically constructs a decoding pipeline using available
    25  * decoders and demuxers via auto-plugging.
    26  *
    27  * At this stage, decodebin2 is considered UNSTABLE. The API provided in the
    28  * signals is expected to change in the near future. 
    29  *
    30  * To try out decodebin2, you can set the USE_DECODEBIN2 environment 
    31  * variable (USE_DECODEBIN2=1 for example). This will cause playbin to use
    32  * decodebin2 instead of the older decodebin for its internal auto-plugging.
    33  */
    34 
    35 #ifdef HAVE_CONFIG_H
    36 #include "config.h"
    37 #endif
    38 
    39 #include <string.h>
    40 #include <gst/gst.h>
    41 
    42 #include "gstplay-marshal.h"
    43 
    44 /* generic templates */
    45 static GstStaticPadTemplate decoder_bin_sink_template =
    46 GST_STATIC_PAD_TEMPLATE ("sink",
    47     GST_PAD_SINK,
    48     GST_PAD_ALWAYS,
    49     GST_STATIC_CAPS_ANY);
    50 
    51 static GstStaticPadTemplate decoder_bin_src_template =
    52 GST_STATIC_PAD_TEMPLATE ("src%d",
    53     GST_PAD_SRC,
    54     GST_PAD_SOMETIMES,
    55     GST_STATIC_CAPS_ANY);
    56 
    57 GST_DEBUG_CATEGORY_STATIC (gst_decode_bin_debug);
    58 #define GST_CAT_DEFAULT gst_decode_bin_debug
    59 
    60 typedef struct _GstDecodeGroup GstDecodeGroup;
    61 typedef struct _GstDecodePad GstDecodePad;
    62 typedef struct _GstDecodeBin GstDecodeBin;
    63 typedef struct _GstDecodeBin GstDecodeBin2;
    64 typedef struct _GstDecodeBinClass GstDecodeBinClass;
    65 
    66 #define GST_TYPE_DECODE_BIN             (gst_decode_bin_get_type())
    67 #define GST_DECODE_BIN_CAST(obj)        ((GstDecodeBin*)(obj))
    68 #define GST_DECODE_BIN(obj)             (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_DECODE_BIN,GstDecodeBin))
    69 #define GST_DECODE_BIN_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_DECODE_BIN,GstDecodeBinClass))
    70 #define GST_IS_DECODE_BIN(obj)          (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_DECODE_BIN))
    71 #define GST_IS_DECODE_BIN_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_DECODE_BIN))
    72 
    73 /**
    74  *  GstDecodeBin2:
    75  *
    76  *  The opaque #DecodeBin2 data structure
    77  */
    78 struct _GstDecodeBin
    79 {
    80   GstBin bin;                   /* we extend GstBin */
    81 
    82   GstElement *typefind;         /* this holds the typefind object */
    83   GstElement *fakesink;
    84 
    85   GMutex *lock;                 /* Protects activegroup and groups */
    86   GstDecodeGroup *activegroup;  /* group currently active */
    87   GList *groups;                /* List of non-active GstDecodeGroups, sorted in
    88                                  * order of creation. */
    89   GList *oldgroups;             /* List of no-longer-used GstDecodeGroups. 
    90                                  * Should be freed in dispose */
    91   gint nbpads;                  /* unique identifier for source pads */
    92   GstCaps *caps;                /* caps on which to stop decoding */
    93 
    94   GList *factories;             /* factories we can use for selecting elements */
    95 };
    96 
    97 struct _GstDecodeBinClass
    98 {
    99   GstBinClass parent_class;
   100 
   101   /* signal we fire when a new pad has been decoded into raw audio/video */
   102   void (*new_decoded_pad) (GstElement * element, GstPad * pad, gboolean last);
   103   /* signal we fire when a pad has been removed */
   104   void (*removed_decoded_pad) (GstElement * element, GstPad * pad);
   105   /* signal fired when we found a pad that we cannot decode */
   106   void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps);
   107   /* signal fired to know if we continue trying to decode the given caps */
   108     gboolean (*autoplug_continue) (GstElement * element, GstCaps * caps);
   109   /* signal fired to reorder the proposed list of factories */
   110     gboolean (*autoplug_sort) (GstElement * element, GstCaps * caps,
   111       GList ** list);
   112 };
   113 
   114 /* signals */
   115 enum
   116 {
   117   SIGNAL_NEW_DECODED_PAD,
   118   SIGNAL_REMOVED_DECODED_PAD,
   119   SIGNAL_UNKNOWN_TYPE,
   120   SIGNAL_AUTOPLUG_CONTINUE,
   121   SIGNAL_AUTOPLUG_SORT,
   122   LAST_SIGNAL
   123 };
   124 
   125 /* Properties */
   126 enum
   127 {
   128   PROP_0,
   129   PROP_CAPS,
   130 };
   131 
   132 static GstBinClass *parent_class;
   133 static guint gst_decode_bin_signals[LAST_SIGNAL] = { 0 };
   134 
   135 static const GstElementDetails gst_decode_bin_details =
   136 GST_ELEMENT_DETAILS ("Decoder Bin",
   137     "Generic/Bin/Decoder",
   138     "Autoplug and decode to raw media",
   139     "Edward Hervey <edward@fluendo.com>");
   140 
   141 
   142 static gboolean add_fakesink (GstDecodeBin * decode_bin);
   143 static void remove_fakesink (GstDecodeBin * decode_bin);
   144 
   145 static void type_found (GstElement * typefind, guint probability,
   146     GstCaps * caps, GstDecodeBin * decode_bin);
   147 
   148 static gboolean gst_decode_bin_autoplug_continue (GstElement * element,
   149     GstCaps * caps);
   150 static gboolean gst_decode_bin_autoplug_sort (GstElement * element,
   151     GstCaps * caps, GList ** list);
   152 static void gst_decode_bin_set_property (GObject * object, guint prop_id,
   153     const GValue * value, GParamSpec * pspec);
   154 static void gst_decode_bin_get_property (GObject * object, guint prop_id,
   155     GValue * value, GParamSpec * pspec);
   156 static void gst_decode_bin_set_caps (GstDecodeBin * dbin, GstCaps * caps);
   157 static GstCaps *gst_decode_bin_get_caps (GstDecodeBin * dbin);
   158 
   159 static GstPad *find_sink_pad (GstElement * element);
   160 static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
   161     GstStateChange transition);
   162 
   163 #define DECODE_BIN_LOCK(dbin) G_STMT_START {				\
   164     GST_LOG_OBJECT (dbin,						\
   165 		    "locking from thread %p",				\
   166 		    g_thread_self ());					\
   167     g_mutex_lock (GST_DECODE_BIN_CAST(dbin)->lock);			\
   168     GST_LOG_OBJECT (dbin,						\
   169 		    "locked from thread %p",				\
   170 		    g_thread_self ());					\
   171 } G_STMT_END
   172 
   173 #define DECODE_BIN_UNLOCK(dbin) G_STMT_START {				\
   174     GST_LOG_OBJECT (dbin,						\
   175 		    "unlocking from thread %p",				\
   176 		    g_thread_self ());					\
   177     g_mutex_unlock (GST_DECODE_BIN_CAST(dbin)->lock);			\
   178 } G_STMT_END
   179 
   180 /* GstDecodeGroup
   181  *
   182  * Streams belonging to the same group/chain of a media file
   183  *
   184  */
   185 
   186 struct _GstDecodeGroup
   187 {
   188   GstDecodeBin *dbin;
   189   GMutex *lock;
   190   GstElement *multiqueue;
   191   gboolean exposed;             /* TRUE if this group is exposed */
   192   gboolean drained;             /* TRUE if EOS went throug all endpads */
   193   gboolean blocked;             /* TRUE if all endpads are blocked */
   194   gboolean complete;            /* TRUE if we are not expecting anymore streams 
   195                                  * on this group */
   196   gulong overrunsig;
   197   gulong underrunsig;
   198   guint nbdynamic;              /* number of dynamic pads in the group. */
   199 
   200   GList *endpads;               /* List of GstDecodePad of source pads to be exposed */
   201   GList *ghosts;                /* List of GstGhostPad for the endpads */
   202 };
   203 
   204 #define GROUP_MUTEX_LOCK(group) G_STMT_START {				\
   205     GST_LOG_OBJECT (group->dbin,					\
   206 		    "locking group %p from thread %p",			\
   207 		    group, g_thread_self ());				\
   208     g_mutex_lock (group->lock);						\
   209     GST_LOG_OBJECT (group->dbin,					\
   210 		    "locked group %p from thread %p",			\
   211 		    group, g_thread_self ());				\
   212 } G_STMT_END
   213 
   214 #define GROUP_MUTEX_UNLOCK(group) G_STMT_START {                        \
   215     GST_LOG_OBJECT (group->dbin,					\
   216 		    "unlocking group %p from thread %p",		\
   217 		    group, g_thread_self ());				\
   218     g_mutex_unlock (group->lock);					\
   219 } G_STMT_END
   220 
   221 
   222 static GstDecodeGroup *gst_decode_group_new (GstDecodeBin * decode_bin);
   223 static GstPad *gst_decode_group_control_demuxer_pad (GstDecodeGroup * group,
   224     GstPad * pad);
   225 static gboolean gst_decode_group_control_source_pad (GstDecodeGroup * group,
   226     GstPad * pad);
   227 static gboolean gst_decode_group_expose (GstDecodeGroup * group);
   228 static void gst_decode_group_check_if_blocked (GstDecodeGroup * group);
   229 static void gst_decode_group_set_complete (GstDecodeGroup * group);
   230 static void gst_decode_group_hide (GstDecodeGroup * group);
   231 static void gst_decode_group_free (GstDecodeGroup * group);
   232 
   233 /* GstDecodePad
   234  *
   235  * GstPad private used for source pads of groups
   236  */
   237 
   238 struct _GstDecodePad
   239 {
   240   GstPad *pad;
   241   GstDecodeGroup *group;
   242   gboolean blocked;
   243   gboolean drained;
   244 };
   245 
   246 static GstDecodePad *gst_decode_pad_new (GstDecodeGroup * group, GstPad * pad,
   247     gboolean block);
   248 static void source_pad_blocked_cb (GstPad * pad, gboolean blocked,
   249     GstDecodePad * dpad);
   250 
   251 /* TempPadStruct
   252  * Internal structure used for pads which have more than one structure.
   253  */
   254 typedef struct _TempPadStruct
   255 {
   256   GstDecodeBin *dbin;
   257   GstDecodeGroup *group;
   258 } TempPadStruct;
   259 
   260 /********************************
   261  * Standard GObject boilerplate *
   262  ********************************/
   263 
   264 static void gst_decode_bin_class_init (GstDecodeBinClass * klass);
   265 static void gst_decode_bin_init (GstDecodeBin * decode_bin);
   266 static void gst_decode_bin_dispose (GObject * object);
   267 static void gst_decode_bin_finalize (GObject * object);
   268 
   269 static GType
   270 gst_decode_bin_get_type (void)
   271 {
   272   static GType gst_decode_bin_type = 0;
   273 
   274   if (!gst_decode_bin_type) {
   275     static const GTypeInfo gst_decode_bin_info = {
   276       sizeof (GstDecodeBinClass),
   277       NULL,
   278       NULL,
   279       (GClassInitFunc) gst_decode_bin_class_init,
   280       NULL,
   281       NULL,
   282       sizeof (GstDecodeBin),
   283       0,
   284       (GInstanceInitFunc) gst_decode_bin_init,
   285       NULL
   286     };
   287 
   288     gst_decode_bin_type =
   289         g_type_register_static (GST_TYPE_BIN, "GstDecodeBin2",
   290         &gst_decode_bin_info, 0);
   291   }
   292 
   293   return gst_decode_bin_type;
   294 }
   295 
   296 static gboolean
   297 _gst_boolean_accumulator (GSignalInvocationHint * ihint,
   298     GValue * return_accu, const GValue * handler_return, gpointer dummy)
   299 {
   300   gboolean myboolean;
   301 
   302   myboolean = g_value_get_boolean (handler_return);
   303   if (!(ihint->run_type & G_SIGNAL_RUN_CLEANUP))
   304     g_value_set_boolean (return_accu, myboolean);
   305 
   306   /* stop emission if FALSE */
   307   return myboolean;
   308 }
   309 
   310 static void
   311 gst_decode_bin_class_init (GstDecodeBinClass * klass)
   312 {
   313   GObjectClass *gobject_klass;
   314   GstElementClass *gstelement_klass;
   315   GstBinClass *gstbin_klass;
   316 
   317   gobject_klass = (GObjectClass *) klass;
   318   gstelement_klass = (GstElementClass *) klass;
   319   gstbin_klass = (GstBinClass *) klass;
   320 
   321   parent_class = g_type_class_peek_parent (klass);
   322 
   323   gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_decode_bin_dispose);
   324   gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_decode_bin_finalize);
   325   gobject_klass->set_property = GST_DEBUG_FUNCPTR (gst_decode_bin_set_property);
   326   gobject_klass->get_property = GST_DEBUG_FUNCPTR (gst_decode_bin_get_property);
   327 
   328   /**
   329    * GstDecodeBin2::new-decoded-pad:
   330    * @pad: the newly created pad
   331    * @islast: #TRUE if this is the last pad to be added. Deprecated.
   332    *
   333    * This signal gets emitted as soon as a new pad of the same type as one of
   334    * the valid 'raw' types is added.
   335    */
   336 
   337   gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD] =
   338       g_signal_new ("new-decoded-pad", G_TYPE_FROM_CLASS (klass),
   339       G_SIGNAL_RUN_LAST,
   340       G_STRUCT_OFFSET (GstDecodeBinClass, new_decoded_pad), NULL, NULL,
   341       gst_play_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2, GST_TYPE_PAD,
   342       G_TYPE_BOOLEAN);
   343 
   344   /**
   345    * GstDecodeBin2::removed-decoded-pad:
   346    * @pad: the pad that was removed
   347    *
   348    * This signal is emitted when a 'final' caps pad has been removed.
   349    */
   350 
   351   gst_decode_bin_signals[SIGNAL_REMOVED_DECODED_PAD] =
   352       g_signal_new ("removed-decoded-pad", G_TYPE_FROM_CLASS (klass),
   353       G_SIGNAL_RUN_LAST,
   354       G_STRUCT_OFFSET (GstDecodeBinClass, removed_decoded_pad), NULL, NULL,
   355       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
   356 
   357   /**
   358    * GstDecodeBin2::unknown-type:
   359    * @pad: the new pad containing caps that cannot be resolved to a 'final' stream type.
   360    * @caps: the #GstCaps of the pad that cannot be resolved.
   361    *
   362    * This signal is emitted when a pad for which there is no further possible
   363    * decoding is added to the decodebin.
   364    */
   365 
   366   gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE] =
   367       g_signal_new ("unknown-type", G_TYPE_FROM_CLASS (klass),
   368       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, unknown_type),
   369       NULL, NULL, gst_marshal_VOID__OBJECT_OBJECT, G_TYPE_NONE, 2,
   370       GST_TYPE_PAD, GST_TYPE_CAPS);
   371 
   372   /**
   373    * GstDecodeBin2::autoplug-continue:
   374    * @caps: The #GstCaps found.
   375    *
   376    * This signal is emitted whenever decodebin2 finds a new stream. It is
   377    * emitted before looking for any elements that can handle that stream.
   378    *
   379    * Returns: #TRUE if you wish decodebin2 to look for elements that can
   380    * handle the given @caps. If #FALSE, those caps will be considered as
   381    * final and the pad will be exposed as such (see 'new-decoded-pad'
   382    * signal).
   383    */
   384 
   385   gst_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE] =
   386       g_signal_new ("autoplug-continue", G_TYPE_FROM_CLASS (klass),
   387       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, autoplug_continue),
   388       _gst_boolean_accumulator, NULL, gst_play_marshal_BOOLEAN__OBJECT,
   389       G_TYPE_BOOLEAN, 1, GST_TYPE_CAPS);
   390 
   391   /**
   392    * GstDecodeBin2::autoplug-sort:
   393    * @caps: The #GstCaps.
   394    * @factories: A #GList of possible #GstElementFactory to use.
   395    *
   396    * This signal is emitted once decodebin2 has found all the possible
   397    * #GstElementFactory that can be used to handle the given @caps.
   398    *
   399    * UNSTABLE API. Will change soon.
   400    *
   401    * Returns: #TRUE if you wish decodebin2 to start trying to decode
   402    * the given @caps with the list of factories. #FALSE if you do not want
   403    * these #GstCaps, if so the pad will be exposed as unknown (see
   404    * 'unknown-type' signal).
   405    */
   406 
   407   gst_decode_bin_signals[SIGNAL_AUTOPLUG_SORT] =
   408       g_signal_new ("autoplug-sort", G_TYPE_FROM_CLASS (klass),
   409       G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstDecodeBinClass, autoplug_sort),
   410       _gst_boolean_accumulator, NULL, gst_play_marshal_BOOLEAN__OBJECT_POINTER,
   411       G_TYPE_BOOLEAN, 2, GST_TYPE_CAPS, G_TYPE_POINTER);
   412 
   413   g_object_class_install_property (gobject_klass, PROP_CAPS,
   414       g_param_spec_boxed ("caps", "Caps", "The caps on which to stop decoding.",
   415           GST_TYPE_CAPS, G_PARAM_READWRITE));
   416 
   417   klass->autoplug_continue =
   418       GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_continue);
   419   klass->autoplug_sort = GST_DEBUG_FUNCPTR (gst_decode_bin_autoplug_sort);
   420 
   421   gst_element_class_add_pad_template (gstelement_klass,
   422       gst_static_pad_template_get (&decoder_bin_sink_template));
   423   gst_element_class_add_pad_template (gstelement_klass,
   424       gst_static_pad_template_get (&decoder_bin_src_template));
   425 
   426   gst_element_class_set_details (gstelement_klass, &gst_decode_bin_details);
   427 
   428   gstelement_klass->change_state =
   429       GST_DEBUG_FUNCPTR (gst_decode_bin_change_state);
   430 }
   431 
   432 /* the filter function for selecting the elements we can use in
   433  * autoplugging */
   434 static gboolean
   435 gst_decode_bin_factory_filter (GstPluginFeature * feature,
   436     GstDecodeBin * decode_bin)
   437 {
   438   guint rank;
   439   const gchar *klass;
   440 
   441   /* we only care about element factories */
   442   if (!GST_IS_ELEMENT_FACTORY (feature))
   443     return FALSE;
   444 
   445   klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
   446   /* only demuxers, decoders and parsers can play */
   447   if (strstr (klass, "Demux") == NULL &&
   448       strstr (klass, "Decoder") == NULL && strstr (klass, "Parse") == NULL) {
   449     return FALSE;
   450   }
   451 
   452   /* only select elements with autoplugging rank */
   453 #if 0
   454   rank = gst_plugin_feature_get_rank (feature);
   455   if (rank < GST_RANK_MARGINAL)
   456     return FALSE;
   457 #endif
   458 
   459   return TRUE;
   460 }
   461 
   462 /* function used to sort element features */
   463 static gint
   464 compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
   465 {
   466   gint diff;
   467   const gchar *rname1, *rname2;
   468 
   469   diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
   470   if (diff != 0)
   471     return diff;
   472 
   473   rname1 = gst_plugin_feature_get_name (f1);
   474   rname2 = gst_plugin_feature_get_name (f2);
   475 
   476   diff = strcmp (rname2, rname1);
   477 
   478   return diff;
   479 }
   480 
   481 static void
   482 print_feature (GstPluginFeature * feature)
   483 {
   484   const gchar *rname;
   485 
   486   rname = gst_plugin_feature_get_name (feature);
   487 
   488   GST_DEBUG ("%s", rname);
   489 }
   490 
   491 static void
   492 gst_decode_bin_init (GstDecodeBin * decode_bin)
   493 {
   494   GList *factories;
   495 
   496   /* first filter out the interesting element factories */
   497   factories = gst_default_registry_feature_filter (
   498       (GstPluginFeatureFilter) gst_decode_bin_factory_filter,
   499       FALSE, decode_bin);
   500 
   501   /* sort them according to their ranks */
   502   decode_bin->factories = g_list_sort (factories, (GCompareFunc) compare_ranks);
   503   /* do some debugging */
   504   g_list_foreach (decode_bin->factories, (GFunc) print_feature, NULL);
   505 
   506 
   507   /* we create the typefind element only once */
   508   decode_bin->typefind = gst_element_factory_make ("typefind", "typefind");
   509   if (!decode_bin->typefind) {
   510     g_warning ("can't find typefind element, decodebin will not work");
   511   } else {
   512     GstPad *pad;
   513     GstPad *gpad;
   514 
   515     /* add the typefind element */
   516     if (!gst_bin_add (GST_BIN (decode_bin), decode_bin->typefind)) {
   517       g_warning ("Could not add typefind element, decodebin will not work");
   518       gst_object_unref (decode_bin->typefind);
   519       decode_bin->typefind = NULL;
   520     }
   521 
   522     /* get the sinkpad */
   523     pad = gst_element_get_pad (decode_bin->typefind, "sink");
   524 
   525     /* ghost the sink pad to ourself */
   526     gpad = gst_ghost_pad_new ("sink", pad);
   527     gst_pad_set_active (gpad, TRUE);
   528     gst_element_add_pad (GST_ELEMENT (decode_bin), gpad);
   529 
   530     gst_object_unref (pad);
   531 
   532     /* connect a signal to find out when the typefind element found
   533      * a type */
   534     g_signal_connect (G_OBJECT (decode_bin->typefind), "have_type",
   535         G_CALLBACK (type_found), decode_bin);
   536   }
   537 
   538   decode_bin->lock = g_mutex_new ();
   539   decode_bin->activegroup = NULL;
   540   decode_bin->groups = NULL;
   541 
   542   decode_bin->caps =
   543       gst_caps_from_string ("video/x-raw-yuv;video/x-raw-rgb;video/x-raw-gray;"
   544       "audio/x-raw-int;audio/x-raw-float;" "text/plain;text/x-pango-markup");
   545 
   546   add_fakesink (decode_bin);
   547 
   548   /* FILLME */
   549 }
   550 
   551 static void
   552 gst_decode_bin_dispose (GObject * object)
   553 {
   554   GstDecodeBin *decode_bin;
   555   GList *tmp;
   556 
   557   decode_bin = GST_DECODE_BIN (object);
   558 
   559   if (decode_bin->factories)
   560     gst_plugin_feature_list_free (decode_bin->factories);
   561   decode_bin->factories = NULL;
   562 
   563   if (decode_bin->activegroup) {
   564     gst_decode_group_free (decode_bin->activegroup);
   565     decode_bin->activegroup = NULL;
   566   }
   567 
   568   /* remove groups */
   569   for (tmp = decode_bin->groups; tmp; tmp = g_list_next (tmp)) {
   570     GstDecodeGroup *group = (GstDecodeGroup *) tmp->data;
   571 
   572     gst_decode_group_free (group);
   573   }
   574   g_list_free (decode_bin->groups);
   575   decode_bin->groups = NULL;
   576 
   577   for (tmp = decode_bin->oldgroups; tmp; tmp = g_list_next (tmp)) {
   578     GstDecodeGroup *group = (GstDecodeGroup *) tmp->data;
   579 
   580     gst_decode_group_free (group);
   581   }
   582   g_list_free (decode_bin->oldgroups);
   583   decode_bin->oldgroups = NULL;
   584 
   585   if (decode_bin->caps)
   586     gst_caps_unref (decode_bin->caps);
   587   decode_bin->caps = NULL;
   588   remove_fakesink (decode_bin);
   589 
   590   G_OBJECT_CLASS (parent_class)->dispose (object);
   591 }
   592 
   593 static void
   594 gst_decode_bin_finalize (GObject * object)
   595 {
   596   GstDecodeBin *decode_bin;
   597 
   598   decode_bin = GST_DECODE_BIN (object);
   599 
   600   if (decode_bin->lock) {
   601     g_mutex_free (decode_bin->lock);
   602     decode_bin->lock = NULL;
   603   }
   604 
   605   G_OBJECT_CLASS (parent_class)->finalize (object);
   606 }
   607 
   608 static void
   609 gst_decode_bin_set_property (GObject * object, guint prop_id,
   610     const GValue * value, GParamSpec * pspec)
   611 {
   612   GstDecodeBin *dbin;
   613 
   614   dbin = GST_DECODE_BIN (object);
   615 
   616   switch (prop_id) {
   617     case PROP_CAPS:
   618       gst_decode_bin_set_caps (dbin, (GstCaps *) g_value_dup_boxed (value));
   619       break;
   620     default:
   621       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   622       break;
   623   }
   624 }
   625 
   626 static void
   627 gst_decode_bin_get_property (GObject * object, guint prop_id,
   628     GValue * value, GParamSpec * pspec)
   629 {
   630   GstDecodeBin *dbin;
   631 
   632   dbin = GST_DECODE_BIN (object);
   633   switch (prop_id) {
   634     case PROP_CAPS:{
   635       g_value_take_boxed (value, gst_decode_bin_get_caps (dbin));
   636       break;
   637     }
   638     default:
   639       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   640       break;
   641   }
   642 
   643 }
   644 
   645 /* _set_caps
   646  * Changes the caps on which decodebin will stop decoding.
   647  * Will unref the previously set one. The refcount of the given caps will be
   648  * taken.
   649  * @caps can be NULL.
   650  *
   651  * MT-safe
   652  */
   653 
   654 static void
   655 gst_decode_bin_set_caps (GstDecodeBin * dbin, GstCaps * caps)
   656 {
   657   GST_DEBUG_OBJECT (dbin, "Setting new caps: %" GST_PTR_FORMAT, caps);
   658 
   659   DECODE_BIN_LOCK (dbin);
   660   if (dbin->caps)
   661     gst_caps_unref (dbin->caps);
   662   dbin->caps = caps;
   663   DECODE_BIN_UNLOCK (dbin);
   664 }
   665 
   666 /* _get_caps
   667  * Returns the currently configured caps on which decodebin will stop decoding.
   668  * The returned caps (if not NULL), will have its refcount incremented.
   669  *
   670  * MT-safe
   671  */
   672 
   673 static GstCaps *
   674 gst_decode_bin_get_caps (GstDecodeBin * dbin)
   675 {
   676   GstCaps *caps;
   677 
   678   GST_DEBUG_OBJECT (dbin, "Getting currently set caps");
   679 
   680   DECODE_BIN_LOCK (dbin);
   681   caps = dbin->caps;
   682   if (caps)
   683     gst_caps_ref (caps);
   684   DECODE_BIN_UNLOCK (dbin);
   685 
   686   return caps;
   687 }
   688 
   689 /*****
   690  * Default autoplug signal handlers
   691  *****/
   692 
   693 static gboolean
   694 gst_decode_bin_autoplug_continue (GstElement * element, GstCaps * caps)
   695 {
   696   return TRUE;
   697 }
   698 
   699 static gboolean
   700 gst_decode_bin_autoplug_sort (GstElement * element, GstCaps * caps,
   701     GList ** list)
   702 {
   703   return TRUE;
   704 }
   705 
   706 
   707 
   708 /********
   709  * Discovery methods
   710  *****/
   711 
   712 static gboolean are_raw_caps (GstDecodeBin * dbin, GstCaps * caps);
   713 static gboolean is_demuxer_element (GstElement * srcelement);
   714 static GList *find_compatibles (GstDecodeBin * decode_bin,
   715     const GstCaps * caps);
   716 
   717 static gboolean connect_pad (GstDecodeBin * dbin, GstElement * src,
   718     GstPad * pad, GList * factories, GstDecodeGroup * group);
   719 static gboolean connect_element (GstDecodeBin * dbin, GstElement * element,
   720     GstDecodeGroup * group);
   721 static void expose_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
   722     GstDecodeGroup * group);
   723 
   724 static void pad_added_group_cb (GstElement * element, GstPad * pad,
   725     GstDecodeGroup * group);
   726 static void pad_removed_group_cb (GstElement * element, GstPad * pad,
   727     GstDecodeGroup * group);
   728 static void no_more_pads_group_cb (GstElement * element,
   729     GstDecodeGroup * group);
   730 static void pad_added_cb (GstElement * element, GstPad * pad,
   731     GstDecodeBin * dbin);
   732 static void pad_removed_cb (GstElement * element, GstPad * pad,
   733     GstDecodeBin * dbin);
   734 static void no_more_pads_cb (GstElement * element, GstDecodeBin * dbin);
   735 
   736 static GstDecodeGroup *get_current_group (GstDecodeBin * dbin);
   737 
   738 static void
   739 analyze_new_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
   740     GstCaps * caps, GstDecodeGroup * group)
   741 {
   742   gboolean apcontinue = TRUE;
   743   GList *factories = NULL;
   744   gboolean apsort = TRUE;
   745 
   746   GST_DEBUG_OBJECT (dbin, "Pad %s:%s caps:%" GST_PTR_FORMAT,
   747       GST_DEBUG_PAD_NAME (pad), caps);
   748 
   749   if ((caps == NULL) || gst_caps_is_empty (caps))
   750     goto unknown_type;
   751 
   752   if (gst_caps_is_any (caps))
   753     goto any_caps;
   754 
   755   /* 1. Emit 'autoplug-continue' */
   756   g_signal_emit (G_OBJECT (dbin),
   757       gst_decode_bin_signals[SIGNAL_AUTOPLUG_CONTINUE], 0, caps, &apcontinue);
   758 
   759   /* 1.a if autoplug-continue is FALSE or caps is a raw format, goto pad_is_final */
   760   if ((!apcontinue) || are_raw_caps (dbin, caps))
   761     goto expose_pad;
   762 
   763   /* 1.b else if there's no compatible factory or 'autoplug-sort' returned FALSE, goto pad_not_used */
   764   if ((factories = find_compatibles (dbin, caps))) {
   765     /* emit autoplug-sort */
   766     g_signal_emit (G_OBJECT (dbin),
   767         gst_decode_bin_signals[SIGNAL_AUTOPLUG_SORT],
   768         0, caps, &factories, &apsort);
   769     if (!apsort) {
   770       g_list_free (factories);
   771       /* User doesn't want that pad */
   772       goto pad_not_wanted;
   773     }
   774   } else {
   775     /* no compatible factories */
   776     goto unknown_type;
   777   }
   778 
   779   /* 1.c else goto pad_is_valid */
   780   GST_LOG_OBJECT (pad, "Let's continue discovery on this pad");
   781 
   782   connect_pad (dbin, src, pad, factories, group);
   783   g_list_free (factories);
   784 
   785   return;
   786 
   787 expose_pad:
   788   {
   789     GST_LOG_OBJECT (dbin, "Pad is final. autoplug-continue:%d", apcontinue);
   790     expose_pad (dbin, src, pad, group);
   791     return;
   792   }
   793 
   794 pad_not_wanted:
   795   {
   796     GST_LOG_OBJECT (pad, "User doesn't want this pad, stopping discovery");
   797     return;
   798   }
   799 
   800 unknown_type:
   801   {
   802     GST_LOG_OBJECT (pad, "Unknown type, firing signal");
   803     g_signal_emit (G_OBJECT (dbin),
   804         gst_decode_bin_signals[SIGNAL_UNKNOWN_TYPE], 0, pad, caps);
   805 
   806     /* Check if there are no pending groups, if so, remove fakesink */
   807     if (dbin->groups == NULL)
   808       remove_fakesink (dbin);
   809 
   810     return;
   811   }
   812 
   813 any_caps:
   814   {
   815     GST_WARNING_OBJECT (pad,
   816         "pad has ANY caps, not able to autoplug to anything");
   817     /* FIXME : connect to caps notification */
   818     return;
   819   }
   820 }
   821 
   822 
   823 /* connect_pad:
   824  *
   825  * Try to connect the given pad to an element created from one of the factories,
   826  * and recursively.
   827  *
   828  * Returns TRUE if an element was properly created and linked
   829  */
   830 
   831 static gboolean
   832 connect_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
   833     GList * factories, GstDecodeGroup * group)
   834 {
   835   gboolean res = FALSE;
   836   GList *tmp;
   837 
   838   g_return_val_if_fail (factories != NULL, FALSE);
   839   GST_DEBUG_OBJECT (dbin, "pad %s:%s , group:%p",
   840       GST_DEBUG_PAD_NAME (pad), group);
   841 
   842   /* 1. is element demuxer or parser */
   843   if (is_demuxer_element (src)) {
   844     GstPad *mqpad;
   845 
   846     GST_LOG_OBJECT (src, "is a demuxer, connecting the pad through multiqueue");
   847 
   848     if (!group)
   849       if (!(group = get_current_group (dbin))) {
   850         group = gst_decode_group_new (dbin);
   851         DECODE_BIN_LOCK (dbin);
   852         dbin->groups = g_list_append (dbin->groups, group);
   853         DECODE_BIN_UNLOCK (dbin);
   854       }
   855 
   856     if (!(mqpad = gst_decode_group_control_demuxer_pad (group, pad)))
   857       goto beach;
   858     pad = mqpad;
   859   }
   860 
   861   /* 2. Try to create an element and link to it */
   862   for (tmp = factories; tmp; tmp = g_list_next (tmp)) {
   863     GstElementFactory *factory = (GstElementFactory *) tmp->data;
   864     GstElement *element;
   865     GstPad *sinkpad;
   866 
   867     /* 2.1. Try to create an element */
   868     if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
   869       GST_WARNING_OBJECT (dbin, "Could not create an element from %s",
   870           gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
   871       continue;
   872     }
   873 
   874     /* 2.3. Find its sink pad */
   875     if (!(sinkpad = find_sink_pad (element))) {
   876       GST_WARNING_OBJECT (dbin, "Element %s doesn't have a sink pad",
   877           GST_ELEMENT_NAME (element));
   878       gst_object_unref (element);
   879       continue;
   880     }
   881 
   882     /* 2.4 add it ... */
   883     if (!(gst_bin_add (GST_BIN (dbin), element))) {
   884       GST_WARNING_OBJECT (dbin, "Couldn't add %s to the bin",
   885           GST_ELEMENT_NAME (element));
   886       gst_object_unref (sinkpad);
   887       gst_object_unref (element);
   888       continue;
   889     }
   890 
   891     /* ... activate it ... */
   892     if ((gst_element_set_state (element,
   893                 GST_STATE_READY)) == GST_STATE_CHANGE_FAILURE) {
   894       GST_WARNING_OBJECT (dbin, "Couldn't set %s to READY",
   895           GST_ELEMENT_NAME (element));
   896       gst_object_unref (sinkpad);
   897       gst_bin_remove (GST_BIN (dbin), element);
   898       continue;
   899     }
   900 
   901     /* 2.5 ...and try to link */
   902     if ((gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) {
   903       GST_WARNING_OBJECT (dbin, "Link failed on pad %s:%s",
   904           GST_DEBUG_PAD_NAME (sinkpad));
   905       gst_element_set_state (element, GST_STATE_NULL);
   906       gst_object_unref (sinkpad);
   907       gst_bin_remove (GST_BIN (dbin), element);
   908       continue;
   909     }
   910 
   911     GST_LOG_OBJECT (dbin, "linked on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
   912 
   913     /* link this element further */
   914     connect_element (dbin, element, group);
   915 
   916     /* Bring the element to the state of the parent */
   917     if ((gst_element_set_state (element,
   918                 GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE) {
   919       GST_WARNING_OBJECT (dbin, "Couldn't set %s to PAUSED",
   920           GST_ELEMENT_NAME (element));
   921       gst_element_set_state (element, GST_STATE_NULL);
   922       gst_object_unref (sinkpad);
   923       gst_bin_remove (GST_BIN (dbin), element);
   924       continue;
   925     }
   926 
   927     res = TRUE;
   928     break;
   929   }
   930 
   931 beach:
   932   return res;
   933 }
   934 
   935 static gboolean
   936 connect_element (GstDecodeBin * dbin, GstElement * element,
   937     GstDecodeGroup * group)
   938 {
   939   GList *pads;
   940   gboolean res = TRUE;
   941   gboolean dynamic = FALSE;
   942   GList *to_connect = NULL;
   943 
   944   GST_DEBUG_OBJECT (dbin, "Attempting to connect element %s [group:%p] further",
   945       GST_ELEMENT_NAME (element), group);
   946 
   947   /* 1. Loop over pad templates, grabbing existing pads along the way */
   948   for (pads = GST_ELEMENT_GET_CLASS (element)->padtemplates; pads;
   949       pads = g_list_next (pads)) {
   950     GstPadTemplate *templ = GST_PAD_TEMPLATE (pads->data);
   951     const gchar *templ_name;
   952 
   953     /* we are only interested in source pads */
   954     if (GST_PAD_TEMPLATE_DIRECTION (templ) != GST_PAD_SRC)
   955       continue;
   956 
   957     templ_name = GST_PAD_TEMPLATE_NAME_TEMPLATE (templ);
   958     GST_DEBUG_OBJECT (dbin, "got a source pad template %s", templ_name);
   959 
   960     /* figure out what kind of pad this is */
   961     switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
   962       case GST_PAD_ALWAYS:
   963       {
   964         /* get the pad that we need to autoplug */
   965         GstPad *pad = gst_element_get_pad (element, templ_name);
   966 
   967         if (pad) {
   968           GST_DEBUG_OBJECT (dbin, "got the pad for always template %s",
   969               templ_name);
   970           /* here is the pad, we need to autoplug it */
   971           to_connect = g_list_prepend (to_connect, pad);
   972         } else {
   973           /* strange, pad is marked as always but it's not
   974            * there. Fix the element */
   975           GST_WARNING_OBJECT (dbin,
   976               "could not get the pad for always template %s", templ_name);
   977         }
   978         break;
   979       }
   980       case GST_PAD_SOMETIMES:
   981       {
   982         /* try to get the pad to see if it is already created or
   983          * not */
   984         GstPad *pad = gst_element_get_pad (element, templ_name);
   985 
   986         if (pad) {
   987           GST_DEBUG_OBJECT (dbin, "got the pad for sometimes template %s",
   988               templ_name);
   989           /* the pad is created, we need to autoplug it */
   990           to_connect = g_list_prepend (to_connect, pad);
   991         } else {
   992           GST_DEBUG_OBJECT (dbin,
   993               "did not get the sometimes pad of template %s", templ_name);
   994           /* we have an element that will create dynamic pads */
   995           dynamic = TRUE;
   996         }
   997         break;
   998       }
   999       case GST_PAD_REQUEST:
  1000         /* ignore request pads */
  1001         GST_DEBUG_OBJECT (dbin, "ignoring request padtemplate %s", templ_name);
  1002         break;
  1003     }
  1004   }
  1005 
  1006   /* 2. if there are more potential pads, connect to relevent signals */
  1007   if (dynamic) {
  1008     if (group) {
  1009       GST_LOG ("Adding signals to element %s in group %p",
  1010           GST_ELEMENT_NAME (element), group);
  1011       GROUP_MUTEX_LOCK (group);
  1012       group->nbdynamic++;
  1013       GST_LOG ("Group %p has now %d dynamic elements", group, group->nbdynamic);
  1014       GROUP_MUTEX_UNLOCK (group);
  1015       g_signal_connect (G_OBJECT (element), "pad-added",
  1016           G_CALLBACK (pad_added_group_cb), group);
  1017       g_signal_connect (G_OBJECT (element), "pad-removed",
  1018           G_CALLBACK (pad_removed_group_cb), group);
  1019       g_signal_connect (G_OBJECT (element), "no-more-pads",
  1020           G_CALLBACK (no_more_pads_group_cb), group);
  1021     } else {
  1022       /* This is a non-grouped element, the handlers are different */
  1023       g_signal_connect (G_OBJECT (element), "pad-added",
  1024           G_CALLBACK (pad_added_cb), dbin);
  1025       g_signal_connect (G_OBJECT (element), "pad-removed",
  1026           G_CALLBACK (pad_removed_cb), dbin);
  1027       g_signal_connect (G_OBJECT (element), "no-more-pads",
  1028           G_CALLBACK (no_more_pads_cb), dbin);
  1029     }
  1030   }
  1031 
  1032   /* 3. for every available pad, connect it */
  1033   for (pads = to_connect; pads; pads = g_list_next (pads)) {
  1034     GstPad *pad = GST_PAD_CAST (pads->data);
  1035     GstCaps *caps;
  1036 
  1037     caps = gst_pad_get_caps (pad);
  1038     analyze_new_pad (dbin, element, pad, caps, group);
  1039     if (caps)
  1040       gst_caps_unref (caps);
  1041 
  1042     gst_object_unref (pad);
  1043   }
  1044   g_list_free (to_connect);
  1045 
  1046   return res;
  1047 }
  1048 
  1049 /* expose_pad:
  1050  *
  1051  * Expose the given pad on the group as a decoded pad.
  1052  * If group is NULL, a GstDecodeGroup will be created and setup properly.
  1053  */
  1054 static void
  1055 expose_pad (GstDecodeBin * dbin, GstElement * src, GstPad * pad,
  1056     GstDecodeGroup * group)
  1057 {
  1058   gboolean newgroup = FALSE;
  1059   gboolean isdemux;
  1060 
  1061   GST_DEBUG_OBJECT (dbin, "pad %s:%s, group:%p",
  1062       GST_DEBUG_PAD_NAME (pad), group);
  1063 
  1064   if (!group)
  1065     if (!(group = get_current_group (dbin))) {
  1066       group = gst_decode_group_new (dbin);
  1067       DECODE_BIN_LOCK (dbin);
  1068       dbin->groups = g_list_append (dbin->groups, group);
  1069       DECODE_BIN_UNLOCK (dbin);
  1070       newgroup = TRUE;
  1071     }
  1072 
  1073   isdemux = is_demuxer_element (src);
  1074 
  1075   if (isdemux || newgroup) {
  1076     GstPad *mqpad;
  1077 
  1078     GST_LOG_OBJECT (src, "is a demuxer, connecting the pad through multiqueue");
  1079 
  1080     if (!(mqpad = gst_decode_group_control_demuxer_pad (group, pad)))
  1081       goto beach;
  1082     pad = mqpad;
  1083   }
  1084 
  1085   gst_decode_group_control_source_pad (group, pad);
  1086 
  1087   if (newgroup && !isdemux) {
  1088     /* If we have discovered a raw pad and it doesn't belong to any group,
  1089      * that means there wasn't any demuxer. In that case, we consider the
  1090      * group as being complete. */
  1091     gst_decode_group_set_complete (group);
  1092   }
  1093 beach:
  1094   return;
  1095 }
  1096 
  1097 static void
  1098 type_found (GstElement * typefind, guint probability,
  1099     GstCaps * caps, GstDecodeBin * decode_bin)
  1100 {
  1101   GstPad *pad;
  1102 
  1103   GST_STATE_LOCK (decode_bin);
  1104 
  1105   GST_DEBUG_OBJECT (decode_bin, "typefind found caps %" GST_PTR_FORMAT, caps);
  1106 
  1107   pad = gst_element_get_pad (typefind, "src");
  1108 
  1109   analyze_new_pad (decode_bin, typefind, pad, caps, NULL);
  1110 
  1111   gst_object_unref (pad);
  1112 
  1113   GST_STATE_UNLOCK (decode_bin);
  1114   return;
  1115 }
  1116 
  1117 static void
  1118 pad_added_group_cb (GstElement * element, GstPad * pad, GstDecodeGroup * group)
  1119 {
  1120   GstCaps *caps;
  1121   gboolean expose = FALSE;
  1122 
  1123   GST_LOG_OBJECT (pad, "pad added, group:%p", group);
  1124 
  1125   caps = gst_pad_get_caps (pad);
  1126   analyze_new_pad (group->dbin, element, pad, caps, group);
  1127   if (caps)
  1128     gst_caps_unref (caps);
  1129 
  1130   GROUP_MUTEX_LOCK (group);
  1131   group->nbdynamic--;
  1132   GST_LOG ("Group %p has now %d dynamic objects", group, group->nbdynamic);
  1133   if (group->nbdynamic == 0)
  1134     expose = TRUE;
  1135   GROUP_MUTEX_UNLOCK (group);
  1136   if (expose) {
  1137     GST_LOG
  1138         ("That was the last dynamic object, now attempting to expose the group");
  1139     DECODE_BIN_LOCK (group->dbin);
  1140     gst_decode_group_expose (group);
  1141     DECODE_BIN_UNLOCK (group->dbin);
  1142   }
  1143 }
  1144 
  1145 static void
  1146 pad_removed_group_cb (GstElement * element, GstPad * pad,
  1147     GstDecodeGroup * group)
  1148 {
  1149   GST_LOG_OBJECT (pad, "pad removed, group:%p", group);
  1150 
  1151   /* In fact, we don't have to do anything here, the active group will be
  1152    * removed when the group's multiqueue is drained */
  1153 }
  1154 
  1155 static void
  1156 no_more_pads_group_cb (GstElement * element, GstDecodeGroup * group)
  1157 {
  1158   GST_LOG_OBJECT (element, "no more pads, setting group %p to complete", group);
  1159 
  1160   /* FIXME : FILLME */
  1161   gst_decode_group_set_complete (group);
  1162 }
  1163 
  1164 static void
  1165 pad_added_cb (GstElement * element, GstPad * pad, GstDecodeBin * dbin)
  1166 {
  1167   GstCaps *caps;
  1168 
  1169   GST_LOG_OBJECT (pad, "Pad added to non-grouped element");
  1170 
  1171   caps = gst_pad_get_caps (pad);
  1172   analyze_new_pad (dbin, element, pad, caps, NULL);
  1173   if (caps)
  1174     gst_caps_unref (caps);
  1175 }
  1176 
  1177 static void
  1178 pad_removed_cb (GstElement * element, GstPad * pad, GstDecodeBin * dbin)
  1179 {
  1180   GST_LOG_OBJECT (pad, "Pad removed from non-grouped element");
  1181 }
  1182 
  1183 static void
  1184 no_more_pads_cb (GstElement * element, GstDecodeBin * dbin)
  1185 {
  1186   GstDecodeGroup *group;
  1187 
  1188   GST_LOG_OBJECT (element, "No more pads, setting current group to complete");
  1189 
  1190   /* Find the non-complete group, there should only be one */
  1191   if (!(group = get_current_group (dbin)))
  1192     goto no_group;
  1193 
  1194   gst_decode_group_set_complete (group);
  1195   return;
  1196 
  1197 no_group:
  1198   {
  1199     GST_WARNING_OBJECT (dbin, "We couldn't find a non-completed group !!");
  1200     return;
  1201   }
  1202 }
  1203 
  1204 /* this function runs through the element factories and returns a list
  1205  * of all elements that are able to sink the given caps 
  1206  */
  1207 static GList *
  1208 find_compatibles (GstDecodeBin * decode_bin, const GstCaps * caps)
  1209 {
  1210   GList *factories;
  1211   GList *to_try = NULL;
  1212 
  1213   /* loop over all the factories */
  1214   for (factories = decode_bin->factories; factories;
  1215       factories = g_list_next (factories)) {
  1216     GstElementFactory *factory = GST_ELEMENT_FACTORY (factories->data);
  1217     const GList *templates;
  1218     GList *walk;
  1219 
  1220     /* get the templates from the element factory */
  1221     templates = gst_element_factory_get_static_pad_templates (factory);
  1222     for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
  1223       GstStaticPadTemplate *templ = walk->data;
  1224 
  1225       /* we only care about the sink templates */
  1226       if (templ->direction == GST_PAD_SINK) {
  1227         GstCaps *intersect;
  1228         GstCaps *tmpl_caps;
  1229 
  1230         /* try to intersect the caps with the caps of the template */
  1231         tmpl_caps = gst_static_caps_get (&templ->static_caps);
  1232 
  1233         intersect = gst_caps_intersect (caps, tmpl_caps);
  1234         gst_caps_unref (tmpl_caps);
  1235 
  1236         /* check if the intersection is empty */
  1237         if (!gst_caps_is_empty (intersect)) {
  1238           /* non empty intersection, we can use this element */
  1239           to_try = g_list_prepend (to_try, factory);
  1240           gst_caps_unref (intersect);
  1241           break;
  1242         }
  1243         gst_caps_unref (intersect);
  1244       }
  1245     }
  1246   }
  1247   to_try = g_list_reverse (to_try);
  1248 
  1249   return to_try;
  1250 }
  1251 
  1252 /* Decide whether an element is a demuxer based on the 
  1253  * klass and number/type of src pad templates it has */
  1254 static gboolean
  1255 is_demuxer_element (GstElement * srcelement)
  1256 {
  1257   GstElementFactory *srcfactory;
  1258   GstElementClass *elemclass;
  1259   GList *templates, *walk;
  1260   const gchar *klass;
  1261   gint potential_src_pads = 0;
  1262 
  1263   srcfactory = gst_element_get_factory (srcelement);
  1264   klass = gst_element_factory_get_klass (srcfactory);
  1265 
  1266   /* Can't be a demuxer unless it has Demux in the klass name */
  1267   if (!strstr (klass, "Demux"))
  1268     return FALSE;
  1269 
  1270   /* Walk the src pad templates and count how many the element
  1271    * might produce */
  1272   elemclass = GST_ELEMENT_GET_CLASS (srcelement);
  1273 
  1274   walk = templates = gst_element_class_get_pad_template_list (elemclass);
  1275   while (walk != NULL) {
  1276     GstPadTemplate *templ;
  1277 
  1278     templ = (GstPadTemplate *) walk->data;
  1279     if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) {
  1280       switch (GST_PAD_TEMPLATE_PRESENCE (templ)) {
  1281         case GST_PAD_ALWAYS:
  1282         case GST_PAD_SOMETIMES:
  1283           if (strstr (GST_PAD_TEMPLATE_NAME_TEMPLATE (templ), "%"))
  1284             potential_src_pads += 2;    /* Might make multiple pads */
  1285           else
  1286             potential_src_pads += 1;
  1287           break;
  1288         case GST_PAD_REQUEST:
  1289           potential_src_pads += 2;
  1290           break;
  1291       }
  1292     }
  1293     walk = g_list_next (walk);
  1294   }
  1295 
  1296   if (potential_src_pads < 2)
  1297     return FALSE;
  1298 
  1299   return TRUE;
  1300 }
  1301 
  1302 /* Returns TRUE if the caps are raw, or if they are compatible with the caps 
  1303  * specified in the 'caps' property 
  1304  * 
  1305  * The decodebin_lock should be taken !
  1306  */
  1307 static gboolean
  1308 are_raw_caps (GstDecodeBin * dbin, GstCaps * caps)
  1309 {
  1310   GstCaps *intersection;
  1311   gboolean res;
  1312 
  1313   GST_LOG_OBJECT (dbin, "Checking with caps %" GST_PTR_FORMAT, caps);
  1314 
  1315   intersection = gst_caps_intersect (dbin->caps, caps);
  1316 
  1317   res = (!(gst_caps_is_empty (intersection)));
  1318 
  1319   gst_caps_unref (intersection);
  1320 
  1321   GST_LOG_OBJECT (dbin, "Caps are %sfinal caps", res ? "" : "not ");
  1322 
  1323   return res;
  1324 }
  1325 
  1326 
  1327 /****
  1328  * GstDecodeGroup functions
  1329  ****/
  1330 
  1331 static void
  1332 multi_queue_overrun_cb (GstElement * queue, GstDecodeGroup * group)
  1333 {
  1334   GST_LOG_OBJECT (group->dbin, "multiqueue is full");
  1335 
  1336   /* if we haven't exposed the group, do it */
  1337   DECODE_BIN_LOCK (group->dbin);
  1338   gst_decode_group_expose (group);
  1339   DECODE_BIN_UNLOCK (group->dbin);
  1340 }
  1341 
  1342 static void
  1343 multi_queue_underrun_cb (GstElement * queue, GstDecodeGroup * group)
  1344 {
  1345   GstDecodeBin *dbin = group->dbin;
  1346 
  1347   GST_LOG_OBJECT (dbin, "multiqueue is empty for group %p", group);
  1348 
  1349   /* Check if we need to activate another group */
  1350   DECODE_BIN_LOCK (dbin);
  1351   if ((group == dbin->activegroup) && dbin->groups) {
  1352     GST_DEBUG_OBJECT (dbin, "Switching to new group");
  1353     /* unexpose current active */
  1354     gst_decode_group_hide (group);
  1355 
  1356     /* expose first group of groups */
  1357     gst_decode_group_expose ((GstDecodeGroup *) dbin->groups->data);
  1358   }
  1359   DECODE_BIN_UNLOCK (dbin);
  1360 }
  1361 
  1362 /* gst_decode_group_new
  1363  *
  1364  * Creates a new GstDecodeGroup. It is up to the caller to add it to the list
  1365  * of groups.
  1366  */
  1367 static GstDecodeGroup *
  1368 gst_decode_group_new (GstDecodeBin * dbin)
  1369 {
  1370   GstDecodeGroup *group;
  1371   GstElement *mq;
  1372 
  1373   GST_LOG_OBJECT (dbin, "Creating new group");
  1374 
  1375   if (!(mq = gst_element_factory_make ("multiqueue", NULL))) {
  1376     GST_WARNING ("Couldn't create multiqueue element");
  1377     return NULL;
  1378   }
  1379 
  1380   g_object_set (G_OBJECT (mq),
  1381       "max-size-bytes", 2 * 1024 * 1024,
  1382       "max-size-time", 5 * GST_SECOND, "max-size-buffers", 0, NULL);
  1383 
  1384   group = g_new0 (GstDecodeGroup, 1);
  1385   group->lock = g_mutex_new ();
  1386   group->dbin = dbin;
  1387   group->multiqueue = mq;
  1388   group->exposed = FALSE;
  1389   group->drained = FALSE;
  1390   group->blocked = FALSE;
  1391   group->complete = FALSE;
  1392   group->endpads = NULL;
  1393 
  1394   group->overrunsig = g_signal_connect (G_OBJECT (mq), "overrun",
  1395       G_CALLBACK (multi_queue_overrun_cb), group);
  1396   group->underrunsig = g_signal_connect (G_OBJECT (mq), "underrun",
  1397       G_CALLBACK (multi_queue_underrun_cb), group);
  1398 
  1399   gst_bin_add (GST_BIN (dbin), group->multiqueue);
  1400   gst_element_set_state (group->multiqueue, GST_STATE_PAUSED);
  1401 
  1402   GST_LOG_OBJECT (dbin, "Returning new group %p", group);
  1403 
  1404   return group;
  1405 }
  1406 
  1407 /** get_current_group:
  1408  *
  1409  * Returns the current non-completed group.
  1410  *
  1411  * Returns NULL if no groups are available, or all groups are completed.
  1412  */
  1413 static GstDecodeGroup *
  1414 get_current_group (GstDecodeBin * dbin)
  1415 {
  1416   GList *tmp;
  1417   GstDecodeGroup *group = NULL;
  1418 
  1419   DECODE_BIN_LOCK (dbin);
  1420   for (tmp = dbin->groups; tmp; tmp = g_list_next (tmp)) {
  1421     GstDecodeGroup *this = (GstDecodeGroup *) tmp->data;
  1422 
  1423     GST_LOG_OBJECT (dbin, "group %p, complete:%d", this, this->complete);
  1424 
  1425     if (!this->complete) {
  1426       group = this;
  1427       break;
  1428     }
  1429   }
  1430   DECODE_BIN_UNLOCK (dbin);
  1431 
  1432   GST_LOG_OBJECT (dbin, "Returning group %p", group);
  1433 
  1434   return group;
  1435 }
  1436 
  1437 static gboolean
  1438 group_demuxer_event_probe (GstPad * pad, GstEvent * event,
  1439     GstDecodeGroup * group)
  1440 {
  1441   if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
  1442     GST_DEBUG_OBJECT (group->dbin,
  1443         "Got EOS on group input pads, exposing group if it wasn't before");
  1444     DECODE_BIN_LOCK (group->dbin);
  1445     gst_decode_group_expose (group);
  1446     DECODE_BIN_UNLOCK (group->dbin);
  1447   }
  1448   return TRUE;
  1449 }
  1450 
  1451 /* gst_decode_group_control_demuxer_pad
  1452  *
  1453  * Adds a new demuxer srcpad to the given group.
  1454  *
  1455  * Returns the srcpad of the multiqueue corresponding the given pad.
  1456  * Returns NULL if there was an error.
  1457  */
  1458 static GstPad *
  1459 gst_decode_group_control_demuxer_pad (GstDecodeGroup * group, GstPad * pad)
  1460 {
  1461   GstPad *srcpad, *sinkpad;
  1462   gchar *nb, *sinkname, *srcname;
  1463 
  1464   GST_LOG ("group:%p pad %s:%s", group, GST_DEBUG_PAD_NAME (pad));
  1465 
  1466   srcpad = NULL;
  1467 
  1468   if (!(sinkpad = gst_element_get_pad (group->multiqueue, "sink%d"))) {
  1469     GST_ERROR ("Couldn't get sinkpad from multiqueue");
  1470     return NULL;
  1471   }
  1472 
  1473   if ((gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)) {
  1474     GST_ERROR ("Couldn't link demuxer and multiqueue");
  1475     goto beach;
  1476   }
  1477 
  1478   sinkname = gst_pad_get_name (sinkpad);
  1479   nb = sinkname + 4;
  1480   srcname = g_strdup_printf ("src%s", nb);
  1481   g_free (sinkname);
  1482 
  1483   GROUP_MUTEX_LOCK (group);
  1484 
  1485   if (!(srcpad = gst_element_get_pad (group->multiqueue, srcname))) {
  1486     GST_ERROR ("Couldn't get srcpad %s from multiqueue", srcname);
  1487     goto chiringuito;
  1488   }
  1489 
  1490   /* connect event handler on pad to intercept EOS events */
  1491   gst_pad_add_event_probe (pad, G_CALLBACK (group_demuxer_event_probe), group);
  1492 
  1493 chiringuito:
  1494   g_free (srcname);
  1495   GROUP_MUTEX_UNLOCK (group);
  1496 
  1497 beach:
  1498   gst_object_unref (sinkpad);
  1499   return srcpad;
  1500 }
  1501 
  1502 static gboolean
  1503 gst_decode_group_control_source_pad (GstDecodeGroup * group, GstPad * pad)
  1504 {
  1505   GstDecodePad *dpad;
  1506 
  1507   g_return_val_if_fail (group != NULL, FALSE);
  1508 
  1509   GST_LOG ("group:%p , pad %s:%s", group, GST_DEBUG_PAD_NAME (pad));
  1510 
  1511   /* FIXME : check if pad is already controlled */
  1512 
  1513   GROUP_MUTEX_LOCK (group);
  1514 
  1515   /* Create GstDecodePad for the pad */
  1516   dpad = gst_decode_pad_new (group, pad, TRUE);
  1517 
  1518   group->endpads = g_list_append (group->endpads, dpad);
  1519 
  1520   GROUP_MUTEX_UNLOCK (group);
  1521 
  1522   return TRUE;
  1523 }
  1524 
  1525 /* gst_decode_group_check_if_blocked:
  1526  *
  1527  * Call this when one of the pads blocked status has changed.
  1528  * If the group is complete and blocked, the group will be marked as blocked
  1529  * and will ghost/expose all pads on decodebin if the group is the current one.
  1530  *
  1531  * Call with the group lock taken ! MT safe
  1532  */
  1533 static void
  1534 gst_decode_group_check_if_blocked (GstDecodeGroup * group)
  1535 {
  1536   GList *tmp;
  1537   gboolean blocked = TRUE;
  1538 
  1539   GST_LOG ("group : %p , ->complete:%d , ->nbdynamic:%d",
  1540       group, group->complete, group->nbdynamic);
  1541 
  1542   /* 1. don't do anything if group is not complete */
  1543   if (!group->complete || group->nbdynamic) {
  1544     GST_DEBUG_OBJECT (group->dbin, "Group isn't complete yet");
  1545     return;
  1546   }
  1547 
  1548   for (tmp = group->endpads; tmp; tmp = g_list_next (tmp)) {
  1549     GstDecodePad *dpad = (GstDecodePad *) tmp->data;
  1550 
  1551     if (!dpad->blocked) {
  1552       blocked = FALSE;
  1553       break;
  1554     }
  1555   }
  1556 
  1557   /* 2. Update status of group */
  1558   group->blocked = blocked;
  1559   GST_LOG ("group is blocked:%d", blocked);
  1560 
  1561   /* 3. don't do anything if not blocked completely */
  1562   if (!blocked)
  1563     return;
  1564 
  1565   /* 4. if we're the current group, expose pads */
  1566   DECODE_BIN_LOCK (group->dbin);
  1567   if (!gst_decode_group_expose (group))
  1568     GST_WARNING_OBJECT (group->dbin, "Couldn't expose group");
  1569   DECODE_BIN_UNLOCK (group->dbin);
  1570 }
  1571 
  1572 static void
  1573 gst_decode_group_check_if_drained (GstDecodeGroup * group)
  1574 {
  1575   GList *tmp;
  1576   GstDecodeBin *dbin = group->dbin;
  1577   gboolean drained = TRUE;
  1578 
  1579   GST_LOG ("group : %p", group);
  1580 
  1581   for (tmp = group->endpads; tmp; tmp = g_list_next (tmp)) {
  1582     GstDecodePad *dpad = (GstDecodePad *) tmp->data;
  1583 
  1584     GST_LOG ("testing dpad %p", dpad);
  1585 
  1586     if (!dpad->drained) {
  1587       drained = FALSE;
  1588       break;
  1589     }
  1590   }
  1591 
  1592   group->drained = drained;
  1593   GST_LOG ("group is drained");
  1594 
  1595   if (!drained)
  1596     return;
  1597 
  1598   DECODE_BIN_LOCK (dbin);
  1599   if ((group == dbin->activegroup) && dbin->groups) {
  1600     GST_DEBUG_OBJECT (dbin, "Switching to new group");
  1601 
  1602     gst_decode_group_hide (group);
  1603 
  1604     gst_decode_group_expose ((GstDecodeGroup *) dbin->groups->data);
  1605   }
  1606   DECODE_BIN_UNLOCK (dbin);
  1607 }
  1608 
  1609 /* sort_end_pads:
  1610  * GCompareFunc to use with lists of GstPad.
  1611  * Sorts pads by mime type.
  1612  * First video (raw, then non-raw), then audio (raw, then non-raw),
  1613  * then others.
  1614  *
  1615  * Return: negative if a<b, 0 if a==b, positive if a>b
  1616  */
  1617 
  1618 static gint
  1619 sort_end_pads (GstDecodePad * da, GstDecodePad * db)
  1620 {
  1621   GstPad *a, *b;
  1622   gint va, vb;
  1623   GstCaps *capsa, *capsb;
  1624   GstStructure *sa, *sb;
  1625   const gchar *namea, *nameb;
  1626 
  1627   a = da->pad;
  1628   b = db->pad;
  1629 
  1630   capsa = gst_pad_get_caps (a);
  1631   capsb = gst_pad_get_caps (b);
  1632 
  1633   sa = gst_caps_get_structure ((const GstCaps *) capsa, 0);
  1634   sb = gst_caps_get_structure ((const GstCaps *) capsb, 0);
  1635 
  1636   namea = gst_structure_get_name (sa);
  1637   nameb = gst_structure_get_name (sb);
  1638 
  1639   if (g_strrstr (namea, "video/x-raw-"))
  1640     va = 0;
  1641   else if (g_strrstr (namea, "video/"))
  1642     va = 1;
  1643   else if (g_strrstr (namea, "audio/x-raw"))
  1644     va = 2;
  1645   else if (g_strrstr (namea, "audio/"))
  1646     va = 3;
  1647   else
  1648     va = 4;
  1649 
  1650   if (g_strrstr (nameb, "video/x-raw-"))
  1651     vb = 0;
  1652   else if (g_strrstr (nameb, "video/"))
  1653     vb = 1;
  1654   else if (g_strrstr (nameb, "audio/x-raw"))
  1655     vb = 2;
  1656   else if (g_strrstr (nameb, "audio/"))
  1657     vb = 3;
  1658   else
  1659     vb = 4;
  1660 
  1661   gst_caps_unref (capsa);
  1662   gst_caps_unref (capsb);
  1663 
  1664   return va - vb;
  1665 }
  1666 
  1667 /* gst_decode_group_expose:
  1668  *
  1669  * Expose this group's pads.
  1670  *
  1671  * Not MT safe, please take the group lock
  1672  */
  1673 
  1674 static gboolean
  1675 gst_decode_group_expose (GstDecodeGroup * group)
  1676 {
  1677   GList *tmp;
  1678   GList *next = NULL;
  1679 
  1680   if (group->dbin->activegroup) {
  1681     GST_DEBUG_OBJECT (group->dbin, "A group is already active and exposed");
  1682     return TRUE;
  1683   }
  1684 
  1685   if (group->dbin->activegroup == group) {
  1686     GST_WARNING ("Group %p is already exposed", group);
  1687     return TRUE;
  1688   }
  1689 
  1690   if (!group->dbin->groups
  1691       || (group != (GstDecodeGroup *) group->dbin->groups->data)) {
  1692     GST_WARNING ("Group %p is not the first group to expose", group);
  1693     return FALSE;
  1694   }
  1695 
  1696   if (group->nbdynamic) {
  1697     GST_WARNING ("Group %p still has %d dynamic objects, not exposing yet",
  1698         group, group->nbdynamic);
  1699     return FALSE;
  1700   }
  1701 
  1702   GST_LOG ("Exposing group %p", group);
  1703 
  1704   /* re-order pads : video, then audio, then others */
  1705   group->endpads = g_list_sort (group->endpads, (GCompareFunc) sort_end_pads);
  1706 
  1707   /* Expose pads */
  1708 
  1709   for (tmp = group->endpads; tmp; tmp = next) {
  1710     GstDecodePad *dpad = (GstDecodePad *) tmp->data;
  1711     gchar *padname;
  1712     GstPad *ghost;
  1713 
  1714     next = g_list_next (tmp);
  1715 
  1716     /* 1. ghost pad */
  1717     padname = g_strdup_printf ("src%d", group->dbin->nbpads);
  1718     group->dbin->nbpads++;
  1719 
  1720     GST_LOG_OBJECT (group->dbin, "About to expose pad %s:%s",
  1721         GST_DEBUG_PAD_NAME (dpad->pad));
  1722 
  1723     ghost = gst_ghost_pad_new (padname, dpad->pad);
  1724     gst_pad_set_active (ghost, TRUE);
  1725     gst_element_add_pad (GST_ELEMENT (group->dbin), ghost);
  1726     group->ghosts = g_list_append (group->ghosts, ghost);
  1727 
  1728     g_free (padname);
  1729 
  1730     /* 2. emit signal */
  1731     GST_DEBUG_OBJECT (group->dbin, "emitting new-decoded-pad");
  1732     g_signal_emit (G_OBJECT (group->dbin),
  1733         gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD], 0, ghost,
  1734         (next == NULL));
  1735     GST_DEBUG_OBJECT (group->dbin, "emitted new-decoded-pad");
  1736 
  1737     /* 3. Unblock internal  pad */
  1738     GST_DEBUG_OBJECT (dpad->pad, "unblocking");
  1739     gst_pad_set_blocked_async (dpad->pad, FALSE,
  1740         (GstPadBlockCallback) source_pad_blocked_cb, dpad);
  1741     GST_DEBUG_OBJECT (dpad->pad, "unblocked");
  1742 
  1743   }
  1744 
  1745   group->dbin->activegroup = group;
  1746 
  1747   /* pop off the first group */
  1748   group->dbin->groups =
  1749       g_list_delete_link (group->dbin->groups, group->dbin->groups);
  1750 
  1751   remove_fakesink (group->dbin);
  1752 
  1753   group->exposed = TRUE;
  1754 
  1755   GST_LOG_OBJECT (group->dbin, "signalling no-more-pads");
  1756   gst_element_no_more_pads (GST_ELEMENT (group->dbin));
  1757 
  1758   GST_LOG_OBJECT (group->dbin, "Group %p exposed", group);
  1759   return TRUE;
  1760 }
  1761 
  1762 static void
  1763 gst_decode_group_hide (GstDecodeGroup * group)
  1764 {
  1765   GList *tmp;
  1766 
  1767   GST_LOG ("Hiding group %p", group);
  1768 
  1769   if (group != group->dbin->activegroup) {
  1770     GST_WARNING ("This group is not the active one, aborting");
  1771     return;
  1772   }
  1773 
  1774   GROUP_MUTEX_LOCK (group);
  1775 
  1776   /* Remove ghost pads */
  1777   for (tmp = group->ghosts; tmp; tmp = g_list_next (tmp))
  1778     gst_element_remove_pad (GST_ELEMENT (group->dbin), (GstPad *) tmp->data);
  1779 
  1780   g_list_free (group->ghosts);
  1781   group->ghosts = NULL;
  1782 
  1783   group->exposed = FALSE;
  1784 
  1785   GROUP_MUTEX_UNLOCK (group);
  1786 
  1787   group->dbin->activegroup = NULL;
  1788   group->dbin->oldgroups = g_list_append (group->dbin->oldgroups, group);
  1789 }
  1790 
  1791 static void
  1792 deactivate_free_recursive (GstDecodeGroup * group, GstElement * element)
  1793 {
  1794   GstIterator *it;
  1795   GstIteratorResult res;
  1796   gpointer point;
  1797 
  1798   GST_LOG ("element:%s", GST_ELEMENT_NAME (element));
  1799 
  1800   /* call on downstream elements */
  1801   it = gst_element_iterate_src_pads (element);
  1802 
  1803 restart:
  1804 
  1805   while (1) {
  1806     res = gst_iterator_next (it, &point);
  1807     switch (res) {
  1808       case GST_ITERATOR_DONE:
  1809         goto done;
  1810       case GST_ITERATOR_RESYNC:
  1811         gst_iterator_resync (it);
  1812         goto restart;
  1813       case GST_ITERATOR_ERROR:
  1814       {
  1815         GST_WARNING ("Had an error while iterating source pads of element: %s",
  1816             GST_ELEMENT_NAME (element));
  1817         goto beach;
  1818       }
  1819       case GST_ITERATOR_OK:
  1820       {
  1821         GstPad *pad = GST_PAD (point);
  1822         GstPad *peerpad = NULL;
  1823 
  1824         if ((peerpad = gst_pad_get_peer (pad))) {
  1825           GstObject *parent = gst_pad_get_parent (peerpad);
  1826 
  1827           if (parent && GST_IS_ELEMENT (parent))
  1828             deactivate_free_recursive (group, GST_ELEMENT (parent));
  1829           if (parent)
  1830             gst_object_unref (parent);
  1831         }
  1832       }
  1833         break;
  1834       default:
  1835         break;
  1836     }
  1837   }
  1838 
  1839 done:
  1840   gst_element_set_state (element, GST_STATE_NULL);
  1841   gst_bin_remove (GST_BIN (group->dbin), element);
  1842 
  1843 beach:
  1844   gst_iterator_free (it);
  1845 
  1846   return;
  1847 }
  1848 
  1849 static void
  1850 gst_decode_group_free (GstDecodeGroup * group)
  1851 {
  1852   GList *tmp;
  1853 
  1854   GST_LOG ("group %p", group);
  1855 
  1856   GROUP_MUTEX_LOCK (group);
  1857   /* Clear all GstDecodePad */
  1858   for (tmp = group->endpads; tmp; tmp = g_list_next (tmp)) {
  1859     GstDecodePad *dpad = (GstDecodePad *) tmp->data;
  1860 
  1861     g_free (dpad);
  1862   }
  1863   g_list_free (group->endpads);
  1864   group->endpads = NULL;
  1865 
  1866   /* disconnect signal handlers on multiqueue */
  1867   g_signal_handler_disconnect (group->multiqueue, group->underrunsig);
  1868   g_signal_handler_disconnect (group->multiqueue, group->overrunsig);
  1869 
  1870   /* remove all elements */
  1871   deactivate_free_recursive (group, group->multiqueue);
  1872 
  1873   GROUP_MUTEX_UNLOCK (group);
  1874 
  1875   g_mutex_free (group->lock);
  1876   g_free (group);
  1877 }
  1878 
  1879 /* gst_decode_group_set_complete:
  1880  *
  1881  * Mark the group as complete. This means no more streams will be controlled
  1882  * through this group.
  1883  *
  1884  * MT safe
  1885  */
  1886 static void
  1887 gst_decode_group_set_complete (GstDecodeGroup * group)
  1888 {
  1889   GST_LOG_OBJECT (group->dbin, "Setting group %p to COMPLETE", group);
  1890 
  1891   GROUP_MUTEX_LOCK (group);
  1892   group->complete = TRUE;
  1893   gst_decode_group_check_if_blocked (group);
  1894   GROUP_MUTEX_UNLOCK (group);
  1895 }
  1896 
  1897 
  1898 
  1899 /*************************
  1900  * GstDecodePad functions
  1901  *************************/
  1902 
  1903 static void
  1904 source_pad_blocked_cb (GstPad * pad, gboolean blocked, GstDecodePad * dpad)
  1905 {
  1906   GST_LOG_OBJECT (pad, "blocked:%d , dpad:%p, dpad->group:%p",
  1907       blocked, dpad, dpad->group);
  1908 
  1909   /* Update this GstDecodePad status */
  1910   dpad->blocked = blocked;
  1911 
  1912   if (blocked) {
  1913     GROUP_MUTEX_LOCK (dpad->group);
  1914     gst_decode_group_check_if_blocked (dpad->group);
  1915     GROUP_MUTEX_UNLOCK (dpad->group);
  1916   }
  1917 }
  1918 
  1919 static gboolean
  1920 source_pad_event_probe (GstPad * pad, GstEvent * event, GstDecodePad * dpad)
  1921 {
  1922   GST_LOG_OBJECT (pad, "%s dpad:%p", GST_EVENT_TYPE_NAME (event), dpad);
  1923 
  1924   if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
  1925     /* Set our pad as drained */
  1926     dpad->drained = TRUE;
  1927 
  1928     /* Check if all pads are drained */
  1929     gst_decode_group_check_if_drained (dpad->group);
  1930   }
  1931 
  1932   return TRUE;
  1933 }
  1934 
  1935 /*gst_decode_pad_new:
  1936  *
  1937  * Creates a new GstDecodePad for the given pad.
  1938  * If block is TRUE, Sets the pad blocking asynchronously
  1939  */
  1940 
  1941 static GstDecodePad *
  1942 gst_decode_pad_new (GstDecodeGroup * group, GstPad * pad, gboolean block)
  1943 {
  1944   GstDecodePad *dpad;
  1945 
  1946   dpad = g_new0 (GstDecodePad, 1);
  1947   dpad->pad = pad;
  1948   dpad->group = group;
  1949   dpad->blocked = FALSE;
  1950   dpad->drained = TRUE;
  1951 
  1952   if (block)
  1953     gst_pad_set_blocked_async (pad, TRUE,
  1954         (GstPadBlockCallback) source_pad_blocked_cb, dpad);
  1955   gst_pad_add_event_probe (pad, G_CALLBACK (source_pad_event_probe), dpad);
  1956   return dpad;
  1957 }
  1958 
  1959 
  1960 /*****
  1961  * Element add/remove
  1962  *****/
  1963 
  1964 /*
  1965  * add_fakesink / remove_fakesink
  1966  *
  1967  * We use a sink so that the parent ::change_state returns GST_STATE_CHANGE_ASYNC
  1968  * when that sink is present (since it's not connected to anything it will 
  1969  * always return GST_STATE_CHANGE_ASYNC).
  1970  *
  1971  * But this is an ugly way of achieving this goal.
  1972  * Ideally, we shouldn't use a sink and just return GST_STATE_CHANGE_ASYNC in
  1973  * our ::change_state if we have not exposed the active group.
  1974  * We also need to override ::get_state to fake the asynchronous behaviour.
  1975  * Once the active group is exposed, we would then post a
  1976  * GST_MESSAGE_STATE_DIRTY and return GST_STATE_CHANGE_SUCCESS (which will call
  1977  * ::get_state .
  1978  */
  1979 
  1980 static gboolean
  1981 add_fakesink (GstDecodeBin * decode_bin)
  1982 {
  1983   GST_DEBUG_OBJECT (decode_bin, "Adding the fakesink");
  1984 
  1985   if (decode_bin->fakesink)
  1986     return TRUE;
  1987 
  1988   decode_bin->fakesink =
  1989       gst_element_factory_make ("fakesink", "async-fakesink");
  1990   if (!decode_bin->fakesink)
  1991     goto no_fakesink;
  1992 
  1993   /* hacky, remove sink flag, we don't want our decodebin to become a sink
  1994    * just because we add a fakesink element to make us ASYNC */
  1995   GST_OBJECT_FLAG_UNSET (decode_bin->fakesink, GST_ELEMENT_IS_SINK);
  1996 
  1997   if (!gst_bin_add (GST_BIN (decode_bin), decode_bin->fakesink))
  1998     goto could_not_add;
  1999 
  2000   return TRUE;
  2001 
  2002   /* ERRORS */
  2003 no_fakesink:
  2004   {
  2005     g_warning ("can't find fakesink element, decodebin will not work");
  2006     return FALSE;
  2007   }
  2008 could_not_add:
  2009   {
  2010     g_warning ("Could not add fakesink to decodebin, decodebin will not work");
  2011     gst_object_unref (decode_bin->fakesink);
  2012     decode_bin->fakesink = NULL;
  2013     return FALSE;
  2014   }
  2015 }
  2016 
  2017 static void
  2018 remove_fakesink (GstDecodeBin * decode_bin)
  2019 {
  2020   if (decode_bin->fakesink == NULL)
  2021     return;
  2022 
  2023   GST_DEBUG_OBJECT (decode_bin, "Removing the fakesink");
  2024 
  2025   gst_element_set_state (decode_bin->fakesink, GST_STATE_NULL);
  2026   gst_bin_remove (GST_BIN (decode_bin), decode_bin->fakesink);
  2027   decode_bin->fakesink = NULL;
  2028 
  2029   gst_element_post_message (GST_ELEMENT_CAST (decode_bin),
  2030       gst_message_new_state_dirty (GST_OBJECT_CAST (decode_bin)));
  2031 }
  2032 
  2033 /*****
  2034  * convenience functions
  2035  *****/
  2036 
  2037 /* find_sink_pad
  2038  *
  2039  * Returns the first sink pad of the given element, or NULL if it doesn't have
  2040  * any.
  2041  */
  2042 
  2043 static GstPad *
  2044 find_sink_pad (GstElement * element)
  2045 {
  2046   GstIterator *it;
  2047   GstPad *pad = NULL;
  2048   gpointer point;
  2049 
  2050   it = gst_element_iterate_sink_pads (element);
  2051 
  2052   if ((gst_iterator_next (it, &point)) == GST_ITERATOR_OK)
  2053     pad = (GstPad *) point;
  2054 
  2055   gst_iterator_free (it);
  2056 
  2057   return pad;
  2058 }
  2059 
  2060 static GstStateChangeReturn
  2061 gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
  2062 {
  2063   GstStateChangeReturn ret;
  2064   GstDecodeBin *dbin = GST_DECODE_BIN (element);
  2065 
  2066   switch (transition) {
  2067     case GST_STATE_CHANGE_NULL_TO_READY:
  2068       if (dbin->typefind == NULL)
  2069         goto missing_typefind;
  2070       break;
  2071     case GST_STATE_CHANGE_READY_TO_PAUSED:{
  2072       if (!add_fakesink (dbin))
  2073         goto missing_fakesink;
  2074       break;
  2075     }
  2076     default:
  2077       break;
  2078   }
  2079 
  2080   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
  2081 
  2082   /* FIXME : put some cleanup functions here.. if needed */
  2083 
  2084   return ret;
  2085 
  2086 /* ERRORS */
  2087 missing_typefind:
  2088   {
  2089     GST_ELEMENT_ERROR (dbin, CORE, MISSING_PLUGIN, (NULL), ("no typefind!"));
  2090     return GST_STATE_CHANGE_FAILURE;
  2091   }
  2092 missing_fakesink:
  2093   {
  2094     GST_ELEMENT_ERROR (dbin, CORE, MISSING_PLUGIN, (NULL), ("no fakesink!"));
  2095     return GST_STATE_CHANGE_FAILURE;
  2096   }
  2097 }
  2098 
  2099 static gboolean
  2100 plugin_init (GstPlugin * plugin)
  2101 {
  2102   GST_DEBUG_CATEGORY_INIT (gst_decode_bin_debug, "decodebin2", 0,
  2103       "decoder bin");
  2104 
  2105   return gst_element_register (plugin, "decodebin2", GST_RANK_NONE,
  2106       GST_TYPE_DECODE_BIN);
  2107 }
  2108 
  2109 GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
  2110     GST_VERSION_MINOR,
  2111     "decodebin2",
  2112     "decoder bin newer version", plugin_init, VERSION, GST_LICENSE,
  2113     GST_PACKAGE_NAME, GST_PACKAGE_ORIGIN)