diff options
Diffstat (limited to 'src/input/input_mms.c')
-rw-r--r-- | src/input/input_mms.c | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/src/input/input_mms.c b/src/input/input_mms.c new file mode 100644 index 000000000..421508906 --- /dev/null +++ b/src/input/input_mms.c @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2000-2002 major mms + * + * This file is part of xine-mms + * + * xine-mms 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-mms 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 + * + * input plugin for mms network streams + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <unistd.h> +#include <stdio.h> +#include <assert.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netdb.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "bswap.h" + +#include "xine_internal.h" +#include "xineutils.h" +#include "input_plugin.h" + +#include "mms.h" +#include "strict_scr.h" + +/* +#define LOG +*/ + +extern int errno; + +#if !defined(NDELAY) && defined(O_NDELAY) +#define FNDELAY O_NDELAY +#endif + + +typedef struct { + input_plugin_t input_plugin; + + xine_t *xine; + config_values_t *config; + + mms_t *mms; + + char *mrl; + + off_t curpos; + + int buffering; + + strictscr_t *scr; + + char scratch[1025]; + +} mms_input_plugin_t; + + +static int mms_plugin_open (input_plugin_t *this_gen, char *mrl) { + + char* nmrl=NULL; + mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; + + + asx_parse(mrl,&nmrl); + + if(!nmrl) + nmrl=mrl; + + printf("mms_plugin_open: using mrl <%s> \n", nmrl); + if (strncasecmp (nmrl, "mms://",6)) + return 0; + + this->mrl = strdup(nmrl); /* FIXME: small memory leak */ + + this->mms = mms_connect (nmrl); + + if (!this->mms) + return 0; + + this->curpos = 0; + this->buffering = 0; + + /* register our scr plugin */ + + this->scr->scr.start (&this->scr->scr, this->xine->metronom->get_current_time (this->xine->metronom)); + this->xine->metronom->register_scr (this->xine->metronom, &this->scr->scr); + + return 1; +} + +#define LOW_WATER_MARK 50 +#define HIGH_WATER_MARK 100 + +static off_t mms_plugin_read (input_plugin_t *this_gen, + char *buf, off_t len) { + mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; + off_t n; + int fifo_fill; + +#ifdef LOG + printf ("mms_plugin_read: %lld bytes ...\n", + len); +#endif + + fifo_fill = this->xine->video_fifo->size(this->xine->video_fifo); + + if (fifo_fill<LOW_WATER_MARK) { + + this->xine->metronom->set_speed (this->xine->metronom, SPEED_PAUSE); + this->buffering = 1; + this->scr->adjustable = 0; + printf ("input_mms: buffering (%d/%d)...\n", fifo_fill, LOW_WATER_MARK); + + } else if ( (fifo_fill>HIGH_WATER_MARK) && (this->buffering)) { + this->xine->metronom->set_speed (this->xine->metronom, SPEED_NORMAL); + this->buffering = 0; + this->scr->adjustable = 1; + printf ("input_mms: buffering...done\n"); + } + + n = mms_read (this->mms, buf, len); + this->curpos += n; + + return n; +} + +static buf_element_t *mms_plugin_read_block (input_plugin_t *this_gen, + fifo_buffer_t *fifo, off_t todo) { + /*mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; */ + buf_element_t *buf = fifo->buffer_pool_alloc (fifo); + int total_bytes; + +#ifdef LOG + printf ("mms_plugin_read_block: %lld bytes...\n", + todo); +#endif + + buf->content = buf->mem; + buf->type = BUF_DEMUX_BLOCK; + + total_bytes = mms_plugin_read (this_gen, buf->content, todo); + + if (total_bytes != todo) { + buf->free_buffer (buf); + return NULL; + } + + buf->size = total_bytes; + + return buf; +} + +static off_t mms_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { + + mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; + + off_t dest = this->curpos; + +#ifdef LOG + printf ("mms_plugin_seek: %lld offset, %d origin...\n", + offset, origin); +#endif + + switch (origin) { + case SEEK_SET: + dest = offset; + break; + case SEEK_CUR: + dest = this->curpos + offset; + break; + case SEEK_END: + printf ("input_mms: SEEK_END not implemented!\n"); + return this->curpos; + default: + printf ("input_mms: unknown origin in seek!\n"); + return this->curpos; + } + + if (this->curpos > dest) { + printf ("input_mms: cannot seek back!\n"); + return this->curpos; + } + + while (this->curpos<dest) { + + int n, diff; + + diff = dest - this->curpos; + + if (diff>1024) + diff = 1024; + + n = mms_read (this->mms, this->scratch, diff); + this->curpos += n; + if (n<diff) + return this->curpos; + } + + return this->curpos; +} + +static off_t mms_plugin_get_length (input_plugin_t *this_gen) { + + mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; + + off_t length; + + if (!this->mms) + return 0; + + length = mms_get_length (this->mms); + +#ifdef LOG + printf ("input_mms: length is %lld\n", length); +#endif + + return length; + +} + +static uint32_t mms_plugin_get_capabilities (input_plugin_t *this_gen) { + + return INPUT_CAP_NOCAP; +} + +static uint32_t mms_plugin_get_blocksize (input_plugin_t *this_gen) { + + return 0; +; +} + +static off_t mms_plugin_get_current_pos (input_plugin_t *this_gen){ + mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; + + /* + printf ("current pos is %lld\n", this->curpos); + */ + + return this->curpos; +} + +static int mms_plugin_eject_media (input_plugin_t *this_gen) { + return 1; +} + + +static void mms_plugin_close (input_plugin_t *this_gen) { + mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; + + if (this->mms) { + mms_close (this->mms); + this->mms = NULL; + } + + this->xine->metronom->unregister_scr (this->xine->metronom, &this->scr->scr); +} + +static void mms_plugin_stop (input_plugin_t *this_gen) { + + mms_plugin_close(this_gen); +} + +static char *mms_plugin_get_description (input_plugin_t *this_gen) { + return "mms input plugin"; +} + +static char *mms_plugin_get_identifier (input_plugin_t *this_gen) { + return "MMS"; +} + +static char* mms_plugin_get_mrl (input_plugin_t *this_gen) { + mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; + + return this->mrl; +} + +static int mms_plugin_get_optional_data (input_plugin_t *this_gen, + void *data, int data_type) { + + return INPUT_OPTIONAL_UNSUPPORTED; +} + + +input_plugin_t *init_input_plugin (int iface, xine_t *xine) { + + mms_input_plugin_t *this; + config_values_t *config; + + if (iface != 5) { + printf ("mms input plugin doesn't support plugin API version %d.\n" + "PLUGIN DISABLED.\n" + "This means there's a version mismatch between xine and this input" + "plugin.\nInstalling current input plugins should help.\n", + iface); + return NULL; + } + + this = (mms_input_plugin_t *) malloc (sizeof (mms_input_plugin_t)); + config = xine->config; + this->xine = xine; + + this->input_plugin.interface_version = INPUT_PLUGIN_IFACE_VERSION; + this->input_plugin.get_capabilities = mms_plugin_get_capabilities; + this->input_plugin.open = mms_plugin_open; + this->input_plugin.read = mms_plugin_read; + this->input_plugin.read_block = mms_plugin_read_block; + this->input_plugin.seek = mms_plugin_seek; + this->input_plugin.get_current_pos = mms_plugin_get_current_pos; + this->input_plugin.get_length = mms_plugin_get_length; + this->input_plugin.get_blocksize = mms_plugin_get_blocksize; + this->input_plugin.get_dir = NULL; + this->input_plugin.eject_media = mms_plugin_eject_media; + this->input_plugin.get_mrl = mms_plugin_get_mrl; + this->input_plugin.close = mms_plugin_close; + this->input_plugin.stop = mms_plugin_stop; + this->input_plugin.get_description = mms_plugin_get_description; + this->input_plugin.get_identifier = mms_plugin_get_identifier; + this->input_plugin.get_autoplay_list = NULL; + this->input_plugin.get_optional_data = mms_plugin_get_optional_data; + this->input_plugin.is_branch_possible= NULL; + + this->mrl = NULL; + this->config = config; + this->curpos = 0; + this->buffering = 0; + + this->scr = strictscr_init (); + + return &this->input_plugin; +} |