~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libmpdemux/dvbin.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:45:33 UTC
  • Revision ID: siretart@tauware.de-20060708084533-dbc155bde7122e78
imported mplayer_0.99+1.0pre7try2+cvs20060117

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
dvbstream
 
4
(C) Dave Chapman <dave@dchapman.com> 2001, 2002.
 
5
 
 
6
The latest version can be found at http://www.linuxstb.org/dvbstream
 
7
 
 
8
Modified for use with MPlayer, for details see the CVS changelog at
 
9
http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
 
10
$Id: dvbin.c,v 1.16 2005/11/18 14:39:19 diego Exp $
 
11
 
 
12
Copyright notice:
 
13
 
 
14
This program is free software; you can redistribute it and/or modify
 
15
it under the terms of the GNU General Public License as published by
 
16
the Free Software Foundation; either version 2 of the License, or
 
17
(at your option) any later version.
 
18
 
 
19
This program is distributed in the hope that it will be useful,
 
20
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
21
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
22
GNU General Public License for more details.
 
23
 
 
24
You should have received a copy of the GNU General Public License
 
25
along with this program; if not, write to the Free Software
 
26
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
27
 
 
28
*/
 
29
 
 
30
#include "config.h"
 
31
#include <stdio.h>
 
32
#include <stdlib.h>
 
33
#include <string.h>
 
34
#include <ctype.h>
 
35
#include <sys/ioctl.h>
 
36
#include <sys/time.h>
 
37
#include <sys/poll.h>
 
38
#include <unistd.h>
 
39
#include <fcntl.h>
 
40
#include <string.h>
 
41
#include <errno.h>
 
42
#include <fcntl.h>
 
43
 
 
44
#include "stream.h"
 
45
#include "demuxer.h"
 
46
#include "help_mp.h"
 
47
#include "m_option.h"
 
48
#include "m_struct.h"
 
49
 
 
50
#include "dvbin.h"
 
51
 
 
52
 
 
53
#define MAX_CHANNELS 8
 
54
#define CHANNEL_LINE_LEN 256
 
55
#define min(a, b) ((a) <= (b) ? (a) : (b))
 
56
 
 
57
 
 
58
//TODO: CAMBIARE list_ptr e da globale a per_priv
 
59
 
 
60
 
 
61
static struct stream_priv_s
 
62
{
 
63
        char *prog;
 
64
        int card;
 
65
        char *type;
 
66
        int vid, aid;
 
67
        char *file;
 
68
}
 
69
stream_defaults =
 
70
{
 
71
        "", 1, "", 0, 0, NULL
 
72
};
 
73
 
 
74
#define ST_OFF(f) M_ST_OFF(struct stream_priv_s, f)
 
75
 
 
76
/// URL definition
 
77
static m_option_t stream_params[] = {
 
78
        {"prog", ST_OFF(prog), CONF_TYPE_STRING, 0, 0 ,0, NULL},
 
79
        {"card", ST_OFF(card), CONF_TYPE_INT, M_OPT_RANGE, 1, 4, NULL},
 
80
        {"type", ST_OFF(type), CONF_TYPE_STRING, 0, 0 ,0, NULL},
 
81
        {"vid",  ST_OFF(vid),  CONF_TYPE_INT, 0, 0 ,0, NULL},
 
82
        {"aid",  ST_OFF(aid),  CONF_TYPE_INT, 0, 0 ,0, NULL},
 
83
        {"file", ST_OFF(file), CONF_TYPE_STRING, 0, 0 ,0, NULL},
 
84
 
 
85
        {"hostname",    ST_OFF(prog), CONF_TYPE_STRING, 0, 0, 0, NULL },
 
86
        {"username",    ST_OFF(card), CONF_TYPE_INT, M_OPT_RANGE, 1, 4, NULL},
 
87
        {NULL, NULL, 0, 0, 0, 0, NULL}
 
88
};
 
89
 
 
90
static struct m_struct_st stream_opts = {
 
91
        "dvbin",
 
92
        sizeof(struct stream_priv_s),
 
93
        &stream_defaults,
 
94
        stream_params
 
95
};
 
96
 
 
97
 
 
98
 
 
99
m_option_t dvbin_opts_conf[] = {
 
100
        {"prog", &stream_defaults.prog, CONF_TYPE_STRING, 0, 0 ,0, NULL},
 
101
        {"card", &stream_defaults.card, CONF_TYPE_INT, M_OPT_RANGE, 1, 4, NULL},
 
102
        {"type", "DVB card type is autodetected and can't be overridden\n", CONF_TYPE_PRINT, CONF_NOCFG, 0 ,0, NULL},
 
103
        {"vid",  &stream_defaults.vid,  CONF_TYPE_INT, 0, 0 ,0, NULL},
 
104
        {"aid",  &stream_defaults.aid,  CONF_TYPE_INT, 0, 0 ,0, NULL},
 
105
        {"file", &stream_defaults.file, CONF_TYPE_STRING, 0, 0 ,0, NULL},
 
106
 
 
107
        {NULL, NULL, 0, 0, 0, 0, NULL}
 
108
};
 
109
 
 
110
 
 
111
 
 
112
 
 
113
extern int dvb_set_ts_filt(int fd, uint16_t pid, dmx_pes_type_t pestype);
 
114
extern int dvb_demux_stop(int fd);
 
115
extern int dvb_get_tuner_type(int fd);
 
116
int dvb_open_devices(dvb_priv_t *priv, int n, int demux_cnt, int *pids);
 
117
int dvb_fix_demuxes(dvb_priv_t *priv, int cnt, int *pids);
 
118
 
 
119
extern int dvb_tune(dvb_priv_t *priv, int freq, char pol, int srate, int diseqc, int tone,
 
120
                fe_spectral_inversion_t specInv, fe_modulation_t modulation, fe_guard_interval_t guardInterval,
 
121
                fe_transmit_mode_t TransmissionMode, fe_bandwidth_t bandWidth, fe_code_rate_t HP_CodeRate,
 
122
                fe_code_rate_t LP_CodeRate, fe_hierarchy_t hier);
 
123
extern char *dvb_dvrdev[4], *dvb_demuxdev[4], *dvb_frontenddev[4];
 
124
 
 
125
static dvb_config_t *dvb_config = NULL;
 
126
 
 
127
 
 
128
static dvb_channels_list *dvb_get_channels(char *filename, int type)
 
129
{
 
130
        dvb_channels_list  *list;
 
131
        FILE *f;
 
132
        char line[CHANNEL_LINE_LEN], *colon;
 
133
 
 
134
        int fields, cnt, pcnt, k;
 
135
        dvb_channel_t *ptr, *tmp, chn;
 
136
        char tmp_lcr[256], tmp_hier[256], inv[256], bw[256], cr[256], mod[256], transm[256], gi[256], vpid_str[256], apid_str[256];
 
137
        const char *cbl_conf = "%d:%255[^:]:%d:%255[^:]:%255[^:]:%255[^:]:%255[^:]\n";
 
138
        const char *sat_conf = "%d:%c:%d:%d:%255[^:]:%255[^:]\n";
 
139
        const char *ter_conf = "%d:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]\n";
 
140
        const char *atsc_conf = "%d:%255[^:]:%255[^:]:%255[^:]\n";
 
141
        
 
142
        mp_msg(MSGT_DEMUX, MSGL_V, "CONFIG_READ FILE: %s, type: %d\n", filename, type);
 
143
        if((f=fopen(filename, "r"))==NULL)
 
144
        {
 
145
                mp_msg(MSGT_DEMUX, MSGL_FATAL, "CAN'T READ CONFIG FILE %s\n", filename);
 
146
                return NULL;
 
147
        }
 
148
 
 
149
        list = malloc(sizeof(dvb_channels_list));
 
150
        if(list == NULL)
 
151
        {
 
152
                mp_msg(MSGT_DEMUX, MSGL_V, "DVB_GET_CHANNELS: couldn't malloc enough memory\n");
 
153
                return NULL;
 
154
        }
 
155
 
 
156
        ptr = &chn;
 
157
        list->NUM_CHANNELS = 0;
 
158
        list->channels = NULL;
 
159
        while(! feof(f))
 
160
        {
 
161
                if( fgets(line, CHANNEL_LINE_LEN, f) == NULL )
 
162
                        continue;
 
163
 
 
164
                if((line[0] == '#') || (strlen(line) == 0))
 
165
                        continue;
 
166
 
 
167
                colon = index(line, ':');
 
168
                if(colon)
 
169
                {
 
170
                        k = colon - line;
 
171
                        if(!k)
 
172
                                continue;
 
173
                        ptr->name = (char*) malloc(k+1);
 
174
                        if(! ptr->name)
 
175
                                continue;
 
176
                        strncpy(ptr->name, line, k);
 
177
                        ptr->name[k] = 0;
 
178
                }
 
179
                else
 
180
                        continue;
 
181
                k++;
 
182
                apid_str[0] = vpid_str[0] = 0;
 
183
                ptr->pids_cnt = 0;
 
184
                ptr->freq = 0;
 
185
                if(type == TUNER_TER)
 
186
                {
 
187
                        fields = sscanf(&line[k], ter_conf,
 
188
                                &ptr->freq, inv, bw, cr, tmp_lcr, mod,
 
189
                                transm, gi, tmp_hier, vpid_str, apid_str);
 
190
                        mp_msg(MSGT_DEMUX, MSGL_V,
 
191
                                "TER, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d",
 
192
                                list->NUM_CHANNELS, fields, ptr->name, ptr->freq);
 
193
                }
 
194
                else if(type == TUNER_CBL)
 
195
                {
 
196
                        fields = sscanf(&line[k], cbl_conf,
 
197
                                &ptr->freq, inv, &ptr->srate,
 
198
                                cr, mod, vpid_str, apid_str);
 
199
                        mp_msg(MSGT_DEMUX, MSGL_V,
 
200
                                "CBL, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, SRATE: %d",
 
201
                                list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate);
 
202
                }
 
203
#ifdef DVB_ATSC
 
204
                else if(type == TUNER_ATSC)
 
205
                {
 
206
                        fields = sscanf(&line[k], atsc_conf,
 
207
                                 &ptr->freq, mod, vpid_str, apid_str);
 
208
                        mp_msg(MSGT_DEMUX, MSGL_V,
 
209
                                "ATSC, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d\n",
 
210
                                list->NUM_CHANNELS, fields, ptr->name, ptr->freq);
 
211
                }
 
212
#endif
 
213
                else //SATELLITE
 
214
                {
 
215
                        fields = sscanf(&line[k], sat_conf,
 
216
                                &ptr->freq, &ptr->pol, &ptr->diseqc, &ptr->srate, vpid_str, apid_str);
 
217
                        ptr->pol = toupper(ptr->pol);
 
218
                        ptr->freq *=  1000UL;
 
219
                        ptr->srate *=  1000UL;
 
220
                        ptr->tone = -1;
 
221
                        ptr->inv = INVERSION_AUTO;
 
222
                        ptr->cr = FEC_AUTO;
 
223
                        if((ptr->diseqc > 4) || (ptr->diseqc < 0))
 
224
                            continue;
 
225
                        if(ptr->diseqc > 0)
 
226
                            ptr->diseqc--;
 
227
                        mp_msg(MSGT_DEMUX, MSGL_V,
 
228
                                "SAT, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, SRATE: %d, POL: %c, DISEQC: %d",
 
229
                                list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate, ptr->pol, ptr->diseqc);
 
230
                }
 
231
 
 
232
                if(vpid_str[0])
 
233
                {
 
234
                        pcnt = sscanf(vpid_str, "%d+%d+%d+%d+%d+%d+%d", &ptr->pids[0], &ptr->pids[1], &ptr->pids[2], &ptr->pids[3],
 
235
                                &ptr->pids[4], &ptr->pids[5], &ptr->pids[6]);
 
236
                        if(pcnt > 0)
 
237
                        {
 
238
                                ptr->pids_cnt = pcnt;
 
239
                                fields++;
 
240
                        }
 
241
                }
 
242
                
 
243
                if(apid_str[0])
 
244
                {
 
245
                        cnt = ptr->pids_cnt;
 
246
                        pcnt = sscanf(apid_str, "%d+%d+%d+%d+%d+%d+%d+%d", &ptr->pids[cnt], &ptr->pids[cnt+1], &ptr->pids[cnt+2],
 
247
                                &ptr->pids[cnt+3], &ptr->pids[cnt+4], &ptr->pids[cnt+5], &ptr->pids[cnt+6], &ptr->pids[cnt+7]);
 
248
                        if(pcnt > 0)
 
249
                        {
 
250
                                ptr->pids_cnt += pcnt;
 
251
                                fields++;
 
252
                        }
 
253
                }
 
254
 
 
255
                if((fields < 2) || (ptr->pids_cnt <= 0) || (ptr->freq == 0) || (strlen(ptr->name) == 0))
 
256
                        continue;
 
257
 
 
258
 
 
259
                ptr->pids[ptr->pids_cnt] = 0;   //PID 0 is the PAT
 
260
                ptr->pids_cnt++;
 
261
                mp_msg(MSGT_DEMUX, MSGL_V, " PIDS: ");
 
262
                for(cnt = 0; cnt < ptr->pids_cnt; cnt++)
 
263
                        mp_msg(MSGT_DEMUX, MSGL_V, " %d ", ptr->pids[cnt]);
 
264
                mp_msg(MSGT_DEMUX, MSGL_V, "\n");
 
265
                
 
266
                if((type == TUNER_TER) || (type == TUNER_CBL))
 
267
                {
 
268
                        if(! strcmp(inv, "INVERSION_ON"))
 
269
                                ptr->inv = INVERSION_ON;
 
270
                        else if(! strcmp(inv, "INVERSION_OFF"))
 
271
                                ptr->inv = INVERSION_OFF;
 
272
                        else
 
273
                                ptr->inv = INVERSION_AUTO;
 
274
 
 
275
 
 
276
                        if(! strcmp(cr, "FEC_1_2"))
 
277
                                ptr->cr =FEC_1_2;
 
278
                        else if(! strcmp(cr, "FEC_2_3"))
 
279
                                ptr->cr =FEC_2_3;
 
280
                        else if(! strcmp(cr, "FEC_3_4"))
 
281
                                ptr->cr =FEC_3_4;
 
282
#ifdef HAVE_DVB_HEAD
 
283
                        else if(! strcmp(cr, "FEC_4_5"))
 
284
                                ptr->cr =FEC_4_5;
 
285
                        else if(! strcmp(cr, "FEC_6_7"))
 
286
                                ptr->cr =FEC_6_7;
 
287
                        else if(! strcmp(cr, "FEC_8_9"))
 
288
                                ptr->cr =FEC_8_9;
 
289
#endif
 
290
                        else if(! strcmp(cr, "FEC_5_6"))
 
291
                                ptr->cr =FEC_5_6;
 
292
                        else if(! strcmp(cr, "FEC_7_8"))
 
293
                                ptr->cr =FEC_7_8;
 
294
                        else if(! strcmp(cr, "FEC_NONE"))
 
295
                                ptr->cr =FEC_NONE;
 
296
                        else ptr->cr =FEC_AUTO;
 
297
                }
 
298
        
 
299
 
 
300
                if((type == TUNER_TER) || (type == TUNER_CBL) || (type == TUNER_ATSC))
 
301
                {
 
302
                        if(! strcmp(mod, "QAM_128"))
 
303
                                ptr->mod = QAM_128;
 
304
                        else if(! strcmp(mod, "QAM_256"))
 
305
                                ptr->mod = QAM_256;
 
306
                        else if(! strcmp(mod, "QAM_64"))
 
307
                                ptr->mod = QAM_64;
 
308
                        else if(! strcmp(mod, "QAM_32"))
 
309
                                ptr->mod = QAM_32;
 
310
                        else if(! strcmp(mod, "QAM_16"))
 
311
                                ptr->mod = QAM_16;
 
312
#ifdef DVB_ATSC 
 
313
                        else if(! strcmp(mod, "VSB_8") || ! strcmp(mod, "8VSB"))
 
314
                                ptr->mod = VSB_8;
 
315
                        else if(! strcmp(mod, "VSB_16") || !strcmp(mod, "16VSB"))
 
316
                                ptr->mod = VSB_16;
 
317
 
 
318
                        ptr->inv = INVERSION_AUTO;
 
319
#endif
 
320
                }
 
321
 
 
322
                if(type == TUNER_TER)
 
323
                {
 
324
                        if(! strcmp(bw, "BANDWIDTH_6_MHZ"))
 
325
                                ptr->bw = BANDWIDTH_6_MHZ;
 
326
                        else if(! strcmp(bw, "BANDWIDTH_7_MHZ"))
 
327
                                ptr->bw = BANDWIDTH_7_MHZ;
 
328
                        else if(! strcmp(bw, "BANDWIDTH_8_MHZ"))
 
329
                                ptr->bw = BANDWIDTH_8_MHZ;
 
330
 
 
331
 
 
332
                        if(! strcmp(transm, "TRANSMISSION_MODE_2K"))
 
333
                                ptr->trans = TRANSMISSION_MODE_2K;
 
334
                        else if(! strcmp(transm, "TRANSMISSION_MODE_8K"))
 
335
                                ptr->trans = TRANSMISSION_MODE_8K;
 
336
 
 
337
 
 
338
                        if(! strcmp(gi, "GUARD_INTERVAL_1_32"))
 
339
                                ptr->gi = GUARD_INTERVAL_1_32;
 
340
                        else if(! strcmp(gi, "GUARD_INTERVAL_1_16"))
 
341
                                ptr->gi = GUARD_INTERVAL_1_16;
 
342
                        else if(! strcmp(gi, "GUARD_INTERVAL_1_8"))
 
343
                                ptr->gi = GUARD_INTERVAL_1_8;
 
344
                        else ptr->gi = GUARD_INTERVAL_1_4;
 
345
                        
 
346
                        if(! strcmp(tmp_lcr, "FEC_1_2"))
 
347
                                ptr->cr_lp =FEC_1_2;
 
348
                        else if(! strcmp(tmp_lcr, "FEC_2_3"))
 
349
                                ptr->cr_lp =FEC_2_3;
 
350
                        else if(! strcmp(tmp_lcr, "FEC_3_4"))
 
351
                                ptr->cr_lp =FEC_3_4;
 
352
#ifdef HAVE_DVB_HEAD
 
353
                        else if(! strcmp(tmp_lcr, "FEC_4_5"))
 
354
                                ptr->cr_lp =FEC_4_5;
 
355
                        else if(! strcmp(tmp_lcr, "FEC_6_7"))
 
356
                                ptr->cr_lp =FEC_6_7;
 
357
                        else if(! strcmp(tmp_lcr, "FEC_8_9"))
 
358
                                ptr->cr_lp =FEC_8_9;
 
359
#endif
 
360
                        else if(! strcmp(tmp_lcr, "FEC_5_6"))
 
361
                                ptr->cr_lp =FEC_5_6;
 
362
                        else if(! strcmp(tmp_lcr, "FEC_7_8"))
 
363
                                ptr->cr_lp =FEC_7_8;
 
364
                        else if(! strcmp(tmp_lcr, "FEC_NONE"))
 
365
                                ptr->cr_lp =FEC_NONE;
 
366
                        else ptr->cr_lp =FEC_AUTO;
 
367
                        
 
368
                        
 
369
                        if(! strcmp(tmp_hier, "HIERARCHY_1"))
 
370
                                ptr->hier = HIERARCHY_1;
 
371
                        else if(! strcmp(tmp_hier, "HIERARCHY_2"))
 
372
                                ptr->hier = HIERARCHY_2;
 
373
                        else if(! strcmp(tmp_hier, "HIERARCHY_4"))
 
374
                                ptr->hier = HIERARCHY_4;
 
375
#ifdef HAVE_DVB_HEAD                            
 
376
                        else if(! strcmp(tmp_hier, "HIERARCHY_AUTO"))
 
377
                                ptr->hier = HIERARCHY_AUTO;
 
378
#endif
 
379
                        else    ptr->hier = HIERARCHY_NONE;
 
380
                }
 
381
 
 
382
                tmp = (dvb_channel_t*)realloc(list->channels, sizeof(dvb_channel_t) * (list->NUM_CHANNELS + 1));
 
383
                if(tmp == NULL)
 
384
                        break;
 
385
 
 
386
                list->channels = tmp;
 
387
                memcpy(&(list->channels[list->NUM_CHANNELS]), ptr, sizeof(dvb_channel_t));
 
388
                list->NUM_CHANNELS++;
 
389
        }
 
390
 
 
391
        fclose(f);
 
392
        if(list->NUM_CHANNELS == 0)
 
393
        {
 
394
                if(list->channels != NULL)
 
395
                        free(list->channels);
 
396
                free(list);
 
397
                return NULL;
 
398
        }
 
399
 
 
400
        list->current = 0;
 
401
        return list;
 
402
}
 
403
 
 
404
 
 
405
 
 
406
static int dvb_streaming_read(stream_t *stream, char *buffer, int size)
 
407
{
 
408
        struct pollfd pfds[1];
 
409
        int pos=0, tries, rk, fd;
 
410
        dvb_priv_t *priv  = (dvb_priv_t *) stream->priv;
 
411
 
 
412
        mp_msg(MSGT_DEMUX, MSGL_DBG3, "dvb_streaming_read(%d)\n", size);
 
413
 
 
414
        tries = priv->retry + 1;
 
415
        
 
416
        fd = stream->fd;
 
417
        while(pos < size)
 
418
        {
 
419
                pfds[0].fd = fd;
 
420
                pfds[0].events = POLLIN | POLLPRI;
 
421
 
 
422
                rk = size - pos;
 
423
                if(poll(pfds, 1, 500) <= 0)
 
424
                {
 
425
                        errno = 0;
 
426
                        mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_streaming_read, attempt N. %d failed with errno %d when reading %d bytes\n", tries, errno, size-pos);
 
427
                        if(--tries > 0)
 
428
                                continue;
 
429
                        else
 
430
                                break;
 
431
                }
 
432
                if((rk = read(fd, &buffer[pos], rk)) > 0)
 
433
                {
 
434
                        pos += rk;
 
435
                        mp_msg(MSGT_DEMUX, MSGL_DBG3, "ret (%d) bytes\n", pos);
 
436
                }
 
437
        }
 
438
                
 
439
 
 
440
        if(! pos)
 
441
                mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_streaming_read, return %d bytes\n", pos);
 
442
 
 
443
        return pos;
 
444
}
 
445
 
 
446
static void dvbin_close(stream_t *stream);
 
447
 
 
448
int dvb_set_channel(dvb_priv_t *priv, int card, int n)
 
449
{
 
450
        dvb_channels_list *new_list;
 
451
        dvb_channel_t *channel;
 
452
        int do_tuning;
 
453
        stream_t *stream  = (stream_t*) priv->stream;
 
454
        char buf[4096];
 
455
        dvb_config_t *conf = (dvb_config_t *) priv->config;
 
456
        int devno;
 
457
        int i;
 
458
 
 
459
        if((card < 0) || (card > conf->count))
 
460
        {
 
461
                mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_set_channel: INVALID CARD NUMBER: %d vs %d, abort\n", card, conf->count);
 
462
                return 0;
 
463
        }
 
464
        
 
465
        devno = conf->cards[card].devno;
 
466
        new_list = conf->cards[card].list;
 
467
        if((n > new_list->NUM_CHANNELS) || (n < 0))
 
468
        {
 
469
                mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_set_channel: INVALID CHANNEL NUMBER: %d, for card %d, abort\n", n, card);
 
470
                return 0;
 
471
        }
 
472
        channel = &(new_list->channels[n]);
 
473
        
 
474
        if(priv->is_on) //the fds are already open and we have to stop the demuxers
 
475
        {
 
476
                for(i = 0; i < priv->demux_fds_cnt; i++)
 
477
                        dvb_demux_stop(priv->demux_fds[i]);
 
478
                        
 
479
                priv->retry = 0;
 
480
                while(dvb_streaming_read(stream, buf, 4096) > 0);       //empty both the stream's and driver's buffer
 
481
                if(priv->card != card)
 
482
                {
 
483
                        dvbin_close(stream);
 
484
                        if(! dvb_open_devices(priv, devno, channel->pids_cnt, channel->pids))
 
485
                        {
 
486
                                mp_msg(MSGT_DEMUX, MSGL_ERR, "DVB_SET_CHANNEL, COULDN'T OPEN DEVICES OF CARD: %d, EXIT\n", card);
 
487
                                return 0;
 
488
                        }
 
489
                        strcpy(priv->prev_tuning, "");
 
490
                }
 
491
                else    //close all demux_fds with pos > pids required for the new channel or open other demux_fds if we have too few
 
492
                {       
 
493
                        if(! dvb_fix_demuxes(priv, channel->pids_cnt, channel->pids))
 
494
                                return 0;
 
495
                }
 
496
        }
 
497
        else
 
498
        {
 
499
                if(! dvb_open_devices(priv, devno, channel->pids_cnt, channel->pids))
 
500
                {
 
501
                        mp_msg(MSGT_DEMUX, MSGL_ERR, "DVB_SET_CHANNEL2, COULDN'T OPEN DEVICES OF CARD: %d, EXIT\n", card);
 
502
                        return 0;
 
503
                }
 
504
                strcpy(priv->prev_tuning, "");
 
505
        }
 
506
 
 
507
        dvb_config->priv = priv;
 
508
        priv->card = card;
 
509
        priv->list = new_list;
 
510
        priv->retry = 5;
 
511
        new_list->current = n;
 
512
        stream->fd = priv->dvr_fd;
 
513
        mp_msg(MSGT_DEMUX, MSGL_V, "DVB_SET_CHANNEL: new channel name=%s, card: %d, channel %d\n", channel->name, card, n);
 
514
 
 
515
        switch(priv->tuner_type)
 
516
        {
 
517
                case TUNER_SAT:
 
518
                        sprintf(priv->new_tuning, "%d|%09d|%09d|%d|%c", priv->card, channel->freq, channel->srate, channel->diseqc, channel->pol);
 
519
                        break;
 
520
 
 
521
                case TUNER_TER:
 
522
                        sprintf(priv->new_tuning, "%d|%09d|%d|%d|%d|%d|%d|%d", priv->card, channel->freq, channel->inv,
 
523
                                channel->bw, channel->cr, channel->mod, channel->trans, channel->gi);
 
524
                  break;
 
525
 
 
526
                case TUNER_CBL:
 
527
                        sprintf(priv->new_tuning, "%d|%09d|%d|%d|%d|%d", priv->card, channel->freq, channel->inv, channel->srate,
 
528
                                channel->cr, channel->mod);
 
529
                break;
 
530
#ifdef DVB_ATSC
 
531
                case TUNER_ATSC:
 
532
                        sprintf(priv->new_tuning, "%d|%09d|%d", priv->card, channel->freq, channel->mod);
 
533
                break;
 
534
#endif
 
535
        }
 
536
 
 
537
 
 
538
 
 
539
        if(strcmp(priv->prev_tuning, priv->new_tuning))
 
540
        {
 
541
                mp_msg(MSGT_DEMUX, MSGL_V, "DIFFERENT TUNING THAN THE PREVIOUS: %s  -> %s\n", priv->prev_tuning, priv->new_tuning);
 
542
                strcpy(priv->prev_tuning, priv->new_tuning);
 
543
                do_tuning = 1;
 
544
        }
 
545
        else
 
546
        {
 
547
                mp_msg(MSGT_DEMUX, MSGL_V, "SAME TUNING PARAMETERS, NO TUNING\n");
 
548
                do_tuning = 0;
 
549
        }
 
550
 
 
551
        stream->eof=1;
 
552
        stream_reset(stream);
 
553
 
 
554
 
 
555
        if(do_tuning)
 
556
                if (! dvb_tune(priv, channel->freq, channel->pol, channel->srate, channel->diseqc, channel->tone,
 
557
                        channel->inv, channel->mod, channel->gi, channel->trans, channel->bw, channel->cr, channel->cr_lp, channel->hier))
 
558
                        return 0;
 
559
 
 
560
 
 
561
        priv->is_on = 1;
 
562
 
 
563
        //sets demux filters and restart the stream
 
564
        for(i = 0; i < channel->pids_cnt; i++)
 
565
        {
 
566
                if(! dvb_set_ts_filt(priv->demux_fds[i], channel->pids[i], DMX_PES_OTHER))
 
567
                        return 0;
 
568
        }
 
569
        
 
570
        return 1;
 
571
}
 
572
 
 
573
 
 
574
 
 
575
int dvb_step_channel(dvb_priv_t *priv, int dir)
 
576
{
 
577
        int new_current;
 
578
        dvb_channels_list *list;
 
579
 
 
580
        mp_msg(MSGT_DEMUX, MSGL_V, "DVB_STEP_CHANNEL dir %d\n", dir);
 
581
 
 
582
        if(priv == NULL)
 
583
        {
 
584
                mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_step_channel: NULL priv_ptr, quit\n");
 
585
                return 0;
 
586
        }
 
587
 
 
588
        list = priv->list;
 
589
        if(list == NULL)
 
590
        {
 
591
                mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_step_channel: NULL list_ptr, quit\n");
 
592
                return 0;
 
593
        }
 
594
 
 
595
 
 
596
        if(dir == DVB_CHANNEL_HIGHER)
 
597
        {
 
598
                if(list->current == list->NUM_CHANNELS-1)
 
599
                        return 0;
 
600
 
 
601
                new_current = list->current + 1;
 
602
        }
 
603
        else
 
604
        {
 
605
                if(list->current == 0)
 
606
                        return 0;
 
607
 
 
608
                new_current = list->current - 1;
 
609
        }
 
610
 
 
611
        return dvb_set_channel(priv, priv->card, new_current);
 
612
}
 
613
 
 
614
 
 
615
 
 
616
 
 
617
extern char *get_path(char *);
 
618
 
 
619
static void dvbin_close(stream_t *stream)
 
620
{
 
621
        int i;
 
622
        dvb_priv_t *priv  = (dvb_priv_t *) stream->priv;
 
623
 
 
624
        for(i = priv->demux_fds_cnt-1; i >= 0; i--)
 
625
        {
 
626
                priv->demux_fds_cnt--;
 
627
                mp_msg(MSGT_DEMUX, MSGL_V, "DVBIN_CLOSE, close(%d), fd=%d, COUNT=%d\n", i, priv->demux_fds[i], priv->demux_fds_cnt);
 
628
                close(priv->demux_fds[i]);
 
629
        }
 
630
        close(priv->dvr_fd);
 
631
 
 
632
        close(priv->fe_fd);
 
633
#ifdef HAVE_DVB
 
634
        close(priv->sec_fd);
 
635
#endif
 
636
 
 
637
        priv->is_on = 0;
 
638
        dvb_config->priv = NULL;
 
639
}
 
640
 
 
641
 
 
642
static int dvb_streaming_start(dvb_priv_t *priv, struct stream_priv_s *opts, int tuner_type, char *progname)
 
643
{
 
644
        int i;
 
645
        dvb_channel_t *channel = NULL;
 
646
        stream_t *stream  = (stream_t*) priv->stream;
 
647
 
 
648
 
 
649
        mp_msg(MSGT_DEMUX, MSGL_INFO, "code taken from dvbstream for mplayer v0.4pre1 - (C) Dave Chapman 2001\n");
 
650
        mp_msg(MSGT_DEMUX, MSGL_INFO, "Released under the GPL.\n");
 
651
        mp_msg(MSGT_DEMUX, MSGL_INFO, "Latest version available from http://www.linuxstb.org/\n");
 
652
        mp_msg(MSGT_DEMUX, MSGL_V,        "PROG: %s, CARD: %d, VID: %d, AID: %d, TYPE: %s, FILE: %s\n",
 
653
            opts->prog, opts->card, opts->vid, opts->aid,  opts->type, opts->file);
 
654
 
 
655
        priv->is_on = 0;
 
656
 
 
657
                        i = 0;
 
658
                        while((channel == NULL) && i < priv->list->NUM_CHANNELS)
 
659
                        {
 
660
                                if(! strcmp(priv->list->channels[i].name, progname))
 
661
                                        channel = &(priv->list->channels[i]);
 
662
 
 
663
                                i++;
 
664
                        }
 
665
 
 
666
                        if(channel != NULL)
 
667
                        {
 
668
                                priv->list->current = i-1;
 
669
                                mp_msg(MSGT_DEMUX, MSGL_V, "PROGRAM NUMBER %d: name=%s, freq=%u\n", i-1, channel->name, channel->freq);
 
670
                        }
 
671
                else
 
672
                {
 
673
                                mp_msg(MSGT_DEMUX, MSGL_ERR, "\n\nDVBIN: no such channel \"%s\"\n\n", progname);
 
674
          return 0;
 
675
        }
 
676
 
 
677
 
 
678
        strcpy(priv->prev_tuning, "");
 
679
        if(!dvb_set_channel(priv, priv->card, priv->list->current))
 
680
        {
 
681
                mp_msg(MSGT_DEMUX, MSGL_ERR, "ERROR, COULDN'T SET CHANNEL  %i: ", priv->list->current);
 
682
                dvbin_close(stream);
 
683
                return 0;
 
684
        }
 
685
 
 
686
        mp_msg(MSGT_DEMUX, MSGL_V,  "SUCCESSFUL EXIT from dvb_streaming_start\n");
 
687
 
 
688
        return 1;
 
689
}
 
690
 
 
691
 
 
692
 
 
693
 
 
694
static int dvb_open(stream_t *stream, int mode, void *opts, int *file_format)
 
695
{
 
696
        // I don't force  the file format bacause, although it's almost always TS,
 
697
        // there are some providers that stream an IP multicast with M$ Mpeg4 inside
 
698
        struct stream_priv_s* p = (struct stream_priv_s*)opts;
 
699
        dvb_priv_t *priv;
 
700
        char *progname;
 
701
        int tuner_type = 0;
 
702
 
 
703
 
 
704
        if(mode != STREAM_READ)
 
705
                return STREAM_UNSUPORTED;
 
706
 
 
707
        stream->priv = (dvb_priv_t*) malloc(sizeof(dvb_priv_t));
 
708
        if(stream->priv ==  NULL)
 
709
                return STREAM_ERROR;
 
710
 
 
711
        priv = (dvb_priv_t *)stream->priv;
 
712
        priv->stream = stream;
 
713
        dvb_config = dvb_get_config();
 
714
        if(dvb_config == NULL)
 
715
        {
 
716
                free(priv);
 
717
                mp_msg(MSGT_DEMUX, MSGL_ERR, "DVB CONFIGURATION IS EMPTY, exit\n");
 
718
                return STREAM_ERROR;
 
719
        }
 
720
        dvb_config->priv = priv;
 
721
        priv->config = dvb_config;
 
722
 
 
723
        if(p->card < 1 || p->card > priv->config->count)
 
724
        {
 
725
                free(priv);
 
726
                mp_msg(MSGT_DEMUX, MSGL_ERR, "NO CONFIGURATION FOUND FOR CARD N. %d, exit\n", p->card);
 
727
                return STREAM_ERROR;
 
728
        }
 
729
        priv->card = p->card - 1;
 
730
        
 
731
        tuner_type = priv->config->cards[priv->card].type;
 
732
 
 
733
        if(tuner_type == 0)
 
734
        {
 
735
                free(priv);
 
736
                mp_msg(MSGT_DEMUX, MSGL_V, "OPEN_DVB: UNKNOWN OR UNDETECTABLE TUNER TYPE, EXIT\n");
 
737
                return STREAM_ERROR;
 
738
        }
 
739
 
 
740
 
 
741
        priv->tuner_type = tuner_type;
 
742
 
 
743
        mp_msg(MSGT_DEMUX, MSGL_V, "OPEN_DVB: prog=%s, card=%d, type=%d, vid=%d, aid=%d\n",
 
744
                p->prog, priv->card+1, priv->tuner_type, p->vid, p->aid);
 
745
 
 
746
        priv->list = priv->config->cards[priv->card].list;
 
747
        
 
748
        if((! strcmp(p->prog, "")) && (priv->list != NULL))
 
749
                progname = priv->list->channels[0].name;
 
750
        else
 
751
                progname = p->prog;
 
752
 
 
753
 
 
754
        if(! dvb_streaming_start(priv, p, tuner_type, progname))
 
755
        {
 
756
                free(stream->priv);
 
757
                stream->priv = NULL;
 
758
                return STREAM_ERROR;
 
759
        }
 
760
 
 
761
        stream->type = STREAMTYPE_DVB;
 
762
        stream->fill_buffer = dvb_streaming_read;
 
763
        stream->close = dvbin_close;
 
764
        m_struct_free(&stream_opts, opts);
 
765
 
 
766
    return STREAM_OK;
 
767
}
 
768
 
 
769
#define MAX_CARDS 4
 
770
dvb_config_t *dvb_get_config()
 
771
{
 
772
        int i, fd, type, size;
 
773
        char filename[30], *conf_file, *name;
 
774
        dvb_channels_list *list;
 
775
        dvb_card_config_t *cards = NULL;
 
776
        dvb_config_t *conf = NULL;
 
777
        
 
778
        if(dvb_config != NULL)
 
779
                return dvb_config;
 
780
                        
 
781
        conf = (dvb_config_t*) malloc(sizeof(dvb_config_t));
 
782
        if(conf == NULL)
 
783
                return NULL;
 
784
 
 
785
        conf->priv = NULL;      
 
786
        conf->count = 0;
 
787
        conf->cards = NULL;
 
788
        for(i=0; i<MAX_CARDS; i++)
 
789
        {
 
790
                sprintf(filename, "/dev/dvb/adapter%d/frontend0", i);
 
791
                fd = open(filename, O_RDWR | O_NONBLOCK);
 
792
                if(fd < 0)
 
793
                {
 
794
                        mp_msg(MSGT_DEMUX, MSGL_V, "DVB_CONFIG, can't open device %s, skipping\n", filename);
 
795
                        continue;
 
796
                }
 
797
                        
 
798
                type = dvb_get_tuner_type(fd);
 
799
                close(fd);
 
800
                if(type != TUNER_SAT && type != TUNER_TER && type != TUNER_CBL && type != TUNER_ATSC)
 
801
                {
 
802
                        mp_msg(MSGT_DEMUX, MSGL_V, "DVB_CONFIG, can't detect tuner type of card %d, skipping\n", i);
 
803
                        continue;
 
804
                }
 
805
                
 
806
                switch(type)
 
807
                        {
 
808
                                case TUNER_TER:
 
809
                                conf_file = get_path("channels.conf.ter");
 
810
                                        break;
 
811
                                case TUNER_CBL:
 
812
                                conf_file = get_path("channels.conf.cbl");
 
813
                                        break;
 
814
                                case TUNER_SAT:
 
815
                                conf_file = get_path("channels.conf.sat");
 
816
                                        break;
 
817
                                case TUNER_ATSC:
 
818
                                conf_file = get_path("channels.conf.atsc");
 
819
                                        break;
 
820
                        }
 
821
                
 
822
                if((access(conf_file, F_OK | R_OK) != 0))
 
823
                        conf_file = get_path("channels.conf");
 
824
 
 
825
                list = dvb_get_channels(conf_file, type);
 
826
                if(list == NULL)
 
827
                        continue;
 
828
                
 
829
                size = sizeof(dvb_card_config_t) * (conf->count + 1);
 
830
                cards = realloc(conf->cards, size);
 
831
 
 
832
                if(cards == NULL)
 
833
        {
 
834
                        fprintf(stderr, "DVB_CONFIG, can't realloc %d bytes, skipping\n", size);
 
835
                        continue;
 
836
        }
 
837
 
 
838
                name = (char*) malloc(20);
 
839
                if(name==NULL)
 
840
        {
 
841
                        fprintf(stderr, "DVB_CONFIG, can't realloc 20 bytes, skipping\n");
 
842
                        continue;
 
843
        }
 
844
 
 
845
                conf->cards = cards;
 
846
                conf->cards[conf->count].devno = i;
 
847
                conf->cards[conf->count].list = list;
 
848
                conf->cards[conf->count].type = type;
 
849
                sprintf(name, "DVB-%c card n. %d", type==TUNER_TER ? 'T' : (type==TUNER_CBL ? 'C' : 'S'), conf->count+1);
 
850
                conf->cards[conf->count].name = name;
 
851
                conf->count++;
 
852
        }
 
853
 
 
854
        if(conf->count == 0)
 
855
        {
 
856
                free(conf);
 
857
                conf = NULL;
 
858
        }
 
859
 
 
860
        dvb_config = conf;
 
861
        return conf;
 
862
}
 
863
 
 
864
 
 
865
 
 
866
stream_info_t stream_info_dvb = {
 
867
        "Dvb Input",
 
868
        "dvbin",
 
869
        "Nico",
 
870
        "based on the code from ??? (probably Arpi)",
 
871
        dvb_open,                       
 
872
        { "dvb", NULL },
 
873
        &stream_opts,
 
874
        1                               // Urls are an option string
 
875
};
 
876
 
 
877
 
 
878
 
 
879