playsink: Chain up to the parent's GstBin::handle_message() for non-prepare-xoverlay...
[platform/upstream/gstreamer.git] / gst / playback / gstplaybasebin.c
1 /* GStreamer
2  * Copyright (C) <2007> Wim Taymans <wim.taymans@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /* FIXME 0.11: suppress warnings for deprecated API such as GValueArray
21  * with newer GLib versions (>= 2.31.0) */
22 #define GLIB_DISABLE_DEPRECATION_WARNINGS
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <gst/gst-i18n-plugin.h>
29 #include <string.h>
30 #include "gstplaybasebin.h"
31 #include "gststreamselector.h"
32 #include "gstplay-marshal.h"
33
34 #include <gst/pbutils/pbutils.h>
35
36 #include "gst/glib-compat-private.h"
37
38 GST_DEBUG_CATEGORY_STATIC (gst_play_base_bin_debug);
39 #define GST_CAT_DEFAULT gst_play_base_bin_debug
40
41 #define DEFAULT_QUEUE_SIZE          (3 * GST_SECOND)
42 #define DEFAULT_QUEUE_MIN_THRESHOLD ((DEFAULT_QUEUE_SIZE * 30) / 100)
43 #define DEFAULT_QUEUE_THRESHOLD     ((DEFAULT_QUEUE_SIZE * 95) / 100)
44 #define DEFAULT_CONNECTION_SPEED    0
45
46 #define GROUP_LOCK(pbb) g_mutex_lock (pbb->group_lock)
47 #define GROUP_UNLOCK(pbb) g_mutex_unlock (pbb->group_lock)
48 #define GROUP_WAIT(pbb) g_cond_wait (pbb->group_cond, pbb->group_lock)
49 #define GROUP_SIGNAL(pbb) g_cond_signal (pbb->group_cond)
50
51 /* props */
52 enum
53 {
54   ARG_0,
55   ARG_URI,
56   ARG_SUBURI,
57   ARG_QUEUE_SIZE,
58   ARG_QUEUE_THRESHOLD,
59   ARG_QUEUE_MIN_THRESHOLD,
60   ARG_NSTREAMS,
61   ARG_STREAMINFO,
62   ARG_STREAMINFO_VALUES,
63   ARG_SOURCE,
64   ARG_VIDEO,
65   ARG_AUDIO,
66   ARG_TEXT,
67   ARG_SUBTITLE_ENCODING,
68   ARG_CONNECTION_SPEED
69 };
70
71 static void gst_play_base_bin_class_init (GstPlayBaseBinClass * klass);
72 static void gst_play_base_bin_init (GstPlayBaseBin * play_base_bin);
73 static void gst_play_base_bin_dispose (GObject * object);
74 static void gst_play_base_bin_finalize (GObject * object);
75
76 static void gst_play_base_bin_set_property (GObject * object, guint prop_id,
77     const GValue * value, GParamSpec * spec);
78 static void gst_play_base_bin_get_property (GObject * object, guint prop_id,
79     GValue * value, GParamSpec * spec);
80 static void gst_play_base_bin_handle_message_func (GstBin * bin,
81     GstMessage * msg);
82
83 static GstStateChangeReturn gst_play_base_bin_change_state (GstElement *
84     element, GstStateChange transition);
85
86 static const GList *gst_play_base_bin_get_streaminfo (GstPlayBaseBin * bin);
87 static GValueArray *gst_play_base_bin_get_streaminfo_value_array (GstPlayBaseBin
88     * play_base_bin);
89 static void preroll_remove_overrun (GstElement * element,
90     GstPlayBaseBin * play_base_bin);
91 static void queue_remove_probe (GstElement * queue, GstPlayBaseBin
92     * play_base_bin);
93
94 static GstElement *make_decoder (GstPlayBaseBin * play_base_bin);
95 static gboolean has_all_raw_caps (GstPad * pad, gboolean * all_raw);
96
97 static gboolean prepare_output (GstPlayBaseBin * play_base_bin);
98 static void set_active_source (GstPlayBaseBin * play_base_bin,
99     GstStreamType type, gint source_num);
100 static gboolean probe_triggered (GstPad * pad, GstEvent * event,
101     gpointer user_data);
102 static void setup_substreams (GstPlayBaseBin * play_base_bin);
103
104 static GstPipelineClass *parent_class;
105
106 /*
107  * GObject playbasebin wrappers.
108  */
109
110 GType
111 gst_play_base_bin_get_type (void)
112 {
113   static GType gst_play_base_bin_type = 0;
114
115   if (!gst_play_base_bin_type) {
116     static const GTypeInfo gst_play_base_bin_info = {
117       sizeof (GstPlayBaseBinClass),
118       NULL,
119       NULL,
120       (GClassInitFunc) gst_play_base_bin_class_init,
121       NULL,
122       NULL,
123       sizeof (GstPlayBaseBin),
124       0,
125       (GInstanceInitFunc) gst_play_base_bin_init,
126       NULL
127     };
128
129     gst_play_base_bin_type = g_type_register_static (GST_TYPE_PIPELINE,
130         "GstPlayBaseBin", &gst_play_base_bin_info, 0);
131   }
132
133   return gst_play_base_bin_type;
134 }
135
136 static void
137 gst_play_base_bin_class_init (GstPlayBaseBinClass * klass)
138 {
139   GObjectClass *gobject_klass;
140   GstElementClass *gstelement_klass;
141   GstBinClass *gstbin_klass;
142
143   gobject_klass = (GObjectClass *) klass;
144   gstelement_klass = (GstElementClass *) klass;
145   gstbin_klass = (GstBinClass *) klass;
146
147   parent_class = g_type_class_peek_parent (klass);
148
149   gobject_klass->set_property = gst_play_base_bin_set_property;
150   gobject_klass->get_property = gst_play_base_bin_get_property;
151
152   g_object_class_install_property (gobject_klass, ARG_URI,
153       g_param_spec_string ("uri", "URI", "URI of the media to play",
154           NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
155   g_object_class_install_property (gobject_klass, ARG_SUBURI,
156       g_param_spec_string ("suburi", ".sub-URI", "Optional URI of a subtitle",
157           NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
158
159   g_object_class_install_property (gobject_klass, ARG_QUEUE_SIZE,
160       g_param_spec_uint64 ("queue-size", "Queue size",
161           "Size of internal queues in nanoseconds", 0, G_MAXINT64,
162           DEFAULT_QUEUE_SIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
163   g_object_class_install_property (gobject_klass, ARG_QUEUE_THRESHOLD,
164       g_param_spec_uint64 ("queue-threshold", "Queue threshold",
165           "Buffering threshold of internal queues in nanoseconds", 0,
166           G_MAXINT64, DEFAULT_QUEUE_THRESHOLD,
167           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
168   g_object_class_install_property (gobject_klass, ARG_QUEUE_MIN_THRESHOLD,
169       g_param_spec_uint64 ("queue-min-threshold", "Queue min threshold",
170           "Buffering low threshold of internal queues in nanoseconds", 0,
171           G_MAXINT64, DEFAULT_QUEUE_MIN_THRESHOLD,
172           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
173
174   g_object_class_install_property (gobject_klass, ARG_NSTREAMS,
175       g_param_spec_int ("nstreams", "NStreams", "number of streams",
176           0, G_MAXINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
177   g_object_class_install_property (gobject_klass, ARG_STREAMINFO,
178       g_param_spec_pointer ("stream-info", "Stream info", "List of streaminfo",
179           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
180   g_object_class_install_property (gobject_klass, ARG_STREAMINFO_VALUES,
181       g_param_spec_value_array ("stream-info-value-array",
182           "StreamInfo GValueArray", "value array of streaminfo",
183           g_param_spec_object ("streaminfo", "StreamInfo", "Streaminfo object",
184               GST_TYPE_STREAM_INFO, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS),
185           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
186   g_object_class_install_property (gobject_klass, ARG_SOURCE,
187       g_param_spec_object ("source", "Source", "Source element",
188           GST_TYPE_ELEMENT, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
189
190   g_object_class_install_property (gobject_klass, ARG_VIDEO,
191       g_param_spec_int ("current-video", "Current video",
192           "Currently playing video stream (-1 = none)",
193           -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
194   g_object_class_install_property (gobject_klass, ARG_AUDIO,
195       g_param_spec_int ("current-audio", "Current audio",
196           "Currently playing audio stream (-1 = none)",
197           -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
198   g_object_class_install_property (gobject_klass, ARG_TEXT,
199       g_param_spec_int ("current-text", "Current text",
200           "Currently playing text stream (-1 = none)",
201           -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
202   g_object_class_install_property (gobject_klass, ARG_SUBTITLE_ENCODING,
203       g_param_spec_string ("subtitle-encoding", "subtitle encoding",
204           "Encoding to assume if input subtitles are not in UTF-8 encoding. "
205           "If not set, the GST_SUBTITLE_ENCODING environment variable will "
206           "be checked for an encoding to use. If that is not set either, "
207           "ISO-8859-15 will be assumed.", NULL,
208           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
209   /**
210    * GstPlayBaseBin:connection-speed
211    *
212    * Network connection speed in kbps (0 = unknown)
213    * <note><simpara>
214    * Since version 0.10.10 in #GstPlayBin, at 0.10.15 moved to #GstPlayBaseBin
215    * </simpara></note>
216    *
217    * Since: 0.10.10
218    */
219   g_object_class_install_property (gobject_klass, ARG_CONNECTION_SPEED,
220       g_param_spec_uint ("connection-speed", "Connection Speed",
221           "Network connection speed in kbps (0 = unknown)",
222           0, G_MAXUINT, DEFAULT_CONNECTION_SPEED,
223           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
224
225   GST_DEBUG_CATEGORY_INIT (gst_play_base_bin_debug, "playbasebin", 0,
226       "playbasebin");
227
228   gobject_klass->dispose = gst_play_base_bin_dispose;
229   gobject_klass->finalize = gst_play_base_bin_finalize;
230
231   gstbin_klass->handle_message =
232       GST_DEBUG_FUNCPTR (gst_play_base_bin_handle_message_func);
233
234   gstelement_klass->change_state =
235       GST_DEBUG_FUNCPTR (gst_play_base_bin_change_state);
236 }
237
238 static void
239 gst_play_base_bin_init (GstPlayBaseBin * play_base_bin)
240 {
241   play_base_bin->uri = NULL;
242   play_base_bin->suburi = NULL;
243   play_base_bin->need_rebuild = TRUE;
244   play_base_bin->is_stream = FALSE;
245   play_base_bin->source = NULL;
246   play_base_bin->decoders = NULL;
247   play_base_bin->subtitle = NULL;
248   play_base_bin->subencoding = NULL;
249   play_base_bin->subtitle_elements = NULL;
250   play_base_bin->sub_lock = g_mutex_new ();
251
252   play_base_bin->group_lock = g_mutex_new ();
253   play_base_bin->group_cond = g_cond_new ();
254
255   play_base_bin->building_group = NULL;
256   play_base_bin->queued_groups = NULL;
257
258   play_base_bin->queue_size = DEFAULT_QUEUE_SIZE;
259   play_base_bin->queue_threshold = DEFAULT_QUEUE_THRESHOLD;
260   play_base_bin->queue_min_threshold = DEFAULT_QUEUE_MIN_THRESHOLD;
261   play_base_bin->connection_speed = DEFAULT_CONNECTION_SPEED;
262 }
263
264 static void
265 gst_play_base_bin_dispose (GObject * object)
266 {
267   GstPlayBaseBin *play_base_bin;
268
269   play_base_bin = GST_PLAY_BASE_BIN (object);
270   g_free (play_base_bin->uri);
271   play_base_bin->uri = NULL;
272   g_free (play_base_bin->suburi);
273   play_base_bin->suburi = NULL;
274   g_free (play_base_bin->subencoding);
275   play_base_bin->subencoding = NULL;
276   if (play_base_bin->subtitle_elements) {
277     g_slist_free (play_base_bin->subtitle_elements);
278     play_base_bin->subtitle_elements = NULL;
279   }
280   G_OBJECT_CLASS (parent_class)->dispose (object);
281 }
282
283 static void
284 gst_play_base_bin_finalize (GObject * object)
285 {
286   GstPlayBaseBin *play_base_bin = GST_PLAY_BASE_BIN (object);
287
288   g_mutex_free (play_base_bin->group_lock);
289   g_cond_free (play_base_bin->group_cond);
290
291   g_mutex_free (play_base_bin->sub_lock);
292
293   G_OBJECT_CLASS (parent_class)->finalize (object);
294 }
295
296 /*
297  * playbasebingroup stuff.
298  */
299
300 static GstPlayBaseGroup *
301 group_create (GstPlayBaseBin * play_base_bin)
302 {
303   GstPlayBaseGroup *group;
304
305   group = g_new0 (GstPlayBaseGroup, 1);
306   group->bin = play_base_bin;
307   group->streaminfo_value_array = g_value_array_new (0);
308
309   GST_DEBUG_OBJECT (play_base_bin, "created new group %p", group);
310
311   return group;
312 }
313
314 /*
315  * Gets the currently playing group.
316  *
317  * Callers must have group-lock held when calling this.
318  */
319
320 static GstPlayBaseGroup *
321 get_active_group (GstPlayBaseBin * play_base_bin)
322 {
323   GstPlayBaseGroup *group = NULL;
324
325   if (play_base_bin->queued_groups)
326     group = play_base_bin->queued_groups->data;
327
328   return group;
329 }
330
331 /*
332  * get the group used for discovering the different streams.
333  * This function creates a group is there is none.
334  *
335  * Callers must have group-lock held when calling this.
336  */
337 static GstPlayBaseGroup *
338 get_building_group (GstPlayBaseBin * play_base_bin)
339 {
340   GstPlayBaseGroup *group;
341
342   group = play_base_bin->building_group;
343   if (group == NULL) {
344     group = group_create (play_base_bin);
345     play_base_bin->building_group = group;
346   }
347
348   return group;
349 }
350
351 /*
352  * Callers must have lock held when calling this!
353  */
354
355 static void
356 group_destroy (GstPlayBaseGroup * group)
357 {
358   GstPlayBaseBin *play_base_bin = group->bin;
359   gint n;
360
361   GST_LOG ("removing group %p", group);
362
363   /* remove the preroll queues */
364   for (n = 0; n < NUM_TYPES; n++) {
365     GstElement *element = group->type[n].preroll;
366     GstElement *fakesrc;
367     GstElement *sel;
368     const GList *item;
369
370     if (!element)
371       continue;
372
373     sel = group->type[n].selector;
374
375     /* remove any fakesrc elements for this preroll element */
376     for (item = sel->pads; item != NULL; item = item->next) {
377       GstPad *pad = GST_PAD (item->data);
378       guint sig_id;
379
380       if (GST_PAD_DIRECTION (pad) != GST_PAD_SINK)
381         continue;
382
383       sig_id =
384           GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pad), "unlinked_id"));
385
386       if (sig_id != 0) {
387         GST_LOG ("removing unlink signal %s:%s", GST_DEBUG_PAD_NAME (pad));
388         g_signal_handler_disconnect (G_OBJECT (pad), sig_id);
389         g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (0));
390       }
391
392       fakesrc = (GstElement *) g_object_get_data (G_OBJECT (pad), "fakesrc");
393       if (fakesrc != NULL) {
394         GST_LOG ("removing fakesrc from %s:%s",
395             GST_PAD_NAME (pad), GST_ELEMENT_NAME (GST_PAD_PARENT (pad)));
396         gst_element_set_state (fakesrc, GST_STATE_NULL);
397         gst_bin_remove (GST_BIN_CAST (play_base_bin), fakesrc);
398       }
399     }
400
401     /* if the group is currently being played, we have to remove the element
402      * from the thread */
403     gst_element_set_state (element, GST_STATE_NULL);
404     gst_element_set_state (group->type[n].selector, GST_STATE_NULL);
405
406     GST_LOG ("removing preroll element %s", GST_ELEMENT_NAME (element));
407
408     gst_bin_remove (group->type[n].bin, element);
409     gst_bin_remove (group->type[n].bin, group->type[n].selector);
410
411     group->type[n].preroll = NULL;
412     group->type[n].selector = NULL;
413     group->type[n].bin = NULL;
414   }
415
416   /* free the streaminfo too */
417   g_list_foreach (group->streaminfo, (GFunc) g_object_unref, NULL);
418   g_list_free (group->streaminfo);
419   g_value_array_free (group->streaminfo_value_array);
420   g_free (group);
421 }
422
423 /*
424  * is called when the current building group is completely finished
425  * and ready for playback
426  *
427  * This function grabs lock, so take care when calling.
428  */
429 static void
430 group_commit (GstPlayBaseBin * play_base_bin, gboolean fatal, gboolean subtitle)
431 {
432   GstPlayBaseGroup *group;
433   gboolean had_active_group;
434
435   GROUP_LOCK (play_base_bin);
436   group = play_base_bin->building_group;
437   had_active_group = (get_active_group (play_base_bin) != NULL);
438
439   GST_DEBUG_OBJECT (play_base_bin, "commit group %p, had active %d",
440       group, had_active_group);
441
442   /* if an element signalled a no-more-pads after we stopped due
443    * to preroll, the group is NULL. This is not an error */
444   if (group == NULL) {
445     if (!fatal) {
446       GROUP_UNLOCK (play_base_bin);
447       return;
448     } else {
449       GST_DEBUG_OBJECT (play_base_bin, "Group loading failed, bailing out");
450     }
451   } else {
452     if (!subtitle) {
453       gint n;
454
455       GST_DEBUG_OBJECT (play_base_bin, "group %p done", group);
456
457       play_base_bin->queued_groups =
458           g_list_append (play_base_bin->queued_groups, group);
459
460       play_base_bin->building_group = NULL;
461
462       /* remove signals. We don't want anymore signals from the preroll
463        * elements at this stage. */
464       for (n = 0; n < NUM_TYPES; n++) {
465         GstElement *element = group->type[n].preroll;
466
467         if (!element)
468           continue;
469
470         preroll_remove_overrun (element, play_base_bin);
471         /* if overrun is removed, probe alse has to be removed */
472         queue_remove_probe (element, play_base_bin);
473       }
474     } else {
475       /* this is a special subtitle bin, we don't commit the group but
476        * mark the subtitles as detected before we signal. */
477       GST_DEBUG_OBJECT (play_base_bin, "marking subtitle bin as complete");
478       play_base_bin->subtitle_done = TRUE;
479     }
480   }
481
482   GST_DEBUG_OBJECT (play_base_bin, "signal group done");
483   GROUP_SIGNAL (play_base_bin);
484   GST_DEBUG_OBJECT (play_base_bin, "signaled group done");
485
486   if (!subtitle && !had_active_group) {
487     if (!prepare_output (play_base_bin)) {
488       GROUP_UNLOCK (play_base_bin);
489       return;
490     }
491
492     setup_substreams (play_base_bin);
493     GST_DEBUG_OBJECT (play_base_bin, "Emitting signal");
494     GST_PLAY_BASE_BIN_GET_CLASS (play_base_bin)->setup_output_pads
495         (play_base_bin, group);
496     GST_DEBUG_OBJECT (play_base_bin, "done");
497
498     GROUP_UNLOCK (play_base_bin);
499
500     g_object_notify (G_OBJECT (play_base_bin), "stream-info");
501   } else {
502     GROUP_UNLOCK (play_base_bin);
503   }
504 }
505
506 /*
507  * check if there are streams in the group that are not muted
508  *
509  * Callers must have group-lock held when calling this.
510  */
511 static gboolean
512 group_is_muted (GstPlayBaseGroup * group)
513 {
514   gint n;
515
516   for (n = 0; n < NUM_TYPES; n++) {
517     if (group->type[n].preroll && !group->type[n].done)
518       return FALSE;
519   }
520
521   return TRUE;
522 }
523
524 /*
525  * Buffer/cache checking.
526  */
527
528 static inline void
529 fill_buffer (GstPlayBaseBin * play_base_bin, gint percent)
530 {
531   GST_DEBUG_OBJECT (play_base_bin, "buffering %d", percent);
532   gst_element_post_message (GST_ELEMENT_CAST (play_base_bin),
533       gst_message_new_buffering (GST_OBJECT_CAST (play_base_bin), percent));
534 }
535
536 static gboolean
537 check_queue_event (GstPad * pad, GstEvent * event, gpointer user_data)
538 {
539   GstElement *queue = GST_ELEMENT_CAST (user_data);
540
541   switch (GST_EVENT_TYPE (event)) {
542     case GST_EVENT_EOS:
543       GST_DEBUG ("EOS event, mark EOS");
544       g_object_set_data (G_OBJECT (queue), "eos", GINT_TO_POINTER (1));
545       break;
546     case GST_EVENT_FLUSH_STOP:
547       GST_DEBUG ("FLUSH_STOP event, remove EOS");
548       g_object_set_data (G_OBJECT (queue), "eos", NULL);
549       break;
550     default:
551       GST_DEBUG ("uninteresting event %s", GST_EVENT_TYPE_NAME (event));
552       break;
553   }
554   return TRUE;
555 }
556
557 static gboolean
558 check_queue (GstPad * pad, GstBuffer * data, gpointer user_data)
559 {
560   GstElement *queue = GST_ELEMENT_CAST (user_data);
561   GstPlayBaseBin *play_base_bin = g_object_get_data (G_OBJECT (queue), "pbb");
562   guint64 level = 0;
563
564   GST_DEBUG_OBJECT (queue, "check queue triggered");
565
566   g_object_get (G_OBJECT (queue), "current-level-time", &level, NULL);
567   GST_DEBUG_OBJECT (play_base_bin, "Queue size: %" GST_TIME_FORMAT,
568       GST_TIME_ARGS (level));
569
570   if (play_base_bin->queue_threshold > 0) {
571     level = level * 99 / play_base_bin->queue_threshold;
572     if (level > 99)
573       level = 99;
574   } else
575     level = 99;
576
577   fill_buffer (play_base_bin, level);
578
579   /* continue! */
580   return TRUE;
581 }
582
583 /* If a queue overruns and we are buffer in streaming mode (we have a min-time)
584  * we can potentially create a deadlock when:
585  *
586  *  1) the max-bytes is hit and
587  *  2) the min-time is not hit.
588  *
589  * We recover from this situation in this callback by
590  * setting the max-bytes to unlimited if we see that there is
591  * a current-time-level (which means some sort of timestamping is
592  * done).
593  */
594 static void
595 queue_deadlock_check (GstElement * queue, GstPlayBaseBin * play_base_bin)
596 {
597   guint64 time, min_time;
598   guint bytes;
599
600   GST_DEBUG_OBJECT (play_base_bin, "overrun signal received from queue %s",
601       GST_ELEMENT_NAME (queue));
602
603   /* figure out where we are */
604   g_object_get (G_OBJECT (queue), "current-level-time", &time,
605       "current-level-bytes", &bytes, "min-threshold-time", &min_time, NULL);
606
607   GST_DEBUG_OBJECT (play_base_bin, "streaming mode, queue %s current %"
608       GST_TIME_FORMAT ", min %" GST_TIME_FORMAT
609       ", bytes %d", GST_ELEMENT_NAME (queue),
610       GST_TIME_ARGS (time), GST_TIME_ARGS (min_time), bytes);
611
612   /* if the bytes in the queue represent time, we disable bytes
613    * overrun checking to not cause deadlocks.
614    */
615   if (bytes && time != 0 && time < min_time) {
616     GST_DEBUG_OBJECT (play_base_bin,
617         "possible deadlock found, removing byte limit");
618
619     /* queue knows about time but is filled with bytes that do
620      * not represent min-threshold time, disable bytes checking so
621      * the queue can grow some more. */
622     g_object_set (G_OBJECT (queue), "max-size-bytes", 0, NULL);
623
624     /* bytes limit is removed, we cannot deadlock anymore */
625     g_signal_handlers_disconnect_by_func (queue,
626         (gpointer) queue_deadlock_check, play_base_bin);
627   } else {
628     GST_DEBUG_OBJECT (play_base_bin, "no deadlock");
629   }
630 }
631
632 static void
633 queue_remove_probe (GstElement * queue, GstPlayBaseBin * play_base_bin)
634 {
635   gpointer data;
636   GstPad *sinkpad;
637
638   data = g_object_get_data (G_OBJECT (queue), "probe");
639   sinkpad = gst_element_get_static_pad (queue, "sink");
640
641   if (data) {
642     GST_DEBUG_OBJECT (play_base_bin,
643         "Removing buffer probe from pad %s:%s (%p)",
644         GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
645
646     g_object_set_data (G_OBJECT (queue), "probe", NULL);
647     gst_pad_remove_buffer_probe (sinkpad, GPOINTER_TO_INT (data));
648   } else {
649     GST_DEBUG_OBJECT (play_base_bin,
650         "No buffer probe to remove from %s:%s (%p)",
651         GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
652   }
653   gst_object_unref (sinkpad);
654 }
655
656 /* Used for time-based buffering in streaming mode and is called when a queue
657  * emits the running signal. This means that the high watermark threshold is
658  * reached and the buffering is completed. */
659 static void
660 queue_threshold_reached (GstElement * queue, GstPlayBaseBin * play_base_bin)
661 {
662   GstPlayBaseGroup *group;
663   gint n;
664
665   GST_DEBUG_OBJECT (play_base_bin, "running signal received from queue %s",
666       GST_ELEMENT_NAME (queue));
667
668   /* we disconnect the signal so that we don't get called for every buffer. */
669   g_signal_handlers_disconnect_by_func (queue,
670       (gpointer) queue_threshold_reached, play_base_bin);
671
672   if (g_object_get_data (G_OBJECT (queue), "eos")) {
673     GST_DEBUG_OBJECT (play_base_bin, "disable min threshold time, we are EOS");
674     g_object_set (queue, "min-threshold-time", (guint64) 0, NULL);
675   } else {
676     /* now place the limits at the low threshold. When we hit this limit, the
677      * underrun signal will be called. The underrun signal is always connected. */
678     GST_DEBUG_OBJECT (play_base_bin,
679         "setting min threshold time to %" G_GUINT64_FORMAT,
680         play_base_bin->queue_min_threshold);
681     g_object_set (queue, "min-threshold-time",
682         play_base_bin->queue_min_threshold, NULL);
683   }
684
685   GROUP_LOCK (play_base_bin);
686   group = get_active_group (play_base_bin);
687   if (!group) {
688     GROUP_UNLOCK (play_base_bin);
689     return;
690   }
691
692   /* we remove the probe now because we don't need it anymore to give progress
693    * about the buffering. */
694   for (n = 0; n < NUM_TYPES; n++) {
695     GstElement *element = group->type[n].preroll;
696
697     if (!element)
698       continue;
699
700     queue_remove_probe (element, play_base_bin);
701   }
702
703   GROUP_UNLOCK (play_base_bin);
704
705   /* we post a 100% buffering message to notify the app that buffering is
706    * completed and playback can start/continue */
707   if (play_base_bin->is_stream)
708     fill_buffer (play_base_bin, 100);
709 }
710
711 /* this signal will be fired when one of the queues with raw
712  * data is filled. This means that the group building stage is over
713  * and playback of the new queued group should start. This is a rather unusual
714  * situation because normally the group is committed when the "no_more_pads"
715  * signal is fired.
716  */
717 static void
718 queue_overrun (GstElement * queue, GstPlayBaseBin * play_base_bin)
719 {
720   GST_DEBUG_OBJECT (play_base_bin, "queue %s overrun",
721       GST_ELEMENT_NAME (queue));
722
723   preroll_remove_overrun (queue, play_base_bin);
724
725   group_commit (play_base_bin, FALSE,
726       GST_OBJECT_PARENT (GST_OBJECT_CAST (queue)) ==
727       GST_OBJECT_CAST (play_base_bin->subtitle));
728
729   /* notify end of buffering */
730   queue_threshold_reached (queue, play_base_bin);
731 }
732
733 /* this signal is only added when in streaming mode to catch underruns
734  */
735 static void
736 queue_out_of_data (GstElement * queue, GstPlayBaseBin * play_base_bin)
737 {
738   GST_DEBUG_OBJECT (play_base_bin, "underrun signal received from queue %s",
739       GST_ELEMENT_NAME (queue));
740
741   /* On underrun, we want to temporarily pause playback, set a "min-size"
742    * threshold and wait for the running signal and then play again.
743    *
744    * This signal could never be called because the queue max-size limits are set
745    * too low. We take care of this possible deadlock in the overrun signal
746    * handler. */
747   g_signal_connect (G_OBJECT (queue), "pushing",
748       G_CALLBACK (queue_threshold_reached), play_base_bin);
749   GST_DEBUG_OBJECT (play_base_bin,
750       "setting min threshold time to %" G_GUINT64_FORMAT,
751       (guint64) play_base_bin->queue_threshold);
752   g_object_set (queue, "min-threshold-time",
753       (guint64) play_base_bin->queue_threshold, NULL);
754
755   /* re-connect probe, this will fire feedback about the percentage that we
756    * buffered and is posted in the BUFFERING message. */
757   if (!g_object_get_data (G_OBJECT (queue), "probe")) {
758     GstPad *sinkpad;
759     guint id;
760
761     sinkpad = gst_element_get_static_pad (queue, "sink");
762     id = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (check_queue), queue);
763     g_object_set_data (G_OBJECT (queue), "probe", GINT_TO_POINTER (id));
764     GST_DEBUG_OBJECT (play_base_bin,
765         "Re-attaching buffering probe to pad %s:%s %p",
766         GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
767     gst_object_unref (sinkpad);
768
769     fill_buffer (play_base_bin, 0);
770   }
771 }
772
773 /*
774  * generate a preroll element which is simply a queue. While there
775  * are still dynamic elements in the pipeline, we wait for one
776  * of the queues to fill. The assumption is that all the dynamic
777  * streams will be detected by that time.
778  *
779  * Callers must have the group-lock held when calling this.
780  */
781 static void
782 gen_preroll_element (GstPlayBaseBin * play_base_bin,
783     GstPlayBaseGroup * group, GstStreamType type, GstPad * pad,
784     GstStreamInfo * info)
785 {
786   GstElement *selector, *preroll;
787   gchar *name, *padname;
788   const gchar *prename;
789   guint overrun_sig;
790   GstPad *preroll_pad;
791   GstBin *target;
792   GstState state;
793
794   if (type == GST_STREAM_TYPE_VIDEO)
795     prename = "video";
796   else if (type == GST_STREAM_TYPE_TEXT)
797     prename = "text";
798   else if (type == GST_STREAM_TYPE_AUDIO)
799     prename = "audio";
800   else if (type == GST_STREAM_TYPE_SUBPICTURE)
801     prename = "subpicture";
802   else
803     g_return_if_reached ();
804
805   /* create stream selector */
806   padname = gst_pad_get_name (pad);
807   name = g_strdup_printf ("selector_%s_%s", prename, padname);
808   selector = g_object_new (GST_TYPE_STREAM_SELECTOR, "name", name, NULL);
809   g_free (name);
810
811   /* create preroll queue */
812   name = g_strdup_printf ("preroll_%s_%s", prename, padname);
813   preroll = gst_element_factory_make ("queue", name);
814   g_free (name);
815   g_free (padname);
816
817   /* for buffering of raw data we ideally want to buffer a
818    * very small amount of buffers since the memory used by
819    * this raw data can be enormously huge.
820    *
821    * We use an upper limit of typically a few seconds here but
822    * cap in case no timestamps are set on the raw data (bad!).
823    *
824    * FIXME: we abuse this buffer to do network buffering since
825    * we can then easily do time-based buffering. The better
826    * solution would be to add a specific network queue right
827    * after the source that measures the datarate and scales this
828    * queue of encoded data instead.
829    */
830   if (play_base_bin->raw_decoding_mode) {
831     if (type == GST_STREAM_TYPE_VIDEO) {
832       g_object_set (G_OBJECT (preroll),
833           "max-size-buffers", 2, "max-size-bytes", 0,
834           "max-size-time", (guint64) 0, NULL);
835     } else {
836       g_object_set (G_OBJECT (preroll),
837           "max-size-buffers", 0, "max-size-bytes",
838           2 * 1024 * 1024, "max-size-time", play_base_bin->queue_size, NULL);
839     }
840   } else {
841     g_object_set (G_OBJECT (preroll),
842         "max-size-buffers", 0, "max-size-bytes",
843         ((type == GST_STREAM_TYPE_VIDEO) ? 25 : 2) * 1024 * 1024,
844         "max-size-time", play_base_bin->queue_size, NULL);
845   }
846
847   /* the overrun signal is always attached and serves two purposes:
848    *
849    *  1) when we are building a group and the overrun is called, we commit the
850    *     group. The reason being that if we fill the entire queue without a
851    *     normal group commit (with _no_more_pads()) we can assume the
852    *     audio/video is completely wacked or the element just does not know when
853    *     it is ready with all the pads (mpeg).
854    *  2) When we are doing network buffering, we keep track of low/high
855    *     watermarks in the queue. It is possible that we set the high watermark
856    *     higher than the max-size limits to trigger an overrun. In this case we
857    *     will never get a running signal but we can use the overrun signal to
858    *     detect this deadlock and correct it.
859    */
860   overrun_sig = g_signal_connect (G_OBJECT (preroll), "overrun",
861       G_CALLBACK (queue_overrun), play_base_bin);
862
863   /* keep a ref to the signal id so that we can disconnect the signal callback
864    * when we are done with the preroll */
865   g_object_set_data (G_OBJECT (preroll), "overrun_signal_id",
866       GINT_TO_POINTER (overrun_sig));
867
868   if (play_base_bin->is_stream &&
869       ((type == GST_STREAM_TYPE_VIDEO &&
870               group->type[GST_STREAM_TYPE_AUDIO - 1].npads == 0) ||
871           (type == GST_STREAM_TYPE_AUDIO &&
872               group->type[GST_STREAM_TYPE_VIDEO - 1].npads == 0))) {
873     GstPad *sinkpad;
874     guint id;
875
876     /* catch deadlocks when we are network buffering in time but the max-limit
877      * in bytes is hit. */
878     g_signal_connect (G_OBJECT (preroll), "overrun",
879         G_CALLBACK (queue_deadlock_check), play_base_bin);
880
881     /* attach pointer to playbasebin */
882     g_object_set_data (G_OBJECT (preroll), "pbb", play_base_bin);
883
884     /* give updates on queue size */
885     sinkpad = gst_element_get_static_pad (preroll, "sink");
886     id = gst_pad_add_buffer_probe (sinkpad, G_CALLBACK (check_queue), preroll);
887     GST_DEBUG_OBJECT (play_base_bin, "Attaching probe to pad %s:%s (%p)",
888         GST_DEBUG_PAD_NAME (sinkpad), sinkpad);
889     g_object_set_data (G_OBJECT (preroll), "probe", GINT_TO_POINTER (id));
890
891     /* catch eos and flush events so that we can ignore underruns */
892     id = gst_pad_add_event_probe (sinkpad, G_CALLBACK (check_queue_event),
893         preroll);
894     g_object_set_data (G_OBJECT (preroll), "eos_probe", GINT_TO_POINTER (id));
895
896     gst_object_unref (sinkpad);
897
898     /* When we connect this queue, it will start running and immediately
899      * fire an underrun. */
900     g_signal_connect (G_OBJECT (preroll), "underrun",
901         G_CALLBACK (queue_out_of_data), play_base_bin);
902     /* configure threshold and callbacks */
903     queue_out_of_data (preroll, play_base_bin);
904   }
905
906   /* listen for EOS so we can switch groups when one ended. */
907   preroll_pad = gst_element_get_static_pad (preroll, "src");
908   gst_pad_add_event_probe (preroll_pad, G_CALLBACK (probe_triggered), info);
909   gst_object_unref (preroll_pad);
910
911   /* add to group list */
912   group->type[type - 1].selector = selector;
913   group->type[type - 1].preroll = preroll;
914
915   /* figure out where the preroll element should go */
916   if (type == GST_STREAM_TYPE_TEXT && play_base_bin->subtitle)
917     target = GST_BIN_CAST (play_base_bin->subtitle);
918   else
919     target = GST_BIN_CAST (play_base_bin);
920
921   group->type[type - 1].bin = target;
922   gst_bin_add (target, selector);
923   gst_bin_add (target, preroll);
924
925   gst_element_link (selector, preroll);
926
927   /* figure out target state and set */
928   state = (GST_STATE (play_base_bin) == GST_STATE_PLAYING ?
929       GST_STATE_PLAYING : GST_STATE_PAUSED);
930
931   gst_element_set_state (selector, state);
932   gst_element_set_state (preroll, state);
933 }
934
935 static void
936 preroll_remove_overrun (GstElement * element, GstPlayBaseBin * play_base_bin)
937 {
938   guint overrun_sig;
939   GObject *obj = G_OBJECT (element);
940
941   overrun_sig = GPOINTER_TO_INT (g_object_get_data (obj, "overrun_signal_id"));
942   if (overrun_sig) {
943     GST_LOG_OBJECT (play_base_bin, "removing preroll signal %s",
944         GST_ELEMENT_NAME (element));
945     g_signal_handler_disconnect (obj, overrun_sig);
946     /* We have disconnected this signal, remove the signal_id from the object
947      * data */
948     g_object_set_data (obj, "overrun_signal_id", NULL);
949   }
950 }
951
952 static void
953 remove_groups (GstPlayBaseBin * play_base_bin)
954 {
955   GROUP_LOCK (play_base_bin);
956
957   /* first destroy the group we were building if any */
958   if (play_base_bin->building_group) {
959     group_destroy (play_base_bin->building_group);
960     play_base_bin->building_group = NULL;
961   }
962
963   /* remove the queued groups */
964   g_list_foreach (play_base_bin->queued_groups, (GFunc) group_destroy, NULL);
965   g_list_free (play_base_bin->queued_groups);
966   play_base_bin->queued_groups = NULL;
967
968   /* clear subs */
969   if (play_base_bin->subtitle) {
970     gst_element_set_state (play_base_bin->subtitle, GST_STATE_NULL);
971     gst_bin_remove (GST_BIN_CAST (play_base_bin), play_base_bin->subtitle);
972     play_base_bin->subtitle = NULL;
973   }
974
975   GROUP_UNLOCK (play_base_bin);
976 }
977
978 /*
979  * Add/remove a single stream to current building group.
980  *
981  * Must be called with group-lock held.
982  */
983 static void
984 add_stream (GstPlayBaseGroup * group, GstStreamInfo * info)
985 {
986   GValue v = { 0, };
987   GST_DEBUG ("add stream to group %p", group);
988
989   /* keep ref to the group */
990   g_object_set_data (G_OBJECT (info), "group", group);
991
992   g_value_init (&v, G_TYPE_OBJECT);
993   g_value_set_object (&v, info);
994   g_value_array_append (group->streaminfo_value_array, &v);
995   g_value_unset (&v);
996   group->streaminfo = g_list_append (group->streaminfo, info);
997   if (info->type > 0 && info->type <= NUM_TYPES) {
998     group->type[info->type - 1].npads++;
999   }
1000 }
1001
1002 static gboolean
1003 string_arr_has_str (const gchar * values[], const gchar * value)
1004 {
1005   if (values && value) {
1006     while (*values != NULL) {
1007       if (strcmp (value, *values) == 0)
1008         return TRUE;
1009       ++values;
1010     }
1011   }
1012   return FALSE;
1013 }
1014
1015 /* mime types we are not handling on purpose right now, don't post a
1016  * missing-plugin message for these */
1017 static const gchar *blacklisted_mimes[] = {
1018   "video/x-dvd-subpicture", NULL
1019 };
1020
1021 #define IS_BLACKLISTED_MIME(type) (string_arr_has_str(blacklisted_mimes,type))
1022
1023 static void
1024 gst_play_base_bin_handle_message_func (GstBin * bin, GstMessage * msg)
1025 {
1026   if (gst_is_missing_plugin_message (msg)) {
1027     gchar *detail;
1028     guint i;
1029
1030     detail = gst_missing_plugin_message_get_installer_detail (msg);
1031     for (i = 0; detail != NULL && blacklisted_mimes[i] != NULL; ++i) {
1032       if (strstr (detail, "|decoder-") && strstr (detail, blacklisted_mimes[i])) {
1033         GST_LOG_OBJECT (bin, "suppressing message %" GST_PTR_FORMAT, msg);
1034         gst_message_unref (msg);
1035         g_free (detail);
1036         return;
1037       }
1038     }
1039     g_free (detail);
1040   }
1041   GST_BIN_CLASS (parent_class)->handle_message (bin, msg);
1042 }
1043
1044 /*
1045  * signal fired when an unknown stream is found. We create a new
1046  * UNKNOWN streaminfo object.
1047  */
1048 static void
1049 unknown_type (GstElement * element, GstPad * pad, GstCaps * caps,
1050     GstPlayBaseBin * play_base_bin)
1051 {
1052   const gchar *type_name;
1053   GstStreamInfo *info;
1054   GstPlayBaseGroup *group;
1055
1056   type_name = gst_structure_get_name (gst_caps_get_structure (caps, 0));
1057   if (type_name && !IS_BLACKLISTED_MIME (type_name)) {
1058     gchar *capsstr;
1059
1060     capsstr = gst_caps_to_string (caps);
1061     GST_DEBUG_OBJECT (play_base_bin, "don't know how to handle %s", capsstr);
1062     /* FIXME, g_message() ? */
1063     g_message ("don't know how to handle %s", capsstr);
1064     g_free (capsstr);
1065   } else {
1066     /* don't spew stuff to the terminal or send message if it's blacklisted */
1067     GST_DEBUG_OBJECT (play_base_bin, "media type %s not handled on purpose, "
1068         "not posting a missing-plugin message on the bus", type_name);
1069   }
1070
1071   GROUP_LOCK (play_base_bin);
1072
1073   group = get_building_group (play_base_bin);
1074
1075   /* add the stream to the list */
1076   info = gst_stream_info_new (GST_OBJECT_CAST (pad), GST_STREAM_TYPE_UNKNOWN,
1077       NULL, caps);
1078   info->origin = GST_OBJECT_CAST (pad);
1079   add_stream (group, info);
1080
1081   GROUP_UNLOCK (play_base_bin);
1082 }
1083
1084 /* add a streaminfo that indicates that the stream is handled by the
1085  * given element. This usually means that a stream without actual data is
1086  * produced but one that is sunken by an element. Examples of this are:
1087  * cdaudio, a hardware decoder/sink, dvd meta bins etc...
1088  */
1089 static void
1090 add_element_stream (GstElement * element, GstPlayBaseBin * play_base_bin)
1091 {
1092   GstStreamInfo *info;
1093   GstPlayBaseGroup *group;
1094
1095   GROUP_LOCK (play_base_bin);
1096
1097   group = get_building_group (play_base_bin);
1098
1099   /* add the stream to the list */
1100   info =
1101       gst_stream_info_new (GST_OBJECT_CAST (element), GST_STREAM_TYPE_ELEMENT,
1102       NULL, NULL);
1103   info->origin = GST_OBJECT_CAST (element);
1104   add_stream (group, info);
1105
1106   GROUP_UNLOCK (play_base_bin);
1107 }
1108
1109 /* when the decoder element signals that no more pads will be generated, we
1110  * can commit the current group.
1111  */
1112 static void
1113 no_more_pads_full (GstElement * element, gboolean subs,
1114     GstPlayBaseBin * play_base_bin)
1115 {
1116   /* setup phase */
1117   GST_DEBUG_OBJECT (element, "no more pads, %d pending",
1118       play_base_bin->pending);
1119
1120   /* nothing pending, we can exit */
1121   if (play_base_bin->pending == 0)
1122     return;
1123
1124   /* the object has no pending no_more_pads */
1125   if (!g_object_get_data (G_OBJECT (element), "pending"))
1126     return;
1127
1128   g_object_set_data (G_OBJECT (element), "pending", NULL);
1129
1130   play_base_bin->pending--;
1131
1132   GST_DEBUG_OBJECT (element, "remove pending, now %d pending",
1133       play_base_bin->pending);
1134
1135   if (play_base_bin->pending == 0) {
1136     /* we can commit this group for playback now */
1137     group_commit (play_base_bin, play_base_bin->is_stream, subs);
1138   }
1139 }
1140
1141 static void
1142 no_more_pads (GstElement * element, GstPlayBaseBin * play_base_bin)
1143 {
1144   no_more_pads_full (element, FALSE, play_base_bin);
1145 }
1146
1147 static void
1148 sub_no_more_pads (GstElement * element, GstPlayBaseBin * play_base_bin)
1149 {
1150   no_more_pads_full (element, TRUE, play_base_bin);
1151 }
1152
1153 static void
1154 source_no_more_pads (GstElement * element, GstPlayBaseBin * bin)
1155 {
1156   GST_DEBUG_OBJECT (bin, "No more pads in source element %s.",
1157       GST_ELEMENT_NAME (element));
1158
1159   g_signal_handler_disconnect (G_OBJECT (element), bin->src_np_sig_id);
1160   bin->src_np_sig_id = 0;
1161   g_signal_handler_disconnect (G_OBJECT (element), bin->src_nmp_sig_id);
1162   bin->src_nmp_sig_id = 0;
1163
1164   no_more_pads_full (element, FALSE, bin);
1165 }
1166
1167 static gboolean
1168 probe_triggered (GstPad * pad, GstEvent * event, gpointer user_data)
1169 {
1170   GstPlayBaseGroup *group;
1171   GstPlayBaseBin *play_base_bin;
1172   GstStreamInfo *info;
1173   GstEventType type;
1174
1175   type = GST_EVENT_TYPE (event);
1176
1177   GST_LOG ("probe triggered, (%d) %s", type, gst_event_type_get_name (type));
1178
1179   /* we only care about EOS */
1180   if (type != GST_EVENT_EOS)
1181     return TRUE;
1182
1183   info = GST_STREAM_INFO (user_data);
1184   group = (GstPlayBaseGroup *) g_object_get_data (G_OBJECT (info), "group");
1185   play_base_bin = group->bin;
1186
1187   if (type == GST_EVENT_EOS) {
1188     gint num_groups = 0;
1189     gboolean have_left;
1190
1191     GST_DEBUG_OBJECT (play_base_bin, "probe got EOS in group %p", group);
1192
1193     GROUP_LOCK (play_base_bin);
1194
1195     /* mute this stream */
1196     g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
1197     if (info->type > 0 && info->type <= NUM_TYPES)
1198       group->type[info->type - 1].done = TRUE;
1199
1200     /* see if we have some more groups left to play */
1201     num_groups = g_list_length (play_base_bin->queued_groups);
1202     if (play_base_bin->building_group)
1203       num_groups++;
1204     have_left = (num_groups > 1);
1205
1206     /* see if the complete group is muted */
1207     if (!group_is_muted (group)) {
1208       /* group is not completely muted, we remove the EOS event
1209        * and continue, eventually the other streams will be EOSed and
1210        * we can switch out this group. */
1211       GST_DEBUG ("group %p not completely muted", group);
1212
1213       GROUP_UNLOCK (play_base_bin);
1214
1215       /* remove the EOS if we have something left */
1216       return !have_left;
1217     }
1218
1219     if (have_left) {
1220       /* ok, get rid of the current group then */
1221       //group_destroy (group);
1222       /* removing the current group brings the next group
1223        * active */
1224       play_base_bin->queued_groups =
1225           g_list_remove (play_base_bin->queued_groups, group);
1226       /* and wait for the next one to be ready */
1227       while (!play_base_bin->queued_groups) {
1228         GROUP_WAIT (play_base_bin);
1229       }
1230       group = play_base_bin->queued_groups->data;
1231
1232       /* now activate the next one */
1233       setup_substreams (play_base_bin);
1234       GST_DEBUG ("switching to next group %p - emitting signal", group);
1235       /* and signal the new group */
1236       GST_PLAY_BASE_BIN_GET_CLASS (play_base_bin)->setup_output_pads
1237           (play_base_bin, group);
1238
1239       GROUP_UNLOCK (play_base_bin);
1240
1241       g_object_notify (G_OBJECT (play_base_bin), "stream-info");
1242
1243       /* get rid of the EOS event */
1244       return FALSE;
1245     } else {
1246       GROUP_UNLOCK (play_base_bin);
1247       GST_LOG ("Last group done, EOS");
1248     }
1249   }
1250
1251   return TRUE;
1252 }
1253
1254 /* This function will be called when the sinkpad of the preroll element
1255  * is unlinked, we have to connect something to the sinkpad or else the
1256  * state change will fail..
1257  */
1258 static void
1259 preroll_unlinked (GstPad * pad, GstPad * peerpad,
1260     GstPlayBaseBin * play_base_bin)
1261 {
1262   GstElement *fakesrc;
1263   guint sig_id;
1264   GstPad *srcpad;
1265
1266   /* make a fakesrc that will just emit one EOS */
1267   fakesrc = gst_element_factory_make ("fakesrc", NULL);
1268   g_object_set (G_OBJECT (fakesrc), "num-buffers", 0, NULL);
1269
1270   GST_DEBUG ("patching unlinked pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1271
1272   srcpad = gst_element_get_static_pad (fakesrc, "src");
1273   gst_bin_add (GST_BIN_CAST (play_base_bin), fakesrc);
1274   gst_pad_link (srcpad, pad);
1275   gst_object_unref (srcpad);
1276
1277   /* keep track of these patch elements */
1278   g_object_set_data (G_OBJECT (pad), "fakesrc", fakesrc);
1279
1280   /* now unlink the unlinked signal so that it is not called again when
1281    * we destroy the queue */
1282   sig_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pad), "unlinked_id"));
1283   if (sig_id != 0) {
1284     g_signal_handler_disconnect (G_OBJECT (pad), sig_id);
1285     g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (0));
1286   }
1287 }
1288
1289 /* Mute stream on first data - for header-is-in-stream-stuff
1290  * (vorbis, ogmtext). */
1291 static gboolean
1292 mute_stream (GstPad * pad, GstBuffer * buf, gpointer data)
1293 {
1294   GstStreamInfo *info = GST_STREAM_INFO (data);
1295   guint id;
1296
1297   GST_DEBUG ("mute stream triggered");
1298
1299   g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
1300   id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), "mute_probe"));
1301   g_object_set_data (G_OBJECT (info), "mute_probe", NULL);
1302   if (id > 0)
1303     gst_pad_remove_buffer_probe (GST_PAD_CAST (info->object), id);
1304
1305   /* no data */
1306   return FALSE;
1307 }
1308
1309 /* Eat data. */
1310 static gboolean
1311 silence_stream (GstPad * pad, GstMiniObject * data, gpointer user_data)
1312 {
1313   GST_DEBUG ("silence stream triggered");
1314
1315   /* no data */
1316   return FALSE;
1317 }
1318
1319 /* Called by the signal handlers when a decodebin (main or subtitle) has
1320  * found a new raw pad.  We create a preroll element if needed and the
1321  * appropriate streaminfo. Commits the group if there will be no more pads
1322  * from decodebin */
1323 static void
1324 new_decoded_pad_full (GstElement * element, GstPad * pad, gboolean last,
1325     GstPlayBaseBin * play_base_bin, gboolean is_subs)
1326 {
1327   GstStructure *structure;
1328   const gchar *mimetype;
1329   GstCaps *caps;
1330   GstStreamInfo *info;
1331   GstStreamType type = GST_STREAM_TYPE_UNKNOWN;
1332   GstPad *sinkpad;
1333   GstPlayBaseGroup *group;
1334   guint sig;
1335   GstObject *parent;
1336   gboolean first_pad;
1337
1338   GST_DEBUG ("play base: new decoded pad. Last: %d", last);
1339
1340   /* first see if this pad has interesting caps */
1341   caps = gst_pad_get_caps (pad);
1342   if (caps == NULL || gst_caps_is_empty (caps) || gst_caps_is_any (caps))
1343     goto no_type;
1344
1345   /* get the mime type */
1346   structure = gst_caps_get_structure (caps, 0);
1347   mimetype = gst_structure_get_name (structure);
1348
1349   GROUP_LOCK (play_base_bin);
1350
1351   group = get_building_group (play_base_bin);
1352
1353   group->nstreams++;
1354
1355   parent = gst_object_get_parent (GST_OBJECT_CAST (element));
1356   if (g_str_has_prefix (mimetype, "audio/") &&
1357       parent != GST_OBJECT_CAST (play_base_bin->subtitle)) {
1358     type = GST_STREAM_TYPE_AUDIO;
1359   } else if (g_str_has_prefix (mimetype, "video/x-dvd-subpicture") &&
1360       parent != GST_OBJECT_CAST (play_base_bin->subtitle)) {
1361     type = GST_STREAM_TYPE_SUBPICTURE;
1362   } else if (g_str_has_prefix (mimetype, "video/") &&
1363       parent != GST_OBJECT_CAST (play_base_bin->subtitle)) {
1364     type = GST_STREAM_TYPE_VIDEO;
1365   } else if (g_str_has_prefix (mimetype, "text/")) {
1366     type = GST_STREAM_TYPE_TEXT;
1367   }
1368   gst_object_unref (parent);
1369
1370   info = gst_stream_info_new (GST_OBJECT_CAST (pad), type, NULL, caps);
1371   gst_caps_unref (caps);
1372
1373   if (type == GST_STREAM_TYPE_UNKNOWN) {
1374     /* Unknown streams get added to the group, but the data
1375      * just gets ignored */
1376     add_stream (group, info);
1377
1378     GROUP_UNLOCK (play_base_bin);
1379
1380     /* signal the no more pads after adding the stream */
1381     if (last)
1382       no_more_pads_full (element, is_subs, play_base_bin);
1383
1384     return;
1385   }
1386
1387   /* first pad of each type gets a selector + preroll queue */
1388   first_pad = (group->type[type - 1].npads == 0);
1389
1390   if (first_pad) {
1391     GST_DEBUG ("play base: pad needs new preroll");
1392     gen_preroll_element (play_base_bin, group, type, pad, info);
1393   }
1394
1395   /* add to stream selector */
1396   sinkpad =
1397       gst_element_get_request_pad (group->type[type - 1].selector, "sink%d");
1398
1399   /* make sure we catch unlink signals */
1400   sig = g_signal_connect (G_OBJECT (sinkpad), "unlinked",
1401       G_CALLBACK (preroll_unlinked), play_base_bin);
1402   /* keep a ref to the signal id so that we can disconnect the signal callback */
1403   g_object_set_data (G_OBJECT (sinkpad), "unlinked_id", GINT_TO_POINTER (sig));
1404   /* Store a pointer to the stream selector pad for this stream */
1405   g_object_set_data (G_OBJECT (pad), "pb_sel_pad", sinkpad);
1406
1407   gst_pad_link (pad, sinkpad);
1408   gst_object_unref (sinkpad);
1409
1410   /* select 1st for now - we'll select a preferred one after preroll */
1411   if (!first_pad) {
1412     guint id;
1413
1414     GST_DEBUG ("Adding silence_stream data probe on type %d (npads %d)", type,
1415         group->type[type - 1].npads);
1416
1417     id = gst_pad_add_data_probe (GST_PAD_CAST (pad),
1418         G_CALLBACK (silence_stream), info);
1419     g_object_set_data (G_OBJECT (pad), "eat_probe", GINT_TO_POINTER (id));
1420   }
1421
1422   /* add the stream to the list */
1423   add_stream (group, info);
1424
1425   GROUP_UNLOCK (play_base_bin);
1426
1427   /* signal the no more pads after adding the stream */
1428   if (last)
1429     no_more_pads_full (element, is_subs, play_base_bin);
1430
1431   return;
1432
1433   /* ERRORS */
1434 no_type:
1435   {
1436     g_warning ("no type on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
1437     if (caps)
1438       gst_caps_unref (caps);
1439     return;
1440   }
1441 }
1442
1443 static void
1444 new_decoded_pad (GstElement * element, GstPad * pad, gboolean last,
1445     GstPlayBaseBin * play_base_bin)
1446 {
1447   new_decoded_pad_full (element, pad, last, play_base_bin, FALSE);
1448 }
1449
1450 static void
1451 subs_new_decoded_pad (GstElement * element, GstPad * pad, gboolean last,
1452     GstPlayBaseBin * play_base_bin)
1453 {
1454   new_decoded_pad_full (element, pad, last, play_base_bin, TRUE);
1455 }
1456
1457 static void
1458 set_encoding_element (GstElement * element, gchar * encoding)
1459 {
1460   GST_DEBUG_OBJECT (element, "setting encoding to %s", GST_STR_NULL (encoding));
1461   g_object_set (G_OBJECT (element), "subtitle-encoding", encoding, NULL);
1462 }
1463
1464
1465 static void
1466 decodebin_element_added_cb (GstBin * decodebin, GstElement * element,
1467     gpointer data)
1468 {
1469   GstPlayBaseBin *play_base_bin = GST_PLAY_BASE_BIN (data);
1470   gchar *encoding;
1471
1472   if (!g_object_class_find_property (G_OBJECT_GET_CLASS (element),
1473           "subtitle-encoding")) {
1474     return;
1475   }
1476
1477   g_mutex_lock (play_base_bin->sub_lock);
1478   play_base_bin->subtitle_elements =
1479       g_slist_append (play_base_bin->subtitle_elements, element);
1480   encoding = g_strdup (play_base_bin->subencoding);
1481   g_mutex_unlock (play_base_bin->sub_lock);
1482
1483   set_encoding_element (element, encoding);
1484   g_free (encoding);
1485 }
1486
1487 static void
1488 decodebin_element_removed_cb (GstBin * decodebin, GstElement * element,
1489     gpointer data)
1490 {
1491   GstPlayBaseBin *play_base_bin = GST_PLAY_BASE_BIN (data);
1492
1493   g_mutex_lock (play_base_bin->sub_lock);
1494   play_base_bin->subtitle_elements =
1495       g_slist_remove (play_base_bin->subtitle_elements, element);
1496   g_mutex_unlock (play_base_bin->sub_lock);
1497 }
1498
1499
1500 /*
1501  * Generate source ! subparse bins.
1502  */
1503
1504 static GstElement *
1505 setup_subtitle (GstPlayBaseBin * play_base_bin, gchar * sub_uri)
1506 {
1507   GstElement *source, *subdecodebin, *subbin;
1508
1509   if (!gst_uri_is_valid (sub_uri))
1510     goto invalid_uri;
1511
1512   source = gst_element_make_from_uri (GST_URI_SRC, sub_uri, NULL);
1513   if (!source)
1514     goto unknown_uri;
1515
1516   if (g_getenv ("USE_DECODEBIN2"))
1517     subdecodebin = gst_element_factory_make ("decodebin2", "subtitle-decoder");
1518   else
1519     subdecodebin = gst_element_factory_make ("decodebin", "subtitle-decoder");
1520   g_signal_connect (subdecodebin, "element-added",
1521       G_CALLBACK (decodebin_element_added_cb), play_base_bin);
1522   g_signal_connect (subdecodebin, "element-removed",
1523       G_CALLBACK (decodebin_element_removed_cb), play_base_bin);
1524   subbin = gst_bin_new ("subtitle-bin");
1525   gst_bin_add_many (GST_BIN_CAST (subbin), source, subdecodebin, NULL);
1526
1527   gst_element_link (source, subdecodebin);
1528
1529   /* return the subtitle GstElement object */
1530   return subbin;
1531
1532   /* WARNINGS */
1533 invalid_uri:
1534   {
1535     GST_ELEMENT_WARNING (play_base_bin, RESOURCE, NOT_FOUND,
1536         (_("Invalid subtitle URI \"%s\", subtitles disabled."), sub_uri),
1537         (NULL));
1538     return NULL;
1539   }
1540 unknown_uri:
1541   {
1542     gchar *prot = gst_uri_get_protocol (sub_uri);
1543
1544     if (prot) {
1545       gchar *desc;
1546
1547       gst_element_post_message (GST_ELEMENT (play_base_bin),
1548           gst_missing_uri_source_message_new (GST_ELEMENT (play_base_bin),
1549               prot));
1550
1551       desc = gst_pb_utils_get_source_description (prot);
1552       GST_ELEMENT_ERROR (play_base_bin, CORE, MISSING_PLUGIN,
1553           (_("A %s plugin is required to play this stream, but not installed."),
1554               desc), ("No URI handler to handle sub_uri: %s", sub_uri));
1555       g_free (desc);
1556       g_free (prot);
1557     } else
1558       goto invalid_uri;
1559
1560     return NULL;
1561   }
1562 }
1563
1564 /* helper function to lookup stuff in lists */
1565 static gboolean
1566 array_has_value (const gchar * values[], const gchar * value)
1567 {
1568   gint i;
1569
1570   for (i = 0; values[i]; i++) {
1571     if (g_str_has_prefix (value, values[i]))
1572       return TRUE;
1573   }
1574   return FALSE;
1575 }
1576
1577 /* list of URIs that we consider to be streams and that need buffering.
1578  * We have no mechanism yet to figure this out with a query. */
1579 static const gchar *stream_uris[] = { "http://", "mms://", "mmsh://",
1580   "mmsu://", "mmst://", "myth://", NULL
1581 };
1582
1583 /* blacklisted URIs, we know they will always fail. */
1584 static const gchar *blacklisted_uris[] = { NULL };
1585
1586 /* mime types that we don't consider to be media types */
1587 static const gchar *no_media_mimes[] = {
1588   "application/x-executable", "application/x-bzip", "application/x-gzip",
1589   "application/zip", "application/x-compress", NULL
1590 };
1591
1592 /* mime types we consider raw media */
1593 static const gchar *raw_mimes[] = {
1594   "audio/x-raw", "video/x-raw", "video/x-dvd-subpicture", NULL
1595 };
1596
1597 #define IS_STREAM_URI(uri)          (array_has_value (stream_uris, uri))
1598 #define IS_BLACKLISTED_URI(uri)     (array_has_value (blacklisted_uris, uri))
1599 #define IS_NO_MEDIA_MIME(mime)      (array_has_value (no_media_mimes, mime))
1600 #define IS_RAW_MIME(mime)           (array_has_value (raw_mimes, mime))
1601
1602 /*
1603  * Generate and configure a source element.
1604  */
1605 static GstElement *
1606 gen_source_element (GstPlayBaseBin * play_base_bin, GstElement ** subbin)
1607 {
1608   GstElement *source;
1609
1610   if (!play_base_bin->uri)
1611     goto no_uri;
1612
1613   if (!gst_uri_is_valid (play_base_bin->uri))
1614     goto invalid_uri;
1615
1616   if (IS_BLACKLISTED_URI (play_base_bin->uri))
1617     goto uri_blacklisted;
1618
1619   if (play_base_bin->suburi) {
1620     GST_LOG_OBJECT (play_base_bin, "Creating decoder for subtitles URI %s",
1621         play_base_bin->suburi);
1622     /* subtitle specified */
1623     *subbin = setup_subtitle (play_base_bin, play_base_bin->suburi);
1624   } else {
1625     /* no subtitle specified */
1626     *subbin = NULL;
1627   }
1628
1629   source = gst_element_make_from_uri (GST_URI_SRC, play_base_bin->uri,
1630       "source");
1631   if (!source)
1632     goto no_source;
1633
1634   play_base_bin->is_stream = IS_STREAM_URI (play_base_bin->uri);
1635
1636   /* make HTTP sources send extra headers so we get icecast
1637    * metadata in case the stream is an icecast stream */
1638   if (!strncmp (play_base_bin->uri, "http://", 7) &&
1639       g_object_class_find_property (G_OBJECT_GET_CLASS (source),
1640           "iradio-mode")) {
1641     g_object_set (source, "iradio-mode", TRUE, NULL);
1642   }
1643
1644   if (g_object_class_find_property (G_OBJECT_GET_CLASS (source),
1645           "connection-speed")) {
1646     GST_DEBUG_OBJECT (play_base_bin,
1647         "setting connection-speed=%d to source element",
1648         play_base_bin->connection_speed / 1000);
1649     g_object_set (source, "connection-speed",
1650         play_base_bin->connection_speed / 1000, NULL);
1651   }
1652
1653   return source;
1654
1655   /* ERRORS */
1656 no_uri:
1657   {
1658     GST_ELEMENT_ERROR (play_base_bin, RESOURCE, NOT_FOUND,
1659         (_("No URI specified to play from.")), (NULL));
1660     return NULL;
1661   }
1662 invalid_uri:
1663   {
1664     GST_ELEMENT_ERROR (play_base_bin, RESOURCE, NOT_FOUND,
1665         (_("Invalid URI \"%s\"."), play_base_bin->uri), (NULL));
1666     return NULL;
1667   }
1668 uri_blacklisted:
1669   {
1670     GST_ELEMENT_ERROR (play_base_bin, RESOURCE, FAILED,
1671         (_("RTSP streams cannot be played yet.")), (NULL));
1672     return NULL;
1673   }
1674 no_source:
1675   {
1676     gchar *prot = gst_uri_get_protocol (play_base_bin->uri);
1677
1678     /* whoops, could not create the source element, dig a little deeper to
1679      * figure out what might be wrong. */
1680     if (prot) {
1681       gchar *desc;
1682
1683       gst_element_post_message (GST_ELEMENT (play_base_bin),
1684           gst_missing_uri_source_message_new (GST_ELEMENT (play_base_bin),
1685               prot));
1686
1687       desc = gst_pb_utils_get_source_description (prot);
1688       GST_ELEMENT_ERROR (play_base_bin, CORE, MISSING_PLUGIN,
1689           (_("A %s plugin is required to play this stream, but not installed."),
1690               desc), ("No URI handler for %s", prot));
1691       g_free (desc);
1692       g_free (prot);
1693     } else
1694       goto invalid_uri;
1695
1696     return NULL;
1697   }
1698 }
1699
1700 /* is called when a dynamic source element created a new pad. */
1701 static void
1702 source_new_pad (GstElement * element, GstPad * pad, GstPlayBaseBin * bin)
1703 {
1704   GstElement *decoder;
1705   gboolean is_raw;
1706
1707   GST_DEBUG_OBJECT (bin, "Found new pad %s.%s in source element %s",
1708       GST_DEBUG_PAD_NAME (pad), GST_ELEMENT_NAME (element));
1709
1710   /* if this is a pad with all raw caps, we can expose it */
1711   if (has_all_raw_caps (pad, &is_raw) && is_raw) {
1712     bin->raw_decoding_mode = TRUE;
1713     /* it's all raw, create output pads. */
1714     new_decoded_pad_full (element, pad, FALSE, bin, FALSE);
1715     return;
1716   }
1717
1718   /* not raw, create decoder */
1719   decoder = make_decoder (bin);
1720   if (!decoder)
1721     goto no_decodebin;
1722
1723   /* and link to decoder */
1724   if (!gst_element_link (bin->source, decoder))
1725     goto could_not_link;
1726
1727   gst_element_set_state (decoder, GST_STATE_PAUSED);
1728
1729   return;
1730
1731   /* ERRORS */
1732 no_decodebin:
1733   {
1734     /* error was posted */
1735     return;
1736   }
1737 could_not_link:
1738   {
1739     GST_ELEMENT_ERROR (bin, CORE, NEGOTIATION,
1740         (NULL), ("Can't link source to decoder element"));
1741     return;
1742   }
1743 }
1744
1745 /*
1746  * Setup the substreams (is called right after group_commit () when
1747  * loading a new group, or after switching groups).
1748  *
1749  * Should be called with group-lock held.
1750  */
1751 static void
1752 setup_substreams (GstPlayBaseBin * play_base_bin)
1753 {
1754   GstPlayBaseGroup *group;
1755   gint n;
1756   const GList *item;
1757
1758   GST_DEBUG_OBJECT (play_base_bin, "setting up substreams");
1759
1760   /* Remove the eat probes */
1761   group = get_active_group (play_base_bin);
1762   for (item = group->streaminfo; item; item = item->next) {
1763     GstStreamInfo *info = item->data;
1764     gpointer data;
1765
1766     data = g_object_get_data (G_OBJECT (info->object), "eat_probe");
1767     if (data) {
1768       gst_pad_remove_data_probe (GST_PAD_CAST (info->object),
1769           GPOINTER_TO_INT (data));
1770       g_object_set_data (G_OBJECT (info->object), "eat_probe", NULL);
1771     }
1772
1773     /* now remove unknown pads */
1774     if (info->type == GST_STREAM_TYPE_UNKNOWN) {
1775       guint id;
1776
1777       id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (info), "mute_probe"));
1778       if (id == 0) {
1779         id = gst_pad_add_buffer_probe (GST_PAD_CAST (info->object),
1780             G_CALLBACK (mute_stream), info);
1781         g_object_set_data (G_OBJECT (info), "mute_probe", GINT_TO_POINTER (id));
1782       }
1783     }
1784   }
1785
1786   /* now check if the requested current streams exist. If
1787    * current >= num_streams, decrease current so at least
1788    * we have output. Always keep it enabled. */
1789   for (n = 0; n < NUM_TYPES; n++) {
1790     if (play_base_bin->current[n] >= group->type[n].npads) {
1791       GST_DEBUG_OBJECT (play_base_bin, "reset type %d to current 0", n);
1792       play_base_bin->current[n] = 0;
1793     }
1794   }
1795
1796   /* now activate the right sources. Don't forget that during preroll,
1797    * we set the first source to forwarding and ignored the rest. */
1798   for (n = 0; n < NUM_TYPES; n++) {
1799     GST_DEBUG_OBJECT (play_base_bin, "setting type %d to current %d", n,
1800         play_base_bin->current[n]);
1801     set_active_source (play_base_bin, n + 1, play_base_bin->current[n]);
1802   }
1803 }
1804
1805 /**
1806  * has_all_raw_caps:
1807  * @pad: a #GstPad
1808  * @all_raw: pointer to hold the result
1809  *
1810  * check if the caps of the pad are all raw. The caps are all raw if
1811  * all of its structures contain audio/x-raw or video/x-raw.
1812  *
1813  * Returns: %FALSE @pad has no caps. Else TRUE and @all_raw set t the result.
1814  */
1815 static gboolean
1816 has_all_raw_caps (GstPad * pad, gboolean * all_raw)
1817 {
1818   GstCaps *caps;
1819   gint capssize;
1820   guint i, num_raw = 0;
1821   gboolean res = FALSE;
1822
1823   caps = gst_pad_get_caps (pad);
1824   if (caps == NULL)
1825     return FALSE;
1826
1827   capssize = gst_caps_get_size (caps);
1828   /* no caps, skip and move to the next pad */
1829   if (capssize == 0 || gst_caps_is_empty (caps) || gst_caps_is_any (caps))
1830     goto done;
1831
1832   /* count the number of raw formats in the caps */
1833   for (i = 0; i < capssize; ++i) {
1834     GstStructure *s;
1835     const gchar *mime_type;
1836
1837     s = gst_caps_get_structure (caps, i);
1838     mime_type = gst_structure_get_name (s);
1839
1840     if (IS_RAW_MIME (mime_type))
1841       ++num_raw;
1842   }
1843
1844   *all_raw = (num_raw == capssize);
1845   res = TRUE;
1846
1847 done:
1848   gst_caps_unref (caps);
1849   return res;
1850 }
1851
1852 /**
1853  * analyse_source:
1854  * @play_base_bin: a #GstPlayBaseBin
1855  * @is_raw: are all pads raw data
1856  * @have_out: does the source have output
1857  * @is_dynamic: is this a dynamic source
1858  *
1859  * Check the source of @play_base_bin and collect information about it.
1860  *
1861  * @is_raw will be set to TRUE if the source only produces raw pads. When this
1862  * function returns, all of the raw pad of the source will be added
1863  * to @play_base_bin.
1864  *
1865  * @have_out: will be set to TRUE if the source has output pads.
1866  *
1867  * @is_dynamic: TRUE if the element will create (more) pads dynamically later
1868  * on.
1869  *
1870  * Returns: FALSE if a fatal error occured while scanning.
1871  */
1872 static gboolean
1873 analyse_source (GstPlayBaseBin * play_base_bin, gboolean * is_raw,
1874     gboolean * have_out, gboolean * is_dynamic)
1875 {
1876   GstIterator *pads_iter;
1877   gboolean done = FALSE;
1878   gboolean res = TRUE;
1879
1880   *have_out = FALSE;
1881   *is_raw = FALSE;
1882   *is_dynamic = FALSE;
1883
1884   pads_iter = gst_element_iterate_src_pads (play_base_bin->source);
1885   while (!done) {
1886     GstPad *pad = NULL;
1887
1888     switch (gst_iterator_next (pads_iter, (gpointer) & pad)) {
1889       case GST_ITERATOR_ERROR:
1890         res = FALSE;
1891         /* FALLTROUGH */
1892       case GST_ITERATOR_DONE:
1893         done = TRUE;
1894         break;
1895       case GST_ITERATOR_RESYNC:
1896         /* reset results and resync */
1897         *have_out = FALSE;
1898         *is_raw = FALSE;
1899         *is_dynamic = FALSE;
1900         gst_iterator_resync (pads_iter);
1901         break;
1902       case GST_ITERATOR_OK:
1903         /* we now officially have an output pad */
1904         *have_out = TRUE;
1905
1906         /* if FALSE, this pad has no caps and we continue with the next pad. */
1907         if (!has_all_raw_caps (pad, is_raw)) {
1908           gst_object_unref (pad);
1909           break;
1910         }
1911
1912         /* caps on source pad are all raw, we can add the pad */
1913         if (*is_raw) {
1914           new_decoded_pad_full (play_base_bin->source, pad, FALSE,
1915               play_base_bin, FALSE);
1916         }
1917
1918         gst_object_unref (pad);
1919         break;
1920     }
1921   }
1922   gst_iterator_free (pads_iter);
1923
1924   if (!*have_out) {
1925     GstElementClass *elemclass;
1926     GList *walk;
1927
1928     /* element has no output pads, check for padtemplates that list SOMETIMES
1929      * pads. */
1930     elemclass = GST_ELEMENT_GET_CLASS (play_base_bin->source);
1931
1932     walk = gst_element_class_get_pad_template_list (elemclass);
1933     while (walk != NULL) {
1934       GstPadTemplate *templ;
1935
1936       templ = (GstPadTemplate *) walk->data;
1937       if (GST_PAD_TEMPLATE_DIRECTION (templ) == GST_PAD_SRC) {
1938         if (GST_PAD_TEMPLATE_PRESENCE (templ) == GST_PAD_SOMETIMES) {
1939           *is_dynamic = TRUE;
1940           break;                /* only break out if we found a sometimes src pad
1941                                    continue walking through if say a request src pad is found
1942                                    elements such as mpegtsparse and dvbbasebin have request
1943                                    and sometimes src pads */
1944         }
1945       }
1946       walk = g_list_next (walk);
1947     }
1948   }
1949
1950   return res;
1951 }
1952
1953 static void
1954 remove_decoders (GstPlayBaseBin * bin)
1955 {
1956   GSList *walk;
1957
1958   for (walk = bin->decoders; walk; walk = g_slist_next (walk)) {
1959     GstElement *decoder = GST_ELEMENT_CAST (walk->data);
1960
1961     GST_DEBUG_OBJECT (bin, "removing old decoder element");
1962     /* Disconnect all the signal handlers we attached to the decodebin before
1963      * we dispose of it */
1964     g_signal_handlers_disconnect_by_func (decoder,
1965         (gpointer) (decodebin_element_added_cb), bin);
1966     g_signal_handlers_disconnect_by_func (decoder,
1967         (gpointer) (decodebin_element_removed_cb), bin);
1968     g_signal_handlers_disconnect_by_func (decoder,
1969         (gpointer) (new_decoded_pad), bin);
1970     g_signal_handlers_disconnect_by_func (decoder,
1971         (gpointer) (no_more_pads), bin);
1972     g_signal_handlers_disconnect_by_func (decoder,
1973         (gpointer) (unknown_type), bin);
1974
1975     gst_element_set_state (decoder, GST_STATE_NULL);
1976     gst_bin_remove (GST_BIN_CAST (bin), decoder);
1977   }
1978   g_slist_free (bin->decoders);
1979   bin->decoders = NULL;
1980 }
1981
1982 static GstElement *
1983 make_decoder (GstPlayBaseBin * play_base_bin)
1984 {
1985   GstElement *decoder;
1986
1987   /* now create the decoder element */
1988   if (g_getenv ("USE_DECODEBIN2"))
1989     decoder = gst_element_factory_make ("decodebin2", NULL);
1990   else
1991     decoder = gst_element_factory_make ("decodebin", NULL);
1992   if (!decoder)
1993     goto no_decodebin;
1994
1995   g_signal_connect (decoder, "element-added",
1996       G_CALLBACK (decodebin_element_added_cb), play_base_bin);
1997   g_signal_connect (decoder, "element-removed",
1998       G_CALLBACK (decodebin_element_removed_cb), play_base_bin);
1999
2000   gst_bin_add (GST_BIN_CAST (play_base_bin), decoder);
2001
2002   /* set up callbacks to create the links between decoded data
2003    * and video/audio/subtitle rendering/output. */
2004   g_signal_connect (G_OBJECT (decoder),
2005       "new-decoded-pad", G_CALLBACK (new_decoded_pad), play_base_bin);
2006   g_signal_connect (G_OBJECT (decoder), "no-more-pads",
2007       G_CALLBACK (no_more_pads), play_base_bin);
2008   g_signal_connect (G_OBJECT (decoder),
2009       "unknown-type", G_CALLBACK (unknown_type), play_base_bin);
2010   g_object_set_data (G_OBJECT (decoder), "pending", GINT_TO_POINTER (1));
2011   play_base_bin->pending++;
2012
2013   GST_DEBUG_OBJECT (play_base_bin, "created decodebin, %d pending",
2014       play_base_bin->pending);
2015
2016   play_base_bin->decoders = g_slist_prepend (play_base_bin->decoders, decoder);
2017
2018   return decoder;
2019
2020   /* ERRORS */
2021 no_decodebin:
2022   {
2023     GST_ELEMENT_ERROR (play_base_bin, CORE, MISSING_PLUGIN,
2024         (_("Could not create \"decodebin\" element.")), (NULL));
2025     return NULL;
2026   }
2027 }
2028
2029 static void
2030 remove_source (GstPlayBaseBin * bin)
2031 {
2032   GstElement *source = bin->source;
2033
2034   if (source) {
2035     GST_DEBUG_OBJECT (bin, "removing old src element");
2036     gst_element_set_state (source, GST_STATE_NULL);
2037
2038     if (bin->src_np_sig_id) {
2039       g_signal_handler_disconnect (G_OBJECT (source), bin->src_np_sig_id);
2040       bin->src_np_sig_id = 0;
2041     }
2042     if (bin->src_nmp_sig_id) {
2043       g_signal_handler_disconnect (G_OBJECT (source), bin->src_nmp_sig_id);
2044       bin->src_nmp_sig_id = 0;
2045     }
2046     gst_bin_remove (GST_BIN_CAST (bin), source);
2047     bin->source = NULL;
2048   }
2049 }
2050
2051 static GstBusSyncReply
2052 subbin_startup_sync_msg (GstBus * bus, GstMessage * msg, gpointer user_data)
2053 {
2054   if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) {
2055     GstPlayBaseBin *play_base_bin;
2056
2057     play_base_bin = GST_PLAY_BASE_BIN (user_data);
2058     if (!play_base_bin->subtitle_done) {
2059       GST_WARNING_OBJECT (play_base_bin, "error starting up subtitle bin: %"
2060           GST_PTR_FORMAT, msg);
2061       play_base_bin->subtitle_done = TRUE;
2062       GST_DEBUG_OBJECT (play_base_bin, "signal group done");
2063       GROUP_SIGNAL (play_base_bin);
2064       GST_DEBUG_OBJECT (play_base_bin, "signaled group done");
2065     }
2066   }
2067   return GST_BUS_PASS;
2068 }
2069
2070 /* construct and run the source and decoder elements until we found
2071  * all the streams or until a preroll queue has been filled.
2072 */
2073 static gboolean
2074 setup_source (GstPlayBaseBin * play_base_bin)
2075 {
2076   GstElement *subbin = NULL;
2077   gboolean is_raw, have_out, is_dynamic;
2078
2079   if (!play_base_bin->need_rebuild)
2080     return TRUE;
2081   play_base_bin->raw_decoding_mode = FALSE;
2082
2083   GST_DEBUG_OBJECT (play_base_bin, "setup source");
2084
2085   /* delete old src */
2086   remove_source (play_base_bin);
2087
2088   /* create and configure an element that can handle the uri */
2089   if (!(play_base_bin->source = gen_source_element (play_base_bin, &subbin)))
2090     goto no_source;
2091
2092   /* state will be merged later - if file is not found, error will be
2093    * handled by the application right after. */
2094   gst_bin_add (GST_BIN_CAST (play_base_bin), play_base_bin->source);
2095   g_object_notify (G_OBJECT (play_base_bin), "source");
2096
2097   /* remove the old decoders now, if any */
2098   remove_decoders (play_base_bin);
2099
2100   /* remove our previous preroll queues */
2101   remove_groups (play_base_bin);
2102
2103   /* clear pending dynamic elements */
2104   play_base_bin->pending = 0;
2105
2106   /* do subs */
2107   if (subbin) {
2108     GstElement *db;
2109     GstBus *bus;
2110
2111     play_base_bin->subtitle = subbin;
2112     db = gst_bin_get_by_name (GST_BIN_CAST (subbin), "subtitle-decoder");
2113
2114     /* do type detection, without adding (so no preroll) */
2115     g_signal_connect (G_OBJECT (db), "new-decoded-pad",
2116         G_CALLBACK (subs_new_decoded_pad), play_base_bin);
2117     g_signal_connect (G_OBJECT (db), "no-more-pads",
2118         G_CALLBACK (sub_no_more_pads), play_base_bin);
2119     g_signal_connect (G_OBJECT (db), "unknown-type",
2120         G_CALLBACK (unknown_type), play_base_bin);
2121     g_object_set_data (G_OBJECT (db), "pending", GINT_TO_POINTER (1));
2122     play_base_bin->pending++;
2123
2124     GST_DEBUG_OBJECT (play_base_bin, "we have subtitles, %d pending",
2125         play_base_bin->pending);
2126
2127     if (!play_base_bin->is_stream) {
2128       GstStateChangeReturn sret;
2129
2130       /* either when the queues are filled or when the decoder element
2131        * has no more dynamic streams, the cond is unlocked. We can remove
2132        * the signal handlers then
2133        */
2134       GST_DEBUG_OBJECT (play_base_bin, "starting subtitle bin");
2135
2136       /* for subtitles in a separate bin we will not commit the
2137        * current building group since we need to add the other
2138        * audio/video streams to the group. We check if we managed
2139        * to commit the subtitle group using an extra flag. */
2140       play_base_bin->subtitle_done = FALSE;
2141
2142       /* since subbin is still a stand-alone bin, we need to add a custom bus
2143        * to intercept error messages, so we can stop waiting and continue */
2144       bus = gst_bus_new ();
2145       gst_element_set_bus (subbin, bus);
2146       gst_bus_set_sync_handler (bus, subbin_startup_sync_msg, play_base_bin);
2147
2148       sret = gst_element_set_state (subbin, GST_STATE_PAUSED);
2149       if (sret != GST_STATE_CHANGE_FAILURE) {
2150         GROUP_LOCK (play_base_bin);
2151         GST_DEBUG ("waiting for subtitle to complete...");
2152         while (!play_base_bin->subtitle_done)
2153           GROUP_WAIT (play_base_bin);
2154         GST_DEBUG ("group done !");
2155         GROUP_UNLOCK (play_base_bin);
2156
2157         if (!play_base_bin->building_group ||
2158             play_base_bin->building_group->type[GST_STREAM_TYPE_TEXT -
2159                 1].npads == 0) {
2160
2161           GST_DEBUG ("No subtitle found - ignoring");
2162           gst_element_set_state (subbin, GST_STATE_NULL);
2163           gst_object_unref (play_base_bin->subtitle);
2164           play_base_bin->subtitle = NULL;
2165         } else {
2166           GST_DEBUG_OBJECT (play_base_bin, "Subtitle set-up successful");
2167         }
2168       } else {
2169         GST_WARNING_OBJECT (play_base_bin, "Failed to start subtitle bin");
2170         gst_element_set_state (subbin, GST_STATE_NULL);
2171         gst_object_unref (play_base_bin->subtitle);
2172         play_base_bin->subtitle = NULL;
2173       }
2174
2175       gst_bus_set_sync_handler (bus, NULL, NULL);
2176       gst_element_set_bus (subbin, NULL);
2177       gst_object_unref (bus);
2178     }
2179     gst_object_unref (db);
2180   }
2181   /* see if the source element emits raw audio/video all by itself,
2182    * if so, we can create streams for the pads and be done with it.
2183    * Also check that is has source pads, if not, we assume it will
2184    * do everything itself.  */
2185   if (!analyse_source (play_base_bin, &is_raw, &have_out, &is_dynamic))
2186     goto invalid_source;
2187
2188   if (is_raw) {
2189     GST_DEBUG_OBJECT (play_base_bin, "Source provides all raw data");
2190     /* source provides raw data, we added the pads and we can now signal a
2191      * no_more pads because we are done. */
2192     group_commit (play_base_bin, play_base_bin->is_stream, FALSE);
2193     return TRUE;
2194   }
2195   if (!have_out && !is_dynamic) {
2196     GST_DEBUG_OBJECT (play_base_bin, "Source has no output pads");
2197     /* create a stream to indicate that this uri is handled by a self
2198      * contained element. We are now done. */
2199     add_element_stream (play_base_bin->source, play_base_bin);
2200     group_commit (play_base_bin, play_base_bin->is_stream, FALSE);
2201     return TRUE;
2202   }
2203   if (is_dynamic) {
2204     /* connect a handler for the new-pad signal */
2205     play_base_bin->src_np_sig_id =
2206         g_signal_connect (G_OBJECT (play_base_bin->source), "pad-added",
2207         G_CALLBACK (source_new_pad), play_base_bin);
2208     play_base_bin->src_nmp_sig_id =
2209         g_signal_connect (G_OBJECT (play_base_bin->source), "no-more-pads",
2210         G_CALLBACK (source_no_more_pads), play_base_bin);
2211     g_object_set_data (G_OBJECT (play_base_bin->source), "pending",
2212         GINT_TO_POINTER (1));
2213     play_base_bin->pending++;
2214     GST_DEBUG_OBJECT (play_base_bin,
2215         "Source has dynamic output pads, %d pending", play_base_bin->pending);
2216   } else {
2217     GstElement *decoder;
2218
2219     /* no dynamic source, we can link now */
2220     decoder = make_decoder (play_base_bin);
2221     if (!decoder)
2222       goto no_decodebin;
2223
2224     if (!gst_element_link (play_base_bin->source, decoder))
2225       goto could_not_link;
2226   }
2227
2228   if (play_base_bin->subtitle)
2229     gst_bin_add (GST_BIN_CAST (play_base_bin), play_base_bin->subtitle);
2230
2231   play_base_bin->need_rebuild = FALSE;
2232
2233   return TRUE;
2234
2235   /* ERRORS */
2236 no_source:
2237   {
2238     /* error message was already posted */
2239     return FALSE;
2240   }
2241 invalid_source:
2242   {
2243     GST_ELEMENT_ERROR (play_base_bin, CORE, FAILED,
2244         (_("Source element is invalid.")), (NULL));
2245     return FALSE;
2246   }
2247 no_decodebin:
2248   {
2249     /* message was posted */
2250     return FALSE;
2251   }
2252 could_not_link:
2253   {
2254     GST_ELEMENT_ERROR (play_base_bin, CORE, NEGOTIATION,
2255         (NULL), ("Can't link source to decoder element"));
2256     return FALSE;
2257   }
2258 }
2259
2260 static void
2261 finish_source (GstPlayBaseBin * play_base_bin)
2262 {
2263   /* FIXME: no need to grab the group lock here? (tpm) */
2264   if (get_active_group (play_base_bin) != NULL) {
2265     if (play_base_bin->subtitle) {
2266       /* make subs iterate from now on */
2267       gst_bin_add (GST_BIN_CAST (play_base_bin), play_base_bin->subtitle);
2268     }
2269   }
2270 }
2271
2272 /*
2273  * Caller must have group-lock held.
2274  *
2275  * We iterate over all detected streams in the streaminfo and try to find
2276  * impossible cases, like subtitles without video.
2277  */
2278 static gboolean
2279 prepare_output (GstPlayBaseBin * play_base_bin)
2280 {
2281   const GList *item;
2282   gboolean stream_found = FALSE, no_media = FALSE;
2283   gboolean got_video = FALSE, got_subtitle = FALSE;
2284   GstPlayBaseGroup *group;
2285
2286   group = get_active_group (play_base_bin);
2287
2288   /* check if we found any supported stream... if not, then
2289    * we detected stream type (or the above would've failed),
2290    * but linking/decoding failed - plugin probably missing. */
2291   for (item = group ? group->streaminfo : NULL; item != NULL; item = item->next) {
2292     GstStreamInfo *info = GST_STREAM_INFO (item->data);
2293
2294     if (info->type == GST_STREAM_TYPE_VIDEO) {
2295       stream_found = TRUE;
2296       got_video = TRUE;
2297       break;
2298     } else if (info->type == GST_STREAM_TYPE_ELEMENT) {
2299       stream_found = TRUE;
2300     } else if (info->type == GST_STREAM_TYPE_AUDIO) {
2301       stream_found = TRUE;
2302     } else if (info->type == GST_STREAM_TYPE_TEXT ||
2303         info->type == GST_STREAM_TYPE_SUBPICTURE) {
2304       got_subtitle = TRUE;
2305     } else if (!item->prev && !item->next) {
2306       /* We're no audio/video and the only stream... We could
2307        * be something not-media that's detected because then our
2308        * typefind doesn't mess up with mp3 (bz2, gz, elf, ...) */
2309       if (info->caps && !gst_caps_is_empty (info->caps)) {
2310         const gchar *mime =
2311             gst_structure_get_name (gst_caps_get_structure (info->caps, 0));
2312
2313         no_media = IS_NO_MEDIA_MIME (mime);
2314       }
2315     }
2316   }
2317
2318   if (!stream_found) {
2319     if (got_subtitle) {
2320       GST_ELEMENT_ERROR (play_base_bin, STREAM, WRONG_TYPE,
2321           (_("Only a subtitle stream was detected. "
2322                   "Either you are loading a subtitle file or some other type of "
2323                   "text file, or the media file was not recognized.")), (NULL));
2324     } else if (!no_media) {
2325       GST_ELEMENT_ERROR (play_base_bin, STREAM, CODEC_NOT_FOUND,
2326           (_("You do not have a decoder installed to handle this file. "
2327                   "You might need to install the necessary plugins.")), (NULL));
2328     } else {
2329       GST_ELEMENT_ERROR (play_base_bin, STREAM, WRONG_TYPE,
2330           (_("This is not a media file")), (NULL));
2331     }
2332     return FALSE;
2333   } else if (got_subtitle && !got_video) {
2334     GST_ELEMENT_ERROR (play_base_bin, STREAM, WRONG_TYPE,
2335         (_("A subtitle stream was detected, but no video stream.")), (NULL));
2336     return FALSE;
2337   }
2338
2339   return TRUE;
2340 }
2341
2342 /*
2343  * Multi-stream management. -1 = none.
2344  *
2345  * Caller has group-lock held.
2346  */
2347 static gint
2348 get_active_source (GstPlayBaseBin * play_base_bin, GstStreamType type)
2349 {
2350   GstPlayBaseGroup *group;
2351   GList *s;
2352   gint num = 0;
2353
2354   group = get_active_group (play_base_bin);
2355   if (!group)
2356     return -1;
2357
2358   for (s = group->streaminfo; s; s = s->next) {
2359     GstStreamInfo *info = s->data;
2360
2361     if (info->type == type) {
2362       if (!info->mute && !g_object_get_data (G_OBJECT (info), "mute_probe")) {
2363         return num;
2364       } else {
2365         num++;
2366       }
2367     }
2368   }
2369
2370   return -1;
2371 }
2372
2373 /* Kill pad reactivation on state change. */
2374
2375 #if 0
2376 static void muted_group_change_state (GstElement * element,
2377     gint old_state, gint new_state, gpointer data);
2378 #endif
2379
2380 static void
2381 mute_group_type (GstPlayBaseGroup * group, GstStreamType type, gboolean mute)
2382 {
2383   gboolean active = !mute;
2384   GstPad *pad;
2385
2386   pad = gst_element_get_static_pad (group->type[type - 1].preroll, "src");
2387   gst_pad_set_active (pad, active);
2388   gst_object_unref (pad);
2389   pad = gst_element_get_static_pad (group->type[type - 1].preroll, "sink");
2390   gst_pad_set_active (pad, active);
2391   gst_object_unref (pad);
2392   pad = gst_element_get_static_pad (group->type[type - 1].selector, "src");
2393   gst_pad_set_active (pad, active);
2394   gst_object_unref (pad);
2395
2396 #if 0
2397   if (mute) {
2398     g_signal_connect (group->type[type - 1].preroll, "state-changed",
2399         G_CALLBACK (muted_group_change_state), group);
2400   } else {
2401     g_signal_handlers_disconnect_by_func (group->type[type - 1].preroll,
2402         G_CALLBACK (muted_group_change_state), group);
2403   }
2404 #endif
2405 }
2406
2407 #if 0
2408 static void
2409 muted_group_change_state (GstElement * element,
2410     gint old_state, gint new_state, gpointer data)
2411 {
2412   GstPlayBaseGroup *group = data;
2413
2414   GROUP_LOCK (group->bin);
2415
2416   if (new_state == GST_STATE_PLAYING) {
2417     gint n;
2418
2419     for (n = 0; n < NUM_TYPES; n++) {
2420       if (group->type[n].selector == element) {
2421         mute_group_type (group, n + 1, TRUE);
2422       }
2423     }
2424   }
2425
2426   GROUP_UNLOCK (group->bin);
2427 }
2428 #endif
2429
2430 static void
2431 set_subtitles_visible (GstPlayBaseBin * play_base_bin, gboolean visible)
2432 {
2433   GstPlayBaseBinClass *klass = GST_PLAY_BASE_BIN_GET_CLASS (play_base_bin);
2434
2435   /* we use a vfunc for this since we don't have a reference to the
2436    * textoverlay element, but playbin does */
2437   if (klass != NULL && klass->set_subtitles_visible != NULL)
2438     klass->set_subtitles_visible (play_base_bin, visible);
2439 }
2440
2441 static void
2442 set_audio_mute (GstPlayBaseBin * play_base_bin, gboolean mute)
2443 {
2444   GstPlayBaseBinClass *klass = GST_PLAY_BASE_BIN_GET_CLASS (play_base_bin);
2445
2446   /* we use a vfunc for this since we don't have a reference to the
2447    * textoverlay element, but playbin does */
2448   if (klass != NULL && klass->set_audio_mute != NULL)
2449     klass->set_audio_mute (play_base_bin, mute);
2450 }
2451
2452 /*
2453  * Caller has group-lock held.
2454  */
2455
2456 static void
2457 set_active_source (GstPlayBaseBin * play_base_bin,
2458     GstStreamType type, gint source_num)
2459 {
2460   GstPlayBaseGroup *group;
2461   GList *s;
2462   gint num = 0;
2463   gboolean have_active = FALSE;
2464   GstElement *sel;
2465
2466   GST_LOG ("Changing active source of type %d to %d", type, source_num);
2467   play_base_bin->current[type - 1] = source_num;
2468
2469   group = get_active_group (play_base_bin);
2470   if (!group || !group->type[type - 1].preroll) {
2471     GST_LOG ("No active group, or group for type %d has no preroll", type);
2472     return;
2473   }
2474
2475   /* HACK: instead of unlinking the subtitle input (= lots of hassle,
2476    * especially if subtitles come from an external source), just tell
2477    * textoverlay not to render them */
2478   if (type == GST_STREAM_TYPE_TEXT) {
2479     gboolean visible = (source_num != -1);
2480
2481     set_subtitles_visible (play_base_bin, visible);
2482     if (!visible)
2483       return;
2484   } else if (type == GST_STREAM_TYPE_AUDIO) {
2485     gboolean mute = (source_num == -1);
2486
2487     set_audio_mute (play_base_bin, mute);
2488
2489     if (mute)
2490       return;
2491   }
2492
2493   sel = group->type[type - 1].selector;
2494
2495   for (s = group->streaminfo; s; s = s->next) {
2496     GstStreamInfo *info = s->data;
2497
2498     if (info->type == type) {
2499       if (num == source_num) {
2500         GstPad *sel_pad;
2501
2502         GST_LOG ("Unmuting (if already muted) source %d of type %d", source_num,
2503             type);
2504         g_object_set (info, "mute", FALSE, NULL);
2505
2506         /* Tell the stream selector which pad to accept */
2507         sel_pad = GST_PAD_CAST (g_object_get_data (G_OBJECT (info->object),
2508                 "pb_sel_pad"));
2509
2510         if (sel && sel_pad != NULL) {
2511           g_object_set (G_OBJECT (sel), "active-pad", sel_pad, NULL);
2512         }
2513
2514         have_active = TRUE;
2515       } else {
2516         guint id;
2517
2518         GST_LOG_OBJECT (info->object, "Muting source %d of type %d", num, type);
2519
2520         id = gst_pad_add_buffer_probe (GST_PAD_CAST (info->object),
2521             G_CALLBACK (mute_stream), info);
2522         g_object_set_data (G_OBJECT (info), "mute_probe", GINT_TO_POINTER (id));
2523       }
2524       num++;
2525     }
2526   }
2527
2528   if (!have_active) {
2529     GST_LOG ("Muting group type: %d", type);
2530     g_object_set (sel, "active-pad", NULL, NULL);
2531   } else {
2532     GST_LOG ("Unmuting group type: %d", type);
2533   }
2534   mute_group_type (group, type, !have_active);
2535 }
2536
2537 static void
2538 gst_play_base_bin_set_property (GObject * object, guint prop_id,
2539     const GValue * value, GParamSpec * pspec)
2540 {
2541   GstPlayBaseBin *play_base_bin;
2542
2543   g_return_if_fail (GST_IS_PLAY_BASE_BIN (object));
2544
2545   play_base_bin = GST_PLAY_BASE_BIN (object);
2546
2547   switch (prop_id) {
2548     case ARG_URI:
2549     {
2550       const gchar *uri = g_value_get_string (value);
2551
2552       if (uri == NULL) {
2553         g_warning ("cannot set NULL uri");
2554         return;
2555       }
2556       /* if we have no previous uri, or the new uri is different from the
2557        * old one, replug */
2558       if (play_base_bin->uri == NULL || strcmp (play_base_bin->uri, uri) != 0) {
2559         g_free (play_base_bin->uri);
2560         play_base_bin->uri = g_strdup (uri);
2561
2562         GST_DEBUG ("setting new uri to %s", uri);
2563
2564         play_base_bin->need_rebuild = TRUE;
2565       }
2566       break;
2567     }
2568     case ARG_SUBURI:{
2569       const gchar *suburi = g_value_get_string (value);
2570
2571       if ((!suburi && !play_base_bin->suburi) ||
2572           (suburi && play_base_bin->suburi &&
2573               !strcmp (play_base_bin->suburi, suburi)))
2574         return;
2575       g_free (play_base_bin->suburi);
2576       play_base_bin->suburi = g_strdup (suburi);
2577       GST_DEBUG ("setting new .sub uri to %s", suburi);
2578       play_base_bin->need_rebuild = TRUE;
2579       break;
2580     }
2581     case ARG_QUEUE_SIZE:
2582       play_base_bin->queue_size = g_value_get_uint64 (value);
2583       break;
2584     case ARG_QUEUE_THRESHOLD:
2585       play_base_bin->queue_threshold = g_value_get_uint64 (value);
2586       break;
2587     case ARG_QUEUE_MIN_THRESHOLD:
2588       play_base_bin->queue_min_threshold = g_value_get_uint64 (value);
2589       break;
2590     case ARG_CONNECTION_SPEED:
2591       play_base_bin->connection_speed = g_value_get_uint (value) * 1000;
2592       break;
2593     case ARG_VIDEO:
2594       GROUP_LOCK (play_base_bin);
2595       set_active_source (play_base_bin,
2596           GST_STREAM_TYPE_VIDEO, g_value_get_int (value));
2597       GROUP_UNLOCK (play_base_bin);
2598       break;
2599     case ARG_AUDIO:
2600       GROUP_LOCK (play_base_bin);
2601       set_active_source (play_base_bin,
2602           GST_STREAM_TYPE_AUDIO, g_value_get_int (value));
2603       GROUP_UNLOCK (play_base_bin);
2604       break;
2605     case ARG_TEXT:
2606       GROUP_LOCK (play_base_bin);
2607       set_active_source (play_base_bin,
2608           GST_STREAM_TYPE_TEXT, g_value_get_int (value));
2609       GROUP_UNLOCK (play_base_bin);
2610       break;
2611     case ARG_SUBTITLE_ENCODING:
2612     {
2613       const gchar *encoding;
2614       GSList *list;
2615
2616       encoding = g_value_get_string (value);
2617       if (encoding && play_base_bin->subencoding &&
2618           !strcmp (play_base_bin->subencoding, encoding)) {
2619         return;
2620       }
2621       if (encoding == NULL && play_base_bin->subencoding == NULL)
2622         return;
2623
2624       g_mutex_lock (play_base_bin->sub_lock);
2625       g_free (play_base_bin->subencoding);
2626       play_base_bin->subencoding = g_strdup (encoding);
2627       list = g_slist_copy (play_base_bin->subtitle_elements);
2628       g_slist_foreach (list, (GFunc) gst_object_ref, NULL);
2629       g_mutex_unlock (play_base_bin->sub_lock);
2630
2631       /* we can't hold a lock when calling g_object_set() on a child, since
2632        * the notify event will trigger GstObject to send a deep-notify event
2633        * which will try to take the lock ... */
2634       g_slist_foreach (list, (GFunc) set_encoding_element, (gpointer) encoding);
2635       g_slist_foreach (list, (GFunc) gst_object_unref, NULL);
2636       g_slist_free (list);
2637       break;
2638     }
2639     default:
2640       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2641       break;
2642   }
2643 }
2644
2645 static void
2646 gst_play_base_bin_get_property (GObject * object, guint prop_id, GValue * value,
2647     GParamSpec * pspec)
2648 {
2649   GstPlayBaseBin *play_base_bin;
2650
2651   g_return_if_fail (GST_IS_PLAY_BASE_BIN (object));
2652
2653   play_base_bin = GST_PLAY_BASE_BIN (object);
2654
2655   switch (prop_id) {
2656     case ARG_URI:
2657       g_value_set_string (value, play_base_bin->uri);
2658       break;
2659     case ARG_SUBURI:
2660       g_value_set_string (value, play_base_bin->suburi);
2661       break;
2662     case ARG_NSTREAMS:
2663     {
2664       GstPlayBaseGroup *group;
2665
2666       GROUP_LOCK (play_base_bin);
2667       group = get_active_group (play_base_bin);
2668       if (group) {
2669         g_value_set_int (value, group->nstreams);
2670       } else {
2671         g_value_set_int (value, 0);
2672       }
2673       GROUP_UNLOCK (play_base_bin);
2674       break;
2675     }
2676     case ARG_QUEUE_SIZE:
2677       g_value_set_uint64 (value, play_base_bin->queue_size);
2678       break;
2679     case ARG_QUEUE_THRESHOLD:
2680       g_value_set_uint64 (value, play_base_bin->queue_threshold);
2681       break;
2682     case ARG_QUEUE_MIN_THRESHOLD:
2683       g_value_set_uint64 (value, play_base_bin->queue_min_threshold);
2684       break;
2685     case ARG_CONNECTION_SPEED:
2686       g_value_set_uint (value, play_base_bin->connection_speed / 1000);
2687       break;
2688     case ARG_STREAMINFO:
2689       /* FIXME: hold some kind of lock here, use iterator */
2690       g_value_set_pointer (value,
2691           (gpointer) gst_play_base_bin_get_streaminfo (play_base_bin));
2692       break;
2693     case ARG_STREAMINFO_VALUES:{
2694       GValueArray *copy;
2695
2696       copy = gst_play_base_bin_get_streaminfo_value_array (play_base_bin);
2697       g_value_take_boxed (value, copy);
2698       break;
2699     }
2700     case ARG_SOURCE:
2701       g_value_set_object (value, play_base_bin->source);
2702       break;
2703     case ARG_VIDEO:
2704       GROUP_LOCK (play_base_bin);
2705       g_value_set_int (value, get_active_source (play_base_bin,
2706               GST_STREAM_TYPE_VIDEO));
2707       GROUP_UNLOCK (play_base_bin);
2708       break;
2709     case ARG_AUDIO:
2710       GROUP_LOCK (play_base_bin);
2711       g_value_set_int (value, get_active_source (play_base_bin,
2712               GST_STREAM_TYPE_AUDIO));
2713       GROUP_UNLOCK (play_base_bin);
2714       break;
2715     case ARG_TEXT:
2716       GROUP_LOCK (play_base_bin);
2717       g_value_set_int (value, get_active_source (play_base_bin,
2718               GST_STREAM_TYPE_TEXT));
2719       GROUP_UNLOCK (play_base_bin);
2720       break;
2721     case ARG_SUBTITLE_ENCODING:
2722       GST_OBJECT_LOCK (play_base_bin);
2723       g_value_set_string (value, play_base_bin->subencoding);
2724       GST_OBJECT_UNLOCK (play_base_bin);
2725       break;
2726     default:
2727       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
2728       break;
2729   }
2730 }
2731
2732 static GstStateChangeReturn
2733 gst_play_base_bin_change_state (GstElement * element, GstStateChange transition)
2734 {
2735   GstStateChangeReturn ret;
2736   GstPlayBaseBin *play_base_bin;
2737
2738   play_base_bin = GST_PLAY_BASE_BIN (element);
2739
2740   switch (transition) {
2741     case GST_STATE_CHANGE_READY_TO_PAUSED:
2742       if (!setup_source (play_base_bin))
2743         goto source_failed;
2744       break;
2745     default:
2746       break;
2747   }
2748
2749   ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
2750
2751   switch (transition) {
2752     case GST_STATE_CHANGE_READY_TO_PAUSED:
2753       if (ret == GST_STATE_CHANGE_FAILURE)
2754         goto cleanup_groups;
2755
2756       finish_source (play_base_bin);
2757       break;
2758       /* clean-up in both cases, READY=>NULL clean-up is if there was an error */
2759     case GST_STATE_CHANGE_PAUSED_TO_READY:
2760     case GST_STATE_CHANGE_READY_TO_NULL:
2761       play_base_bin->need_rebuild = TRUE;
2762       remove_decoders (play_base_bin);
2763       remove_groups (play_base_bin);
2764       remove_source (play_base_bin);
2765       break;
2766     default:
2767       break;
2768   }
2769   return ret;
2770
2771   /* ERRORS */
2772 source_failed:
2773   {
2774     play_base_bin->need_rebuild = TRUE;
2775
2776     return GST_STATE_CHANGE_FAILURE;
2777   }
2778 cleanup_groups:
2779   {
2780     /* clean up leftover groups */
2781     remove_groups (play_base_bin);
2782     play_base_bin->need_rebuild = TRUE;
2783
2784     return GST_STATE_CHANGE_FAILURE;
2785   }
2786 }
2787
2788 static const GList *
2789 gst_play_base_bin_get_streaminfo (GstPlayBaseBin * play_base_bin)
2790 {
2791   GstPlayBaseGroup *group = get_active_group (play_base_bin);
2792   GList *info = NULL;
2793
2794   if (group) {
2795     info = group->streaminfo;
2796   }
2797   return info;
2798 }
2799
2800 static GValueArray *
2801 gst_play_base_bin_get_streaminfo_value_array (GstPlayBaseBin * play_base_bin)
2802 {
2803   GstPlayBaseGroup *group;
2804   GValueArray *array = NULL;
2805
2806   GROUP_LOCK (play_base_bin);
2807   group = get_active_group (play_base_bin);
2808   if (group) {
2809     array = g_value_array_copy (group->streaminfo_value_array);
2810   } else {
2811     array = g_value_array_new (0);
2812   }
2813   GROUP_UNLOCK (play_base_bin);
2814
2815   return array;
2816 }