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),
-
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
#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",
#include "gst/gst-i18n-plugin.h"
#include "gstgnomevfs.h"
+#include "gstgnomevfsuri.h"
#include <gst/gst.h>
#include <libgnomevfs/gnome-vfs.h>
/* uri */
GnomeVFSURI *uri;
+ gchar *uri_name;
/* handle */
GnomeVFSHandle *handle;
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,
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;
}
gnome_vfs_uri_unref (sink->uri);
sink->uri = NULL;
}
+
+ if (sink->uri_name) {
+ g_free (sink->uri_name);
+ sink->uri_name = NULL;
+ }
}
static void
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)
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;
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);
GST_ELEMENT_ERROR (sink, RESOURCE, FAILED, (_("No filename given")),
(NULL));
return FALSE;
+ } else {
+ sink->own_handle = FALSE;
}
GST_FLAG_SET (sink, GST_GNOMEVFSSINK_OPEN);
}
sink->own_handle = FALSE;
+ sink->handle = NULL;
}
GST_FLAG_UNSET (sink, GST_GNOMEVFSSINK_OPEN);
#include "gst/gst-i18n-plugin.h"
#include "gstgnomevfs.h"
+#include "gstgnomevfsuri.h"
#include <stdlib.h>
#include <sys/types.h>
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;
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,
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;
}
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;
}
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 */
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);
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);
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;
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;
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;
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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__ */