Revision a24dbbce

View differences:

ChangeLog
1
2005-04-09  John Knottenbelt  <jak@users.sourceforge.net>
2
	Updated tuning code from latest version of dvbstream
3
	Should work with DiBcom 3000-MB DVB-T now.
4
	
1 5
2004-10-11  John Knottenbelt  <jak@users.sourceforge.net>
2 6
	Added some Fedora Core compatibility fixes. Removed
3 7
	ofstream from dvb-cat (used file descriptors instead)
src/Makefile.am
15 15
    signals.cpp configfile.cpp scheduler.cpp fakedemuxer.cpp faketuner.cpp	\
16 16
    faketunermanager.cpp recording.cpp utils.cpp stringrep.cpp			\
17 17
    transform.c tune.c ringbuffy.c remux.c ctools.c psfilter.cpp	        \
18
    dvbstuneparams.cpp dvbctuneparams.cpp dvbtuneparamscommon.cpp
18
    dvbstuneparams.cpp dvbctuneparams.cpp dvbtuneparamscommon.cpp timer.cpp
19 19

  
20 20
dvbsched_SOURCES =						\
21 21
    unixclientsocket.cpp stringutil.cpp				\
......
44 44
    outputbuffer.h parsetime.h recording.h remux.h ringbuffy.h scheduler.h	\
45 45
    select.h source.h stringrep.h stringutil.h time-parser.h transform.h	\
46 46
    tune.h tuneparams.h tuner.h tunermanager.h unixclientsocket.h		\
47
    unixserversocket.h utils.h psfilter.h recordconnection.h
47
    unixserversocket.h utils.h psfilter.h recordconnection.h                    \
48
    dvbtuneparamscommon.h timer.h
48 49

  
49 50

  
50 51

  
src/ctools.c
32 32

  
33 33
#define MAX_SEARCH 1024 * 1024
34 34

  
35

  
35 36
/*
36 37

  
37 38
      PES
......
2041 2042

  
2042 2043
	if (break_up_filename(name,base_name,path,ext) < 0) exit(1);
2043 2044

  
2045

  
2044 2046
	if ( (fdin = open(name, O_RDONLY|O_LARGEFILE)) < 0){
2045 2047
		fprintf(stderr,"Can't open %s\n",name);
2046 2048
		exit(1);
src/ctools.h
27 27
 * the project's page is at http://linuxtv.org/dvb/
28 28
 */
29 29

  
30
#include <unistd.h>
31
#include <fcntl.h>
32 30
#include <stdio.h>
33 31
#include <stdlib.h>
34 32
#include <errno.h>
33
#include <unistd.h>
35 34
#include <netinet/in.h>
36 35
#include <string.h>
37 36
#include <sys/types.h>
38 37
#include <sys/stat.h>
38
#include <fcntl.h>
39 39
#include <sys/ioctl.h>
40 40
#include <libgen.h>
41 41
#include <stdint.h>
src/dvb_defaults.h
97 97
#endif
98 98

  
99 99
#if HIERARCHY_DEFAULT == HIERARCHY_NONE && !defined (LP_CODERATE_DEFAULT)
100
#define LP_CODERATE_DEFAULT (0) /* unused if HIERARCHY_NONE */
100
#define LP_CODERATE_DEFAULT (FEC_NONE) /* unused if HIERARCHY_NONE */
101 101
#endif
102 102

  
103 103
#endif
src/dvbctuneparams.cpp
70 70
  // Give it three goes at least!
71 71
  for (int i = 0; i < 3; i++) {
72 72
    int rc = tune_it(frontendFD, 
73
		     0,		// old fd_sec 
74 73
		     freq, 
75 74
		     sr,       	// Symbol Rate for DVB-C or DVB-S 
76 75
		     0,		// Polarity 
......
81 80
		     fe_code_rate_t(fec),
82 81
		     TRANSMISSION_MODE_DEFAULT,
83 82
		     GUARD_INTERVAL_DEFAULT,
84
		     BANDWIDTH_DEFAULT);
83
		     BANDWIDTH_DEFAULT,
84
		     LP_CODERATE_DEFAULT,
85
		     HIERARCHY_DEFAULT);
85 86

  
86 87
    if (rc >= 0)
87 88
      return true;
src/dvbstuneparams.cpp
70 70
  // Give it three goes at least!
71 71
  for (int i = 0; i < 3; i++) {
72 72
    int rc = tune_it(frontendFD, 
73
		     0,		// old fd_sec 
74 73
		     freq,       // frequency to tune to
75 74
		     sr,	// Symbol Rate for DVB-C or DVB-S 
76 75
		     polarity,	// Polarity 
......
81 80
		     fe_code_rate_t(0), 
82 81
		     fe_transmit_mode_t(0),
83 82
		     fe_guard_interval_t(0), 
84
		     fe_bandwidth_t(0)
83
		     fe_bandwidth_t(0),
84
		     fe_code_rate_t(0),
85
		     fe_hierarchy_t(0)
85 86
    );
86 87
    if (rc >= 0)
87 88
      return true;
src/dvbttuneparams.cpp
33 33
    qam(CONSTELLATION_DEFAULT),
34 34
    inv(INVERSION_OFF),
35 35
    fec1(HP_CODERATE_DEFAULT),
36
    fec2(HP_CODERATE_DEFAULT),
36
    fec2(LP_CODERATE_DEFAULT),
37 37
    hier(HIERARCHY_DEFAULT),
38 38
    bandw(BANDWIDTH_DEFAULT),
39 39
    mode(TRANSMISSION_MODE_DEFAULT),
......
79 79
  // Give it three goes at least!
80 80
  for (int i = 0; i < 3; i++) {
81 81
    int rc = tune_it(frontendFD, 
82
		     0,		// old fd_sec 
83 82
		     freq / 1000, 
84 83
		     0,		// Symbol Rate for DVB-C or DVB-S 
85 84
		     0,		// Polarity 
......
90 89
		     fe_code_rate_t(fec1), 
91 90
		     fe_transmit_mode_t(mode),
92 91
		     fe_guard_interval_t(guard), 
93
		     fe_bandwidth_t(bandw));
92
		     fe_bandwidth_t(bandw),
93
		     fe_code_rate_t(fec2),
94
		     fe_hierarchy_t(hier));
94 95
    if (rc >= 0)
95 96
      return true;
96 97
  }
src/remux.c
1
/*
2
  Copyright 2003 John Knottenbelt
3
  
4
  This program is free software; you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation; either version 2 of the License, or
7
  (at your option) any later version.
8
 
9
  This program is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
 
14
  You should have received a copy of the GNU General Public License
15
  along with this program; if not, write to the Free Software
16
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
17
*/
18

  
19
#include "config.h"
20 1
#include "remux.h"
21 2

  
22 3
unsigned int bitrates[3][16] =
src/ringbuffy.c
18 18
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 19
*/
20 20

  
21
#include "config.h"
22 21
#include "ringbuffy.h"
23
#include <string.h>
24 22

  
25 23
int ring_init (ringbuffy *rbuf, int size)
26 24
{
src/timer.cpp
1
#include "timer.h"
2

  
3
#include <signal.h>
4

  
5
#include <iostream>
6
#include <queue>
7
#include <functional>
8

  
9
struct TimerLess {
10
  bool operator()(Timer *& left, Timer *& right) const
11
  {
12
    // a Timer has less priority if it's expiry time is bigger
13
    struct timeval a = left->getExpiry();
14
    struct timeval b = right->getExpiry();
15
    return timercmp(&a, &b, >); 
16
  }
17
};
18

  
19
typedef std::priority_queue<Timer *, std::vector<Timer *>, struct TimerLess> TimerQueue; 
20

  
21
static TimerQueue timerQueue;
22
static struct timeval earliestTime;
23

  
24
static void maskTimer()
25
{
26
  sigset_t set;
27
  sigemptyset(&set);
28
  sigaddset(&set, SIGALRM);
29
  sigprocmask(SIG_BLOCK, &set, NULL);
30
}
31

  
32
static void unmaskTimer()
33
{
34
  sigset_t set;
35
  sigemptyset(&set);
36
  sigaddset(&set, SIGALRM);
37
  sigprocmask(SIG_UNBLOCK, &set, NULL);
38
}
39

  
40
void calcInterval(const struct timeval &future, struct timeval &interval)
41
{
42
  struct timeval now;
43
  gettimeofday(&now, 0);
44

  
45
  interval.tv_sec = future.tv_sec - now.tv_sec;
46
  interval.tv_usec = future.tv_usec - now.tv_usec;
47

  
48
  if (interval.tv_usec < 0) {
49
    interval.tv_usec += 1000000;
50
    interval.tv_sec--;
51
  }
52
}
53

  
54
static void fireTimers()
55
{
56
  struct timeval now;
57
  gettimeofday(&now, 0);
58

  
59
  while (!timerQueue.empty()) {
60
    Timer *top = timerQueue.top();
61
    struct timeval expiry = top->getExpiry();
62
    if (timercmp(&now, &expiry, >=)) {
63
      timerQueue.pop();
64
      top->fire();
65
    }
66
    else
67
      break;
68
  }
69
}
70

  
71
static void setTimer()
72
{
73
  // Must be called with an timer in the timerQueue
74
  Timer *top = timerQueue.top();
75
  struct timeval expiry = top->getExpiry();
76
  struct timeval interval;
77

  
78
  calcInterval(expiry, interval);
79

  
80
  if (interval.tv_sec < 0) {
81
    interval.tv_sec = 0;
82
    fireTimers();
83
    return;
84
  }
85
  
86
  earliestTime = expiry;
87
  
88
  // Single shot timer
89
  struct itimerval it;
90
  it.it_interval.tv_sec = 0;
91
  it.it_interval.tv_usec = 0;
92
  it.it_value = interval;
93
    
94
  std::cout << "Setting up itimer\n";
95
  setitimer(ITIMER_REAL, &it, 0);
96
}
97

  
98
static void handleAlarmSig(int sig)
99
{
100
  std::cout << "Got alarm signal\n";
101
  // Alarm signal is masked already
102
  fireTimers();
103
  if (!timerQueue.empty())
104
    setTimer();
105
}
106

  
107
static struct SetupSignalHandler {
108
  SetupSignalHandler()
109
  {
110
    std::cout << "Setting up signal handler\n";
111
    struct sigaction act;
112
    act.sa_handler = handleAlarmSig;
113
    sigemptyset(&act.sa_mask);
114
    sigaddset(&act.sa_mask, SIGALRM);
115
    act.sa_flags = 0;
116
    sigaction(SIGALRM, &act, 0);
117
  }
118
} setupSignalHandler;
119

  
120

  
121
void Timer::start()
122
{
123
  // Calculate expiry time
124
  gettimeofday(&expiry, 0);
125
  expiry.tv_usec += delayMs * 1000;
126
  expiry.tv_sec += expiry.tv_usec % 1000000;
127
  expiry.tv_usec %= 1000000;
128
  
129
  // Add the timer to the queue
130
  maskTimer();
131
  timerQueue.push(this);
132
  setTimer();
133
  unmaskTimer();
134
}
135

  
136
void Timer::fire()
137
{
138
  callback(arg);
139
}
140

  
141
void Timer::stop()
142
{
143
  maskTimer();
144
  TimerQueue copy = timerQueue;
145

  
146
  while (!timerQueue.empty())
147
    timerQueue.pop();
148

  
149
  while (!copy.empty()) {
150
    Timer *top = copy.top();
151
    copy.pop();
152
    if (top != this)
153
      timerQueue.push(top);
154
  }
155
  unmaskTimer();
156
}
src/timer.h
1
#if !defined __MY_TIMER_H
2
#define __MY_TIMER_H
3

  
4
#include <sys/time.h>
5
#include <time.h>
6

  
7
class Timer {
8
 public:
9
  typedef void CallbackType( void * );
10
  
11
  Timer( unsigned delayMs, CallbackType *callback, void *arg )
12
    : delayMs(delayMs), callback(callback), arg(arg)
13
    {
14
    }
15

  
16
  void start();
17
  void stop();
18

  
19
  struct timeval getExpiry() const
20
    {
21
      return expiry;
22
    }
23
  
24
  void fire();
25

  
26
 private:
27

  
28
  unsigned delayMs;
29
  CallbackType *callback;
30
  void *arg;
31
  struct timeval expiry;
32
};
33

  
34

  
35
#endif // __MY_TIMER_H
src/transform.c
27 27
 * the project's page is at http://linuxtv.org/dvb/
28 28
 */
29 29

  
30
#include "config.h"
30

  
31 31
#include "transform.h"
32 32
#include <stdlib.h>
33 33
#include <string.h>
src/tune.c
19 19

  
20 20
*/
21 21
   
22
#include "config.h"
23 22
#include <stdio.h>
24 23
#include <stdlib.h>
24
#include <stdint.h>
25 25
#include <ctype.h>
26 26
#include <sys/ioctl.h>
27 27
#include <sys/poll.h>
28 28
#include <unistd.h>
29 29
#include <error.h>
30
#include <time.h>
30 31
#include <errno.h>
31 32

  
32
#ifdef NEWSTRUCT
33 33
#include <linux/dvb/dmx.h>
34 34
#include <linux/dvb/frontend.h>
35
#else
36
#include <ost/dmx.h>
37
#include <ost/sec.h>
38
#include <ost/frontend.h>
39
#endif
40 35

  
41 36
#include "tune.h"
42 37

  
43
#ifndef NEWSTRUCT
44
int OSTSelftest(int fd)
45
{
46
    int ans;
47

  
48
    if ( (ans = ioctl(fd,FE_SELFTEST,0) < 0)){
49
        perror("FE SELF TEST: ");
50
        return -1;
51
    }
52

  
53
    return 0;
54
}
55

  
56
int OSTSetPowerState(int fd, uint32_t state)
57
{
58
    int ans;
59

  
60
    if ( (ans = ioctl(fd,FE_SET_POWER_STATE,state) < 0)){
61
        perror("OST SET POWER STATE: ");
62
        return -1;
63
    }
64

  
65
    return 0;
66
}
67

  
68
int OSTGetPowerState(int fd, uint32_t *state)
69
{
70
    int ans;
71

  
72
    if ( (ans = ioctl(fd,FE_GET_POWER_STATE,state) < 0)){
73
        perror("OST GET POWER STATE: ");
74
        return -1;
75
    }
76

  
77
    switch(*state){
78
    case FE_POWER_ON:
79
        fprintf(stderr,"POWER ON (%d)\n",*state);
80
        break;
81
    case FE_POWER_STANDBY:
82
        fprintf(stderr,"POWER STANDBY (%d)\n",*state);
83
        break;
84
    case FE_POWER_SUSPEND:
85
        fprintf(stderr,"POWER SUSPEND (%d)\n",*state);
86
        break;
87
    case FE_POWER_OFF:
88
        fprintf(stderr,"POWER OFF (%d)\n",*state);
89
        break;
90
    default:
91
        fprintf(stderr,"unknown (%d)\n",*state);
92
        break;
93
    }
94

  
95
    return 0;
96
}
97

  
98
int SecGetStatus (int fd, struct secStatus *state)
99
{
100
    int ans;
101

  
102
    if ( (ans = ioctl(fd,SEC_GET_STATUS, state) < 0)){
103
        perror("SEC GET STATUS: ");
104
        return -1;
105
    }
106

  
107
    switch (state->busMode){
108
    case SEC_BUS_IDLE:
109
        fprintf(stderr,"SEC BUS MODE:  IDLE (%d)\n",state->busMode);
110
        break;
111
    case SEC_BUS_BUSY:
112
        fprintf(stderr,"SEC BUS MODE:  BUSY (%d)\n",state->busMode);
113
        break;
114
    case SEC_BUS_OFF:
115
        fprintf(stderr,"SEC BUS MODE:  OFF  (%d)\n",state->busMode);
116
        break;
117
    case SEC_BUS_OVERLOAD:
118
        fprintf(stderr,"SEC BUS MODE:  OVERLOAD (%d)\n",state->busMode);
119
        break;
120
    default:
121
        fprintf(stderr,"SEC BUS MODE:  unknown  (%d)\n",state->busMode);
122
        break;
123
    }
124

  
125
    switch (state->selVolt){
126
    case SEC_VOLTAGE_OFF:
127
        fprintf(stderr,"SEC VOLTAGE:  OFF (%d)\n",state->selVolt);
128
        break;
129
    case SEC_VOLTAGE_LT:
130
        fprintf(stderr,"SEC VOLTAGE:  LT  (%d)\n",state->selVolt);
131
        break;
132
    case SEC_VOLTAGE_13:
133
        fprintf(stderr,"SEC VOLTAGE:  13  (%d)\n",state->selVolt);
134
        break;
135
    case SEC_VOLTAGE_13_5:
136
        fprintf(stderr,"SEC VOLTAGE:  13.5 (%d)\n",state->selVolt);
137
        break;
138
    case SEC_VOLTAGE_18:
139
        fprintf(stderr,"SEC VOLTAGE:  18 (%d)\n",state->selVolt);
140
        break;
141
    case SEC_VOLTAGE_18_5:
142
        fprintf(stderr,"SEC VOLTAGE:  18.5 (%d)\n",state->selVolt);
143
        break;
144
    default:
145
        fprintf(stderr,"SEC VOLTAGE:  unknown (%d)\n",state->selVolt);
146
        break;
147
    }
148

  
149
    fprintf(stderr,"SEC CONT TONE: %s\n", (state->contTone == SEC_TONE_ON ? "ON" : "OFF"));
150
    return 0;
151
}
152
#endif
153 38

  
154 39
void print_status(FILE* fd,fe_status_t festatus) {
155 40
  fprintf(fd,"FE_STATUS:");
156 41
  if (festatus & FE_HAS_SIGNAL) fprintf(fd," FE_HAS_SIGNAL");
157
#ifdef NEWSTRUCT
158 42
  if (festatus & FE_TIMEDOUT) fprintf(fd," FE_TIMEDOUT");
159
#else
160
  if (festatus & FE_HAS_POWER) fprintf(fd," FE_HAS_POWER");
161
  if (festatus & FE_SPECTRUM_INV) fprintf(fd," FE_SPECTRUM_INV");
162
  if (festatus & FE_TUNER_HAS_LOCK) fprintf(fd," FE_TUNER_HAS_LOCK");
163
#endif
164 43
  if (festatus & FE_HAS_LOCK) fprintf(fd," FE_HAS_LOCK");
165 44
  if (festatus & FE_HAS_CARRIER) fprintf(fd," FE_HAS_CARRIER");
166 45
  if (festatus & FE_HAS_VITERBI) fprintf(fd," FE_HAS_VITERBI");
......
168 47
  fprintf(fd,"\n");
169 48
}
170 49

  
171
#ifdef NEWSTRUCT
50

  
172 51
struct diseqc_cmd {
173 52
   struct dvb_diseqc_master_cmd cmd;
174 53
   uint32_t wait;
175 54
};
176 55

  
177
void diseqc_send_msg(int fd, fe_sec_voltage_t v, struct diseqc_cmd *cmd,
178
		     fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b)
56
static int diseqc_send_msg(int fd, fe_sec_voltage_t v, struct diseqc_cmd *cmd,
57
		     fe_sec_tone_mode_t t, unsigned char sat_no)
179 58
{
180
   ioctl(fd, FE_SET_TONE, SEC_TONE_OFF);
181
   ioctl(fd, FE_SET_VOLTAGE, v);
59
   if(ioctl(fd, FE_SET_TONE, SEC_TONE_OFF) < 0)
60
   	return -1;
61
   if(ioctl(fd, FE_SET_VOLTAGE, v) < 0)
62
   	return -1;
182 63
   usleep(15 * 1000);
183
   ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd);
184
   usleep(cmd->wait * 1000);
185
   usleep(15 * 1000);
186
   ioctl(fd, FE_DISEQC_SEND_BURST, b);
187
   usleep(15 * 1000);
188
   ioctl(fd, FE_SET_TONE, t);
64
   if(sat_no >= 1 && sat_no <= 4)	//1.x compatible equipment
65
   {
66
    if(ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd) < 0)
67
   	return -1;
68
    usleep(cmd->wait * 1000);
69
    usleep(15 * 1000);
70
   }
71
   else	//A or B simple diseqc
72
   {
73
    fprintf(stderr, "SETTING SIMPLE %c BURST\n", sat_no);
74
    if(ioctl(fd, FE_DISEQC_SEND_BURST, (sat_no == 'B' ? SEC_MINI_B : SEC_MINI_A)) < 0)
75
   	return -1;
76
    usleep(15 * 1000);
77
   }
78
   if(ioctl(fd, FE_SET_TONE, t) < 0)
79
   	return -1;
80

  
81
   return 0;
189 82
}
190 83

  
191

  
192

  
193

  
194 84
/* digital satellite equipment control,
195 85
 * specification is available from http://www.eutelsat.com/ 
196 86
 */
197
static int do_diseqc(int secfd, int sat_no, int pol, int hi_lo)
198
{
199
   struct diseqc_cmd cmd =
200
       { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 };
201

  
202
   /* param: high nibble: reset bits, low nibble set bits,
203
    * bits are: option, position, polarizaion, band
204
    */
205
   cmd.cmd.msg[3] =
206
       0xf0 | (((sat_no * 4) & 0x0f) | (hi_lo ? 1 : 0) | (pol ? 0 : 2));
207

  
208
   diseqc_send_msg(secfd, pol,
209
		   &cmd, hi_lo,
210
		   (sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A);
211 87

  
212
   return 1;
88
static int do_diseqc(int fd, unsigned char sat_no, int polv, int hi_lo)
89
{
90
    struct diseqc_cmd cmd =  { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 };
91

  
92
    if(sat_no != 0)
93
    {
94
	unsigned char d = sat_no;
95

  
96
	/* param: high nibble: reset bits, low nibble set bits,
97
	* bits are: option, position, polarizaion, band
98
	*/
99
	sat_no--;
100
	cmd.cmd.msg[3] =
101
    	    0xf0 | (((sat_no * 4) & 0x0f) | (polv ? 0 : 2) | (hi_lo ? 1 : 0));
102

  
103
	return diseqc_send_msg(fd, 
104
		    polv ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18,
105
		    &cmd, 
106
		    hi_lo ? SEC_TONE_ON : SEC_TONE_OFF, 
107
		    d);
108
    }
109
    else 	//only tone and voltage
110
    {
111
	fe_sec_voltage_t voltage;
112
	
113
	fprintf(stderr, "Setting only tone %s and voltage %dV\n", (hi_lo ? "ON" : "OFF"), (polv ? 13 : 18));
114
	
115
	if(ioctl(fd, FE_SET_VOLTAGE, (polv ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18)) < 0)
116
   	    return -1;
117
	    
118
	if(ioctl(fd, FE_SET_TONE, (hi_lo ? SEC_TONE_ON : SEC_TONE_OFF)) < 0)
119
   	    return -1;
120
	
121
	usleep(15 * 1000);
122
	
123
	return 0;
124
    }
213 125
}
214 126

  
215
int check_status(int fd_frontend,struct dvb_frontend_parameters* feparams,int tone) {
127
int check_status(int fd_frontend,int type, struct dvb_frontend_parameters* feparams,unsigned int base) {
216 128
  int32_t strength;
217 129
  fe_status_t festatus;
218
  struct dvb_frontend_event event;
219
  struct dvb_frontend_info fe_info;
220 130
  struct pollfd pfd[1];
221
  int status;
131
  int status, locks=0, ok=0;
132
  time_t tm1, tm2;
222 133

  
223 134
  if (ioctl(fd_frontend,FE_SET_FRONTEND,feparams) < 0) {
224 135
    perror("ERROR tuning channel\n");
......
226 137
  }
227 138

  
228 139
  pfd[0].fd = fd_frontend;
229
  pfd[0].events = POLLIN;
230

  
231
  event.status=0;
232
  while (((event.status & FE_TIMEDOUT)==0) && ((event.status & FE_HAS_LOCK)==0)) {
233
    fprintf(stderr,"polling....\n");
234
    if (poll(pfd,1,10000)){
235
      if (pfd[0].revents & POLLIN){
236
        fprintf(stderr,"Getting frontend event\n");
237
        if ((status = ioctl(fd_frontend, FE_GET_EVENT, &event)) < 0){
238
	  if (errno != EOVERFLOW) {
239
	    perror("FE_GET_EVENT");
240
	    fprintf(stderr,"status = %d\n", status);
241
	    fprintf(stderr,"errno = %d\n", errno);
242
	    return -1;
243
	  }
244
	  else fprintf(stderr,"Overflow error, trying again (status = %d, errno = %d)", status, errno);
245
        }
140
  pfd[0].events = POLLPRI;
141

  
142
  tm1 = tm2 = time((time_t*) NULL);
143
  fprintf(stderr,"Getting frontend status\n");
144
  while (!ok) {
145
    festatus = 0;
146
    if (poll(pfd,1,3000) > 0){
147
      if (pfd[0].revents & POLLPRI){
148
        if(ioctl(fd_frontend,FE_READ_STATUS,&festatus) >= 0)
149
          if(festatus & FE_HAS_LOCK)
150
	    locks++;
246 151
      }
247
      print_status(stderr,event.status);
248 152
    }
153
    usleep(10000);
154
    tm2 = time((time_t*) NULL);
155
    if((festatus & FE_TIMEDOUT) || (locks >= 2) || (tm2 - tm1 >= 3))
156
	    ok = 1;
249 157
  }
250 158

  
251
  if (event.status & FE_HAS_LOCK) {
252
      switch(fe_info.type) {
159
  if (festatus & FE_HAS_LOCK) {
160
      if(ioctl(fd_frontend,FE_GET_FRONTEND,feparams) >= 0) {
161
        switch(type) {
253 162
         case FE_OFDM:
254
           fprintf(stderr,"Event:  Frequency: %d\n",event.parameters.frequency);
163
           fprintf(stderr,"Event:  Frequency: %d\n",feparams->frequency);
255 164
           break;
256 165
         case FE_QPSK:
257
           fprintf(stderr,"Event:  Frequency: %d\n",(unsigned int)((event.parameters.frequency)+(tone==SEC_TONE_OFF ? LOF1 : LOF2)));
258
           fprintf(stderr,"        SymbolRate: %d\n",event.parameters.u.qpsk.symbol_rate);
259
           fprintf(stderr,"        FEC_inner:  %d\n",event.parameters.u.qpsk.fec_inner);
166
           fprintf(stderr,"Event:  Frequency: %d\n",(unsigned int)(feparams->frequency + base));
167
           fprintf(stderr,"        SymbolRate: %d\n",feparams->u.qpsk.symbol_rate);
168
           fprintf(stderr,"        FEC_inner:  %d\n",feparams->u.qpsk.fec_inner);
260 169
           fprintf(stderr,"\n");
261 170
           break;
262 171
         case FE_QAM:
263
           fprintf(stderr,"Event:  Frequency: %d\n",event.parameters.frequency);
264
           fprintf(stderr,"        SymbolRate: %d\n",event.parameters.u.qpsk.symbol_rate);
265
           fprintf(stderr,"        FEC_inner:  %d\n",event.parameters.u.qpsk.fec_inner);
172
           fprintf(stderr,"Event:  Frequency: %d\n",feparams->frequency);
173
           fprintf(stderr,"        SymbolRate: %d\n",feparams->u.qpsk.symbol_rate);
174
           fprintf(stderr,"        FEC_inner:  %d\n",feparams->u.qpsk.fec_inner);
266 175
           break;
176
#ifdef DVB_ATSC
177
	case FE_ATSC:
178
	   fprintf(stderr, "Event:  Frequency: %d\n",feparams->frequency);
179
	   fprintf(stderr, "        Modulation: %d\n",feparams->u.vsb.modulation);
180
	   break;
181
#endif
267 182
         default:
268 183
           break;
184
        }
269 185
      }
270 186

  
271 187
      strength=0;
272
      ioctl(fd_frontend,FE_READ_BER,&strength);
273
      fprintf(stderr,"Bit error rate: %d\n",strength);
274

  
275
      strength=0;
276
      ioctl(fd_frontend,FE_READ_SIGNAL_STRENGTH,&strength);
277
      fprintf(stderr,"Signal strength: %d\n",strength);
188
      if(ioctl(fd_frontend,FE_READ_BER,&strength) >= 0)
189
        fprintf(stderr,"Bit error rate: %d\n",strength);
278 190

  
279 191
      strength=0;
280
      ioctl(fd_frontend,FE_READ_SNR,&strength);
281
      fprintf(stderr,"SNR: %d\n",strength);
282

  
283
      festatus=0;
284
      ioctl(fd_frontend,FE_READ_STATUS,&festatus);
285
      print_status(stderr,festatus);
286
    } else {
287
    fprintf(stderr,"Not able to lock to the signal on the given frequency\n");
288
    return -1;
289
  }
290
  return 0;
291
}
292
#else
293
int check_status(int fd_frontend,FrontendParameters* feparams,int tone) {
294
  int i,res;
295
  int32_t strength;
296
  fe_status_t festatus;
297
  FrontendEvent event;
298
  FrontendInfo fe_info;
299
  struct pollfd pfd[1];
300

  
301
  i = 0; res = -1;
302
  while ((i < 3) && (res < 0)) {
303
    if (ioctl(fd_frontend,FE_SET_FRONTEND,feparams) < 0) {
304
      perror("ERROR tuning channel\n");
305
      return -1;
306
    }
307

  
308
    pfd[0].fd = fd_frontend;
309
    pfd[0].events = POLLIN;
310

  
311
    if (poll(pfd,1,10000)){
312
      if (pfd[0].revents & POLLIN){
313
        fprintf(stderr,"Getting frontend event\n");
314
        if ( ioctl(fd_frontend, FE_GET_EVENT, &event) < 0) {
315
          perror("FE_GET_EVENT");
316
          return -1;
317
        }
318
        fprintf(stderr,"Received ");
319
        switch(event.type){
320
          case FE_UNEXPECTED_EV:
321
            fprintf(stderr,"unexpected event\n");
322
            res = -1;
323
            break;
324
          case FE_FAILURE_EV:
325
            fprintf(stderr,"failure event\n");
326
            res = -1;
327
            break;
328
          case FE_COMPLETION_EV:
329
            fprintf(stderr,"completion event\n");
330
            res = 0;
331
          break;
332
        }
333
      }
334
      i++;
335
    }
336
  }
337

  
338
  if (res > 0)
339
    switch (event.type) {
340
       case FE_UNEXPECTED_EV: fprintf(stderr,"FE_UNEXPECTED_EV\n");
341
                                break;
342
       case FE_COMPLETION_EV: fprintf(stderr,"FE_COMPLETION_EV\n");
343
                                break;
344
       case FE_FAILURE_EV: fprintf(stderr,"FE_FAILURE_EV\n");
345
                                break;
346
    }
347

  
348
    if (event.type == FE_COMPLETION_EV) {
349
      switch(fe_info.type) {
350
         case FE_OFDM:
351
           fprintf(stderr,"Event:  Frequency: %d\n",event.u.completionEvent.Frequency);
352
           break;
353
         case FE_QPSK:
354
           fprintf(stderr,"Event:  Frequency: %d\n",(unsigned int)((event.u.completionEvent.Frequency)+(tone==SEC_TONE_OFF ? LOF1 : LOF2)));
355
           fprintf(stderr,"        SymbolRate: %d\n",event.u.completionEvent.u.qpsk.SymbolRate);
356
           fprintf(stderr,"        FEC_inner:  %d\n",event.u.completionEvent.u.qpsk.FEC_inner);
357
           fprintf(stderr,"\n");
358
           break;
359
         case FE_QAM:
360
           fprintf(stderr,"Event:  Frequency: %d\n",event.u.completionEvent.Frequency);
361
           fprintf(stderr,"        SymbolRate: %d\n",event.u.completionEvent.u.qpsk.SymbolRate);
362
           fprintf(stderr,"        FEC_inner:  %d\n",event.u.completionEvent.u.qpsk.FEC_inner);
363
           break;
364
         default:
365
           break;
366
      }
192
      if(ioctl(fd_frontend,FE_READ_SIGNAL_STRENGTH,&strength) >= 0)
193
        fprintf(stderr,"Signal strength: %d\n",strength);
367 194

  
368 195
      strength=0;
369
      ioctl(fd_frontend,FE_READ_BER,&strength);
370
      fprintf(stderr,"Bit error rate: %d\n",strength);
371

  
196
      if(ioctl(fd_frontend,FE_READ_SNR,&strength) >= 0)
197
        fprintf(stderr,"SNR: %d\n",strength);
198
      
372 199
      strength=0;
373
      ioctl(fd_frontend,FE_READ_SIGNAL_STRENGTH,&strength);
374
      fprintf(stderr,"Signal strength: %d\n",strength);
200
      if(ioctl(fd_frontend,FE_READ_UNCORRECTED_BLOCKS,&strength) >= 0)
201
        fprintf(stderr,"UNC: %d\n",strength);
375 202

  
376
      strength=0;
377
      ioctl(fd_frontend,FE_READ_SNR,&strength);
378
      fprintf(stderr,"SNR: %d\n",strength);
379

  
380
      festatus=0;
381
      ioctl(fd_frontend,FE_READ_STATUS,&festatus);
382

  
383
      fprintf(stderr,"FE_STATUS:");
384
      if (festatus & FE_HAS_POWER) fprintf(stderr," FE_HAS_POWER");
385
      if (festatus & FE_HAS_SIGNAL) fprintf(stderr," FE_HAS_SIGNAL");
386
      if (festatus & FE_SPECTRUM_INV) fprintf(stderr," FE_SPECTRUM_INV");
387
      if (festatus & FE_HAS_LOCK) fprintf(stderr," FE_HAS_LOCK");
388
      if (festatus & FE_HAS_CARRIER) fprintf(stderr," FE_HAS_CARRIER");
389
      if (festatus & FE_HAS_VITERBI) fprintf(stderr," FE_HAS_VITERBI");
390
      if (festatus & FE_HAS_SYNC) fprintf(stderr," FE_HAS_SYNC");
391
      if (festatus & FE_TUNER_HAS_LOCK) fprintf(stderr," FE_TUNER_HAS_LOCK");
392
      fprintf(stderr,"\n");
203
      print_status(stderr,festatus);
393 204
    } else {
394 205
    fprintf(stderr,"Not able to lock to the signal on the given frequency\n");
395 206
    return -1;
396 207
  }
397 208
  return 0;
398 209
}
399
#endif
400 210

  
401
int tune_it(int fd_frontend, int fd_sec, unsigned int freq, unsigned int srate, char pol, int tone, fe_spectral_inversion_t specInv, unsigned int diseqc,fe_modulation_t modulation,fe_code_rate_t HP_CodeRate,fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth) {
402
  int res;
403
#ifdef NEWSTRUCT
211
int tune_it(int fd_frontend, unsigned int freq, unsigned int srate, char pol, int tone, fe_spectral_inversion_t specInv, unsigned char diseqc,fe_modulation_t modulation,fe_code_rate_t HP_CodeRate,fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth, fe_code_rate_t LP_CodeRate, fe_hierarchy_t hier) {
212
  int res, hi_lo, dfd;
213
  unsigned int base;
404 214
  struct dvb_frontend_parameters feparams;
405 215
  struct dvb_frontend_info fe_info;
406
  fe_sec_voltage_t voltage;
407
#else
408
  FrontendParameters feparams;
409
  FrontendInfo fe_info;
410
  secVoltage voltage;
411
  struct secStatus sec_state;
412
#endif
413 216

  
414
  /* discard stale frontend events */
415
  /*
416
  pfd[0].fd = fd_frontend;
417
  pfd[0].events = POLLIN;
418

  
419
  if (poll(pfd,1,500)){
420
    if (pfd[0].revents & POLLIN){
421
      while (1) {
422
        if (ioctl (fd_frontend, FE_GET_EVENT, &event) == -1) { break; }
423
      }
424
    }
425
  }
426
  */
427 217
  if ( (res = ioctl(fd_frontend,FE_GET_INFO, &fe_info) < 0)){
428 218
     perror("FE_GET_INFO: ");
429 219
     return -1;
430 220
  }
431 221
  
432
//  OSTSelftest(fd_frontend);
433
//  OSTSetPowerState(fd_frontend, FE_POWER_ON);
434
//  OSTGetPowerState(fd_frontend, &festatus);
435

  
436
#ifdef NEWSTRUCT
437
  fprintf(stderr,"Using DVB card \"%s\"\n",fe_info.name);
438
#endif
222
  fprintf(stderr,"Using DVB card \"%s\", freq=%d\n",fe_info.name, freq);
439 223

  
224
  if (freq < 1000000) freq*=1000UL;
440 225
  switch(fe_info.type) {
441 226
    case FE_OFDM:
442
#ifdef NEWSTRUCT
443
      if (freq < 1000000) freq*=1000UL;
444 227
      feparams.frequency=freq;
445
      feparams.inversion=INVERSION_OFF;
228
      feparams.inversion=specInv;
446 229
      feparams.u.ofdm.bandwidth=bandwidth;
447 230
      feparams.u.ofdm.code_rate_HP=HP_CodeRate;
448
      feparams.u.ofdm.code_rate_LP=LP_CODERATE_DEFAULT;
231
      feparams.u.ofdm.code_rate_LP=LP_CodeRate;
449 232
      feparams.u.ofdm.constellation=modulation;
450 233
      feparams.u.ofdm.transmission_mode=TransmissionMode;
451 234
      feparams.u.ofdm.guard_interval=guardInterval;
452
      feparams.u.ofdm.hierarchy_information=HIERARCHY_DEFAULT;
453
#else
454
      if (freq < 1000000) freq*=1000UL;
455
      feparams.Frequency=freq;
456
      feparams.Inversion=INVERSION_OFF;
457
      feparams.u.ofdm.bandWidth=bandwidth;
458
      feparams.u.ofdm.HP_CodeRate=HP_CodeRate;
459
      feparams.u.ofdm.LP_CodeRate=LP_CODERATE_DEFAULT;
460
      feparams.u.ofdm.Constellation=modulation;
461
      feparams.u.ofdm.TransmissionMode=TransmissionMode;
462
      feparams.u.ofdm.guardInterval=guardInterval;
463
      feparams.u.ofdm.HierarchyInformation=HIERARCHY_DEFAULT;
464
#endif
465
      fprintf(stderr,"tuning DVB-T (%s) to %d Hz\n",DVB_T_LOCATION,freq);
235
      feparams.u.ofdm.hierarchy_information=hier;
236
      fprintf(stderr,"tuning DVB-T (%s) to %d Hz, Bandwidth: %d\n",DVB_T_LOCATION,freq, 
237
	bandwidth==BANDWIDTH_8_MHZ ? 8 : (bandwidth==BANDWIDTH_7_MHZ ? 7 : 6));
466 238
      break;
467 239
    case FE_QPSK:
468
#ifdef NEWSTRUCT
469
      fprintf(stderr,"tuning DVB-S to L-Band:%d, Pol:%c Srate=%d, 22kHz=%s\n",feparams.frequency,pol,srate,tone == SEC_TONE_ON ? "on" : "off");
470
#else
471
      fprintf(stderr,"tuning DVB-S to L-Band:%d, Pol:%c Srate=%d, 22kHz=%s\n",feparams.Frequency,pol,srate,tone == SEC_TONE_ON ? "on" : "off");
472
#endif
473
      if ((pol=='h') || (pol=='H')) {
474
        voltage = SEC_VOLTAGE_18;
475
      } else {
476
        voltage = SEC_VOLTAGE_13;
477
      }
478
#ifdef NEWSTRUCT
479
if (diseqc==0) if (ioctl(fd_frontend,FE_SET_VOLTAGE,voltage) < 0) {
480
#else
481
      if (ioctl(fd_sec,SEC_SET_VOLTAGE,voltage) < 0) {
482
#endif
483
         perror("ERROR setting voltage\n");
484
      }
485

  
486
      if (freq > 2200000) {
487
        // this must be an absolute frequency
240
    	pol = toupper(pol);
241
	if (freq > 2200000) {
488 242
        if (freq < SLOF) {
489
#ifdef NEWSTRUCT
490 243
          feparams.frequency=(freq-LOF1);
491
#else
492
          feparams.Frequency=(freq-LOF1);
493
#endif
494
          if (tone < 0) tone = SEC_TONE_OFF;
244
	  hi_lo = 0;
245
	  base = LOF1;
495 246
        } else {
496
#ifdef NEWSTRUCT
497 247
          feparams.frequency=(freq-LOF2);
498
#else
499
          feparams.Frequency=(freq-LOF2);
500
#endif
501
          if (tone < 0) tone = SEC_TONE_ON;
502
        }
248
	  hi_lo = 1;
249
	  base = LOF2;
250
      } 
503 251
      } else {
504
        // this is an L-Band frequency
505
#ifdef NEWSTRUCT
506
       feparams.frequency=freq;
507
#else
508
       feparams.Frequency=freq;
509
#endif
252
          feparams.frequency=freq;
253
	  base = 0;
510 254
      }
511 255

  
512
#ifdef NEWSTRUCT
256
      fprintf(stderr,"tuning DVB-S to Freq: %u, Pol:%c Srate=%d, 22kHz tone=%s, LNB: %d\n",feparams.frequency,pol,srate,tone == SEC_TONE_ON ? "on" : "off", diseqc);
513 257
      feparams.inversion=specInv;
514 258
      feparams.u.qpsk.symbol_rate=srate;
515 259
      feparams.u.qpsk.fec_inner=FEC_AUTO;
516
#else
517
      feparams.Inversion=specInv;
518
      feparams.u.qpsk.SymbolRate=srate;
519
      feparams.u.qpsk.FEC_inner=FEC_AUTO;
520
#endif
521

  
522
#ifdef NEWSTRUCT
523
      if (diseqc==0) {
524
      if (ioctl(fd_frontend,FE_SET_TONE,tone) < 0) {
525
               perror("ERROR setting tone\n");
526
      }
527
      }
528
#else
529
      if (ioctl(fd_sec,SEC_SET_TONE,tone) < 0) {
530
         perror("ERROR setting tone\n");
531
      }
532
#endif
260
      dfd = fd_frontend;
533 261

  
534
#ifdef NEWSTRUCT
535
	      if (diseqc > 0) {
536
		do_diseqc(fd_frontend, diseqc-1,voltage,tone);
537
		sleep(1);
538
              }
539
#else
540
      if (diseqc > 0) {
541
        struct secCommand scmd;
542
        struct secCmdSequence scmds;
543

  
544
        scmds.continuousTone = tone;
545
        scmds.voltage = voltage;
546
        /*
547
        scmds.miniCommand = toneBurst ? SEC_MINI_B : SEC_MINI_A;
548
        */
549
        scmds.miniCommand = SEC_MINI_NONE;
550

  
551
        scmd.type = 0;
552
        scmds.numCommands = 1;
553
        scmds.commands = &scmd;
554

  
555
        scmd.u.diseqc.addr = 0x10;
556
        scmd.u.diseqc.cmd = 0x38;
557
        scmd.u.diseqc.numParams = 1;
558
        scmd.u.diseqc.params[0] = 0xf0 | 
559
                                  (((diseqc - 1) << 2) & 0x0c) |
560
                                  (voltage==SEC_VOLTAGE_18 ? 0x02 : 0) |
561
                                  (tone==SEC_TONE_ON ? 0x01 : 0);
562

  
563
        if (ioctl(fd_sec,SEC_SEND_SEQUENCE,&scmds) < 0) {
564
          perror("Error sending DisEqC");
262
   if(do_diseqc(dfd, diseqc, (pol == 'V' ? 1 : 0), hi_lo) == 0)
263
	fprintf(stderr, "DISEQC SETTING SUCCEDED\n");
264
   else  {
265
	fprintf(stderr, "DISEQC SETTING FAILED\n");
565 266
          return -1;
566 267
        }
567
      }
568
#endif
569 268
      break;
570 269
    case FE_QAM:
571 270
      fprintf(stderr,"tuning DVB-C to %d, srate=%d\n",freq,srate);
572
#ifdef NEWSTRUCT
573
      feparams.frequency = freq;
574
      feparams.inversion = specInv;
271
      feparams.frequency=freq;
272
      feparams.inversion=INVERSION_OFF;
575 273
      feparams.u.qam.symbol_rate = srate;
576
      feparams.u.qam.fec_inner = HP_CodeRate;
274
      feparams.u.qam.fec_inner = FEC_AUTO;
577 275
      feparams.u.qam.modulation = modulation;
578
#else
579
      feparams.Frequency = freq;
580
      feparams.Inversion = specInv;
581
      feparams.u.qam.SymbolRate = srate;
582
      feparams.u.qam.FEC_inner = HP_CodeRate;
583
      feparams.u.qam.QAM = modulation;
584
#endif
585 276
      break;
277
#ifdef DVB_ATSC
278
    case FE_ATSC:
279
      fprintf(stderr, "tuning ATSC to %d, modulation=%d\n",freq,modulation);
280
      feparams.frequency=freq;
281
      feparams.u.vsb.modulation = modulation;
282
      break;
283
#endif
586 284
    default:
587 285
      fprintf(stderr,"Unknown FE type. Aborting\n");
588 286
      exit(-1);
589 287
  }
590 288
  usleep(100000);
591 289

  
592
#ifndef NEWSTRUCT   
593
  if (fd_sec) SecGetStatus(fd_sec, &sec_state);
594
#endif
595

  
596
  return(check_status(fd_frontend,&feparams,tone));
290
  return(check_status(fd_frontend,fe_info.type,&feparams,base));
597 291
}
src/tune.h
1 1
#ifndef _TUNE_H
2 2
#define _TUNE_H
3 3

  
4
#ifdef NEWSTRUCT
5
  #include <linux/dvb/frontend.h>
6
#else
7

  
8
// The following defines make the "OLDSTRUCT" driver more compatible with NEWSTRUCT.
9

  
10
  #include <ost/frontend.h>
11

  
12
#define fe_status_t FrontendStatus
13
#define fe_spectral_inversion_t SpectralInversion
14
#define fe_modulation_t Modulation
15
#define fe_code_rate_t CodeRate
16
#define fe_transmit_mode_t TransmitMode
17
#define fe_guard_interval_t GuardInterval
18
#define fe_bandwidth_t BandWidth
19
#define fe_sec_voltage_t SecVoltage
20
#define dmx_pes_filter_params dmxPesFilterParams
21
#define dmx_sct_filter_params dmxSctFilterParams
22
#define dmx_pes_type_t dmxPesType_t
23
#endif
4
#include <linux/dvb/frontend.h>
5
#include <linux/dvb/version.h>
24 6

  
25 7
#include "dvb_defaults.h"
26 8

  
9
#undef DVB_ATSC
10
#if defined(DVB_API_VERSION_MINOR)
11
#if DVB_API_VERSION == 3 && DVB_API_VERSION_MINOR >= 1
12
#define DVB_ATSC 1
13
#endif
14
#endif
15

  
16

  
27 17
#ifdef __cplusplus
28 18
extern "C" {
29 19
#endif
30 20

  
31
int tune_it(int fd_frontend, int fd_sec, unsigned int freq, unsigned int srate, char pol, int tone, fe_spectral_inversion_t specInv, unsigned int diseqc,fe_modulation_t modulation,fe_code_rate_t HP_CodeRate,fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth);
21
int tune_it(int fd_frontend, unsigned int freq, unsigned int srate, char pol, int tone, fe_spectral_inversion_t specInv, unsigned char diseqc,fe_modulation_t modulation,fe_code_rate_t HP_CodeRate,fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth, fe_code_rate_t LP_CodeRate, fe_hierarchy_t hier);
32 22

  
33 23
#ifdef __cplusplus
34 24
}
src/tuner.cpp
39 39
    : numReaders(0),
40 40
      frontendFD(-1),
41 41
      dvrFD(-1),
42
      tuneParams(NULL),
43
      frontendDevice(frontendDevice)      
42
      tuneParams(NULL), oldTuneParams(NULL),
43
      frontendDevice(frontendDevice),
44
      closeTimer(1000, &Tuner::reallyCloseFrontendCallback, this)
44 45
{
45 46
  // Derive the demuxDevice from the frontend string
46 47
  unsigned fPos = frontendDevice.find("frontend");
......
139 140

  
140 141
bool Tuner::openFrontend()
141 142
{
143
  closeTimer.stop();
144
  
145
  // Front end is already open, no need to close it.
146
  if (frontendFD != -1) 
147
    return true;
148
  
142 149
  if((frontendFD = open(frontendDevice.c_str(),O_RDWR)) < 0){
143 150
    std::cerr << "Error opening frontend device " << frontendDevice << ":" 
144 151
	      << strerror(errno) << std::endl;
......
151 158
void Tuner::closeFrontend()
152 159
{
153 160
  if (frontendFD >= 0) {
154
    close(frontendFD);
155
    frontendFD = -1;
161
    // Take a second to actually close the front end
162
    // So that if another channel of the same frequency
163
    // is requested in that time we don't have to waste time re-tuning.
164
    closeTimer.start();
165
    oldTuneParams = tuneParams;
156 166
  }
157 167
}
158 168

  
169
void Tuner::reallyCloseFrontendCallback( void *arg )
170
{
171
  Tuner *self = (Tuner *) arg;
172
  close(self->frontendFD);
173
  self->frontendFD = -1;
174
  self->oldTuneParams = 0;
175
}
176

  
159 177
bool Tuner::openDvr()
160 178
{
161 179
  if((dvrFD = open(dvrDevice.c_str(),O_RDONLY|O_NONBLOCK)) < 0){
......
176 194

  
177 195
bool Tuner::tune()
178 196
{
179
  return tuneParams->tune(frontendFD);
197
  if (tuneParams == oldTuneParams)
198
    return true;
199
  
200
  if (!tuneParams->tune(frontendFD))
201
    return false;
202
  
203
  oldTuneParams = tuneParams;
204
  return true;
180 205
}
181 206

  
182 207
bool Tuner::subscribe(Sink *s)
src/tuner.h
23 23
#include "source.h"
24 24
#include "select.h"
25 25
#include "demuxer.h"
26
#include "timer.h"
26 27

  
27 28
#include <string>
28 29
#include <map>
......
64 65
  virtual bool tune();
65 66

  
66 67
private:
68
  static void reallyCloseFrontendCallback(void *);
69

  
70
private:
67 71
  int numReaders;
68 72
  int frontendFD, dvrFD;
69
  const TuneParams *tuneParams;
73
  const TuneParams *tuneParams, *oldTuneParams;
70 74
  std::string frontendDevice, demuxDevice, dvrDevice;
75

  
76
  Timer closeTimer;
71 77
  
72 78
  // Keep a track of all the demuxers ever created.
73 79
  // The Tuner owns the demuxers.

Also available in: Unified diff