Added typefind helper.
authorWim Taymans <wim.taymans@gmail.com>
Tue, 12 Apr 2005 10:52:55 +0000 (10:52 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Tue, 12 Apr 2005 10:52:55 +0000 (10:52 +0000)
Original commit message from CVS:
Added typefind helper.
Small preroll fix in the base sink.
Disable typefind code in basesrc.
Crude port of typefindelement.
Fakesrc cleanups.

28 files changed:
ChangeLog
gst/base/Makefile.am
gst/base/gstbasesink.c
gst/base/gstbasesrc.c
gst/base/gsttypefindhelper.c [new file with mode: 0644]
gst/base/gsttypefindhelper.h [new file with mode: 0644]
gst/elements/Makefile.am
gst/elements/gstelements.c
gst/elements/gstfakesink.c
gst/elements/gstfakesrc.c
gst/elements/gstfakesrc.h
gst/elements/gstfilesrc.c
gst/elements/gsttypefindelement.c
gst/elements/gsttypefindelement.h
gst/gstpipeline.c
libs/gst/base/Makefile.am
libs/gst/base/gstbasesink.c
libs/gst/base/gstbasesrc.c
libs/gst/base/gsttypefindhelper.c [new file with mode: 0644]
libs/gst/base/gsttypefindhelper.h [new file with mode: 0644]
plugins/elements/Makefile.am
plugins/elements/gstelements.c
plugins/elements/gstfakesink.c
plugins/elements/gstfakesrc.c
plugins/elements/gstfakesrc.h
plugins/elements/gstfilesrc.c
plugins/elements/gsttypefindelement.c
plugins/elements/gsttypefindelement.h

index 57f2f9c..c04b93a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,55 @@
-2005-04-11  set REAL_NAME environment variable  <set EMAIL_ADDRESS environment variable>
+2005-04-12  Wim Taymans  <wim@fluendo.com>
+
+       * gst/base/Makefile.am:
+       * gst/base/gstbasesink.c: (gst_basesink_base_init),
+       (gst_basesink_pad_getcaps), (gst_basesink_init),
+       (gst_basesink_event), (gst_basesink_change_state):
+       * gst/base/gstbasesrc.c: (gst_basesrc_get_type),
+       (gst_basesrc_init), (gst_basesrc_query),
+       (gst_basesrc_get_event_mask), (gst_basesrc_do_seek),
+       (gst_basesrc_event_handler), (gst_basesrc_get_range_unlocked),
+       (gst_basesrc_check_get_range), (gst_basesrc_loop),
+       (gst_basesrc_unlock), (gst_basesrc_get_size), (gst_basesrc_start),
+       (gst_basesrc_stop), (gst_basesrc_activate),
+       (gst_basesrc_change_state):
+       * gst/base/gsttypefindhelper.c: (helper_find_peek),
+       (helper_find_suggest), (gst_type_find_helper):
+       * gst/base/gsttypefindhelper.h:
+       * gst/elements/Makefile.am:
+       * gst/elements/gstelements.c:
+       * gst/elements/gstfakesink.c: (gst_fakesink_class_init),
+       (gst_fakesink_get_times), (gst_fakesink_event),
+       (gst_fakesink_preroll), (gst_fakesink_render):
+       * gst/elements/gstfakesrc.c: (gst_fakesrc_class_init),
+       (gst_fakesrc_init), (gst_fakesrc_event_handler),
+       (gst_fakesrc_get_property), (gst_fakesrc_create),
+       (gst_fakesrc_start), (gst_fakesrc_stop):
+       * gst/elements/gstfakesrc.h:
+       * gst/elements/gstfilesrc.c: (gst_filesrc_class_init),
+       (gst_filesrc_free_parent_mmap), (gst_filesrc_map_region),
+       (gst_filesrc_map_small_region), (gst_filesrc_create_mmap),
+       (gst_filesrc_create_read), (gst_filesrc_create),
+       (gst_filesrc_is_seekable), (gst_filesrc_get_size),
+       (gst_filesrc_start):
+       * gst/elements/gsttypefindelement.c:
+       (gst_type_find_element_have_type), (gst_type_find_element_init),
+       (start_typefinding), (stop_typefinding), (push_buffer_store),
+       (gst_type_find_element_handle_event),
+       (gst_type_find_element_chain),
+       (gst_type_find_element_checkgetrange),
+       (gst_type_find_element_getrange), (do_typefind),
+       (gst_type_find_element_activate),
+       (gst_type_find_element_change_state):
+       * gst/elements/gsttypefindelement.h:
+       * gst/gstpipeline.c: (pipeline_bus_handler):
+       Added typefind helper.
+       Small preroll fix in the base sink.
+       Disable typefind code in basesrc.
+       Crude port of typefindelement.
+       Fakesrc cleanups.
+
+
+2005-04-11  Wim Taymans  <wim@fluendo.com>
 
        * check/gst/gstbus.c: (gstbus_suite):
        * check/gst/gstdata.c: (thread_ref), (gst_data_suite):
index 39c382c..528f63a 100644 (file)
@@ -7,9 +7,10 @@ noinst_DATA = $(as_libtool_noinst_DATA_files)
 libgstbase_@GST_MAJORMINOR@_la_DEPENDENCIES = \
        ../libgstreamer-@GST_MAJORMINOR@.la
 libgstbase_@GST_MAJORMINOR@_la_SOURCES =       \
-       gstbasesink.c   \
-       gstbasesrc.c    \
-       gstbasetransform.c      
+       gstbasesink.c           \
+       gstbasesrc.c            \
+       gstbasetransform.c      \
+       gsttypefindhelper.c     
 
 libgstbase_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS)
 libgstbase_@GST_MAJORMINOR@_la_LIBADD = $(GST_OBJ_LIBS) \
@@ -20,9 +21,10 @@ libgstbase_@GST_MAJORMINOR@includedir =              \
        $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/base
 
 libgstbase_@GST_MAJORMINOR@include_HEADERS =   \
-       gstbasesink.h   \
-       gstbasesrc.h    \
-       gstbasetransform.h      
+       gstbasesink.h           \
+       gstbasesrc.h            \
+       gstbasetransform.h      \
+       gsttypefindhelper.h     
 
 install-data-local: as-libtool-install-data-local
 
index 49696c6..6bc6ce0 100644 (file)
@@ -502,9 +502,7 @@ gst_basesink_event (GstPad * pad, GstEvent * event)
 
       GST_STREAM_LOCK (pad);
 
-      GST_PREROLL_LOCK (pad);
-      gst_basesink_preroll_queue_empty (basesink, pad);
-      GST_PREROLL_UNLOCK (pad);
+      gst_basesink_finish_preroll (basesink, pad, NULL);
 
       GST_LOCK (basesink);
       need_eos = basesink->eos = TRUE;
@@ -880,6 +878,8 @@ gst_basesink_change_state (GstElement * element)
       /* make sure the element is finished processing */
       GST_STREAM_LOCK (basesink->sinkpad);
       GST_STREAM_UNLOCK (basesink->sinkpad);
+      /* clear EOS state */
+      basesink->eos = FALSE;
       break;
     case GST_STATE_READY_TO_NULL:
       break;
index 7ff18ba..47b259c 100644 (file)
@@ -29,6 +29,7 @@
 #endif
 
 #include "gstbasesrc.h"
+#include "gsttypefindhelper.h"
 #include <gst/gstmarshal.h>
 
 #define DEFAULT_BLOCKSIZE      4096
@@ -103,8 +104,6 @@ static gboolean gst_basesrc_check_get_range (GstPad * pad);
 static GstFlowReturn gst_basesrc_get_range (GstPad * pad, guint64 offset,
     guint length, GstBuffer ** buf);
 
-static GstCaps *gst_basesrc_type_find (GstBaseSrc * src);
-
 static void
 gst_basesrc_base_init (gpointer g_class)
 {
@@ -351,8 +350,14 @@ static gboolean
 gst_basesrc_event_handler (GstPad * pad, GstEvent * event)
 {
   GstBaseSrc *src;
+  GstBaseSrcClass *bclass;
+  gboolean result;
 
   src = GST_BASESRC (GST_PAD_PARENT (pad));
+  bclass = GST_BASESRC_GET_CLASS (src);
+
+  if (bclass->event)
+    result = bclass->event (src, event);
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_SEEK:
@@ -594,12 +599,14 @@ gst_basesrc_start (GstBaseSrc * basesrc)
   basesrc->segment_start = 0;
 
   /* figure out the size */
-  if (bclass->get_size)
+  if (bclass->get_size) {
     result = bclass->get_size (basesrc, &basesrc->size);
-  else
+  } else {
     result = FALSE;
+    basesrc->size = -1;
+  }
 
-  GST_DEBUG ("size %lld", basesrc->size);
+  GST_DEBUG ("size %d %lld", result, basesrc->size);
 
   /* we always run to the end */
   basesrc->segment_end = -1;
@@ -611,12 +618,15 @@ gst_basesrc_start (GstBaseSrc * basesrc)
     basesrc->seekable = FALSE;
 
   /* run typefind */
+#if 0
   if (basesrc->seekable) {
     GstCaps *caps;
 
-    caps = gst_basesrc_type_find (basesrc);
+    caps = gst_type_find_helper (basesrc->srcpad, basesrc->size);
     gst_pad_set_caps (basesrc->srcpad, caps);
   }
+#endif
+
   return TRUE;
 
   /* ERROR */
@@ -750,100 +760,3 @@ gst_basesrc_change_state (GstElement * element)
 
   return result;
 }
-
-/**
- * typefind code here
- */
-typedef struct
-{
-  GstBaseSrc *src;
-  guint best_probability;
-  GstCaps *caps;
-
-  GstBuffer *buffer;
-}
-BaseSrcTypeFind;
-
-static guint8 *
-basesrc_find_peek (gpointer data, gint64 offset, guint size)
-{
-  BaseSrcTypeFind *find;
-  GstBuffer *buffer;
-  GstBaseSrc *src;
-  GstFlowReturn ret;
-
-  if (size == 0)
-    return NULL;
-
-  find = (BaseSrcTypeFind *) data;
-  src = find->src;
-
-  if (offset < 0) {
-    offset += src->size;
-  }
-
-  buffer = NULL;
-  ret = gst_basesrc_get_range_unlocked (src->srcpad, offset, size, &buffer);
-
-  if (find->buffer) {
-    gst_buffer_unref (find->buffer);
-    find->buffer = NULL;
-  }
-
-  if (ret != GST_FLOW_OK)
-    goto error;
-
-  find->buffer = buffer;
-
-  return GST_BUFFER_DATA (buffer);
-
-error:
-  {
-    return NULL;
-  }
-}
-
-static void
-basesrc_find_suggest (gpointer data, guint probability, const GstCaps * caps)
-{
-  BaseSrcTypeFind *find = (BaseSrcTypeFind *) data;
-
-  if (probability > find->best_probability) {
-    gst_caps_replace (&find->caps, gst_caps_copy (caps));
-    find->best_probability = probability;
-  }
-}
-
-static GstCaps *
-gst_basesrc_type_find (GstBaseSrc * src)
-{
-  GstTypeFind gst_find;
-  BaseSrcTypeFind find;
-  GList *walk, *type_list = NULL;
-  GstCaps *result = NULL;
-
-  walk = type_list = gst_type_find_factory_get_list ();
-
-  find.src = src;
-  find.best_probability = 0;
-  find.caps = NULL;
-  find.buffer = NULL;
-  gst_find.data = &find;
-  gst_find.peek = basesrc_find_peek;
-  gst_find.suggest = basesrc_find_suggest;
-  gst_find.get_length = NULL;
-
-  while (walk) {
-    GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
-
-    gst_type_find_factory_call_function (factory, &gst_find);
-    if (find.best_probability >= GST_TYPE_FIND_MAXIMUM)
-      break;
-    walk = g_list_next (walk);
-  }
-
-  if (find.best_probability > 0)
-    result = find.caps;
-
-  return result;
-}
diff --git a/gst/base/gsttypefindhelper.c b/gst/base/gsttypefindhelper.c
new file mode 100644 (file)
index 0000000..6aa44b4
--- /dev/null
@@ -0,0 +1,131 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *               2000,2005 Wim Taymans <wim@fluendo.com>
+ *
+ * gsttypefindhelper.c: 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "gsttypefindhelper.h"
+
+/**
+ * typefind code here
+ */
+typedef struct
+{
+  GstPad *src;
+  guint best_probability;
+  GstCaps *caps;
+  guint64 size;
+  GstBuffer *buffer;
+}
+GstTypeFindHelper;
+
+static guint8 *
+helper_find_peek (gpointer data, gint64 offset, guint size)
+{
+  GstTypeFindHelper *find;
+  GstBuffer *buffer;
+  GstPad *src;
+  GstFlowReturn ret;
+
+  if (size == 0)
+    return NULL;
+
+  find = (GstTypeFindHelper *) data;
+  src = find->src;
+
+  if (offset < 0) {
+    if (find->size == -1)
+      return NULL;
+
+    offset += find->size;
+  }
+
+  buffer = NULL;
+  ret = GST_RPAD_GETRANGEFUNC (src) (src, offset, size, &buffer);
+
+  if (find->buffer) {
+    gst_buffer_unref (find->buffer);
+    find->buffer = NULL;
+  }
+
+  if (ret != GST_FLOW_OK)
+    goto error;
+
+  find->buffer = buffer;
+
+  return GST_BUFFER_DATA (buffer);
+
+error:
+  {
+    return NULL;
+  }
+}
+
+static void
+helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
+{
+  GstTypeFindHelper *find = (GstTypeFindHelper *) data;
+
+  if (probability > find->best_probability) {
+    gst_caps_replace (&find->caps, gst_caps_copy (caps));
+    find->best_probability = probability;
+  }
+}
+
+GstCaps *
+gst_type_find_helper (GstPad * src, guint64 size)
+{
+  GstTypeFind gst_find;
+  GstTypeFindHelper find;
+  GList *walk, *type_list = NULL;
+  GstCaps *result = NULL;
+
+  walk = type_list = gst_type_find_factory_get_list ();
+
+  find.src = src;
+  find.best_probability = 0;
+  find.caps = NULL;
+  find.size = size;
+  find.buffer = NULL;
+  gst_find.data = &find;
+  gst_find.peek = helper_find_peek;
+  gst_find.suggest = helper_find_suggest;
+  gst_find.get_length = NULL;
+
+  while (walk) {
+    GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
+
+    gst_type_find_factory_call_function (factory, &gst_find);
+    if (find.best_probability >= GST_TYPE_FIND_MAXIMUM)
+      break;
+    walk = g_list_next (walk);
+  }
+
+  if (find.best_probability > 0)
+    result = find.caps;
+
+  return result;
+}
diff --git a/gst/base/gsttypefindhelper.h b/gst/base/gsttypefindhelper.h
new file mode 100644 (file)
index 0000000..6b1e608
--- /dev/null
@@ -0,0 +1,34 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *               2000,2005 Wim Taymans <wim@fluendo.com>
+ *
+ * gsttypefindhelper.h: 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_TYPEFINDHELPER_H__
+#define __GST_TYPEFINDHELPER_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+GstCaps * gst_type_find_helper (GstPad *src, guint64 size);
+
+G_END_DECLS
+
+#endif /* __GST_TYPEFINDHELPER_H__ */
index 1cd9bc1..8565358 100644 (file)
@@ -24,19 +24,20 @@ endif
 
 libgstelements_la_DEPENDENCIES = ../libgstreamer-@GST_MAJORMINOR@.la
 libgstelements_la_SOURCES =    \
+       gstbufferstore.c        \
        gstfakesrc.c            \
        gstfakesink.c           \
        gstfilesrc.c            \
        gstidentity.c           \
        gstelements.c           \
-       gsttee.c
+       gsttee.c                \
+       gsttypefindelement.c
 
 # FIXME 0.9: mentioned by po/POTFILES.in, so we include them here --
 # this is a short-term hack, really we should just decide the fate of
 # these files above, then this will be unnecessary
 EXTRA_DIST +=                  \
        gstaggregator.c         \
-       gstbufferstore.c        \
        gstfilesink.c           \
        gstfdsink.c             \
        gstfdsrc.c              \
@@ -44,8 +45,7 @@ EXTRA_DIST +=                 \
        gstmultifilesrc.c       \
        gstpipefilter.c         \
        gstshaper.c             \
-       gststatistics.c         \
-       gsttypefindelement.c
+       gststatistics.c
 
 
 libgstelements_la_CFLAGS = $(GST_OBJ_CFLAGS)
index 2099c74..249a944 100644 (file)
@@ -71,7 +71,7 @@ static struct _elements_entry _elements[] = {
 //  {"shaper", GST_RANK_NONE, gst_shaper_get_type},
 //  {"statistics", GST_RANK_NONE, gst_statistics_get_type},
   {"tee", GST_RANK_NONE, gst_tee_get_type},
-//  {"typefind", GST_RANK_NONE, gst_type_find_element_get_type},
+  {"typefind", GST_RANK_NONE, gst_type_find_element_get_type},
 //  {NULL, 0},
 };
 
index b8d483c..30a8fdb 100644 (file)
@@ -278,7 +278,7 @@ gst_fakesink_event (GstBaseSink * bsink, GstEvent * event)
     g_free (sink->last_message);
 
     sink->last_message =
-        g_strdup_printf ("chain   ******* E (type: %d) %p",
+        g_strdup_printf ("event   ******* E (type: %d) %p",
         GST_EVENT_TYPE (event), event);
 
     g_object_notify (G_OBJECT (sink), "last_message");
index 3be5c0b..b437fa3 100644 (file)
 #include "gstfakesrc.h"
 #include <gst/gstmarshal.h>
 
-#define DEFAULT_SIZEMIN                0
-#define DEFAULT_SIZEMAX                4096
-#define DEFAULT_PARENTSIZE     4096*10
-#define DEFAULT_DATARATE       0
-#define DEFAULT_SYNC           FALSE
-
 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
@@ -60,10 +54,25 @@ enum
   LAST_SIGNAL
 };
 
+#define DEFAULT_OUTPUT         FAKESRC_FIRST_LAST_LOOP
+#define DEFAULT_DATA           FAKESRC_DATA_ALLOCATE
+#define DEFAULT_SIZETYPE       FAKESRC_SIZETYPE_NULL
+#define DEFAULT_SIZEMIN                0
+#define DEFAULT_SIZEMAX                4096
+#define DEFAULT_FILLTYPE       FAKESRC_FILLTYPE_NULL
+#define DEFAULT_DATARATE       0
+#define DEFAULT_SYNC           FALSE
+#define DEFAULT_PATTERN                NULL
+#define DEFAULT_NUM_BUFFERS    -1
+#define DEFAULT_EOS            FALSE
+#define DEFAULT_SIGNAL_HANDOFFS FALSE
+#define DEFAULT_SILENT         FALSE
+#define DEFAULT_DUMP           FALSE
+#define DEFAULT_PARENTSIZE     4096*10
+
 enum
 {
   ARG_0,
-  ARG_NUM_SOURCES,
   ARG_OUTPUT,
   ARG_DATA,
   ARG_SIZETYPE,
@@ -176,7 +185,8 @@ static void gst_fakesrc_set_property (GObject * object, guint prop_id,
 static void gst_fakesrc_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static GstElementStateReturn gst_fakesrc_change_state (GstElement * element);
+static gboolean gst_fakesrc_start (GstBaseSrc * basesrc);
+static gboolean gst_fakesrc_stop (GstBaseSrc * basesrc);
 
 static gboolean gst_fakesrc_event_handler (GstBaseSrc * src, GstEvent * event);
 static GstFlowReturn gst_fakesrc_create (GstBaseSrc * src, guint64 offset,
@@ -209,19 +219,16 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass)
   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesrc_set_property);
   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesrc_get_property);
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES,
-      g_param_spec_int ("num-sources", "num-sources", "Number of sources",
-          1, G_MAXINT, 1, G_PARAM_READABLE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_OUTPUT,
       g_param_spec_enum ("output", "output", "Output method (currently unused)",
-          GST_TYPE_FAKESRC_OUTPUT, FAKESRC_FIRST_LAST_LOOP, G_PARAM_READWRITE));
+          GST_TYPE_FAKESRC_OUTPUT, DEFAULT_OUTPUT, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATA,
       g_param_spec_enum ("data", "data", "Data allocation method",
-          GST_TYPE_FAKESRC_DATA, FAKESRC_DATA_ALLOCATE, G_PARAM_READWRITE));
+          GST_TYPE_FAKESRC_DATA, DEFAULT_DATA, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZETYPE,
       g_param_spec_enum ("sizetype", "sizetype",
           "How to determine buffer sizes", GST_TYPE_FAKESRC_SIZETYPE,
-          FAKESRC_SIZETYPE_NULL, G_PARAM_READWRITE));
+          DEFAULT_SIZETYPE, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
       g_param_spec_int ("sizemin", "sizemin", "Minimum buffer size", 0,
           G_MAXINT, DEFAULT_SIZEMIN, G_PARAM_READWRITE));
@@ -235,7 +242,7 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass)
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILLTYPE,
       g_param_spec_enum ("filltype", "filltype",
           "How to fill the buffer, if at all", GST_TYPE_FAKESRC_FILLTYPE,
-          FAKESRC_FILLTYPE_NULL, G_PARAM_READWRITE));
+          DEFAULT_FILLTYPE, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATARATE,
       g_param_spec_int ("datarate", "Datarate",
           "Timestamps buffers with number of bytes per second (0 = none)", 0,
@@ -244,27 +251,29 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass)
       g_param_spec_boolean ("sync", "Sync", "Sync to the clock to the datarate",
           DEFAULT_SYNC, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PATTERN,
-      g_param_spec_string ("pattern", "pattern", "pattern", NULL,
+      g_param_spec_string ("pattern", "pattern", "pattern", DEFAULT_PATTERN,
           G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_BUFFERS,
       g_param_spec_int ("num-buffers", "num-buffers",
-          "Number of buffers to output before sending EOS", -1, G_MAXINT, 0,
-          G_PARAM_READWRITE));
+          "Number of buffers to output before sending EOS", -1, G_MAXINT,
+          DEFAULT_NUM_BUFFERS, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EOS,
-      g_param_spec_boolean ("eos", "eos", "Send out the EOS event?", TRUE,
-          G_PARAM_READWRITE));
+      g_param_spec_boolean ("eos", "eos", "Send out the EOS event?",
+          DEFAULT_EOS, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
       g_param_spec_string ("last-message", "last-message",
           "The last status message", NULL, G_PARAM_READABLE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
       g_param_spec_boolean ("silent", "Silent",
-          "Don't produce last_message events", FALSE, G_PARAM_READWRITE));
+          "Don't produce last_message events", DEFAULT_SILENT,
+          G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIGNAL_HANDOFFS,
       g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
-          "Send a signal before pushing the buffer", FALSE, G_PARAM_READWRITE));
+          "Send a signal before pushing the buffer", DEFAULT_SIGNAL_HANDOFFS,
+          G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
       g_param_spec_boolean ("dump", "Dump", "Dump produced bytes to stdout",
-          FALSE, G_PARAM_READWRITE));
+          DEFAULT_DUMP, G_PARAM_READWRITE));
 
   gst_fakesrc_signals[SIGNAL_HANDOFF] =
       g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
@@ -272,8 +281,8 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass)
       gst_marshal_VOID__BOXED_OBJECT, G_TYPE_NONE, 1,
       GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE);
 
-  gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_fakesrc_change_state);
-
+  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_fakesrc_start);
+  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_fakesrc_stop);
   gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_fakesrc_event_handler);
   gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_fakesrc_create);
 }
@@ -284,14 +293,13 @@ gst_fakesrc_init (GstFakeSrc * fakesrc)
   fakesrc->output = FAKESRC_FIRST_LAST_LOOP;
   fakesrc->segment_start = -1;
   fakesrc->segment_end = -1;
-  fakesrc->num_buffers = -1;
+  fakesrc->num_buffers = DEFAULT_NUM_BUFFERS;
   fakesrc->rt_num_buffers = -1;
   fakesrc->buffer_count = 0;
-  fakesrc->silent = FALSE;
-  fakesrc->signal_handoffs = FALSE;
-  fakesrc->dump = FALSE;
+  fakesrc->silent = DEFAULT_SILENT;
+  fakesrc->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
+  fakesrc->dump = DEFAULT_DUMP;
   fakesrc->pattern_byte = 0x00;
-  fakesrc->need_flush = FALSE;
   fakesrc->data = FAKESRC_DATA_ALLOCATE;
   fakesrc->sizetype = FAKESRC_SIZETYPE_NULL;
   fakesrc->filltype = FAKESRC_FILLTYPE_NOTHING;
@@ -302,7 +310,6 @@ gst_fakesrc_init (GstFakeSrc * fakesrc)
   fakesrc->last_message = NULL;
   fakesrc->datarate = DEFAULT_DATARATE;
   fakesrc->sync = DEFAULT_SYNC;
-  fakesrc->pad_mode = GST_ACTIVATE_NONE;
 }
 
 static gboolean
@@ -312,22 +319,16 @@ gst_fakesrc_event_handler (GstBaseSrc * basesrc, GstEvent * event)
 
   src = GST_FAKESRC (basesrc);
 
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_SEEK:
-      src->segment_start = GST_EVENT_SEEK_OFFSET (event);
-      src->segment_end = GST_EVENT_SEEK_ENDOFFSET (event);
-      src->buffer_count = src->segment_start;
-      src->segment_loop =
-          GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_SEGMENT_LOOP;
-      src->need_flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH;
-      break;
-    case GST_EVENT_FLUSH:
-      src->need_flush = TRUE;
-      break;
-    default:
-      break;
+  if (!src->silent) {
+    g_free (src->last_message);
+
+    src->last_message =
+        g_strdup_printf ("event   ******* E (type: %d) %p",
+        GST_EVENT_TYPE (event), event);
+
+    g_object_notify (G_OBJECT (src), "last_message");
   }
-  gst_event_unref (event);
+
 
   return TRUE;
 }
@@ -427,9 +428,6 @@ gst_fakesrc_get_property (GObject * object, guint prop_id, GValue * value,
   src = GST_FAKESRC (object);
 
   switch (prop_id) {
-    case ARG_NUM_SOURCES:
-      g_value_set_int (value, GST_ELEMENT (src)->numsrcpads);
-      break;
     case ARG_OUTPUT:
       g_value_set_enum (value, src->output);
       break;
@@ -632,6 +630,8 @@ gst_fakesrc_create (GstBaseSrc * basesrc, guint64 offset, guint length,
   src = GST_FAKESRC (basesrc);
 
   if (src->buffer_count == src->segment_end) {
+    GST_INFO ("buffer_count reaches segment_end %d %d", src->buffer_count,
+        src->segment_end);
     return GST_FLOW_UNEXPECTED;
   }
 
@@ -686,51 +686,35 @@ gst_fakesrc_create (GstBaseSrc * basesrc, guint64 offset, guint length,
   return GST_FLOW_OK;
 }
 
-static GstElementStateReturn
-gst_fakesrc_change_state (GstElement * element)
+static gboolean
+gst_fakesrc_start (GstBaseSrc * basesrc)
 {
-  GstFakeSrc *fakesrc;
-  GstElementStateReturn result = GST_STATE_FAILURE;
+  GstFakeSrc *src;
 
-  g_return_val_if_fail (GST_IS_FAKESRC (element), result);
+  src = GST_FAKESRC (basesrc);
 
-  fakesrc = GST_FAKESRC (element);
+  src->buffer_count = 0;
+  src->pattern_byte = 0x00;
+  src->eos = FALSE;
+  src->bytes_sent = 0;
+  src->rt_num_buffers = src->num_buffers;
 
-  switch (GST_STATE_TRANSITION (element)) {
-    case GST_STATE_NULL_TO_READY:
-      break;
-    case GST_STATE_READY_TO_PAUSED:
-    {
-      fakesrc->buffer_count = 0;
-      fakesrc->pattern_byte = 0x00;
-      fakesrc->need_flush = FALSE;
-      fakesrc->eos = FALSE;
-      fakesrc->bytes_sent = 0;
-      fakesrc->rt_num_buffers = fakesrc->num_buffers;
-      break;
-    }
-    case GST_STATE_PAUSED_TO_PLAYING:
-      break;
-  }
+  return TRUE;
+}
 
-  result = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+static gboolean
+gst_fakesrc_stop (GstBaseSrc * basesrc)
+{
+  GstFakeSrc *src;
 
-  switch (GST_STATE_TRANSITION (element)) {
-    case GST_STATE_PLAYING_TO_PAUSED:
-      break;
-    case GST_STATE_PAUSED_TO_READY:
-      if (fakesrc->parent) {
-        gst_buffer_unref (fakesrc->parent);
-        fakesrc->parent = NULL;
-      }
-      g_free (fakesrc->last_message);
-      fakesrc->last_message = NULL;
-      break;
-    case GST_STATE_READY_TO_NULL:
-      break;
-    default:
-      break;
+  src = GST_FAKESRC (basesrc);
+
+  if (src->parent) {
+    gst_buffer_unref (src->parent);
+    src->parent = NULL;
   }
+  g_free (src->last_message);
+  src->last_message = NULL;
 
-  return result;
+  return TRUE;
 }
index 3cda131..af286fd 100644 (file)
@@ -84,7 +84,6 @@ struct _GstFakeSrc {
   GstFakeSrcDataType   data;
   GstFakeSrcSizeType   sizetype;
   GstFakeSrcFillType   filltype;
-  GstActivateMode      pad_mode;
 
   guint         sizemin;
   guint         sizemax;
@@ -106,7 +105,6 @@ struct _GstFakeSrc {
   gboolean      silent;
   gboolean      signal_handoffs;
   gboolean      dump;
-  gboolean      need_flush;
 
   guint64        bytes_sent;
 
index 2c60acd..22f93d5 100644 (file)
@@ -135,6 +135,7 @@ static void gst_filesrc_get_property (GObject * object, guint prop_id,
 static gboolean gst_filesrc_start (GstBaseSrc * basesrc);
 static gboolean gst_filesrc_stop (GstBaseSrc * basesrc);
 
+static gboolean gst_filesrc_is_seekable (GstBaseSrc * src);
 static gboolean gst_filesrc_get_size (GstBaseSrc * src, guint64 * size);
 static GstFlowReturn gst_filesrc_create (GstBaseSrc * src, guint64 offset,
     guint length, GstBuffer ** buffer);
@@ -203,6 +204,7 @@ gst_filesrc_class_init (GstFileSrcClass * klass)
 
   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_filesrc_start);
   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_filesrc_stop);
+  gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_filesrc_is_seekable);
   gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_filesrc_get_size);
   gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_filesrc_create);
 }
@@ -713,6 +715,12 @@ gst_filesrc_create (GstBaseSrc * basesrc, guint64 offset, guint length,
 }
 
 static gboolean
+gst_filesrc_is_seekable (GstBaseSrc * src)
+{
+  return TRUE;
+}
+
+static gboolean
 gst_filesrc_get_size (GstBaseSrc * basesrc, guint64 * size)
 {
   struct stat stat_results;
index 9c7b162..a0e9ae9 100644 (file)
  *    requests
  * 7) goto 2
  * 8) take best available result and use its caps
+ *
+ * The element has two scheduling modes:
+ *
+ * 1) chain based, it will collect buffers and run the typefind function on
+ *    the buffer until something is found.
+ * 2) getrange based, it will proxy the getrange function to the sinkpad. It
+ *    is assumed that the peer element is happy with whatever format we 
+ *    eventually read.
+ *
+ * When the element has no connected srcpad, and the sinkpad can operate in
+ * getrange based mode, the element starts its own task to figure out the 
+ * type of the stream.
+ * 
  */
 
 #ifdef HAVE_CONFIG_H
@@ -41,6 +54,7 @@
 #include "gsttypefindelement.h"
 #include "gst/gst_private.h"
 #include "gst/gst-i18n-lib.h"
+#include "gst/base/gsttypefindhelper.h"
 
 #include <gst/gsttypefind.h>
 #include <gst/gstutils.h>
@@ -84,8 +98,6 @@ enum
 enum
 {
   MODE_NORMAL,                  /* act as identity */
-  MODE_TRANSITION,              /* wait for the discont between the two
-                                 * other modes */
   MODE_TYPEFIND                 /* do typefinding */
 };
 
@@ -108,11 +120,19 @@ static gboolean gst_type_find_element_src_event (GstPad * pad,
     GstEvent * event);
 static gboolean gst_type_find_handle_src_query (GstPad * pad,
     GstQueryType type, GstFormat * fmt, gint64 * value);
-static void push_buffer_store (GstTypeFindElement * typefind);
+static GstFlowReturn push_buffer_store (GstTypeFindElement * typefind);
 
-static void gst_type_find_element_chain (GstPad * sinkpad, GstData * data);
+static gboolean gst_type_find_element_handle_event (GstPad * pad,
+    GstEvent * event);
+static GstFlowReturn gst_type_find_element_chain (GstPad * sinkpad,
+    GstBuffer * buffer);
+static GstFlowReturn gst_type_find_element_getrange (GstPad * srcpad,
+    guint64 offset, guint length, GstBuffer ** buffer);
+static gboolean gst_type_find_element_checkgetrange (GstPad * srcpad);
 static GstElementStateReturn
 gst_type_find_element_change_state (GstElement * element);
+static gboolean
+gst_type_find_element_activate (GstPad * pad, GstActivateMode mode);
 
 static guint gst_type_find_element_signals[LAST_SIGNAL] = { 0 };
 
@@ -125,8 +145,9 @@ gst_type_find_element_have_type (GstTypeFindElement * typefind,
 
   GST_INFO_OBJECT (typefind, "found caps %" GST_PTR_FORMAT, caps);
   typefind->caps = gst_caps_copy (caps);
-  gst_pad_set_explicit_caps (typefind->src, caps);
+  gst_pad_set_caps (typefind->src, (GstCaps *) caps);
 }
+
 static void
 gst_type_find_element_base_init (gpointer g_class)
 {
@@ -182,18 +203,26 @@ gst_type_find_element_init (GstTypeFindElement * typefind)
   typefind->sink =
       gst_pad_new_from_template (gst_static_pad_template_get
       (&type_find_element_sink_template), "sink");
+  gst_pad_set_activate_function (typefind->sink,
+      gst_type_find_element_activate);
   gst_pad_set_chain_function (typefind->sink, gst_type_find_element_chain);
+  gst_pad_set_event_function (typefind->sink,
+      gst_type_find_element_handle_event);
   gst_element_add_pad (GST_ELEMENT (typefind), typefind->sink);
   /* srcpad */
   typefind->src =
       gst_pad_new_from_template (gst_static_pad_template_get
       (&type_find_element_src_template), "src");
+  gst_pad_set_activate_function (typefind->src, gst_type_find_element_activate);
+  gst_pad_set_checkgetrange_function (typefind->src,
+      gst_type_find_element_checkgetrange);
+  gst_pad_set_getrange_function (typefind->src, gst_type_find_element_getrange);
   gst_pad_set_event_function (typefind->src, gst_type_find_element_src_event);
   gst_pad_set_event_mask_function (typefind->src,
       gst_type_find_element_src_event_mask);
   gst_pad_set_query_function (typefind->src,
       GST_DEBUG_FUNCPTR (gst_type_find_handle_src_query));
-  gst_pad_use_explicit_caps (typefind->src);
+  gst_pad_use_fixed_caps (typefind->src);
   gst_element_add_pad (GST_ELEMENT (typefind), typefind->src);
 
   typefind->caps = NULL;
@@ -201,8 +230,6 @@ gst_type_find_element_init (GstTypeFindElement * typefind)
   typefind->max_probability = GST_TYPE_FIND_MAXIMUM;
 
   typefind->store = gst_buffer_store_new ();
-
-  GST_FLAG_SET (typefind, GST_ELEMENT_EVENT_AWARE);
 }
 static void
 gst_type_find_element_dispose (GObject * object)
@@ -359,7 +386,7 @@ start_typefinding (GstTypeFindElement * typefind)
   g_assert (typefind->possibilities == NULL);
 
   GST_DEBUG_OBJECT (typefind, "starting typefinding");
-  gst_pad_unnegotiate (typefind->src);
+  gst_pad_set_caps (typefind->src, NULL);
   if (typefind->caps) {
     gst_caps_replace (&typefind->caps, NULL);
   }
@@ -370,9 +397,14 @@ start_typefinding (GstTypeFindElement * typefind)
 static void
 stop_typefinding (GstTypeFindElement * typefind)
 {
+  GstElementState state;
+
   /* stop all typefinding and set mode back to normal */
-  gboolean push_cached_buffers =
-      gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING;
+  gboolean push_cached_buffers;
+
+  gst_element_get_state (GST_ELEMENT (typefind), &state, NULL, NULL);
+
+  push_cached_buffers = (state >= GST_STATE_PAUSED);
 
   GST_DEBUG_OBJECT (typefind, "stopping typefinding%s",
       push_cached_buffers ? " and pushing cached buffers" : "");
@@ -384,47 +416,35 @@ stop_typefinding (GstTypeFindElement * typefind)
     g_list_free (typefind->possibilities);
     typefind->possibilities = NULL;
   }
-
-  typefind->mode = MODE_TRANSITION;
+  //typefind->mode = MODE_TRANSITION;
 
   if (!push_cached_buffers) {
     gst_buffer_store_clear (typefind->store);
   } else {
-    guint size = gst_buffer_store_get_size (typefind->store, 0);
-
-    GST_DEBUG_OBJECT (typefind, "seeking back to current position %u", size);
-    if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink),
-            gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES,
-                size))) {
-      GST_WARNING_OBJECT (typefind,
-          "could not seek to required position %u, hope for the best", size);
-      typefind->mode = MODE_NORMAL;
-      /* push out our queued buffers here */
-      push_buffer_store (typefind);
-    } else {
-      typefind->waiting_for_discont_offset = size;
-    }
+    typefind->mode = MODE_NORMAL;
+    /* push out our queued buffers here */
+    push_buffer_store (typefind);
   }
 }
 
-static void
+static GstFlowReturn
 push_buffer_store (GstTypeFindElement * typefind)
 {
   guint size = gst_buffer_store_get_size (typefind->store, 0);
   GstBuffer *buffer;
+  GstFlowReturn ret;
 
-  gst_pad_push (typefind->src, GST_DATA (gst_event_new_discontinuous (TRUE,
-              GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0,
-              GST_FORMAT_UNDEFINED)));
   if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) {
     GST_DEBUG_OBJECT (typefind, "pushing cached data (%u bytes)", size);
-    gst_pad_push (typefind->src, GST_DATA (buffer));
+    ret = gst_pad_push (typefind->src, buffer);
   } else {
-    /* FIXME: shouldn't we throw an error here? */
     size = 0;
+    ret = GST_FLOW_ERROR;
   }
 
   gst_buffer_store_clear (typefind->store);
+
+  return ret;
 }
 
 static guint64
@@ -460,9 +480,11 @@ find_element_get_length (gpointer data)
 
   return entry->self->stream_length;
 }
-static void
+
+static gboolean
 gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
 {
+  gboolean res = FALSE;
   TypeFindEntry *entry;
   GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad));
 
@@ -485,9 +507,9 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
                 0, entry->probability, entry->caps);
             stop_typefinding (typefind);
             push_buffer_store (typefind);
-            gst_pad_event_default (pad, event);
+            res = gst_pad_event_default (pad, event);
           } else {
-            gst_pad_event_default (pad, event);
+            res = gst_pad_event_default (pad, event);
             GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL),
                 (NULL));
             stop_typefinding (typefind);
@@ -495,44 +517,23 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
           break;
         default:
           gst_data_unref (GST_DATA (event));
+          res = TRUE;
           break;
       }
       break;
-    case MODE_TRANSITION:
-      if (GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS) {
-        if (GST_EVENT_DISCONT_NEW_MEDIA (event)) {
-          start_typefinding (typefind);
-          gst_event_unref (event);
-        } else {
-          guint64 off;
-
-          if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &off) &&
-              off == typefind->waiting_for_discont_offset) {
-            typefind->mode = MODE_NORMAL;
-            push_buffer_store (typefind);
-          } else {
-            gst_event_unref (event);
-          }
-        }
-      } else if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
-        push_buffer_store (typefind);
-        gst_pad_event_default (pad, event);
-      } else {
-        gst_event_unref (event);
-      }
-      break;
     case MODE_NORMAL:
-      if (GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS &&
-          GST_EVENT_DISCONT_NEW_MEDIA (event)) {
+      if (GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS) {
         start_typefinding (typefind);
         gst_event_unref (event);
+        res = TRUE;
       } else {
-        gst_pad_event_default (pad, event);
+        res = gst_pad_event_default (pad, event);
       }
       break;
     default:
       g_assert_not_reached ();
   }
+  return res;
 }
 static guint8 *
 find_peek (gpointer data, gint64 offset, guint size)
@@ -583,6 +584,7 @@ find_suggest (gpointer data, guint probability, const GstCaps * caps)
     gst_caps_replace (&entry->caps, gst_caps_copy (caps));
   }
 }
+
 static gint
 compare_type_find_entry (gconstpointer a, gconstpointer b)
 {
@@ -596,40 +598,37 @@ compare_type_find_entry (gconstpointer a, gconstpointer b)
     return two->probability - one->probability;
   }
 }
+
 static gint
 compare_type_find_factory (gconstpointer fac1, gconstpointer fac2)
 {
   return GST_PLUGIN_FEATURE (fac1)->rank - GST_PLUGIN_FEATURE (fac2)->rank;
 }
-static void
-gst_type_find_element_chain (GstPad * pad, GstData * data)
+
+static GstFlowReturn
+gst_type_find_element_chain (GstPad * pad, GstBuffer * buffer)
 {
   GstTypeFindElement *typefind;
   GList *entries;
   TypeFindEntry *entry;
   GList *walk;
+  GstFlowReturn res = GST_FLOW_OK;
   GstTypeFind find = { find_peek, find_suggest, NULL, find_element_get_length };
 
   typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad));
-  if (GST_IS_EVENT (data)) {
-    gst_type_find_element_handle_event (pad, GST_EVENT (data));
-    return;
-  }
+
   switch (typefind->mode) {
     case MODE_NORMAL:
-      gst_pad_push (typefind->src, data);
-      return;
-    case MODE_TRANSITION:
-      gst_data_unref (data);
-      return;
+      return gst_pad_push (typefind->src, buffer);
     case MODE_TYPEFIND:{
       guint64 current_offset;
 
-      gst_buffer_store_add_buffer (typefind->store, GST_BUFFER (data));
-      current_offset = GST_BUFFER_OFFSET_IS_VALID (data) ?
-          GST_BUFFER_OFFSET (data) + GST_BUFFER_SIZE (data) :
+      gst_buffer_store_add_buffer (typefind->store, buffer);
+      current_offset = GST_BUFFER_OFFSET_IS_VALID (buffer) ?
+          GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer) :
           gst_buffer_store_get_size (typefind->store, 0);
-      gst_data_unref (data);
+      gst_buffer_unref (buffer);
+
       if (typefind->possibilities == NULL) {
         /* not yet started, get all typefinding functions into our "queue" */
         GList *all_factories = gst_type_find_factory_get_list ();
@@ -800,27 +799,108 @@ gst_type_find_element_chain (GstPad * pad, GstData * data)
     }
     default:
       g_assert_not_reached ();
-      return;
+      return GST_FLOW_ERROR;
   }
+
+  return res;
 }
+
+static gboolean
+gst_type_find_element_checkgetrange (GstPad * srcpad)
+{
+  GstTypeFindElement *typefind;
+
+  typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (srcpad));
+
+  return gst_pad_check_pull_range (typefind->sink);
+}
+
+static GstFlowReturn
+gst_type_find_element_getrange (GstPad * srcpad,
+    guint64 offset, guint length, GstBuffer ** buffer)
+{
+  GstTypeFindElement *typefind;
+
+  typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (srcpad));
+
+  return gst_pad_pull_range (typefind->sink, offset, length, buffer);
+}
+
+static gboolean
+do_typefind (GstTypeFindElement * typefind)
+{
+  GstCaps *caps;
+  GstPad *peer;
+
+  peer = gst_pad_get_peer (typefind->sink);
+  if (peer) {
+    gst_pad_peer_set_active (typefind->sink, GST_ACTIVATE_PULL);
+
+    caps = gst_type_find_helper (peer, 0);
+    gst_pad_set_caps (typefind->src, caps);
+
+    if (caps) {
+      g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE],
+          0, 100, caps);
+    }
+
+    gst_object_unref (GST_OBJECT (peer));
+  }
+
+  return TRUE;
+}
+
+static gboolean
+gst_type_find_element_activate (GstPad * pad, GstActivateMode mode)
+{
+  gboolean result;
+  GstTypeFindElement *typefind;
+
+  typefind = GST_TYPE_FIND_ELEMENT (GST_OBJECT_PARENT (pad));
+
+  switch (mode) {
+    case GST_ACTIVATE_PUSH:
+    case GST_ACTIVATE_PULL:
+      result = TRUE;
+      break;
+    default:
+      result = TRUE;
+      break;
+  }
+
+  return result;
+}
+
 static GstElementStateReturn
 gst_type_find_element_change_state (GstElement * element)
 {
+  GstElementState transition;
+  GstElementStateReturn ret;
   GstTypeFindElement *typefind;
 
   typefind = GST_TYPE_FIND_ELEMENT (element);
 
-  switch (GST_STATE_TRANSITION (element)) {
+  transition = GST_STATE_TRANSITION (element);
+  switch (transition) {
     case GST_STATE_READY_TO_PAUSED:
-      start_typefinding (typefind);
+      do_typefind (typefind);
+
+      //start_typefinding (typefind);
       break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  switch (transition) {
     case GST_STATE_PAUSED_TO_READY:
-      stop_typefinding (typefind);
+      //stop_typefinding (typefind);
       gst_caps_replace (&typefind->caps, NULL);
       break;
     default:
       break;
   }
 
-  return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+  return ret;
 }
index 43debd5..03eeccd 100644 (file)
@@ -53,7 +53,6 @@ struct _GstTypeFindElement {
   GstCaps *            caps;
 
   guint                        mode;
-  guint64              waiting_for_discont_offset;
   GstBufferStore *     store;
   guint64              stream_length;
   gboolean             stream_length_available;
index 1446fbd..62f9005 100644 (file)
@@ -318,6 +318,7 @@ pipeline_bus_handler (GstBus * bus, GstMessage * message,
   switch (GST_MESSAGE_TYPE (message)) {
     case GST_MESSAGE_EOS:
       if (GST_MESSAGE_SRC (message) != GST_OBJECT (pipeline)) {
+        GST_DEBUG ("got EOS message");
         GST_LOCK (bus);
         pipeline->eosed =
             g_list_prepend (pipeline->eosed, GST_MESSAGE_SRC (message));
index 39c382c..528f63a 100644 (file)
@@ -7,9 +7,10 @@ noinst_DATA = $(as_libtool_noinst_DATA_files)
 libgstbase_@GST_MAJORMINOR@_la_DEPENDENCIES = \
        ../libgstreamer-@GST_MAJORMINOR@.la
 libgstbase_@GST_MAJORMINOR@_la_SOURCES =       \
-       gstbasesink.c   \
-       gstbasesrc.c    \
-       gstbasetransform.c      
+       gstbasesink.c           \
+       gstbasesrc.c            \
+       gstbasetransform.c      \
+       gsttypefindhelper.c     
 
 libgstbase_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS)
 libgstbase_@GST_MAJORMINOR@_la_LIBADD = $(GST_OBJ_LIBS) \
@@ -20,9 +21,10 @@ libgstbase_@GST_MAJORMINOR@includedir =              \
        $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/base
 
 libgstbase_@GST_MAJORMINOR@include_HEADERS =   \
-       gstbasesink.h   \
-       gstbasesrc.h    \
-       gstbasetransform.h      
+       gstbasesink.h           \
+       gstbasesrc.h            \
+       gstbasetransform.h      \
+       gsttypefindhelper.h     
 
 install-data-local: as-libtool-install-data-local
 
index 49696c6..6bc6ce0 100644 (file)
@@ -502,9 +502,7 @@ gst_basesink_event (GstPad * pad, GstEvent * event)
 
       GST_STREAM_LOCK (pad);
 
-      GST_PREROLL_LOCK (pad);
-      gst_basesink_preroll_queue_empty (basesink, pad);
-      GST_PREROLL_UNLOCK (pad);
+      gst_basesink_finish_preroll (basesink, pad, NULL);
 
       GST_LOCK (basesink);
       need_eos = basesink->eos = TRUE;
@@ -880,6 +878,8 @@ gst_basesink_change_state (GstElement * element)
       /* make sure the element is finished processing */
       GST_STREAM_LOCK (basesink->sinkpad);
       GST_STREAM_UNLOCK (basesink->sinkpad);
+      /* clear EOS state */
+      basesink->eos = FALSE;
       break;
     case GST_STATE_READY_TO_NULL:
       break;
index 7ff18ba..47b259c 100644 (file)
@@ -29,6 +29,7 @@
 #endif
 
 #include "gstbasesrc.h"
+#include "gsttypefindhelper.h"
 #include <gst/gstmarshal.h>
 
 #define DEFAULT_BLOCKSIZE      4096
@@ -103,8 +104,6 @@ static gboolean gst_basesrc_check_get_range (GstPad * pad);
 static GstFlowReturn gst_basesrc_get_range (GstPad * pad, guint64 offset,
     guint length, GstBuffer ** buf);
 
-static GstCaps *gst_basesrc_type_find (GstBaseSrc * src);
-
 static void
 gst_basesrc_base_init (gpointer g_class)
 {
@@ -351,8 +350,14 @@ static gboolean
 gst_basesrc_event_handler (GstPad * pad, GstEvent * event)
 {
   GstBaseSrc *src;
+  GstBaseSrcClass *bclass;
+  gboolean result;
 
   src = GST_BASESRC (GST_PAD_PARENT (pad));
+  bclass = GST_BASESRC_GET_CLASS (src);
+
+  if (bclass->event)
+    result = bclass->event (src, event);
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_SEEK:
@@ -594,12 +599,14 @@ gst_basesrc_start (GstBaseSrc * basesrc)
   basesrc->segment_start = 0;
 
   /* figure out the size */
-  if (bclass->get_size)
+  if (bclass->get_size) {
     result = bclass->get_size (basesrc, &basesrc->size);
-  else
+  } else {
     result = FALSE;
+    basesrc->size = -1;
+  }
 
-  GST_DEBUG ("size %lld", basesrc->size);
+  GST_DEBUG ("size %d %lld", result, basesrc->size);
 
   /* we always run to the end */
   basesrc->segment_end = -1;
@@ -611,12 +618,15 @@ gst_basesrc_start (GstBaseSrc * basesrc)
     basesrc->seekable = FALSE;
 
   /* run typefind */
+#if 0
   if (basesrc->seekable) {
     GstCaps *caps;
 
-    caps = gst_basesrc_type_find (basesrc);
+    caps = gst_type_find_helper (basesrc->srcpad, basesrc->size);
     gst_pad_set_caps (basesrc->srcpad, caps);
   }
+#endif
+
   return TRUE;
 
   /* ERROR */
@@ -750,100 +760,3 @@ gst_basesrc_change_state (GstElement * element)
 
   return result;
 }
-
-/**
- * typefind code here
- */
-typedef struct
-{
-  GstBaseSrc *src;
-  guint best_probability;
-  GstCaps *caps;
-
-  GstBuffer *buffer;
-}
-BaseSrcTypeFind;
-
-static guint8 *
-basesrc_find_peek (gpointer data, gint64 offset, guint size)
-{
-  BaseSrcTypeFind *find;
-  GstBuffer *buffer;
-  GstBaseSrc *src;
-  GstFlowReturn ret;
-
-  if (size == 0)
-    return NULL;
-
-  find = (BaseSrcTypeFind *) data;
-  src = find->src;
-
-  if (offset < 0) {
-    offset += src->size;
-  }
-
-  buffer = NULL;
-  ret = gst_basesrc_get_range_unlocked (src->srcpad, offset, size, &buffer);
-
-  if (find->buffer) {
-    gst_buffer_unref (find->buffer);
-    find->buffer = NULL;
-  }
-
-  if (ret != GST_FLOW_OK)
-    goto error;
-
-  find->buffer = buffer;
-
-  return GST_BUFFER_DATA (buffer);
-
-error:
-  {
-    return NULL;
-  }
-}
-
-static void
-basesrc_find_suggest (gpointer data, guint probability, const GstCaps * caps)
-{
-  BaseSrcTypeFind *find = (BaseSrcTypeFind *) data;
-
-  if (probability > find->best_probability) {
-    gst_caps_replace (&find->caps, gst_caps_copy (caps));
-    find->best_probability = probability;
-  }
-}
-
-static GstCaps *
-gst_basesrc_type_find (GstBaseSrc * src)
-{
-  GstTypeFind gst_find;
-  BaseSrcTypeFind find;
-  GList *walk, *type_list = NULL;
-  GstCaps *result = NULL;
-
-  walk = type_list = gst_type_find_factory_get_list ();
-
-  find.src = src;
-  find.best_probability = 0;
-  find.caps = NULL;
-  find.buffer = NULL;
-  gst_find.data = &find;
-  gst_find.peek = basesrc_find_peek;
-  gst_find.suggest = basesrc_find_suggest;
-  gst_find.get_length = NULL;
-
-  while (walk) {
-    GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
-
-    gst_type_find_factory_call_function (factory, &gst_find);
-    if (find.best_probability >= GST_TYPE_FIND_MAXIMUM)
-      break;
-    walk = g_list_next (walk);
-  }
-
-  if (find.best_probability > 0)
-    result = find.caps;
-
-  return result;
-}
diff --git a/libs/gst/base/gsttypefindhelper.c b/libs/gst/base/gsttypefindhelper.c
new file mode 100644 (file)
index 0000000..6aa44b4
--- /dev/null
@@ -0,0 +1,131 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *               2000,2005 Wim Taymans <wim@fluendo.com>
+ *
+ * gsttypefindhelper.c: 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "gsttypefindhelper.h"
+
+/**
+ * typefind code here
+ */
+typedef struct
+{
+  GstPad *src;
+  guint best_probability;
+  GstCaps *caps;
+  guint64 size;
+  GstBuffer *buffer;
+}
+GstTypeFindHelper;
+
+static guint8 *
+helper_find_peek (gpointer data, gint64 offset, guint size)
+{
+  GstTypeFindHelper *find;
+  GstBuffer *buffer;
+  GstPad *src;
+  GstFlowReturn ret;
+
+  if (size == 0)
+    return NULL;
+
+  find = (GstTypeFindHelper *) data;
+  src = find->src;
+
+  if (offset < 0) {
+    if (find->size == -1)
+      return NULL;
+
+    offset += find->size;
+  }
+
+  buffer = NULL;
+  ret = GST_RPAD_GETRANGEFUNC (src) (src, offset, size, &buffer);
+
+  if (find->buffer) {
+    gst_buffer_unref (find->buffer);
+    find->buffer = NULL;
+  }
+
+  if (ret != GST_FLOW_OK)
+    goto error;
+
+  find->buffer = buffer;
+
+  return GST_BUFFER_DATA (buffer);
+
+error:
+  {
+    return NULL;
+  }
+}
+
+static void
+helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
+{
+  GstTypeFindHelper *find = (GstTypeFindHelper *) data;
+
+  if (probability > find->best_probability) {
+    gst_caps_replace (&find->caps, gst_caps_copy (caps));
+    find->best_probability = probability;
+  }
+}
+
+GstCaps *
+gst_type_find_helper (GstPad * src, guint64 size)
+{
+  GstTypeFind gst_find;
+  GstTypeFindHelper find;
+  GList *walk, *type_list = NULL;
+  GstCaps *result = NULL;
+
+  walk = type_list = gst_type_find_factory_get_list ();
+
+  find.src = src;
+  find.best_probability = 0;
+  find.caps = NULL;
+  find.size = size;
+  find.buffer = NULL;
+  gst_find.data = &find;
+  gst_find.peek = helper_find_peek;
+  gst_find.suggest = helper_find_suggest;
+  gst_find.get_length = NULL;
+
+  while (walk) {
+    GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (walk->data);
+
+    gst_type_find_factory_call_function (factory, &gst_find);
+    if (find.best_probability >= GST_TYPE_FIND_MAXIMUM)
+      break;
+    walk = g_list_next (walk);
+  }
+
+  if (find.best_probability > 0)
+    result = find.caps;
+
+  return result;
+}
diff --git a/libs/gst/base/gsttypefindhelper.h b/libs/gst/base/gsttypefindhelper.h
new file mode 100644 (file)
index 0000000..6b1e608
--- /dev/null
@@ -0,0 +1,34 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *               2000,2005 Wim Taymans <wim@fluendo.com>
+ *
+ * gsttypefindhelper.h: 
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_TYPEFINDHELPER_H__
+#define __GST_TYPEFINDHELPER_H__
+
+#include <gst/gst.h>
+
+G_BEGIN_DECLS
+
+GstCaps * gst_type_find_helper (GstPad *src, guint64 size);
+
+G_END_DECLS
+
+#endif /* __GST_TYPEFINDHELPER_H__ */
index 1cd9bc1..8565358 100644 (file)
@@ -24,19 +24,20 @@ endif
 
 libgstelements_la_DEPENDENCIES = ../libgstreamer-@GST_MAJORMINOR@.la
 libgstelements_la_SOURCES =    \
+       gstbufferstore.c        \
        gstfakesrc.c            \
        gstfakesink.c           \
        gstfilesrc.c            \
        gstidentity.c           \
        gstelements.c           \
-       gsttee.c
+       gsttee.c                \
+       gsttypefindelement.c
 
 # FIXME 0.9: mentioned by po/POTFILES.in, so we include them here --
 # this is a short-term hack, really we should just decide the fate of
 # these files above, then this will be unnecessary
 EXTRA_DIST +=                  \
        gstaggregator.c         \
-       gstbufferstore.c        \
        gstfilesink.c           \
        gstfdsink.c             \
        gstfdsrc.c              \
@@ -44,8 +45,7 @@ EXTRA_DIST +=                 \
        gstmultifilesrc.c       \
        gstpipefilter.c         \
        gstshaper.c             \
-       gststatistics.c         \
-       gsttypefindelement.c
+       gststatistics.c
 
 
 libgstelements_la_CFLAGS = $(GST_OBJ_CFLAGS)
index 2099c74..249a944 100644 (file)
@@ -71,7 +71,7 @@ static struct _elements_entry _elements[] = {
 //  {"shaper", GST_RANK_NONE, gst_shaper_get_type},
 //  {"statistics", GST_RANK_NONE, gst_statistics_get_type},
   {"tee", GST_RANK_NONE, gst_tee_get_type},
-//  {"typefind", GST_RANK_NONE, gst_type_find_element_get_type},
+  {"typefind", GST_RANK_NONE, gst_type_find_element_get_type},
 //  {NULL, 0},
 };
 
index b8d483c..30a8fdb 100644 (file)
@@ -278,7 +278,7 @@ gst_fakesink_event (GstBaseSink * bsink, GstEvent * event)
     g_free (sink->last_message);
 
     sink->last_message =
-        g_strdup_printf ("chain   ******* E (type: %d) %p",
+        g_strdup_printf ("event   ******* E (type: %d) %p",
         GST_EVENT_TYPE (event), event);
 
     g_object_notify (G_OBJECT (sink), "last_message");
index 3be5c0b..b437fa3 100644 (file)
 #include "gstfakesrc.h"
 #include <gst/gstmarshal.h>
 
-#define DEFAULT_SIZEMIN                0
-#define DEFAULT_SIZEMAX                4096
-#define DEFAULT_PARENTSIZE     4096*10
-#define DEFAULT_DATARATE       0
-#define DEFAULT_SYNC           FALSE
-
 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
     GST_PAD_ALWAYS,
@@ -60,10 +54,25 @@ enum
   LAST_SIGNAL
 };
 
+#define DEFAULT_OUTPUT         FAKESRC_FIRST_LAST_LOOP
+#define DEFAULT_DATA           FAKESRC_DATA_ALLOCATE
+#define DEFAULT_SIZETYPE       FAKESRC_SIZETYPE_NULL
+#define DEFAULT_SIZEMIN                0
+#define DEFAULT_SIZEMAX                4096
+#define DEFAULT_FILLTYPE       FAKESRC_FILLTYPE_NULL
+#define DEFAULT_DATARATE       0
+#define DEFAULT_SYNC           FALSE
+#define DEFAULT_PATTERN                NULL
+#define DEFAULT_NUM_BUFFERS    -1
+#define DEFAULT_EOS            FALSE
+#define DEFAULT_SIGNAL_HANDOFFS FALSE
+#define DEFAULT_SILENT         FALSE
+#define DEFAULT_DUMP           FALSE
+#define DEFAULT_PARENTSIZE     4096*10
+
 enum
 {
   ARG_0,
-  ARG_NUM_SOURCES,
   ARG_OUTPUT,
   ARG_DATA,
   ARG_SIZETYPE,
@@ -176,7 +185,8 @@ static void gst_fakesrc_set_property (GObject * object, guint prop_id,
 static void gst_fakesrc_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static GstElementStateReturn gst_fakesrc_change_state (GstElement * element);
+static gboolean gst_fakesrc_start (GstBaseSrc * basesrc);
+static gboolean gst_fakesrc_stop (GstBaseSrc * basesrc);
 
 static gboolean gst_fakesrc_event_handler (GstBaseSrc * src, GstEvent * event);
 static GstFlowReturn gst_fakesrc_create (GstBaseSrc * src, guint64 offset,
@@ -209,19 +219,16 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass)
   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesrc_set_property);
   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesrc_get_property);
 
-  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES,
-      g_param_spec_int ("num-sources", "num-sources", "Number of sources",
-          1, G_MAXINT, 1, G_PARAM_READABLE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_OUTPUT,
       g_param_spec_enum ("output", "output", "Output method (currently unused)",
-          GST_TYPE_FAKESRC_OUTPUT, FAKESRC_FIRST_LAST_LOOP, G_PARAM_READWRITE));
+          GST_TYPE_FAKESRC_OUTPUT, DEFAULT_OUTPUT, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATA,
       g_param_spec_enum ("data", "data", "Data allocation method",
-          GST_TYPE_FAKESRC_DATA, FAKESRC_DATA_ALLOCATE, G_PARAM_READWRITE));
+          GST_TYPE_FAKESRC_DATA, DEFAULT_DATA, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZETYPE,
       g_param_spec_enum ("sizetype", "sizetype",
           "How to determine buffer sizes", GST_TYPE_FAKESRC_SIZETYPE,
-          FAKESRC_SIZETYPE_NULL, G_PARAM_READWRITE));
+          DEFAULT_SIZETYPE, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
       g_param_spec_int ("sizemin", "sizemin", "Minimum buffer size", 0,
           G_MAXINT, DEFAULT_SIZEMIN, G_PARAM_READWRITE));
@@ -235,7 +242,7 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass)
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILLTYPE,
       g_param_spec_enum ("filltype", "filltype",
           "How to fill the buffer, if at all", GST_TYPE_FAKESRC_FILLTYPE,
-          FAKESRC_FILLTYPE_NULL, G_PARAM_READWRITE));
+          DEFAULT_FILLTYPE, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATARATE,
       g_param_spec_int ("datarate", "Datarate",
           "Timestamps buffers with number of bytes per second (0 = none)", 0,
@@ -244,27 +251,29 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass)
       g_param_spec_boolean ("sync", "Sync", "Sync to the clock to the datarate",
           DEFAULT_SYNC, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PATTERN,
-      g_param_spec_string ("pattern", "pattern", "pattern", NULL,
+      g_param_spec_string ("pattern", "pattern", "pattern", DEFAULT_PATTERN,
           G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_BUFFERS,
       g_param_spec_int ("num-buffers", "num-buffers",
-          "Number of buffers to output before sending EOS", -1, G_MAXINT, 0,
-          G_PARAM_READWRITE));
+          "Number of buffers to output before sending EOS", -1, G_MAXINT,
+          DEFAULT_NUM_BUFFERS, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_EOS,
-      g_param_spec_boolean ("eos", "eos", "Send out the EOS event?", TRUE,
-          G_PARAM_READWRITE));
+      g_param_spec_boolean ("eos", "eos", "Send out the EOS event?",
+          DEFAULT_EOS, G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE,
       g_param_spec_string ("last-message", "last-message",
           "The last status message", NULL, G_PARAM_READABLE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
       g_param_spec_boolean ("silent", "Silent",
-          "Don't produce last_message events", FALSE, G_PARAM_READWRITE));
+          "Don't produce last_message events", DEFAULT_SILENT,
+          G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIGNAL_HANDOFFS,
       g_param_spec_boolean ("signal-handoffs", "Signal handoffs",
-          "Send a signal before pushing the buffer", FALSE, G_PARAM_READWRITE));
+          "Send a signal before pushing the buffer", DEFAULT_SIGNAL_HANDOFFS,
+          G_PARAM_READWRITE));
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
       g_param_spec_boolean ("dump", "Dump", "Dump produced bytes to stdout",
-          FALSE, G_PARAM_READWRITE));
+          DEFAULT_DUMP, G_PARAM_READWRITE));
 
   gst_fakesrc_signals[SIGNAL_HANDOFF] =
       g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
@@ -272,8 +281,8 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass)
       gst_marshal_VOID__BOXED_OBJECT, G_TYPE_NONE, 1,
       GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE);
 
-  gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_fakesrc_change_state);
-
+  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_fakesrc_start);
+  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_fakesrc_stop);
   gstbasesrc_class->event = GST_DEBUG_FUNCPTR (gst_fakesrc_event_handler);
   gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_fakesrc_create);
 }
@@ -284,14 +293,13 @@ gst_fakesrc_init (GstFakeSrc * fakesrc)
   fakesrc->output = FAKESRC_FIRST_LAST_LOOP;
   fakesrc->segment_start = -1;
   fakesrc->segment_end = -1;
-  fakesrc->num_buffers = -1;
+  fakesrc->num_buffers = DEFAULT_NUM_BUFFERS;
   fakesrc->rt_num_buffers = -1;
   fakesrc->buffer_count = 0;
-  fakesrc->silent = FALSE;
-  fakesrc->signal_handoffs = FALSE;
-  fakesrc->dump = FALSE;
+  fakesrc->silent = DEFAULT_SILENT;
+  fakesrc->signal_handoffs = DEFAULT_SIGNAL_HANDOFFS;
+  fakesrc->dump = DEFAULT_DUMP;
   fakesrc->pattern_byte = 0x00;
-  fakesrc->need_flush = FALSE;
   fakesrc->data = FAKESRC_DATA_ALLOCATE;
   fakesrc->sizetype = FAKESRC_SIZETYPE_NULL;
   fakesrc->filltype = FAKESRC_FILLTYPE_NOTHING;
@@ -302,7 +310,6 @@ gst_fakesrc_init (GstFakeSrc * fakesrc)
   fakesrc->last_message = NULL;
   fakesrc->datarate = DEFAULT_DATARATE;
   fakesrc->sync = DEFAULT_SYNC;
-  fakesrc->pad_mode = GST_ACTIVATE_NONE;
 }
 
 static gboolean
@@ -312,22 +319,16 @@ gst_fakesrc_event_handler (GstBaseSrc * basesrc, GstEvent * event)
 
   src = GST_FAKESRC (basesrc);
 
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_SEEK:
-      src->segment_start = GST_EVENT_SEEK_OFFSET (event);
-      src->segment_end = GST_EVENT_SEEK_ENDOFFSET (event);
-      src->buffer_count = src->segment_start;
-      src->segment_loop =
-          GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_SEGMENT_LOOP;
-      src->need_flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH;
-      break;
-    case GST_EVENT_FLUSH:
-      src->need_flush = TRUE;
-      break;
-    default:
-      break;
+  if (!src->silent) {
+    g_free (src->last_message);
+
+    src->last_message =
+        g_strdup_printf ("event   ******* E (type: %d) %p",
+        GST_EVENT_TYPE (event), event);
+
+    g_object_notify (G_OBJECT (src), "last_message");
   }
-  gst_event_unref (event);
+
 
   return TRUE;
 }
@@ -427,9 +428,6 @@ gst_fakesrc_get_property (GObject * object, guint prop_id, GValue * value,
   src = GST_FAKESRC (object);
 
   switch (prop_id) {
-    case ARG_NUM_SOURCES:
-      g_value_set_int (value, GST_ELEMENT (src)->numsrcpads);
-      break;
     case ARG_OUTPUT:
       g_value_set_enum (value, src->output);
       break;
@@ -632,6 +630,8 @@ gst_fakesrc_create (GstBaseSrc * basesrc, guint64 offset, guint length,
   src = GST_FAKESRC (basesrc);
 
   if (src->buffer_count == src->segment_end) {
+    GST_INFO ("buffer_count reaches segment_end %d %d", src->buffer_count,
+        src->segment_end);
     return GST_FLOW_UNEXPECTED;
   }
 
@@ -686,51 +686,35 @@ gst_fakesrc_create (GstBaseSrc * basesrc, guint64 offset, guint length,
   return GST_FLOW_OK;
 }
 
-static GstElementStateReturn
-gst_fakesrc_change_state (GstElement * element)
+static gboolean
+gst_fakesrc_start (GstBaseSrc * basesrc)
 {
-  GstFakeSrc *fakesrc;
-  GstElementStateReturn result = GST_STATE_FAILURE;
+  GstFakeSrc *src;
 
-  g_return_val_if_fail (GST_IS_FAKESRC (element), result);
+  src = GST_FAKESRC (basesrc);
 
-  fakesrc = GST_FAKESRC (element);
+  src->buffer_count = 0;
+  src->pattern_byte = 0x00;
+  src->eos = FALSE;
+  src->bytes_sent = 0;
+  src->rt_num_buffers = src->num_buffers;
 
-  switch (GST_STATE_TRANSITION (element)) {
-    case GST_STATE_NULL_TO_READY:
-      break;
-    case GST_STATE_READY_TO_PAUSED:
-    {
-      fakesrc->buffer_count = 0;
-      fakesrc->pattern_byte = 0x00;
-      fakesrc->need_flush = FALSE;
-      fakesrc->eos = FALSE;
-      fakesrc->bytes_sent = 0;
-      fakesrc->rt_num_buffers = fakesrc->num_buffers;
-      break;
-    }
-    case GST_STATE_PAUSED_TO_PLAYING:
-      break;
-  }
+  return TRUE;
+}
 
-  result = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+static gboolean
+gst_fakesrc_stop (GstBaseSrc * basesrc)
+{
+  GstFakeSrc *src;
 
-  switch (GST_STATE_TRANSITION (element)) {
-    case GST_STATE_PLAYING_TO_PAUSED:
-      break;
-    case GST_STATE_PAUSED_TO_READY:
-      if (fakesrc->parent) {
-        gst_buffer_unref (fakesrc->parent);
-        fakesrc->parent = NULL;
-      }
-      g_free (fakesrc->last_message);
-      fakesrc->last_message = NULL;
-      break;
-    case GST_STATE_READY_TO_NULL:
-      break;
-    default:
-      break;
+  src = GST_FAKESRC (basesrc);
+
+  if (src->parent) {
+    gst_buffer_unref (src->parent);
+    src->parent = NULL;
   }
+  g_free (src->last_message);
+  src->last_message = NULL;
 
-  return result;
+  return TRUE;
 }
index 3cda131..af286fd 100644 (file)
@@ -84,7 +84,6 @@ struct _GstFakeSrc {
   GstFakeSrcDataType   data;
   GstFakeSrcSizeType   sizetype;
   GstFakeSrcFillType   filltype;
-  GstActivateMode      pad_mode;
 
   guint         sizemin;
   guint         sizemax;
@@ -106,7 +105,6 @@ struct _GstFakeSrc {
   gboolean      silent;
   gboolean      signal_handoffs;
   gboolean      dump;
-  gboolean      need_flush;
 
   guint64        bytes_sent;
 
index 2c60acd..22f93d5 100644 (file)
@@ -135,6 +135,7 @@ static void gst_filesrc_get_property (GObject * object, guint prop_id,
 static gboolean gst_filesrc_start (GstBaseSrc * basesrc);
 static gboolean gst_filesrc_stop (GstBaseSrc * basesrc);
 
+static gboolean gst_filesrc_is_seekable (GstBaseSrc * src);
 static gboolean gst_filesrc_get_size (GstBaseSrc * src, guint64 * size);
 static GstFlowReturn gst_filesrc_create (GstBaseSrc * src, guint64 offset,
     guint length, GstBuffer ** buffer);
@@ -203,6 +204,7 @@ gst_filesrc_class_init (GstFileSrcClass * klass)
 
   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_filesrc_start);
   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_filesrc_stop);
+  gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_filesrc_is_seekable);
   gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_filesrc_get_size);
   gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_filesrc_create);
 }
@@ -713,6 +715,12 @@ gst_filesrc_create (GstBaseSrc * basesrc, guint64 offset, guint length,
 }
 
 static gboolean
+gst_filesrc_is_seekable (GstBaseSrc * src)
+{
+  return TRUE;
+}
+
+static gboolean
 gst_filesrc_get_size (GstBaseSrc * basesrc, guint64 * size)
 {
   struct stat stat_results;
index 9c7b162..a0e9ae9 100644 (file)
  *    requests
  * 7) goto 2
  * 8) take best available result and use its caps
+ *
+ * The element has two scheduling modes:
+ *
+ * 1) chain based, it will collect buffers and run the typefind function on
+ *    the buffer until something is found.
+ * 2) getrange based, it will proxy the getrange function to the sinkpad. It
+ *    is assumed that the peer element is happy with whatever format we 
+ *    eventually read.
+ *
+ * When the element has no connected srcpad, and the sinkpad can operate in
+ * getrange based mode, the element starts its own task to figure out the 
+ * type of the stream.
+ * 
  */
 
 #ifdef HAVE_CONFIG_H
@@ -41,6 +54,7 @@
 #include "gsttypefindelement.h"
 #include "gst/gst_private.h"
 #include "gst/gst-i18n-lib.h"
+#include "gst/base/gsttypefindhelper.h"
 
 #include <gst/gsttypefind.h>
 #include <gst/gstutils.h>
@@ -84,8 +98,6 @@ enum
 enum
 {
   MODE_NORMAL,                  /* act as identity */
-  MODE_TRANSITION,              /* wait for the discont between the two
-                                 * other modes */
   MODE_TYPEFIND                 /* do typefinding */
 };
 
@@ -108,11 +120,19 @@ static gboolean gst_type_find_element_src_event (GstPad * pad,
     GstEvent * event);
 static gboolean gst_type_find_handle_src_query (GstPad * pad,
     GstQueryType type, GstFormat * fmt, gint64 * value);
-static void push_buffer_store (GstTypeFindElement * typefind);
+static GstFlowReturn push_buffer_store (GstTypeFindElement * typefind);
 
-static void gst_type_find_element_chain (GstPad * sinkpad, GstData * data);
+static gboolean gst_type_find_element_handle_event (GstPad * pad,
+    GstEvent * event);
+static GstFlowReturn gst_type_find_element_chain (GstPad * sinkpad,
+    GstBuffer * buffer);
+static GstFlowReturn gst_type_find_element_getrange (GstPad * srcpad,
+    guint64 offset, guint length, GstBuffer ** buffer);
+static gboolean gst_type_find_element_checkgetrange (GstPad * srcpad);
 static GstElementStateReturn
 gst_type_find_element_change_state (GstElement * element);
+static gboolean
+gst_type_find_element_activate (GstPad * pad, GstActivateMode mode);
 
 static guint gst_type_find_element_signals[LAST_SIGNAL] = { 0 };
 
@@ -125,8 +145,9 @@ gst_type_find_element_have_type (GstTypeFindElement * typefind,
 
   GST_INFO_OBJECT (typefind, "found caps %" GST_PTR_FORMAT, caps);
   typefind->caps = gst_caps_copy (caps);
-  gst_pad_set_explicit_caps (typefind->src, caps);
+  gst_pad_set_caps (typefind->src, (GstCaps *) caps);
 }
+
 static void
 gst_type_find_element_base_init (gpointer g_class)
 {
@@ -182,18 +203,26 @@ gst_type_find_element_init (GstTypeFindElement * typefind)
   typefind->sink =
       gst_pad_new_from_template (gst_static_pad_template_get
       (&type_find_element_sink_template), "sink");
+  gst_pad_set_activate_function (typefind->sink,
+      gst_type_find_element_activate);
   gst_pad_set_chain_function (typefind->sink, gst_type_find_element_chain);
+  gst_pad_set_event_function (typefind->sink,
+      gst_type_find_element_handle_event);
   gst_element_add_pad (GST_ELEMENT (typefind), typefind->sink);
   /* srcpad */
   typefind->src =
       gst_pad_new_from_template (gst_static_pad_template_get
       (&type_find_element_src_template), "src");
+  gst_pad_set_activate_function (typefind->src, gst_type_find_element_activate);
+  gst_pad_set_checkgetrange_function (typefind->src,
+      gst_type_find_element_checkgetrange);
+  gst_pad_set_getrange_function (typefind->src, gst_type_find_element_getrange);
   gst_pad_set_event_function (typefind->src, gst_type_find_element_src_event);
   gst_pad_set_event_mask_function (typefind->src,
       gst_type_find_element_src_event_mask);
   gst_pad_set_query_function (typefind->src,
       GST_DEBUG_FUNCPTR (gst_type_find_handle_src_query));
-  gst_pad_use_explicit_caps (typefind->src);
+  gst_pad_use_fixed_caps (typefind->src);
   gst_element_add_pad (GST_ELEMENT (typefind), typefind->src);
 
   typefind->caps = NULL;
@@ -201,8 +230,6 @@ gst_type_find_element_init (GstTypeFindElement * typefind)
   typefind->max_probability = GST_TYPE_FIND_MAXIMUM;
 
   typefind->store = gst_buffer_store_new ();
-
-  GST_FLAG_SET (typefind, GST_ELEMENT_EVENT_AWARE);
 }
 static void
 gst_type_find_element_dispose (GObject * object)
@@ -359,7 +386,7 @@ start_typefinding (GstTypeFindElement * typefind)
   g_assert (typefind->possibilities == NULL);
 
   GST_DEBUG_OBJECT (typefind, "starting typefinding");
-  gst_pad_unnegotiate (typefind->src);
+  gst_pad_set_caps (typefind->src, NULL);
   if (typefind->caps) {
     gst_caps_replace (&typefind->caps, NULL);
   }
@@ -370,9 +397,14 @@ start_typefinding (GstTypeFindElement * typefind)
 static void
 stop_typefinding (GstTypeFindElement * typefind)
 {
+  GstElementState state;
+
   /* stop all typefinding and set mode back to normal */
-  gboolean push_cached_buffers =
-      gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING;
+  gboolean push_cached_buffers;
+
+  gst_element_get_state (GST_ELEMENT (typefind), &state, NULL, NULL);
+
+  push_cached_buffers = (state >= GST_STATE_PAUSED);
 
   GST_DEBUG_OBJECT (typefind, "stopping typefinding%s",
       push_cached_buffers ? " and pushing cached buffers" : "");
@@ -384,47 +416,35 @@ stop_typefinding (GstTypeFindElement * typefind)
     g_list_free (typefind->possibilities);
     typefind->possibilities = NULL;
   }
-
-  typefind->mode = MODE_TRANSITION;
+  //typefind->mode = MODE_TRANSITION;
 
   if (!push_cached_buffers) {
     gst_buffer_store_clear (typefind->store);
   } else {
-    guint size = gst_buffer_store_get_size (typefind->store, 0);
-
-    GST_DEBUG_OBJECT (typefind, "seeking back to current position %u", size);
-    if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink),
-            gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES,
-                size))) {
-      GST_WARNING_OBJECT (typefind,
-          "could not seek to required position %u, hope for the best", size);
-      typefind->mode = MODE_NORMAL;
-      /* push out our queued buffers here */
-      push_buffer_store (typefind);
-    } else {
-      typefind->waiting_for_discont_offset = size;
-    }
+    typefind->mode = MODE_NORMAL;
+    /* push out our queued buffers here */
+    push_buffer_store (typefind);
   }
 }
 
-static void
+static GstFlowReturn
 push_buffer_store (GstTypeFindElement * typefind)
 {
   guint size = gst_buffer_store_get_size (typefind->store, 0);
   GstBuffer *buffer;
+  GstFlowReturn ret;
 
-  gst_pad_push (typefind->src, GST_DATA (gst_event_new_discontinuous (TRUE,
-              GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0,
-              GST_FORMAT_UNDEFINED)));
   if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) {
     GST_DEBUG_OBJECT (typefind, "pushing cached data (%u bytes)", size);
-    gst_pad_push (typefind->src, GST_DATA (buffer));
+    ret = gst_pad_push (typefind->src, buffer);
   } else {
-    /* FIXME: shouldn't we throw an error here? */
     size = 0;
+    ret = GST_FLOW_ERROR;
   }
 
   gst_buffer_store_clear (typefind->store);
+
+  return ret;
 }
 
 static guint64
@@ -460,9 +480,11 @@ find_element_get_length (gpointer data)
 
   return entry->self->stream_length;
 }
-static void
+
+static gboolean
 gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
 {
+  gboolean res = FALSE;
   TypeFindEntry *entry;
   GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad));
 
@@ -485,9 +507,9 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
                 0, entry->probability, entry->caps);
             stop_typefinding (typefind);
             push_buffer_store (typefind);
-            gst_pad_event_default (pad, event);
+            res = gst_pad_event_default (pad, event);
           } else {
-            gst_pad_event_default (pad, event);
+            res = gst_pad_event_default (pad, event);
             GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL),
                 (NULL));
             stop_typefinding (typefind);
@@ -495,44 +517,23 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
           break;
         default:
           gst_data_unref (GST_DATA (event));
+          res = TRUE;
           break;
       }
       break;
-    case MODE_TRANSITION:
-      if (GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS) {
-        if (GST_EVENT_DISCONT_NEW_MEDIA (event)) {
-          start_typefinding (typefind);
-          gst_event_unref (event);
-        } else {
-          guint64 off;
-
-          if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &off) &&
-              off == typefind->waiting_for_discont_offset) {
-            typefind->mode = MODE_NORMAL;
-            push_buffer_store (typefind);
-          } else {
-            gst_event_unref (event);
-          }
-        }
-      } else if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
-        push_buffer_store (typefind);
-        gst_pad_event_default (pad, event);
-      } else {
-        gst_event_unref (event);
-      }
-      break;
     case MODE_NORMAL:
-      if (GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS &&
-          GST_EVENT_DISCONT_NEW_MEDIA (event)) {
+      if (GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS) {
         start_typefinding (typefind);
         gst_event_unref (event);
+        res = TRUE;
       } else {
-        gst_pad_event_default (pad, event);
+        res = gst_pad_event_default (pad, event);
       }
       break;
     default:
       g_assert_not_reached ();
   }
+  return res;
 }
 static guint8 *
 find_peek (gpointer data, gint64 offset, guint size)
@@ -583,6 +584,7 @@ find_suggest (gpointer data, guint probability, const GstCaps * caps)
     gst_caps_replace (&entry->caps, gst_caps_copy (caps));
   }
 }
+
 static gint
 compare_type_find_entry (gconstpointer a, gconstpointer b)
 {
@@ -596,40 +598,37 @@ compare_type_find_entry (gconstpointer a, gconstpointer b)
     return two->probability - one->probability;
   }
 }
+
 static gint
 compare_type_find_factory (gconstpointer fac1, gconstpointer fac2)
 {
   return GST_PLUGIN_FEATURE (fac1)->rank - GST_PLUGIN_FEATURE (fac2)->rank;
 }
-static void
-gst_type_find_element_chain (GstPad * pad, GstData * data)
+
+static GstFlowReturn
+gst_type_find_element_chain (GstPad * pad, GstBuffer * buffer)
 {
   GstTypeFindElement *typefind;
   GList *entries;
   TypeFindEntry *entry;
   GList *walk;
+  GstFlowReturn res = GST_FLOW_OK;
   GstTypeFind find = { find_peek, find_suggest, NULL, find_element_get_length };
 
   typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad));
-  if (GST_IS_EVENT (data)) {
-    gst_type_find_element_handle_event (pad, GST_EVENT (data));
-    return;
-  }
+
   switch (typefind->mode) {
     case MODE_NORMAL:
-      gst_pad_push (typefind->src, data);
-      return;
-    case MODE_TRANSITION:
-      gst_data_unref (data);
-      return;
+      return gst_pad_push (typefind->src, buffer);
     case MODE_TYPEFIND:{
       guint64 current_offset;
 
-      gst_buffer_store_add_buffer (typefind->store, GST_BUFFER (data));
-      current_offset = GST_BUFFER_OFFSET_IS_VALID (data) ?
-          GST_BUFFER_OFFSET (data) + GST_BUFFER_SIZE (data) :
+      gst_buffer_store_add_buffer (typefind->store, buffer);
+      current_offset = GST_BUFFER_OFFSET_IS_VALID (buffer) ?
+          GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer) :
           gst_buffer_store_get_size (typefind->store, 0);
-      gst_data_unref (data);
+      gst_buffer_unref (buffer);
+
       if (typefind->possibilities == NULL) {
         /* not yet started, get all typefinding functions into our "queue" */
         GList *all_factories = gst_type_find_factory_get_list ();
@@ -800,27 +799,108 @@ gst_type_find_element_chain (GstPad * pad, GstData * data)
     }
     default:
       g_assert_not_reached ();
-      return;
+      return GST_FLOW_ERROR;
   }
+
+  return res;
 }
+
+static gboolean
+gst_type_find_element_checkgetrange (GstPad * srcpad)
+{
+  GstTypeFindElement *typefind;
+
+  typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (srcpad));
+
+  return gst_pad_check_pull_range (typefind->sink);
+}
+
+static GstFlowReturn
+gst_type_find_element_getrange (GstPad * srcpad,
+    guint64 offset, guint length, GstBuffer ** buffer)
+{
+  GstTypeFindElement *typefind;
+
+  typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (srcpad));
+
+  return gst_pad_pull_range (typefind->sink, offset, length, buffer);
+}
+
+static gboolean
+do_typefind (GstTypeFindElement * typefind)
+{
+  GstCaps *caps;
+  GstPad *peer;
+
+  peer = gst_pad_get_peer (typefind->sink);
+  if (peer) {
+    gst_pad_peer_set_active (typefind->sink, GST_ACTIVATE_PULL);
+
+    caps = gst_type_find_helper (peer, 0);
+    gst_pad_set_caps (typefind->src, caps);
+
+    if (caps) {
+      g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE],
+          0, 100, caps);
+    }
+
+    gst_object_unref (GST_OBJECT (peer));
+  }
+
+  return TRUE;
+}
+
+static gboolean
+gst_type_find_element_activate (GstPad * pad, GstActivateMode mode)
+{
+  gboolean result;
+  GstTypeFindElement *typefind;
+
+  typefind = GST_TYPE_FIND_ELEMENT (GST_OBJECT_PARENT (pad));
+
+  switch (mode) {
+    case GST_ACTIVATE_PUSH:
+    case GST_ACTIVATE_PULL:
+      result = TRUE;
+      break;
+    default:
+      result = TRUE;
+      break;
+  }
+
+  return result;
+}
+
 static GstElementStateReturn
 gst_type_find_element_change_state (GstElement * element)
 {
+  GstElementState transition;
+  GstElementStateReturn ret;
   GstTypeFindElement *typefind;
 
   typefind = GST_TYPE_FIND_ELEMENT (element);
 
-  switch (GST_STATE_TRANSITION (element)) {
+  transition = GST_STATE_TRANSITION (element);
+  switch (transition) {
     case GST_STATE_READY_TO_PAUSED:
-      start_typefinding (typefind);
+      do_typefind (typefind);
+
+      //start_typefinding (typefind);
       break;
+    default:
+      break;
+  }
+
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  switch (transition) {
     case GST_STATE_PAUSED_TO_READY:
-      stop_typefinding (typefind);
+      //stop_typefinding (typefind);
       gst_caps_replace (&typefind->caps, NULL);
       break;
     default:
       break;
   }
 
-  return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+  return ret;
 }
index 43debd5..03eeccd 100644 (file)
@@ -53,7 +53,6 @@ struct _GstTypeFindElement {
   GstCaps *            caps;
 
   guint                        mode;
-  guint64              waiting_for_discont_offset;
   GstBufferStore *     store;
   guint64              stream_length;
   gboolean             stream_length_available;