ext/gnomevfs/: Port gnomevfssink; add gtk-doc blurb.
authorTim-Philipp Müller <tim@centricular.net>
Tue, 27 Dec 2005 21:42:23 +0000 (21:42 +0000)
committerTim-Philipp Müller <tim@centricular.net>
Tue, 27 Dec 2005 21:42:23 +0000 (21:42 +0000)
Original commit message from CVS:
* ext/gnomevfs/Makefile.am:
* ext/gnomevfs/gstgnomevfs.c: (gst_gnome_vfs_uri_get_type),
(gst_gnome_vfs_handle_copy), (gst_gnome_vfs_handle_free),
(gst_gnome_vfs_handle_get_type), (plugin_init):
* ext/gnomevfs/gstgnomevfs.h:
* ext/gnomevfs/gstgnomevfssink.c: (gst_gnome_vfs_sink_do_init),
(gst_gnome_vfs_sink_base_init), (gst_gnome_vfs_sink_class_init),
(gst_gnome_vfs_sink_finalize), (gst_gnome_vfs_sink_init),
(gst_gnome_vfs_sink_set_property),
(gst_gnome_vfs_sink_get_property), (gst_gnome_vfs_sink_open_file),
(gst_gnome_vfs_sink_close_file), (gst_gnome_vfs_sink_start),
(gst_gnome_vfs_sink_stop), (gst_gnome_vfs_sink_handle_event),
(gst_gnome_vfs_sink_query), (gst_gnome_vfs_sink_render),
(gst_gnome_vfs_sink_uri_get_type),
(gst_gnome_vfs_sink_uri_get_protocols),
(gst_gnome_vfs_sink_uri_get_uri), (gst_gnome_vfs_sink_uri_set_uri),
(gst_gnome_vfs_sink_uri_handler_init):
* ext/gnomevfs/gstgnomevfssink.h:
Port gnomevfssink; add gtk-doc blurb.
* ext/gnomevfs/gstgnomevfssrc.c: (gst_gnome_vfs_src_get_type),
(gst_gnome_vfs_src_base_init), (gst_gnome_vfs_src_class_init),
(gst_gnome_vfs_src_init), (gst_gnome_vfs_src_finalize),
(gst_gnome_vfs_src_uri_get_type),
(gst_gnome_vfs_src_uri_get_protocols),
(gst_gnome_vfs_src_uri_get_uri), (gst_gnome_vfs_src_uri_set_uri),
(gst_gnome_vfs_src_uri_handler_init),
(gst_gnome_vfs_src_set_property), (gst_gnome_vfs_src_get_property),
(gst_gnome_vfs_src_unicodify), (audiocast_thread_run),
(gst_gnome_vfs_src_send_additional_headers_callback),
(gst_gnome_vfs_src_received_headers_callback),
(gst_gnome_vfs_src_push_callbacks),
(gst_gnome_vfs_src_pop_callbacks),
(gst_gnome_vfs_src_get_icy_metadata), (gst_gnome_vfs_src_create),
(gst_gnome_vfs_src_is_seekable), (gst_gnome_vfs_src_get_size),
(gst_gnome_vfs_src_start), (gst_gnome_vfs_src_stop):
* ext/gnomevfs/gstgnomevfssrc.h:
s/gst_gnomevfssrc/gst_gnome_vfs_src/; move header stuff to header
file; add gtk-doc blurb with example pipelines.

ChangeLog
ext/gnomevfs/Makefile.am
ext/gnomevfs/gstgnomevfs.c
ext/gnomevfs/gstgnomevfs.h
ext/gnomevfs/gstgnomevfssink.c
ext/gnomevfs/gstgnomevfssink.h [new file with mode: 0644]
ext/gnomevfs/gstgnomevfssrc.c
ext/gnomevfs/gstgnomevfssrc.h [new file with mode: 0644]

index 2739cc8..acaff38 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2005-12-27  Tim-Philipp Müller  <tim at centricular dot net>
+
+       * ext/gnomevfs/Makefile.am:
+       * ext/gnomevfs/gstgnomevfs.c: (gst_gnome_vfs_uri_get_type),
+       (gst_gnome_vfs_handle_copy), (gst_gnome_vfs_handle_free),
+       (gst_gnome_vfs_handle_get_type), (plugin_init):
+       * ext/gnomevfs/gstgnomevfs.h:
+       * ext/gnomevfs/gstgnomevfssink.c: (gst_gnome_vfs_sink_do_init),
+       (gst_gnome_vfs_sink_base_init), (gst_gnome_vfs_sink_class_init),
+       (gst_gnome_vfs_sink_finalize), (gst_gnome_vfs_sink_init),
+       (gst_gnome_vfs_sink_set_property),
+       (gst_gnome_vfs_sink_get_property), (gst_gnome_vfs_sink_open_file),
+       (gst_gnome_vfs_sink_close_file), (gst_gnome_vfs_sink_start),
+       (gst_gnome_vfs_sink_stop), (gst_gnome_vfs_sink_handle_event),
+       (gst_gnome_vfs_sink_query), (gst_gnome_vfs_sink_render),
+       (gst_gnome_vfs_sink_uri_get_type),
+       (gst_gnome_vfs_sink_uri_get_protocols),
+       (gst_gnome_vfs_sink_uri_get_uri), (gst_gnome_vfs_sink_uri_set_uri),
+       (gst_gnome_vfs_sink_uri_handler_init):
+       * ext/gnomevfs/gstgnomevfssink.h:
+         Port gnomevfssink; add gtk-doc blurb.
+
+       * ext/gnomevfs/gstgnomevfssrc.c: (gst_gnome_vfs_src_get_type),
+       (gst_gnome_vfs_src_base_init), (gst_gnome_vfs_src_class_init),
+       (gst_gnome_vfs_src_init), (gst_gnome_vfs_src_finalize),
+       (gst_gnome_vfs_src_uri_get_type),
+       (gst_gnome_vfs_src_uri_get_protocols),
+       (gst_gnome_vfs_src_uri_get_uri), (gst_gnome_vfs_src_uri_set_uri),
+       (gst_gnome_vfs_src_uri_handler_init),
+       (gst_gnome_vfs_src_set_property), (gst_gnome_vfs_src_get_property),
+       (gst_gnome_vfs_src_unicodify), (audiocast_thread_run),
+       (gst_gnome_vfs_src_send_additional_headers_callback),
+       (gst_gnome_vfs_src_received_headers_callback),
+       (gst_gnome_vfs_src_push_callbacks),
+       (gst_gnome_vfs_src_pop_callbacks),
+       (gst_gnome_vfs_src_get_icy_metadata), (gst_gnome_vfs_src_create),
+       (gst_gnome_vfs_src_is_seekable), (gst_gnome_vfs_src_get_size),
+       (gst_gnome_vfs_src_start), (gst_gnome_vfs_src_stop):
+       * ext/gnomevfs/gstgnomevfssrc.h:
+         s/gst_gnomevfssrc/gst_gnome_vfs_src/; move header stuff to header
+         file; add gtk-doc blurb with example pipelines.
+
 === release 0.10.1 ===
 
 2005-12-23  Thomas Vander Stichele <thomas at apestaart dot org>
index 9c8b800..4466b97 100644 (file)
@@ -2,16 +2,16 @@ plugin_LTLIBRARIES = libgstgnomevfs.la
  
 libgstgnomevfs_la_SOURCES = \
        gstgnomevfs.c \
+       gstgnomevfssink.c \
        gstgnomevfssrc.c \
        gstgnomevfsuri.c
 
-EXTRA_DIST = \
-       gstgnomevfssink.c
-
 libgstgnomevfs_la_CFLAGS = $(GST_CFLAGS) $(GNOME_VFS_CFLAGS)
 libgstgnomevfs_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 libgstgnomevfs_la_LIBADD = $(GNOME_VFS_LIBS) $(GST_BASE_LIBS)
 
 noinst_HEADERS = \
        gstgnomevfs.h \
+       gstgnomevfssink.h \
+       gstgnomevfssrc.h \
        gstgnomevfsuri.h
index 43ef565..1e6fb64 100644 (file)
 #include "gst/gst-i18n-plugin.h"
 
 #include "gstgnomevfs.h"
+#include "gstgnomevfssrc.h"
+#include "gstgnomevfssink.h"
+
 #include <libgnomevfs/gnome-vfs.h>
 #include <gst/gst.h>
 
-GST_DEBUG_CATEGORY_EXTERN (gnomevfssrc_debug);
-static gboolean
-plugin_init (GstPlugin * plugin)
+GType
+gst_gnome_vfs_uri_get_type (void)
+{
+  static GType type;            /* 0 */
+
+  if (type == 0) {
+    type = g_boxed_type_register_static ("GnomeVFSURI",
+        (GBoxedCopyFunc) gnome_vfs_uri_ref,
+        (GBoxedFreeFunc) gnome_vfs_uri_unref);
+  }
+
+  return type;
+}
+
+static gpointer
+gst_gnome_vfs_handle_copy (gpointer handle)
+{
+  return handle;
+}
+
+static void
+gst_gnome_vfs_handle_free (gpointer handle)
 {
-  gnome_vfs_init ();
+  return;
+}
+
+GType
+gst_gnome_vfs_handle_get_type (void)
+{
+  static GType type;            /* 0 */
+
+  if (type == 0) {
+    /* hackish, but makes it show up nicely in gst-inspect */
+    type = g_boxed_type_register_static ("GnomeVFSHandle",
+        (GBoxedCopyFunc) gst_gnome_vfs_handle_copy,
+        (GBoxedFreeFunc) gst_gnome_vfs_handle_free);
+  }
 
-  GST_DEBUG_CATEGORY_INIT (gnomevfssrc_debug, "gnomevfssrc", 0,
-      "Gnome-VFS Source");
+  return type;
+}
 
+static gboolean
+plugin_init (GstPlugin * plugin)
+{
+  /* gnome vfs engine init */
+  if (!gnome_vfs_initialized ())
+    gnome_vfs_init ();
 
   if (!gst_element_register (plugin, "gnomevfssrc", GST_RANK_SECONDARY,
-          gst_gnomevfssrc_get_type ()))
+          gst_gnome_vfs_src_get_type ()))
     return FALSE;
-/*
+
   if (!gst_element_register (plugin, "gnomevfssink", GST_RANK_SECONDARY,
-      gst_gnomevfssink_get_type ()))
+          gst_gnome_vfs_sink_get_type ()))
     return FALSE;
-*/
 
 #ifdef ENABLE_NLS
   setlocale (LC_ALL, "");
index 350a911..8069a6f 100644 (file)
 #include <glib-object.h>
 
 G_BEGIN_DECLS
-  
 
-GType gst_gnomevfssink_get_type (void);
-GType gst_gnomevfssrc_get_type (void);
+#define GST_TYPE_GNOME_VFS_URI     (gst_gnome_vfs_uri_get_type ())
+#define GST_TYPE_GNOME_VFS_HANDLE  (gst_gnome_vfs_handle_get_type ())
 
+GType gst_gnome_vfs_uri_get_type (void);
+GType gst_gnome_vfs_handle_get_type (void);
 
 G_END_DECLS
 
index fb1a3e1..9114d65 100644 (file)
@@ -3,6 +3,7 @@
  *                    2000 Wim Taymans <wtay@chello.be>
  *                    2001 Bastien Nocera <hadess@hadess.net>
  *                    2003 Colin Walters <walters@verbum.org>
+ *                    2005 Tim-Philipp Müller <tim centricular net>
  *
  * gstgnomevfssink.c: 
  *
  * Boston, MA 02111-1307, USA.
  */
 
+/**
+ * SECTION:element-gnomevfssink
+ * @short_description: Write a stream to a GnomeVFS URI
+ * @see_also: #GstFileSink, #GstGnomeVFSSrc
+ *
+ * <refsect2>
+ * <para>
+ * This plugin writes incoming data to a local or remote location specified
+ * by an URI. This location can be specified using any protocol supported by
+ * the GnomeVFS library. Common protocols are 'file', 'ftp', or 'smb'.
+ * </para>
+ * <para>
+ * Example pipeline:
+ * <programlisting>
+ * gst-launch -v filesrc location=input.xyz ! gnomevfssink location=file:///home/joe/out.xyz
+ * </programlisting>
+ * The above pipeline will simply copy a local file. Instead of gnomevfssink,
+ * we could just as well have used the filesink element here.
+ * </para>
+ * <para>
+ * Another example pipeline:
+ * <programlisting>
+ * gst-launch -v filesrc location=foo.mp3 ! mad ! flacenc ! gnomevfssink location=smb://othercomputer/foo.flac
+ * </programlisting>
+ * The above pipeline will re-encode an mp3 file into FLAC format and store
+ * it on a remote host using the Samba protocol.
+ * </para>
+ * </refsect2>
+ *
+ */
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include "gst/gst-i18n-plugin.h"
+#include "gstgnomevfssink.h"
 
-#include "gstgnomevfs.h"
-#include "gstgnomevfsuri.h"
+#include "gst/gst-i18n-plugin.h"
 
 #include <gst/gst.h>
 #include <libgnomevfs/gnome-vfs.h>
 #include <string.h>
 #include <errno.h>
 
-
-#define GST_TYPE_GNOMEVFSSINK \
-  (gst_gnomevfssink_get_type())
-#define GST_GNOMEVFSSINK(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GNOMEVFSSINK,GstGnomeVFSSink))
-#define GST_GNOMEVFSSINK_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GNOMEVFSSINK,GstGnomeVFSSinkClass))
-#define GST_IS_GNOMEVFSSINK(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GNOMEVFSSINK))
-#define GST_IS_GNOMEVFSSINK_CLASS(obj) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GNOMEVFSSINK))
-
-typedef struct _GstGnomeVFSSink GstGnomeVFSSink;
-typedef struct _GstGnomeVFSSinkClass GstGnomeVFSSinkClass;
-
-typedef enum
-{
-  GST_GNOMEVFSSINK_OPEN = GST_ELEMENT_FLAG_LAST,
-
-  GST_GNOMEVFSSINK_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2
-}
-GstGnomeVFSSinkFlags;
-
-struct _GstGnomeVFSSink
-{
-  GstElement element;
-
-  /* uri */
-  GnomeVFSURI *uri;
-  gchar *uri_name;
-
-  /* handle */
-  GnomeVFSHandle *handle;
-
-  /* whether we opened the handle ourselves */
-  gboolean own_handle;
-};
-
-struct _GstGnomeVFSSinkClass
-{
-  GstElementClass parent_class;
-
-  /* signals */
-    gboolean (*erase_ask) (GstElement * element, GnomeVFSURI * uri);
-};
-
-/* GnomeVFSSink signals and args */
 enum
 {
-  /* FILL ME */
   SIGNAL_ERASE_ASK,
   LAST_SIGNAL
 };
@@ -99,73 +81,68 @@ enum
   ARG_HANDLE
 };
 
-static void gst_gnomevfssink_base_init (gpointer g_class);
-static void gst_gnomevfssink_class_init (GstGnomeVFSSinkClass * klass);
-static void gst_gnomevfssink_init (GstGnomeVFSSink * gnomevfssink);
-static void gst_gnomevfssink_finalize (GObject * obj);
+static void gst_gnome_vfs_sink_finalize (GObject * obj);
 
-static void gst_gnomevfssink_uri_handler_init (gpointer g_iface,
+static void gst_gnome_vfs_sink_uri_handler_init (gpointer g_iface,
     gpointer iface_data);
 
-static void gst_gnomevfssink_set_property (GObject * object, guint prop_id,
+static void gst_gnome_vfs_sink_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
-static void gst_gnomevfssink_get_property (GObject * object, guint prop_id,
+static void gst_gnome_vfs_sink_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static gboolean gst_gnomevfssink_open_file (GstGnomeVFSSink * sink);
-static void gst_gnomevfssink_close_file (GstGnomeVFSSink * sink);
+static gboolean gst_gnome_vfs_sink_open_file (GstGnomeVFSSink * sink);
+static void gst_gnome_vfs_sink_close_file (GstGnomeVFSSink * sink);
+static gboolean gst_gnome_vfs_sink_start (GstBaseSink * basesink);
+static gboolean gst_gnome_vfs_sink_stop (GstBaseSink * basesink);
+static GstFlowReturn gst_gnome_vfs_sink_render (GstBaseSink * basesink,
+    GstBuffer * buffer);
+static gboolean gst_gnome_vfs_sink_handle_event (GstBaseSink * basesink,
+    GstEvent * event);
+static gboolean gst_gnome_vfs_sink_query (GstPad * pad, GstQuery * query);
 
-static void gst_gnomevfssink_chain (GstPad * pad, GstData * _data);
+static guint gst_gnome_vfs_sink_signals[LAST_SIGNAL];   /* all 0 */
 
-static GstStateChangeReturn gst_gnomevfssink_change_state (GstElement *
-    element);
+static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink",
+    GST_PAD_SINK,
+    GST_PAD_ALWAYS,
+    GST_STATIC_CAPS_ANY);
 
-static GstElementClass *parent_class = NULL;
-static guint gst_gnomevfssink_signals[LAST_SIGNAL] = { 0 };
+GST_DEBUG_CATEGORY_STATIC (gst_gnome_vfs_sink_debug);
+#define GST_CAT_DEFAULT gst_gnome_vfs_sink_debug
 
-GType
-gst_gnomevfssink_get_type (void)
+static void
+gst_gnome_vfs_sink_do_init (GType type)
 {
-  static GType gnomevfssink_type = 0;
-
-  if (!gnomevfssink_type) {
-    static const GTypeInfo gnomevfssink_info = {
-      sizeof (GstGnomeVFSSinkClass),
-      gst_gnomevfssink_base_init,
-      NULL,
-      (GClassInitFunc) gst_gnomevfssink_class_init,
-      NULL,
-      NULL,
-      sizeof (GstGnomeVFSSink),
-      0,
-      (GInstanceInitFunc) gst_gnomevfssink_init,
-    };
-    static const GInterfaceInfo urihandler_info = {
-      gst_gnomevfssink_uri_handler_init,
-      NULL,
-      NULL
-    };
-
-    gnomevfssink_type =
-        g_type_register_static (GST_TYPE_ELEMENT, "GstGnomeVFSSink",
-        &gnomevfssink_info, 0);
-    g_type_add_interface_static (gnomevfssink_type, GST_TYPE_URI_HANDLER,
-        &urihandler_info);
-  }
-  return gnomevfssink_type;
+  static const GInterfaceInfo urihandler_info = {
+    gst_gnome_vfs_sink_uri_handler_init,
+    NULL,
+    NULL
+  };
+
+  g_type_add_interface_static (type, GST_TYPE_URI_HANDLER, &urihandler_info);
+
+  GST_DEBUG_CATEGORY_INIT (gst_gnome_vfs_sink_debug, "gnomevfssink", 0,
+      "Gnome VFS sink element");
 }
 
+GST_BOILERPLATE_FULL (GstGnomeVFSSink, gst_gnome_vfs_sink, GstBaseSink,
+    GST_TYPE_BASE_SINK, gst_gnome_vfs_sink_do_init);
+
 static void
-gst_gnomevfssink_base_init (gpointer g_class)
+gst_gnome_vfs_sink_base_init (gpointer g_class)
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-  static GstElementDetails gst_gnomevfssink_details =
+  static GstElementDetails gst_gnome_vfs_sink_details =
       GST_ELEMENT_DETAILS ("GnomeVFS Sink",
       "Sink/File",
-      "Write stream to a GnomeVFS URI",
+      "Write stream to a GnomeVFS URI",
       "Bastien Nocera <hadess@hadess.net>");
 
-  gst_element_class_set_details (element_class, &gst_gnomevfssink_details);
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&sinktemplate));
+
+  gst_element_class_set_details (element_class, &gst_gnome_vfs_sink_details);
 }
 
 static gboolean
@@ -183,48 +160,45 @@ _gst_boolean_allow_overwrite_accumulator (GSignalInvocationHint * ihint,
 }
 
 static void
-gst_gnomevfssink_class_init (GstGnomeVFSSinkClass * klass)
+gst_gnome_vfs_sink_class_init (GstGnomeVFSSinkClass * klass)
 {
+  GstBaseSinkClass *basesink_class;
   GObjectClass *gobject_class;
-  GstElementClass *gstelement_class;
 
   gobject_class = (GObjectClass *) klass;
-  gstelement_class = (GstElementClass *) klass;
-
-  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+  basesink_class = (GstBaseSinkClass *) klass;
 
+  gobject_class->set_property = gst_gnome_vfs_sink_set_property;
+  gobject_class->get_property = gst_gnome_vfs_sink_get_property;
+  gobject_class->finalize = gst_gnome_vfs_sink_finalize;
 
   gst_element_class_install_std_props (GST_ELEMENT_CLASS (klass),
       "location", ARG_LOCATION, G_PARAM_READWRITE, NULL);
   g_object_class_install_property (gobject_class, ARG_URI,
-      g_param_spec_pointer ("uri", "GnomeVFSURI", "URI for GnomeVFS",
-          G_PARAM_READWRITE));
+      g_param_spec_boxed ("uri", "GnomeVFSURI", "URI for GnomeVFS",
+          GST_TYPE_GNOME_VFS_URI, G_PARAM_READWRITE));
   g_object_class_install_property (gobject_class, ARG_HANDLE,
-      g_param_spec_pointer ("handle",
-          "GnomeVFSHandle", "Handle for GnomeVFS", G_PARAM_READWRITE));
+      g_param_spec_boxed ("handle",
+          "GnomeVFSHandle", "Handle for GnomeVFS",
+          GST_TYPE_GNOME_VFS_HANDLE, G_PARAM_READWRITE));
 
-  gst_gnomevfssink_signals[SIGNAL_ERASE_ASK] =
+  gst_gnome_vfs_sink_signals[SIGNAL_ERASE_ASK] =
       g_signal_new ("allow-overwrite", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_CLEANUP, G_STRUCT_OFFSET (GstGnomeVFSSinkClass, erase_ask),
       _gst_boolean_allow_overwrite_accumulator, NULL,
-      gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
+      gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, GST_TYPE_GNOME_VFS_URI);
 
-
-  gobject_class->set_property = gst_gnomevfssink_set_property;
-  gobject_class->get_property = gst_gnomevfssink_get_property;
-  gobject_class->finalize = gst_gnomevfssink_finalize;
-
-  gstelement_class->change_state = gst_gnomevfssink_change_state;
-
-  /* gnome vfs engine init */
-  if (gnome_vfs_initialized () == FALSE)
-    gnome_vfs_init ();
+  basesink_class->stop = GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_stop);
+  basesink_class->start = GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_start);
+  basesink_class->event = GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_handle_event);
+  basesink_class->render = GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_render);
+  basesink_class->get_times = NULL;
 }
 
 static void
-gst_gnomevfssink_finalize (GObject * obj)
+gst_gnome_vfs_sink_finalize (GObject * obj)
 {
-  GstGnomeVFSSink *sink = GST_GNOMEVFSSINK (obj);
+  GstGnomeVFSSink *sink = GST_GNOME_VFS_SINK (obj);
 
   if (sink->uri) {
     gnome_vfs_uri_unref (sink->uri);
@@ -240,168 +214,122 @@ gst_gnomevfssink_finalize (GObject * obj)
 }
 
 static void
-gst_gnomevfssink_init (GstGnomeVFSSink * gnomevfssink)
+gst_gnome_vfs_sink_init (GstGnomeVFSSink * sink, GstGnomeVFSSinkClass * klass)
 {
-  GstPad *pad;
+  gst_pad_set_query_function (GST_BASE_SINK_PAD (sink),
+      GST_DEBUG_FUNCPTR (gst_gnome_vfs_sink_query));
 
-  GST_OBJECT_FLAG_SET (gnomevfssink, GST_ELEMENT_EVENT_AWARE);
+  sink->uri = NULL;
+  sink->uri_name = NULL;
+  sink->handle = NULL;
+  sink->own_handle = FALSE;
+  sink->data_written = 0;
 
-  pad = gst_pad_new ("sink", GST_PAD_SINK);
-  gst_element_add_pad (GST_ELEMENT (gnomevfssink), pad);
-  gst_pad_set_chain_function (pad, gst_gnomevfssink_chain);
-
-  gnomevfssink->uri = NULL;
-  gnomevfssink->uri_name = NULL;
-  gnomevfssink->handle = NULL;
-  gnomevfssink->own_handle = FALSE;
-}
-
-static guint
-gst_gnomevfssink_uri_get_type (void)
-{
-  return GST_URI_SINK;
-}
-
-static gchar **
-gst_gnomevfssink_uri_get_protocols (void)
-{
-  static gchar **protocols = NULL;
-
-  if (!protocols)
-    protocols = gst_gnomevfs_get_supported_uris ();
-
-  return protocols;
-}
-
-static const gchar *
-gst_gnomevfssink_uri_get_uri (GstURIHandler * handler)
-{
-  GstGnomeVFSSink *sink = GST_GNOMEVFSSINK (handler);
-
-  return sink->uri_name;
-}
-
-static gboolean
-gst_gnomevfssink_uri_set_uri (GstURIHandler * handler, const gchar * uri)
-{
-  GstGnomeVFSSink *sink = GST_GNOMEVFSSINK (handler);
-
-  if (GST_STATE (sink) == GST_STATE_PLAYING ||
-      GST_STATE (sink) == GST_STATE_PAUSED)
-    return FALSE;
-
-  g_object_set (G_OBJECT (sink), "location", uri, NULL);
-
-  return TRUE;
-}
-
-static void
-gst_gnomevfssink_uri_handler_init (gpointer g_iface, gpointer iface_data)
-{
-  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
-
-  iface->get_type = gst_gnomevfssink_uri_get_type;
-  iface->get_protocols = gst_gnomevfssink_uri_get_protocols;
-  iface->get_uri = gst_gnomevfssink_uri_get_uri;
-  iface->set_uri = gst_gnomevfssink_uri_set_uri;
+  GST_BASE_SINK (sink)->sync = FALSE;
 }
 
 static void
-gst_gnomevfssink_set_property (GObject * object, guint prop_id,
+gst_gnome_vfs_sink_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
   GstGnomeVFSSink *sink;
+  GstState cur_state;
 
-  sink = GST_GNOMEVFSSINK (object);
+  sink = GST_GNOME_VFS_SINK (object);
+
+  gst_element_get_state (GST_ELEMENT (sink), &cur_state, NULL, 0);
+
+  if (cur_state == GST_STATE_PLAYING || cur_state == GST_STATE_PAUSED) {
+    GST_WARNING_OBJECT (sink, "cannot set property when PAUSED or PLAYING");
+    return;
+  }
+
+  GST_OBJECT_LOCK (sink);
 
   switch (prop_id) {
-    case ARG_LOCATION:
-      if (GST_STATE (sink) == GST_STATE_NULL ||
-          GST_STATE (sink) == GST_STATE_READY) {
-        if (sink->uri) {
-          gnome_vfs_uri_unref (sink->uri);
-          sink->uri = NULL;
-        }
-        if (sink->uri_name) {
-          g_free (sink->uri_name);
-          sink->uri_name = NULL;
-        }
-        if (g_value_get_string (value)) {
-          sink->uri_name = g_strdup (g_value_get_string (value));
-          sink->uri = gnome_vfs_uri_new (sink->uri_name);
-        }
+    case ARG_LOCATION:{
+      if (sink->uri) {
+        gnome_vfs_uri_unref (sink->uri);
+        sink->uri = NULL;
+      }
+      if (sink->uri_name) {
+        g_free (sink->uri_name);
+        sink->uri_name = NULL;
+      }
+      if (g_value_get_string (value)) {
+        sink->uri_name = g_value_dup_string (value);
+        sink->uri = gnome_vfs_uri_new (sink->uri_name);
       }
       break;
-    case ARG_URI:
-      if (GST_STATE (sink) == GST_STATE_NULL ||
-          GST_STATE (sink) == GST_STATE_READY) {
-        if (sink->uri) {
-          gnome_vfs_uri_unref (sink->uri);
-          sink->uri = NULL;
-        }
-        if (sink->uri_name) {
-          g_free (sink->uri_name);
-          sink->uri_name = NULL;
-        }
-        if (g_value_get_pointer (value)) {
-          sink->uri = gnome_vfs_uri_ref (g_value_get_pointer (value));
-          sink->uri_name = gnome_vfs_uri_to_string (sink->uri, 0);
-        }
+    }
+    case ARG_URI:{
+      if (sink->uri) {
+        gnome_vfs_uri_unref (sink->uri);
+        sink->uri = NULL;
+      }
+      if (sink->uri_name) {
+        g_free (sink->uri_name);
+        sink->uri_name = NULL;
+      }
+      if (g_value_get_boxed (value)) {
+        sink->uri = (GnomeVFSURI *) g_value_dup_boxed (value);
+        sink->uri_name = gnome_vfs_uri_to_string (sink->uri, 0);
       }
       break;
-    case ARG_HANDLE:
-      if (GST_STATE (sink) == GST_STATE_NULL ||
-          GST_STATE (sink) == GST_STATE_READY) {
-        if (sink->uri) {
-          gnome_vfs_uri_unref (sink->uri);
-          sink->uri = NULL;
-        }
-        if (sink->uri_name) {
-          g_free (sink->uri_name);
-          sink->uri_name = NULL;
-        }
-        sink->handle = g_value_get_pointer (value);
+    }
+    case ARG_HANDLE:{
+      if (sink->uri) {
+        gnome_vfs_uri_unref (sink->uri);
+        sink->uri = NULL;
+      }
+      if (sink->uri_name) {
+        g_free (sink->uri_name);
+        sink->uri_name = NULL;
       }
+      sink->handle = g_value_get_boxed (value);
       break;
+    }
     default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+
+  GST_OBJECT_UNLOCK (sink);
 }
 
 static void
-gst_gnomevfssink_get_property (GObject * object, guint prop_id, GValue * value,
-    GParamSpec * pspec)
+gst_gnome_vfs_sink_get_property (GObject * object, guint prop_id,
+    GValue * value, GParamSpec * pspec)
 {
   GstGnomeVFSSink *sink;
 
-  g_return_if_fail (GST_IS_GNOMEVFSSINK (object));
+  sink = GST_GNOME_VFS_SINK (object);
 
-  sink = GST_GNOMEVFSSINK (object);
+  GST_OBJECT_LOCK (sink);
 
   switch (prop_id) {
     case ARG_LOCATION:
       g_value_set_string (value, sink->uri_name);
       break;
     case ARG_URI:
-      g_value_set_pointer (value, sink->uri);
+      g_value_set_boxed (value, sink->uri);
       break;
     case ARG_HANDLE:
-      g_value_set_pointer (value, sink->handle);
+      g_value_set_boxed (value, sink->handle);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
+
+  GST_OBJECT_UNLOCK (sink);
 }
 
 static gboolean
-gst_gnomevfssink_open_file (GstGnomeVFSSink * sink)
+gst_gnome_vfs_sink_open_file (GstGnomeVFSSink * sink)
 {
   GnomeVFSResult result;
 
-  g_return_val_if_fail (!GST_OBJECT_FLAG_IS_SET (sink, GST_GNOMEVFSSINK_OPEN),
-      FALSE);
-
   if (sink->uri) {
     /* open the file */
     result = gnome_vfs_create_uri (&(sink->handle), sink->uri,
@@ -413,7 +341,7 @@ gst_gnomevfssink_open_file (GstGnomeVFSSink * sink)
       gboolean erase_anyway = FALSE;
 
       g_signal_emit (G_OBJECT (sink),
-          gst_gnomevfssink_signals[SIGNAL_ERASE_ASK], 0, sink->uri,
+          gst_gnome_vfs_sink_signals[SIGNAL_ERASE_ASK], 0, sink->uri,
           &erase_anyway);
       if (erase_anyway) {
         result = gnome_vfs_create_uri (&(sink->handle), sink->uri,
@@ -422,7 +350,9 @@ gst_gnomevfssink_open_file (GstGnomeVFSSink * sink)
             | GNOME_VFS_PERM_GROUP_READ);
       }
     }
-    GST_DEBUG ("open: %s", gnome_vfs_result_to_string (result));
+
+    GST_DEBUG_OBJECT (sink, "open: %s", gnome_vfs_result_to_string (result));
+
     if (result != GNOME_VFS_OK) {
       gchar *filename = gnome_vfs_uri_to_string (sink->uri,
           GNOME_VFS_URI_HIDE_PASSWORD);
@@ -442,18 +372,16 @@ gst_gnomevfssink_open_file (GstGnomeVFSSink * sink)
     sink->own_handle = FALSE;
   }
 
-  GST_OBJECT_FLAG_SET (sink, GST_GNOMEVFSSINK_OPEN);
+  sink->data_written = 0;
 
   return TRUE;
 }
 
 static void
-gst_gnomevfssink_close_file (GstGnomeVFSSink * sink)
+gst_gnome_vfs_sink_close_file (GstGnomeVFSSink * sink)
 {
   GnomeVFSResult result;
 
-  g_return_if_fail (GST_OBJECT_FLAG_IS_SET (sink, GST_GNOMEVFSSINK_OPEN));
-
   if (sink->own_handle) {
     /* close the file */
     result = gnome_vfs_close (sink->handle);
@@ -470,176 +398,212 @@ gst_gnomevfssink_close_file (GstGnomeVFSSink * sink)
     sink->own_handle = FALSE;
     sink->handle = NULL;
   }
-
-  GST_OBJECT_FLAG_UNSET (sink, GST_GNOMEVFSSINK_OPEN);
 }
 
-/**
- * gst_gnomevfssink_handle_event:
- * @sink: reference to GstGnomeVFSSink
- * @event: the event to dispatch
- *
- * Handles the event appropriately (seek, end-of-file, ...)
- *
- * Return value: whether to continue processing or not.
- */
-
 static gboolean
-gst_gnomevfssink_handle_event (GstGnomeVFSSink * sink, GstEvent * event)
+gst_gnome_vfs_sink_start (GstBaseSink * basesink)
 {
-  GstEventType type;
-  gboolean res = FALSE;
+  gboolean ret;
 
-  type = GST_EVENT_TYPE (event);
+  ret = gst_gnome_vfs_sink_open_file (GST_GNOME_VFS_SINK (basesink));
 
-  switch (type) {
-    case GST_EVENT_EOS:
-      gst_gnomevfssink_close_file (sink);
-      gst_element_set_eos (GST_ELEMENT (sink));
-      break;
+  return ret;
+}
 
-    case GST_EVENT_DISCONTINUOUS:{
-      GnomeVFSResult res;
-      gint64 offset;
+static gboolean
+gst_gnome_vfs_sink_stop (GstBaseSink * basesink)
+{
+  GST_DEBUG_OBJECT (basesink, "closing ...");
+  gst_gnome_vfs_sink_close_file (GST_GNOME_VFS_SINK (basesink));
+  return TRUE;
+}
 
-      if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &offset)) {
-        if ((res = gnome_vfs_seek (sink->handle, GNOME_VFS_SEEK_START,
-                    offset)) != GNOME_VFS_OK) {
-          GST_ERROR_OBJECT (sink, "Failed to seek to offset %"
-              G_GINT64_FORMAT ": %s", offset, gnome_vfs_result_to_string (res));
-        }
-      }
+static gboolean
+gst_gnome_vfs_sink_handle_event (GstBaseSink * basesink, GstEvent * event)
+{
+  GstGnomeVFSSink *sink;
 
-      res = TRUE;
-      break;
-    }
+  sink = GST_GNOME_VFS_SINK (basesink);
+
+  GST_DEBUG_OBJECT (sink, "processing %s event", GST_EVENT_TYPE_NAME (event));
 
-    case GST_EVENT_SEEK:{
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_NEWSEGMENT:{
       GnomeVFSResult res;
-      GnomeVFSSeekPosition method;
+      GstFormat format;
       gint64 offset;
 
-      if (GST_EVENT_SEEK_FORMAT (event) != GST_FORMAT_BYTES) {
-        GST_ERROR_OBJECT (sink, "Can only seek in bytes");
+      gst_event_parse_new_segment (event, NULL, NULL, &format, &offset,
+          NULL, NULL);
+
+      if (format != GST_FORMAT_BYTES) {
+        GST_WARNING_OBJECT (sink, "ignored NEWSEGMENT event in %s format",
+            gst_format_get_name (format));
         break;
       }
 
-      switch (GST_EVENT_SEEK_METHOD (event)) {
-        case GST_SEEK_METHOD_SET:
-          method = GNOME_VFS_SEEK_START;
-          break;
-        case GST_SEEK_METHOD_CUR:
-          method = GNOME_VFS_SEEK_CURRENT;
-          break;
-        case GST_SEEK_METHOD_END:
-          method = GNOME_VFS_SEEK_END;
-          break;
-        default:
-          GST_ERROR_OBJECT (sink, "Unknown seek method %d",
-              GST_EVENT_SEEK_METHOD (event));
-          goto end;
-          break;
-      }
-      offset = GST_EVENT_SEEK_OFFSET (event);
+      GST_LOG_OBJECT (sink, "seeking to offset %" G_GINT64_FORMAT, offset);
+      res = gnome_vfs_seek (sink->handle, GNOME_VFS_SEEK_START, offset);
 
-      if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) {
-        /* how does Gnome-VFS flush? */
-      }
-
-      if ((res = gnome_vfs_seek (sink->handle, method, offset)) != GNOME_VFS_OK) {
+      if (res != GNOME_VFS_OK) {
         GST_ERROR_OBJECT (sink, "Failed to seek to offset %"
-            G_GINT64_FORMAT " with method %d: %s", offset, method,
-            gnome_vfs_result_to_string (res));
+            G_GINT64_FORMAT ": %s", offset, gnome_vfs_result_to_string (res));
       }
 
-      res = TRUE;
       break;
     }
 
-    case GST_EVENT_FLUSH:
-      /* how does Gnome-VFS flush? */
+    case GST_EVENT_FLUSH_START:
+    case GST_EVENT_EOS:{
+      /* how does Gnome-VFS flush? Do we need to flush? */
       break;
-
+    }
     default:
-      GST_WARNING ("Unhandled event type %d", type);
-      gst_pad_event_default (gst_element_get_pad (GST_ELEMENT (sink), "sink"),
-          event);
-      event = NULL;
       break;
   }
 
-end:
-  if (event)
-    gst_event_unref (event);
+  return TRUE;
+}
+
+static gboolean
+gst_gnome_vfs_sink_query (GstPad * pad, GstQuery * query)
+{
+  GstGnomeVFSSink *sink;
+  GstFormat format;
+
+  sink = GST_GNOME_VFS_SINK (GST_PAD_PARENT (pad));
+
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_POSITION:
+      gst_query_parse_position (query, &format, NULL);
+      switch (format) {
+        case GST_FORMAT_DEFAULT:
+        case GST_FORMAT_BYTES:
+          gst_query_set_position (query, GST_FORMAT_BYTES, sink->data_written);
+          return TRUE;
+        default:
+          return FALSE;
+      }
+
+    case GST_QUERY_FORMATS:
+      gst_query_set_formats (query, 2, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES);
+      return TRUE;
 
-  return res;
+    default:
+      return gst_pad_query_default (pad, query);
+  }
 }
 
-/**
- * gst_gnomevfssink_chain:
- * @pad: the pad this gnomevfssink is connected to
- * @buf: the buffer that has to be absorbed
- *
- * take the buffer from the pad and write to file if it's open
- */
-static void
-gst_gnomevfssink_chain (GstPad * pad, GstData * _data)
+static GstFlowReturn
+gst_gnome_vfs_sink_render (GstBaseSink * basesink, GstBuffer * buf)
 {
-  GstBuffer *buf;
+  GnomeVFSFileSize written, cur_pos;
   GstGnomeVFSSink *sink;
   GnomeVFSResult result;
-  GnomeVFSFileSize bytes_written;
+  GstFlowReturn ret;
+  guint64 back_pending = 0;
 
-  g_return_if_fail (pad != NULL);
-  g_return_if_fail (GST_IS_PAD (pad));
+  sink = GST_GNOME_VFS_SINK (basesink);
 
-  sink = GST_GNOMEVFSSINK (gst_pad_get_parent (pad));
+  if (gnome_vfs_tell (sink->handle, &cur_pos) == GNOME_VFS_OK) {
+    if (cur_pos < sink->data_written)
+      back_pending = sink->data_written - cur_pos;
+  }
+
+  result = gnome_vfs_write (sink->handle, GST_BUFFER_DATA (buf),
+      GST_BUFFER_SIZE (buf), &written);
+
+  switch (result) {
+    case GNOME_VFS_OK:{
+      GST_DEBUG_OBJECT (sink, "wrote %" G_GINT64_FORMAT " bytes at %"
+          G_GINT64_FORMAT, (gint64) written, (gint64) cur_pos);
+
+      if (written < GST_BUFFER_SIZE (buf)) {
+        /* FIXME: what to do here? (tpm) */
+        g_warning ("%s: %d bytes should be written, only %"
+            G_GUINT64_FORMAT " bytes written", G_STRLOC,
+            GST_BUFFER_SIZE (buf), written);
+      }
 
-  if (GST_OBJECT_FLAG_IS_SET (sink, GST_GNOMEVFSSINK_OPEN)) {
-    if (GST_IS_EVENT (_data)) {
-      gst_gnomevfssink_handle_event (sink, GST_EVENT (_data));
-      return;
+      sink->data_written += GST_BUFFER_SIZE (buf) - back_pending;
+      ret = GST_FLOW_OK;
+      break;
+    }
+    case GNOME_VFS_ERROR_NO_SPACE:{
+      /* TODO: emit signal/send msg on out-of-diskspace and
+       * handle this gracefully (see open bug) (tpm) */
     }
+      /* fall-through */
+    default:{
+      gchar *filename = gnome_vfs_uri_to_string (sink->uri,
+          GNOME_VFS_URI_HIDE_PASSWORD);
+
+      GST_ELEMENT_ERROR (sink, RESOURCE, WRITE,
+          (_("Error while writing to file \"%s\"."), filename),
+          ("%s, bufsize=%u, written=%u", gnome_vfs_result_to_string (result),
+              GST_BUFFER_SIZE (buf), (guint) written));
 
-    buf = GST_BUFFER (_data);
-    g_return_if_fail (buf != NULL);
-    result =
-        gnome_vfs_write (sink->handle, GST_BUFFER_DATA (buf),
-        GST_BUFFER_SIZE (buf), &bytes_written);
-    GST_DEBUG ("write: %s, written_bytes: %" G_GUINT64_FORMAT,
-        gnome_vfs_result_to_string (result), bytes_written);
-    if (bytes_written < GST_BUFFER_SIZE (buf)) {
-      printf ("gnomevfssink : Warning : %d bytes should be written, only %"
-          G_GUINT64_FORMAT " bytes written\n", GST_BUFFER_SIZE (buf),
-          bytes_written);
+      g_free (filename);
+      ret = GST_FLOW_ERROR;
+      break;
     }
   }
-  gst_data_unref (_data);
+
+  return GST_FLOW_OK;
 }
 
-static GstStateChangeReturn
-gst_gnomevfssink_change_state (GstElement * element, GstStateChange transition)
+/*** GSTURIHANDLER INTERFACE *************************************************/
+
+static guint
+gst_gnome_vfs_sink_uri_get_type (void)
 {
-  g_return_val_if_fail (GST_IS_GNOMEVFSSINK (element),
-      GST_STATE_CHANGE_FAILURE);
-
-  switch (transition) {
-    case GST_STATE_CHANGE_READY_TO_PAUSED:
-      if (!GST_OBJECT_FLAG_IS_SET (element, GST_GNOMEVFSSINK_OPEN)) {
-        if (!gst_gnomevfssink_open_file (GST_GNOMEVFSSINK (element)))
-          return GST_STATE_CHANGE_FAILURE;
-      }
-      break;
-    case GST_STATE_CHANGE_PAUSED_TO_READY:
-      if (GST_OBJECT_FLAG_IS_SET (element, GST_GNOMEVFSSINK_OPEN))
-        gst_gnomevfssink_close_file (GST_GNOMEVFSSINK (element));
-      break;
-    default:
-      break;
+  return GST_URI_SINK;
+}
+
+static gchar **
+gst_gnome_vfs_sink_uri_get_protocols (void)
+{
+  static gchar **protocols = NULL;
+
+  if (!protocols)
+    protocols = gst_gnomevfs_get_supported_uris ();
+
+  return protocols;
+}
+
+static const gchar *
+gst_gnome_vfs_sink_uri_get_uri (GstURIHandler * handler)
+{
+  GstGnomeVFSSink *sink = GST_GNOME_VFS_SINK (handler);
+
+  return sink->uri_name;
+}
+
+static gboolean
+gst_gnome_vfs_sink_uri_set_uri (GstURIHandler * handler, const gchar * uri)
+{
+  GstGnomeVFSSink *sink = GST_GNOME_VFS_SINK (handler);
+  GstState cur_state;
+
+  gst_element_get_state (GST_ELEMENT (sink), &cur_state, NULL, 0);
+
+  if (cur_state == GST_STATE_PLAYING || cur_state == GST_STATE_PAUSED) {
+    GST_WARNING_OBJECT (sink, "cannot set uri when PAUSED or PLAYING");
+    return FALSE;
   }
 
-  if (GST_ELEMENT_CLASS (parent_class)->change_state)
-    return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
+  g_object_set (sink, "location", uri, NULL);
+
+  return TRUE;
+}
+
+static void
+gst_gnome_vfs_sink_uri_handler_init (gpointer g_iface, gpointer iface_data)
+{
+  GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
 
-  return GST_STATE_CHANGE_SUCCESS;
+  iface->get_type = gst_gnome_vfs_sink_uri_get_type;
+  iface->get_protocols = gst_gnome_vfs_sink_uri_get_protocols;
+  iface->get_uri = gst_gnome_vfs_sink_uri_get_uri;
+  iface->set_uri = gst_gnome_vfs_sink_uri_set_uri;
 }
diff --git a/ext/gnomevfs/gstgnomevfssink.h b/ext/gnomevfs/gstgnomevfssink.h
new file mode 100644 (file)
index 0000000..b8ec518
--- /dev/null
@@ -0,0 +1,79 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *                    2001 Bastien Nocera <hadess@hadess.net>
+ *                    2003 Colin Walters <walters@verbum.org>
+ *                    2005 Tim-Philipp Müller <tim centricular net>
+ *
+ * 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_GNOME_VFS_SINK_H__
+#define __GST_GNOME_VFS_SINK_H__
+
+#include "gstgnomevfs.h"
+#include "gstgnomevfsuri.h"
+#include <gst/base/gstbasesink.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_GNOME_VFS_SINK \
+  (gst_gnome_vfs_sink_get_type())
+#define GST_GNOME_VFS_SINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GNOME_VFS_SINK,GstGnomeVFSSink))
+#define GST_GNOME_VFS_SINK_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GNOME_VFS_SINK,GstGnomeVFSSinkClass))
+#define GST_IS_GNOME_VFS_SINK(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GNOME_VFS_SINK))
+#define GST_IS_GNOME_VFS_SINK_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GNOME_VFS_SINK))
+
+typedef struct _GstGnomeVFSSink GstGnomeVFSSink;
+typedef struct _GstGnomeVFSSinkClass GstGnomeVFSSinkClass;
+
+struct _GstGnomeVFSSink
+{
+  GstBaseSink basesink;
+
+  /*< private >*/
+
+  /* uri */
+  GnomeVFSURI *uri;
+  gchar *uri_name;
+
+  /* handle */
+  GnomeVFSHandle *handle;
+
+  /* whether we opened the handle ourselves */
+  gboolean own_handle;
+
+  guint64  data_written;
+};
+
+struct _GstGnomeVFSSinkClass
+{
+  GstBaseSink basesink_class;
+
+  /* signals */
+  gboolean (*erase_ask) (GstElement * element, GnomeVFSURI * uri);
+};
+
+GType gst_gnome_vfs_sink_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_GNOME_VFS_SINK_H__ */
+
index 92914a1..20daa44 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
+/**
+ * SECTION:element-gnomevfssrc
+ * @short_description: Read from any GnomeVFS-supported location
+ * @see_also: #GstFileSrc, #GstGnomeVFSSink
+ *
+ * <refsect2>
+ * <para>
+ * This plugin reads data from a local or remote location specified
+ * by an URI. This location can be specified using any protocol supported by
+ * the GnomeVFS library. Common protocols are 'file', 'http', 'ftp', or 'smb'.
+ * </para>
+ * <para>
+ * Example pipeline:
+ * <programlisting>
+ * gst-launch -v gnomevfssrc location=file:///home/joe/foo.xyz ! fakesink
+ * </programlisting>
+ * The above pipeline will simply read a local file and do nothing with the
+ * data read. Instead of gnomevfssrc, we could just as well have used the
+ * filesrc element here.
+ * </para>
+ * <para>
+ * Another example pipeline:
+ * <programlisting>
+ * gst-launch -v gnomevfssrc location=smb://othercomputer/foo.xyz ! filesink location=/home/joe/foo.xyz
+ * </programlisting>
+ * The above pipeline will copy a file from a remote host to the local file
+ * system using the Samba protocol.
+ * </para>
+ * <para>
+ * Yet another example pipeline:
+ * <programlisting>
+ * gst-launch -v gnomevfssrc location=http://music.foobar.com/demo.mp3 ! mad ! audioconvert ! audioscale ! alsasink
+ * </programlisting>
+ * The above pipeline will read and decode and play an mp3 file from a
+ * web server using the http protocol.
+ * </para>
+ * </refsect2>
+ *
+ */
+
+
 #define BROKEN_SIG 1
 /*#undef BROKEN_SIG */
 
@@ -32,8 +73,7 @@
 
 #include "gst/gst-i18n-plugin.h"
 
-#include "gstgnomevfs.h"
-#include "gstgnomevfsuri.h"
+#include "gstgnomevfssrc.h"
 
 #include <stdlib.h>
 #include <sys/types.h>
 #include <string.h>
 
 #include <gst/gst.h>
-#include <gst/base/gstbasesrc.h>
-#include <libgnomevfs/gnome-vfs.h>
 /* gnome-vfs.h doesn't include the following header, which we need: */
 #include <libgnomevfs/gnome-vfs-standard-callbacks.h>
 
-GST_DEBUG_CATEGORY (gnomevfssrc_debug);
+GST_DEBUG_CATEGORY_STATIC (gnomevfssrc_debug);
 #define GST_CAT_DEFAULT gnomevfssrc_debug
 
-#define GST_TYPE_GNOMEVFSSRC \
-  (gst_gnomevfssrc_get_type())
-#define GST_GNOMEVFSSRC(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GNOMEVFSSRC,GstGnomeVFSSrc))
-#define GST_GNOMEVFSSRC_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GNOMEVFSSRC,GstGnomeVFSSrcClass))
-#define GST_IS_GNOMEVFSSRC(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GNOMEVFSSRC))
-#define GST_IS_GNOMEVFSSRC_CLASS(obj) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GNOMEVFSSRC))
 
 static GStaticMutex count_lock = G_STATIC_MUTEX_INIT;
 static gint ref_count = 0;
 static gboolean vfs_owner = FALSE;
 
-typedef struct _GstGnomeVFSSrc
-{
-  GstBaseSrc element;
-
-  /* uri, file, ... */
-  GnomeVFSURI *uri;
-  gchar *uri_name;
-  GnomeVFSHandle *handle;
-  gboolean own_handle;
-  GnomeVFSFileSize size;        /* -1 = unknown */
-  GnomeVFSFileOffset curoffset; /* current offset in file */
-  gboolean seekable;
-
-  /* icecast/audiocast metadata extraction handling */
-  gboolean iradio_mode;
-  gboolean http_callbacks_pushed;
-
-  gint icy_metaint;
-  GnomeVFSFileSize icy_count;
-
-  gchar *iradio_name;
-  gchar *iradio_genre;
-  gchar *iradio_url;
-  gchar *iradio_title;
-
-  GThread *audiocast_thread;
-  GList *audiocast_notify_queue;
-  GMutex *audiocast_queue_mutex;
-  GMutex *audiocast_udpdata_mutex;
-  gint audiocast_thread_die_infd;
-  gint audiocast_thread_die_outfd;
-  gint audiocast_port;
-  gint audiocast_fd;
-} GstGnomeVFSSrc;
-
-typedef struct _GstGnomeVFSSrcClass
-{
-  GstBaseSrcClass parent_class;
-} GstGnomeVFSSrcClass;
 
 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_SRC,
@@ -130,23 +119,23 @@ enum
   ARG_IRADIO_TITLE
 };
 
-static void gst_gnomevfssrc_base_init (gpointer g_class);
-static void gst_gnomevfssrc_class_init (GstGnomeVFSSrcClass * klass);
-static void gst_gnomevfssrc_init (GstGnomeVFSSrc * gnomevfssrc);
-static void gst_gnomevfssrc_finalize (GObject * object);
-static void gst_gnomevfssrc_uri_handler_init (gpointer g_iface,
+static void gst_gnome_vfs_src_base_init (gpointer g_class);
+static void gst_gnome_vfs_src_class_init (GstGnomeVFSSrcClass * klass);
+static void gst_gnome_vfs_src_init (GstGnomeVFSSrc * gnomevfssrc);
+static void gst_gnome_vfs_src_finalize (GObject * object);
+static void gst_gnome_vfs_src_uri_handler_init (gpointer g_iface,
     gpointer iface_data);
 
-static void gst_gnomevfssrc_set_property (GObject * object, guint prop_id,
+static void gst_gnome_vfs_src_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
-static void gst_gnomevfssrc_get_property (GObject * object, guint prop_id,
+static void gst_gnome_vfs_src_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static gboolean gst_gnomevfssrc_stop (GstBaseSrc * src);
-static gboolean gst_gnomevfssrc_start (GstBaseSrc * src);
-static gboolean gst_gnomevfssrc_is_seekable (GstBaseSrc * src);
-static gboolean gst_gnomevfssrc_get_size (GstBaseSrc * src, guint64 * size);
-static GstFlowReturn gst_gnomevfssrc_create (GstBaseSrc * basesrc,
+static gboolean gst_gnome_vfs_src_stop (GstBaseSrc * src);
+static gboolean gst_gnome_vfs_src_start (GstBaseSrc * src);
+static gboolean gst_gnome_vfs_src_is_seekable (GstBaseSrc * src);
+static gboolean gst_gnome_vfs_src_get_size (GstBaseSrc * src, guint64 * size);
+static GstFlowReturn gst_gnome_vfs_src_create (GstBaseSrc * basesrc,
     guint64 offset, guint size, GstBuffer ** buffer);
 
 static int audiocast_init (GstGnomeVFSSrc * src);
@@ -158,24 +147,24 @@ static void audiocast_thread_kill (GstGnomeVFSSrc * src);
 static GstElementClass *parent_class = NULL;
 
 GType
-gst_gnomevfssrc_get_type (void)
+gst_gnome_vfs_src_get_type (void)
 {
   static GType gnomevfssrc_type = 0;
 
   if (!gnomevfssrc_type) {
     static const GTypeInfo gnomevfssrc_info = {
       sizeof (GstGnomeVFSSrcClass),
-      gst_gnomevfssrc_base_init,
+      gst_gnome_vfs_src_base_init,
       NULL,
-      (GClassInitFunc) gst_gnomevfssrc_class_init,
+      (GClassInitFunc) gst_gnome_vfs_src_class_init,
       NULL,
       NULL,
       sizeof (GstGnomeVFSSrc),
       0,
-      (GInstanceInitFunc) gst_gnomevfssrc_init,
+      (GInstanceInitFunc) gst_gnome_vfs_src_init,
     };
     static const GInterfaceInfo urihandler_info = {
-      gst_gnomevfssrc_uri_handler_init,
+      gst_gnome_vfs_src_uri_handler_init,
       NULL,
       NULL
     };
@@ -190,10 +179,10 @@ gst_gnomevfssrc_get_type (void)
 }
 
 static void
-gst_gnomevfssrc_base_init (gpointer g_class)
+gst_gnome_vfs_src_base_init (gpointer g_class)
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-  static GstElementDetails gst_gnomevfssrc_details =
+  static GstElementDetails gst_gnome_vfs_src_details =
       GST_ELEMENT_DETAILS ("GnomeVFS Source",
       "Source/File",
       "Read from any GnomeVFS-supported file",
@@ -202,11 +191,14 @@ gst_gnomevfssrc_base_init (gpointer g_class)
 
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (&srctemplate));
-  gst_element_class_set_details (element_class, &gst_gnomevfssrc_details);
+  gst_element_class_set_details (element_class, &gst_gnome_vfs_src_details);
+
+  GST_DEBUG_CATEGORY_INIT (gnomevfssrc_debug, "gnomevfssrc", 0,
+      "Gnome-VFS Source");
 }
 
 static void
-gst_gnomevfssrc_class_init (GstGnomeVFSSrcClass * klass)
+gst_gnome_vfs_src_class_init (GstGnomeVFSSrcClass * klass)
 {
   GObjectClass *gobject_class;
   GstElementClass *gstelement_class;
@@ -216,19 +208,20 @@ gst_gnomevfssrc_class_init (GstGnomeVFSSrcClass * klass)
   gstelement_class = GST_ELEMENT_CLASS (klass);
   gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
 
-  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+  parent_class = g_type_class_peek_parent (klass);
 
-  gobject_class->finalize = gst_gnomevfssrc_finalize;
-  gobject_class->set_property = gst_gnomevfssrc_set_property;
-  gobject_class->get_property = gst_gnomevfssrc_get_property;
+  gobject_class->finalize = gst_gnome_vfs_src_finalize;
+  gobject_class->set_property = gst_gnome_vfs_src_set_property;
+  gobject_class->get_property = gst_gnome_vfs_src_get_property;
 
   /* properties */
   gst_element_class_install_std_props (GST_ELEMENT_CLASS (klass),
       "location", ARG_LOCATION, G_PARAM_READWRITE, NULL);
   g_object_class_install_property (gobject_class,
       ARG_HANDLE,
-      g_param_spec_pointer ("handle",
-          "GnomeVFSHandle", "Handle for GnomeVFS", G_PARAM_READWRITE));
+      g_param_spec_boxed ("handle",
+          "GnomeVFSHandle", "Handle for GnomeVFS",
+          GST_TYPE_GNOME_VFS_HANDLE, G_PARAM_READWRITE));
 
   /* icecast stuff */
   g_object_class_install_property (gobject_class,
@@ -256,16 +249,16 @@ gst_gnomevfssrc_class_init (GstGnomeVFSSrcClass * klass)
           "iradio-title",
           "Name of currently playing song", NULL, G_PARAM_READABLE));
 
-  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gnomevfssrc_start);
-  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_gnomevfssrc_stop);
-  gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_gnomevfssrc_get_size);
+  gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_start);
+  gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_stop);
+  gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_get_size);
   gstbasesrc_class->is_seekable =
-      GST_DEBUG_FUNCPTR (gst_gnomevfssrc_is_seekable);
-  gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_gnomevfssrc_create);
+      GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_is_seekable);
+  gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_create);
 }
 
 static void
-gst_gnomevfssrc_init (GstGnomeVFSSrc * gnomevfssrc)
+gst_gnome_vfs_src_init (GstGnomeVFSSrc * gnomevfssrc)
 {
   gnomevfssrc->uri = NULL;
   gnomevfssrc->uri_name = NULL;
@@ -300,9 +293,9 @@ gst_gnomevfssrc_init (GstGnomeVFSSrc * gnomevfssrc)
 }
 
 static void
-gst_gnomevfssrc_finalize (GObject * object)
+gst_gnome_vfs_src_finalize (GObject * object)
 {
-  GstGnomeVFSSrc *src = GST_GNOMEVFSSRC (object);
+  GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (object);
 
   g_static_mutex_lock (&count_lock);
   ref_count--;
@@ -334,13 +327,13 @@ gst_gnomevfssrc_finalize (GObject * object)
  */
 
 static guint
-gst_gnomevfssrc_uri_get_type (void)
+gst_gnome_vfs_src_uri_get_type (void)
 {
   return GST_URI_SRC;
 }
 
 static gchar **
-gst_gnomevfssrc_uri_get_protocols (void)
+gst_gnome_vfs_src_uri_get_protocols (void)
 {
   static gchar **protocols = NULL;
 
@@ -351,17 +344,17 @@ gst_gnomevfssrc_uri_get_protocols (void)
 }
 
 static const gchar *
-gst_gnomevfssrc_uri_get_uri (GstURIHandler * handler)
+gst_gnome_vfs_src_uri_get_uri (GstURIHandler * handler)
 {
-  GstGnomeVFSSrc *src = GST_GNOMEVFSSRC (handler);
+  GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (handler);
 
   return src->uri_name;
 }
 
 static gboolean
-gst_gnomevfssrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
+gst_gnome_vfs_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
 {
-  GstGnomeVFSSrc *src = GST_GNOMEVFSSRC (handler);
+  GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (handler);
 
   if (GST_STATE (src) == GST_STATE_PLAYING ||
       GST_STATE (src) == GST_STATE_PAUSED)
@@ -373,24 +366,24 @@ gst_gnomevfssrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
 }
 
 static void
-gst_gnomevfssrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
+gst_gnome_vfs_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
 {
   GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
 
-  iface->get_type = gst_gnomevfssrc_uri_get_type;
-  iface->get_protocols = gst_gnomevfssrc_uri_get_protocols;
-  iface->get_uri = gst_gnomevfssrc_uri_get_uri;
-  iface->set_uri = gst_gnomevfssrc_uri_set_uri;
+  iface->get_type = gst_gnome_vfs_src_uri_get_type;
+  iface->get_protocols = gst_gnome_vfs_src_uri_get_protocols;
+  iface->get_uri = gst_gnome_vfs_src_uri_get_uri;
+  iface->set_uri = gst_gnome_vfs_src_uri_set_uri;
 }
 
 static void
-gst_gnomevfssrc_set_property (GObject * object, guint prop_id,
+gst_gnome_vfs_src_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
   GstGnomeVFSSrc *src;
   gchar cwd[PATH_MAX];
 
-  src = GST_GNOMEVFSSRC (object);
+  src = GST_GNOME_VFS_SRC (object);
 
   switch (prop_id) {
     case ARG_LOCATION:
@@ -438,7 +431,7 @@ gst_gnomevfssrc_set_property (GObject * object, guint prop_id,
           g_free (src->uri_name);
           src->uri_name = NULL;
         }
-        src->handle = g_value_get_pointer (value);
+        src->handle = g_value_get_boxed (value);
       }
       break;
     case ARG_IRADIO_MODE:
@@ -451,19 +444,19 @@ gst_gnomevfssrc_set_property (GObject * object, guint prop_id,
 }
 
 static void
-gst_gnomevfssrc_get_property (GObject * object, guint prop_id, GValue * value,
+gst_gnome_vfs_src_get_property (GObject * object, guint prop_id, GValue * value,
     GParamSpec * pspec)
 {
   GstGnomeVFSSrc *src;
 
-  src = GST_GNOMEVFSSRC (object);
+  src = GST_GNOME_VFS_SRC (object);
 
   switch (prop_id) {
     case ARG_LOCATION:
       g_value_set_string (value, src->uri_name);
       break;
     case ARG_HANDLE:
-      g_value_set_pointer (value, src->handle);
+      g_value_set_boxed (value, src->handle);
       break;
     case ARG_IRADIO_MODE:
       g_value_set_boolean (value, src->iradio_mode);
@@ -515,7 +508,7 @@ unicodify (const char *str, int len, ...)
 }
 
 static char *
-gst_gnomevfssrc_unicodify (const char *str)
+gst_gnome_vfs_src_unicodify (const char *str)
 {
   return unicodify (str, -1, "locale", "ISO-8859-1", NULL);
 }
@@ -674,7 +667,7 @@ audiocast_thread_run (GstGnomeVFSSrc * src)
         if (!strlen (valptr))
           continue;
 
-        value = gst_gnomevfssrc_unicodify (valptr);
+        value = gst_gnome_vfs_src_unicodify (valptr);
         if (!value) {
           g_print ("Unable to convert \"%s\" to UTF-8!\n", valptr);
           continue;
@@ -745,10 +738,10 @@ audiocast_thread_kill (GstGnomeVFSSrc * src)
 }
 
 static void
-gst_gnomevfssrc_send_additional_headers_callback (gconstpointer in,
+gst_gnome_vfs_src_send_additional_headers_callback (gconstpointer in,
     gsize in_size, gpointer out, gsize out_size, gpointer callback_data)
 {
-  GstGnomeVFSSrc *src = GST_GNOMEVFSSRC (callback_data);
+  GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (callback_data);
   GnomeVFSModuleCallbackAdditionalHeadersOut *out_args =
       (GnomeVFSModuleCallbackAdditionalHeadersOut *) out;
 
@@ -763,12 +756,12 @@ gst_gnomevfssrc_send_additional_headers_callback (gconstpointer in,
 }
 
 static void
-gst_gnomevfssrc_received_headers_callback (gconstpointer in,
+gst_gnome_vfs_src_received_headers_callback (gconstpointer in,
     gsize in_size, gpointer out, gsize out_size, gpointer callback_data)
 {
   GList *i;
   gint icy_metaint;
-  GstGnomeVFSSrc *src = GST_GNOMEVFSSRC (callback_data);
+  GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (callback_data);
   GnomeVFSModuleCallbackReceivedHeadersIn *in_args =
       (GnomeVFSModuleCallbackReceivedHeadersIn *) in;
 
@@ -810,17 +803,17 @@ gst_gnomevfssrc_received_headers_callback (gconstpointer in,
     GST_DEBUG_OBJECT (src, "key: %s", key);
     if (!strncmp (key, "name", 4)) {
       g_free (src->iradio_name);
-      src->iradio_name = gst_gnomevfssrc_unicodify (value);
+      src->iradio_name = gst_gnome_vfs_src_unicodify (value);
       if (src->iradio_name)
         g_object_notify (G_OBJECT (src), "iradio-name");
     } else if (!strncmp (key, "genre", 5)) {
       g_free (src->iradio_genre);
-      src->iradio_genre = gst_gnomevfssrc_unicodify (value);
+      src->iradio_genre = gst_gnome_vfs_src_unicodify (value);
       if (src->iradio_genre)
         g_object_notify (G_OBJECT (src), "iradio-genre");
     } else if (!strncmp (key, "url", 3)) {
       g_free (src->iradio_url);
-      src->iradio_url = gst_gnomevfssrc_unicodify (value);
+      src->iradio_url = gst_gnome_vfs_src_unicodify (value);
       if (src->iradio_url)
         g_object_notify (G_OBJECT (src), "iradio-url");
     }
@@ -828,7 +821,7 @@ gst_gnomevfssrc_received_headers_callback (gconstpointer in,
 }
 
 static void
-gst_gnomevfssrc_push_callbacks (GstGnomeVFSSrc * src)
+gst_gnome_vfs_src_push_callbacks (GstGnomeVFSSrc * src)
 {
   if (src->http_callbacks_pushed)
     return;
@@ -836,16 +829,16 @@ gst_gnomevfssrc_push_callbacks (GstGnomeVFSSrc * src)
   GST_DEBUG_OBJECT (src, "pushing callbacks");
   gnome_vfs_module_callback_push
       (GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS,
-      gst_gnomevfssrc_send_additional_headers_callback, src, NULL);
+      gst_gnome_vfs_src_send_additional_headers_callback, src, NULL);
   gnome_vfs_module_callback_push
       (GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS,
-      gst_gnomevfssrc_received_headers_callback, src, NULL);
+      gst_gnome_vfs_src_received_headers_callback, src, NULL);
 
   src->http_callbacks_pushed = TRUE;
 }
 
 static void
-gst_gnomevfssrc_pop_callbacks (GstGnomeVFSSrc * src)
+gst_gnome_vfs_src_pop_callbacks (GstGnomeVFSSrc * src)
 {
   if (!src->http_callbacks_pushed)
     return;
@@ -858,7 +851,7 @@ gst_gnomevfssrc_pop_callbacks (GstGnomeVFSSrc * src)
 }
 
 static void
-gst_gnomevfssrc_get_icy_metadata (GstGnomeVFSSrc * src)
+gst_gnome_vfs_src_get_icy_metadata (GstGnomeVFSSrc * src)
 {
   GnomeVFSFileSize length = 0;
   GnomeVFSResult res;
@@ -903,7 +896,7 @@ gst_gnomevfssrc_get_icy_metadata (GstGnomeVFSSrc * src)
   for (i = 0; tags[i]; i++) {
     if (!g_ascii_strncasecmp (tags[i], "StreamTitle=", 12)) {
       g_free (src->iradio_title);
-      src->iradio_title = gst_gnomevfssrc_unicodify (tags[i] + 13);
+      src->iradio_title = gst_gnome_vfs_src_unicodify (tags[i] + 13);
       if (src->iradio_title) {
         GST_DEBUG_OBJECT (src, "sending notification on icecast title");
         g_object_notify (G_OBJECT (src), "iradio-title");
@@ -914,7 +907,7 @@ gst_gnomevfssrc_get_icy_metadata (GstGnomeVFSSrc * src)
     }
     if (!g_ascii_strncasecmp (tags[i], "StreamUrl=", 10)) {
       g_free (src->iradio_url);
-      src->iradio_url = gst_gnomevfssrc_unicodify (tags[i] + 11);
+      src->iradio_url = gst_gnome_vfs_src_unicodify (tags[i] + 11);
       if (src->iradio_url) {
         GST_DEBUG_OBJECT (src, "sending notification on icecast url");
         g_object_notify (G_OBJECT (src), "iradio-url");
@@ -934,7 +927,7 @@ gst_gnomevfssrc_get_icy_metadata (GstGnomeVFSSrc * src)
  * and seeking and such.
  */
 static GstFlowReturn
-gst_gnomevfssrc_create (GstBaseSrc * basesrc, guint64 offset, guint size,
+gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
     GstBuffer ** buffer)
 {
   GnomeVFSResult res;
@@ -943,7 +936,7 @@ gst_gnomevfssrc_create (GstBaseSrc * basesrc, guint64 offset, guint size,
   guint8 *data;
   GstGnomeVFSSrc *src;
 
-  src = GST_GNOMEVFSSRC (basesrc);
+  src = GST_GNOME_VFS_SRC (basesrc);
 
   GST_DEBUG ("now at %llu, reading %lld, size %u", src->curoffset, offset,
       size);
@@ -988,7 +981,7 @@ gst_gnomevfssrc_create (GstBaseSrc * basesrc, guint64 offset, guint size,
     src->curoffset += readbytes;
 
     if (src->icy_count == src->icy_metaint) {
-      gst_gnomevfssrc_get_icy_metadata (src);
+      gst_gnome_vfs_src_get_icy_metadata (src);
       src->icy_count = 0;
     }
   } else {
@@ -1045,21 +1038,21 @@ eos:
 }
 
 static gboolean
-gst_gnomevfssrc_is_seekable (GstBaseSrc * basesrc)
+gst_gnome_vfs_src_is_seekable (GstBaseSrc * basesrc)
 {
   GstGnomeVFSSrc *src;
 
-  src = GST_GNOMEVFSSRC (basesrc);
+  src = GST_GNOME_VFS_SRC (basesrc);
 
   return src->seekable;
 }
 
 static gboolean
-gst_gnomevfssrc_get_size (GstBaseSrc * basesrc, guint64 * size)
+gst_gnome_vfs_src_get_size (GstBaseSrc * basesrc, guint64 * size)
 {
   GstGnomeVFSSrc *src;
 
-  src = GST_GNOMEVFSSRC (basesrc);
+  src = GST_GNOME_VFS_SRC (basesrc);
 
   GST_DEBUG_OBJECT (src, "size %" G_GUINT64_FORMAT, src->size);
 
@@ -1073,18 +1066,18 @@ gst_gnomevfssrc_get_size (GstBaseSrc * basesrc, guint64 * size)
 
 /* open the file, do stuff necessary to go to READY state */
 static gboolean
-gst_gnomevfssrc_start (GstBaseSrc * basesrc)
+gst_gnome_vfs_src_start (GstBaseSrc * basesrc)
 {
   GnomeVFSResult res;
   GnomeVFSFileInfo *info;
   GstGnomeVFSSrc *src;
 
-  src = GST_GNOMEVFSSRC (basesrc);
+  src = GST_GNOME_VFS_SRC (basesrc);
 
   if (!audiocast_init (src))
     return FALSE;
 
-  gst_gnomevfssrc_push_callbacks (src);
+  gst_gnome_vfs_src_push_callbacks (src);
 
   if (src->uri != NULL) {
     if ((res = gnome_vfs_open_uri (&src->handle, src->uri,
@@ -1092,7 +1085,7 @@ gst_gnomevfssrc_start (GstBaseSrc * basesrc)
       gchar *filename = gnome_vfs_uri_to_string (src->uri,
           GNOME_VFS_URI_HIDE_PASSWORD);
 
-      gst_gnomevfssrc_pop_callbacks (src);
+      gst_gnome_vfs_src_pop_callbacks (src);
       audiocast_thread_kill (src);
 
       if (res == GNOME_VFS_ERROR_NOT_FOUND) {
@@ -1143,13 +1136,13 @@ gst_gnomevfssrc_start (GstBaseSrc * basesrc)
 }
 
 static gboolean
-gst_gnomevfssrc_stop (GstBaseSrc * basesrc)
+gst_gnome_vfs_src_stop (GstBaseSrc * basesrc)
 {
   GstGnomeVFSSrc *src;
 
-  src = GST_GNOMEVFSSRC (basesrc);
+  src = GST_GNOME_VFS_SRC (basesrc);
 
-  gst_gnomevfssrc_pop_callbacks (src);
+  gst_gnome_vfs_src_pop_callbacks (src);
   audiocast_thread_kill (src);
 
   if (src->own_handle) {
diff --git a/ext/gnomevfs/gstgnomevfssrc.h b/ext/gnomevfs/gstgnomevfssrc.h
new file mode 100644 (file)
index 0000000..2a8853b
--- /dev/null
@@ -0,0 +1,94 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *                    2001 Bastien Nocera <hadess@hadess.net>
+ *                    2002 Kristian Rietveld <kris@gtk.org>
+ *                    2002,2003 Colin Walters <walters@gnu.org>
+ *
+ * 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_GNOME_VFS_SRC_H__
+#define __GST_GNOME_VFS_SRC_H__
+
+#include <gst/base/gstbasesrc.h>
+
+#include "gstgnomevfs.h"
+#include "gstgnomevfsuri.h"
+#include <libgnomevfs/gnome-vfs.h>
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_GNOME_VFS_SRC \
+  (gst_gnome_vfs_src_get_type())
+#define GST_GNOME_VFS_SRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_GNOME_VFS_SRC,GstGnomeVFSSrc))
+#define GST_GNOME_VFS_SRC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_GNOME_VFS_SRC,GstGnomeVFSSrcClass))
+#define GST_IS_GNOME_VFS_SRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_GNOME_VFS_SRC))
+#define GST_IS_GNOME_VFS_SRC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_GNOME_VFS_SRC))
+
+typedef struct _GstGnomeVFSSrc      GstGnomeVFSSrc;
+typedef struct _GstGnomeVFSSrcClass GstGnomeVFSSrcClass;
+
+struct _GstGnomeVFSSrc
+{
+  GstBaseSrc basesrc;
+
+  /* uri, file, ... */
+  GnomeVFSURI *uri;
+  gchar *uri_name;
+  GnomeVFSHandle *handle;
+  gboolean own_handle;
+  GnomeVFSFileSize size;        /* -1 = unknown */
+  GnomeVFSFileOffset curoffset; /* current offset in file */
+  gboolean seekable;
+
+  /* icecast/audiocast metadata extraction handling */
+  gboolean iradio_mode;
+  gboolean http_callbacks_pushed;
+
+  gint icy_metaint;
+  GnomeVFSFileSize icy_count;
+
+  gchar *iradio_name;
+  gchar *iradio_genre;
+  gchar *iradio_url;
+  gchar *iradio_title;
+
+  GThread *audiocast_thread;
+  GList *audiocast_notify_queue;
+  GMutex *audiocast_queue_mutex;
+  GMutex *audiocast_udpdata_mutex;
+  gint audiocast_thread_die_infd;
+  gint audiocast_thread_die_outfd;
+  gint audiocast_port;
+  gint audiocast_fd;
+};
+
+struct _GstGnomeVFSSrcClass
+{
+  GstBaseSrcClass  basesrc_class;
+};
+
+GType gst_gnome_vfs_src_get_type (void);
+
+G_END_DECLS
+
+#endif /* __GST_GNOME_VFS_SRC_H__ */
+