New typefind system: bytestream is now part of the core all plugins have been modifie...
[platform/upstream/gstreamer.git] / gst / gsttypefind.c
index 11768ef..19a2f10 100644 (file)
@@ -26,8 +26,6 @@
 #include "gstinfo.h"
 #include "gsttypefind.h"
 
-#define DEFAULT_MAX_BUFFERS    1
-
 GstElementDetails gst_type_find_details = {
   "TypeFind",
   "Generic",
@@ -39,6 +37,13 @@ GstElementDetails gst_type_find_details = {
   "(C) 1999",
 };
 
+/* generic templates */
+GST_PAD_TEMPLATE_FACTORY (type_find_sink_factory,
+  "sink",
+  GST_PAD_SINK,
+  GST_PAD_ALWAYS,
+  NULL
+);
 
 /* TypeFind signals and args */
 enum {
@@ -49,7 +54,6 @@ enum {
 enum {
   ARG_0,
   ARG_CAPS,
-  ARG_MAX_BUFFERS,
 };
 
 
@@ -63,7 +67,7 @@ static void   gst_type_find_get_property      (GObject *object, guint prop_id,
                                                 GValue *value, 
                                                 GParamSpec *pspec);
 
-static void    gst_type_find_chain             (GstPad *pad, GstBuffer *buf);
+static void    gst_type_find_loopfunc          (GstElement *element);
 static GstElementStateReturn
                gst_type_find_change_state      (GstElement *element);
 
@@ -88,7 +92,9 @@ gst_type_find_get_type (void)
       (GInstanceInitFunc)gst_type_find_init,
       NULL
     };
-    typefind_type = g_type_register_static (GST_TYPE_ELEMENT, "GstTypeFind", &typefind_info, 0);
+    typefind_type = g_type_register_static (GST_TYPE_ELEMENT,
+                                           "GstTypeFind",
+                                           &typefind_info, 0);
   }
   return typefind_type;
 }
@@ -106,11 +112,6 @@ gst_type_find_class_init (GstTypeFindClass *klass)
 
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CAPS,
     g_param_spec_pointer ("caps", "Caps", "Found capabilities", G_PARAM_READABLE));
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BUFFERS,
-    g_param_spec_int ("max_buffers", 
-                     "Max Buffers", 
-                     "Maximal amount of buffers before giving en error (0 == unlimited)", 
-                     0, G_MAXINT, DEFAULT_MAX_BUFFERS, G_PARAM_READWRITE));
 
   gst_type_find_signals[HAVE_TYPE] =
       g_signal_new ("have_type", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
@@ -127,12 +128,13 @@ gst_type_find_class_init (GstTypeFindClass *klass)
 static void
 gst_type_find_init (GstTypeFind *typefind)
 {
-  typefind->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
+  typefind->sinkpad = gst_pad_new_from_template (
+               GST_PAD_TEMPLATE_GET (type_find_sink_factory), "sink");
   gst_element_add_pad (GST_ELEMENT (typefind), typefind->sinkpad);
-  gst_pad_set_chain_function (typefind->sinkpad, gst_type_find_chain);
 
-  typefind->num_buffer = 0;
-  typefind->max_buffers = DEFAULT_MAX_BUFFERS;
+  gst_element_set_loop_function (GST_ELEMENT (typefind),
+                                gst_type_find_loopfunc);
+
   typefind->caps = NULL;
 }
 
@@ -147,9 +149,6 @@ gst_type_find_set_property (GObject *object, guint prop_id,
   typefind = GST_TYPE_FIND (object);
 
   switch (prop_id) {
-    case ARG_MAX_BUFFERS:
-      typefind->max_buffers = g_value_get_int (value);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -170,9 +169,6 @@ gst_type_find_get_property (GObject *object, guint prop_id,
     case ARG_CAPS:
       g_value_set_pointer (value, typefind->caps);
       break;
-    case ARG_MAX_BUFFERS:
-      g_value_set_int (value, typefind->max_buffers);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -180,18 +176,16 @@ gst_type_find_get_property (GObject *object, guint prop_id,
 }
 
 static void
-gst_type_find_chain (GstPad *pad, GstBuffer *buf)
+gst_type_find_loopfunc (GstElement *element)
 {
   GstTypeFind *typefind;
   const GList *type_list;
   GstType *type;
 
-  g_return_if_fail (GST_IS_PAD (pad));
-
-  typefind = GST_TYPE_FIND (GST_OBJECT_PARENT (pad));
+  typefind = GST_TYPE_FIND (element);
 
-  GST_DEBUG ("got buffer of %d bytes in '%s'",
-        GST_BUFFER_SIZE (buf), GST_OBJECT_NAME (typefind));
+  GST_DEBUG ("Started typefinding loop in '%s'",
+            GST_OBJECT_NAME (typefind));
 
   type_list = gst_type_get_list ();
 
@@ -203,42 +197,34 @@ gst_type_find_chain (GstPad *pad, GstBuffer *buf)
 
     while (factories) {
       GstTypeFactory *factory = GST_TYPE_FACTORY (factories->data);
-      GstTypeFindFunc typefindfunc = (GstTypeFindFunc)factory->typefindfunc;
+      GstTypeFindFunc typefindfunc = (GstTypeFindFunc) factory->typefindfunc;
       GstCaps *caps;
 
       GST_CAT_DEBUG (GST_CAT_TYPES, "try type (%p) :%d \"%s\" %p", 
                 factory, type->id, type->mime, typefindfunc);
-      if (typefindfunc && (caps = typefindfunc (buf, factory))) {
+      if (typefindfunc && (caps = typefindfunc (typefind->bs, factory))) {
         GST_CAT_DEBUG (GST_CAT_TYPES, "found type: %d \"%s\" \"%s\"", 
                   caps->id, type->mime, gst_caps_get_name (caps));
-       typefind->caps = caps;
+       gst_caps_replace (&typefind->caps, caps);
 
-       if (gst_pad_try_set_caps (pad, caps) <= 0) {
+       if (gst_pad_try_set_caps (typefind->sinkpad, caps) <= 0) {
           g_warning ("typefind: found type but peer didn't accept it");
        }
 
-       {
-         gst_object_ref (GST_OBJECT (typefind));
-          g_signal_emit (G_OBJECT (typefind), gst_type_find_signals[HAVE_TYPE], 0,
-                             typefind->caps);
-         gst_object_unref (GST_OBJECT (typefind));
-          goto end;
-       }
+       gst_object_ref (GST_OBJECT (typefind));
+       g_signal_emit (G_OBJECT (typefind), gst_type_find_signals[HAVE_TYPE],
+                      0, typefind->caps);
+       gst_object_unref (GST_OBJECT (typefind));
+        return;
       }
       factories = g_slist_next (factories);
     }
     type_list = g_list_next (type_list);
   }
 
-  typefind->num_buffer++;
-
-end:
-  gst_buffer_unref (buf);
-
-  if (typefind->max_buffers && typefind->num_buffer >= typefind->max_buffers) {
-    gst_element_error (GST_ELEMENT (typefind), 
-                   "typefind could not determine type after %d buffers", typefind->num_buffer);
-  }
+  /* if we get here, nothing worked... :'(. */
+  gst_element_error (GST_ELEMENT (typefind), 
+                    "media type could not be detected");
 }
 
 static GstElementStateReturn
@@ -250,17 +236,14 @@ gst_type_find_change_state (GstElement *element)
   typefind = GST_TYPE_FIND (element);
 
   switch (GST_STATE_TRANSITION (element)) {
-    case GST_STATE_NULL_TO_READY:
-      break;
     case GST_STATE_READY_TO_PAUSED:
-      typefind->num_buffer = 0;
-      gst_caps_unref (typefind->caps);
-      typefind->caps = NULL;
+      typefind->bs = gst_bytestream_new (typefind->sinkpad);
       break;
-    case GST_STATE_PAUSED_TO_PLAYING:
-    case GST_STATE_PLAYING_TO_PAUSED:
     case GST_STATE_PAUSED_TO_READY:
-    case GST_STATE_READY_TO_NULL:
+      gst_bytestream_destroy (typefind->bs);
+      gst_caps_replace (&typefind->caps, NULL);
+      break;
+    default:
       break;
   }