summaryrefslogtreecommitdiff
path: root/src/input/input_dvb.c
diff options
context:
space:
mode:
authorGuenter Bartsch <guenter@users.sourceforge.net>2003-01-12 23:20:37 +0000
committerGuenter Bartsch <guenter@users.sourceforge.net>2003-01-12 23:20:37 +0000
commiteaac42f1becbbcc62317e9bf81e07608aaad62fd (patch)
tree6aa81bcbf245576653928f43aac4a6627dbdd30c /src/input/input_dvb.c
parent74d0944f178bc53557b814de4a90d01034890e9a (diff)
downloadxine-lib-eaac42f1becbbcc62317e9bf81e07608aaad62fd.tar.gz
xine-lib-eaac42f1becbbcc62317e9bf81e07608aaad62fd.tar.bz2
DVB plugin updated to new api. thanks to Micael Beronius, Chris Purnell for their great work
CVS patchset: 3884 CVS date: 2003/01/12 23:20:37
Diffstat (limited to 'src/input/input_dvb.c')
-rw-r--r--src/input/input_dvb.c625
1 files changed, 370 insertions, 255 deletions
diff --git a/src/input/input_dvb.c b/src/input/input_dvb.c
index 4bf69b4cd..7dd052e54 100644
--- a/src/input/input_dvb.c
+++ b/src/input/input_dvb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2002 the xine project
+ * Copyright (C) 2000-2003 the xine project
*
* This file is part of xine, a free video player.
*
@@ -38,9 +38,9 @@
#include <sys/ioctl.h>
#include <sys/poll.h>
-#include "ost/dmx.h"
-#include "ost/sec.h"
-#include "ost/frontend.h"
+/* These will eventually be #include <linux/dvb/...> */
+#include "dvb/dmx.h"
+#include "dvb/frontend.h"
#include "xine_internal.h"
#include "xineutils.h"
@@ -51,43 +51,34 @@
#define LOG
*/
-#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 FRONTEND_DEVICE "/dev/dvb/adapter0/frontend0"
+#define DEMUX_DEVICE "/dev/dvb/adapter0/demux0"
+#define DVR_DEVICE "/dev/dvb/adapter0/dvr0"
#define BUFSIZE 4096
#define NOPID 0xffff
typedef struct {
- int fd_frontend;
- int fd_sec;
- int fd_demuxa, fd_demuxv, fd_demuxtt;
+ int fd_frontend;
+ int fd_demuxa, fd_demuxv;
- FrontendInfo feinfo;
- FrontendParameters front_param;
+ struct dvb_frontend_info feinfo;
- struct secCommand scmd;
- struct secCmdSequence scmds;
- struct dmxPesFilterParams pesFilterParamsV;
- struct dmxPesFilterParams pesFilterParamsA;
- struct dmxPesFilterParams pesFilterParamsTT;
+ struct dmx_pes_filter_params pesFilterParamsV;
+ struct dmx_pes_filter_params pesFilterParamsA;
} 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;
-
+ struct dvb_frontend_parameters front_param;
+ int vpid;
+ int apid;
+ int sat_no;
+ int tone;
+ int pol;
} channel_t;
typedef struct {
@@ -106,13 +97,13 @@ typedef struct {
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;
@@ -127,10 +118,84 @@ typedef struct {
/* scratch buffer for forward seeking */
char seek_buf[BUFSIZE];
- int out_fd; /* recording function */
-
} dvb_input_plugin_t;
+typedef struct {
+ char *name;
+ int value;
+} Param;
+
+static const Param inversion_list [] = {
+ { "INVERSION_OFF", INVERSION_OFF },
+ { "INVERSION_ON", INVERSION_ON },
+ { "INVERSION_AUTO", INVERSION_AUTO },
+ { NULL, 0 }
+};
+
+static const Param bw_list [] = {
+ { "BANDWIDTH_6_MHZ", BANDWIDTH_6_MHZ },
+ { "BANDWIDTH_7_MHZ", BANDWIDTH_7_MHZ },
+ { "BANDWIDTH_8_MHZ", BANDWIDTH_8_MHZ },
+ { NULL, 0 }
+};
+
+static const Param fec_list [] = {
+ { "FEC_1_2", FEC_1_2 },
+ { "FEC_2_3", FEC_2_3 },
+ { "FEC_3_4", FEC_3_4 },
+ { "FEC_4_5", FEC_4_5 },
+ { "FEC_5_6", FEC_5_6 },
+ { "FEC_6_7", FEC_6_7 },
+ { "FEC_7_8", FEC_7_8 },
+ { "FEC_8_9", FEC_8_9 },
+ { "FEC_AUTO", FEC_AUTO },
+ { "FEC_NONE", FEC_NONE },
+ { NULL, 0 }
+};
+
+static const Param guard_list [] = {
+ {"GUARD_INTERVAL_1_16", GUARD_INTERVAL_1_16},
+ {"GUARD_INTERVAL_1_32", GUARD_INTERVAL_1_32},
+ {"GUARD_INTERVAL_1_4", GUARD_INTERVAL_1_4},
+ {"GUARD_INTERVAL_1_8", GUARD_INTERVAL_1_8},
+ { NULL, 0 }
+};
+
+static const Param hierarchy_list [] = {
+ { "HIERARCHY_1", HIERARCHY_1 },
+ { "HIERARCHY_2", HIERARCHY_2 },
+ { "HIERARCHY_4", HIERARCHY_4 },
+ { "HIERARCHY_NONE", HIERARCHY_NONE },
+ { NULL, 0 }
+};
+
+static const Param qam_list [] = {
+ { "QPSK", QPSK },
+ { "QAM_128", QAM_128 },
+ { "QAM_16", QAM_16 },
+ { "QAM_256", QAM_256 },
+ { "QAM_32", QAM_32 },
+ { "QAM_64", QAM_64 },
+ { NULL, 0 }
+};
+
+static const Param transmissionmode_list [] = {
+ { "TRANSMISSION_MODE_2K", TRANSMISSION_MODE_2K },
+ { "TRANSMISSION_MODE_8K", TRANSMISSION_MODE_8K },
+ { NULL, 0 }
+};
+
+static void tuner_dispose (tuner_t *this) {
+
+ if (this->fd_frontend >= 0)
+ close (this->fd_frontend);
+ if (this->fd_demuxa >= 0)
+ close (this->fd_demuxa);
+ if (this->fd_demuxv >= 0)
+ close (this->fd_demuxv);
+
+ free (this);
+}
static tuner_t *tuner_init () {
@@ -138,69 +203,52 @@ static tuner_t *tuner_init () {
this = malloc (sizeof (tuner_t));
+ this->fd_frontend = -1;
+ this->fd_demuxa = -1;
+ this->fd_demuxv = -1;
+
if ((this->fd_frontend = open(FRONTEND_DEVICE, O_RDWR)) < 0){
- perror("FRONTEND DEVICE: ");
- free (this);
+ perror("FRONTEND DEVICE");
+ tuner_dispose(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);
+ if ((ioctl (this->fd_frontend, FE_GET_INFO, &this->feinfo)) < 0) {
+ perror("FE_GET_INFO");
+ tuner_dispose(this);
return NULL;
}
this->fd_demuxa = open (DEMUX_DEVICE, O_RDWR);
if (this->fd_demuxa < 0) {
- perror ("DEMUX DEVICE audio: ");
- free (this);
+ perror ("DEMUX DEVICE audio");
+ tuner_dispose(this);
return NULL;
}
this->fd_demuxv=open (DEMUX_DEVICE, O_RDWR);
if (this->fd_demuxv < 0) {
- perror ("DEMUX DEVICE video: ");
- free (this);
+ perror ("DEMUX DEVICE video");
+ tuner_dispose(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);
+ ioctl (this->fd_demuxv, DMX_STOP);
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;
+ this->pesFilterParamsV.pid = vpid;
+ this->pesFilterParamsV.input = DMX_IN_FRONTEND;
+ this->pesFilterParamsV.output = DMX_OUT_TS_TAP;
+ this->pesFilterParamsV.pes_type = DMX_PES_VIDEO;
+ this->pesFilterParamsV.flags = DMX_IMMEDIATE_START;
if (ioctl(this->fd_demuxv, DMX_SET_PES_FILTER,
&this->pesFilterParamsV) < 0)
perror("set_vpid");
@@ -208,155 +256,100 @@ static void tuner_set_vpid (tuner_t *this, ushort 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);
+ ioctl (this->fd_demuxa, DMX_STOP);
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;
+
+ this->pesFilterParamsA.pid = apid;
+ this->pesFilterParamsA.input = DMX_IN_FRONTEND;
+ this->pesFilterParamsA.output = DMX_OUT_TS_TAP;
+ this->pesFilterParamsA.pes_type = 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) {
+static int tuner_set_diseqc(tuner_t *this, channel_t *c)
+{
+ struct dvb_diseqc_master_cmd cmd =
+ {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4};
- 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");
- }
-}
+ cmd.msg[3] = 0xf0 | ((c->sat_no * 4) & 0x0f) |
+ (c->tone ? 1 : 0) | (c->pol ? 0 : 2);
-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) {
+ if (ioctl(this->fd_frontend, FE_SET_TONE, SEC_TONE_OFF) < 0)
+ return 0;
+ if (ioctl(this->fd_frontend, FE_SET_VOLTAGE,
+ c->pol ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18) < 0)
+ return 0;
+ usleep(15000);
+ if (ioctl(this->fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) < 0)
+ return 0;
+ usleep(15000);
+ if (ioctl(this->fd_frontend, FE_DISEQC_SEND_BURST,
+ (c->sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A) < 0)
+ return 0;
+ usleep(15000);
+ if (ioctl(this->fd_frontend, FE_SET_TONE,
+ c->tone ? SEC_TONE_ON : SEC_TONE_OFF) < 0)
+ return 0;
- 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);
+ return 1;
}
-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, struct dvb_frontend_parameters
+ *front_param) {
+ fe_status_t status;
-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)
+ 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;
- }
+ do {
+ if (ioctl(this->fd_frontend, FE_READ_STATUS, &status) < 0) {
+ perror("fe get event");
+ return 0;
+ }
+ printf("input_dvb: status: %x\n", status);
+ if (status & FE_HAS_LOCK) {
+ return 1;
}
+ usleep(500000);
}
- return 0;
-}
-
+ while (!(status & FE_TIMEDOUT));
-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);
+ return 0;
}
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",
+ printf ("input_dvb: channel '%s' freq %d vpid %d apid %d\n",
channel->name,
- channel->diseqcnr,
- channel->freq,
- channel->volt,
- channel->srate,
- channel->fec,
+ channel->front_param.frequency,
channel->vpid,
channel->apid);
-
}
-static int tuner_set_channel (tuner_t *this,
+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))
+ tuner_set_vpid (this, 0);
+ tuner_set_apid (this, 0);
+
+ if (this->feinfo.type==FE_QPSK) {
+ if (!tuner_set_diseqc(this, c))
+ return 0;
+ }
+
+ if (!tuner_tune_it (this, &c->front_param))
return 0;
-
+
tuner_set_vpid (this, c->vpid);
tuner_set_apid (this, c->apid);
- tuner_set_ttpid (this, 0);
-
+
return 1; /* fixme: error handling */
}
@@ -364,15 +357,15 @@ static void osd_show_channel (dvb_input_plugin_t *this) {
int i, channel ;
- this->stream->osd_renderer->filled_rect (this->osd, 0, 0, 395, 400, 2);
+ 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,
+ this->stream->osd_renderer->render_text (this->osd, 10, 10+i*35,
+ this->channels[channel].name,
OSD_TEXT3);
channel ++;
}
@@ -394,7 +387,7 @@ static void switch_channel (dvb_input_plugin_t *this) {
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);
@@ -408,11 +401,11 @@ static void switch_channel (dvb_input_plugin_t *this) {
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);
this->stream->osd_renderer->hide (this->osd, 0);
@@ -440,27 +433,27 @@ static void dvb_event_handler (dvb_input_plugin_t *this) {
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;
@@ -469,7 +462,7 @@ static void dvb_event_handler (dvb_input_plugin_t *this) {
this->stream->osd_renderer->hide (this->osd, 0);
break;
-#if 0
+#if 0
default:
printf ("input_dvb: got an event, type 0x%08x\n", event->type);
#endif
@@ -479,7 +472,9 @@ static void dvb_event_handler (dvb_input_plugin_t *this) {
}
}
-static off_t dvb_plugin_read (input_plugin_t *this_gen,
+
+
+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;
@@ -511,14 +506,11 @@ static off_t dvb_plugin_read (input_plugin_t *this_gen,
}
}
- 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,
+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);
@@ -527,7 +519,7 @@ static buf_element_t *dvb_plugin_read_block (input_plugin_t *this_gen,
buf->content = buf->mem;
buf->type = BUF_DEMUX_BLOCK;
-
+
total_bytes = dvb_plugin_read (this_gen, buf->content, todo);
if (total_bytes != todo) {
@@ -540,7 +532,7 @@ static buf_element_t *dvb_plugin_read_block (input_plugin_t *this_gen,
return buf;
}
-static off_t dvb_plugin_seek (input_plugin_t *this_gen, off_t offset,
+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;
@@ -593,12 +585,11 @@ static void dvb_plugin_dispose (input_plugin_t *this_gen) {
this->nbc = NULL;
}
- if (this->out_fd>0)
- close (this->out_fd);
-
xine_event_dispose_queue (this->event_queue);
free (this->mrl);
+ free (this->channels);
+ tuner_dispose ( ((dvb_input_plugin_t *)this)->tuner );
free (this);
}
@@ -608,21 +599,28 @@ static char* dvb_plugin_get_mrl (input_plugin_t *this_gen) {
return this->mrl;
}
-static int dvb_plugin_get_optional_data (input_plugin_t *this_gen,
+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) {
+static int find_param(const Param *list, const char *name)
+{
+ while (list->name && strcmp(list->name, name))
+ list++;
+ return list->value;;
+}
+
+static channel_t *load_channels (int *num_ch, fe_type_t fe_type) {
- FILE *f;
- unsigned char str[BUFSIZE];
- unsigned char filename[BUFSIZE];
- channel_t *channels;
- int num_channels;
+ FILE *f;
+ char str[BUFSIZE];
+ char filename[BUFSIZE];
+ channel_t *channels;
+ int num_channels;
- snprintf (filename, BUFSIZE, "%s/.xine/dvb_channels", xine_get_homedir());
+ snprintf (filename, BUFSIZE, "%s/.xine/channels.conf", xine_get_homedir());
f = fopen (filename, "rb");
if (!f) {
@@ -635,7 +633,6 @@ static channel_t *load_channels (int *num_ch) {
*/
num_channels = 0;
while ( fgets (str, BUFSIZE, f)) {
- fgets (str, BUFSIZE, f);
num_channels++;
}
fclose (f);
@@ -650,53 +647,175 @@ static channel_t *load_channels (int *num_ch) {
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;
+
+ unsigned long freq;
+ char *field, *tmp;
+
+ tmp = str;
+ if (!(field = strsep(&tmp, ":")))
+ continue;
+
+ channels[num_channels].name = strdup(field);
+
+ if (!(field = strsep(&tmp, ":")))
+ continue;
+
+ freq = strtoul(field, NULL, 0);
+
+ switch (fe_type)
+ {
+ case FE_QPSK:
+
+ if (freq > 11700) {
+ channels[num_channels].front_param.frequency = (freq - 10600)*1000;
+ channels[num_channels].tone = 1;
+ } else {
+ channels[num_channels].front_param.frequency = (freq - 9750)*1000;
+ channels[num_channels].tone = 0;
+ }
+
+ channels[num_channels].front_param.inversion = INVERSION_OFF;
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].pol = (field[0] == 'h' ? 0 : 1);
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].sat_no = strtoul(field, NULL, 0);
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.u.qpsk.symbol_rate =
+ strtoul(field, NULL, 0) * 1000;
+
+ channels[num_channels].front_param.u.qpsk.fec_inner = FEC_AUTO;
+
+ break;
+
+ case FE_QAM:
+
+ channels[num_channels].front_param.frequency = freq;
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.inversion =
+ find_param(inversion_list, field);
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.u.qam.symbol_rate =
+ strtoul(field, NULL, 0);
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.u.qam.fec_inner =
+ find_param(fec_list, field);
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.u.qam.modulation =
+ find_param(qam_list, field);
+
+ break;
+
+ case FE_OFDM:
+
+ channels[num_channels].front_param.frequency = freq;
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.inversion =
+ find_param(inversion_list, field);
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.u.ofdm.bandwidth =
+ find_param(bw_list, field);
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.u.ofdm.code_rate_HP =
+ find_param(fec_list, field);
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.u.ofdm.code_rate_LP =
+ find_param(fec_list, field);
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.u.ofdm.constellation =
+ find_param(qam_list, field);
+
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.u.ofdm.transmission_mode =
+ find_param(transmissionmode_list, field);
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.u.ofdm.guard_interval =
+ find_param(guard_list, field);
+
+ if (!(field = strsep(&tmp, ":")))
+ break;
+
+ channels[num_channels].front_param.u.ofdm.hierarchy_information =
+ find_param(hierarchy_list, field);
+
+ break;
+
}
+ if (!(field = strsep(&tmp, ":")))
+ continue;
+
+ channels[num_channels].vpid = strtoul(field, NULL, 0);
+
+ if (!(field = strsep(&tmp, ":")))
+ continue;
+
+ channels[num_channels].apid = strtoul(field, NULL, 0);
+
#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,
+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_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))
+ if (strncasecmp (mrl, "dvb:/",5))
return NULL;
if ( !(tuner = tuner_init()) ) {
@@ -704,11 +823,11 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen,
return NULL;
}
- if ( !(channels = load_channels(&num_channels)) ) {
+ if ( !(channels = load_channels(&num_channels, tuner->feinfo.type)) ) {
tuner_dispose (tuner);
return NULL;
}
-
+
this = (dvb_input_plugin_t *) xine_xmalloc (sizeof(dvb_input_plugin_t));
this->tuner = tuner;
@@ -719,17 +838,21 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen,
if (!tuner_set_channel (this->tuner, &this->channels[this->channel])) {
printf ("input_dvb: tuner_set_channel failed\n");
+ tuner_dispose(this->tuner);
+ free(this->channels);
free (this);
return NULL;
}
if ((this->fd = open (DVR_DEVICE, O_RDONLY)) < 0){
printf ("input_dvb: cannot open dvr device '%s'\n", DVR_DEVICE);
+ tuner_dispose(this->tuner);
+ free(this->channels);
free (this);
return NULL;
}
- this->mrl = strdup(mrl);
+ this->mrl = strdup(mrl);
this->curpos = 0;
this->nbc = nbc_init (stream);
@@ -755,15 +878,9 @@ static input_plugin_t *open_plugin (input_class_t *cls_gen,
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);
- this->osd = this->stream->osd_renderer->new_object (this->stream->osd_renderer,
+ 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);
@@ -787,9 +904,7 @@ static char *dvb_class_get_identifier (input_class_t *this_gen) {
}
static void dvb_class_dispose (input_class_t *this_gen) {
-
- dvb_input_class_t *cls = (dvb_input_class_t *) this_gen;
-
+ dvb_input_class_t *cls = (dvb_input_class_t *) this_gen;
free (cls);
}
@@ -797,9 +912,9 @@ 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,
+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;
+ dvb_input_class_t *cls = (dvb_input_class_t *) this_gen;
*num_files = 1;
return cls->mrls;
@@ -835,7 +950,7 @@ static void *init_class (xine_t *xine, void *data) {
*/
plugin_info_t xine_plugin_info[] = {
- /* type, API, "name", version, special_info, init_function */
+ /* type, API, "name", version, special_info, init_function */
{ PLUGIN_INPUT, 11, "DVB", XINE_VERSION_CODE, NULL, init_class },
{ PLUGIN_NONE, 0, "", 0, NULL, NULL }
};