gst/playback/gstplaybasebin.c: Don't block for streams.
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Tue, 25 Jan 2005 10:51:48 +0000 (10:51 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Tue, 25 Jan 2005 10:51:48 +0000 (10:51 +0000)
Original commit message from CVS:
* gst/playback/gstplaybasebin.c: (group_commit),
(gen_preroll_element), (probe_triggered), (gen_source_element),
(setup_source), (gst_play_base_bin_change_state),
(gst_play_base_bin_add_element):
Don't block for streams.
* gst/playback/gststreaminfo.c: (stream_info_change_state),
(gst_stream_info_set_mute):
Use gst_pad_set_active_recursive.

ChangeLog
gst/playback/gstplaybasebin.c
gst/playback/gststreaminfo.c

index d0e175d..4730050 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2005-01-25  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
+
+       * gst/playback/gstplaybasebin.c: (group_commit),
+       (gen_preroll_element), (probe_triggered), (gen_source_element),
+       (setup_source), (gst_play_base_bin_change_state),
+       (gst_play_base_bin_add_element):
+         Don't block for streams.
+       * gst/playback/gststreaminfo.c: (stream_info_change_state),
+       (gst_stream_info_set_mute):
+         Use gst_pad_set_active_recursive.
+
 2005-01-25  Andy Wingo  <wingo@pobox.com>
 
        * sys/v4l/gstv4lelement.c (gst_v4l_iface_supported): Fix compile
index 05e88ee..eff94ae 100644 (file)
@@ -373,6 +373,7 @@ static void
 group_commit (GstPlayBaseBin * play_base_bin, gboolean fatal)
 {
   GstPlayBaseGroup *group = play_base_bin->building_group;
+  gboolean had_active_group = (get_active_group (play_base_bin) != NULL);
 
   /* if an element signalled a no-more-pads after we stopped due
    * to preroll, the group is NULL. This is not an error */
@@ -414,6 +415,14 @@ group_commit (GstPlayBaseBin * play_base_bin, gboolean fatal)
   g_cond_signal (play_base_bin->group_cond);
   GST_DEBUG ("signaled group done");
   g_mutex_unlock (play_base_bin->group_lock);
+
+  if (!had_active_group && GST_STATE (play_base_bin) > GST_STATE_READY) {
+    setup_substreams (play_base_bin);
+    GST_DEBUG ("Emitting signal");
+    g_signal_emit (play_base_bin,
+        gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0);
+    GST_DEBUG ("done");
+  }
 }
 
 /* check if there are streams in the group that are not muted */
@@ -504,7 +513,12 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin,
     gst_bin_add (GST_BIN (play_base_bin->thread), preroll);
     gst_element_set_state (selector, GST_STATE_PLAYING);
   }
-  gst_element_set_state (preroll, GST_STATE_PAUSED);
+  if (GST_STATE (play_base_bin) == GST_STATE_PLAYING &&
+      !get_active_group (play_base_bin)) {
+    gst_element_set_state (preroll, GST_STATE_PLAYING);
+  } else {
+    gst_element_set_state (preroll, GST_STATE_PAUSED);
+  }
 
   play_base_bin->threaded = TRUE;
 }
@@ -648,15 +662,6 @@ probe_triggered (GstProbe * probe, GstData ** data, gpointer user_data)
       }
 
       if (have_left) {
-        g_mutex_lock (play_base_bin->group_lock);
-        while (g_list_length (play_base_bin->queued_groups) < 2 &&
-            GST_STATE (play_base_bin->thread) == GST_STATE_PLAYING) {
-          GST_DEBUG ("Waiting for new groups");
-          g_cond_wait (play_base_bin->group_cond, play_base_bin->group_lock);
-          GST_DEBUG ("done");
-        }
-        g_mutex_unlock (play_base_bin->group_lock);
-
         /* error? */
         if (GST_STATE (play_base_bin->thread) != GST_STATE_PLAYING)
           return TRUE;
@@ -671,14 +676,16 @@ probe_triggered (GstProbe * probe, GstData ** data, gpointer user_data)
          * active */
         play_base_bin->queued_groups =
             g_list_remove (play_base_bin->queued_groups, group);
-        setup_substreams (play_base_bin);
-        GST_DEBUG ("switching to next group %p",
-            play_base_bin->queued_groups->data);
-        /* and signal the new group */
-        GST_DEBUG ("emit signal");
-        g_signal_emit (play_base_bin,
-            gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0);
-
+        if (play_base_bin->queued_groups) {
+          setup_substreams (play_base_bin);
+          GST_DEBUG ("switching to next group %p",
+              play_base_bin->queued_groups->data);
+          /* and signal the new group */
+          GST_DEBUG ("emit signal");
+          g_signal_emit (play_base_bin,
+              gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0);
+        }
+        /* else, it'll be handled in commit_group */
         GST_DEBUG ("Syncing state from %d", GST_STATE (play_base_bin->thread));
         gst_element_set_state (play_base_bin->thread, GST_STATE_PLAYING);
         GST_DEBUG ("done");
@@ -988,7 +995,8 @@ setup_subtitle (GstPlayBaseBin * play_base_bin, gchar * sub_uri)
  */
 
 static GstElement *
-gen_source_element (GstPlayBaseBin * play_base_bin, GstElement ** subbin)
+gen_source_element (GstPlayBaseBin * play_base_bin,
+    GstElement ** subbin, gboolean * _is_stream)
 {
   GstElement *source, *queue, *bin;
   GstProbe *probe;
@@ -1011,7 +1019,7 @@ gen_source_element (GstPlayBaseBin * play_base_bin, GstElement ** subbin)
     return NULL;
 
   /* lame - FIXME, maybe we can use seek_types/mask here? */
-  is_stream = !strncmp (play_base_bin->uri, "http://", 7) ||
+  *_is_stream = is_stream = !strncmp (play_base_bin->uri, "http://", 7) ||
       !strncmp (play_base_bin->uri, "mms://", 6);
   if (!is_stream)
     return source;
@@ -1089,12 +1097,14 @@ setup_substreams (GstPlayBaseBin * play_base_bin)
  * all the streams or until a preroll queue has been filled.
  */
 static gboolean
-setup_source (GstPlayBaseBin * play_base_bin, GError ** error)
+setup_source (GstPlayBaseBin * play_base_bin,
+    gboolean * _stream, GError ** error)
 {
   GstElement *old_src;
   GstElement *old_dec;
   GstPad *srcpad = NULL;
   GstElement *subbin;
+  gboolean stream;
 
   if (!play_base_bin->need_rebuild)
     return TRUE;
@@ -1105,7 +1115,8 @@ setup_source (GstPlayBaseBin * play_base_bin, GError ** error)
   old_src = play_base_bin->source;
 
   /* create and configure an element that can handle the uri */
-  play_base_bin->source = gen_source_element (play_base_bin, &subbin);
+  play_base_bin->source = gen_source_element (play_base_bin, &subbin, &stream);
+  *_stream = stream;
 
   if (!play_base_bin->source) {
     /* whoops, could not create the source element */
@@ -1243,33 +1254,39 @@ setup_source (GstPlayBaseBin * play_base_bin, GError ** error)
         "removed-decoded-pad", G_CALLBACK (removed_decoded_pad), play_base_bin);
     sig3 = g_signal_connect (G_OBJECT (play_base_bin->decoder), "no-more-pads",
         G_CALLBACK (no_more_pads), play_base_bin);
-    sig4 = g_signal_connect (G_OBJECT (play_base_bin->decoder), "unknown-type",
-        G_CALLBACK (unknown_type), play_base_bin);
-    sig5 = g_signal_connect (G_OBJECT (play_base_bin->thread), "error",
-        G_CALLBACK (thread_error), error);
-
-    /* either when the queues are filled or when the decoder element has no more
-     * dynamic streams, the cond is unlocked. We can remove the signal handlers then
-     */
-    g_mutex_lock (play_base_bin->group_lock);
-    if (gst_element_set_state (play_base_bin->thread, GST_STATE_PLAYING) ==
-        GST_STATE_SUCCESS) {
-      GST_DEBUG ("waiting for first group...");
-      sig6 = g_signal_connect (G_OBJECT (play_base_bin->thread),
-          "state-change", G_CALLBACK (state_change), play_base_bin);
-      g_cond_wait (play_base_bin->group_cond, play_base_bin->group_lock);
-      GST_DEBUG ("group done !");
-    } else {
-      GST_DEBUG ("state change failed, media cannot be loaded");
-      sig6 = 0;
-    }
-    g_mutex_unlock (play_base_bin->group_lock);
 
-    if (sig6 != 0)
-      g_signal_handler_disconnect (G_OBJECT (play_base_bin->thread), sig6);
+    if (!stream) {
+      sig4 = g_signal_connect (G_OBJECT (play_base_bin->decoder),
+          "unknown-type", G_CALLBACK (unknown_type), play_base_bin);
+      sig5 = g_signal_connect (G_OBJECT (play_base_bin->thread), "error",
+          G_CALLBACK (thread_error), error);
+
+      /* either when the queues are filled or when the decoder element
+       * has no more dynamic streams, the cond is unlocked. We can remove
+       * the signal handlers then
+       */
+      g_mutex_lock (play_base_bin->group_lock);
+      if (gst_element_set_state (play_base_bin->thread, GST_STATE_PLAYING) ==
+          GST_STATE_SUCCESS) {
+        GST_DEBUG ("waiting for first group...");
+        sig6 = g_signal_connect (G_OBJECT (play_base_bin->thread),
+            "state-change", G_CALLBACK (state_change), play_base_bin);
+        g_cond_wait (play_base_bin->group_cond, play_base_bin->group_lock);
+        GST_DEBUG ("group done !");
+      } else {
+        GST_DEBUG ("state change failed, media cannot be loaded");
+        sig6 = 0;
+      }
+      g_mutex_unlock (play_base_bin->group_lock);
+
+      if (sig6 != 0)
+        g_signal_handler_disconnect (G_OBJECT (play_base_bin->thread), sig6);
 
-    g_signal_handler_disconnect (G_OBJECT (play_base_bin->thread), sig5);
-    g_signal_handler_disconnect (G_OBJECT (play_base_bin->decoder), sig4);
+      g_signal_handler_disconnect (G_OBJECT (play_base_bin->thread), sig5);
+      g_signal_handler_disconnect (G_OBJECT (play_base_bin->decoder), sig4);
+    } else {
+      GST_DEBUG ("Source is a stream, delaying stream initialization");
+    }
 
     play_base_bin->need_rebuild = FALSE;
   }
@@ -1279,7 +1296,9 @@ setup_source (GstPlayBaseBin * play_base_bin, GError ** error)
       /* make subs iterate from now on */
       gst_bin_add (GST_BIN (play_base_bin->thread), play_base_bin->subtitle);
     }
-    setup_substreams (play_base_bin);
+    if (!stream) {
+      setup_substreams (play_base_bin);
+    }
   }
 
   return TRUE;
@@ -1564,8 +1583,9 @@ gst_play_base_bin_change_state (GstElement * element)
     case GST_STATE_READY_TO_PAUSED:
     {
       GError *error = NULL;
+      gboolean stream;
 
-      if (!setup_source (play_base_bin, &error) || error != NULL) {
+      if (!setup_source (play_base_bin, &stream, &error) || error != NULL) {
         if (!error) {
           /* opening failed but no error - hellup */
           GST_ELEMENT_ERROR (GST_ELEMENT (play_base_bin), STREAM,
@@ -1578,6 +1598,8 @@ gst_play_base_bin_change_state (GstElement * element)
           g_error_free (error);
         }
         ret = GST_STATE_FAILURE;
+      } else if (stream) {
+        ret = gst_element_set_state (play_base_bin->thread, GST_STATE_PAUSED);
       } else {
         const GList *item;
         gboolean stream_found = FALSE, no_media = FALSE;
@@ -1640,10 +1662,12 @@ gst_play_base_bin_change_state (GstElement * element)
             G_CALLBACK (gst_play_base_bin_error), play_base_bin);
         g_signal_connect (G_OBJECT (play_base_bin->thread), "eos",
             G_CALLBACK (play_base_eos), play_base_bin);
-        GST_DEBUG ("emit signal");
-        g_signal_emit (play_base_bin,
-            gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0);
-        GST_DEBUG ("done");
+        if (!stream) {
+          GST_DEBUG ("emit signal");
+          g_signal_emit (play_base_bin,
+              gst_play_base_bin_signals[SETUP_OUTPUT_PADS_SIGNAL], 0);
+          GST_DEBUG ("done");
+        }
       } else {
         /* clean up leftover groups */
         remove_groups (play_base_bin);
@@ -1708,6 +1732,9 @@ gst_play_base_bin_add_element (GstBin * bin, GstElement * element)
       element = thread;
     }
     gst_bin_add (GST_BIN (play_base_bin->thread), element);
+    if (GST_STATE (play_base_bin) > GST_STATE_READY) {
+      gst_element_set_state (element, GST_STATE (play_base_bin));
+    }
 
     /* hack, the clock is not correctly distributed in the core */
     sched = gst_element_get_scheduler (GST_ELEMENT (play_base_bin->thread));
index 08fcb74..160738c 100644 (file)
@@ -216,42 +216,6 @@ gst_stream_info_dispose (GObject * object)
 }
 
 static void
-stream_info_mute_pad (GstStreamInfo * stream_info, GstPad * pad, gboolean mute)
-{
-  GList *int_links;
-  gboolean activate = !mute;
-  gchar *debug_str = (activate ? "activate" : "inactivate");
-
-  GST_DEBUG_OBJECT (stream_info, "%s %s:%s", debug_str,
-      GST_DEBUG_PAD_NAME (pad));
-  gst_pad_set_active (pad, activate);
-  if (gst_pad_get_parent (pad)->numsrcpads > 1)
-    return;
-
-  for (int_links = gst_pad_get_internal_links (pad);
-      int_links; int_links = g_list_next (int_links)) {
-    GstPad *pad = GST_PAD (int_links->data);
-    GstPad *peer = gst_pad_get_peer (pad);
-    GstElement *peer_elem = peer ? gst_pad_get_parent (peer) : NULL;
-
-    GST_DEBUG_OBJECT (stream_info, "%s internal pad %s:%s",
-        debug_str, GST_DEBUG_PAD_NAME (pad));
-
-    gst_pad_set_active (pad, activate);
-
-    if (peer_elem && peer_elem->numsrcpads == 1) {
-      GST_DEBUG_OBJECT (stream_info, "recursing element %s on pad %s:%s",
-          gst_element_get_name (peer_elem), GST_DEBUG_PAD_NAME (peer));
-      stream_info_mute_pad (stream_info, peer, mute);
-    } else if (peer) {
-      GST_DEBUG_OBJECT (stream_info, "%s final pad %s:%s",
-          debug_str, GST_DEBUG_PAD_NAME (peer));
-      gst_pad_set_active (peer, activate);
-    }
-  }
-}
-
-static void
 stream_info_change_state (GstElement * element,
     gint old_state, gint new_state, gpointer data)
 {
@@ -261,7 +225,7 @@ stream_info_change_state (GstElement * element,
     /* state change will annoy us */
     g_return_if_fail (stream_info->mute == TRUE);
     GST_DEBUG_OBJECT (stream_info, "Re-muting pads after state-change");
-    stream_info_mute_pad (stream_info, GST_PAD (stream_info->object), TRUE);
+    gst_pad_set_active_recursive (GST_PAD (stream_info->object), FALSE);
   }
 }
 
@@ -277,8 +241,8 @@ gst_stream_info_set_mute (GstStreamInfo * stream_info, gboolean mute)
 
   if (mute != stream_info->mute) {
     stream_info->mute = mute;
-    stream_info_mute_pad (stream_info,
-        (GstPad *) GST_PAD_REALIZE (stream_info->object), mute);
+    gst_pad_set_active_recursive ((GstPad *)
+        GST_PAD_REALIZE (stream_info->object), !mute);
 
     if (mute) {
       g_signal_connect (gst_pad_get_parent ((GstPad *)