gst/playback/: Some playbin cleanups mostly refcounting sloppyness.
authorWim Taymans <wim.taymans@gmail.com>
Wed, 25 May 2005 19:47:52 +0000 (19:47 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 25 May 2005 19:47:52 +0000 (19:47 +0000)
Original commit message from CVS:
* gst/playback/gstdecodebin.c: (gst_decode_bin_init),
(gst_decode_bin_dispose), (try_to_link_1), (get_our_ghost_pad),
(remove_element_chain), (no_more_pads), (unlinked), (close_link),
(type_found):
* gst/playback/gstplaybasebin.c: (gst_play_base_bin_dispose),
(group_destroy), (group_commit), (queue_overrun),
(gen_preroll_element), (no_more_pads), (preroll_unlinked),
(mute_stream), (new_decoded_pad), (setup_substreams),
(setup_source), (mute_group_type), (set_active_source),
(gst_play_base_bin_change_state):
* gst/playback/gstplaybin.c: (gst_play_bin_dispose),
(gen_video_element), (gen_text_element), (gen_audio_element),
(gen_vis_element), (remove_sinks), (add_sink), (setup_sinks):
* gst/playback/gststreaminfo.c: (gst_stream_info_new),
(gst_stream_info_dispose), (gst_stream_info_set_mute):
* gst/playback/gststreamselector.c: (gst_stream_selector_chain):
Some playbin cleanups mostly refcounting sloppyness.

ChangeLog
gst/playback/gstdecodebin.c
gst/playback/gstplaybasebin.c
gst/playback/gstplaybin.c
gst/playback/gststreaminfo.c
gst/playback/gststreamselector.c

index d0af3d2fde9be3c81c9024b95907baac0e84b219..e82a75166f5437844521abb56185398aa5793d9d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2005-05-25  Wim Taymans  <wim@fluendo.com>
+
+       * gst/playback/gstdecodebin.c: (gst_decode_bin_init),
+       (gst_decode_bin_dispose), (try_to_link_1), (get_our_ghost_pad),
+       (remove_element_chain), (no_more_pads), (unlinked), (close_link),
+       (type_found):
+       * gst/playback/gstplaybasebin.c: (gst_play_base_bin_dispose),
+       (group_destroy), (group_commit), (queue_overrun),
+       (gen_preroll_element), (no_more_pads), (preroll_unlinked),
+       (mute_stream), (new_decoded_pad), (setup_substreams),
+       (setup_source), (mute_group_type), (set_active_source),
+       (gst_play_base_bin_change_state):
+       * gst/playback/gstplaybin.c: (gst_play_bin_dispose),
+       (gen_video_element), (gen_text_element), (gen_audio_element),
+       (gen_vis_element), (remove_sinks), (add_sink), (setup_sinks):
+       * gst/playback/gststreaminfo.c: (gst_stream_info_new),
+       (gst_stream_info_dispose), (gst_stream_info_set_mute):
+       * gst/playback/gststreamselector.c: (gst_stream_selector_chain):
+       Some playbin cleanups mostly refcounting sloppyness.
+
 2005-05-25  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
 
        * ext/ogg/gstoggdemux.c: (gst_ogg_pad_submit_packet):
index 0b0b2ca3ed8587596296b2ff7e1cde2e105057c4..26f3d06538ff1bdb29d2b78de3530c940866e241 100644 (file)
@@ -309,11 +309,18 @@ gst_decode_bin_init (GstDecodeBin * decode_bin)
   if (!decode_bin->typefind) {
     g_warning ("can't find typefind element, decodebin will not work");
   } else {
+    GstPad *pad;
+
     /* add the typefind element */
     gst_bin_add (GST_BIN (decode_bin), decode_bin->typefind);
+
+    /* get the sinkpad */
+    pad = gst_element_get_pad (decode_bin->typefind, "sink");
+
     /* ghost the sink pad to ourself */
-    gst_element_add_ghost_pad (GST_ELEMENT (decode_bin),
-        gst_element_get_pad (decode_bin->typefind, "sink"), "sink");
+    gst_element_add_ghost_pad (GST_ELEMENT (decode_bin), pad, "sink");
+
+    gst_object_unref (GST_OBJECT_CAST (pad));
 
     /* connect a signal to find out when the typefind element found
      * a type */
@@ -326,6 +333,8 @@ gst_decode_bin_init (GstDecodeBin * decode_bin)
   decode_bin->dynamics = NULL;
 }
 
+static void dynamic_free (GstDynamic * dyn);
+
 static void
 gst_decode_bin_dispose (GObject * object)
 {
@@ -344,14 +353,12 @@ gst_decode_bin_dispose (GObject * object)
   for (dyns = decode_bin->dynamics; dyns; dyns = g_list_next (dyns)) {
     GstDynamic *dynamic = (GstDynamic *) dyns->data;
 
-    g_free (dynamic);
+    dynamic_free (dynamic);
   }
   g_list_free (decode_bin->dynamics);
   decode_bin->dynamics = NULL;
 
-  if (G_OBJECT_CLASS (parent_class)->dispose) {
-    G_OBJECT_CLASS (parent_class)->dispose (object);
-  }
+  G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
 static GstDynamic *
@@ -553,27 +560,37 @@ static GstElement *
 try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad, GList * factories)
 {
   GList *walk;
+  GstElement *result = NULL;
 
   /* loop over the factories */
   for (walk = factories; walk; walk = g_list_next (walk)) {
     GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data);
     GstElement *element;
     GstPadLinkReturn ret;
+    GstPad *sinkpad;
 
     GST_DEBUG_OBJECT (decode_bin, "trying to link %s",
         gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
 
     /* make an element from the factory first */
-    element = gst_element_factory_create (factory, NULL);
-    if (element == NULL) {
+    if ((element = gst_element_factory_create (factory, NULL)) == NULL) {
       /* hmm, strange. Like with all things in live, let's move on.. */
       GST_WARNING_OBJECT (decode_bin, "could not create  an element from %s",
           gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
       continue;
     }
 
+    /* try to link the given pad to a sinkpad */
+    /* FIXME, find the sinkpad by looping over the pads instead of 
+     * looking it up by name */
+    if ((sinkpad = gst_element_get_pad (element, "sink")) == NULL) {
+      /* if no pad is found we can't do anything */
+      GST_WARNING_OBJECT (decode_bin, "could not find sinkpad in element");
+      continue;
+    }
+
     /* now add the element to the bin first */
-    GST_DEBUG_OBJECT (decode_bin, "adding %s", gst_element_get_name (element));
+    GST_DEBUG_OBJECT (decode_bin, "adding %s", GST_OBJECT_NAME (element));
     gst_bin_add (GST_BIN (decode_bin), element);
 
     /* set to ready first so it is ready */
@@ -582,11 +599,15 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad, GList * factories)
     /* keep our own list of elements */
     decode_bin->elements = g_list_prepend (decode_bin->elements, element);
 
-    /* try to link the given pad to a sinkpad */
-    /* FIXME, find the sinkpad by looping over the pads instead of 
-     * looking it up by name */
-    ret = gst_pad_link (pad, gst_element_get_pad (element, "sink"));
-    if (ret == GST_PAD_LINK_OK) {
+    if ((ret = gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) {
+      GST_DEBUG_OBJECT (decode_bin, "link failed on pad %s:%s, reason %d",
+          GST_DEBUG_PAD_NAME (pad), ret);
+      /* get rid of the sinkpad */
+      gst_object_unref (GST_OBJECT_CAST (sinkpad));
+      /* this element did not work, remove it again and continue trying
+       * other elements, the element will be disposed. */
+      gst_bin_remove (GST_BIN (decode_bin), element);
+    } else {
       const gchar *klass;
       GstElementFactory *factory;
       guint sig;
@@ -597,6 +618,7 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad, GList * factories)
       /* The link worked, now figure out what it was that we connected */
       factory = gst_element_get_factory (element);
       klass = gst_element_factory_get_klass (factory);
+
       /* check if we can use threads */
       if (decode_bin->threaded) {
         if (strstr (klass, "Demux") != NULL) {
@@ -608,8 +630,9 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad, GList * factories)
       }
 
       /* make sure we catch unlink signals */
-      sig = g_signal_connect (G_OBJECT (GST_PAD_REALIZE (pad)), "unlinked",
+      sig = g_signal_connect (G_OBJECT (pad), "unlinked",
           G_CALLBACK (unlinked), decode_bin);
+
       /* keep a ref to the signal id so that we can disconnect the signal callback */
       g_object_set_data (G_OBJECT (pad), "unlinked_id", GINT_TO_POINTER (sig));
 
@@ -618,21 +641,24 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad, GList * factories)
       close_link (element, decode_bin);
       /* change the state of the element to that of the parent */
       gst_element_set_state (element, GST_STATE_PAUSED);
-      return element;
-    } else {
-      GST_DEBUG_OBJECT (decode_bin, "link failed on pad %s:%s",
-          GST_DEBUG_PAD_NAME (pad));
-      /* this element did not work, remove it again and continue trying
-       * other elements */
-      gst_bin_remove (GST_BIN (decode_bin), element);
+
+      result = element;
+
+      /* get rid of the sinkpad now */
+      gst_object_unref (GST_OBJECT_CAST (sinkpad));
+
+      /* and exit */
+      goto done;
     }
   }
-  return NULL;
+done:
+  return result;
 }
 
 static GstPad *
 get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
 {
+#if 0
   GList *ghostpads;
 
   if (pad == NULL || !GST_PAD_IS_SRC (pad)) {
@@ -643,8 +669,7 @@ get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
   if (GST_IS_GHOST_PAD (pad)) {
     GstElement *parent = gst_pad_get_parent (pad);
 
-    GST_DEBUG_OBJECT (decode_bin, "pad parent %s",
-        gst_element_get_name (parent));
+    GST_DEBUG_OBJECT (decode_bin, "pad parent %s", GST_ELEMENT_NAME (parent));
 
     if (parent == GST_ELEMENT (decode_bin)) {
       GST_DEBUG_OBJECT (decode_bin, "pad is our ghostpad");
@@ -669,6 +694,7 @@ get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
     ghostpads = g_list_next (ghostpads);
   }
   GST_DEBUG_OBJECT (decode_bin, "done looping over ghostpads, nothing found");
+#endif
 
   return NULL;
 }
@@ -680,7 +706,7 @@ get_our_ghost_pad (GstDecodeBin * decode_bin, GstPad * pad)
 static void
 remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
 {
-  GList *int_links;
+  GList *int_links, *walk;
   GstElement *elem = GST_ELEMENT (GST_OBJECT_PARENT (pad));
 
   while (GST_OBJECT_PARENT (elem) &&
@@ -688,16 +714,16 @@ remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
     elem = GST_ELEMENT (GST_OBJECT_PARENT (elem));
 
   GST_DEBUG_OBJECT (decode_bin, "%s:%s", GST_DEBUG_PAD_NAME (pad));
+  int_links = gst_pad_get_internal_links (pad);
 
   /* remove all elements linked to this pad up to the ghostpad 
    * that we created for this stream */
-  for (int_links = gst_pad_get_internal_links (pad);
-      int_links; int_links = g_list_next (int_links)) {
+  for (walk = int_links; walk; walk = g_list_next (walk)) {
     GstPad *pad;
     GstPad *ghostpad;
     GstPad *peer;
 
-    pad = GST_PAD (int_links->data);
+    pad = GST_PAD (walk->data);
     GST_DEBUG_OBJECT (decode_bin, "inspecting internal pad %s:%s",
         GST_DEBUG_PAD_NAME (pad));
 
@@ -723,20 +749,24 @@ remove_element_chain (GstDecodeBin * decode_bin, GstPad * pad)
         GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer));
 
     {
-      GstElement *parent = gst_pad_get_real_parent (peer);
+      GstElement *parent = gst_pad_get_parent (peer);
 
       if (parent != GST_ELEMENT (decode_bin)) {
         GST_DEBUG_OBJECT (decode_bin, "dead end pad %s:%s",
             GST_DEBUG_PAD_NAME (peer));
       } else {
         GST_DEBUG_OBJECT (decode_bin, "recursing element %s on pad %s:%s",
-            gst_element_get_name (elem), GST_DEBUG_PAD_NAME (pad));
+            GST_ELEMENT_NAME (elem), GST_DEBUG_PAD_NAME (pad));
         remove_element_chain (decode_bin, peer);
       }
       gst_object_unref (GST_OBJECT_CAST (parent));
     }
+    gst_object_unref (GST_OBJECT_CAST (peer));
   }
-  GST_DEBUG_OBJECT (decode_bin, "removing %s", gst_element_get_name (elem));
+  GST_DEBUG_OBJECT (decode_bin, "removing %s", GST_ELEMENT_NAME (elem));
+
+  g_list_free (int_links);
+
   gst_bin_remove (GST_BIN (decode_bin), elem);
 }
 
@@ -768,7 +798,7 @@ no_more_pads (GstElement * element, GstDynamic * dynamic)
   GstDecodeBin *decode_bin = dynamic->decode_bin;
 
   GST_DEBUG_OBJECT (decode_bin, "no more pads on element %s",
-      gst_element_get_name (element));
+      GST_ELEMENT_NAME (element));
 
   /* remove the element from the list of dynamic elements */
   decode_bin->dynamics = g_list_remove (decode_bin->dynamics, dynamic);
@@ -793,7 +823,7 @@ unlinked (GstPad * pad, GstPad * peerpad, GstDecodeBin * decode_bin)
   GstElement *element;
 
   /* inactivate pad */
-  gst_pad_set_active (pad, FALSE);
+  gst_pad_set_active (pad, GST_ACTIVATE_NONE);
 
   /* remove all elements linked to the peerpad */
   remove_element_chain (decode_bin, peerpad);
@@ -825,7 +855,7 @@ close_link (GstElement * element, GstDecodeBin * decode_bin)
   gboolean more;
 
   GST_DEBUG_OBJECT (decode_bin, "closing links with element %s",
-      gst_element_get_name (element));
+      GST_ELEMENT_NAME (element));
 
   /* loop over all the padtemplates */
   for (pads = GST_ELEMENT_GET_CLASS (element)->padtemplates; pads;
@@ -905,7 +935,7 @@ close_link (GstElement * element, GstDecodeBin * decode_bin)
 
   /* now loop over all the pads we need to connect */
   for (pads = to_connect; pads; pads = g_list_next (pads)) {
-    GstPad *pad = GST_PAD (pads->data);
+    GstPad *pad = GST_PAD_CAST (pads->data);
     GstCaps *caps;
 
     /* we have more pads if we have more than 1 pad to connect or
@@ -915,15 +945,16 @@ close_link (GstElement * element, GstDecodeBin * decode_bin)
     more |= gst_decode_bin_is_dynamic (decode_bin);
 
     GST_DEBUG_OBJECT (decode_bin, "closing pad link for %s",
-        gst_pad_get_name (pad));
+        GST_OBJECT_NAME (pad));
 
     /* continue autoplugging on the pads */
     caps = gst_pad_get_caps (pad);
     close_pad_link (element, pad, caps, decode_bin, more);
     if (caps)
       gst_caps_unref (caps);
-  }
 
+    gst_object_unref (GST_OBJECT_CAST (pad));
+  }
   g_list_free (to_connect);
 }
 
@@ -941,7 +972,7 @@ type_found (GstElement * typefind, guint probability, GstCaps * caps,
   /* autoplug the new pad with the caps that the signal gave us. */
   pad = gst_element_get_pad (typefind, "src");
   close_pad_link (typefind, pad, caps, decode_bin, FALSE);
-  gst_object_unref (GST_OBJECT (pad));
+  gst_object_unref (GST_OBJECT_CAST (pad));
 
   dynamic = gst_decode_bin_is_dynamic (decode_bin);
   if (dynamic == FALSE) {
index dba17a5935e03ecb31adde357e21696ceb07a3ab..9fbfdcfb1d96e843a0af47cce818da52a768c1ac 100644 (file)
@@ -202,9 +202,7 @@ gst_play_base_bin_dispose (GObject * object)
   g_free (play_base_bin->suburi);
   play_base_bin->suburi = NULL;
 
-  if (G_OBJECT_CLASS (parent_class)->dispose) {
-    G_OBJECT_CLASS (parent_class)->dispose (object);
-  }
+  G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
 static void
@@ -312,8 +310,7 @@ group_destroy (GstPlayBaseGroup * group)
       fakesrc = (GstElement *) g_object_get_data (G_OBJECT (pad), "fakesrc");
       if (fakesrc != NULL) {
         GST_LOG ("removing fakesrc from %s:%s",
-            gst_pad_get_name (pad),
-            GST_ELEMENT_NAME (gst_pad_get_parent (pad)));
+            GST_PAD_NAME (pad), GST_ELEMENT_NAME (gst_pad_get_parent (pad)));
         gst_bin_remove (GST_BIN (play_base_bin), fakesrc);
       }
     }
@@ -321,7 +318,7 @@ group_destroy (GstPlayBaseGroup * group)
     /* if the group is currently being played, we have to remove the element 
      * from the thread */
     if (get_active_group (play_base_bin) == group) {
-      GST_LOG ("removing preroll element %s", gst_element_get_name (element));
+      GST_LOG ("removing preroll element %s", GST_ELEMENT_NAME (element));
       gst_bin_remove (group->type[n].bin, element);
       gst_bin_remove (group->type[n].bin, group->type[n].selector);
     } else {
@@ -388,7 +385,7 @@ group_commit (GstPlayBaseBin * play_base_bin, gboolean fatal, gboolean subtitle)
       sig_id =
           GPOINTER_TO_INT (g_object_get_data (G_OBJECT (element), "signal_id"));
 
-      GST_LOG ("removing preroll signal %s", gst_element_get_name (element));
+      GST_LOG ("removing preroll signal %s", GST_ELEMENT_NAME (element));
       g_signal_handler_disconnect (G_OBJECT (element), sig_id);
     }
   }
@@ -469,7 +466,7 @@ check_queue (GstProbe * probe, GstMiniObject ** data, gpointer user_data)
 static void
 queue_overrun (GstElement * element, GstPlayBaseBin * play_base_bin)
 {
-  GST_DEBUG ("queue %s overrun", gst_element_get_name (element));
+  GST_DEBUG ("queue %s overrun", GST_ELEMENT_NAME (element));
 
   group_commit (play_base_bin, FALSE, FALSE);
 
@@ -550,7 +547,7 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin,
     GstStreamInfo * info)
 {
   GstElement *selector, *preroll;
-  gchar *name;
+  gchar *name, *padname;
   const gchar *prename;
   guint sig;
   GstPad *preroll_pad;
@@ -566,20 +563,26 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin,
     g_return_if_reached ();
 
   /* create stream selector */
-  name = g_strdup_printf ("selector_%s_%s", prename, gst_pad_get_name (pad));
+  padname = gst_pad_get_name (pad);
+  name = g_strdup_printf ("selector_%s_%s", prename, padname);
   selector = g_object_new (GST_TYPE_STREAM_SELECTOR, NULL);
   gst_object_set_name (GST_OBJECT (selector), name);
   g_free (name);
 
   /* create preroll queue */
-  name = g_strdup_printf ("preroll_%s_%s", prename, gst_pad_get_name (pad));
+  name = g_strdup_printf ("preroll_%s_%s", prename, padname);
   preroll = gst_element_factory_make ("queue", name);
+  g_free (padname);
+  g_free (name);
+
   g_object_set (G_OBJECT (preroll),
       "max-size-buffers", 0, "max-size-bytes",
       ((type == GST_STREAM_TYPE_VIDEO) ? 25 : 1) * 1024 * 1024,
       "max-size-time", play_base_bin->queue_size, NULL);
+
   sig = g_signal_connect (G_OBJECT (preroll), "overrun",
       G_CALLBACK (queue_overrun), play_base_bin);
+
   if (play_base_bin->is_stream &&
       ((type == GST_STREAM_TYPE_VIDEO &&
               group->type[GST_STREAM_TYPE_AUDIO - 1].npads == 0) ||
@@ -609,34 +612,32 @@ gen_preroll_element (GstPlayBaseBin * play_base_bin,
   /* keep a ref to the signal id so that we can disconnect the signal callback
    * when we are done with the preroll */
   g_object_set_data (G_OBJECT (preroll), "signal_id", GINT_TO_POINTER (sig));
-  g_free (name);
 
   /* listen for EOS */
   preroll_pad = gst_element_get_pad (preroll, "src");
   probe = gst_probe_new (FALSE, probe_triggered, info);
   /* have to REALIZE the pad as we cannot attach a padprobe to a ghostpad */
   gst_pad_add_probe (preroll_pad, probe);
+  gst_object_unref (GST_OBJECT_CAST (preroll_pad));
 
   /* add to group list */
-  gst_element_link (selector, preroll);
+  /* FIXME refcount elements */
   group->type[type - 1].selector = selector;
   group->type[type - 1].preroll = preroll;
   if (type == GST_STREAM_TYPE_TEXT && play_base_bin->subtitle) {
     group->type[type - 1].bin = GST_BIN (play_base_bin->subtitle);
     gst_bin_add (GST_BIN (play_base_bin->subtitle), selector);
     gst_bin_add (GST_BIN (play_base_bin->subtitle), preroll);
-    gst_element_set_state (selector,
-        GST_STATE (play_base_bin) == GST_STATE_PLAYING ?
-        GST_STATE_PLAYING : GST_STATE_PAUSED);
   } else {
     group->type[type - 1].bin = GST_BIN (play_base_bin);
     gst_bin_add (GST_BIN (play_base_bin), selector);
     gst_bin_add (GST_BIN (play_base_bin), preroll);
-    gst_element_set_state (selector,
-        GST_STATE (play_base_bin) == GST_STATE_PLAYING ?
-        GST_STATE_PLAYING : GST_STATE_PAUSED);
   }
+  gst_element_link (selector, preroll);
 
+  gst_element_set_state (selector,
+      GST_STATE (play_base_bin) == GST_STATE_PLAYING ?
+      GST_STATE_PLAYING : GST_STATE_PAUSED);
   gst_element_set_state (preroll,
       GST_STATE (play_base_bin) == GST_STATE_PLAYING ?
       GST_STATE_PLAYING : GST_STATE_PAUSED);
@@ -754,7 +755,7 @@ no_more_pads (GstElement * element, GstPlayBaseBin * play_base_bin)
 
   /* we can commit this group for playback now */
   group_commit (play_base_bin, play_base_bin->is_stream,
-      gst_object_get_parent (GST_OBJECT (element)) ==
+      GST_OBJECT_PARENT (GST_OBJECT_CAST (element)) ==
       GST_OBJECT (play_base_bin->subtitle));
 }
 
@@ -848,6 +849,7 @@ preroll_unlinked (GstPad * pad, GstPad * peerpad,
 {
   GstElement *fakesrc;
   guint sig_id;
+  GstPad *srcpad;
 
   /* make a fakesrc that will just emit one EOS */
   fakesrc = gst_element_factory_make ("fakesrc", NULL);
@@ -855,8 +857,10 @@ preroll_unlinked (GstPad * pad, GstPad * peerpad,
 
   GST_DEBUG ("patching unlinked pad %s:%s", GST_DEBUG_PAD_NAME (pad));
 
-  gst_pad_link (gst_element_get_pad (fakesrc, "src"), pad);
+  srcpad = gst_element_get_pad (fakesrc, "src");
   gst_bin_add (GST_BIN (play_base_bin), fakesrc);
+  gst_pad_link (srcpad, pad);
+  gst_object_unref (GST_OBJECT_CAST (srcpad));
 
   /* keep track of these patch elements */
   g_object_set_data (G_OBJECT (pad), "fakesrc", fakesrc);
@@ -879,7 +883,7 @@ mute_stream (GstProbe * probe, GstMiniObject ** d, gpointer data)
 
   if (GST_IS_BUFFER (*d)) {
     g_object_set (G_OBJECT (info), "mute", TRUE, NULL);
-    gst_pad_remove_probe ((GstPad *) GST_PAD_REALIZE (info->object), probe);
+    gst_pad_remove_probe (GST_PAD_CAST (info->object), probe);
     gst_probe_destroy (probe);
   }
 
@@ -911,18 +915,14 @@ new_decoded_pad (GstElement * element, GstPad * pad, gboolean last,
   GstPlayBaseGroup *group;
   GstProbe *probe;
   guint sig;
+  GstObject *parent;
 
   GST_DEBUG ("play base: new decoded pad %d", last);
 
   /* first see if this pad has interesting caps */
   caps = gst_pad_get_caps (pad);
-  if (caps == NULL || gst_caps_is_empty (caps) || gst_caps_is_any (caps)) {
-    g_warning ("no type on pad %s:%s",
-        GST_DEBUG_PAD_NAME (GST_PAD_REALIZE (pad)));
-    if (caps)
-      gst_caps_unref (caps);
-    return;
-  }
+  if (caps == NULL || gst_caps_is_empty (caps) || gst_caps_is_any (caps))
+    goto no_type;
 
   /* get the mime type */
   structure = gst_caps_get_structure (caps, 0);
@@ -934,19 +934,19 @@ new_decoded_pad (GstElement * element, GstPad * pad, gboolean last,
 
   group->nstreams++;
 
+  parent = gst_object_get_parent (GST_OBJECT (element));
   if (g_str_has_prefix (mimetype, "audio/") &&
-      gst_object_get_parent (GST_OBJECT (element)) !=
-      GST_OBJECT (play_base_bin->subtitle)) {
+      parent != GST_OBJECT_CAST (play_base_bin->subtitle)) {
     type = GST_STREAM_TYPE_AUDIO;
   } else if (g_str_has_prefix (mimetype, "video/") &&
-      gst_object_get_parent (GST_OBJECT (element)) !=
-      GST_OBJECT (play_base_bin->subtitle)) {
+      parent != GST_OBJECT_CAST (play_base_bin->subtitle)) {
     type = GST_STREAM_TYPE_VIDEO;
   } else if (g_str_has_prefix (mimetype, "text/")) {
     type = GST_STREAM_TYPE_TEXT;
   } else {
     type = GST_STREAM_TYPE_UNKNOWN;
   }
+  gst_object_unref (parent);
 
   info = gst_stream_info_new (GST_OBJECT (pad), type, NULL, caps);
   if (type > 0 && type <= NUM_TYPES) {
@@ -974,7 +974,7 @@ new_decoded_pad (GstElement * element, GstPad * pad, gboolean last,
   /* select 1st for now - we'll select a preferred one after preroll */
   if (type == GST_STREAM_TYPE_UNKNOWN || group->type[type - 1].npads > 0) {
     probe = gst_probe_new (FALSE, silence_stream, info);
-    gst_pad_add_probe (GST_PAD_REALIZE (pad), probe);
+    gst_pad_add_probe (GST_PAD_CAST (pad), probe);
     g_object_set_data (G_OBJECT (pad), "eat_probe", probe);
   }
 
@@ -985,6 +985,16 @@ new_decoded_pad (GstElement * element, GstPad * pad, gboolean last,
   /* signal the no more pads after adding the stream */
   if (last)
     no_more_pads (element, play_base_bin);
+
+  return;
+
+no_type:
+  {
+    g_warning ("no type on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+    if (caps)
+      gst_caps_unref (caps);
+    return;
+  }
 }
 
 
@@ -1066,7 +1076,7 @@ setup_substreams (GstPlayBaseBin * play_base_bin)
 
     probe = g_object_get_data (G_OBJECT (info->object), "eat_probe");
     if (probe) {
-      gst_pad_remove_probe (GST_PAD_REALIZE (info->object), probe);
+      gst_pad_remove_probe (GST_PAD_CAST (info->object), probe);
       gst_probe_destroy (probe);
     }
 
@@ -1075,7 +1085,7 @@ setup_substreams (GstPlayBaseBin * play_base_bin)
       GstProbe *probe;
 
       probe = gst_probe_new (FALSE, mute_stream, info);
-      gst_pad_add_probe (GST_PAD_REALIZE (info->object), probe);
+      gst_pad_add_probe (GST_PAD_CAST (info->object), probe);
     }
   }
 
@@ -1115,24 +1125,12 @@ setup_source (GstPlayBaseBin * play_base_bin,
   }
 
   /* create and configure an element that can handle the uri */
-  play_base_bin->source = gen_source_element (play_base_bin, &subbin);
-  if (!play_base_bin->source) {
-    gchar *prot;
-
-    /* whoops, could not create the source element */
-    prot = gst_uri_get_protocol (play_base_bin->uri);
-    if (prot) {
-      g_set_error (error, 0, 0, "No URI handler implemented for \"%s\"", prot);
-      g_free (prot);
-    } else {
-      g_set_error (error, 0, 0, "Invalid URI \"%s\"", play_base_bin->uri);
-    }
-    GST_WARNING ("don't know how to read %s", play_base_bin->uri);
-    return FALSE;
-  }
+  if (!(play_base_bin->source = gen_source_element (play_base_bin, &subbin)))
+    goto no_source;
 
   gst_bin_add (GST_BIN (play_base_bin), play_base_bin->source);
   g_object_notify (G_OBJECT (play_base_bin), "source");
+
   /* state will be merged later - if file is not found, error will be
    * handled by the application right after. */
 
@@ -1274,18 +1272,14 @@ setup_source (GstPlayBaseBin * play_base_bin,
   }
 
   /* now create the decoder element */
-  play_base_bin->decoder = gst_element_factory_make ("decodebin", "decoder");
-  if (!play_base_bin->decoder) {
-    g_set_error (error, 0, 0, "Could not create autoplugger element");
-    GST_WARNING ("can't find decoder element");
-    return FALSE;
-  }
+  if (!(play_base_bin->decoder =
+          gst_element_factory_make ("decodebin", "decoder")))
+    goto no_decodebin;
+
   gst_bin_add (GST_BIN (play_base_bin), play_base_bin->decoder);
-  if (!gst_element_link (play_base_bin->source, play_base_bin->decoder)) {
-    g_set_error (error, 0, 0, "Could not link source and autoplugger");
-    GST_WARNING ("can't link source to decoder element");
-    return FALSE;
-  }
+
+  if (!gst_element_link (play_base_bin->source, play_base_bin->decoder))
+    goto could_not_link;
 
   /* set up callbacks to create the links between decoded data
    * and video/audio/subtitle rendering/output. */
@@ -1299,6 +1293,35 @@ setup_source (GstPlayBaseBin * play_base_bin,
   play_base_bin->need_rebuild = FALSE;
 
   return TRUE;
+
+  /* ERRORS */
+no_source:
+  {
+    gchar *prot;
+
+    /* whoops, could not create the source element */
+    prot = gst_uri_get_protocol (play_base_bin->uri);
+    if (prot) {
+      g_set_error (error, 0, 0, "No URI handler implemented for \"%s\"", prot);
+      g_free (prot);
+    } else {
+      g_set_error (error, 0, 0, "Invalid URI \"%s\"", play_base_bin->uri);
+    }
+    GST_WARNING ("don't know how to read %s", play_base_bin->uri);
+    return FALSE;
+  }
+no_decodebin:
+  {
+    g_set_error (error, 0, 0, "Could not create autoplugger element");
+    GST_WARNING ("can't find decoder element");
+    return FALSE;
+  }
+could_not_link:
+  {
+    g_set_error (error, 0, 0, "Could not link source and autoplugger");
+    GST_WARNING ("can't link source to decoder element");
+    return FALSE;
+  }
 }
 
 static void
@@ -1408,13 +1431,17 @@ static void
 mute_group_type (GstPlayBaseGroup * group, GstStreamType type, gboolean mute)
 {
   gboolean active = !mute;
-
-  gst_pad_set_active (gst_element_get_pad (group->type[type - 1].preroll,
-          "src"), active);
-  gst_pad_set_active (gst_element_get_pad (group->type[type - 1].preroll,
-          "sink"), active);
-  gst_pad_set_active (gst_element_get_pad (group->type[type - 1].selector,
-          "src"), active);
+  GstPad *pad;
+
+  pad = gst_element_get_pad (group->type[type - 1].preroll, "src");
+  gst_pad_set_active (pad, active);
+  gst_object_unref (GST_OBJECT_CAST (pad));
+  pad = gst_element_get_pad (group->type[type - 1].preroll, "sink");
+  gst_pad_set_active (pad, active);
+  gst_object_unref (GST_OBJECT_CAST (pad));
+  pad = gst_element_get_pad (group->type[type - 1].selector, "src");
+  gst_pad_set_active (pad, active);
+  gst_object_unref (GST_OBJECT_CAST (pad));
 
   if (mute) {
     g_signal_connect (group->type[type - 1].preroll, "state-change",
@@ -1477,7 +1504,7 @@ set_active_source (GstPlayBaseBin * play_base_bin,
         GstProbe *probe;
 
         probe = gst_probe_new (FALSE, mute_stream, info);
-        gst_pad_add_probe (GST_PAD_REALIZE (info->object), probe);
+        gst_pad_add_probe (GST_PAD_CAST (info->object), probe);
       }
       num++;
     }
@@ -1632,44 +1659,24 @@ gst_play_base_bin_get_property (GObject * object, guint prop_id, GValue * value,
 static GstElementStateReturn
 gst_play_base_bin_change_state (GstElement * element)
 {
-  GstElementStateReturn ret = GST_STATE_SUCCESS;
+  GstElementStateReturn ret;
   GstPlayBaseBin *play_base_bin;
   gint transition = GST_STATE_TRANSITION (element);
   gchar *new_location = NULL;
+  GError *error = NULL;
 
   play_base_bin = GST_PLAY_BASE_BIN (element);
 
   switch (transition) {
     case GST_STATE_READY_TO_PAUSED:
-    {
-      GError *error = NULL;
-
-      if (!setup_source (play_base_bin, &new_location, &error) || error != NULL) {
-        if (!error) {
-          /* opening failed but no error - hellup */
-          GST_ELEMENT_ERROR (GST_ELEMENT (play_base_bin), STREAM,
-              NOT_IMPLEMENTED,
-              ("cannot open file \"%s\"", play_base_bin->uri), (NULL));
-        } else {
-          /* just copy the cached error - type doesn't matter */
-          GST_ELEMENT_ERROR (play_base_bin, STREAM, TOO_LAZY,
-              (error->message), (NULL));
-          g_error_free (error);
-        }
-        ret = GST_STATE_FAILURE;
-        play_base_bin->need_rebuild = TRUE;
-      }
+      if (!setup_source (play_base_bin, &new_location, &error) || error != NULL)
+        goto source_failed;
       break;
-    }
     default:
       break;
   }
 
-  if (ret != GST_STATE_SUCCESS) {
-    return ret;
-  } else {
-    ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
-  }
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
 
   switch (transition) {
     case GST_STATE_READY_TO_PAUSED:
@@ -1688,8 +1695,26 @@ gst_play_base_bin_change_state (GstElement * element)
     default:
       break;
   }
-
   return ret;
+
+  /* ERRORS */
+source_failed:
+  {
+    if (!error) {
+      /* opening failed but no error - hellup */
+      GST_ELEMENT_ERROR (GST_ELEMENT (play_base_bin), STREAM,
+          NOT_IMPLEMENTED,
+          ("cannot open file \"%s\"", play_base_bin->uri), (NULL));
+    } else {
+      /* just copy the cached error - type doesn't matter */
+      GST_ELEMENT_ERROR (play_base_bin, STREAM, TOO_LAZY,
+          (error->message), (NULL));
+      g_error_free (error);
+    }
+    play_base_bin->need_rebuild = TRUE;
+
+    return GST_STATE_FAILURE;
+  }
 }
 
 const GList *
index e7d5f1812d09aa7d8c76da1adc8fcd4a2779feb1..653366fa7d90d3b3c4e9362249ad7fde7361d5ff 100644 (file)
@@ -237,9 +237,7 @@ gst_play_bin_dispose (GObject * object)
   g_free (play_bin->font_desc);
   play_bin->font_desc = NULL;
 
-  if (G_OBJECT_CLASS (parent_class)->dispose) {
-    G_OBJECT_CLASS (parent_class)->dispose (object);
-  }
+  G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
 
@@ -410,7 +408,7 @@ gen_video_element (GstPlayBin * play_bin)
 
   pad = gst_element_get_pad (identity, "sink");
   gst_element_add_ghost_pad (element, pad, "sink");
-  g_object_unref (G_OBJECT (pad));
+  gst_object_unref (GST_OBJECT (pad));
 
   gst_element_set_state (element, GST_STATE_READY);
 
@@ -460,11 +458,11 @@ gen_text_element (GstPlayBin * play_bin)
 
   pad = gst_element_get_pad (overlay, "text_sink");
   gst_element_add_ghost_pad (element, pad, "text_sink");
-  g_object_unref (G_OBJECT (pad));
+  gst_object_unref (GST_OBJECT (pad));
 
   pad = gst_element_get_pad (csp, "sink");
   gst_element_add_ghost_pad (element, pad, "sink");
-  g_object_unref (G_OBJECT (pad));
+  gst_object_unref (GST_OBJECT (pad));
 
   return element;
 }
@@ -525,7 +523,7 @@ gen_audio_element (GstPlayBin * play_bin)
 
   pad = gst_element_get_pad (conv, "sink");
   gst_element_add_ghost_pad (element, pad, "sink");
-  g_object_unref (G_OBJECT (pad));
+  gst_object_unref (GST_OBJECT (pad));
 
   gst_element_set_state (element, GST_STATE_READY);
 
@@ -606,19 +604,19 @@ gen_vis_element (GstPlayBin * play_bin)
   pad = gst_element_get_pad (aqueue, "sink");
   rpad = gst_element_get_request_pad (tee, "src%d");
   gst_pad_link (rpad, pad);
-  g_object_unref (G_OBJECT (rpad));
-  g_object_unref (G_OBJECT (pad));
+  gst_object_unref (GST_OBJECT (rpad));
+  gst_object_unref (GST_OBJECT (pad));
   gst_element_link_pads (aqueue, "src", asink, "sink");
 
   pad = gst_element_get_pad (conv, "sink");
   rpad = gst_element_get_request_pad (tee, "src%d");
   gst_pad_link (rpad, pad);
-  g_object_unref (G_OBJECT (rpad));
-  g_object_unref (G_OBJECT (pad));
+  gst_object_unref (GST_OBJECT (rpad));
+  gst_object_unref (GST_OBJECT (pad));
 
   pad = gst_element_get_pad (tee, "sink");
   gst_element_add_ghost_pad (element, pad, "sink");
-  g_object_unref (G_OBJECT (pad));
+  gst_object_unref (GST_OBJECT (pad));
 
   return element;
 }
@@ -639,27 +637,37 @@ remove_sinks (GstPlayBin * play_bin)
       /* we remove the element from the parent so that
        * there is no unwanted state change when the parent
        * is disposed */
+      play_bin->sinks = g_list_remove (play_bin->sinks, element);
       gst_bin_remove (GST_BIN (parent), element);
-      g_object_unref (G_OBJECT (parent));
+      gst_object_unref (GST_OBJECT (parent));
     }
   }
   element = g_hash_table_lookup (play_bin->cache, "vbin");
   if (element != NULL) {
     parent = gst_element_get_parent (element);
     if (parent != NULL) {
+      play_bin->sinks = g_list_remove (play_bin->sinks, element);
       gst_bin_remove (GST_BIN (parent), element);
-      g_object_unref (G_OBJECT (parent));
+      gst_object_unref (GST_OBJECT (parent));
     }
   }
 
   for (sinks = play_bin->sinks; sinks; sinks = g_list_next (sinks)) {
     GstElement *element = GST_ELEMENT (sinks->data);
-    GstPad *pad = gst_element_get_pad (element, "sink");
+    GstPad *pad;
+    GstPad *peer;
+
+    pad = gst_element_get_pad (element, "sink");
 
     GST_LOG ("removing sink %p", element);
-    if (GST_PAD_PEER (pad))
-      gst_pad_unlink (GST_PAD_PEER (pad), pad);
-    g_object_unref (G_OBJECT (pad));
+
+    peer = gst_pad_get_peer (pad);
+    if (peer) {
+      gst_pad_unlink (peer, pad);
+      gst_object_unref (GST_OBJECT (peer));
+    }
+    gst_object_unref (GST_OBJECT (pad));
+
     gst_bin_remove (GST_BIN (play_bin), element);
   }
   g_list_free (play_bin->sinks);
@@ -694,12 +702,12 @@ add_sink (GstPlayBin * play_bin, GstElement * sink, GstPad * srcpad)
   /* we found a sink for this stream, now try to install it */
   sinkpad = gst_element_get_pad (sink, "sink");
   res = gst_pad_link (srcpad, sinkpad);
-  g_object_unref (G_OBJECT (sinkpad));
+  gst_object_unref (GST_OBJECT (sinkpad));
 
   parent = gst_pad_get_parent (srcpad);
   GST_DEBUG ("Adding sink with state %d (parent: %d, peer: %d)\n",
       GST_STATE (sink), GST_STATE (play_bin), GST_STATE (parent));
-  g_object_unref (G_OBJECT (parent));
+  gst_object_unref (GST_OBJECT (parent));
 
   /* try to link the pad of the sink to the stream */
   if (res < 0) {
@@ -770,7 +778,7 @@ setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group)
     pad = gst_element_get_pad (group->type[GST_STREAM_TYPE_AUDIO - 1].preroll,
         "src");
     add_sink (play_bin, sink, pad);
-    g_object_unref (G_OBJECT (pad));
+    gst_object_unref (GST_OBJECT (pad));
   }
 
   /* link video */
@@ -783,15 +791,15 @@ setup_sinks (GstPlayBaseBin * play_base_bin, GstPlayBaseGroup * group)
           gst_element_get_pad (group->type[GST_STREAM_TYPE_TEXT - 1].preroll,
           "src");
       gst_pad_link (textsrcpad, textsinkpad);
-      g_object_unref (G_OBJECT (textsinkpad));
-      g_object_unref (G_OBJECT (textsrcpad));
+      gst_object_unref (GST_OBJECT (textsinkpad));
+      gst_object_unref (GST_OBJECT (textsrcpad));
     } else {
       sink = gen_video_element (play_bin);
     }
     pad = gst_element_get_pad (group->type[GST_STREAM_TYPE_VIDEO - 1].preroll,
         "src");
     add_sink (play_bin, sink, pad);
-    g_object_unref (G_OBJECT (pad));
+    gst_object_unref (GST_OBJECT (pad));
   }
 
   if (play_bin->fakesink) {
index 22e236a1d267e26701ce1db1b514325c695ef179..f6de76434455cd25511f71ff426e5d0477cb398e 100644 (file)
@@ -219,7 +219,7 @@ gst_stream_info_new (GstObject * object,
     GstProbe *probe;
 
     probe = gst_probe_new (FALSE, cb_probe, info);
-    gst_pad_add_probe (GST_PAD_REALIZE (object), probe);
+    gst_pad_add_probe (GST_PAD_CAST (object), probe);
   }
   info->object = object;
   info->type = type;
@@ -243,7 +243,7 @@ gst_stream_info_dispose (GObject * object)
     GstElement *parent;
 
     parent = gst_pad_get_parent ((GstPad *)
-        GST_PAD_REALIZE (stream_info->object));
+        GST_PAD_CAST (stream_info->object));
     if (parent != NULL) {
       g_signal_handlers_disconnect_by_func (parent,
           G_CALLBACK (stream_info_change_state), stream_info);
@@ -301,11 +301,11 @@ gst_stream_info_set_mute (GstStreamInfo * stream_info, gboolean mute)
 
     stream_info->mute = mute;
     //gst_pad_set_active_recursive ((GstPad *)
-    //GST_PAD_REALIZE (stream_info->object), !mute);
+    //GST_PAD_CAST (stream_info->object), !mute);
     g_warning ("FIXME");
 
     element = gst_pad_get_parent ((GstPad *)
-        GST_PAD_REALIZE (stream_info->object));
+        GST_PAD_CAST (stream_info->object));
     if (mute) {
       g_signal_connect (element, "state-change",
           G_CALLBACK (stream_info_change_state), stream_info);
index eaf6d72f7fea4e69d806c3fe794c27b24f730eba..a52431b5da7d48baf7b8f74a9680d13b2541d705 100644 (file)
@@ -238,8 +238,6 @@ gst_stream_selector_chain (GstPad * pad, GstBuffer * buf)
   GstStreamSelector *sel = GST_STREAM_SELECTOR (gst_pad_get_parent (pad));
   GstFlowReturn res;
 
-  GST_STREAM_LOCK (pad);
-
   /* first, check if the active pad changed. If so, redo
    * negotiation and fail if that fails. */
   if (pad != sel->last_active_sinkpad) {
@@ -255,7 +253,5 @@ gst_stream_selector_chain (GstPad * pad, GstBuffer * buf)
       "buf", gst_pad_get_name (pad));
   res = gst_pad_push (sel->srcpad, buf);
 
-  GST_STREAM_UNLOCK (pad);
-
   return res;
 }