ext/gnomevfs/: Add URI support to Gnome-VFS plugins. Tries to load a fixed list of...
authorRonald S. Bultje <rbultje@ronald.bitfreak.net>
Mon, 13 Sep 2004 17:33:19 +0000 (17:33 +0000)
committerRonald S. Bultje <rbultje@ronald.bitfreak.net>
Mon, 13 Sep 2004 17:33:19 +0000 (17:33 +0000)
Original commit message from CVS:
* ext/gnomevfs/Makefile.am:
* ext/gnomevfs/gstgnomevfs.c: (plugin_init):
* ext/gnomevfs/gstgnomevfssink.c: (gst_gnomevfssink_get_type),
(gst_gnomevfssink_dispose), (gst_gnomevfssink_init),
(gst_gnomevfssink_uri_get_type),
(gst_gnomevfssink_uri_get_protocols),
(gst_gnomevfssink_uri_get_uri), (gst_gnomevfssink_uri_set_uri),
(gst_gnomevfssink_uri_handler_init),
(gst_gnomevfssink_set_property), (gst_gnomevfssink_get_property),
(gst_gnomevfssink_open_file), (gst_gnomevfssink_close_file):
* ext/gnomevfs/gstgnomevfssrc.c: (gst_gnomevfssrc_get_type),
(gst_gnomevfssrc_init), (gst_gnomevfssrc_dispose),
(gst_gnomevfssrc_uri_get_type),
(gst_gnomevfssrc_uri_get_protocols), (gst_gnomevfssrc_uri_get_uri),
(gst_gnomevfssrc_uri_set_uri), (gst_gnomevfssrc_uri_handler_init),
(gst_gnomevfssrc_set_property), (gst_gnomevfssrc_get_property),
(gst_gnomevfssrc_open_file), (gst_gnomevfssrc_close_file):
* ext/gnomevfs/gstgnomevfsuri.c: (gst_gnomevfs_get_supported_uris):
* ext/gnomevfs/gstgnomevfsuri.h:
Add URI support to Gnome-VFS plugins. Tries to load a fixed list
of fake URIs to see which this version of Gnome-VFS likes, and
uses that for the Gst-URI interface. Makes playbin support http://
streams. Also fix up some stupid behaviour in gnomevfssrc.

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

index b8fad1b..0215240 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,31 @@
 2004-09-13  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
 
+       * ext/gnomevfs/Makefile.am:
+       * ext/gnomevfs/gstgnomevfs.c: (plugin_init):
+       * ext/gnomevfs/gstgnomevfssink.c: (gst_gnomevfssink_get_type),
+       (gst_gnomevfssink_dispose), (gst_gnomevfssink_init),
+       (gst_gnomevfssink_uri_get_type),
+       (gst_gnomevfssink_uri_get_protocols),
+       (gst_gnomevfssink_uri_get_uri), (gst_gnomevfssink_uri_set_uri),
+       (gst_gnomevfssink_uri_handler_init),
+       (gst_gnomevfssink_set_property), (gst_gnomevfssink_get_property),
+       (gst_gnomevfssink_open_file), (gst_gnomevfssink_close_file):
+       * ext/gnomevfs/gstgnomevfssrc.c: (gst_gnomevfssrc_get_type),
+       (gst_gnomevfssrc_init), (gst_gnomevfssrc_dispose),
+       (gst_gnomevfssrc_uri_get_type),
+       (gst_gnomevfssrc_uri_get_protocols), (gst_gnomevfssrc_uri_get_uri),
+       (gst_gnomevfssrc_uri_set_uri), (gst_gnomevfssrc_uri_handler_init),
+       (gst_gnomevfssrc_set_property), (gst_gnomevfssrc_get_property),
+       (gst_gnomevfssrc_open_file), (gst_gnomevfssrc_close_file):
+       * ext/gnomevfs/gstgnomevfsuri.c: (gst_gnomevfs_get_supported_uris):
+       * ext/gnomevfs/gstgnomevfsuri.h:
+         Add URI support to Gnome-VFS plugins. Tries to load a fixed list
+         of fake URIs to see which this version of Gnome-VFS likes, and
+         uses that for the Gst-URI interface. Makes playbin support http://
+         streams. Also fix up some stupid behaviour in gnomevfssrc.
+
+2004-09-13  Ronald S. Bultje  <rbultje@ronald.bitfreak.net>
+
        * ext/alsa/gstalsamixer.c: (gst_alsa_mixer_update),
        (gst_alsa_mixer_get_volume), (gst_alsa_mixer_set_volume),
        (gst_alsa_mixer_set_mute), (gst_alsa_mixer_set_record),
index 6d4bf7d..16fa6e4 100644 (file)
@@ -1,10 +1,14 @@
 plugin_LTLIBRARIES = libgstgnomevfs.la
  
-libgstgnomevfs_la_SOURCES = gstgnomevfs.c gstgnomevfssrc.c gstgnomevfssink.c
+libgstgnomevfs_la_SOURCES = \
+       gstgnomevfs.c \
+       gstgnomevfssrc.c \
+       gstgnomevfssink.c \
+       gstgnomevfsuri.c
 libgstgnomevfs_la_CFLAGS = $(GST_CFLAGS) $(GNOME_VFS_CFLAGS)
 libgstgnomevfs_la_LIBADD = $(GNOME_VFS_LIBS)
 libgstgnomevfs_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
 
-noinst_HEADERS = gstgnomevfs.h
-
+noinst_HEADERS = \
+       gstgnomevfs.h \
+       gstgnomevfsuri.h
index f71afd1..37c78c6 100644 (file)
 #include "gst/gst-i18n-plugin.h"
 
 #include "gstgnomevfs.h"
+#include <libgnomevfs/gnome-vfs.h>
 #include <gst/gst.h>
 
 static gboolean
 plugin_init (GstPlugin * plugin)
 {
+  gnome_vfs_init ();
+
   if (!gst_element_register (plugin, "gnomevfssrc",
           GST_RANK_SECONDARY, gst_gnomevfssrc_get_type ()) ||
       !gst_element_register (plugin, "gnomevfssink",
index ce8f39a..e8d4070 100644 (file)
@@ -30,6 +30,7 @@
 #include "gst/gst-i18n-plugin.h"
 
 #include "gstgnomevfs.h"
+#include "gstgnomevfsuri.h"
 
 #include <gst/gst.h>
 #include <libgnomevfs/gnome-vfs.h>
@@ -65,6 +66,7 @@ struct _GstGnomeVFSSink
 
   /* uri */
   GnomeVFSURI *uri;
+  gchar *uri_name;
 
   /* handle */
   GnomeVFSHandle *handle;
@@ -102,6 +104,9 @@ static void gst_gnomevfssink_class_init (GstGnomeVFSSinkClass * klass);
 static void gst_gnomevfssink_init (GstGnomeVFSSink * gnomevfssink);
 static void gst_gnomevfssink_dispose (GObject * obj);
 
+static void gst_gnomevfssink_uri_handler_init (gpointer g_iface,
+    gpointer iface_data);
+
 static void gst_gnomevfssink_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
 static void gst_gnomevfssink_get_property (GObject * object, guint prop_id,
@@ -135,10 +140,17 @@ gst_gnomevfssink_get_type (void)
       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;
 }
@@ -218,6 +230,11 @@ gst_gnomevfssink_dispose (GObject * obj)
     gnome_vfs_uri_unref (sink->uri);
     sink->uri = NULL;
   }
+
+  if (sink->uri_name) {
+    g_free (sink->uri_name);
+    sink->uri_name = NULL;
+  }
 }
 
 static void
@@ -230,10 +247,61 @@ gst_gnomevfssink_init (GstGnomeVFSSink * gnomevfssink)
   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 (GNOME_VFS_OPEN_WRITE);
+
+  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;
+}
+
 static void
 gst_gnomevfssink_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
@@ -245,26 +313,50 @@ gst_gnomevfssink_set_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case ARG_LOCATION:
-      if (sink->uri) {
-        gnome_vfs_uri_unref (sink->uri);
-        sink->uri = NULL;
-      }
-      if (g_value_get_string (value)) {
-        sink->uri = gnome_vfs_uri_new (g_value_get_string (value));
+      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);
+        }
       }
       break;
     case ARG_URI:
-      if (sink->uri) {
-        gnome_vfs_uri_unref (sink->uri);
-        sink->uri = NULL;
-      }
-      if (g_value_get_pointer (value)) {
-        sink->uri = gnome_vfs_uri_ref (g_value_get_pointer (value));
+      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);
+        }
       }
       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);
       }
       break;
@@ -286,15 +378,7 @@ gst_gnomevfssink_get_property (GObject * object, guint prop_id, GValue * value,
 
   switch (prop_id) {
     case ARG_LOCATION:
-      if (sink->uri) {
-        gchar *filename = gnome_vfs_uri_to_string (sink->uri,
-            GNOME_VFS_URI_HIDE_PASSWORD);
-
-        g_value_set_string (value, filename);
-        g_free (filename);
-      } else {
-        g_value_set_string (value, NULL);
-      }
+      g_value_set_string (value, sink->uri_name);
       break;
     case ARG_URI:
       g_value_set_pointer (value, sink->uri);
@@ -351,6 +435,8 @@ gst_gnomevfssink_open_file (GstGnomeVFSSink * sink)
     GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (_("No filename given")),
         (NULL));
     return FALSE;
+  } else {
+    sink->own_handle = FALSE;
   }
 
   GST_FLAG_SET (sink, GST_GNOMEVFSSINK_OPEN);
@@ -379,6 +465,7 @@ gst_gnomevfssink_close_file (GstGnomeVFSSink * sink)
     }
 
     sink->own_handle = FALSE;
+    sink->handle = NULL;
   }
 
   GST_FLAG_UNSET (sink, GST_GNOMEVFSSINK_OPEN);
index 2085254..ba700bf 100644 (file)
@@ -33,6 +33,7 @@
 #include "gst/gst-i18n-plugin.h"
 
 #include "gstgnomevfs.h"
+#include "gstgnomevfsuri.h"
 
 #include <stdlib.h>
 #include <sys/types.h>
@@ -83,16 +84,18 @@ typedef struct _GstGnomeVFSSrcClass GstGnomeVFSSrcClass;
 struct _GstGnomeVFSSrc
 {
   GstElement element;
+
   /* pads */
   GstPad *srcpad;
 
-  /* filename */
-  gchar *filename;
   /* uri */
   GnomeVFSURI *uri;
+  gchar *uri_name;
 
   /* handle */
   GnomeVFSHandle *handle;
+  gboolean own_handle;
+
   /* Seek stuff */
   gboolean need_flush;
 
@@ -199,6 +202,9 @@ static void gst_gnomevfssrc_class_init (GstGnomeVFSSrcClass * klass);
 static void gst_gnomevfssrc_init (GstGnomeVFSSrc * gnomevfssrc);
 static void gst_gnomevfssrc_dispose (GObject * object);
 
+static void gst_gnomevfssrc_uri_handler_init (gpointer g_iface,
+    gpointer iface_data);
+
 static void gst_gnomevfssrc_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
 static void gst_gnomevfssrc_get_property (GObject * object, guint prop_id,
@@ -240,10 +246,17 @@ gst_gnomevfssrc_get_type (void)
       0,
       (GInstanceInitFunc) gst_gnomevfssrc_init,
     };
+    static const GInterfaceInfo urihandler_info = {
+      gst_gnomevfssrc_uri_handler_init,
+      NULL,
+      NULL
+    };
 
     gnomevfssrc_type =
         g_type_register_static (GST_TYPE_ELEMENT,
         "GstGnomeVFSSrc", &gnomevfssrc_info, 0);
+    g_type_add_interface_static (gnomevfssrc_type, GST_TYPE_URI_HANDLER,
+        &urihandler_info);
   }
   return gnomevfssrc_type;
 }
@@ -332,6 +345,7 @@ gst_gnomevfssrc_init (GstGnomeVFSSrc * gnomevfssrc)
   gst_element_add_pad (GST_ELEMENT (gnomevfssrc), gnomevfssrc->srcpad);
 
   gnomevfssrc->uri = NULL;
+  gnomevfssrc->uri_name = NULL;
   gnomevfssrc->handle = NULL;
   gnomevfssrc->curoffset = 0;
   gnomevfssrc->bytes_per_read = 4096;
@@ -380,21 +394,77 @@ gst_gnomevfssrc_dispose (GObject * object)
   }
   g_static_mutex_unlock (&count_lock);
 
-  g_free (src->filename);
-  src->filename = NULL;
+  if (src->uri) {
+    gnome_vfs_uri_unref (src->uri);
+    src->uri = NULL;
+  }
+
+  if (src->uri_name) {
+    g_free (src->uri_name);
+    src->uri_name = NULL;
+  }
+
   g_mutex_free (src->audiocast_udpdata_mutex);
   g_mutex_free (src->audiocast_queue_mutex);
 
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
+static guint
+gst_gnomevfssrc_uri_get_type (void)
+{
+  return GST_URI_SRC;
+}
+
+static gchar **
+gst_gnomevfssrc_uri_get_protocols (void)
+{
+  static gchar **protocols = NULL;
+
+  if (!protocols)
+    protocols = gst_gnomevfs_get_supported_uris (GNOME_VFS_OPEN_READ);
+
+  return protocols;
+}
+
+static const gchar *
+gst_gnomevfssrc_uri_get_uri (GstURIHandler * handler)
+{
+  GstGnomeVFSSrc *src = GST_GNOMEVFSSRC (handler);
+
+  return src->uri_name;
+}
+
+static gboolean
+gst_gnomevfssrc_uri_set_uri (GstURIHandler * handler, const gchar * uri)
+{
+  GstGnomeVFSSrc *src = GST_GNOMEVFSSRC (handler);
+
+  if (GST_STATE (src) == GST_STATE_PLAYING ||
+      GST_STATE (src) == GST_STATE_PAUSED)
+    return FALSE;
+
+  g_object_set (G_OBJECT (src), "location", uri, NULL);
+
+  return TRUE;
+}
+
+static void
+gst_gnomevfssrc_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;
+}
 
 static void
 gst_gnomevfssrc_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
 {
   GstGnomeVFSSrc *src;
-  const gchar *location;
   gchar cwd[PATH_MAX];
 
   /* it's not null if we got it, but it might not be ours */
@@ -405,42 +475,51 @@ gst_gnomevfssrc_set_property (GObject * object, guint prop_id,
   switch (prop_id) {
     case ARG_LOCATION:
       /* the element must be stopped or paused in order to do this */
-      if (GST_STATE (src) == GST_STATE_PLAYING)
+      if (GST_STATE (src) == GST_STATE_PLAYING ||
+          GST_STATE (src) == GST_STATE_PAUSED)
         break;
 
-      g_free (src->filename);
-
-      /* clear the filename if we get a NULL */
-      if (g_value_get_string (value) == NULL) {
-        gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL);
-        src->filename = NULL;
-      } else {
-        /* otherwise set the new filename */
-        location = g_value_get_string (value);
-        /* if it's not a proper uri, default to file: -- this
-         * is a crude test */
+      if (src->uri) {
+        gnome_vfs_uri_unref (src->uri);
+        src->uri = NULL;
+      }
+      if (src->uri_name) {
+        g_free (src->uri_name);
+        src->uri_name = NULL;
+      }
+
+      if (g_value_get_string (value)) {
+        const gchar *location = g_value_get_string (value);
+
         if (!strchr (location, ':')) {
           gchar *newloc = gnome_vfs_escape_path_string (location);
 
           if (*newloc == '/')
-            src->filename = g_strdup_printf ("file://%s", newloc);
+            src->uri_name = g_strdup_printf ("file://%s", newloc);
           else
-            src->filename =
+            src->uri_name =
                 g_strdup_printf ("file://%s/%s", getcwd (cwd, PATH_MAX),
                 newloc);
           g_free (newloc);
         } else
-          src->filename = g_strdup (g_value_get_string (value));
-      }
+          src->uri_name = g_strdup (location);
 
-      if ((GST_STATE (src) == GST_STATE_PAUSED)
-          && (src->filename != NULL)) {
-        gst_gnomevfssrc_close_file (src);
-        gst_gnomevfssrc_open_file (src);
+        src->uri = gnome_vfs_uri_new (src->uri_name);
       }
       break;
     case ARG_HANDLE:
-      src->handle = g_value_get_pointer (value);
+      if (GST_STATE (src) == GST_STATE_NULL ||
+          GST_STATE (src) == GST_STATE_READY) {
+        if (src->uri) {
+          gnome_vfs_uri_unref (src->uri);
+          src->uri = NULL;
+        }
+        if (src->uri_name) {
+          g_free (src->uri_name);
+          src->uri_name = NULL;
+        }
+        src->handle = g_value_get_pointer (value);
+      }
       break;
     case ARG_BYTESPERREAD:
       src->bytes_per_read = g_value_get_int (value);
@@ -467,7 +546,7 @@ gst_gnomevfssrc_get_property (GObject * object, guint prop_id, GValue * value,
 
   switch (prop_id) {
     case ARG_LOCATION:
-      g_value_set_string (value, src->filename);
+      g_value_set_string (value, src->uri_name);
       break;
     case ARG_BYTESPERREAD:
       g_value_set_int (value, src->bytes_per_read);
@@ -1059,43 +1138,38 @@ gst_gnomevfssrc_open_file (GstGnomeVFSSrc * src)
 
   g_return_val_if_fail (!GST_FLAG_IS_SET (src, GST_GNOMEVFSSRC_OPEN), FALSE);
 
-  if (src->filename) {
-    /* create the uri */
-    src->uri = gnome_vfs_uri_new (src->filename);
-    if (!src->uri) {
-      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
-          (_("Could not open vfs file \"%s\" for reading."), src->filename),
-          GST_ERROR_SYSTEM);
-      return FALSE;
-    }
-  }
-
   if (!audiocast_init (src))
     return FALSE;
 
   gst_gnomevfssrc_push_callbacks (src);
 
-  if (src->filename)
+  if (src->uri != NULL) {
     result = gnome_vfs_open_uri (&(src->handle), src->uri, GNOME_VFS_OPEN_READ);
-  else
-    result = GNOME_VFS_OK;
-  if (result != GNOME_VFS_OK) {
-    char *escaped;
+    if (result != GNOME_VFS_OK) {
+      gchar *filename = gnome_vfs_uri_to_string (src->uri,
+          GNOME_VFS_URI_HIDE_PASSWORD);
 
-    gst_gnomevfssrc_pop_callbacks (src);
-    audiocast_thread_kill (src);
+      gst_gnomevfssrc_pop_callbacks (src);
+      audiocast_thread_kill (src);
 
-    escaped = gnome_vfs_unescape_string_for_display (src->filename);
+      GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
+          (_("Could not open vfs file \"%s\" for reading."), filename),
+          (gnome_vfs_result_to_string (result)));
+      g_free (filename);
+      return FALSE;
+    }
+    src->own_handle = TRUE;
+  } else if (!src->handle) {
     GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ,
-        (_("Could not open vfs file \"%s\" for reading."), escaped),
-        (gnome_vfs_result_to_string (result)));
-    g_free (escaped);
+        (_("No filename given.")), (NULL));
     return FALSE;
+  } else {
+    src->own_handle = FALSE;
   }
 
   info = gnome_vfs_file_info_new ();
-  if (gnome_vfs_get_file_info_from_handle (src->handle, info,
-          GNOME_VFS_FILE_INFO_DEFAULT)
+  if ((result = gnome_vfs_get_file_info_from_handle (src->handle,
+              info, GNOME_VFS_FILE_INFO_DEFAULT))
       == GNOME_VFS_OK) {
     if (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE)
       src->size = info->size;
@@ -1108,8 +1182,6 @@ gst_gnomevfssrc_open_file (GstGnomeVFSSrc * src)
 
   audiocast_do_notifications (src);
 
-  GST_DEBUG ("open result: %s", gnome_vfs_result_to_string (result));
-
   if (gnome_vfs_seek (src->handle, GNOME_VFS_SEEK_CURRENT, 0)
       == GNOME_VFS_OK) {
     src->seekable = TRUE;
@@ -1130,10 +1202,9 @@ gst_gnomevfssrc_close_file (GstGnomeVFSSrc * src)
   gst_gnomevfssrc_pop_callbacks (src);
   audiocast_thread_kill (src);
 
-  if (src->filename) {
+  if (src->own_handle) {
     gnome_vfs_close (src->handle);
-
-    gnome_vfs_uri_unref (src->uri);
+    src->handle = NULL;
   }
   src->size = 0;
   src->curoffset = 0;
diff --git a/ext/gnomevfs/gstgnomevfsuri.c b/ext/gnomevfs/gstgnomevfsuri.c
new file mode 100644 (file)
index 0000000..d977e3d
--- /dev/null
@@ -0,0 +1,76 @@
+/* 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>
+ *
+ * gstgnomevfssink.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.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libgnomevfs/gnome-vfs.h>
+#include "gstgnomevfsuri.h"
+
+gchar **
+gst_gnomevfs_get_supported_uris (GnomeVFSOpenMode mode)
+{
+  GnomeVFSResult res;
+  GnomeVFSHandle *handle;
+  gchar *uris[] = {
+    "http://localhost/bla",
+    "file:///bla",
+    "smb://localhost/bla",
+    "ftp://localhost/bla",
+    "sftp://localhost/bla",
+    "nfs://localhost/bla",
+    "ssh://localhost/bla",
+    "bla://bla",
+    NULL
+  }
+  , **result;
+  gint n, r = 0;
+
+  result = g_new (gchar *, 9);
+  for (n = 0; uris[n] != NULL; n++) {
+    res = gnome_vfs_open (&handle, uris[n], mode);
+    if (res == GNOME_VFS_OK) {
+      gnome_vfs_close (handle);
+    }
+    /* FIXME: do something with mode error */
+    if (res != GNOME_VFS_ERROR_INVALID_URI) {
+      gchar *protocol = g_strdup (uris[n]);
+      gint n;
+
+      for (n = 0; protocol[n] != '\0'; n++) {
+        if (protocol[n] == ':') {
+          protocol[n] = '\0';
+          break;
+        }
+      }
+
+      result[r++] = protocol;
+    }
+  }
+  result[r] = NULL;
+
+  return result;
+}
diff --git a/ext/gnomevfs/gstgnomevfsuri.h b/ext/gnomevfs/gstgnomevfsuri.h
new file mode 100644 (file)
index 0000000..c953768
--- /dev/null
@@ -0,0 +1,32 @@
+/* GStreamer
+ * Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
+ *
+ * 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_URI_H__
+#define __GST_GNOME_VFS_URI_H__
+
+#include <libgnomevfs/gnome-vfs.h>
+
+G_BEGIN_DECLS
+
+gchar **gst_gnomevfs_get_supported_uris        (GnomeVFSOpenMode mode);
+
+G_END_DECLS
+
+#endif /* __GST_GNOME_VFS_URI_H__ */