[gst-cvs] gst-plugins-base: playbin2: Aggregate the stream-changed message by looking at the seqnum

Sebastian Dröge slomo at kemper.freedesktop.org
Thu Nov 19 03:13:04 PST 2009


Module: gst-plugins-base
Branch: master
Commit: d6dd987ffb9a2e00caffd14d7c1d34119585cf6c
URL:    http://cgit.freedesktop.org/gstreamer/gst-plugins-base/commit/?id=d6dd987ffb9a2e00caffd14d7c1d34119585cf6c

Author: Sebastian Dröge <sebastian.droege at collabora.co.uk>
Date:   Thu Nov 19 12:10:58 2009 +0100

playbin2: Aggregate the stream-changed message by looking at the seqnum

Just counting how many messages were sent and how many were received
is not good enough because they might've been duplicated (e.g. by the
visualization audio tee). Comparing the sequence numbers should give
better results in that case.

---

 gst/playback/gstplaybin2.c |   55 ++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 48 insertions(+), 7 deletions(-)

diff --git a/gst/playback/gstplaybin2.c b/gst/playback/gstplaybin2.c
index 6ffca51..9b87083 100644
--- a/gst/playback/gstplaybin2.c
+++ b/gst/playback/gstplaybin2.c
@@ -316,7 +316,8 @@ struct _GstSourceGroup
   gulong sub_no_more_pads_id;
   gulong sub_autoplug_continue_id;
 
-  gint stream_changed_pending;
+  GMutex *stream_changed_pending_lock;
+  GList *stream_changed_pending;
 
   /* selectors for different streams */
   GstSourceSelect selector[GST_PLAY_SINK_TYPE_LAST];
@@ -1109,6 +1110,13 @@ free_group (GstPlayBin * playbin, GstSourceGroup * group)
   if (group->video_sink)
     gst_object_unref (group->video_sink);
   group->video_sink = NULL;
+
+  g_list_free (group->stream_changed_pending);
+  group->stream_changed_pending = NULL;
+
+  if (group->stream_changed_pending_lock);
+  g_mutex_free (group->stream_changed_pending_lock);
+  group->stream_changed_pending_lock = NULL;
 }
 
 static void
@@ -2042,8 +2050,17 @@ gst_play_bin_query (GstElement * element, GstQuery * query)
 
   if (GST_QUERY_TYPE (query) == GST_QUERY_DURATION) {
     GstSourceGroup *group = playbin->curr_group;
+    gboolean pending;
+
     GST_SOURCE_GROUP_LOCK (group);
-    if (group->pending || group->stream_changed_pending) {
+    if (group->stream_changed_pending_lock) {
+      g_mutex_lock (group->stream_changed_pending_lock);
+      pending = group->pending || group->stream_changed_pending;
+      g_mutex_unlock (group->stream_changed_pending_lock);
+    } else {
+      pending = group->pending;
+    }
+    if (pending) {
       GstFormat fmt;
       gint i;
 
@@ -2106,11 +2123,25 @@ gst_play_bin_handle_message (GstBin * bin, GstMessage * msg)
 
     /* Drop all stream-changed messages except the last one */
     if (strcmp ("playbin2-stream-changed", gst_structure_get_name (s)) == 0) {
+      guint32 seqnum = gst_message_get_seqnum (msg);
+      GList *l;
+
       group = playbin->curr_group;
-      if (!g_atomic_int_dec_and_test (&group->stream_changed_pending)) {
-        gst_message_unref (msg);
-        msg = NULL;
+      g_mutex_lock (group->stream_changed_pending_lock);
+      for (l = group->stream_changed_pending; l; l = l->next) {
+        guint32 l_seqnum = GPOINTER_TO_UINT (l->data);
+
+        if (l_seqnum == seqnum) {
+          group->stream_changed_pending =
+              g_list_delete_link (group->stream_changed_pending, l);
+          if (group->stream_changed_pending) {
+            gst_message_unref (msg);
+            msg = NULL;
+            break;
+          }
+        }
       }
+      g_mutex_unlock (group->stream_changed_pending_lock);
     }
   } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ASYNC_START ||
       GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ASYNC_DONE) {
@@ -2683,14 +2714,20 @@ no_more_pads_cb (GstElement * decodebin, GstSourceGroup * group)
         GstStructure *s;
         GstMessage *msg;
         GstEvent *event;
+        guint32 seqnum;
 
         s = gst_structure_new ("playbin2-stream-changed", "uri", G_TYPE_STRING,
             group->uri, NULL);
         if (group->suburi)
           gst_structure_set (s, "suburi", G_TYPE_STRING, group->suburi, NULL);
         msg = gst_message_new_element (GST_OBJECT_CAST (playbin), s);
+        seqnum = gst_message_get_seqnum (msg);
         event = gst_event_new_sink_message (msg);
-        g_atomic_int_inc (&group->stream_changed_pending);
+        g_mutex_lock (group->stream_changed_pending_lock);
+        group->stream_changed_pending =
+            g_list_prepend (group->stream_changed_pending,
+            GUINT_TO_POINTER (seqnum));
+        g_mutex_unlock (group->stream_changed_pending_lock);
         gst_pad_send_event (select->sinkpad, event);
         gst_message_unref (msg);
       }
@@ -2966,7 +3003,11 @@ activate_group (GstPlayBin * playbin, GstSourceGroup * group, GstState target)
   GST_DEBUG_OBJECT (playbin, "activating group %p", group);
 
   GST_SOURCE_GROUP_LOCK (group);
-  group->stream_changed_pending = 0;
+
+  g_list_free (group->stream_changed_pending);
+  group->stream_changed_pending = NULL;
+  if (!group->stream_changed_pending_lock)
+    group->stream_changed_pending_lock = g_mutex_new ();
 
   if (group->uridecodebin) {
     GST_DEBUG_OBJECT (playbin, "reusing existing uridecodebin");





More information about the Gstreamer-commits mailing list