Revision 59be6a47

View differences:

.cvsignore
2 2
Makefile.in
3 3
aclocal.m4
4 4
autom4te.cache
5
build-arch-stamp
6
build-indep-stamp
5 7
config.guess
6 8
config.h
7 9
config.h.in
ChangeLog
1
2003-12-28  John Knottenbelt  <jak@buffy.home.net>
2

  
3
	Default is now to record TS streams
4
	Can use -P to specify program stream
5
	
6
2003-12-27  John Knottenbelt  <jak@buffy.home.net>
7

  
8
	Include header files in dist
9
	Debian packagified
10
	Automakified
11
	fixed bug with reporting job number
TODO
2 2
you have suggestions on what else to put on this
3 3
list please contact me at jak@users.sourceforge.net
4 4
   
5
improve Autoconf / Automake, Debian packages
6
Display job number of scheduled job (dvbsched)
5
Output threshold for OutputBuffer.
6

  
7 7
Allow scheduled jobs to be removed (dvbsched)
8 8
Xine input plugin
9 9
Satellite and Cable support.   
configure.ac
1
AC_INIT(dvbd, 0.5.0)
1
AC_INIT(dvbd, 0.5.2)
2 2
AC_CONFIG_SRCDIR(src/dvbd.cpp)
3 3
AM_INIT_AUTOMAKE
4 4
AM_CONFIG_HEADER(config.h)
debian/changelog
1
dvbd (0.5.2) unstable; urgency=low
2

  
3
  * Permissions bug fixes
4

  
5
 -- John Knottenbelt <jak@users.sourceforge.net>  Sun, 28 Dec 2003 18:08:00 +0000
1 6
dvbd (0.5.0) unstable; urgency=low
2 7

  
3 8
  * Initial Release.
debian/dirs
1 1
usr/bin
2 2
usr/sbin
3
var/spool/dvbd
4
var/run/dvbd
3
var/spool
4
var/run
5
etc
debian/docs
1 1
NEWS
2 2
README
3 3
TODO
4
CREDITS
5
dvbd.html
6
dvbd.css
src/Makefile.am
13 13
    lobby.cpp circularbuffer.cpp inputbuffer.cpp outputbuffer.cpp		\
14 14
    signals.cpp configfile.cpp scheduler.cpp fakedemuxer.cpp faketuner.cpp	\
15 15
    faketunermanager.cpp recording.cpp utils.cpp stringrep.cpp			\
16
    transform.c tune.c ringbuffy.c remux.c ctools.c
16
    transform.c tune.c ringbuffy.c remux.c ctools.c psfilter.cpp
17 17

  
18 18
dvbsched_SOURCES =						\
19 19
    unixclientsocket.cpp stringutil.cpp				\
......
42 42
    outputbuffer.h parsetime.h recording.h remux.h ringbuffy.h scheduler.h	\
43 43
    select.h source.h stringrep.h stringutil.h time-parser.h transform.h	\
44 44
    tune.h tuneparams.h tuner.h tunermanager.h unixclientsocket.h		\
45
    unixserversocket.h utils.h
45
    unixserversocket.h utils.h psfilter.h
46 46

  
47 47

  
48 48

  
src/clientconnection.cpp
107 107
}
108 108

  
109 109
int ClientConnection::schedule(const std::string &type, const std::string &channel,
110
			       time_t when, unsigned duration, int priority,
110
			       bool convertToPS, time_t when, unsigned duration, int priority,
111 111
			       const std::string &outputFile)
112 112
{
113 113
  SetBlocking saveBlocking(control_, true);
......
118 118

  
119 119
  std::string command = 
120 120
    "SCHEDULE " + dateTime + " " + type + " " + escapeWS(channel) + " " + 
121
    toString(priority) + " " + toString(duration * 60) + " " + outputFile + "\n";
121
    toString(convertToPS) + " " + toString(priority) + " " + 
122
    toString(duration * 60) + " " + outputFile + "\n";
122 123
  std::cerr << command;
123 124

  
124 125
  control_.write(command);
......
174 175
  return false;
175 176
}
176 177

  
177
bool ClientConnection::tune(const std::string &type, const std::string &channel, int priority)
178
bool ClientConnection::tune(const std::string &type, const std::string &channel, 
179
			    bool convertToPS, int priority)
178 180
{
179 181
  SetBlocking saveBlocking(control_, true);
180
  control_.write("TUNE " + type + " " + escapeWS(channel) + " " + toString(priority) + "\n");
182
  control_.write("TUNE " + type + " " + escapeWS(channel) + " " + 
183
		 toString(convertToPS) + " " + toString(priority) + "\n");
181 184
  std::string reply;
182 185
  control_.readLine(reply);
183 186
  if (reply == "OK\n")
src/clientconnection.h
43 43
  void checkSchedule(StringList&);
44 44

  
45 45
  int schedule(const std::string &type, const std::string &channel,
46
	       time_t when, unsigned duration, int priority,
46
	       bool convertToPS, time_t when, unsigned duration, int priority,
47 47
	       const std::string &outputFile);
48 48

  
49 49
  bool removeJob(int job);
50 50

  
51 51
  bool listSchedule(StringList &);
52 52

  
53
  bool tune(const std::string &type, const std::string &channel, int priority);
53
  bool tune(const std::string &type, const std::string &channel, bool convertToPS, int priority);
54 54

  
55 55
  bool getNextJobTime(time_t &nextJobTime);
56 56

  
src/connection.cpp
62 62

  
63 63
void Connection::doUnsubscribe()
64 64
{
65
  DemuxerList copy = demuxers;
66
  for (DemuxerList::iterator i = copy.begin(); i != copy.end(); i++)
65
  SourceList copy = demuxers;
66
  for (SourceList::iterator i = copy.begin(); i != copy.end(); i++)
67 67
    (*i)->unsubscribe(this);
68 68
}
69 69

  
......
72 72
  bool result = true;
73 73
  int n = 0;
74 74

  
75
  for (DemuxerList::iterator i = demuxers.begin(); i != demuxers.end(); i++) 
75
  for (SourceList::iterator i = demuxers.begin(); i != demuxers.end(); i++) 
76 76
    result = (*i)->subscribe(this) && result;
77 77
   
78 78
  if (!result) {
......
172 172
}
173 173

  
174 174

  
175
bool Connection::tune(const std::string &newType, const std::string &newChannel, int p)
175
bool Connection::tune(const std::string &newType, const std::string &newChannel, bool convertToPS, int p)
176 176
{
177 177
  if (tuned) {
178 178
    if (type == newType && channel == newChannel) {
......
191 191
  // be expected since the request is to change the channel!
192 192
  retuning = true;
193 193
  
194
  DemuxerList newDemuxers;
194
  SourceList newDemuxers;
195 195

  
196 196
  // Set the priority of the current channel
197 197
  // to be less than the specified priority
......
199 199
    SavePriority save(this, p - 1);
200 200

  
201 201
    // Try to allocate the new demuxers
202
    tm->getDemuxers(newType, newChannel, true, newDemuxers, p);
202
    tm->getDemuxers(newType, newChannel, convertToPS, newDemuxers, p);
203 203
    retuning = false;
204 204

  
205 205
    if (newDemuxers.empty()) 
src/connection.h
50 50
  time_t getStopTime() const;
51 51

  
52 52
  bool canTune(const std::string &newType, const std::string &newChannel, int p) const;
53
  bool tune(const std::string &newType, const std::string &newChannel, int p);
53
  bool tune(const std::string &newType, const std::string &newChannel, bool convertToPS, int p);
54 54

  
55 55
  bool getInterrupted() const;
56 56

  
......
80 80
  TunerManager *tm;
81 81
  std::string channel, type;
82 82
  OutputBuffer *dataOutput;
83
  DemuxerList demuxers;
83
  SourceList demuxers;
84 84
  bool removeMe;
85 85
  time_t stopTime;
86 86
  bool interrupted;
src/controlledconnection.cpp
142 142
    // TUNE <type> <channel> <priority>
143 143
    // (Used to tune/retune)
144 144
    else if (words[0] == "TUNE") {
145
      if (words.size() != 4) 
146
	writeControl("ERROR TUNE WRONG NUMBER OF ARGS (Expected 3, got " +
145
      if (words.size() != 5) 
146
	writeControl("ERROR TUNE WRONG NUMBER OF ARGS (Expected 4, got " +
147 147
		     ::toString(words.size() - 1) + ")\n");
148 148
      else {
149 149
	const std::string &type = words[1];
150 150
	std::string channel = unescapeWS(words[2]);
151
	int priority = toInt(words[3]);
151
	bool convertToPS = toBool(words[3]);
152
	int priority = toInt(words[4]);
152 153

  
153 154
	// Check the arguments
154 155
	if (!isValidType(type)) 
......
159 160
	  writeControl( "ERROR TUNE INSUFFICIENT PRIORITY ("+::toString(priority)+")\n");
160 161
	}
161 162
	else {
162
	  bool result = tune(type, channel, priority);
163
	  bool result = tune(type, channel, convertToPS, priority);
163 164
	  if (result)
164 165
	    writeControl( "OK\n");
165 166
	  else 
......
169 170
    }
170 171
    // SCHEDULE <date> <time> <type> <channel> <priority> <duration> <path>
171 172
    else if (words[0] == "SCHEDULE") {
172
      if (words.size() != 8) 
173
	writeControl("ERROR SCHEDULE WRONG NUMBER OF ARGS (Expected 7, got " +
173
      if (words.size() != 9) 
174
	writeControl("ERROR SCHEDULE WRONG NUMBER OF ARGS (Expected 8, got " +
174 175
		     ::toString(words.size() - 1) + ")\n");
175 176
      else {
176 177
	std::string dateTime = words[1] + " " + words[2];
......
183 184

  
184 185
	  const std::string &type = words[3];
185 186
	  const std::string channel = unescapeWS(words[4]);
186
	  int priority = toInt(words[5]);
187
	  int duration = toInt(words[6]);	// duration in seconds
188
	  const std::string path = unescapeWS(words[7]);
187
	  bool convertToPS = toBool(words[5]);
188
	  int priority = toInt(words[6]);
189
	  int duration = toInt(words[7]);	// duration in seconds
190
	  const std::string path = unescapeWS(words[8]);
189 191
	  pid_t pid = 0;
190 192
	  uid_t uid = 0;
191 193
	  gid_t gid = 0;
......
205 207
	    std::cerr << "Scheduling recording for " << theTime 
206 208
		      << " (now " << time(NULL) << ")\n";
207 209

  
208
	    Recording r(type, channel, priority, theTime, duration, path, uid);
210
	    Recording r(type, channel, convertToPS, priority, theTime, duration, path, uid);
209 211
	    scheduler->add(r);
210 212
	    std::cerr << "Job number is " << r.getJob() << "\n";
211 213
	    writeControl("JOB " + ::toString(r.getJob()) + "\n");
src/debug.h
1
// -*- c++ -*-
1 2
/*
2 3
  Copyright 2003 John Knottenbelt
3 4
  
src/demuxer.cpp
36 36

  
37 37
#include <linux/dvb/dmx.h>
38 38

  
39
#define IPACKS 2048
40
#define TS_SIZE 188
41

  
42 39
static void set_ts_filt(int fd,uint16_t pid, dmx_pes_type_t pestype);
43 40

  
44
Demuxer::Demuxer(Tuner *tuner, int pid, bool convertToPS, Demuxer::PESType pestype)
41
Demuxer::Demuxer(Tuner *tuner, int pid, Demuxer::PESType pestype)
45 42
  : tuner(tuner), pid(pid), demuxFD(-1)
46 43
{
47
  init_ipack(&packer, IPACKS, output, 1);
48

  
49 44
  switch (pestype) {
50 45
  case Video: this->pesType = int(DMX_PES_VIDEO); break;
51 46
  case Audio: this->pesType = int(DMX_PES_AUDIO); break;
52 47
  case Teletext: this->pesType = int(DMX_PES_TELETEXT); break;
53 48
  }
54
  packer.data = this;
55 49
}
56 50

  
57 51
Demuxer::~Demuxer()
58 52
{
59 53
  unsubscribeAll();
60
  free_ipack(&packer);
61
}
62

  
63
// Static function for use by the ipack code
64
void Demuxer::output(uint8_t *data, int size, void *priv)
65
{
66
  Demuxer *d = (Demuxer *) priv;
67
  d->sendData(data, (unsigned) size);
68 54
}
69 55

  
70 56
bool Demuxer::openDemux()
......
136 122
}
137 123

  
138 124

  
139
void Demuxer::receiveData(unsigned char *data, unsigned size)
125
// From transform.c (Marcus Metzler)
126
#define PID_MASK_HI 0x1F
127
static inline uint16_t get_pid(uint8_t *pid)
140 128
{
141
  if (convertToPS) {
142
    // adapted from my_ts_to_ps( uint8_t* buf, uint16_t pida, uint16_t pidv)
143
    // in dvbstream.c (Dave Chapman)
144

  
145
    uint16_t pid;
146
    ipack *p = &this->packer;
147
    uint8_t off = 0;
148
    uint8_t *buf = (uint8_t *) data;
149

  
150
    pid = get_pid(buf+1);
151
    if (!(buf[3]&0x10)) // no payload?
152
      return;
153

  
154
    // Is this our packet?
155
    if (pid != this->pid)
156
      return;
157

  
158
    if ( buf[1]&0x40) {
159
      if (p->plength == MMAX_PLENGTH-6){
160
	p->plength = p->found-6;
161
	p->found = 0;
162
	send_ipack(p);
163
	reset_ipack(p);
164
      }
165
    }
129
  uint16_t pp = 0;
166 130

  
167
    if ( buf[3] & 0x20) {  // adaptation field?
168
      off = buf[4] + 1;
169
    }
170
        
171
    instant_repack(buf+4+off, TS_SIZE-4-off, p);
172
  }
173
  else {
174
    if (get_pid(data + 1) == pid)
175
      sendData(data, (unsigned) size);
176
  }
131
  pp = (pid[0] & PID_MASK_HI)<<8;
132
  pp |= pid[1];
133

  
134
  return pp;
135
}
136

  
137
void Demuxer::receiveData(unsigned char *data, unsigned size)
138
{
139
  if (get_pid(data + 1) == pid)
140
    sendData(data, (unsigned) size);
177 141
}
178 142

  
179 143
static void set_ts_filt(int fd,uint16_t pid, dmx_pes_type_t pestype)
src/demuxer.h
21 21
#define __DEMUXER_H
22 22

  
23 23
#include "source.h"
24
#include "transform.h"
25 24

  
26 25
class Tuner;
27 26

  
......
32 31
protected:
33 32

  
34 33
  friend class Tuner;
35
  Demuxer(Tuner *tuner, int pid, bool convertToPS, PESType pestype);
34
  Demuxer(Tuner *tuner, int pid, PESType pestype);
36 35
  virtual ~Demuxer();
37 36

  
38 37
public:
......
52 51
private:
53 52
  Tuner *tuner;
54 53
  int pid;
55
  bool convertToPS;
56 54
  int demuxFD;
57
  ipack packer;
58 55
  int pesType;
59

  
60
  // Called when enough data is ready to write
61
  static void output(uint8_t *data, int size, void *priv);
62 56
};
63 57

  
64 58
#endif // __DEMUXER_H
src/dvbcat.cpp
56 56
  bool durationSpecified = false;
57 57
  unsigned duration = 0;
58 58
  int priority = 10;
59
  bool convertToPS = false;
59 60

  
60 61
  while (true) {
61 62
    static struct option long_options[] = {
......
63 64
      {"priority", 1, 0, 'p'},
64 65
      {"output", 1, 0, 'o'},
65 66
      {"socket", 1, 0, 's'},
67
      {"ps", 0, 0, 'P'},
66 68
      {0, 0, 0, 0}
67 69
    };
68 70
 
69 71
    int option_index = 0;
70
    int c = getopt_long(argc, argv, "d:p:o:s:", long_options, &option_index);
72
    int c = getopt_long(argc, argv, "Pd:p:o:s:", long_options, &option_index);
71 73
    if (c == -1)
72 74
      break;
73 75
    switch (c) {
......
84 86
    case 's':
85 87
      socketFile = optarg;
86 88
      break;
89
    case 'P':
90
      convertToPS = true;
91
      break;
87 92
    default:
88 93
      usage(argv[0]);
89 94
      return 1;
......
118 123
  }
119 124

  
120 125
  // Tune the channel
121
  if (!client.tune(type, channel, priority)) {
126
  if (!client.tune(type, channel, convertToPS, priority)) {
122 127
    std::cerr << "Failed to tune channel. Response from server was:\n"
123 128
	      << client.getError() << "\n";
124 129
    return 1;
......
217 222
	    << "  -o, --output           Record to output file\n"
218 223
	    << "                         (default is standard output).\n"
219 224
	    << "  -s, --socket           Specify socket to connect to\n"
220
	    << "                         (default is " << DEFAULT_SOCKET_FILE << ")\n";
225
	    << "                         (default is " << DEFAULT_SOCKET_FILE << ")\n"
226
	    << "  -P, --ps               Convert stream to program stream\n";
221 227
}
src/dvbsched.cpp
51 51
  std::ios::sync_with_stdio(false);
52 52

  
53 53
  std::string socketFile = DEFAULT_SOCKET_FILE;
54

  
54
  bool convertToPS = false;
55 55
  int priority = 10;
56 56

  
57 57
  while (true) {
58 58
    static struct option long_options[] = {
59 59
      {"priority", 1, 0, 'p'},
60 60
      {"socket", 1, 0, 's'},
61
      {"ps", 0, 0, 'P'},
61 62
      {0, 0, 0, 0}
62 63
    };
63 64
 
......
72 73
    case 's':
73 74
      socketFile = optarg;
74 75
      break;
75
      
76
    case 'P':
77
      convertToPS = true;
76 78
      break;
77 79
    default:
78 80
      usage(argv[0]);
......
104 106

  
105 107
  // Schedule
106 108

  
107
    int job = client.schedule(type, channel, scheduleTime, duration, priority, outputFile);
109
    int job = client.schedule(type, channel, convertToPS, scheduleTime, duration, priority, outputFile);
108 110

  
109 111
    if (job < 0) {
110 112
      std::cerr << "Failed to schedule job\n";
......
127 129
      while (std::cin >> answer) {
128 130
	switch (tolower(answer)) {
129 131
	case 'y':
130
	  std::cout << "Scheduled as job " << job << "\n";
132
	  std::cout << "Job Scheduled\n";
131 133
	  return 0;
132 134
	case 'n':
133 135
	  client.removeJob(job);
......
169 171
	    << "                         higher priorities may dislodge lower\n"
170 172
	    << "                         ones).\n"
171 173
	    << "  -s, --socket           Specify socket to connect to\n"
172
	    << "                         (default is " << DEFAULT_SOCKET_FILE << ")\n";
174
	    << "                         (default is " << DEFAULT_SOCKET_FILE << ")\n"
175
	    << "  -P, --ps               Convert stream to program stream\n";
173 176
}
174 177

  
175 178
// For parsetime
src/fakedemuxer.cpp
18 18

  
19 19
#include "fakedemuxer.h"
20 20

  
21
FakeDemuxer::FakeDemuxer(Tuner *tuner, int pid, bool convertToPS, PESType pestype)
22
  : Demuxer(tuner, pid, convertToPS, pestype)
21
FakeDemuxer::FakeDemuxer(Tuner *tuner, int pid, PESType pestype)
22
  : Demuxer(tuner, pid, pestype)
23 23
{
24 24
}
25 25

  
src/fakedemuxer.h
27 27
class FakeDemuxer : public Demuxer {
28 28
protected:
29 29
  friend class FakeTuner;
30
  FakeDemuxer(Tuner *tuner, int pid, bool convertToPS, PESType pestype);
30
  FakeDemuxer(Tuner *tuner, int pid, PESType pestype);
31 31

  
32 32
protected:
33 33
  virtual bool openDemux();
src/faketuner.cpp
29 29
  setTuneParams(realTuner.getTuneParams());
30 30
}
31 31

  
32
Demuxer *FakeTuner::makeNewDemuxer(int pid, bool convertToPS, Demuxer::PESType pesType) const
32
Demuxer *FakeTuner::makeNewDemuxer(int pid, Demuxer::PESType pesType) const
33 33
{
34
  return new FakeDemuxer(const_cast<FakeTuner *>(this), pid, convertToPS, pesType);
34
  return new FakeDemuxer(const_cast<FakeTuner *>(this), pid, pesType);
35 35
}
36 36

  
37 37
bool FakeTuner::openFrontend()
src/faketuner.h
27 27
  FakeTuner( const Tuner &realTuner );
28 28

  
29 29
protected:
30
  virtual Demuxer *makeNewDemuxer(int pid, bool convertToPS, Demuxer::PESType pesType) const;
30
  virtual Demuxer *makeNewDemuxer(int pid, Demuxer::PESType pesType) const;
31 31
  virtual bool openFrontend();
32 32
  virtual void closeFrontend();
33 33
  virtual bool openDvr();
src/psfilter.cpp
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
  You should have received a copy of the GNU General Public License
14
  along with this program; if not, write to the Free Software
15
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
16
*/
17

  
18
#include "config.h"
19
#include "psfilter.h"
20

  
21
#define IPACKS 2048
22
#define TS_SIZE 188
23

  
24
PSFilter::PSFilter(Source *source)
25
  : source(source)
26
{
27
  init_ipack(&packer, IPACKS, output, 1);
28
  packer.data = this;
29
}
30

  
31
PSFilter::~PSFilter()
32
{
33
  unsubscribeAll();
34
  free_ipack(&packer);
35
}
36

  
37
// Static function for use by the ipack code
38
void PSFilter::output(uint8_t *data, int size, void *priv)
39
{
40
  PSFilter *d = static_cast<PSFilter *>(priv);
41
  d->sendData(data, (unsigned) size);
42
}
43

  
44
void PSFilter::unsubscribe(Sink *s) 
45
{
46
  Source::unsubscribe(s);
47
  if (getNumSubscribers() == 0) {
48
    source->unsubscribe(this);
49
    reset_ipack(&packer);
50
  }
51
}
52

  
53
void PSFilter::notifyUnsubscribe(Source *)
54
{
55
  // Since our source is no longer available
56
  // we should unsubscribe the clients.
57
  unsubscribeAll();
58
}
59

  
60
bool PSFilter::subscribe(Sink *s)
61
{
62
  if (getNumSubscribers() == 0) {
63
    if (!source->subscribe(this))
64
      return false;
65
  } 
66
  return Source::subscribe(s);
67
}
68

  
69
void PSFilter::receiveData(unsigned char *data, unsigned size)
70
{
71
  // adapted from my_ts_to_ps( uint8_t* buf, uint16_t pida, uint16_t pidv)
72
  // in dvbstream.c (Dave Chapman)
73

  
74
  ipack *p = &packer;
75
  uint8_t off = 0;
76
  uint8_t *buf = (uint8_t *) data;
77

  
78
  if (!(buf[3]&0x10)) // no payload?
79
    return;
80

  
81
  if ( buf[1]&0x40) {
82
    if (p->plength == MMAX_PLENGTH-6){
83
      p->plength = p->found-6;
84
      p->found = 0;
85
      send_ipack(p);
86
      reset_ipack(p);
87
    }
88
  }
89

  
90
  if ( buf[3] & 0x20) {  // adaptation field?
91
    off = buf[4] + 1;
92
  }
93
        
94
  instant_repack(buf+4+off, TS_SIZE-4-off, p);
95
}
src/psfilter.h
1
// -*- c++ -*-
2
/*
3
  Copyright 2003 John Knottenbelt
4
  
5
  This program is free software; you can redistribute it and/or modify
6
  it under the terms of the GNU General Public License as published by
7
  the Free Software Foundation; either version 2 of the License, or
8
  (at your option) any later version.
9
 
10
  This program is distributed in the hope that it will be useful,
11
  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
  GNU General Public License for more details.
14
 
15
  You should have received a copy of the GNU General Public License
16
  along with this program; if not, write to the Free Software
17
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
18
*/
19

  
20
#if !defined __PSFILTER_H
21
#define __PSFILTER_H
22

  
23
#include "source.h"
24
#include "transform.h"
25

  
26
/** Class to convert TS (actually PES) to PS streams **/
27

  
28
class PSFilter : public Source, public Sink {
29
public:
30

  
31
  PSFilter(Source *source);
32
  virtual ~PSFilter();
33

  
34
  virtual void receiveData(unsigned char *data, unsigned size);
35
  virtual bool subscribe(Sink *s);
36
  virtual void unsubscribe(Sink *s);
37
  virtual void notifyUnsubscribe(Source *s);
38

  
39
private:
40
  ipack packer;
41
  // Called when enough data is ready to write
42
  static void output(uint8_t *data, int size, void *priv);
43
  Source *source;
44
};
45

  
46
#endif // __PSFILTER_H
src/recording.cpp
18 18

  
19 19
#include "config.h"
20 20
#include "utils.h"
21
#include "stringutil.h"
21 22
#include "recording.h"
22 23

  
23 24
Recording::~Recording()
......
32 33
	   localtime(&startTime));
33 34

  
34 35
  o << job << " " << uid << " " << dateTime << " " << type << " " 
35
    << escapeWS(channel) << " " 
36
    << escapeWS(channel) << " " << ::toString(convertToPS) << " "
36 37
    << duration << " " << priority << " " << escapeWS(path);
37 38

  
38 39
  return o;
......
40 41

  
41 42
std::istream &operator >> (std::istream &i, Recording &r)
42 43
{
43
  std::string datePart, timePart, channel, path;
44
  std::string datePart, timePart, channel, path, convertToPS;
44 45

  
45 46
  i >> r.job 
46 47
    >> r.uid >> datePart >> timePart >> r.type >> channel
47
    >> r.duration >> r.priority >> path;
48
    >> convertToPS >> r.duration >> r.priority >> path;
48 49

  
49 50
  r.channel = unescapeWS(channel);
51
  r.convertToPS = toBool(convertToPS);
50 52
  r.path = unescapeWS(path);
51 53
  
52 54
  std::string dateTime = datePart + " " + timePart;
src/recording.h
35 35

  
36 36
  Recording(const std::string &type,
37 37
	    const std::string &channel,
38
	    bool convertToPS,
38 39
	    int priority,
39 40
	    time_t startTime,
40 41
	    unsigned duration,
......
42 43
	    uid_t uid)
43 44
    : job(-1),
44 45
      type(type), channel(channel),
46
      convertToPS(convertToPS),
45 47
      priority(priority), startTime(startTime),
46 48
      duration(duration), path(path), 
47 49
      uid(uid)
......
66 68
    return channel;
67 69
  }
68 70

  
71
  bool getConvertToPS() const {
72
    return convertToPS;
73
  }
74

  
69 75
  int getPriority() const {
70 76
    return priority;
71 77
  }
......
99 105
private:
100 106
  int job;
101 107
  std::string type, channel;
108
  bool convertToPS;
102 109
  int priority; 
103 110
  time_t startTime;
104 111
  unsigned duration;
src/scheduler.cpp
162 162

  
163 163
  Connection *c = new Connection( tm, dataFD );
164 164
  c->setStopTime( r.getStopTime() );
165
  c->tune(r.getType(), r.getChannel(), r.getPriority());
165
  c->tune(r.getType(), r.getChannel(), r.getConvertToPS(), r.getPriority());
166 166
  cm->add(c);
167 167
}
168 168

  
......
213 213
    programs[c] = r;
214 214
    c->setStopTime( r.getStopTime() );
215 215

  
216
    if (!c->tune(r.getType(), r.getChannel(), r.getPriority())) {
216
    if (!c->tune(r.getType(), r.getChannel(), r.getConvertToPS(), r.getPriority())) {
217 217
      interruptions.push_back( "Failed to start recording: " + r.toString() );
218 218
      delete c;
219 219
    }
src/source.cpp
59 59

  
60 60
void Source::unsubscribeAll()
61 61
{
62
  List copy = subscribers;
62
  SinkList copy = subscribers;
63 63

  
64
  for (List::const_iterator i = copy.begin(); i != copy.end(); i++)
64
  for (SinkList::const_iterator i = copy.begin(); i != copy.end(); i++)
65 65
    unsubscribe(*i);
66 66
}
67 67

  
68 68
void Source::sendData(unsigned char *data, unsigned size) const
69 69
{
70
  for (List::const_iterator i = subscribers.begin(); i != subscribers.end(); i++)
70
  for (SinkList::const_iterator i = subscribers.begin(); i != subscribers.end(); i++)
71 71
    (*i)->receiveData(data, size);
72 72
}
73 73

  
......
76 76
  // Kick subscribers with priority < specified priority
77 77
  // Return number of subscribers kicked.
78 78
  int count = 0;
79
  List copy = subscribers;
79
  SinkList copy = subscribers;
80 80

  
81
  for (List::iterator i = copy.begin(); i != copy.end(); i++) {
81
  for (SinkList::iterator i = copy.begin(); i != copy.end(); i++) {
82 82
    Sink *d = *i;
83 83

  
84 84
    if (d->getPriority() < priority) {
......
93 93
{
94 94
  // Return the number of subscribers with priority >= specified priority
95 95
  int count = 0;
96
  for (List::const_iterator i = subscribers.begin(); i != subscribers.end(); i++) {
96
  for (SinkList::const_iterator i = subscribers.begin(); i != subscribers.end(); i++) {
97 97
    const Sink *d = *i;
98 98

  
99 99
    if (d->getPriority() >= priority)
......
106 106
{
107 107
  // Return the maximum subscribed priority
108 108
  int result = INT_MIN;
109
  for (List::const_iterator i = subscribers.begin(); i != subscribers.end(); i++) {
109
  for (SinkList::const_iterator i = subscribers.begin(); i != subscribers.end(); i++) {
110 110
    const Sink *c = *i;
111 111

  
112 112
    if (c->getPriority() > result)
src/source.h
60 60
  virtual void notifyUnsubscribe(Source *source);
61 61
};
62 62

  
63
typedef std::list<Source *> SourceList;
64
typedef std::list<Sink *> SinkList;
65

  
63 66
// Source abstract base class
64 67
class Source : public virtual Priority {
65 68
public:
......
78 81
protected:
79 82
  virtual void sendData(unsigned char *data, unsigned size) const;
80 83

  
81
  typedef std::list<Sink *> List;
82
  List subscribers;
84
  SinkList subscribers;
83 85
};
84 86

  
87

  
85 88
#endif // __SOURCE_H
src/stringutil.cpp
32 32
    return l;
33 33
}
34 34

  
35
string toString(bool b)
36
{
37
  if (b) return "true";
38
  else return "false";
39
}
40

  
35 41
string toString(int n)
36 42
{
37 43
    char text[64];
......
64 70
	return 0.0;
65 71
}
66 72

  
73
bool toBool(const std::string &s)
74
{
75
  if (s == "true")
76
    return true;
77
  else
78
    return false;
79
}
80

  
67 81
unsigned long toUnsignedLong(const std::string &s)
68 82
{
69 83
    istringstream input(s);
src/stringutil.h
24 24
#include <vector>
25 25
#include <ctime>
26 26

  
27
std::string toString(bool b);
27 28
std::string toString(int n);
28 29
std::string toString(unsigned n);
29 30
std::string toString(double n);
......
32 33
unsigned toUnsigned(const std::string &s);
33 34
unsigned long toUnsignedLong(const std::string &s);
34 35
double toDouble(const std::string &s);
36
bool toBool(const std::string &s);
35 37

  
36 38
void splitString(const std::string &s, char delim, std::vector<std::string> &v);
37 39
std::string stripLeadingWS(const std::string &s);
src/tuner.cpp
20 20
#include "tuner.h"
21 21
#include "demuxer.h"
22 22
#include "tuneparams.h"
23
#include "psfilter.h"
23 24
#include "debug.h"
24 25

  
25 26
#include <iostream>
......
64 65

  
65 66
Tuner::~Tuner()
66 67
{
67
  List copy = subscribers;
68
  SinkList copy = subscribers;
68 69

  
69 70
  unsubscribeAll();
70 71

  
71 72
  // Destroy all the Demuxes
72
  for (int h = 0; h < 2; h++) {
73
    DemuxerMap &dm = demuxerMap[h];
74
    for (DemuxerMap::iterator i = dm.begin(); i != dm.end(); i++) {
75
      PIDMap &pidmap = i->second;
76
      for (PIDMap::iterator j = pidmap.begin(); j != pidmap.end(); j++)
77
	delete j->second;
78
    }
73
  for (DemuxerMap::iterator i = demuxerMap.begin(); i != demuxerMap.end(); i++) {
74
    PIDMap &pidmap = i->second;
75
    for (PIDMap::iterator j = pidmap.begin(); j != pidmap.end(); j++)
76
      delete j->second;
79 77
  }
78

  
79
  // Destroy all the PSFilters
80
  for (PSFilterMap::iterator i = psfilterMap.begin(); i != psfilterMap.end(); i++) 
81
    delete i->second;
80 82
}
81 83

  
82 84
void Tuner::setTuneParams(const TuneParams *tuneParams)
......
101 103
  return s.readyToRead(dvrFD);
102 104
}
103 105

  
104
Demuxer *Tuner::makeNewDemuxer(int pid, bool convertToPS, Demuxer::PESType pesType) const
106
Demuxer *Tuner::makeNewDemuxer(int pid, Demuxer::PESType pesType) const
105 107
{
106
  return new Demuxer(const_cast<Tuner *>(this), pid, convertToPS, pesType);
108
  return new Demuxer(const_cast<Tuner *>(this), pid, pesType);
107 109
}
108 110

  
109 111
// Keep a list of all the demuxers ever created
110
Demuxer *Tuner::getDemuxer(int pid, bool convertToPS, Demuxer::PESType pesType) const
112
Source *Tuner::getDemuxer(int pid, bool convertToPS, Demuxer::PESType pesType) const
111 113
{
112 114
  // Strictly speaking getDemuxer() is not a const
113 115
  // method, however, it does have minimal side
......
119 121

  
120 122
  assert(tuneParams != NULL);
121 123

  
122
  DemuxerMap &dm = demuxerMap[ convertToPS ? 1 : 0 ];
124
  DemuxerMap &dm = demuxerMap;
123 125
  PIDMap &pidMap = dm[tuneParams];
124 126
  Demuxer *&demuxer = pidMap[pid];
125 127

  
126
  if (demuxer == NULL)
127
    demuxer = makeNewDemuxer(pid, convertToPS, pesType);
128
  if (demuxer == NULL) 
129
    demuxer = makeNewDemuxer(pid, pesType);
130

  
131
  if (!convertToPS) 
132
    return demuxer;
128 133

  
129
  return demuxer;
134
  PSFilter *&psfilter = psfilterMap[demuxer];
135
  if (psfilter == NULL) 
136
    psfilter = new PSFilter(demuxer);
137
  return psfilter;
130 138
}
131 139

  
132 140
bool Tuner::openFrontend()
src/tuner.h
29 29

  
30 30
class TuneParams;
31 31
class Demuxer;
32
class PSFilter;
32 33

  
33 34
class Tuner : public Source, public Selectable {
34 35
public:
......
45 46
  virtual void addSelectFDs(Select &) const;
46 47
  virtual bool isReady(const Select &) const;
47 48

  
48
  Demuxer *getDemuxer(int pid, bool convertToPS, Demuxer::PESType pesType) const;
49
  Source *getDemuxer(int pid, bool convertToPS, Demuxer::PESType pesType) const;
49 50

  
50 51
  int getMaxNumSubscribers() const { return 8; }
51 52
  virtual bool subscribe(Sink *s);
......
55 56
  void process();
56 57

  
57 58
protected:
58
  virtual Demuxer *makeNewDemuxer(int pid, bool convertToPS, Demuxer::PESType pesType) const;
59
  virtual Demuxer *makeNewDemuxer(int pid, Demuxer::PESType pesType) const;
59 60
  virtual bool openFrontend();
60 61
  virtual void closeFrontend();
61 62
  virtual bool openDvr();
......
73 74

  
74 75
  typedef std::map <int, Demuxer *> PIDMap;
75 76
  typedef std::map <const TuneParams *, PIDMap> DemuxerMap;
77
  typedef std::map <Demuxer *, PSFilter *> PSFilterMap;
78

  
79
  mutable DemuxerMap demuxerMap;
80
  mutable PSFilterMap psfilterMap;
76 81

  
77
  // demuxerMap[0] for TS
78
  // demuxerMap[1] for PS
79
  mutable DemuxerMap demuxerMap[2];
80 82
};
81 83

  
82 84
#endif // __TUNER_H
src/tunermanager.cpp
180 180
	  continue;
181 181
      }
182 182

  
183
      Demuxer *audio = t->getDemuxer(c->getAudioPID(), false, Demuxer::Audio);
184
      Demuxer *video = t->getDemuxer(c->getVideoPID(), false, Demuxer::Video);
183
      Source *audio = t->getDemuxer(c->getAudioPID(), false, Demuxer::Audio);
184
      Source *video = t->getDemuxer(c->getVideoPID(), false, Demuxer::Video);
185 185

  
186 186
      // Check to see if perhaps someone else has already
187 187
      // tuned the audio or video channels (this should
......
205 205
}
206 206

  
207 207
void TunerManager::getDemuxers(const std::string &type, const std::string &channel,
208
			       bool convertToPS, DemuxerList &demuxers, int priority) 
208
			       bool convertToPS, SourceList &demuxers, int priority) 
209 209
{
210 210
  TypeTunerMap::iterator li = typeTunerMap.find(type);
211 211
  assert(li != typeTunerMap.end());
......
233 233
      if (!t->getTuneParams()->sameAsExceptPIDs(*c)) 
234 234
	continue;
235 235

  
236
      Demuxer *audio = t->getDemuxer(c->getAudioPID(), convertToPS, Demuxer::Audio);
237
      Demuxer *video = t->getDemuxer(c->getVideoPID(), convertToPS, Demuxer::Video);
236
      Source *audio = t->getDemuxer(c->getAudioPID(), convertToPS, Demuxer::Audio);
237
      Source *video = t->getDemuxer(c->getVideoPID(), convertToPS, Demuxer::Video);
238 238

  
239 239
      // Check to see if perhaps someone else has already
240 240
      // tuned the audio or video channels (this should
src/tunermanager.h
22 22

  
23 23
#include "dvbd.h"
24 24
#include "select.h"
25
#include "source.h"
25 26

  
26 27
#include <list>
27 28
#include <map>
28 29
#include <string>
29 30

  
30 31
class Tuner;
31
class Demuxer;
32 32
class ConfigFile;
33 33

  
34 34
typedef std::list<Tuner *> TunerList;
35
typedef std::list<Demuxer *> DemuxerList;
36 35

  
37 36
class TunerManager : public Selectable {
38 37
public:
......
51 50
	    const std::string &channels );
52 51

  
53 52
  void getDemuxers(const std::string &type, const std::string &channel,
54
		   bool convertToPS, DemuxerList &demuxers, int priority);
53
		   bool convertToPS, SourceList &demuxers, int priority);
55 54

  
56 55
  bool canGetDemuxers(const std::string &type, const std::string &channel,
57 56
		      int priority) const;
src/unixserversocket.cpp
43 43
  addr.sun_family = AF_UNIX;
44 44
  strcpy(addr.sun_path, filename.c_str());
45 45

  
46
  mode_t oldMask = umask(007);
46 47
  while (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
47 48
    if (errno == EADDRINUSE) {
48 49
      // Possibly old socket
......
67 68
	      << strerror(errno) << std::endl;
68 69
    exit(1);
69 70
  }
71

  
72
  umask(oldMask);
70 73
}
71 74

  
72 75
void UnixServerSocket::setNonBlocking()

Also available in: Unified diff