wtay gst-plugins-base: gst-plugins-base/ gst-plugins-base/gst/playback/

[email protected] Wed, 7 Jan 2009 05:52:28 -0800 (PST)
Newsgroups gmane.comp.video.gstreamer.cvs
Message-ID <[email protected]>
--===============4693498646305374251==

CVS Root:       /cvs/gstreamer
Module:         gst-plugins-base
Changes by:     wtay
Date:           Wed Jan 07 2009  13:52:28 UTC

Log message:
* gst/playback/gstplaybin2.c: (gst_play_bin_class_init),
(gst_play_bin_set_uri), (gst_play_bin_set_suburi),
(no_more_pads_cb), (drained_cb), (group_set_locked_state_unlocked),
(activate_group), (deactivate_group), (groups_set_locked_state),
(gst_play_bin_change_state):
Fix some comments and docs.
Post an error message when we fail to link the selector to the sink.
Remove pushing of EOS, this seems unneeded.
Lock the state of deactivated groups so that they don't accidentally
reactivate when the playbin2 state changes.
Reuse uridecodebins.
Unlock and relock state of groups when playbin goes to NULL.
Fixes #566654.
Fixes #566341.
* gst/playback/gsturidecodebin.c: (pad_removed_cb), (type_found):
Only do something in the pad removed callback when we are dealing with
our sourcepads because the sinkpads don't have a ghostpad.

Modified files:
    .               : ChangeLog
    gst/playback    : gstplaybin2.c gsturidecodebin.c

Links:
http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/ChangeLog.diff?r1=1.4280&r2=1.4281
http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst/playback/gstplaybin2.c.diff?r1=1.32&r2=1.33
http://freedesktop.org/cgi-bin/viewcvs.cgi/gstreamer/gst-plugins-base/gst/playback/gsturidecodebin.c.diff?r1=1.22&r2=1.23

====Begin Diffs====
Index: ChangeLog
===================================================================
RCS file: /cvs/gstreamer/gst-plugins-base/ChangeLog,v
retrieving revision 1.4280
retrieving revision 1.4281
diff -u -d -r1.4280 -r1.4281
--- ChangeLog	7 Jan 2009 10:50:12 -0000	1.4280
+++ ChangeLog	7 Jan 2009 13:52:12 -0000	1.4281
@@ -1,3 +1,24 @@
+2009-01-07  Wim Taymans  <[email protected]>
+
+	* gst/playback/gstplaybin2.c: (gst_play_bin_class_init),
+	(gst_play_bin_set_uri), (gst_play_bin_set_suburi),
+	(no_more_pads_cb), (drained_cb), (group_set_locked_state_unlocked),
+	(activate_group), (deactivate_group), (groups_set_locked_state),
+	(gst_play_bin_change_state):
+	Fix some comments and docs.
+	Post an error message when we fail to link the selector to the sink.
+	Remove pushing of EOS, this seems unneeded. 
+	Lock the state of deactivated groups so that they don't accidentally
+	reactivate when the playbin2 state changes.
+	Reuse uridecodebins.
+	Unlock and relock state of groups when playbin goes to NULL.
+	Fixes #566654.
+	Fixes #566341.
+	* gst/playback/gsturidecodebin.c: (pad_removed_cb), (type_found):
+	Only do something in the pad removed callback when we are dealing with
+	our sourcepads because the sinkpads don't have a ghostpad.
 2009-01-07  Sebastian Dröge  <[email protected]>
 
 	* gst-libs/gst/cdda/gstcddabasesrc.c:
Index: gstplaybin2.c
RCS file: /cvs/gstreamer/gst-plugins-base/gst/playback/gstplaybin2.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- gstplaybin2.c	5 Jan 2009 12:18:52 -0000	1.32
+++ gstplaybin2.c	7 Jan 2009 13:52:14 -0000	1.33
@@ -732,7 +732,7 @@
    * @playbin: a #GstPlayBin2
    *
    * This signal is emitted when the current uri is about to finish. You can
-   * set the next-uri and next-suburi to make sure that playback continues.
+   * set the uri and suburi to make sure that playback continues.
    */
   gst_play_bin_signals[SIGNAL_ABOUT_TO_FINISH] =
       g_signal_new ("about-to-finish", G_TYPE_FROM_CLASS (klass),
@@ -1022,14 +1022,13 @@
   group = playbin->next_group;
   GST_SOURCE_GROUP_LOCK (group);
-  /* if we have no previous uri, or the new uri is different from the
-   * old one, replug */
+  /* store the uri in the next group we will play */
   g_free (group->uri);
   group->uri = g_strdup (uri);
   group->valid = TRUE;
   GST_SOURCE_GROUP_UNLOCK (group);
-  GST_DEBUG ("setting new uri to %s", uri);
+  GST_DEBUG ("set new uri to %s", uri);
   GST_PLAY_BIN_UNLOCK (playbin);
 }
@@ -1042,17 +1041,12 @@
-  if ((!suburi && !group->suburi) ||
-      (suburi && group->suburi && !strcmp (group->suburi, suburi)))
-    goto done;
-
   g_free (group->suburi);
   group->suburi = g_strdup (suburi);
+  GST_SOURCE_GROUP_UNLOCK (group);
   GST_DEBUG ("setting new .sub uri to %s", suburi);
-done:
-  GST_SOURCE_GROUP_UNLOCK (group);
@@ -1894,6 +1888,11 @@
       res = gst_pad_link (select->srcpad, select->sinkpad);
       GST_DEBUG_OBJECT (playbin, "linked type %s, result: %d", select->media,
           res);
+      if (res != GST_PAD_LINK_OK) {
+        GST_ELEMENT_ERROR (playbin, CORE, PAD,
+            ("Internal playbin error."),
+            ("Failed to link selector to sink. Error %d", res));
+      }
     }
   }
   GST_DEBUG_OBJECT (playbin, "pending %d > %d", group->pending,
@@ -1944,41 +1943,6 @@
-/* send an EOS event to all of the selectors */
-static void
-perform_eos (GstPlayBin * playbin, GstSourceGroup * group)
-{
-  gboolean res;
-  GstEvent *event;
-  gint i;
-  GST_DEBUG_OBJECT (playbin, "doing EOS in group %p", group);
-  event = gst_event_new_eos ();
-  res = FALSE;
-  GST_SOURCE_GROUP_LOCK (group);
-  for (i = 0; i < GST_PLAY_SINK_TYPE_LAST; i++) {
-    GstSourceSelect *select = &group->selector[i];
-    if (select->selector) {
-      GST_DEBUG_OBJECT (playbin, "send EOS in selector %s", select->media);
-      gst_event_ref (event);
-      res |= gst_pad_push_event (select->srcpad, event);
-    }
-  }
-  gst_event_unref (event);
-  if (!res) {
-    /* we cannot post an error because we don't know if the EOS failed because
-     * of a fatal error or simply a pipeline shutdown */
-    GST_ERROR_OBJECT (playbin, "failed to send EOS");
-}
 static void
 drained_cb (GstElement * decodebin, GstSourceGroup * group)
 {
@@ -2000,9 +1964,7 @@
   /* now activate the next group. If the app did not set a next-uri, this will
    * fail and we can do EOS */
-  if (!setup_next_source (playbin)) {
-    perform_eos (playbin, group);
+  setup_next_source (playbin);
 /* Called when we must provide a list of factories to plug to @pad with @caps.
@@ -2124,6 +2086,20 @@
   g_object_notify (G_OBJECT (playbin), "source");
+static gboolean
+group_set_locked_state_unlocked (GstPlayBin * playbin, GstSourceGroup * group,
+    gboolean locked)
+{
+  GST_DEBUG_OBJECT (playbin, "locked_state %d on group %p", locked, group);
+  if (group->uridecodebin)
+    gst_element_set_locked_state (group->uridecodebin, locked);
+  if (group->suburidecodebin)
+    gst_element_set_locked_state (group->suburidecodebin, locked);
+  return TRUE;
+}
 #define REMOVE_SIGNAL(obj,id)            \
 if (id) {                                \
   g_signal_handler_disconnect (obj, id); \
@@ -2142,6 +2118,7 @@
   if (group->uridecodebin) {
+    GST_DEBUG_OBJECT (playbin, "reusing existing uridecodebin");
     REMOVE_SIGNAL (group->uridecodebin, group->pad_added_id);
     REMOVE_SIGNAL (group->uridecodebin, group->pad_removed_id);
     REMOVE_SIGNAL (group->uridecodebin, group->no_more_pads_id);
@@ -2150,14 +2127,16 @@
     REMOVE_SIGNAL (group->uridecodebin, group->autoplug_factories_id);
     REMOVE_SIGNAL (group->uridecodebin, group->autoplug_select_id);
     gst_element_set_state (group->uridecodebin, GST_STATE_NULL);
-    gst_bin_remove (GST_BIN_CAST (playbin), group->uridecodebin);
-    group->uridecodebin = NULL;
+    uridecodebin = group->uridecodebin;
+  } else {
+    GST_DEBUG_OBJECT (playbin, "making new uridecodebin");
+    uridecodebin = gst_element_factory_make ("uridecodebin", NULL);
+    if (!uridecodebin)
+      goto no_decodebin;
+    gst_bin_add (GST_BIN_CAST (playbin), uridecodebin);
+    group->uridecodebin = uridecodebin;
-  uridecodebin = gst_element_factory_make ("uridecodebin", NULL);
-  if (!uridecodebin)
-    goto no_decodebin;
   /* configure connection speed */
   g_object_set (uridecodebin, "connection-speed", playbin->connection_speed,
       NULL);
@@ -2195,24 +2174,24 @@
   group->autoplug_select_id = g_signal_connect (uridecodebin, "autoplug-select",
       G_CALLBACK (autoplug_select_cb), group);
-  /*  */
-  gst_bin_add (GST_BIN_CAST (playbin), uridecodebin);
-  group->uridecodebin = uridecodebin;
   if (group->suburi) {
     /* subtitles */
     if (group->suburidecodebin) {
+      GST_DEBUG_OBJECT (playbin, "reusing existing suburidecodebin");
       REMOVE_SIGNAL (group->suburidecodebin, group->sub_pad_added_id);
       REMOVE_SIGNAL (group->suburidecodebin, group->sub_pad_removed_id);
       REMOVE_SIGNAL (group->suburidecodebin, group->sub_no_more_pads_id);
       gst_element_set_state (group->suburidecodebin, GST_STATE_NULL);
-      gst_bin_remove (GST_BIN_CAST (playbin), group->suburidecodebin);
-      group->suburidecodebin = NULL;
+      suburidecodebin = group->suburidecodebin;
+    } else {
+      GST_DEBUG_OBJECT (playbin, "making new suburidecodebin");
+      suburidecodebin = gst_element_factory_make ("uridecodebin", NULL);
+      if (!suburidecodebin)
+        goto no_decodebin;
-    suburidecodebin = gst_element_factory_make ("uridecodebin", NULL);
-    if (!suburidecodebin)
-      goto no_decodebin;
+      gst_bin_add (GST_BIN_CAST (playbin), suburidecodebin);
+      group->suburidecodebin = suburidecodebin;
+    }
     /* configure connection speed */
     g_object_set (suburidecodebin, "connection-speed",
@@ -2223,10 +2202,6 @@
     /* configure uri */
     g_object_set (suburidecodebin, "uri", group->suburi, NULL);
-    /*  */
-    gst_bin_add (GST_BIN_CAST (playbin), suburidecodebin);
-    group->suburidecodebin = suburidecodebin;
     /* connect pads and other things */
     group->sub_pad_added_id = g_signal_connect (suburidecodebin, "pad-added",
         G_CALLBACK (pad_added_cb), group);
@@ -2246,6 +2221,8 @@
           GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE)
     goto uridecodebin_failure;
+  /* alow state changes of the playbin2 affect the group elements now */
+  group_set_locked_state_unlocked (playbin, group, FALSE);
   group->active = TRUE;
@@ -2294,9 +2271,11 @@
     GST_DEBUG_OBJECT (playbin, "unlinking selector %s", select->media);
     if (select->sinkpad) {
+      GST_LOG_OBJECT (playbin, "unlinking from sink");
       gst_pad_unlink (select->srcpad, select->sinkpad);
       /* release back */
+      GST_LOG_OBJECT (playbin, "release sink pad");
       gst_play_sink_release_pad (playbin->playsink, select->sinkpad);
       select->sinkpad = NULL;
@@ -2308,6 +2287,11 @@
     gst_bin_remove (GST_BIN_CAST (playbin), select->selector);
     select->selector = NULL;
+  /* we still have the decodebins added to the playbin2 but we can't remove them
+   * yet or change their state because this function might be called from the
+   * streaming threads, instead block the state so that state changes on the
+   * playbin2 don't affect us anymore */
+  group_set_locked_state_unlocked (playbin, group, TRUE);
   return TRUE;
@@ -2364,7 +2348,7 @@
 /* The group that is currently playing is copied again to the
- * next_group.
+ * next_group so that it will start playing the next time.
  */
 static gboolean
 save_current_group (GstPlayBin * playbin)
@@ -2388,6 +2372,25 @@
+/* clear the locked state from all groups. This function is called before a
+ * state change to NULL is performed on them. */
+groups_set_locked_state (GstPlayBin * playbin, gboolean locked)
+  GST_DEBUG_OBJECT (playbin, "setting locked state to %d on groups groups");
+  GST_PLAY_BIN_LOCK (playbin);
+  GST_SOURCE_GROUP_LOCK (playbin->curr_group);
+  group_set_locked_state_unlocked (playbin, playbin->curr_group, locked);
+  GST_SOURCE_GROUP_UNLOCK (playbin->curr_group);
+  GST_SOURCE_GROUP_LOCK (playbin->next_group);
+  group_set_locked_state_unlocked (playbin, playbin->next_group, locked);
+  GST_SOURCE_GROUP_UNLOCK (playbin->next_group);
+  GST_PLAY_BIN_UNLOCK (playbin);
 static GstStateChangeReturn
 gst_play_bin_change_state (GstElement * element, GstStateChange transition)
@@ -2404,6 +2407,10 @@
     case GST_STATE_CHANGE_PAUSED_TO_READY:
       /* FIXME unlock our waiting groups */
       break;
+    case GST_STATE_CHANGE_READY_TO_NULL:
+      /* unlock so that all groups go to NULL */
+      groups_set_locked_state (playbin, FALSE);
+      break;
     default:
@@ -2421,6 +2428,9 @@
       save_current_group (playbin);
+      groups_set_locked_state (playbin, TRUE);
Index: gsturidecodebin.c
RCS file: /cvs/gstreamer/gst-plugins-base/gst/playback/gsturidecodebin.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- gsturidecodebin.c	12 Dec 2008 10:54:41 -0000	1.22
+++ gsturidecodebin.c	7 Jan 2009 13:52:14 -0000	1.23
@@ -693,6 +693,10 @@
   GST_DEBUG_OBJECT (element, "pad removed name: <%s:%s>",
       GST_DEBUG_PAD_NAME (pad));
+  /* we only care about srcpads */
+  if (!GST_PAD_IS_SRC (pad))
+    return;
   if (!(ghost = g_object_get_data (G_OBJECT (pad), "uridecodebin.ghostpad")))
     goto no_ghost;
@@ -1141,7 +1145,7 @@
     goto no_queue2;
   g_object_set (G_OBJECT (queue), "use-buffering", TRUE, NULL);
-//  g_object_set (G_OBJECT (queue), "temp-location", "temp", NULL);
+  /* g_object_set (G_OBJECT (queue), "temp-location", "temp", NULL); */
   /* Disable max-size-buffers */
   g_object_set (G_OBJECT (queue), "max-size-buffers", 0, NULL);


--===============4693498646305374251==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

------------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It is the best place to buy or sell services for
just about anything Open Source.
http://p.sf.net/sfu/Xq1LFB
--===============4693498646305374251==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
gstreamer-cvs-verbose mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/gstreamer-cvs-verbose

--===============4693498646305374251==--