2 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3 * 2000 Wim Taymans <wtay@chello.be>
4 * 2001 Bastien Nocera <hadess@hadess.net>
5 * 2002 Kristian Rietveld <kris@gtk.org>
6 * 2002,2003 Colin Walters <walters@gnu.org>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Library General Public
12 * License as published by the Free Software Foundation; either
13 * version 2 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Library General Public License for more details.
20 * You should have received a copy of the GNU Library General Public
21 * License along with this library; if not, write to the
22 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 * Boston, MA 02111-1307, USA.
27 * SECTION:element-gnomevfssrc
28 * @short_description: Read from any GnomeVFS-supported location
29 * @see_also: #GstFileSrc, #GstGnomeVFSSink
33 * This plugin reads data from a local or remote location specified
34 * by an URI. This location can be specified using any protocol supported by
35 * the GnomeVFS library. Common protocols are 'file', 'http', 'ftp', or 'smb'.
40 * gst-launch -v gnomevfssrc location=file:///home/joe/foo.xyz ! fakesink
42 * The above pipeline will simply read a local file and do nothing with the
43 * data read. Instead of gnomevfssrc, we could just as well have used the
44 * filesrc element here.
47 * Another example pipeline:
49 * gst-launch -v gnomevfssrc location=smb://othercomputer/foo.xyz ! filesink location=/home/joe/foo.xyz
51 * The above pipeline will copy a file from a remote host to the local file
52 * system using the Samba protocol.
55 * Yet another example pipeline:
57 * gst-launch -v gnomevfssrc location=http://music.foobar.com/demo.mp3 ! mad ! audioconvert ! audioresample ! alsasink
59 * The above pipeline will read and decode and play an mp3 file from a
60 * web server using the http protocol.
68 /*#undef BROKEN_SIG */
74 #include "gst/gst-i18n-plugin.h"
76 #include "gstgnomevfssrc.h"
79 #include <sys/types.h>
80 #include <sys/socket.h>
82 #include <netinet/in.h>
83 #include <arpa/inet.h>
93 /* gnome-vfs.h doesn't include the following header, which we need: */
94 #include <libgnomevfs/gnome-vfs-standard-callbacks.h>
96 GST_DEBUG_CATEGORY_STATIC (gnomevfssrc_debug);
97 #define GST_CAT_DEFAULT gnomevfssrc_debug
99 static const GstElementDetails gst_gnome_vfs_src_details =
100 GST_ELEMENT_DETAILS ("GnomeVFS Source",
102 "Read from any GnomeVFS-supported file",
103 "Bastien Nocera <hadess@hadess.net>\n"
104 "Ronald S. Bultje <rbultje@ronald.bitfreak.net>");
106 static GStaticMutex count_lock = G_STATIC_MUTEX_INIT;
107 static gint ref_count = 0;
108 static gboolean vfs_owner = FALSE;
110 static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
113 GST_STATIC_CAPS_ANY);
127 static void gst_gnome_vfs_src_base_init (gpointer g_class);
128 static void gst_gnome_vfs_src_class_init (GstGnomeVFSSrcClass * klass);
129 static void gst_gnome_vfs_src_init (GstGnomeVFSSrc * gnomevfssrc);
130 static void gst_gnome_vfs_src_finalize (GObject * object);
131 static void gst_gnome_vfs_src_uri_handler_init (gpointer g_iface,
132 gpointer iface_data);
134 static void gst_gnome_vfs_src_set_property (GObject * object, guint prop_id,
135 const GValue * value, GParamSpec * pspec);
136 static void gst_gnome_vfs_src_get_property (GObject * object, guint prop_id,
137 GValue * value, GParamSpec * pspec);
139 static gboolean gst_gnome_vfs_src_stop (GstBaseSrc * src);
140 static gboolean gst_gnome_vfs_src_start (GstBaseSrc * src);
141 static gboolean gst_gnome_vfs_src_is_seekable (GstBaseSrc * src);
142 static gboolean gst_gnome_vfs_src_check_get_range (GstBaseSrc * src);
143 static gboolean gst_gnome_vfs_src_get_size (GstBaseSrc * src, guint64 * size);
144 static GstFlowReturn gst_gnome_vfs_src_create (GstBaseSrc * basesrc,
145 guint64 offset, guint size, GstBuffer ** buffer);
147 static GstElementClass *parent_class = NULL;
150 gst_gnome_vfs_src_get_type (void)
152 static GType gnomevfssrc_type = 0;
154 if (!gnomevfssrc_type) {
155 static const GTypeInfo gnomevfssrc_info = {
156 sizeof (GstGnomeVFSSrcClass),
157 gst_gnome_vfs_src_base_init,
159 (GClassInitFunc) gst_gnome_vfs_src_class_init,
162 sizeof (GstGnomeVFSSrc),
164 (GInstanceInitFunc) gst_gnome_vfs_src_init,
166 static const GInterfaceInfo urihandler_info = {
167 gst_gnome_vfs_src_uri_handler_init,
173 g_type_register_static (GST_TYPE_BASE_SRC,
174 "GstGnomeVFSSrc", &gnomevfssrc_info, 0);
175 g_type_add_interface_static (gnomevfssrc_type, GST_TYPE_URI_HANDLER,
178 return gnomevfssrc_type;
182 gst_gnome_vfs_src_base_init (gpointer g_class)
184 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
186 gst_element_class_add_pad_template (element_class,
187 gst_static_pad_template_get (&srctemplate));
188 gst_element_class_set_details (element_class, &gst_gnome_vfs_src_details);
190 GST_DEBUG_CATEGORY_INIT (gnomevfssrc_debug, "gnomevfssrc", 0,
195 gst_gnome_vfs_src_class_init (GstGnomeVFSSrcClass * klass)
197 GObjectClass *gobject_class;
198 GstElementClass *gstelement_class;
199 GstBaseSrcClass *gstbasesrc_class;
201 gobject_class = G_OBJECT_CLASS (klass);
202 gstelement_class = GST_ELEMENT_CLASS (klass);
203 gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
205 parent_class = g_type_class_peek_parent (klass);
207 gobject_class->finalize = gst_gnome_vfs_src_finalize;
208 gobject_class->set_property = gst_gnome_vfs_src_set_property;
209 gobject_class->get_property = gst_gnome_vfs_src_get_property;
212 gst_element_class_install_std_props (GST_ELEMENT_CLASS (klass),
213 "location", ARG_LOCATION, G_PARAM_READWRITE, NULL);
214 g_object_class_install_property (gobject_class,
216 g_param_spec_boxed ("handle",
217 "GnomeVFSHandle", "Handle for GnomeVFS",
218 GST_TYPE_GNOME_VFS_HANDLE, G_PARAM_READWRITE));
221 g_object_class_install_property (gobject_class,
223 g_param_spec_boolean ("iradio-mode",
225 "Enable internet radio mode (extraction of shoutcast/icecast metadata)",
226 FALSE, G_PARAM_READWRITE));
227 g_object_class_install_property (gobject_class,
229 g_param_spec_string ("iradio-name",
230 "iradio-name", "Name of the stream", NULL, G_PARAM_READABLE));
231 g_object_class_install_property (gobject_class,
233 g_param_spec_string ("iradio-genre",
234 "iradio-genre", "Genre of the stream", NULL, G_PARAM_READABLE));
235 g_object_class_install_property (gobject_class,
237 g_param_spec_string ("iradio-url",
239 "Homepage URL for radio stream", NULL, G_PARAM_READABLE));
240 g_object_class_install_property (gobject_class,
242 g_param_spec_string ("iradio-title",
244 "Name of currently playing song", NULL, G_PARAM_READABLE));
246 gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_start);
247 gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_stop);
248 gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_get_size);
249 gstbasesrc_class->is_seekable =
250 GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_is_seekable);
251 gstbasesrc_class->check_get_range =
252 GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_check_get_range);
253 gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_gnome_vfs_src_create);
257 gst_gnome_vfs_src_init (GstGnomeVFSSrc * gnomevfssrc)
259 gnomevfssrc->uri = NULL;
260 gnomevfssrc->uri_name = NULL;
261 gnomevfssrc->handle = NULL;
262 gnomevfssrc->curoffset = 0;
263 gnomevfssrc->seekable = FALSE;
265 gnomevfssrc->icy_caps = NULL;
266 gnomevfssrc->iradio_mode = FALSE;
267 gnomevfssrc->http_callbacks_pushed = FALSE;
268 gnomevfssrc->iradio_name = NULL;
269 gnomevfssrc->iradio_genre = NULL;
270 gnomevfssrc->iradio_url = NULL;
271 gnomevfssrc->iradio_title = NULL;
273 g_static_mutex_lock (&count_lock);
274 if (ref_count == 0) {
275 /* gnome vfs engine init */
276 if (gnome_vfs_initialized () == FALSE) {
282 g_static_mutex_unlock (&count_lock);
286 gst_gnome_vfs_src_finalize (GObject * object)
288 GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (object);
290 g_static_mutex_lock (&count_lock);
292 if (ref_count == 0 && vfs_owner) {
293 if (gnome_vfs_initialized () == TRUE) {
294 gnome_vfs_shutdown ();
297 g_static_mutex_unlock (&count_lock);
300 gnome_vfs_uri_unref (src->uri);
304 g_free (src->uri_name);
305 src->uri_name = NULL;
307 g_free (src->iradio_name);
308 src->iradio_name = NULL;
310 g_free (src->iradio_genre);
311 src->iradio_genre = NULL;
313 g_free (src->iradio_url);
314 src->iradio_url = NULL;
316 g_free (src->iradio_title);
317 src->iradio_title = NULL;
320 gst_caps_unref (src->icy_caps);
321 src->icy_caps = NULL;
324 G_OBJECT_CLASS (parent_class)->finalize (object);
328 * URI interface support.
332 gst_gnome_vfs_src_uri_get_type (void)
338 gst_gnome_vfs_src_uri_get_protocols (void)
340 static gchar **protocols = NULL;
343 protocols = gst_gnomevfs_get_supported_uris ();
349 gst_gnome_vfs_src_uri_get_uri (GstURIHandler * handler)
351 GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (handler);
353 return src->uri_name;
357 gst_gnome_vfs_src_uri_set_uri (GstURIHandler * handler, const gchar * uri)
359 GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (handler);
361 if (GST_STATE (src) == GST_STATE_PLAYING ||
362 GST_STATE (src) == GST_STATE_PAUSED)
365 g_object_set (G_OBJECT (src), "location", uri, NULL);
371 gst_gnome_vfs_src_uri_handler_init (gpointer g_iface, gpointer iface_data)
373 GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
375 iface->get_type = gst_gnome_vfs_src_uri_get_type;
376 iface->get_protocols = gst_gnome_vfs_src_uri_get_protocols;
377 iface->get_uri = gst_gnome_vfs_src_uri_get_uri;
378 iface->set_uri = gst_gnome_vfs_src_uri_set_uri;
382 gst_gnome_vfs_src_set_property (GObject * object, guint prop_id,
383 const GValue * value, GParamSpec * pspec)
387 src = GST_GNOME_VFS_SRC (object);
391 const gchar *new_location;
393 /* the element must be stopped or paused in order to do this */
394 if (GST_STATE (src) == GST_STATE_PLAYING ||
395 GST_STATE (src) == GST_STATE_PAUSED)
399 gnome_vfs_uri_unref (src->uri);
403 g_free (src->uri_name);
404 src->uri_name = NULL;
407 new_location = g_value_get_string (value);
409 src->uri_name = gst_gnome_vfs_location_to_uri_string (new_location);
410 src->uri = gnome_vfs_uri_new (src->uri_name);
415 if (GST_STATE (src) == GST_STATE_NULL ||
416 GST_STATE (src) == GST_STATE_READY) {
418 gnome_vfs_uri_unref (src->uri);
422 g_free (src->uri_name);
423 src->uri_name = NULL;
425 src->handle = g_value_get_boxed (value);
428 case ARG_IRADIO_MODE:
429 src->iradio_mode = g_value_get_boolean (value);
432 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
438 gst_gnome_vfs_src_get_property (GObject * object, guint prop_id, GValue * value,
443 src = GST_GNOME_VFS_SRC (object);
447 g_value_set_string (value, src->uri_name);
450 g_value_set_boxed (value, src->handle);
452 case ARG_IRADIO_MODE:
453 g_value_set_boolean (value, src->iradio_mode);
455 case ARG_IRADIO_NAME:
456 g_value_set_string (value, src->iradio_name);
458 case ARG_IRADIO_GENRE:
459 g_value_set_string (value, src->iradio_genre);
462 g_value_set_string (value, src->iradio_url);
464 case ARG_IRADIO_TITLE:
465 g_value_set_string (value, src->iradio_title);
468 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
474 unicodify (const char *str, int len, ...)
476 char *ret = NULL, *cset;
478 gsize bytes_read, bytes_written;
480 if (g_utf8_validate (str, len, NULL))
481 return g_strndup (str, len >= 0 ? len : strlen (str));
483 va_start (args, len);
484 while ((cset = va_arg (args, char *)) != NULL)
486 if (!strcmp (cset, "locale"))
487 ret = g_locale_to_utf8 (str, len, &bytes_read, &bytes_written, NULL);
489 ret = g_convert (str, len, "UTF-8", cset,
490 &bytes_read, &bytes_written, NULL);
500 gst_gnome_vfs_src_unicodify (const char *str)
502 return unicodify (str, -1, "locale", "ISO-8859-1", NULL);
506 gst_gnome_vfs_src_send_additional_headers_callback (gconstpointer in,
507 gsize in_size, gpointer out, gsize out_size, gpointer callback_data)
509 GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (callback_data);
510 GnomeVFSModuleCallbackAdditionalHeadersOut *out_args =
511 (GnomeVFSModuleCallbackAdditionalHeadersOut *) out;
513 if (!src->iradio_mode)
515 GST_DEBUG_OBJECT (src, "sending headers\n");
517 out_args->headers = g_list_append (out_args->headers,
518 g_strdup ("icy-metadata:1\r\n"));
522 gst_gnome_vfs_src_received_headers_callback (gconstpointer in,
523 gsize in_size, gpointer out, gsize out_size, gpointer callback_data)
527 GstGnomeVFSSrc *src = GST_GNOME_VFS_SRC (callback_data);
528 GnomeVFSModuleCallbackReceivedHeadersIn *in_args =
529 (GnomeVFSModuleCallbackReceivedHeadersIn *) in;
531 /* This is only used for internet radio stuff right now */
532 if (!src->iradio_mode)
535 for (i = in_args->headers; i; i = i->next) {
536 char *data = (char *) i->data;
538 char *value = strchr (data, ':');
549 if (strncmp (data, "icy-metaint:", 12) == 0) { /* ugh */
550 if (sscanf (data + 12, "%d", &icy_metaint) == 1) {
552 src->icy_caps = gst_caps_new_simple ("application/x-icy",
553 "metadata-interval", G_TYPE_INT, icy_metaint, NULL);
558 if (!strncmp (data, "icy-", 4))
563 GST_DEBUG_OBJECT (src, "key: %s", key);
564 if (!strncmp (key, "name", 4)) {
565 g_free (src->iradio_name);
566 src->iradio_name = gst_gnome_vfs_src_unicodify (value);
567 if (src->iradio_name)
568 g_object_notify (G_OBJECT (src), "iradio-name");
569 } else if (!strncmp (key, "genre", 5)) {
570 g_free (src->iradio_genre);
571 src->iradio_genre = gst_gnome_vfs_src_unicodify (value);
572 if (src->iradio_genre)
573 g_object_notify (G_OBJECT (src), "iradio-genre");
574 } else if (!strncmp (key, "url", 3)) {
575 g_free (src->iradio_url);
576 src->iradio_url = gst_gnome_vfs_src_unicodify (value);
578 g_object_notify (G_OBJECT (src), "iradio-url");
584 gst_gnome_vfs_src_push_callbacks (GstGnomeVFSSrc * src)
586 if (src->http_callbacks_pushed)
589 GST_DEBUG_OBJECT (src, "pushing callbacks");
590 gnome_vfs_module_callback_push
591 (GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS,
592 gst_gnome_vfs_src_send_additional_headers_callback, src, NULL);
593 gnome_vfs_module_callback_push
594 (GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS,
595 gst_gnome_vfs_src_received_headers_callback, src, NULL);
597 src->http_callbacks_pushed = TRUE;
601 gst_gnome_vfs_src_pop_callbacks (GstGnomeVFSSrc * src)
603 if (!src->http_callbacks_pushed)
606 GST_DEBUG_OBJECT (src, "popping callbacks");
607 gnome_vfs_module_callback_pop
608 (GNOME_VFS_MODULE_CALLBACK_HTTP_SEND_ADDITIONAL_HEADERS);
609 gnome_vfs_module_callback_pop
610 (GNOME_VFS_MODULE_CALLBACK_HTTP_RECEIVED_HEADERS);
612 src->http_callbacks_pushed = FALSE;
616 * Read a new buffer from src->reqoffset, takes care of events
617 * and seeking and such.
620 gst_gnome_vfs_src_create (GstBaseSrc * basesrc, guint64 offset, guint size,
625 GnomeVFSFileSize readbytes;
629 src = GST_GNOME_VFS_SRC (basesrc);
631 GST_DEBUG ("now at %llu, reading %lld, size %u", src->curoffset, offset,
634 /* seek if required */
635 if (G_UNLIKELY (src->curoffset != offset)) {
636 GST_DEBUG ("need to seek");
638 GST_DEBUG ("seeking to %lld", offset);
639 res = gnome_vfs_seek (src->handle, GNOME_VFS_SEEK_START, offset);
640 if (res != GNOME_VFS_OK)
642 src->curoffset = offset;
648 buf = gst_buffer_new_and_alloc (size);
651 gst_buffer_set_caps (buf, src->icy_caps);
653 data = GST_BUFFER_DATA (buf);
654 GST_BUFFER_OFFSET (buf) = src->curoffset;
656 res = gnome_vfs_read (src->handle, data, size, &readbytes);
658 if (G_UNLIKELY (res == GNOME_VFS_ERROR_EOF || (res == GNOME_VFS_OK
662 GST_BUFFER_SIZE (buf) = readbytes;
664 if (G_UNLIKELY (res != GNOME_VFS_OK))
667 src->curoffset += readbytes;
669 /* we're done, return the buffer */
676 GST_ELEMENT_ERROR (src, RESOURCE, SEEK, (NULL),
677 ("Failed to seek to requested position %" G_GINT64_FORMAT ": %s",
678 offset, gnome_vfs_result_to_string (res)));
679 return GST_FLOW_ERROR;
683 GST_ELEMENT_ERROR (src, RESOURCE, SEEK, (NULL),
684 ("Requested seek from %" G_GINT64_FORMAT " to %" G_GINT64_FORMAT
685 "on non-seekable stream", src->curoffset, offset));
686 return GST_FLOW_ERROR;
690 gst_buffer_unref (buf);
691 GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
692 ("Failed to read data: %s", gnome_vfs_result_to_string (res)));
693 return GST_FLOW_ERROR;
697 gst_buffer_unref (buf);
698 GST_DEBUG_OBJECT (src, "Reading data gave EOS");
699 return GST_FLOW_UNEXPECTED;
704 gst_gnome_vfs_src_is_seekable (GstBaseSrc * basesrc)
708 src = GST_GNOME_VFS_SRC (basesrc);
710 return src->seekable;
714 gst_gnome_vfs_src_check_get_range (GstBaseSrc * basesrc)
717 const gchar *protocol;
719 src = GST_GNOME_VFS_SRC (basesrc);
721 if (src->uri == NULL) {
722 GST_WARNING_OBJECT (src, "no URI set yet");
726 if (gnome_vfs_uri_is_local (src->uri)) {
727 GST_LOG_OBJECT (src, "local URI (%s), assuming random access is possible",
728 GST_STR_NULL (src->uri_name));
732 /* blacklist certain protocols we know won't work getrange-based */
733 protocol = gnome_vfs_uri_get_scheme (src->uri);
734 if (protocol == NULL)
737 if (strcmp (protocol, "http") == 0) {
738 GST_LOG_OBJECT (src, "blacklisted protocol '%s', no random access possible"
739 " (URI=%s)", protocol, GST_STR_NULL (src->uri_name));
743 /* fall through to undecided */
747 /* don't know what to do, let the basesrc class decide for us */
748 GST_LOG_OBJECT (src, "undecided about URI '%s', let base class handle it",
749 GST_STR_NULL (src->uri_name));
751 if (GST_BASE_SRC_CLASS (parent_class)->check_get_range)
752 return GST_BASE_SRC_CLASS (parent_class)->check_get_range (basesrc);
759 gst_gnome_vfs_src_get_size (GstBaseSrc * basesrc, guint64 * size)
763 src = GST_GNOME_VFS_SRC (basesrc);
765 GST_DEBUG_OBJECT (src, "size %" G_GUINT64_FORMAT, src->size);
767 if (src->size == (GnomeVFSFileSize) - 1)
775 /* open the file, do stuff necessary to go to PAUSED state */
777 gst_gnome_vfs_src_start (GstBaseSrc * basesrc)
779 GnomeVFSFileInfoOptions options;
781 GnomeVFSFileInfo *info;
784 src = GST_GNOME_VFS_SRC (basesrc);
786 gst_gnome_vfs_src_push_callbacks (src);
788 if (src->uri != NULL) {
789 GnomeVFSOpenMode mode;
791 /* this can block... */
792 mode = GNOME_VFS_OPEN_READ;
793 res = gnome_vfs_open_uri (&src->handle, src->uri, mode);
794 if (res != GNOME_VFS_OK)
796 src->own_handle = TRUE;
797 } else if (!src->handle) {
800 src->own_handle = FALSE;
803 src->size = (GnomeVFSFileSize) - 1;
804 info = gnome_vfs_file_info_new ();
805 options = GNOME_VFS_FILE_INFO_DEFAULT | GNOME_VFS_FILE_INFO_FOLLOW_LINKS;
806 res = gnome_vfs_get_file_info_from_handle (src->handle, info, options);
807 if (res == GNOME_VFS_OK) {
808 if ((info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) != 0) {
809 src->size = info->size;
810 GST_DEBUG_OBJECT (src, "size: %" G_GUINT64_FORMAT " bytes", src->size);
811 } else if (src->own_handle && gnome_vfs_uri_is_local (src->uri)) {
812 GST_DEBUG_OBJECT (src, "file size not known, trying fallback");
813 res = gnome_vfs_get_file_info_uri (src->uri, info, options);
814 if (res == GNOME_VFS_OK &&
815 (info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_SIZE) != 0) {
816 src->size = info->size;
817 GST_DEBUG_OBJECT (src, "size: %" G_GUINT64_FORMAT " bytes", src->size);
820 if (src->size == (GnomeVFSFileSize) - 1)
821 GST_DEBUG_OBJECT (src, "file size not known");
823 GST_WARNING_OBJECT (src, "getting info failed: %s",
824 gnome_vfs_result_to_string (res));
826 gnome_vfs_file_info_unref (info);
828 if (gnome_vfs_seek (src->handle, GNOME_VFS_SEEK_CURRENT, 0)
830 src->seekable = TRUE;
832 src->seekable = FALSE;
840 gchar *filename = gnome_vfs_uri_to_string (src->uri,
841 GNOME_VFS_URI_HIDE_PASSWORD);
843 gst_gnome_vfs_src_pop_callbacks (src);
845 if (res == GNOME_VFS_ERROR_NOT_FOUND ||
846 res == GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE) {
847 GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL),
848 ("Could not open vfs file \"%s\" for reading: %s",
849 filename, gnome_vfs_result_to_string (res)));
851 GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL),
852 ("Could not open vfs file \"%s\" for reading: %s",
853 filename, gnome_vfs_result_to_string (res)));
860 GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), ("No filename given"));
866 gst_gnome_vfs_src_stop (GstBaseSrc * basesrc)
870 src = GST_GNOME_VFS_SRC (basesrc);
872 gst_gnome_vfs_src_pop_callbacks (src);
874 if (src->own_handle) {
875 gnome_vfs_close (src->handle);
878 src->size = (GnomeVFSFileSize) - 1;
882 gst_caps_unref (src->icy_caps);
883 src->icy_caps = NULL;