diff options
-rw-r--r-- | ChangeLog | 1 | ||||
-rw-r--r-- | configure.ac | 19 | ||||
-rw-r--r-- | m4/pkg.m4 | 57 | ||||
-rw-r--r-- | src/input/Makefile.am | 13 | ||||
-rw-r--r-- | src/input/input_gnome_vfs.c | 404 |
5 files changed, 492 insertions, 2 deletions
@@ -12,6 +12,7 @@ * reporting of unhandled codecs * NSF audio decoding via Nosefart * DVB plugin updated to new DVB API, DVB-C and DVB-T support + * gnome-vfs input plugin added xine-lib (1-beta2) * what a GOOM! post plugin diff --git a/configure.ac b/configure.ac index 49c2c2371..8df2cc8f4 100644 --- a/configure.ac +++ b/configure.ac @@ -616,6 +616,22 @@ AM_PATH_ARTS(0.9.5, AM_CONDITIONAL(HAVE_ARTS, test x"$no_arts" != "xyes") dnl --------------------------------------------- +dnl gnome-vfs support +dnl --------------------------------------------- +PKG_CHECK_MODULES(GNOME_VFS, gnome-vfs-2.0, + no_gnome_vfs=no, + no_gnome_vfs=yes) +AC_SUBST(GNOME_VFS_CFLAGS) +AC_SUBST(GNOME_VFS_LIBS) +if test x"$no_gnome_vfs" != "xyes"; then +AC_DEFINE(HAVE_GNOME_VFS,1,[Define this if you have gnome-vfs installed]) +else +AC_MSG_RESULT(*** All of the gnome-vfs dependent parts will be disabled ***) +fi +AM_CONDITIONAL(HAVE_GNOME_VFS, test x"$no_gnome_vfs" != "xyes") + + +dnl --------------------------------------------- dnl SUN style audio interface dnl --------------------------------------------- AC_MSG_CHECKING(for Sun audio support) @@ -1276,6 +1292,9 @@ if test x"$have_cdrom_ioctls" = "xyes"; then echo " - dvd - vcd" echo " - cdda" fi +if test x"$no_gnome_vfs" = "xno"; then + echo " - gnome-vfs" +fi echo "" dnl Demuxers diff --git a/m4/pkg.m4 b/m4/pkg.m4 new file mode 100644 index 000000000..c80e0acfc --- /dev/null +++ b/m4/pkg.m4 @@ -0,0 +1,57 @@ + +dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) +dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page +dnl also defines GSTUFF_PKG_ERRORS on error +AC_DEFUN(PKG_CHECK_MODULES, [ + succeeded=no + + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + AC_MSG_CHECKING(for $2) + + if $PKG_CONFIG --exists "$2" ; then + AC_MSG_RESULT(yes) + succeeded=yes + + AC_MSG_CHECKING($1_CFLAGS) + $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` + AC_MSG_RESULT($$1_CFLAGS) + + AC_MSG_CHECKING($1_LIBS) + $1_LIBS=`$PKG_CONFIG --libs "$2"` + AC_MSG_RESULT($$1_LIBS) + else + $1_CFLAGS="" + $1_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + ifelse([$4], ,echo $$1_PKG_ERRORS,) + fi + + AC_SUBST($1_CFLAGS) + AC_SUBST($1_LIBS) + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + ifelse([$3], , :, [$3]) + else + ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) + fi +]) + + 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 <hadess@hadess.net> + * + * 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 <libgnomevfs/gnome-vfs.h> + +//#define D(x...) +#define D(x...) g_message (x) +#define LOG + +#define PREVIEW_SIZE 16384 + +#include <xine/xine_internal.h> +#include <xine/xineutils.h> +#include <xine/compat.h> +#include <xine/input_plugin.h> + +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 } +}; + |