summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/demuxers/demux_ts.c50
-rw-r--r--src/input/Makefile.am9
-rw-r--r--src/input/input_dvb.c865
-rw-r--r--src/input/ost/Makefile.am22
-rw-r--r--src/input/ost/README9
-rw-r--r--src/input/ost/ca.h84
-rw-r--r--src/input/ost/demux.h346
-rw-r--r--src/input/ost/dmx.h141
-rw-r--r--src/input/ost/frontend.h208
-rw-r--r--src/input/ost/sec.h118
-rw-r--r--src/xine-engine/audio_decoder.c18
-rw-r--r--src/xine-engine/xine.c4
12 files changed, 1860 insertions, 14 deletions
diff --git a/src/demuxers/demux_ts.c b/src/demuxers/demux_ts.c
index e4ef198ef..9cc331830 100644
--- a/src/demuxers/demux_ts.c
+++ b/src/demuxers/demux_ts.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: demux_ts.c,v 1.71 2002/12/21 12:56:46 miguelfreitas Exp $
+ * $Id: demux_ts.c,v 1.72 2002/12/27 00:53:49 guenter Exp $
*
* Demultiplexer for MPEG2 Transport Streams.
*
@@ -139,8 +139,7 @@
#include "xine_internal.h"
#include "xineutils.h"
#include "demux.h"
-
-#define VALID_MRLS "fifo,stdin,dvb,tcp"
+#include "events.h"
/*
#define TS_LOG
@@ -285,6 +284,9 @@ typedef struct {
demux_ts_spu_lang spu_langs[MAX_NO_SPU_LANGS];
int no_spu_langs;
int current_spu_channel;
+
+ /* dvb */
+ xine_event_queue_t *event_queue;
} demux_ts_t;
typedef struct {
@@ -1597,6 +1599,33 @@ static void demux_ts_parse_packet (demux_ts_t*this) {
}
}
+/*
+ * check for pids change events
+ */
+
+static void demux_ts_event_handler (demux_ts_t *this) {
+
+ xine_event_t *event;
+
+ while ((event = xine_event_get (this->event_queue))) {
+
+
+ switch (event->type) {
+
+ case XINE_EVENT_PIDS_CHANGE:
+
+ this->videoPid = INVALID_PID;
+ this->audioPid = INVALID_PID;
+ this->media_num = 0;
+ this->send_newpts = 1;
+
+ break;
+
+ }
+
+ xine_event_free (event);
+ }
+}
/*
* send a piece of data down the fifos
@@ -1606,14 +1635,15 @@ static int demux_ts_send_chunk (demux_plugin_t *this_gen) {
demux_ts_t*this = (demux_ts_t*)this_gen;
+ demux_ts_event_handler (this);
+
demux_ts_parse_packet(this);
/* DVBSUB: check if channel has changed. Dunno if I should, or
* even could, lock the xine object. */
- if (this->stream->spu_channel != this->current_spu_channel)
- {
- demux_ts_update_spu_channel(this);
- }
+ if (this->stream->spu_channel != this->current_spu_channel) {
+ demux_ts_update_spu_channel(this);
+ }
return this->status;
}
@@ -1629,6 +1659,9 @@ static void demux_ts_dispose (demux_plugin_t *this_gen) {
if (this->media[i].buf != NULL)
this->media[i].buf->free_buffer(this->media[i].buf);
}
+
+ xine_event_dispose_queue (this->event_queue);
+
free(this_gen);
}
@@ -1953,6 +1986,9 @@ static demux_plugin_t *open_plugin (demux_class_t *class_gen,
this->spu_pid = INVALID_PID;
this->no_spu_langs = 0;
this->current_spu_channel = this->stream->spu_channel;
+
+ /* dvb */
+ this->event_queue = xine_event_new_queue (this->stream);
return &this->demux_plugin;
}
diff --git a/src/input/Makefile.am b/src/input/Makefile.am
index d19cf63e5..1304163ab 100644
--- a/src/input/Makefile.am
+++ b/src/input/Makefile.am
@@ -3,9 +3,9 @@
##
if HAVE_DVDNAV
-SUBDIRS = libreal librtsp libdvdread
+SUBDIRS = ost libreal librtsp libdvdread
else
-SUBDIRS = libreal librtsp libdvdread libdvdnav
+SUBDIRS = ost libreal librtsp libdvdread libdvdnav
endif
LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic
@@ -48,6 +48,7 @@ lib_LTLIBRARIES = \
$(in_vcd) \
xineplug_inp_mms.la \
xineplug_inp_stdin_fifo.la \
+ xineplug_inp_dvb.la \
xineplug_inp_pnm.la \
xineplug_inp_rtsp.la \
xineplug_inp_net.la
@@ -104,6 +105,10 @@ xineplug_inp_pnm_la_SOURCES = input_pnm.c net_buf_ctrl.c pnm.c
xineplug_inp_pnm_la_LIBADD = $(XINE_LIB)
xineplug_inp_pnm_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
+xineplug_inp_dvb_la_SOURCES = input_dvb.c net_buf_ctrl.c
+xineplug_inp_dvb_la_LIBADD = $(XINE_LIB)
+xineplug_inp_dvb_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
+
xineplug_inp_rtsp_la_SOURCES = input_rtsp.c net_buf_ctrl.c
xineplug_inp_rtsp_la_LIBADD = $(XINE_LIB) libreal/libreal.la librtsp/librtsp.la
xineplug_inp_rtsp_la_LDFLAGS = -avoid-version -module @XINE_PLUGIN_MIN_SYMS@
diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c
new file mode 100644
index 000000000..12ad6dd09
--- /dev/null
+++ b/src/input/input_dvb.c
@@ -0,0 +1,865 @@
+/*
+ * Copyright (C) 2000-2002 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
+ *
+ *
+ * input plugin for Digital TV (Digital Video Broadcast - DVB) devices
+ * e.g. Hauppauge WinTV Nova supported by DVB drivers from Convergence
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <sys/poll.h>
+
+#include "ost/dmx.h"
+#include "ost/sec.h"
+#include "ost/frontend.h"
+
+#include "xine_internal.h"
+#include "xineutils.h"
+#include "events.h"
+#include "input_plugin.h"
+#include "net_buf_ctrl.h"
+
+/*
+#define LOG
+*/
+
+extern int errno;
+
+#define FRONTEND_DEVICE "/dev/ost/frontend"
+#define SEC_DEVICE "/dev/ost/sec"
+#define DEMUX_DEVICE "/dev/ost/demux"
+#define DVR_DEVICE "/dev/ost/dvr"
+
+#define BUFSIZE 4096
+
+#define NOPID 0xffff
+
+typedef struct {
+ int fd_frontend;
+ int fd_sec;
+ int fd_demuxa, fd_demuxv, fd_demuxtt;
+
+ FrontendInfo feinfo;
+ FrontendParameters front_param;
+
+ struct secCommand scmd;
+ struct secCmdSequence scmds;
+ struct dmxPesFilterParams pesFilterParamsV;
+ struct dmxPesFilterParams pesFilterParamsA;
+ struct dmxPesFilterParams pesFilterParamsTT;
+
+} tuner_t;
+
+typedef struct {
+
+ char *name;
+ int freq; /* freq - lof */
+ int tone; /* SEC_TONE_ON/OFF */
+ int volt; /* SC_VOLTAGE_13/18 */
+ int diseqcnr;
+ int srate;
+ int fec;
+ int vpid;
+ int apid;
+
+} channel_t;
+
+typedef struct {
+
+ input_class_t input_class;
+
+ xine_t *xine;
+
+ char *mrls[2];
+
+} dvb_input_class_t;
+
+typedef struct {
+ input_plugin_t input_plugin;
+
+ dvb_input_class_t *cls;
+
+ xine_stream_t *stream;
+
+ char *mrl;
+
+ off_t curpos;
+
+ nbc_t *nbc;
+
+ tuner_t *tuner;
+ channel_t *channels;
+ int fd;
+ int num_channels;
+ int channel;
+ pthread_mutex_t mutex;
+
+ osd_object_t *osd;
+
+ xine_event_queue_t *event_queue;
+
+ /* scratch buffer for forward seeking */
+ char seek_buf[BUFSIZE];
+
+ int out_fd; /* recording function */
+
+} dvb_input_plugin_t;
+
+
+static tuner_t *tuner_init () {
+
+ tuner_t *this;
+
+ this = malloc (sizeof (tuner_t));
+
+ if ((this->fd_frontend = open(FRONTEND_DEVICE, O_RDWR)) < 0){
+ perror("FRONTEND DEVICE: ");
+ free (this);
+ return NULL;
+ }
+
+ ioctl (this->fd_frontend, FE_GET_INFO, &this->feinfo);
+ if (this->feinfo.type==FE_QPSK) {
+
+ if ((this->fd_sec = open (SEC_DEVICE, O_RDWR)) < 0) {
+ perror ("SEC DEVICE: ");
+ free (this);
+ return NULL;
+ }
+ }
+
+ this->fd_demuxtt = open (DEMUX_DEVICE, O_RDWR);
+ if (this->fd_demuxtt < 0) {
+ perror ("DEMUX DEVICE tt: ");
+ free (this);
+ return NULL;
+ }
+
+ this->fd_demuxa = open (DEMUX_DEVICE, O_RDWR);
+ if (this->fd_demuxa < 0) {
+ perror ("DEMUX DEVICE audio: ");
+ free (this);
+ return NULL;
+ }
+
+ this->fd_demuxv=open (DEMUX_DEVICE, O_RDWR);
+ if (this->fd_demuxv < 0) {
+ perror ("DEMUX DEVICE video: ");
+ free (this);
+ return NULL;
+ }
+
+ return this;
+}
+
+static void tuner_dispose (tuner_t *this) {
+
+ close (this->fd_frontend);
+ close (this->fd_sec);
+ close (this->fd_demuxa);
+ close (this->fd_demuxv);
+ close (this->fd_demuxtt);
+
+ free (this);
+}
+
+static void tuner_set_vpid (tuner_t *this, ushort vpid) {
+
+ if (vpid==0 || vpid==NOPID || vpid==0x1fff) {
+ ioctl (this->fd_demuxv, DMX_STOP, 0);
+ return;
+ }
+
+ this->pesFilterParamsV.pid = vpid;
+ this->pesFilterParamsV.input = DMX_IN_FRONTEND;
+ this->pesFilterParamsV.output = DMX_OUT_TS_TAP;
+ this->pesFilterParamsV.pesType = DMX_PES_VIDEO;
+ this->pesFilterParamsV.flags = DMX_IMMEDIATE_START;
+ if (ioctl(this->fd_demuxv, DMX_SET_PES_FILTER,
+ &this->pesFilterParamsV) < 0)
+ perror("set_vpid");
+}
+
+static void tuner_set_apid (tuner_t *this, ushort apid) {
+ if (apid==0 || apid==NOPID || apid==0x1fff) {
+ ioctl (this->fd_demuxa, DMX_STOP, apid);
+ return;
+ }
+
+ this->pesFilterParamsA.pid = apid;
+ this->pesFilterParamsA.input = DMX_IN_FRONTEND;
+ this->pesFilterParamsA.output = DMX_OUT_TS_TAP;
+ this->pesFilterParamsA.pesType = DMX_PES_AUDIO;
+ this->pesFilterParamsA.flags = DMX_IMMEDIATE_START;
+ if (ioctl (this->fd_demuxa, DMX_SET_PES_FILTER,
+ &this->pesFilterParamsA) < 0)
+ perror("set_apid");
+}
+
+static void tuner_set_ttpid (tuner_t *this, ushort ttpid) {
+
+ if (ttpid==0 || ttpid== NOPID || ttpid==0x1fff) {
+ ioctl (this->fd_demuxtt, DMX_STOP, 0);
+ return;
+ }
+ this->pesFilterParamsTT.pid = ttpid;
+ this->pesFilterParamsTT.input = DMX_IN_FRONTEND;
+ this->pesFilterParamsTT.output = DMX_OUT_DECODER;
+ this->pesFilterParamsTT.pesType = DMX_PES_TELETEXT;
+ this->pesFilterParamsTT.flags = DMX_IMMEDIATE_START;
+ if (ioctl(this->fd_demuxtt, DMX_SET_PES_FILTER,
+ &this->pesFilterParamsTT) < 0) {
+ /* printf("PID=%04x\n", ttpid); */
+ perror("set_ttpid");
+ }
+}
+
+static void tuner_get_front (tuner_t *this) {
+ tuner_set_vpid (this, 0);
+ tuner_set_apid (this, 0);
+ tuner_set_ttpid(this, 0);
+ this->scmds.voltage = SEC_VOLTAGE_13;
+ this->scmds.miniCommand = SEC_MINI_NONE;
+ this->scmds.continuousTone = SEC_TONE_OFF;
+ this->scmds.numCommands = 1;
+ this->scmds.commands = &this->scmd;
+}
+
+static void tuner_set_diseqc_nr (tuner_t *this, int nr) {
+
+ this->scmd.type=0;
+ this->scmd.u.diseqc.addr = 0x10;
+ this->scmd.u.diseqc.cmd = 0x38;
+ this->scmd.u.diseqc.numParams = 1;
+ this->scmd.u.diseqc.params[0] = 0xF0 | ((nr * 4) & 0x0F) |
+ (this->scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
+ (this->scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
+}
+
+static void tuner_set_tp (tuner_t *this, int freq, int tone,
+ int volt, int diseqcnr,
+ int srate, int fec) {
+
+ static const uint8_t rfectab[9] = {1,2,3,0,4,0,5,0,0};
+
+ this->front_param.Frequency = freq;
+ this->scmds.continuousTone = tone;
+ this->scmds.voltage = volt;
+ tuner_set_diseqc_nr (this, diseqcnr);
+ this->front_param.u.qpsk.SymbolRate = srate;
+ this->front_param.u.qpsk.FEC_inner = (CodeRate)rfectab[fec];
+ this->front_param.Inversion = INVERSION_AUTO;
+}
+
+static int tuner_tune_it (tuner_t *this, FrontendParameters *front_param) {
+ FrontendEvent event;
+ struct pollfd pfd[1];
+
+ if (ioctl(this->fd_frontend, FE_SET_FRONTEND, front_param) <0)
+ perror("setfront front");
+
+ pfd[0].fd=this->fd_frontend;
+ pfd[0].events=POLLIN;
+ if (poll(pfd,1,2000)) {
+ if (pfd[0].revents & POLLIN){
+ if (ioctl(this->fd_frontend, FE_GET_EVENT, &event)
+ == -EBUFFEROVERFLOW){
+ perror("fe get event");
+ return 0;
+ }
+ switch(event.type){
+ case FE_UNEXPECTED_EV:
+ perror("unexpected event\n");
+ return 0;
+ case FE_FAILURE_EV:
+ perror("failure event\n");
+ return 0;
+
+ case FE_COMPLETION_EV:
+ fprintf(stderr, "completion event\n");
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+static int tuner_set_front (tuner_t *this) {
+ this->scmds.miniCommand = SEC_MINI_NONE;
+ this->scmds.numCommands=1;
+ this->scmds.commands=&this->scmd;
+
+ tuner_set_vpid (this, 0);
+ tuner_set_apid (this, 0);
+ tuner_set_ttpid(this,0);
+
+ if (this->feinfo.type==FE_QPSK) {
+ if (ioctl(this->fd_sec, SEC_SEND_SEQUENCE, &this->scmds) < 0)
+ perror("setfront sec");
+ usleep(70000);
+ }
+ return tuner_tune_it(this, &this->front_param);
+}
+
+static void print_channel (channel_t *channel) {
+
+ printf ("input_dvb: channel '%s' diseqc %d freq %d volt %d srate %d fec %d vpid %d apid %d\n",
+ channel->name,
+ channel->diseqcnr,
+ channel->freq,
+ channel->volt,
+ channel->srate,
+ channel->fec,
+ channel->vpid,
+ channel->apid);
+
+}
+
+
+static int tuner_set_channel (tuner_t *this,
+ channel_t *c) {
+
+ print_channel (c);
+
+ tuner_get_front (this);
+ tuner_set_tp (this, c->freq, c->tone, c->volt, c->diseqcnr, c->srate, c->fec);
+ if (!tuner_set_front (this))
+ return 0;
+
+ tuner_set_vpid (this, c->vpid);
+ tuner_set_apid (this, c->apid);
+ tuner_set_ttpid (this, 0);
+
+ return 1; /* fixme: error handling */
+}
+
+static void osd_show_channel (dvb_input_plugin_t *this) {
+
+ printf ("input_dvb: channel=%d\n", this->channel);
+
+#if 0 /* FIXME */
+ int i, channel ;
+
+ if (!this->osd) {
+ this->osd = this->stream->osd_renderer->new_object (this->stream->osd_renderer,
+ 410, 410);
+ this->stream->osd_renderer->set_position (this->osd, 20, 20);
+ this->stream->osd_renderer->set_font (this->osd, "cetus", 32);
+ this->stream->osd_renderer->set_text_palette (this->osd,
+ TEXTPALETTE_WHITE_NONE_TRANSLUCID,
+ OSD_TEXT3);
+ }
+
+ this->stream->osd_renderer->filled_rect (this->osd, 0, 0, 395, 400, 2);
+
+ channel = this->channel - 5;
+
+ for (i=0; i<11; i++) {
+
+ if ( (channel >= 0) && (channel < this->num_channels) )
+ this->stream->osd_renderer->render_text (this->osd, 10, 10+i*35,
+ this->channels[channel].name,
+ OSD_TEXT3);
+ channel ++;
+ }
+
+ this->stream->osd_renderer->line (this->osd, 5, 183, 390, 183, 10);
+ this->stream->osd_renderer->line (this->osd, 5, 183, 5, 219, 10);
+ this->stream->osd_renderer->line (this->osd, 5, 219, 390, 219, 10);
+ this->stream->osd_renderer->line (this->osd, 390, 183, 390, 219, 10);
+
+ this->stream->osd_renderer->show (this->osd, 0);
+#endif
+
+}
+
+static void switch_channel (dvb_input_plugin_t *this) {
+
+ xine_event_t event;
+ xine_pids_data_t data;
+
+ pthread_mutex_lock (&this->mutex);
+
+ close (this->fd);
+
+ if (!tuner_set_channel (this->tuner, &this->channels[this->channel])) {
+ printf ("input_dvb: tuner_set_channel failed\n");
+ pthread_mutex_unlock (&this->mutex);
+ return;
+ }
+
+ event.type = XINE_EVENT_PIDS_CHANGE;
+ data.vpid = this->channels[this->channel].vpid;
+ data.apid = this->channels[this->channel].apid;
+ event.data = &data;
+ event.data_length = sizeof (xine_pids_data_t);
+
+ printf ("input_dvb: sending event\n");
+
+ xine_event_send (this->stream, &event);
+
+ this->fd = open (DVR_DEVICE, O_RDONLY);
+
+ pthread_mutex_unlock (&this->mutex);
+
+#if 0 /* FIXME */
+ this->stream->osd_renderer->hide (this->osd, 0);
+#endif
+}
+
+static void dvb_event_handler (dvb_input_plugin_t *this) {
+
+ xine_event_t *event;
+
+ while ((event = xine_event_get (this->event_queue))) {
+
+ if (this->fd<0) {
+ xine_event_free (event);
+ return;
+ }
+
+ switch (event->type) {
+
+ case XINE_EVENT_INPUT_NEXT:
+ if (this->channel < (this->num_channels-1))
+ this->channel++;
+ osd_show_channel (this);
+ break;
+
+ case XINE_EVENT_INPUT_PREVIOUS:
+ if (this->channel>0)
+ this->channel--;
+ osd_show_channel (this);
+ break;
+
+ case XINE_EVENT_INPUT_DOWN:
+ if (this->channel < (this->num_channels-1)) {
+ this->channel++;
+ switch_channel (this);
+ }
+ break;
+
+ case XINE_EVENT_INPUT_UP:
+ if (this->channel>0) {
+ this->channel--;
+ switch_channel (this);
+ }
+ break;
+
+ case XINE_EVENT_INPUT_SELECT:
+ switch_channel (this);
+ break;
+
+ case XINE_EVENT_INPUT_MENU3:
+ this->stream->osd_renderer->hide (this->osd, 0);
+ break;
+
+#if 0
+ default:
+ printf ("input_dvb: got an event, type 0x%08x\n", event->type);
+#endif
+ }
+
+ xine_event_free (event);
+ }
+}
+
+static off_t dvb_plugin_read (input_plugin_t *this_gen,
+ char *buf, off_t len) {
+ dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen;
+ off_t n, total;
+
+ dvb_event_handler (this);
+
+#ifdef LOG
+ printf ("input_dvb: reading %lld bytes...\n", len);
+#endif
+
+ nbc_check_buffers (this->nbc);
+
+ pthread_mutex_lock( &this->mutex ); /* protect agains channel changes */
+ total=0;
+ while (total<len){
+ n = read (this->fd, &buf[total], len-total);
+
+#ifdef LOG
+ printf ("input_dvb: got %lld bytes (%lld/%lld bytes read)\n",
+ n,total,len);
+#endif
+
+ if (n > 0){
+ this->curpos += n;
+ total += n;
+ } else if (n<0 && errno!=EAGAIN) {
+ pthread_mutex_unlock( &this->mutex );
+ return total;
+ }
+ }
+
+ if (this->out_fd>0)
+ write (this->out_fd, buf, total);
+
+ pthread_mutex_unlock( &this->mutex );
+ return total;
+}
+
+static buf_element_t *dvb_plugin_read_block (input_plugin_t *this_gen,
+ fifo_buffer_t *fifo, off_t todo) {
+ /* dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; */
+ buf_element_t *buf = fifo->buffer_pool_alloc (fifo);
+ int total_bytes;
+
+
+#if 0
+ if (this->report_pids) {
+
+ printf ("input_dvb: reporting pids %d (video), %d (audio)\n",
+ this->channels[this->channel].vpid,
+ this->channels[this->channel].apid);
+
+ this->report_pids = 0;
+
+ }
+#endif
+
+ buf->content = buf->mem;
+ buf->type = BUF_DEMUX_BLOCK;
+
+ total_bytes = dvb_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 dvb_plugin_seek (input_plugin_t *this_gen, off_t offset,
+ int origin) {
+
+ dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen;
+
+#ifdef LOG
+ printf ("input_dvb: seek %lld bytes, origin %d\n",
+ offset, origin);
+#endif
+
+ /* only relative forward-seeking is implemented */
+
+ if ((origin == SEEK_CUR) && (offset >= 0)) {
+
+ for (;((int)offset) - BUFSIZE > 0; offset -= BUFSIZE) {
+ this->curpos += dvb_plugin_read (this_gen, this->seek_buf, BUFSIZE);
+ }
+
+ this->curpos += dvb_plugin_read (this_gen, this->seek_buf, offset);
+ }
+
+ return this->curpos;
+}
+
+static off_t dvb_plugin_get_length (input_plugin_t *this_gen) {
+ return 0;
+}
+
+static uint32_t dvb_plugin_get_capabilities (input_plugin_t *this_gen) {
+ return 0; /* where did INPUT_CAP_AUTOPLAY go ?!? */
+}
+
+static uint32_t dvb_plugin_get_blocksize (input_plugin_t *this_gen) {
+ return 0;
+}
+
+static off_t dvb_plugin_get_current_pos (input_plugin_t *this_gen){
+ dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen;
+
+ return this->curpos;
+}
+
+static void dvb_plugin_dispose (input_plugin_t *this_gen) {
+ dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen;
+
+ close(this->fd);
+ this->fd = -1;
+
+ if (this->nbc) {
+ nbc_close (this->nbc);
+ this->nbc = NULL;
+ }
+
+ if (this->out_fd>0)
+ close (this->out_fd);
+
+ xine_event_dispose_queue (this->event_queue);
+
+ free (this->mrl);
+ free (this);
+}
+
+static char* dvb_plugin_get_mrl (input_plugin_t *this_gen) {
+ dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen;
+
+ return this->mrl;
+}
+
+static int dvb_plugin_get_optional_data (input_plugin_t *this_gen,
+ void *data, int data_type) {
+
+ return INPUT_OPTIONAL_UNSUPPORTED;
+}
+
+static channel_t *load_channels (int *num_ch) {
+
+ FILE *f;
+ unsigned char str[BUFSIZE];
+ unsigned char filename[BUFSIZE];
+ channel_t *channels;
+ int num_channels;
+
+ snprintf (filename, BUFSIZE, "%s/.xine/dvb_channels", xine_get_homedir());
+
+ f = fopen (filename, "rb");
+ if (!f) {
+ printf ("input_dvb: failed to open dvb channel file '%s'\n", filename);
+ return NULL;
+ }
+
+ /*
+ * count and alloc channels
+ */
+ num_channels = 0;
+ while ( fgets (str, BUFSIZE, f)) {
+ fgets (str, BUFSIZE, f);
+ num_channels++;
+ }
+ fclose (f);
+ printf ("input_dvb: %d channels found.\n", num_channels);
+
+ channels = malloc (sizeof (channel_t) * num_channels);
+
+ /*
+ * load channel list
+ */
+
+ f = fopen (filename, "rb");
+ num_channels = 0;
+ while ( fgets (str, BUFSIZE, f)) {
+
+ int freq;
+
+ channels[num_channels].name = strdup (str);
+
+ fgets (str, BUFSIZE, f);
+
+ sscanf (str, "%d %d %d %d %d %d %d\n",
+ &channels[num_channels].diseqcnr,
+ &freq,
+ &channels[num_channels].volt,
+ &channels[num_channels].srate,
+ &channels[num_channels].fec,
+ &channels[num_channels].vpid,
+ &channels[num_channels].apid);
+
+ if (freq > 11700000) {
+ channels[num_channels].freq = freq - 10600000;
+ channels[num_channels].tone = SEC_TONE_ON;
+ } else {
+ channels[num_channels].freq = freq - 9750000;
+ channels[num_channels].tone = SEC_TONE_OFF;
+ }
+
+#ifdef LOG
+ printf ("input: dvb channel %s loaded\n", channels[num_channels].name);
+#endif
+
+ num_channels++;
+ }
+
+ *num_ch = num_channels;
+ return channels;
+}
+
+static input_plugin_t *open_plugin (input_class_t *cls_gen,
+ xine_stream_t *stream,
+ const char *data) {
+
+ dvb_input_class_t *cls = (dvb_input_class_t *) cls_gen;
+ dvb_input_plugin_t *this;
+ tuner_t *tuner;
+ channel_t *channels;
+ int num_channels;
+ char *mrl = (char *) data;
+
+ if (strncasecmp (mrl, "dvb:/",5))
+ return NULL;
+
+ if ( !(tuner = tuner_init()) ) {
+ printf ("input_dvb: cannot open dvb device\n");
+ return NULL;
+ }
+
+ if ( !(channels = load_channels(&num_channels)) ) {
+ tuner_dispose (tuner);
+ return NULL;
+ }
+
+ this = (dvb_input_plugin_t *) xine_xmalloc (sizeof(dvb_input_plugin_t));
+
+ this->tuner = tuner;
+ this->channels = channels;
+
+ if ( sscanf (mrl, "dvb://%d", &this->channel) != 1)
+ this->channel = 0;
+
+ if (!tuner_set_channel (this->tuner, &this->channels[this->channel])) {
+ printf ("input_dvb: tuner_set_channel failed\n");
+ free (this);
+ return NULL;
+ }
+
+ if ((this->fd = open (DVR_DEVICE, O_RDONLY)) < 0){
+ printf ("input_dvb: cannot open dvr device '%s'\n", DVR_DEVICE);
+ free (this);
+ return NULL;
+ }
+
+ this->mrl = strdup(mrl);
+
+ this->curpos = 0;
+ this->nbc = nbc_init (stream);
+ this->stream = stream;
+ this->tuner = tuner;
+ this->channels = channels;
+ this->num_channels = num_channels;
+ this->osd = NULL;
+
+ this->input_plugin.get_capabilities = dvb_plugin_get_capabilities;
+ this->input_plugin.read = dvb_plugin_read;
+ this->input_plugin.read_block = dvb_plugin_read_block;
+ this->input_plugin.seek = dvb_plugin_seek;
+ this->input_plugin.get_current_pos = dvb_plugin_get_current_pos;
+ this->input_plugin.get_length = dvb_plugin_get_length;
+ this->input_plugin.get_blocksize = dvb_plugin_get_blocksize;
+ this->input_plugin.get_mrl = dvb_plugin_get_mrl;
+ this->input_plugin.get_optional_data = dvb_plugin_get_optional_data;
+ this->input_plugin.dispose = dvb_plugin_dispose;
+ this->input_plugin.input_class = cls_gen;
+ this->cls = cls;
+
+ /*
+ xine_register_event_listener (this->stream, dvb_event_listener, this);
+ */
+
+ pthread_mutex_init (&this->mutex, NULL);
+
+#if 0
+ this->out_fd = open ("foo.ts", O_CREAT | O_WRONLY | O_TRUNC, 0644);
+#else
+ this->out_fd = 0;
+#endif
+
+ this->event_queue = xine_event_new_queue (this->stream);
+
+ return (input_plugin_t *) this;
+}
+
+/*
+ * dvb input plugin class stuff
+ */
+
+static char *dvb_class_get_description (input_class_t *this_gen) {
+ return _("DVB (Digital TV) input plugin");
+}
+
+static char *dvb_class_get_identifier (input_class_t *this_gen) {
+ return "dvb";
+}
+
+static void dvb_class_dispose (input_class_t *this_gen) {
+
+ dvb_input_class_t *cls = (dvb_input_class_t *) this_gen;
+
+ free (cls->mrls[0]);
+
+ free (cls);
+}
+
+static int dvb_class_eject_media (input_class_t *this_gen) {
+ return 1;
+}
+
+static char ** dvb_class_get_autoplay_list (input_class_t *this_gen,
+ int *num_files) {
+ dvb_input_class_t *cls = (dvb_input_class_t *) this_gen;
+
+ *num_files = 1;
+ return cls->mrls;
+}
+
+static void *init_class (xine_t *xine, void *data) {
+
+ dvb_input_class_t *this;
+
+ this = (dvb_input_class_t *) xine_xmalloc (sizeof (dvb_input_class_t));
+
+ this->xine = xine;
+
+ this->input_class.open_plugin = open_plugin;
+ this->input_class.get_identifier = dvb_class_get_identifier;
+ this->input_class.get_description = dvb_class_get_description;
+ this->input_class.get_dir = NULL;
+ this->input_class.get_autoplay_list = dvb_class_get_autoplay_list;
+ this->input_class.dispose = dvb_class_dispose;
+ this->input_class.eject_media = dvb_class_eject_media;
+
+ this->mrls[0] = "dvb://";
+ this->mrls[1] = 0;
+
+ printf ("input_dvb: init class succeeded\n");
+
+ return this;
+}
+
+
+/*
+ * exported plugin catalog entry
+ */
+
+plugin_info_t xine_plugin_info[] = {
+ /* type, API, "name", version, special_info, init_function */
+ { PLUGIN_INPUT, 11, "DVB", XINE_VERSION_CODE, NULL, init_class },
+ { PLUGIN_NONE, 0, "", 0, NULL, NULL }
+};
diff --git a/src/input/ost/Makefile.am b/src/input/ost/Makefile.am
new file mode 100644
index 000000000..7c179a4af
--- /dev/null
+++ b/src/input/ost/Makefile.am
@@ -0,0 +1,22 @@
+noinst_HEADERS = \
+ demux.h \
+ dmx.h \
+ frontend.h \
+ sec.h
+
+debug:
+ @list='$(SUBDIRS)'; for subdir in $$list; do \
+ (cd $$subdir && $(MAKE) $@) || exit;\
+ done;
+ @$(MAKE) CFLAGS="$(DEBUG_CFLAGS)"
+
+install-debug: debug
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+mostlyclean-generic:
+ -rm -f *~ \#* .*~ .\#*
+
+maintainer-clean-generic:
+ -@echo "This command is intended for maintainers to use;"
+ -@echo "it deletes files that may require special tools to rebuild."
+ -rm -f Makefile.in
diff --git a/src/input/ost/README b/src/input/ost/README
new file mode 100644
index 000000000..5fc680215
--- /dev/null
+++ b/src/input/ost/README
@@ -0,0 +1,9 @@
+This directories contains header files for the Linux DVB drivers
+from convergence integrated media GmbH
+
+ Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
+ & Marcus Metzler <marcus@convergence.de>
+ for convergence integrated media GmbH
+
+released under the LGPL license. For details see the individual
+header files.
diff --git a/src/input/ost/ca.h b/src/input/ost/ca.h
new file mode 100644
index 000000000..226ef5c09
--- /dev/null
+++ b/src/input/ost/ca.h
@@ -0,0 +1,84 @@
+/*
+ * ca.h
+ *
+ * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
+ * & Marcus Metzler <marcus@convergence.de>
+ for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Lesser Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 Lesser 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.
+ *
+ */
+
+#ifndef _OST_CA_H_
+#define _OST_CA_H_
+
+/* slot interface types and info */
+
+typedef struct ca_slot_info_s {
+ int num; /* slot number */
+
+ int type; /* CA interface this slot supports */
+#define CA_CI 1 /* CI high level interface */
+#define CA_CI_LINK 2 /* CI link layer level interface */
+#define CA_CI_PHYS 4 /* CI physical layer level interface */
+#define CA_SC 128 /* simple smart card interface */
+
+ unsigned int flags;
+#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
+#define CA_CI_MODULE_READY 2
+} ca_slot_info_t;
+
+
+/* descrambler types and info */
+
+typedef struct ca_descr_info_s {
+ unsigned int num; /* number of available descramblers (keys) */
+ unsigned int type; /* type of supported scrambling system */
+#define CA_ECD 1
+#define CA_NDS 2
+#define CA_DSS 4
+} ca_descr_info_t;
+
+typedef struct ca_cap_s {
+ unsigned int slot_num; /* total number of CA card and module slots */
+ unsigned int slot_type; /* OR of all supported types */
+ unsigned int descr_num; /* total number of descrambler slots (keys) */
+ unsigned int descr_type; /* OR of all supported types */
+} ca_cap_t;
+
+/* a message to/from a CI-CAM */
+typedef struct ca_msg_s {
+ unsigned int index;
+ unsigned int type;
+ unsigned int length;
+ unsigned char msg[256];
+} ca_msg_t;
+
+typedef struct ca_descr_s {
+ unsigned int index;
+ unsigned int parity;
+ unsigned char cw[8];
+} ca_descr_t;
+
+#define CA_RESET _IOW('o', 128, int)
+#define CA_GET_CAP _IOR('o', 129, ca_cap_t *)
+#define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t *)
+#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t *)
+#define CA_GET_MSG _IOR('o', 132, ca_msg_t *)
+#define CA_SEND_MSG _IOW('o', 133, ca_msg_t *)
+#define CA_SET_DESCR _IOW('o', 134, ca_descr_t *)
+
+#endif
+
diff --git a/src/input/ost/demux.h b/src/input/ost/demux.h
new file mode 100644
index 000000000..758e921b6
--- /dev/null
+++ b/src/input/ost/demux.h
@@ -0,0 +1,346 @@
+/* * demux.h * * Copyright (c) 2000 Nokia Research Center
+ * Tampere, FINLAND
+ *
+ * Project:
+ * Universal Broadcast Access
+ *
+ * Contains:
+ * Type definitions of a Linux kernel-level API for filtering MPEG-2 TS
+ * packets and MPEG-2 sections. Support for PES packet filtering will be
+ * added later.
+ *
+ * History:
+ * 12.01.2000/JPL File created - Initial version.
+ * 18.02.2000/JPL Minor corrections.
+ * 21.02.2000/JPL DMX_NAME_SIZE and dmx_in_use() removed, typos fixed,
+ * some names changed.
+ * 23.02.2000/JPL Added a parameter indicating the callback source in
+ * the callback functions.
+ * 10.03.2000/JPL Added the macros DMX_DIR_ENTRY() and DMX_FE_ENTRY().
+ * 15.03.2000/JPL Added the capabilities field to dmx_demux_t.
+ * 22.03.2000/JPL Corrected the callback parameter in the
+ * allocate_x_feed() functions.
+ * 03.04.2000/JPL Added support for optional resource conflict resolution
+ * and scarce resource handling.
+ * 05.04.2000/JPL Changed the dmx_resolve_conflict() to use resource
+ * type as a parameter.
+ * 12.04.2000/JPL Added a second buffer parameter for dmx_x_callback()
+ * functions to better handle buffer wrapping.
+ * 26.04.2000/JPL Added functions for section-level descrambling.
+ * 03.09.2000/JPL Removed support for conflict resolution and scarce
+ * resource handling. Otherwise only minor changes to
+ * data structures and function prototypes.
+ *
+ *
+ * Author:
+ * Juha-Pekka Luoma (JPL)
+ * Nokia Research Center
+ *
+ * Notes:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 Lesser 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: demux.h,v 1.1 2002/12/27 00:53:50 guenter Exp $ */
+
+#ifndef __DEMUX_H
+#define __DEMUX_H
+
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+
+#include <linux/types.h> /* __u8, __u16, ... */
+#include <linux/list.h> /* list_entry(), struct list_head */
+#include <linux/time.h> /* struct timespec */
+#include <linux/errno.h> /* Function return values */
+
+/*--------------------------------------------------------------------------*/
+/* Common definitions */
+/*--------------------------------------------------------------------------*/
+
+/*
+ * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter.
+ */
+
+#ifndef DMX_MAX_FILTER_SIZE
+#define DMX_MAX_FILTER_SIZE 18
+#endif
+/*
+ * dmx_success_t: Success codes for the Demux Callback API.
+ */
+
+typedef enum {
+ DMX_OK = 0, /* Received Ok */
+ DMX_LENGTH_ERROR, /* Incorrect length */
+ DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */
+ DMX_CRC_ERROR, /* Incorrect CRC */
+ DMX_FRAME_ERROR, /* Frame alignment error */
+ DMX_FIFO_ERROR, /* Receiver FIFO overrun */
+ DMX_MISSED_ERROR /* Receiver missed packet */
+} dmx_success_t;
+
+/*--------------------------------------------------------------------------*/
+/* TS packet reception */
+/*--------------------------------------------------------------------------*/
+
+/* TS filter type for set_type() */
+
+#define TS_PACKET 1 /* send TS packets (188 bytes) to callback (default) */
+#define TS_PAYLOAD_ONLY 2 /* in case TS_PACKET is set, only send the TS
+ payload (<=184 bytes per packet) to callback */
+#define TS_DECODER 4 /* send stream to built-in decoder (if present) */
+
+/* PES type for filters which write to built-in decoder */
+/* these should be kept identical to the types in dmx.h */
+
+typedef enum
+{
+ DMX_TS_PES_AUDIO, /* also send packets to audio decoder (if it exists) */
+ DMX_TS_PES_VIDEO, /* ... */
+ DMX_TS_PES_TELETEXT,
+ DMX_TS_PES_SUBTITLE,
+ DMX_TS_PES_PCR,
+ DMX_TS_PES_OTHER,
+} dmx_ts_pes_t;
+
+
+struct dmx_ts_feed_s {
+ int is_filtering; /* Set to non-zero when filtering in progress */
+ struct dmx_demux_s* parent; /* Back-pointer */
+ void* priv; /* Pointer to private data of the API client */
+ int (*set) (struct dmx_ts_feed_s* feed,
+ __u16 pid,
+ size_t callback_length,
+ size_t circular_buffer_size,
+ int descramble,
+ struct timespec timeout);
+ int (*start_filtering) (struct dmx_ts_feed_s* feed);
+ int (*stop_filtering) (struct dmx_ts_feed_s* feed);
+ int (*set_type) (struct dmx_ts_feed_s* feed,
+ int type,
+ dmx_ts_pes_t pes_type);
+};
+
+typedef struct dmx_ts_feed_s dmx_ts_feed_t;
+
+/*--------------------------------------------------------------------------*/
+/* PES packet reception (not supported yet) */
+/*--------------------------------------------------------------------------*/
+
+typedef struct dmx_pes_filter_s {
+ struct dmx_pes_s* parent; /* Back-pointer */
+ void* priv; /* Pointer to private data of the API client */
+} dmx_pes_filter_t;
+
+typedef struct dmx_pes_feed_s {
+ int is_filtering; /* Set to non-zero when filtering in progress */
+ struct dmx_demux_s* parent; /* Back-pointer */
+ void* priv; /* Pointer to private data of the API client */
+ int (*set) (struct dmx_pes_feed_s* feed,
+ __u16 pid,
+ size_t circular_buffer_size,
+ int descramble,
+ struct timespec timeout);
+ int (*start_filtering) (struct dmx_pes_feed_s* feed);
+ int (*stop_filtering) (struct dmx_pes_feed_s* feed);
+ int (*allocate_filter) (struct dmx_pes_feed_s* feed,
+ dmx_pes_filter_t** filter);
+ int (*release_filter) (struct dmx_pes_feed_s* feed,
+ dmx_pes_filter_t* filter);
+} dmx_pes_feed_t;
+
+/*--------------------------------------------------------------------------*/
+/* Section reception */
+/*--------------------------------------------------------------------------*/
+
+typedef struct {
+ __u8 filter_value [DMX_MAX_FILTER_SIZE];
+ __u8 filter_mask [DMX_MAX_FILTER_SIZE];
+ struct dmx_section_feed_s* parent; /* Back-pointer */
+ void* priv; /* Pointer to private data of the API client */
+} dmx_section_filter_t;
+
+struct dmx_section_feed_s {
+ int is_filtering; /* Set to non-zero when filtering in progress */
+ struct dmx_demux_s* parent; /* Back-pointer */
+ void* priv; /* Pointer to private data of the API client */
+ int (*set) (struct dmx_section_feed_s* feed,
+ __u16 pid,
+ size_t circular_buffer_size,
+ int descramble,
+ int check_crc);
+ int (*allocate_filter) (struct dmx_section_feed_s* feed,
+ dmx_section_filter_t** filter);
+ int (*release_filter) (struct dmx_section_feed_s* feed,
+ dmx_section_filter_t* filter);
+ int (*start_filtering) (struct dmx_section_feed_s* feed);
+ int (*stop_filtering) (struct dmx_section_feed_s* feed);
+};
+typedef struct dmx_section_feed_s dmx_section_feed_t;
+
+/*--------------------------------------------------------------------------*/
+/* Callback functions */
+/*--------------------------------------------------------------------------*/
+
+typedef int (*dmx_ts_cb) ( __u8 * buffer1,
+ size_t buffer1_length,
+ __u8 * buffer2,
+ size_t buffer2_length,
+ dmx_ts_feed_t* source,
+ dmx_success_t success);
+
+typedef int (*dmx_section_cb) ( __u8 * buffer1,
+ size_t buffer1_len,
+ __u8 * buffer2,
+ size_t buffer2_len,
+ dmx_section_filter_t * source,
+ dmx_success_t success);
+
+typedef int (*dmx_pes_cb) ( __u8 * buffer1,
+ size_t buffer1_len,
+ __u8 * buffer2,
+ size_t buffer2_len,
+ dmx_pes_filter_t* source,
+ dmx_success_t success);
+
+/*--------------------------------------------------------------------------*/
+/* DVB Front-End */
+/*--------------------------------------------------------------------------*/
+
+typedef enum {
+ DMX_OTHER_FE = 0,
+ DMX_SATELLITE_FE,
+ DMX_CABLE_FE,
+ DMX_TERRESTRIAL_FE,
+ DMX_LVDS_FE,
+ DMX_ASI_FE, /* DVB-ASI interface */
+ DMX_MEMORY_FE
+} dmx_frontend_source_t;
+
+typedef struct {
+ /* The following char* fields point to NULL terminated strings */
+ char* id; /* Unique front-end identifier */
+ char* vendor; /* Name of the front-end vendor */
+ char* model; /* Name of the front-end model */
+ struct list_head connectivity_list; /* List of front-ends that can
+ be connected to a particular
+ demux */
+ void* priv; /* Pointer to private data of the API client */
+ dmx_frontend_source_t source;
+} dmx_frontend_t;
+
+/*--------------------------------------------------------------------------*/
+/* MPEG-2 TS Demux */
+/*--------------------------------------------------------------------------*/
+
+/*
+ * Flags OR'ed in the capabilites field of struct dmx_demux_s.
+ */
+
+#define DMX_TS_FILTERING 1
+#define DMX_PES_FILTERING 2
+#define DMX_SECTION_FILTERING 4
+#define DMX_MEMORY_BASED_FILTERING 8 /* write() available */
+#define DMX_CRC_CHECKING 16
+#define DMX_TS_DESCRAMBLING 32
+#define DMX_SECTION_PAYLOAD_DESCRAMBLING 64
+#define DMX_MAC_ADDRESS_DESCRAMBLING 128
+
+/*
+ * Demux resource type identifier.
+*/
+
+/*
+ * DMX_FE_ENTRY(): Casts elements in the list of registered
+ * front-ends from the generic type struct list_head
+ * to the type * dmx_frontend_t
+ *.
+*/
+
+#define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list)
+
+struct dmx_demux_s {
+ /* The following char* fields point to NULL terminated strings */
+ char* id; /* Unique demux identifier */
+ char* vendor; /* Name of the demux vendor */
+ char* model; /* Name of the demux model */
+ __u32 capabilities; /* Bitfield of capability flags */
+ dmx_frontend_t* frontend; /* Front-end connected to the demux */
+ struct list_head reg_list; /* List of registered demuxes */
+ void* priv; /* Pointer to private data of the API client */
+ int users; /* Number of users */
+ int (*open) (struct dmx_demux_s* demux);
+ int (*close) (struct dmx_demux_s* demux);
+ int (*write) (struct dmx_demux_s* demux, const char* buf, size_t count);
+ int (*allocate_ts_feed) (struct dmx_demux_s* demux,
+ dmx_ts_feed_t** feed,
+ dmx_ts_cb callback);
+ int (*release_ts_feed) (struct dmx_demux_s* demux,
+ dmx_ts_feed_t* feed);
+ int (*allocate_pes_feed) (struct dmx_demux_s* demux,
+ dmx_pes_feed_t** feed,
+ dmx_pes_cb callback);
+ int (*release_pes_feed) (struct dmx_demux_s* demux,
+ dmx_pes_feed_t* feed);
+ int (*allocate_section_feed) (struct dmx_demux_s* demux,
+ dmx_section_feed_t** feed,
+ dmx_section_cb callback);
+ int (*release_section_feed) (struct dmx_demux_s* demux,
+ dmx_section_feed_t* feed);
+ int (*descramble_mac_address) (struct dmx_demux_s* demux,
+ __u8* buffer1,
+ size_t buffer1_length,
+ __u8* buffer2,
+ size_t buffer2_length,
+ __u16 pid);
+ int (*descramble_section_payload) (struct dmx_demux_s* demux,
+ __u8* buffer1,
+ size_t buffer1_length,
+ __u8* buffer2, size_t buffer2_length,
+ __u16 pid);
+ int (*add_frontend) (struct dmx_demux_s* demux,
+ dmx_frontend_t* frontend);
+ int (*remove_frontend) (struct dmx_demux_s* demux,
+ dmx_frontend_t* frontend);
+ struct list_head* (*get_frontends) (struct dmx_demux_s* demux);
+ int (*connect_frontend) (struct dmx_demux_s* demux,
+ dmx_frontend_t* frontend);
+ int (*disconnect_frontend) (struct dmx_demux_s* demux);
+
+
+ /* added because js cannot keep track of these himself */
+ int (*get_pes_pids) (struct dmx_demux_s* demux, __u16 *pids);
+};
+typedef struct dmx_demux_s dmx_demux_t;
+
+/*--------------------------------------------------------------------------*/
+/* Demux directory */
+/*--------------------------------------------------------------------------*/
+
+/*
+ * DMX_DIR_ENTRY(): Casts elements in the list of registered
+ * demuxes from the generic type struct list_head* to the type dmx_demux_t
+ *.
+ */
+
+#define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list)
+
+int dmx_register_demux (dmx_demux_t* demux);
+int dmx_unregister_demux (dmx_demux_t* demux);
+struct list_head* dmx_get_demuxes (void);
+
+#endif /* #ifndef __DEMUX_H */
+
diff --git a/src/input/ost/dmx.h b/src/input/ost/dmx.h
new file mode 100644
index 000000000..9c4bb6b6d
--- /dev/null
+++ b/src/input/ost/dmx.h
@@ -0,0 +1,141 @@
+/*
+ * dmx.h
+ *
+ * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
+ * & Ralph Metzler <ralph@convergence.de>
+ for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 Lesser 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.
+ *
+ */
+
+#ifndef _OST_DMX_H_
+#define _OST_DMX_H_
+
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stdint.h>
+#endif
+
+#ifndef EBUFFEROVERFLOW
+#define EBUFFEROVERFLOW 769
+#endif
+
+/* pid_t conflicts with linux/include/linux/types.h !!!*/
+
+typedef uint16_t dvb_pid_t;
+
+#define DMX_FILTER_SIZE 16
+
+typedef enum
+{
+ DMX_OUT_DECODER, /* Streaming directly to decoder. */
+ DMX_OUT_TAP, /* Output going to a memory buffer */
+ /* (to be retrieved via the read command).*/
+ DMX_OUT_TS_TAP /* Output multiplexed into a new TS */
+ /* (to be retrieved by reading from the */
+ /* logical DVR device). */
+} dmxOutput_t;
+
+
+typedef enum
+{
+ DMX_IN_FRONTEND, /* Input from a front-end device. */
+ DMX_IN_DVR /* Input from the logical DVR device. */
+} dmxInput_t;
+
+
+typedef enum
+{
+ DMX_PES_AUDIO,
+ DMX_PES_VIDEO,
+ DMX_PES_TELETEXT,
+ DMX_PES_SUBTITLE,
+ DMX_PES_PCR,
+ DMX_PES_OTHER
+} dmxPesType_t;
+
+
+typedef enum
+{
+ DMX_SCRAMBLING_EV,
+ DMX_FRONTEND_EV
+} dmxEvent_t;
+
+
+typedef enum
+{
+ DMX_SCRAMBLING_OFF,
+ DMX_SCRAMBLING_ON
+} dmxScramblingStatus_t;
+
+
+typedef struct dmxFilter
+{
+ uint8_t filter[DMX_FILTER_SIZE];
+ uint8_t mask[DMX_FILTER_SIZE];
+} dmxFilter_t;
+
+
+struct dmxFrontEnd
+{
+ /*TBD tbd; */
+};
+
+
+struct dmxSctFilterParams
+{
+ dvb_pid_t pid;
+ dmxFilter_t filter;
+ uint32_t timeout;
+ uint32_t flags;
+#define DMX_CHECK_CRC 1
+#define DMX_ONESHOT 2
+#define DMX_IMMEDIATE_START 4
+#define DMX_KERNEL_CLIENT 0x8000
+};
+
+
+struct dmxPesFilterParams
+{
+ dvb_pid_t pid;
+ dmxInput_t input;
+ dmxOutput_t output;
+ dmxPesType_t pesType;
+ uint32_t flags;
+};
+
+
+struct dmxEvent
+{
+ dmxEvent_t event;
+ time_t timeStamp;
+ union
+ {
+ dmxScramblingStatus_t scrambling;
+ } u;
+};
+
+
+#define DMX_START _IOW('o',41,int)
+#define DMX_STOP _IOW('o',42,int)
+#define DMX_SET_FILTER _IOW('o',43,struct dmxSctFilterParams *)
+#define DMX_SET_PES_FILTER _IOW('o',44,struct dmxPesFilterParams *)
+#define DMX_SET_BUFFER_SIZE _IOW('o',45,unsigned long)
+#define DMX_GET_EVENT _IOR('o',46,struct dmxEvent *)
+#define DMX_GET_PES_PIDS _IOR('o',47,dvb_pid_t *)
+
+#endif /*_OST_DMX_H_*/
diff --git a/src/input/ost/frontend.h b/src/input/ost/frontend.h
new file mode 100644
index 000000000..57fb69e83
--- /dev/null
+++ b/src/input/ost/frontend.h
@@ -0,0 +1,208 @@
+/*
+ * frontend.h
+ *
+ * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de>
+ * & Ralph Metzler <ralph@convergence.de>
+ * for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 Lesser 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.
+ *
+ */
+
+#ifndef _FRONTEND_H_
+#define _FRONTEND_H_
+
+#include <asm/types.h>
+
+
+#define ENOSIGNAL 768
+#ifndef EBUFFEROVERFLOW
+#define EBUFFEROVERFLOW 769
+#endif
+
+
+typedef __u32 FrontendStatus;
+
+/* bit definitions for FrontendStatus */
+#define FE_HAS_POWER 1
+#define FE_HAS_SIGNAL 2
+#define FE_SPECTRUM_INV 4
+#define FE_HAS_LOCK 8
+#define FE_HAS_CARRIER 16
+#define FE_HAS_VITERBI 32
+#define FE_HAS_SYNC 64
+#define FE_TUNER_HAS_LOCK 128
+
+
+/* possible values for spectral inversion */
+typedef enum {
+ INVERSION_OFF,
+ INVERSION_ON,
+ INVERSION_AUTO
+} SpectralInversion;
+
+/* possible values for FEC_inner/FEC_outer */
+typedef enum {
+ FEC_AUTO,
+ FEC_1_2,
+ FEC_2_3,
+ FEC_3_4,
+ FEC_5_6,
+ FEC_7_8,
+ FEC_NONE
+} CodeRate;
+
+
+typedef enum {
+ QPSK,
+ QAM_16,
+ QAM_32,
+ QAM_64,
+ QAM_128,
+ QAM_256
+} Modulation;
+
+
+typedef enum {
+ TRANSMISSION_MODE_2K,
+ TRANSMISSION_MODE_8K
+} TransmitMode;
+
+typedef enum {
+ BANDWIDTH_8_MHZ,
+ BANDWIDTH_7_MHZ,
+ BANDWIDTH_6_MHZ
+} BandWidth;
+
+
+typedef enum {
+ GUARD_INTERVAL_1_32,
+ GUARD_INTERVAL_1_16,
+ GUARD_INTERVAL_1_8,
+ GUARD_INTERVAL_1_4
+} GuardInterval;
+
+
+typedef enum {
+ HIERARCHY_NONE,
+ HIERARCHY_1,
+ HIERARCHY_2,
+ HIERARCHY_4
+} Hierarchy;
+
+
+typedef struct {
+ __u32 SymbolRate; /* symbol rate in Symbols per second */
+ CodeRate FEC_inner; /* forward error correction (see above) */
+} QPSKParameters;
+
+
+typedef struct {
+ __u32 SymbolRate; /* symbol rate in Symbols per second */
+ CodeRate FEC_inner; /* forward error correction (see above) */
+ Modulation QAM; /* modulation type (see above) */
+} QAMParameters;
+
+
+typedef struct {
+ BandWidth bandWidth;
+ CodeRate HP_CodeRate; /* high priority stream code rate */
+ CodeRate LP_CodeRate; /* low priority stream code rate */
+ Modulation Constellation; /* modulation type (see above) */
+ TransmitMode TransmissionMode;
+ GuardInterval guardInterval;
+ Hierarchy HierarchyInformation;
+} OFDMParameters;
+
+
+typedef enum {
+ FE_QPSK,
+ FE_QAM,
+ FE_OFDM
+} FrontendType;
+
+
+typedef struct {
+ __u32 Frequency; /* (absolute) frequency in Hz for QAM/OFDM */
+ /* intermediate frequency in kHz for QPSK */
+ SpectralInversion Inversion; /* spectral inversion */
+ union {
+ QPSKParameters qpsk;
+ QAMParameters qam;
+ OFDMParameters ofdm;
+ } u;
+} FrontendParameters;
+
+
+typedef enum {
+ FE_UNEXPECTED_EV, /* unexpected event (e.g. loss of lock) */
+ FE_COMPLETION_EV, /* completion event, tuning succeeded */
+ FE_FAILURE_EV /* failure event, we couldn't tune */
+} EventType;
+
+
+typedef struct {
+ EventType type; /* type of event, FE_UNEXPECTED_EV, ... */
+
+ long timestamp; /* time in seconds since 1970-01-01 */
+
+ union {
+ struct {
+ FrontendStatus previousStatus; /* status before event */
+ FrontendStatus currentStatus; /* status during event */
+ } unexpectedEvent;
+ FrontendParameters completionEvent; /* parameters for which the
+ tuning succeeded */
+ FrontendStatus failureEvent; /* status at failure (e.g. no lock) */
+ } u;
+} FrontendEvent;
+
+typedef struct {
+ FrontendType type;
+ __u32 minFrequency;
+ __u32 maxFrequency;
+ __u32 maxSymbolRate;
+ __u32 minSymbolRate;
+ __u32 hwType;
+ __u32 hwVersion;
+} FrontendInfo;
+
+
+typedef enum {
+ FE_POWER_ON,
+ FE_POWER_STANDBY,
+ FE_POWER_SUSPEND,
+ FE_POWER_OFF
+} FrontendPowerState;
+
+
+#define FE_SELFTEST _IO('o', 61)
+#define FE_SET_POWER_STATE _IOW('o', 62, FrontendPowerState)
+#define FE_GET_POWER_STATE _IOR('o', 63, FrontendPowerState*)
+#define FE_READ_STATUS _IOR('o', 64, FrontendStatus*)
+#define FE_READ_BER _IOW('o', 65, __u32*)
+#define FE_READ_SIGNAL_STRENGTH _IOR('o', 66, __s32*)
+#define FE_READ_SNR _IOR('o', 67, __s32*)
+#define FE_READ_UNCORRECTED_BLOCKS _IOW('o', 68, __u32*)
+#define FE_GET_NEXT_FREQUENCY _IOW('o', 69, __u32*)
+#define FE_GET_NEXT_SYMBOL_RATE _IOW('o', 70, __u32*)
+
+#define FE_SET_FRONTEND _IOW('o', 71, FrontendParameters*)
+#define FE_GET_FRONTEND _IOR('o', 72, FrontendParameters*)
+#define FE_GET_INFO _IOR('o', 73, FrontendInfo*)
+#define FE_GET_EVENT _IOR('o', 74, FrontendEvent*)
+
+#endif /*_FRONTEND_H_*/
+
diff --git a/src/input/ost/sec.h b/src/input/ost/sec.h
new file mode 100644
index 000000000..8863df268
--- /dev/null
+++ b/src/input/ost/sec.h
@@ -0,0 +1,118 @@
+/*
+ * sec.h
+ *
+ * Copyright (C) 2000 Ralph Metzler <ralph@convergence.de>
+ * & Marcus Metzler <marcus@convergence.de>
+ for convergence integrated media GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 Lesser 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.
+ *
+ */
+
+#ifndef _OST_SEC_H_
+#define _OST_SEC_H_
+
+#define SEC_MAX_DISEQC_PARAMS 3
+
+struct secDiseqcCmd {
+ uint8_t addr;
+ uint8_t cmd;
+ uint8_t numParams;
+ uint8_t params[SEC_MAX_DISEQC_PARAMS];
+};
+
+typedef uint32_t secVoltage;
+
+enum {
+ SEC_VOLTAGE_OFF,
+ SEC_VOLTAGE_LT,
+ SEC_VOLTAGE_13,
+ SEC_VOLTAGE_13_5,
+ SEC_VOLTAGE_18,
+ SEC_VOLTAGE_18_5
+};
+
+#define SEC_VOLTAGE_HORIZONTAL SEC_VOLTAGE_18
+#define SEC_VOLTAGE_VERTICAL SEC_VOLTAGE_13
+
+typedef uint32_t secToneMode;
+
+typedef enum {
+ SEC_TONE_ON,
+ SEC_TONE_OFF
+} secToneMode_t;
+
+
+typedef uint32_t secMiniCmd;
+
+typedef enum {
+ SEC_MINI_NONE,
+ SEC_MINI_A,
+ SEC_MINI_B
+} secMiniCmd_t;
+
+struct secStatus {
+ int32_t busMode;
+ secVoltage selVolt;
+ secToneMode contTone;
+};
+
+enum {
+ SEC_BUS_IDLE,
+ SEC_BUS_BUSY,
+ SEC_BUS_OFF,
+ SEC_BUS_OVERLOAD
+};
+
+struct secCommand {
+ int32_t type;
+ union {
+ struct secDiseqcCmd diseqc;
+ uint8_t vsec;
+ uint32_t pause;
+ } u;
+};
+
+struct secCmdSequence {
+ secVoltage voltage;
+ secMiniCmd miniCommand;
+ secToneMode continuousTone;
+
+ uint32_t numCommands;
+ struct secCommand* commands;
+};
+
+enum {
+ SEC_CMDTYPE_DISEQC,
+ SEC_CMDTYPE_VSEC,
+ SEC_CMDTYPE_PAUSE
+};
+
+
+#define SEC_GET_STATUS _IOR('o',91,struct secStatus *)
+#define SEC_RESET_OVERLOAD _IOW('o',92,void)
+#define SEC_SEND_SEQUENCE _IOW('o',93,struct secCmdSequence *)
+#define SEC_SET_TONE _IOW('o',94,secToneMode)
+#define SEC_SET_VOLTAGE _IOW('o',95,secVoltage)
+
+typedef enum {
+ SEC_DISEQC_SENT,
+ SEC_VSEC_SENT,
+ SEC_PAUSE_COMPLETE,
+ SEC_CALLBACK_ERROR
+} secCallback_t;
+
+
+#endif /*_OST_SEC_H_*/
diff --git a/src/xine-engine/audio_decoder.c b/src/xine-engine/audio_decoder.c
index b5c8bf79c..104539871 100644
--- a/src/xine-engine/audio_decoder.c
+++ b/src/xine-engine/audio_decoder.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: audio_decoder.c,v 1.95 2002/12/26 21:53:42 miguelfreitas Exp $
+ * $Id: audio_decoder.c,v 1.96 2002/12/27 00:53:50 guenter Exp $
*
*
* functions that implement audio decoding
@@ -195,7 +195,8 @@ void *audio_decoder_loop (void *stream_gen) {
while ( (i<stream->audio_track_map_entries) && (stream->audio_track_map[i]<buf->type) )
i++;
- if ( (i==stream->audio_track_map_entries) || (stream->audio_track_map[i] != buf->type) ) {
+ if ( (i==stream->audio_track_map_entries)
+ || (stream->audio_track_map[i] != buf->type) ) {
j = stream->audio_track_map_entries;
while (j>i) {
@@ -208,12 +209,23 @@ void *audio_decoder_loop (void *stream_gen) {
/* find out which audio type to decode */
+#ifdef LOG
+ printf ("audio_decoder: audio_channel_user = %d, map[0]=%08x\n",
+ stream->audio_channel_user,
+ stream->audio_track_map[0]);
+#endif
+
if (stream->audio_channel_user > -2) {
if (stream->audio_channel_user == -1) {
/* auto */
+#ifdef LOG
+ printf ("audio_decoder: audio_channel_auto = %d\n",
+ stream->audio_channel_auto);
+#endif
+
if (stream->audio_channel_auto>=0) {
if ((buf->type & 0xFF) == stream->audio_channel_auto) {
@@ -311,7 +323,7 @@ void audio_decoder_init (xine_stream_t *stream) {
*/
stream->audio_fifo = fifo_buffer_new (230, 8192);
stream->audio_channel_user = -1;
- stream->audio_channel_auto = 0;
+ stream->audio_channel_auto = -1;
stream->audio_track_map_entries = 0;
stream->audio_type = 0;
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index 1d1816eb4..063333178 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.203 2002/12/26 21:53:42 miguelfreitas Exp $
+ * $Id: xine.c,v 1.204 2002/12/27 00:53:50 guenter Exp $
*
* top-level xine functions
*
@@ -309,7 +309,7 @@ xine_stream_t *xine_stream_new (xine_t *this,
stream->spu_decoder_streamtype = -1;
stream->audio_out = ao;
stream->audio_channel_user = -1;
- stream->audio_channel_auto = 0;
+ stream->audio_channel_auto = -1;
stream->audio_decoder_plugin = NULL;
stream->audio_decoder_streamtype = -1;
stream->spu_channel_auto = -1;