From d6ca6d9d6694c6df2249ecdb4d202ce39edaa3ac Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Mon, 13 Jan 2003 12:38:08 +0000 Subject: - gnome-vfs plugin added CVS patchset: 3891 CVS date: 2003/01/13 12:38:08 --- src/input/Makefile.am | 13 +- src/input/input_gnome_vfs.c | 404 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 415 insertions(+), 2 deletions(-) create mode 100644 src/input/input_gnome_vfs.c (limited to 'src') diff --git a/src/input/Makefile.am b/src/input/Makefile.am index eb22810d0..d74c71600 100644 --- a/src/input/Makefile.am +++ b/src/input/Makefile.am @@ -25,6 +25,10 @@ in_vcd = xineplug_inp_vcd.la #in_cda = xineplug_inp_cda.la endif +if HAVE_GNOME_VFS +in_gnome_vfs = xineplug_inp_gnome_vfs.la +endif + # For DVD if HAVE_DVDNAV DVD_CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \ @@ -38,7 +42,7 @@ DVD_CFLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE \ link_dvdnav = libdvdnav/libdvdnav.la libdvdread/libdvdread.la endif -AM_CFLAGS = $(DVD_CFLAGS) @ANSI_FLAGS@ +AM_CFLAGS = $(GNOME_VFS_CFLAGS) $(DVD_CFLAGS) @ANSI_FLAGS@ DEBUG_CFLAGS = @DEBUG_CFLAGS@ $(DVD_CFLAGS) @ANSI_FLAGS@ lib_LTLIBRARIES = \ @@ -46,6 +50,7 @@ lib_LTLIBRARIES = \ xineplug_inp_http.la \ $(in_dvd) \ $(in_vcd) \ + $(in_gnome_vfs) \ xineplug_inp_mms.la \ xineplug_inp_stdin_fifo.la \ xineplug_inp_pnm.la \ @@ -118,10 +123,14 @@ xineplug_inp_cdda_la_SOURCES = input_cdda.c xineplug_inp_cdda_la_LIBADD = $(XINE_LIB) xineplug_inp_cdda_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ +xineplug_inp_gnome_vfs_la_SOURCES = input_gnome_vfs.c +xineplug_inp_gnome_vfs_la_LIBADD = $(GNOME_VFS_LIBS) $(XINE_LIB) +xineplug_inp_gnome_vfs_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@ + include_HEADERS = input_plugin.h noinst_HEADERS = net_buf_ctrl.h mms.h pnm.h -EXTRA_DIST = input_dvd.c input_vcd.c +EXTRA_DIST = input_dvd.c input_vcd.c input_gnome_vfs.c $(XINE_LIB): @cd $(top_builddir)/src/xine-engine && $(MAKE) diff --git a/src/input/input_gnome_vfs.c b/src/input/input_gnome_vfs.c new file mode 100644 index 000000000..8d6697d7e --- /dev/null +++ b/src/input/input_gnome_vfs.c @@ -0,0 +1,404 @@ +/* + * Copyright (C) 2000-2002 the xine project + * 2002 Bastien Nocera + * + * This file is part of totem, + * + * xine is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * xine 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + * $Id: input_gnome_vfs.c,v 1.1 2003/01/13 12:38:08 hadess Exp $ + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +//#define D(x...) +#define D(x...) g_message (x) +#define LOG + +#define PREVIEW_SIZE 16384 + +#include +#include +#include +#include + +typedef struct { + input_class_t input_class; + xine_t *xine; +} gnomevfs_input_class_t; + +typedef struct { + input_plugin_t input_plugin; + xine_stream_t *stream; + + /* File */ + GnomeVFSHandle *fh; + off_t curpos; + char *mrl; + /* Subtitle */ + GnomeVFSHandle *sub; + + /* Preview */ + char preview[PREVIEW_SIZE]; + off_t preview_size; + off_t preview_pos; +} gnomevfs_input_t; + +static off_t gnomevfs_plugin_get_current_pos (input_plugin_t *this_gen); + + +static uint32_t +gnomevfs_plugin_get_capabilities (input_plugin_t *this_gen) +{ + return INPUT_CAP_SEEKABLE | INPUT_CAP_SPULANG; +} + +static off_t +gnomevfs_plugin_read (input_plugin_t *this_gen, char *buf, off_t len) +{ + gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; + off_t n, num_bytes; + + D("gnomevfs_plugin_read: %ld", (long int) len); + + num_bytes = 0; + + while (num_bytes < len) + { + GnomeVFSResult res; + + res = gnome_vfs_read (this->fh, &buf[num_bytes], + (GnomeVFSFileSize) (len - num_bytes), + (GnomeVFSFileSize *)&n); + + D("gnomevfs_plugin_read: read %ld from gnome-vfs", + (long int) n); + + if (res != GNOME_VFS_OK) + { + D("gnomevfs_plugin_read: gnome_vfs_read returns %s", + gnome_vfs_result_to_string (res)); + return 0; + } + + if (n <= 0) + { + g_warning ("input_gnomevfs: read error"); + } + + num_bytes += n; + this->curpos += n; + } + + return num_bytes; +} + +/* + * helper function to release buffer + * in case demux thread is cancelled + */ +static void +pool_release_buffer (void *arg) +{ + buf_element_t *buf = (buf_element_t *) arg; + if( buf != NULL ) + buf->free_buffer(buf); +} + +static buf_element_t* +gnomevfs_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, + off_t todo) +{ + off_t total_bytes; + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + + pthread_setcancelstate (PTHREAD_CANCEL_ENABLE,NULL); + pthread_cleanup_push (pool_release_buffer, buf); + + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + + total_bytes = gnomevfs_plugin_read (this_gen, buf->content, todo); + + while (total_bytes != todo) + { + buf->free_buffer (buf); + buf = NULL; + } + + if (buf != NULL) + buf->size = total_bytes; + + pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); + pthread_cleanup_pop (0); + + return buf; +} + +static off_t +gnomevfs_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) +{ + gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; + + if (gnome_vfs_seek (this->fh, origin, offset) == GNOME_VFS_OK) + { + D ("gnomevfs_plugin_seek: %d", (int) (origin + offset)); + return (off_t) (origin + offset); + } else + return (off_t) gnomevfs_plugin_get_current_pos (this_gen); +} + +static off_t +gnomevfs_plugin_get_current_pos (input_plugin_t *this_gen) +{ + gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; + GnomeVFSFileSize offset; + + if (this->fh == NULL) + { + D ("gnomevfs_plugin_get_current_pos: (this->fh == NULL)"); + return 0; + } + + if (gnome_vfs_tell (this->fh, &offset) == GNOME_VFS_OK) + { + D ("gnomevfs_plugin_get_current_pos: %d", (int) offset); + return (off_t) offset; + } else + return 0; +} + +static off_t +gnomevfs_plugin_get_length (input_plugin_t *this_gen) +{ + gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; + GnomeVFSFileInfo info; + + if (this->fh == NULL) + { + D ("gnomevfs_plugin_get_length: (this->fh == NULL)"); + return 0; + } + + if (gnome_vfs_get_file_info_from_handle (this->fh, + &info, + GNOME_VFS_FILE_INFO_DEFAULT) == GNOME_VFS_OK) + { + D ("gnomevfs_plugin_get_length: %d", (int) info.size); + return (off_t) info.size; + } else + return 0; +} + +static uint32_t +gnomevfs_plugin_get_blocksize (input_plugin_t *this_gen) +{ + return 0; +} + +static int +gnomevfs_klass_eject_media (input_class_t *this_gen) +{ + return 1; /* doesn't make sense */ +} + +static char* +gnomevfs_plugin_get_mrl (input_plugin_t *this_gen) +{ + gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; + + return this->mrl; +} + +static char +*gnomevfs_klass_get_description (input_class_t *this_gen) +{ + return _("gnome-vfs input plugin as shipped with xine"); +} + +static char +*gnomevfs_klass_get_identifier (input_class_t *this_gen) +{ + return "gnomevfs"; +} + +static int +gnomevfs_plugin_get_optional_data (input_plugin_t *this_gen, + void *data, int data_type) +{ + gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; + + D ("input_gnomevfs: get optional data, type %08x, sub %p\n", + data_type, this->sub); +//FIXME +#if 0 + switch (data_type) { + case INPUT_OPTIONAL_DATA_TEXTSPU0: + if(this->sub) + { + GnomeVFSHandle **tmp; + + /* dirty hacks... */ + tmp = data; + *tmp = this->sub; + + return INPUT_OPTIONAL_SUCCESS; + } + break; + case INPUT_OPTIONAL_DATA_SPULANG: + sprintf(data, "%3s", (this->sub) ? "on" : "off"); + return INPUT_OPTIONAL_SUCCESS; + break; + case INPUT_OPTIONAL_DATA_PREVIEW: + memcpy (data, this->preview, this->preview_size); + return this->preview_size; + default: + return INPUT_OPTIONAL_UNSUPPORTED; + break; + } +#endif + return INPUT_OPTIONAL_UNSUPPORTED; +} + +static void +gnomevfs_plugin_dispose (input_plugin_t *this_gen ) +{ + gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; + + if (this->fh) + gnome_vfs_close (this->fh); + if (this->sub) + gnome_vfs_close (this->sub); + if (this->mrl) + g_free (this->mrl); + + g_free (this); +} + +static void +gnomevfs_klass_dispose (input_class_t *this_gen) +{ + gnomevfs_input_class_t *this = (gnomevfs_input_class_t *) this_gen; + + g_free (this); +} + +static input_plugin_t * +gnomevfs_klass_open (input_class_t *klass_gen, xine_stream_t *stream, + const char *mrl) +{ + gnomevfs_input_t *this; + GnomeVFSHandle *fh, *sub; + const char *subtitle_file; + char *subtitle_path, *subtitle; + GnomeVFSURI *uri; + + D("gnomevfs_klass_open: %s", mrl); + + uri = gnome_vfs_uri_new (mrl); + if (uri == NULL) + return NULL; + + /* local files should be handled by the file input */ + if (gnome_vfs_uri_is_local (uri) == TRUE) + { + gnome_vfs_uri_unref (uri); + return NULL; + } + + subtitle_file = gnome_vfs_uri_get_fragment_identifier (uri); + if (subtitle_file != NULL) + { + subtitle_path = gnome_vfs_uri_extract_dirname (uri); + subtitle = g_strdup_printf ("%s%s", subtitle_path, + subtitle_file); + g_free (subtitle_path); + + D("input_file: trying to open subtitle file '%s'\n", + subtitle); + + if (gnome_vfs_open (&sub, subtitle, GNOME_VFS_OPEN_READ) + != GNOME_VFS_OK) + D("input_file: failed to open subtitle file '%s'\n", + subtitle); + } else { + sub = NULL; + } + + if (gnome_vfs_open_uri (&fh, uri, GNOME_VFS_OPEN_READ) + != GNOME_VFS_OK) + { + if (sub != NULL) + gnome_vfs_close (sub); + return NULL; + } + + this = g_new0 (gnomevfs_input_t, 1); + this->stream = stream; + this->fh = fh; + this->mrl = g_strdup (mrl); + this->sub = sub; + + this->input_plugin.get_capabilities = gnomevfs_plugin_get_capabilities; + this->input_plugin.read = gnomevfs_plugin_read; + this->input_plugin.read_block = gnomevfs_plugin_read_block; + this->input_plugin.seek = gnomevfs_plugin_seek; + this->input_plugin.get_current_pos = gnomevfs_plugin_get_current_pos; + this->input_plugin.get_length = gnomevfs_plugin_get_length; + this->input_plugin.get_blocksize = gnomevfs_plugin_get_blocksize; + this->input_plugin.get_mrl = gnomevfs_plugin_get_mrl; + this->input_plugin.get_optional_data = + gnomevfs_plugin_get_optional_data; + this->input_plugin.dispose = gnomevfs_plugin_dispose; + this->input_plugin.input_class = klass_gen; + + return &this->input_plugin; +} + +static void +*init_input_class (xine_t *xine, void *data) +{ + gnomevfs_input_class_t *this; + + if (gnome_vfs_initialized () == FALSE) + gnome_vfs_init (); + if (!g_thread_supported ()) + g_thread_init (NULL); + + this = g_new0 (gnomevfs_input_class_t, 1); + this->xine = xine; + + this->input_class.open_plugin = gnomevfs_klass_open; + this->input_class.get_identifier = gnomevfs_klass_get_identifier; + this->input_class.get_description = gnomevfs_klass_get_description; + this->input_class.get_dir = NULL; + this->input_class.get_autoplay_list = NULL; + this->input_class.dispose = gnomevfs_klass_dispose; + this->input_class.eject_media = gnomevfs_klass_eject_media; + + return (input_class_t *) this; +} + +plugin_info_t xine_plugin_info[] = { + { PLUGIN_INPUT, 9, "gnomevfs", XINE_VERSION_CODE, NULL, + init_input_class }, + { PLUGIN_NONE, 0, "", 0, NULL, NULL } +}; + -- cgit v1.2.3