1 /*
2 gnutv utility
3
4 Copyright (C) 2004, 2005 Manu Abraham <abraham.manu@gmail.com>
5 Copyright (C) 2006 Andrew de Quincey (adq_dvb@lidskialf.net)
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #define _FILE_OFFSET_BITS 64
24 #define _LARGEFILE_SOURCE 1
25 #define _LARGEFILE64_SOURCE 1
26
27 #include <stdio.h>
28 #include <unistd.h>
29 #include <limits.h>
30 #include <string.h>
31 #include <fcntl.h>
32 #include <signal.h>
33 #include <pthread.h>
34 #include <errno.h>
35 #include <sys/poll.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <netdb.h>
40 #include <arpa/inet.h>
41 #include <libdvbapi/dvbdemux.h>
42 #include <libdvbapi/dvbaudio.h>
43 #include <libucsi/mpeg/section.h>
44 #include "gnutv.h"
45 #include "gnutv_dvb.h"
46 #include "gnutv_ca.h"
47 #include "gnutv_data.h"
48
49 static void *fileoutputthread_func(void* arg);
50 static void *udpoutputthread_func(void* arg);
51
52 static int gnutv_data_create_decoder_filter(int adapter, int demux, uint16_t pid, int pestype);
53 static int gnutv_data_create_dvr_filter(int adapter, int demux, uint16_t pid);
54
55 static void gnutv_data_decoder_pmt(struct mpeg_pmt_section *pmt);
56 static void gnutv_data_dvr_pmt(struct mpeg_pmt_section *pmt);
57
58 static void gnutv_data_append_pid_fd(int pid, int fd);
59 static void gnutv_data_free_pid_fds(void);
60
61 static pthread_t outputthread;
62 static int outfd = -1;
63 static int dvrfd = -1;
64 static int pat_fd_dvrout = -1;
65 static int pmt_fd_dvrout = -1;
66 static int outputthread_shutdown = 0;
67
68 static int usertp = 0;
69 static int adapter_id = -1;
70 static int demux_id = -1;
71 static int output_type = 0;
72 static struct addrinfo *outaddrs = NULL;
73
74 struct pid_fd {
75 int pid;
76 int fd;
77 };
78 static struct pid_fd *pid_fds = NULL;
79 static int pid_fds_count = 0;
80
gnutv_data_start(int _output_type,int ffaudiofd,int _adapter_id,int _demux_id,int buffer_size,char * outfile,char * outif,struct addrinfo * _outaddrs,int _usertp)81 void gnutv_data_start(int _output_type,
82 int ffaudiofd, int _adapter_id, int _demux_id, int buffer_size,
83 char *outfile,
84 char* outif, struct addrinfo *_outaddrs, int _usertp)
85 {
86 usertp = _usertp;
87 demux_id = _demux_id;
88 adapter_id = _adapter_id;
89 output_type = _output_type;
90
91 // setup output
92 switch(output_type) {
93 case OUTPUT_TYPE_DECODER:
94 case OUTPUT_TYPE_DECODER_ABYPASS:
95 dvbaudio_set_bypass(ffaudiofd, (output_type == OUTPUT_TYPE_DECODER_ABYPASS) ? 1 : 0);
96 close(ffaudiofd);
97 break;
98
99 case OUTPUT_TYPE_STDOUT:
100 case OUTPUT_TYPE_FILE:
101 if (output_type == OUTPUT_TYPE_FILE) {
102 // open output file
103 outfd = open(outfile, O_WRONLY|O_CREAT|0|O_TRUNC, 0644);
104 if (outfd < 0) {
105 fprintf(stderr, "Failed to open output file\n");
106 exit(1);
107 }
108 } else {
109 outfd = STDOUT_FILENO;
110 }
111
112 // open dvr device
113 dvrfd = dvbdemux_open_dvr(adapter_id, 0, 1, 0);
114 if (dvrfd < 0) {
115 fprintf(stderr, "Failed to open DVR device\n");
116 exit(1);
117 }
118
119 // optionally set dvr buffer size
120 if (buffer_size > 0) {
121 if (dvbdemux_set_buffer(dvrfd, buffer_size) != 0) {
122 fprintf(stderr, "Failed to set DVR buffer size\n");
123 exit(1);
124 }
125 }
126
127 pthread_create(&outputthread, NULL, fileoutputthread_func, NULL);
128 break;
129
130 case OUTPUT_TYPE_UDP:
131 outaddrs = _outaddrs;
132
133 // open output socket
134 outfd = socket(outaddrs->ai_family, outaddrs->ai_socktype, outaddrs->ai_protocol);
135 if (outfd < 0) {
136 fprintf(stderr, "Failed to open output socket\n");
137 exit(1);
138 }
139
140 // bind to local interface if requested
141 if (outif != NULL) {
142 if (1 /*setsockopt(outfd, SOL_SOCKET, SO_BINDTODEVICE, outif, strlen(outif)) < 0*/) {
143 fprintf(stderr, "SO_BINDTODEVICE not supported on FreeBSD\n");
144 fprintf(stderr, "Failed to bind to interface %s\n", outif);
145 exit(1);
146 }
147 }
148
149 // open dvr device
150 dvrfd = dvbdemux_open_dvr(adapter_id, 0, 1, 0);
151 if (dvrfd < 0) {
152 fprintf(stderr, "Failed to open DVR device\n");
153 exit(1);
154 }
155
156 // optionally set dvr buffer size
157 if (buffer_size > 0) {
158 if (dvbdemux_set_buffer(dvrfd, buffer_size) != 0) {
159 fprintf(stderr, "Failed to set DVR buffer size\n");
160 exit(1);
161 }
162 }
163
164 pthread_create(&outputthread, NULL, udpoutputthread_func, NULL);
165 break;
166 }
167
168 // output PAT to DVR if requested
169 switch(output_type) {
170 case OUTPUT_TYPE_DVR:
171 case OUTPUT_TYPE_FILE:
172 case OUTPUT_TYPE_STDOUT:
173 case OUTPUT_TYPE_UDP:
174 pat_fd_dvrout = gnutv_data_create_dvr_filter(adapter_id, demux_id, TRANSPORT_PAT_PID);
175 }
176 }
177
gnutv_data_stop()178 void gnutv_data_stop()
179 {
180 // shutdown output thread if necessary
181 if (dvrfd != -1) {
182 outputthread_shutdown = 1;
183 pthread_join(outputthread, NULL);
184 }
185 gnutv_data_free_pid_fds();
186 if (pat_fd_dvrout != -1)
187 close(pat_fd_dvrout);
188 if (pmt_fd_dvrout != -1)
189 close(pmt_fd_dvrout);
190 if (outaddrs)
191 freeaddrinfo(outaddrs);
192 }
193
gnutv_data_new_pat(int pmt_pid)194 void gnutv_data_new_pat(int pmt_pid)
195 {
196 // output PMT to DVR if requested
197 switch(output_type) {
198 case OUTPUT_TYPE_DVR:
199 case OUTPUT_TYPE_FILE:
200 case OUTPUT_TYPE_STDOUT:
201 case OUTPUT_TYPE_UDP:
202 if (pmt_fd_dvrout != -1)
203 close(pmt_fd_dvrout);
204 pmt_fd_dvrout = gnutv_data_create_dvr_filter(adapter_id, demux_id, pmt_pid);
205 }
206 }
207
gnutv_data_new_pmt(struct mpeg_pmt_section * pmt)208 int gnutv_data_new_pmt(struct mpeg_pmt_section *pmt)
209 {
210 // close all old PID FDs
211 gnutv_data_free_pid_fds();
212
213 // deal with the PMT appropriately
214 switch(output_type) {
215 case OUTPUT_TYPE_DECODER:
216 case OUTPUT_TYPE_DECODER_ABYPASS:
217 gnutv_data_decoder_pmt(pmt);
218 break;
219
220 case OUTPUT_TYPE_DVR:
221 case OUTPUT_TYPE_FILE:
222 case OUTPUT_TYPE_STDOUT:
223 case OUTPUT_TYPE_UDP:
224 gnutv_data_dvr_pmt(pmt);
225 break;
226 }
227
228 return 1;
229 }
230
fileoutputthread_func(void * arg)231 static void *fileoutputthread_func(void* arg)
232 {
233 (void)arg;
234 uint8_t buf[4096];
235 struct pollfd pollfd;
236 int written;
237
238 pollfd.fd = dvrfd;
239 pollfd.events = POLLIN|POLLPRI|POLLERR;
240
241 while(!outputthread_shutdown) {
242 if (poll(&pollfd, 1, 1000) == -1) {
243 if (errno == EINTR)
244 continue;
245 fprintf(stderr, "DVR device poll failure\n");
246 return 0;
247 }
248
249 if (pollfd.revents == 0)
250 continue;
251
252 int size = read(dvrfd, buf, sizeof(buf));
253 if (size < 0) {
254 if (errno == EINTR)
255 continue;
256
257 if (errno == EOVERFLOW) {
258 // The error flag has been cleared, next read should succeed.
259 fprintf(stderr, "DVR overflow\n");
260 continue;
261 }
262
263 fprintf(stderr, "DVR device read failure\n");
264 return 0;
265 }
266
267 written = 0;
268 while(written < size) {
269 int tmp = write(outfd, buf + written, size - written);
270 if (tmp == -1) {
271 if (errno != EINTR) {
272 fprintf(stderr, "Write error: %m\n");
273 break;
274 }
275 } else {
276 written += tmp;
277 }
278 }
279 }
280
281 return 0;
282 }
283
284 #define TS_PAYLOAD_SIZE (188*7)
285
udpoutputthread_func(void * arg)286 static void *udpoutputthread_func(void* arg)
287 {
288 (void)arg;
289 uint8_t buf[12 + TS_PAYLOAD_SIZE];
290 struct pollfd pollfd;
291 int bufsize = 0;
292 int bufbase = 0;
293 int readsize;
294 uint16_t rtpseq = 0;
295
296 pollfd.fd = dvrfd;
297 pollfd.events = POLLIN|POLLPRI|POLLERR;
298
299 if (usertp) {
300 srandom(time(NULL));
301 int ssrc = random();
302 rtpseq = random();
303 buf[0x0] = 0x80;
304 buf[0x1] = 0x21;
305 buf[0x4] = 0x00; // }
306 buf[0x5] = 0x00; // } FIXME: should really be a valid stamp
307 buf[0x6] = 0x00; // }
308 buf[0x7] = 0x00; // }
309 buf[0x8] = ssrc >> 24;
310 buf[0x9] = ssrc >> 16;
311 buf[0xa] = ssrc >> 8;
312 buf[0xb] = ssrc;
313 bufbase = 12;
314 }
315
316 while(!outputthread_shutdown) {
317 if (poll(&pollfd, 1, 1000) != 1)
318 continue;
319 if (pollfd.revents & POLLERR) {
320 if (errno == EINTR)
321 continue;
322 fprintf(stderr, "DVR device read failure\n");
323 return 0;
324 }
325
326 readsize = TS_PAYLOAD_SIZE - bufsize;
327 readsize = read(dvrfd, buf + bufbase + bufsize, readsize);
328 if (readsize < 0) {
329 if (errno == EINTR)
330 continue;
331 fprintf(stderr, "DVR device read failure\n");
332 return 0;
333 }
334 bufsize += readsize;
335
336 if (bufsize == TS_PAYLOAD_SIZE) {
337 if (usertp) {
338 buf[2] = rtpseq >> 8;
339 buf[3] = rtpseq;
340 }
341 if (sendto(outfd, buf, bufbase + bufsize, 0, outaddrs->ai_addr, outaddrs->ai_addrlen) < 0) {
342 if (errno != EINTR) {
343 fprintf(stderr, "Socket send failure: %m\n");
344 return 0;
345 }
346 }
347 rtpseq++;
348 bufsize = 0;
349 }
350 }
351
352 if (bufsize) {
353 if (usertp) {
354 buf[2] = rtpseq >> 8;
355 buf[3] = rtpseq;
356 }
357 if (sendto(outfd, buf, bufbase + bufsize, 0, outaddrs->ai_addr, outaddrs->ai_addrlen) < 0) {
358 if (errno != EINTR)
359 fprintf(stderr, "Socket send failure: %m\n");
360 }
361 }
362
363 return 0;
364 }
365
gnutv_data_create_decoder_filter(int adapter,int demux,uint16_t pid,int pestype)366 static int gnutv_data_create_decoder_filter(int adapter, int demux, uint16_t pid, int pestype)
367 {
368 int demux_fd = -1;
369
370 // open the demuxer
371 if ((demux_fd = dvbdemux_open_demux(adapter, demux, 0)) < 0) {
372 return -1;
373 }
374
375 // create a section filter
376 if (dvbdemux_set_pes_filter(demux_fd, pid, DVBDEMUX_INPUT_FRONTEND, DVBDEMUX_OUTPUT_DECODER, pestype, 1)) {
377 close(demux_fd);
378 return -1;
379 }
380
381 // done
382 return demux_fd;
383 }
384
gnutv_data_create_dvr_filter(int adapter,int demux,uint16_t pid)385 static int gnutv_data_create_dvr_filter(int adapter, int demux, uint16_t pid)
386 {
387 int demux_fd = -1;
388
389 // open the demuxer
390 if ((demux_fd = dvbdemux_open_demux(adapter, demux, 0)) < 0) {
391 return -1;
392 }
393
394 // create a section filter
395 if (dvbdemux_set_pid_filter(demux_fd, pid, DVBDEMUX_INPUT_FRONTEND, DVBDEMUX_OUTPUT_DVR, 1)) {
396 close(demux_fd);
397 return -1;
398 }
399
400 // done
401 return demux_fd;
402 }
403
gnutv_data_decoder_pmt(struct mpeg_pmt_section * pmt)404 static void gnutv_data_decoder_pmt(struct mpeg_pmt_section *pmt)
405 {
406 int audio_pid = -1;
407 int video_pid = -1;
408 struct mpeg_pmt_stream *cur_stream;
409 mpeg_pmt_section_streams_for_each(pmt, cur_stream) {
410 switch(cur_stream->stream_type) {
411 case 1:
412 case 2: // video
413 video_pid = cur_stream->pid;
414 break;
415
416 case 3:
417 case 4: // audio
418 audio_pid = cur_stream->pid;
419 break;
420 }
421 }
422
423 if (audio_pid != -1) {
424 int fd = gnutv_data_create_decoder_filter(adapter_id, demux_id, audio_pid, DVBDEMUX_PESTYPE_AUDIO);
425 if (fd < 0) {
426 fprintf(stderr, "Unable to create dvr filter for PID %i\n", audio_pid);
427 } else {
428 gnutv_data_append_pid_fd(audio_pid, fd);
429 }
430 }
431 if (video_pid != -1) {
432 int fd = gnutv_data_create_decoder_filter(adapter_id, demux_id, video_pid, DVBDEMUX_PESTYPE_VIDEO);
433 if (fd < 0) {
434 fprintf(stderr, "Unable to create dvr filter for PID %i\n", video_pid);
435 } else {
436 gnutv_data_append_pid_fd(video_pid, fd);
437 }
438 }
439 int fd = gnutv_data_create_decoder_filter(adapter_id, demux_id, pmt->pcr_pid, DVBDEMUX_PESTYPE_PCR);
440 if (fd < 0) {
441 fprintf(stderr, "Unable to create dvr filter for PID %i\n", pmt->pcr_pid);
442 } else {
443 gnutv_data_append_pid_fd(pmt->pcr_pid, fd);
444 }
445 }
446
gnutv_data_dvr_pmt(struct mpeg_pmt_section * pmt)447 static void gnutv_data_dvr_pmt(struct mpeg_pmt_section *pmt)
448 {
449 struct mpeg_pmt_stream *cur_stream;
450 mpeg_pmt_section_streams_for_each(pmt, cur_stream) {
451 int fd = gnutv_data_create_dvr_filter(adapter_id, demux_id, cur_stream->pid);
452 if (fd < 0) {
453 fprintf(stderr, "Unable to create dvr filter for PID %i\n", cur_stream->pid);
454 } else {
455 gnutv_data_append_pid_fd(cur_stream->pid, fd);
456 }
457 }
458 }
459
gnutv_data_append_pid_fd(int pid,int fd)460 static void gnutv_data_append_pid_fd(int pid, int fd)
461 {
462 struct pid_fd *tmp;
463 if ((tmp = realloc(pid_fds, (pid_fds_count +1) * sizeof(struct pid_fd))) == NULL) {
464 fprintf(stderr, "Out of memory when adding a new pid_fd\n");
465 exit(1);
466 }
467 tmp[pid_fds_count].pid = pid;
468 tmp[pid_fds_count].fd = fd;
469 pid_fds_count++;
470 pid_fds = tmp;
471 }
472
gnutv_data_free_pid_fds()473 static void gnutv_data_free_pid_fds()
474 {
475 if (pid_fds_count) {
476 int i;
477 for(i=0; i< pid_fds_count; i++) {
478 close(pid_fds[i].fd);
479 }
480 }
481 if (pid_fds)
482 free(pid_fds);
483
484 pid_fds_count = 0;
485 pid_fds = NULL;
486 }
487