summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-08-21 00:37:26 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-08-21 00:37:26 +0000
commitfa630d674955c0a6ea29d1427081e200223b85cc (patch)
tree3a696b538dfcfa9e8ed81244f2f7549380df97ac /src
parent44d393d0d8b4ff75e76e21860386ce5c145d304a (diff)
downloadxine-lib-fa630d674955c0a6ea29d1427081e200223b85cc.tar.gz
xine-lib-fa630d674955c0a6ea29d1427081e200223b85cc.tar.bz2
RIP Input Plugin
CVS patchset: 5300 CVS date: 2003/08/21 00:37:26
Diffstat (limited to 'src')
-rw-r--r--src/input/input_dvd.c11
-rw-r--r--src/input/input_http.c11
-rw-r--r--src/input/input_plugin.h10
-rw-r--r--src/xine-engine/Makefile.am3
-rw-r--r--src/xine-engine/input_rip.c425
-rw-r--r--src/xine-engine/xine.c40
-rw-r--r--src/xine-engine/xine_internal.h3
7 files changed, 495 insertions, 8 deletions
diff --git a/src/input/input_dvd.c b/src/input/input_dvd.c
index 8c7290ddc..9fe9805dd 100644
--- a/src/input/input_dvd.c
+++ b/src/input/input_dvd.c
@@ -18,7 +18,7 @@
* 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_dvd.c,v 1.166 2003/06/29 10:57:08 mroi Exp $
+ * $Id: input_dvd.c,v 1.167 2003/08/21 00:37:26 miguelfreitas Exp $
*
*/
@@ -255,7 +255,11 @@ static uint32_t dvd_plugin_get_capabilities (input_plugin_t *this_gen) {
trace_print("Called\n");
- return INPUT_CAP_BLOCK |
+ return INPUT_CAP_BLOCK |
+ /* TODO: figure out if there is any "allow copying" flag on DVD.
+ * maybe set INPUT_CAP_RIP_FORBIDDEN only for encrypted media?
+ */
+ INPUT_CAP_RIP_FORBIDDEN |
#if CAN_SEEK
(this->seekable ? INPUT_CAP_SEEKABLE : 0) |
#endif
@@ -1732,6 +1736,9 @@ static void *init_class (xine_t *xine, void *data) {
/*
* $Log: input_dvd.c,v $
+ * Revision 1.167 2003/08/21 00:37:26 miguelfreitas
+ * RIP Input Plugin
+ *
* Revision 1.166 2003/06/29 10:57:08 mroi
* on some DVDs, the first highlight information (which button to highlight) will
* arrive before the first SPU packet, therefore the SPU decoder has not yet been
diff --git a/src/input/input_http.c b/src/input/input_http.c
index 7ac5e8b59..ea87ccbe7 100644
--- a/src/input/input_http.c
+++ b/src/input/input_http.c
@@ -19,7 +19,7 @@
*
* input plugin for http network streams
*
- * $Id: input_http.c,v 1.62 2003/06/19 14:46:03 guenter Exp $
+ * $Id: input_http.c,v 1.63 2003/08/21 00:37:29 miguelfreitas Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -541,8 +541,15 @@ static off_t http_plugin_get_length (input_plugin_t *this_gen) {
}
static uint32_t http_plugin_get_capabilities (input_plugin_t *this_gen) {
+ http_input_plugin_t *this = (http_input_plugin_t *) this_gen;
+ uint32_t caps = INPUT_CAP_PREVIEW;
+
+ /* Nullsoft asked to not allow saving streaming nsv files */
+ if (this->filename &&
+ !strncmp(this->filename + strlen(this->filename) - 4, ".nsv", 4))
+ caps |= INPUT_CAP_RIP_FORBIDDEN;
- return INPUT_CAP_PREVIEW;
+ return caps;
}
static uint32_t http_plugin_get_blocksize (input_plugin_t *this_gen) {
diff --git a/src/input/input_plugin.h b/src/input/input_plugin.h
index 99fb1d738..4377ae51a 100644
--- a/src/input/input_plugin.h
+++ b/src/input/input_plugin.h
@@ -17,7 +17,7 @@
* 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_plugin.h,v 1.50 2003/07/03 00:58:51 andruil Exp $
+ * $Id: input_plugin.h,v 1.51 2003/08/21 00:37:29 miguelfreitas Exp $
*/
#ifndef HAVE_INPUT_PLUGIN_H
@@ -265,6 +265,14 @@ struct input_plugin_s {
#define INPUT_CAP_CHAPTERS 0x00000080
+/*
+ * INPUT_CAP_RIP_FORBIDDEN:
+ * means that rip/disk saving must not be used.
+ * (probably at author's request)
+ */
+
+#define INPUT_CAP_RIP_FORBIDDEN 0x00000100
+
#define INPUT_IS_SEEKABLE(input) (((input)->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0)
#define INPUT_OPTIONAL_UNSUPPORTED 0
diff --git a/src/xine-engine/Makefile.am b/src/xine-engine/Makefile.am
index d82c3811a..0a4a04155 100644
--- a/src/xine-engine/Makefile.am
+++ b/src/xine-engine/Makefile.am
@@ -13,7 +13,8 @@ libxine_la_SOURCES = xine.c metronom.c configfile.c buffer.c \
load_plugins.c video_decoder.c buffer_types.c \
audio_decoder.c video_out.c audio_out.c resample.c events.c \
video_overlay.c osd.c scratch.c demux.c vo_scale.c \
- xine_interface.c post.c tvmode.c broadcaster.c io_helper.c
+ xine_interface.c post.c tvmode.c broadcaster.c io_helper.c \
+ input_rip.c
# FIXME: these are currently unused:
EXTRA_DIST = lrb.c lrb.h
diff --git a/src/xine-engine/input_rip.c b/src/xine-engine/input_rip.c
new file mode 100644
index 000000000..122837db2
--- /dev/null
+++ b/src/xine-engine/input_rip.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright (C) 2000-2003 the xine project
+ *
+ * This file is part of xine, a free video player.
+ *
+ * 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
+ *
+ * Rip Input Plugin for catching streams
+ *
+ * It saves raw data into file as go from input plugins.
+ *
+ * Usage:
+ *
+ * - activation:
+ * xine stream_mrl#rip:file.raw
+ *
+ * - it's possible speeder saving streams in the xine without playing:
+ * xine stream_mrl#rip:file.raw;noaudio;novideo
+ *
+ * $Id: input_rip.c,v 1.1 2003/08/21 00:37:29 miguelfreitas Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+/* logging */
+/*
+#define LOG 1
+*/
+#define LOG_MODULE "input_rip"
+#define CLR_FAIL "\e[1;31m"
+#define CLR_RST "\e[0;39m"
+
+#include "xine_internal.h"
+
+#define SCRATCH_SIZE 1024
+
+typedef struct {
+ input_plugin_t input_plugin; /* inherited structure */
+
+ input_plugin_t *main_input_plugin; /* original input plugin */
+
+ xine_stream_t *stream;
+ FILE *file; /* destination file */
+
+ char *preview; /* preview data */
+ off_t preview_size; /* size of read preview data */
+ off_t curpos; /* current position */
+} rip_input_plugin_t;
+
+
+/*
+ * read data from input plugin and write it into file
+ */
+static off_t rip_plugin_read(input_plugin_t *this_gen, char *buf, off_t len) {
+ rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen;
+ off_t retlen, nreal, npreview;
+
+ lprintf("reading %lld bytes\n", len);
+
+ if (this->curpos < this->preview_size && this->preview) {
+ /* get some data from preview */
+ npreview = this->preview_size - this->curpos;
+ if (npreview > len) npreview = len;
+
+ lprintf(" => get %lld bytes from preview (%lld bytes)\n", npreview, this->preview_size);
+
+ memcpy(buf, &this->preview[this->curpos], npreview);
+ } else {
+ /* no data from preview */
+ npreview = 0;
+ }
+
+ /* really to read/catch */
+ nreal = len - npreview;
+ if (nreal) {
+ lprintf(" => read %lld bytes from input plugin\n", nreal);
+
+ /* read from main input plugin */
+ retlen = this->main_input_plugin->read(this->main_input_plugin, &buf[npreview], nreal);
+ lprintf("%s => returned %lld\e" CLR_RST "\n", retlen == nreal ? "" : CLR_FAIL, retlen);
+
+ if (retlen < 0) {
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("input_rip: reading by input plugin failed\n"));
+ return -1;
+ }
+
+ /* write to file */
+ if (retlen && this->file) {
+ if (fwrite(buf + npreview, retlen, 1, this->file) != 1) {
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("input_rip: error writing to file %lld bytes: %s\n"),
+ retlen, strerror(errno));
+ return 0;
+ }
+ }
+ } else {
+ retlen = 0;
+ }
+
+ this->curpos += (npreview + retlen);
+
+ return npreview + retlen;
+}
+
+/*
+ * open catching file and slave input plugin
+ */
+static int rip_plugin_open(input_plugin_t *this_gen) {
+ rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen;
+
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("input_rip: open() function should never be called\n"));
+ return 0;
+}
+
+/*
+ * delete seeking from capabilities,
+ * set preview cap (implemented by original plugin or rip plugin)
+ *
+ * preview capability can be deleted after opening with some special inputs
+ */
+static uint32_t rip_plugin_get_capabilities(input_plugin_t *this_gen) {
+ rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen;
+ uint32_t caps;
+
+ caps = this->main_input_plugin->get_capabilities(this->main_input_plugin);
+ return (caps & (~INPUT_CAP_SEEKABLE)) | (this->preview ? INPUT_CAP_PREVIEW : 0);
+}
+
+/*
+ * read a block of data from input plugin and write it into file
+ *
+ * This rip plugin returns block unchanged from main input plugin. But special
+ * case is reading over preview - it returns own allocated block.
+ */
+static buf_element_t *rip_plugin_read_block(input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) {
+ rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen;
+ buf_element_t *buf;
+ off_t npreview, nreal, retval;
+
+ lprintf("read %lld bytes (block)\n", todo);
+
+ if (!todo) return NULL;
+
+ /* number of bytes from preview */
+ if (this->preview && this->curpos < this->preview_size) {
+ npreview = this->preview_size - this->curpos;
+ if (npreview > todo) npreview = todo;
+ } else {
+ npreview = 0;
+ }
+ /* really read & catched bytes */
+ nreal = todo - npreview;
+
+ if (npreview) {
+ /* new block created by rip input plugin */
+ buf = fifo->buffer_pool_alloc(fifo);
+ buf->content = buf->mem;
+ buf->type = BUF_DEMUX_BLOCK;
+ buf->size = npreview;
+ memcpy(buf->content, &this->preview[this->curpos], npreview);
+
+ lprintf(" => read %lld bytes by rip plugin (block)\n", nreal + npreview);
+ retval = rip_plugin_read(this_gen, &buf->content[npreview], nreal);
+ if (retval != nreal) {
+ buf->free_buffer(buf);
+ return NULL;
+ }
+
+ buf->size += retval;
+ } else {
+ /* all data go as block from input plugin */
+ lprintf(" => reading %lld bytes from input plugin (block)\n", nreal);
+
+ buf = this->main_input_plugin->read_block(this->main_input_plugin, fifo, nreal);
+ if (!buf) {
+ lprintf(CLR_FAIL " => reading failed (block)" CLR_RST "\n");
+ return NULL;
+ }
+ }
+
+ this->curpos += buf->size;
+
+ /* write the block */
+ if (buf && this->file && buf->type == BUF_DEMUX_BLOCK) {
+ if (nreal > 0 && fwrite(&buf->content[npreview], nreal, 1, this->file) != 1) {
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("input_rip: error writing to file: %s\n"), strerror(errno));
+ buf->free_buffer(buf);
+ return NULL;
+ }
+ }
+
+ return buf;
+}
+
+/*
+ * enabled only forward seeking
+ */
+static off_t rip_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin) {
+ char buffer[SCRATCH_SIZE];
+ rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen;
+ uint32_t blocksize;
+ off_t toread, writed;
+
+ lprintf("seek, offset %lld, origin %d (curpos %lld)\n", offset, origin, this->curpos);
+
+ switch (origin) {
+ case SEEK_SET: toread = offset - this->curpos; break;
+ case SEEK_CUR: toread = offset; break;
+ default: toread = 0;
+ }
+
+ if (toread < 0) {
+ xprintf(this->stream->xine, XINE_VERBOSITY_LOG,
+ "cannot seek back (%lld bytes)\n", -toread);
+ return -1;
+ }
+
+ if( this_gen->get_capabilities(this_gen) & INPUT_CAP_BLOCK )
+ blocksize = this_gen->get_blocksize(this_gen);
+ else
+ blocksize = 1;
+
+ toread -= (toread % blocksize);
+
+ /* read/catch by sizeof(buffer) bytes */
+ while (toread > 0) {
+ if( blocksize > 1 ) {
+ buf_element_t *buf;
+
+ buf = rip_plugin_read_block(this_gen, this->stream->video_fifo, blocksize);
+ if (buf) {
+ writed = buf->size;
+ buf->free_buffer(buf);
+ } else {
+ toread = 0;
+ writed = 0;
+ }
+ } else {
+ writed = rip_plugin_read(this_gen, buffer, (toread > sizeof buffer) ? (sizeof buffer) : toread);
+ }
+
+ if (writed <= 0) {
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("input_rip: seeking failed\n"));
+ break;
+ }
+ toread -= writed;
+ }
+
+ lprintf(" => newpos %lld\n", this->curpos);
+
+ return this->curpos;
+}
+
+/*
+ * return current position,
+ * check values for debug build
+ */
+static off_t rip_plugin_get_current_pos(input_plugin_t *this_gen) {
+ rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen;
+#ifdef DEBUG
+ off_t pos;
+
+ pos = this->main_input_plugin->get_current_pos(this->main_input_plugin);
+ if (pos != this->curpos) {
+ lprintf("position: computed = %lld, input plugin = %lld\n", this->curpos, pos);
+ }
+#endif
+
+ return this->curpos;
+}
+
+static off_t rip_plugin_get_length (input_plugin_t *this_gen) {
+ rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen;
+
+ return this->main_input_plugin->get_length(this->main_input_plugin);
+}
+
+static uint32_t rip_plugin_get_blocksize(input_plugin_t *this_gen) {
+ rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen;
+
+ return this->main_input_plugin->get_blocksize(this->main_input_plugin);
+}
+
+static char* rip_plugin_get_mrl (input_plugin_t *this_gen) {
+ rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen;
+
+ return this->main_input_plugin->get_mrl(this->main_input_plugin);
+}
+
+static int rip_plugin_get_optional_data (input_plugin_t *this_gen,
+ void *data, int data_type) {
+ rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen;
+
+ lprintf("get optional data\n");
+ if (this->preview && data_type == INPUT_OPTIONAL_DATA_PREVIEW) {
+ memcpy(data, this->preview, this->preview_size);
+ return this->preview_size;
+ } else
+ return this->main_input_plugin->get_optional_data(
+ this->main_input_plugin, data, data_type);
+}
+
+/*
+ * dispose main input plugin and self
+ */
+static void rip_plugin_dispose(input_plugin_t *this_gen) {
+ rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen;
+
+ lprintf("rip_plugin_dispose\n");
+
+ this->main_input_plugin->dispose(this->main_input_plugin);
+ if (this->file) fclose(this->file);
+ if (this->preview) free(this->preview);
+ free(this);
+}
+
+/*
+ * create self instance,
+ * target file for writing stream is specified in 'data'
+ */
+input_plugin_t *rip_plugin_get_instance (xine_stream_t *stream, const char *filename) {
+ rip_input_plugin_t *this;
+ input_plugin_t *main_plugin = stream->input_plugin;
+
+ lprintf("rip_plugin_get_instance(catch file = %s)\n", filename ? filename : "(null)");
+
+ /* check given input plugin */
+ if (!stream->input_plugin) {
+ xine_log(stream->xine, XINE_LOG_MSG,
+ _("input_rip: input plugin not defined!\n"));
+ return NULL;
+ }
+
+ if ( main_plugin->get_capabilities(main_plugin) & INPUT_CAP_RIP_FORBIDDEN ) {
+ xine_log(stream->xine, XINE_LOG_MSG,
+ _("input_rip: ripping/caching is not permitted!\n"));
+ return NULL;
+ }
+
+ if (!filename || !filename[0]) {
+ xine_log(stream->xine, XINE_LOG_MSG,
+ _("input_rip: file name not given!\n"));
+ return NULL;
+ }
+
+ this = (rip_input_plugin_t *)xine_xmalloc(sizeof(rip_input_plugin_t));
+ this->main_input_plugin = main_plugin;
+ this->stream = stream;
+ this->curpos = 0;
+
+ if ((this->file = fopen(filename, "wb")) == NULL) {
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("input_rip: error opening file %s: %s\n"),
+ filename, strerror(errno));
+ free(this);
+ return NULL;
+ }
+
+ /* fill preview memory */
+ if ( main_plugin->get_capabilities(main_plugin) & INPUT_CAP_BLOCK ) {
+ buf_element_t *buf;
+ uint32_t blocksize;
+
+ blocksize = main_plugin->get_blocksize(main_plugin);
+ buf = main_plugin->read_block(main_plugin, stream->video_fifo, blocksize);
+
+ this->preview_size = buf->size;
+ this->preview = malloc(this->preview_size);
+ memcpy(this->preview, buf->content, this->preview_size);
+
+ buf->free_buffer(buf);
+ } else {
+ this->preview = malloc(MAX_PREVIEW_SIZE);
+ this->preview_size = main_plugin->read(main_plugin, this->preview, MAX_PREVIEW_SIZE);
+ }
+
+ if (this->file && this->preview && this->preview_size) {
+ if (fwrite(this->preview, this->preview_size, 1, this->file) != 1) {
+ xine_log(this->stream->xine, XINE_LOG_MSG,
+ _("input_rip: error writing to file %lld bytes: %s\n"),
+ this->preview_size, strerror(errno));
+ fclose(this->file);
+ free(this);
+ return NULL;
+ }
+ }
+
+
+ this->input_plugin.open = rip_plugin_open;
+ this->input_plugin.get_capabilities = rip_plugin_get_capabilities;
+ this->input_plugin.read = rip_plugin_read;
+ this->input_plugin.read_block = rip_plugin_read_block;
+ this->input_plugin.seek = rip_plugin_seek;
+ this->input_plugin.get_current_pos = rip_plugin_get_current_pos;
+ this->input_plugin.get_length = rip_plugin_get_length;
+ this->input_plugin.get_blocksize = rip_plugin_get_blocksize;
+ this->input_plugin.get_mrl = rip_plugin_get_mrl;
+ this->input_plugin.get_optional_data = rip_plugin_get_optional_data;
+ this->input_plugin.dispose = rip_plugin_dispose;
+ this->input_plugin.input_class = main_plugin->input_class;
+
+ return &this->input_plugin;
+}
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index eb3e03f7f..5eaab21a1 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine.c,v 1.253 2003/08/15 14:35:09 mroi Exp $
+ * $Id: xine.c,v 1.254 2003/08/21 00:37:29 miguelfreitas Exp $
*/
/*
@@ -576,6 +576,44 @@ static int xine_open_internal (xine_stream_t *stream, const char *mrl) {
}
continue;
}
+ if (strncasecmp(stream_setup, "rip", 3) == 0) {
+ if (*(stream_setup += 3) == ':') {
+ /* filename to rip */
+ const char *tmp = ++stream_setup;
+ char *filename;
+ input_plugin_t *input_rip;
+
+ stream_setup = strchr(stream_setup, ';');
+ if (stream_setup) {
+ filename = (char *)malloc(stream_setup - tmp + 1);
+ memcpy(filename, tmp, stream_setup - tmp);
+ filename[stream_setup - tmp] = '\0';
+ } else {
+ filename = (char *)malloc(strlen(tmp));
+ memcpy(filename, tmp, strlen(tmp));
+ filename[strlen(tmp)] = '\0';
+ }
+
+ xine_log(stream->xine, XINE_LOG_MSG,
+ _("xine: join rip input plugin\n"));
+ input_rip = rip_plugin_get_instance (stream, filename);
+ if( input_rip ) {
+ stream->input_plugin = input_rip;
+ } else {
+ printf("xine: error opening rip plugin instance\n");
+ stream->err = XINE_ERROR_MALFORMED_MRL;
+ stream->status = XINE_STATUS_STOP;
+ return 0;
+ }
+
+ } else {
+ printf("xine: error while parsing mrl\n");
+ stream->err = XINE_ERROR_MALFORMED_MRL;
+ stream->status = XINE_STATUS_STOP;
+ return 0;
+ }
+ continue;
+ }
if (strncasecmp(stream_setup, "lastdemuxprobe", 14) == 0) {
if (*(stream_setup += 14) == ':') {
/* all demuxers will be probed before the specified one */
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 2610288f3..c0c92b7a9 100644
--- a/src/xine-engine/xine_internal.h
+++ b/src/xine-engine/xine_internal.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_internal.h,v 1.138 2003/05/20 13:50:57 mroi Exp $
+ * $Id: xine_internal.h,v 1.139 2003/08/21 00:37:29 miguelfreitas Exp $
*
*/
@@ -289,6 +289,7 @@ input_plugin_t *find_input_plugin (xine_stream_t *stream, const char *mrl);
demux_plugin_t *find_demux_plugin (xine_stream_t *stream, input_plugin_t *input);
demux_plugin_t *find_demux_plugin_by_name (xine_stream_t *stream, const char *name, input_plugin_t *input);
demux_plugin_t *find_demux_plugin_last_probe(xine_stream_t *stream, const char *last_demux_name, input_plugin_t *input);
+input_plugin_t *rip_plugin_get_instance (xine_stream_t *stream, const char *filename);
/* create decoder fifos and threads */