summaryrefslogtreecommitdiff
path: root/input_pps.c
diff options
context:
space:
mode:
authorLuo Jinghua <sunmoon1997@gmail.com>2009-09-02 15:10:53 +0800
committerLuo Jinghua <sunmoon1997@gmail.com>2009-09-02 15:10:53 +0800
commit4cf9ceff200476e001737d56ad9ba3f4690d87a5 (patch)
tree9ad4fad80d6555b0b01db9700b15c9f2d522ba70 /input_pps.c
Initial commit of xine-ppsHEADmaster
Diffstat (limited to 'input_pps.c')
-rw-r--r--input_pps.c338
1 files changed, 338 insertions, 0 deletions
diff --git a/input_pps.c b/input_pps.c
new file mode 100644
index 0000000..7de012d
--- /dev/null
+++ b/input_pps.c
@@ -0,0 +1,338 @@
+/*
+ * Copyright (C) 2009 Luo Jinghua<sunmoon1997@gmail.com>
+ *
+ * PPStream plugin for xine
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
+ *
+ * pps input plugin
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#define LOG_MODULE "input_pps"
+#define LOG_VERBOSE
+/*
+#define LOG
+*/
+
+#include <xine/xine_internal.h>
+#include <xine/xineutils.h>
+#include <xine/input_plugin.h>
+
+#include "pps-fixed.h"
+
+#ifndef EXPORTED
+#define EXPORTED
+#endif
+
+typedef struct {
+
+ input_class_t input_class;
+
+ xine_t *xine;
+} pps_input_class_t;
+
+typedef struct {
+ input_plugin_t input_plugin;
+
+ int fd;
+ int size;
+
+ xine_stream_t *stream;
+
+ char *mrl;
+
+ off_t curpos;
+} pps_input_plugin_t;
+
+
+static off_t pps_plugin_read (input_plugin_t *this_gen,
+ char *buf, off_t len) {
+ pps_input_plugin_t *this = (pps_input_plugin_t *) this_gen;
+ int ret;
+
+ lprintf ("pps_plugin_read: %"PRId64" bytes ...\n", len);
+
+ while (1) {
+ struct timeval tv;
+ int error;
+
+ tv.tv_sec = 0;
+ tv.tv_usec = 500000;
+ ret = ppsvod_read(this->fd, buf, len,
+ this->curpos, &tv);
+ error = errno;
+ if (ret >= 0)
+ break;
+ if (error != EAGAIN)
+ return -1;
+ usleep (5000);
+ }
+
+ if (ret > 0)
+ this->curpos += ret;
+
+ return ret;
+}
+
+static buf_element_t *pps_plugin_read_block (input_plugin_t *this_gen,
+ fifo_buffer_t *fifo, off_t todo) {
+ /*pps_input_plugin_t *this = (pps_input_plugin_t *) this_gen; */
+ buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
+ int total_bytes;
+
+ lprintf ("pps_plugin_read_block: %"PRId64" bytes...\n", todo);
+
+ if (todo > buf->max_size)
+ todo = buf->max_size;
+ if (todo < 0) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
+ buf->content = buf->mem;
+ buf->type = BUF_DEMUX_BLOCK;
+
+ total_bytes = pps_plugin_read (this_gen, (char*)buf->content, todo);
+
+ if (total_bytes != todo) {
+ buf->free_buffer (buf);
+ return NULL;
+ }
+
+ buf->size = total_bytes;
+
+ return buf;
+}
+
+static off_t pps_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) {
+
+ pps_input_plugin_t *this = (pps_input_plugin_t *) this_gen;
+ int ret;
+
+ lprintf ("seek %"PRId64" bytes, origin %d\n", offset, origin);
+
+ /* only realtive forward-seeking is implemented */
+
+ if (origin == SEEK_CUR) {
+ offset += this->curpos;
+ } else if (origin == SEEK_END) {
+ if (this->size == -1)
+ return -1;
+ offset = this->size - offset;
+ }
+ ret = ppsvod_seek (this->fd, offset);
+ if (ret < 0) {
+ return -1;
+ }
+
+ this->curpos = offset;
+ return this->curpos;
+}
+
+static off_t pps_plugin_get_length (input_plugin_t *this_gen) {
+
+ pps_input_plugin_t *this = (pps_input_plugin_t *) this_gen;
+
+ if (this->size == -1)
+ this->size = ppsvod_get_file_length(this->fd);
+ return this->size;
+}
+
+static uint32_t pps_plugin_get_capabilities (input_plugin_t *this_gen) {
+ return INPUT_CAP_SEEKABLE;
+}
+
+static uint32_t pps_plugin_get_blocksize (input_plugin_t *this_gen) {
+ return 0;
+}
+
+static off_t pps_plugin_get_current_pos (input_plugin_t *this_gen){
+ pps_input_plugin_t *this = (pps_input_plugin_t *) this_gen;
+
+ /*
+ printf ("current pos is %"PRId64"\n", this->curpos);
+ */
+
+ return this->curpos;
+}
+
+static int pps_plugin_event_callback (int index, pps_event event)
+{
+ return 0;
+}
+
+static void pps_plugin_dispose (input_plugin_t *this_gen) {
+ pps_input_plugin_t *this = (pps_input_plugin_t *) this_gen;
+
+ if (this->fd >= 0) {
+ ppsvod_stop_item(this->fd);
+ ppsvod_remove_item(this->fd);
+ this->fd = -1;
+ }
+
+ if(this->mrl)
+ free(this->mrl);
+
+ ppsvod_destroy();
+
+ free (this);
+}
+
+static const char* pps_plugin_get_mrl (input_plugin_t *this_gen) {
+ pps_input_plugin_t *this = (pps_input_plugin_t *) this_gen;
+
+ return this->mrl;
+}
+
+static int pps_plugin_get_optional_data (input_plugin_t *this_gen,
+ void *data, int data_type) {
+#if 0
+ pps_input_plugin_t *this = (pps_input_plugin_t *) this_gen;
+
+ switch (data_type) {
+ case INPUT_OPTIONAL_DATA_PREVIEW:
+ break;
+ }
+#endif
+
+ return INPUT_OPTIONAL_UNSUPPORTED;
+}
+
+static int pps_plugin_open (input_plugin_t *this_gen) {
+ pps_input_plugin_t *this = (pps_input_plugin_t *) this_gen;
+
+ int ret;
+
+ lprintf ("trying to open '%s'\n", this->mrl);
+
+ if (ppsvod_create("ppstream", "demo", "ppsdemo001",
+ pps_plugin_event_callback) < 0) {
+ lprintf ("Failed to initialize ppsvod.\n");
+ return 0;
+ }
+
+ ret = ppsvod_add_item(this->mrl, 0);
+ if (ret < 0) {
+ lprintf ("Failed to open url.\n");
+
+ ppsvod_destroy();
+ return 0;
+ }
+ this->fd = ret;
+
+ ret = ppsvod_play_item(this->fd, NULL);
+ if (ret < 0) {
+ lprintf ("Failed to play url.\n");
+
+ ppsvod_remove_item(this->fd);
+ ppsvod_destroy();
+ return 0;
+ }
+ this->size = ppsvod_get_file_length(this->fd);
+
+ return 1;
+}
+
+static input_plugin_t *pps_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream,
+ const char *mrl) {
+
+ /* pps_input_class_t *cls = (pps_input_class_t *) cls_gen; */
+ pps_input_plugin_t *this;
+
+ if (strncasecmp (mrl, "pps://", 6) &&
+ strncasecmp (mrl, "tvod://", 7))
+ return NULL;
+
+ this = calloc(1, sizeof (pps_input_plugin_t));
+
+ this->stream = stream;
+ this->fd = -1;
+ this->mrl = strdup (mrl);
+
+ this->input_plugin.open = pps_plugin_open;
+ this->input_plugin.get_capabilities = pps_plugin_get_capabilities;
+ this->input_plugin.read = pps_plugin_read;
+ this->input_plugin.read_block = pps_plugin_read_block;
+ this->input_plugin.seek = pps_plugin_seek;
+ this->input_plugin.get_current_pos = pps_plugin_get_current_pos;
+ this->input_plugin.get_length = pps_plugin_get_length;
+ this->input_plugin.get_blocksize = pps_plugin_get_blocksize;
+ this->input_plugin.get_mrl = pps_plugin_get_mrl;
+ this->input_plugin.dispose = pps_plugin_dispose;
+ this->input_plugin.get_optional_data = pps_plugin_get_optional_data;
+ this->input_plugin.input_class = cls_gen;
+
+ return &this->input_plugin;
+}
+
+/*
+ * pps input plugin class stuff
+ */
+
+static const char *pps_class_get_description (input_class_t *this_gen) {
+ return _("pps streaming input plugin");
+}
+
+static const char *pps_class_get_identifier (input_class_t *this_gen) {
+ return "pps";
+}
+
+static void pps_class_dispose (input_class_t *this_gen) {
+ pps_input_class_t *this = (pps_input_class_t *) this_gen;
+
+ free (this);
+}
+
+static void *init_class (xine_t *xine, void *data) {
+
+ pps_input_class_t *this;
+
+ this = calloc(1, sizeof (pps_input_class_t));
+
+ this->xine = xine;
+
+ this->input_class.get_instance = pps_class_get_instance;
+ this->input_class.get_identifier = pps_class_get_identifier;
+ this->input_class.get_description = pps_class_get_description;
+ this->input_class.get_dir = NULL;
+ this->input_class.get_autoplay_list = NULL;
+ this->input_class.dispose = pps_class_dispose;
+ this->input_class.eject_media = NULL;
+
+ return this;
+}
+
+/*
+ * exported plugin catalog entry
+ */
+
+const plugin_info_t xine_plugin_info[] EXPORTED = {
+ /* type, API, "name", version, special_info, init_function */
+ { PLUGIN_INPUT, 17, "pps", XINE_VERSION_CODE, NULL, init_class },
+ { PLUGIN_NONE, 0, "", 0, NULL, NULL }
+};
+