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