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