gst/playback/gstdecodebin.c: Remove unused properties, and add queues between demuxer...
authorEdward Hervey <bilboed@bilboed.com>
Sun, 27 Nov 2005 17:57:54 +0000 (17:57 +0000)
committerEdward Hervey <bilboed@bilboed.com>
Sun, 27 Nov 2005 17:57:54 +0000 (17:57 +0000)
Original commit message from CVS:
* gst/playback/gstdecodebin.c: (gst_decode_bin_class_init),
(gst_decode_bin_init), (close_pad_link), (try_to_link_1):
Remove unused properties, and add queues between demuxers and decoders
so that a lot more files can preroll properly.

ChangeLog
gst/playback/gstdecodebin.c

index 80df005..f042b7e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2005-11-27  Edward Hervey  <edward@fluendo.com>
+
+       * gst/playback/gstdecodebin.c: (gst_decode_bin_class_init),
+       (gst_decode_bin_init), (close_pad_link), (try_to_link_1):
+       Remove unused properties, and add queues between demuxers and decoders
+       so that a lot more files can preroll properly.
+
 2005-11-27  Thomas Vander Stichele  <thomas at apestaart dot org>
 
        * gst-libs/gst/net/Makefile.am:
index d35ef0a..bd40590 100644 (file)
@@ -58,15 +58,12 @@ struct _GstDecodeBin
   GstElement *typefind;         /* this holds the typefind object */
   GstElement *fakesink;
 
-  gboolean threaded;            /* indicating threaded execution is desired */
   GList *dynamics;              /* list of dynamic connections */
 
   GList *factories;             /* factories we can use for selecting elements */
   gint numpads;
   gint numwaiting;
 
-  GList *elements;              /* elements we added in autoplugging */
-
   guint have_type_id;           /* signal id for the typefind element */
 
   gboolean shutting_down;       /* stop pluggin if we're shutting down */
@@ -84,15 +81,6 @@ struct _GstDecodeBinClass
   void (*unknown_type) (GstElement * element, GstPad * pad, GstCaps * caps);
 };
 
-#define DEFAULT_THREADED       FALSE
-
-/* props */
-enum
-{
-  ARG_0,
-  ARG_THREADED,
-};
-
 /* signals */
 enum
 {
@@ -119,18 +107,14 @@ static void gst_decode_bin_class_init (GstDecodeBinClass * klass);
 static void gst_decode_bin_init (GstDecodeBin * decode_bin);
 static void gst_decode_bin_dispose (GObject * object);
 
-static void gst_decode_bin_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * spec);
-static void gst_decode_bin_get_property (GObject * object, guint prop_id,
-    GValue * value, GParamSpec * spec);
 static GstStateChangeReturn gst_decode_bin_change_state (GstElement * element,
     GstStateChange transition);
 
 static void free_dynamics (GstDecodeBin * decode_bin);
 static void type_found (GstElement * typefind, guint probability,
     GstCaps * caps, GstDecodeBin * decode_bin);
-static GstElement *try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad,
-    GList * factories);
+static GstElement *try_to_link_1 (GstDecodeBin * decode_bin,
+    GstElement * origelement, GstPad * pad, GList * factories);
 static void close_link (GstElement * element, GstDecodeBin * decode_bin);
 static void close_pad_link (GstElement * element, GstPad * pad,
     GstCaps * caps, GstDecodeBin * decode_bin, gboolean more);
@@ -190,13 +174,6 @@ gst_decode_bin_class_init (GstDecodeBinClass * klass)
 
   parent_class = g_type_class_ref (gst_bin_get_type ());
 
-  gobject_klass->set_property = gst_decode_bin_set_property;
-  gobject_klass->get_property = gst_decode_bin_get_property;
-
-  g_object_class_install_property (gobject_klass, ARG_THREADED,
-      g_param_spec_boolean ("threaded", "Threaded", "Use threads",
-          DEFAULT_THREADED, G_PARAM_READWRITE));
-
   gst_decode_bin_signals[SIGNAL_NEW_DECODED_PAD] =
       g_signal_new ("new-decoded-pad", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST,
@@ -351,7 +328,6 @@ gst_decode_bin_init (GstDecodeBin * decode_bin)
     }
   }
 
-  decode_bin->threaded = DEFAULT_THREADED;
   decode_bin->dynamics = NULL;
 }
 
@@ -597,7 +573,7 @@ close_pad_link (GstElement * element, GstPad * pad, GstCaps * caps,
       /* no compatible elements, we cannot go on */
       goto unknown_type;
 
-    try_to_link_1 (decode_bin, pad, to_try);
+    try_to_link_1 (decode_bin, element, pad, to_try);
     /* can free the list again now */
     g_list_free (to_try);
   }
@@ -630,17 +606,29 @@ many_types:
  * pad.
  */
 static GstElement *
-try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad, GList * factories)
+try_to_link_1 (GstDecodeBin * decode_bin, GstElement * srcelement, GstPad * pad,
+    GList * factories)
 {
   GList *walk;
+  GstElementFactory *srcfactory = NULL;
   GstElement *result = NULL;
+  gboolean isdemux = FALSE;
+  const gchar *klass;
+
+  /* Check if the parent of the src pad is a demuxer */
+  srcfactory = gst_element_get_factory (srcelement);
+  klass = gst_element_factory_get_klass (srcfactory);
+  isdemux = !!(strstr (klass, "Demux"));
 
   /* loop over the factories */
   for (walk = factories; walk; walk = g_list_next (walk)) {
     GstElementFactory *factory = GST_ELEMENT_FACTORY (walk->data);
     GstElement *element;
+    GstElement *queue = NULL;
     GstPadLinkReturn ret;
     GstPad *sinkpad;
+    GstPad *usedsrcpad = pad;
+    GstPad *queuesinkpad = NULL, *queuesrcpad = NULL;
 
     GST_DEBUG_OBJECT (decode_bin, "trying to link %s",
         gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
@@ -669,42 +657,53 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad, GList * factories)
     /* set to ready first so it is ready */
     gst_element_set_state (element, GST_STATE_READY);
 
-    /* keep our own list of elements */
-    decode_bin->elements = g_list_prepend (decode_bin->elements, element);
+    if (isdemux) {
+      /* Insert a queue between demuxer and decoder */
+      GST_DEBUG_OBJECT (decode_bin,
+          "Element %s is a demuxer, inserting a queue",
+          GST_OBJECT_NAME (srcelement));
+
+      queue = gst_element_factory_make ("queue", NULL);
+      g_object_set (G_OBJECT (queue), (const gchar *) "max-size-buffers", 0,
+          NULL);
+      g_object_set (G_OBJECT (queue), (const gchar *) "max-size-time", 0LL,
+          NULL);
+      gst_bin_add (GST_BIN (decode_bin), queue);
+      gst_element_set_state (queue, GST_STATE_READY);
+      queuesinkpad = gst_element_get_pad (queue, "sink");
+      usedsrcpad = queuesrcpad = gst_element_get_pad (queue, "src");
+
+      gst_pad_link (pad, queuesinkpad);
+    }
 
-    if ((ret = gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) {
+    if ((ret = gst_pad_link (usedsrcpad, 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 (sinkpad);
       /* this element did not work, remove it again and continue trying
        * other elements, the element will be disposed. */
+      if (isdemux)
+        gst_element_set_state (queue, GST_STATE_NULL);
       gst_element_set_state (element, GST_STATE_NULL);
+      if (isdemux) {
+        gst_pad_unlink (pad, queuesrcpad);
+        gst_object_unref (queuesrcpad);
+        gst_object_unref (queuesinkpad);
+        gst_bin_remove (GST_BIN (decode_bin), queue);
+      }
       gst_bin_remove (GST_BIN (decode_bin), element);
+
     } else {
-      const gchar *klass;
-      GstElementFactory *factory;
       guint sig;
 
       GST_DEBUG_OBJECT (decode_bin, "linked on pad %s:%s",
-          GST_DEBUG_PAD_NAME (pad));
+          GST_DEBUG_PAD_NAME (usedsrcpad));
 
       /* 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) {
-          /* FIXME, do something with threads here. Not sure that it 
-           * really matters here but in general it is better to preroll
-           * on encoded data from the muxer than on raw encoded streams
-           * because that would consume less memory. */
-        }
-      }
 
       /* make sure we catch unlink signals */
-      sig = g_signal_connect (G_OBJECT (pad), "unlinked",
+      sig = g_signal_connect (G_OBJECT (usedsrcpad), "unlinked",
           G_CALLBACK (unlinked), decode_bin);
 
       /* keep a ref to the signal id so that we can disconnect the signal callback */
@@ -720,6 +719,11 @@ try_to_link_1 (GstDecodeBin * decode_bin, GstPad * pad, GList * factories)
 
       /* get rid of the sinkpad now */
       gst_object_unref (sinkpad);
+      if (isdemux) {
+        gst_element_set_state (queue, GST_STATE_PAUSED);
+        gst_object_unref (queuesrcpad);
+        gst_object_unref (queuesinkpad);
+      }
 
       /* and exit */
       goto done;
@@ -1118,46 +1122,6 @@ shutting_down:
   return;
 }
 
-static void
-gst_decode_bin_set_property (GObject * object, guint prop_id,
-    const GValue * value, GParamSpec * pspec)
-{
-  GstDecodeBin *decode_bin;
-
-  g_return_if_fail (GST_IS_DECODE_BIN (object));
-
-  decode_bin = GST_DECODE_BIN (object);
-
-  switch (prop_id) {
-    case ARG_THREADED:
-      decode_bin->threaded = g_value_get_boolean (value);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
-static void
-gst_decode_bin_get_property (GObject * object, guint prop_id, GValue * value,
-    GParamSpec * pspec)
-{
-  GstDecodeBin *decode_bin;
-
-  g_return_if_fail (GST_IS_DECODE_BIN (object));
-
-  decode_bin = GST_DECODE_BIN (object);
-
-  switch (prop_id) {
-    case ARG_THREADED:
-      g_value_set_boolean (value, decode_bin->threaded);
-      break;
-    default:
-      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-      break;
-  }
-}
-
 static GstStateChangeReturn
 gst_decode_bin_change_state (GstElement * element, GstStateChange transition)
 {