1 /*
2 * libzvbi -- Linux DVB driver interface
3 *
4 * (c) 2004, 2005, 2007 Michael H. Schimek
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA.
20 */
21
22 #ifdef HAVE_CONFIG_H
23 # include "config.h"
24 #endif
25
26 #ifdef ENABLE_DVB
27
28 #include <unistd.h> /* read() */
29 #include <errno.h>
30 #include <sys/select.h>
31 #include <sys/ioctl.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34
35 #ifndef HAVE_S64_U64
36 /* Linux 2.6.x asm/types.h defines __s64 and __u64 only
37 if __GNUC__ is defined. */
38 typedef int64_t __s64;
39 typedef uint64_t __u64;
40 #endif
41 #include "dvb/dmx.h"
42
43 #include "io.h"
44 #include "vbi.h" /* vbi_init_once */
45 #include "dvb_demux.h"
46
47 typedef struct {
48 vbi_capture capture;
49
50 int fd;
51
52 /* FIXME This may be too small? */
53 uint8_t pes_buffer[1024 * 8];
54 const uint8_t * bp;
55 unsigned int b_left;
56
57 vbi_dvb_demux * demux;
58
59 vbi_capture_buffer sliced_buffer;
60 vbi_sliced sliced_data[256];
61 double sample_time;
62 int64_t last_pts;
63
64 vbi_bool do_trace;
65 vbi_bool bug_compatible;
66 } vbi_capture_dvb;
67
68 #define printv(format, args...) \
69 do { \
70 if (dvb->do_trace) { \
71 fprintf (stderr, "libzvbi: " format ,##args); \
72 fflush (stderr); \
73 } \
74 } while (0)
75
76 static __inline__ void
timeval_subtract(struct timeval * delta,const struct timeval * tv1,const struct timeval * tv2)77 timeval_subtract (struct timeval * delta,
78 const struct timeval * tv1,
79 const struct timeval * tv2)
80 {
81 if (tv1->tv_usec < tv2->tv_usec) {
82 delta->tv_sec = tv1->tv_sec - tv2->tv_sec - 1;
83 delta->tv_usec = 1000000 + tv1->tv_usec - tv2->tv_usec;
84 } else {
85 delta->tv_sec = tv1->tv_sec - tv2->tv_sec;
86 delta->tv_usec = tv1->tv_usec - tv2->tv_usec;
87 }
88 }
89
90 static void
timeout_subtract_elapsed(struct timeval * result,const struct timeval * timeout,const struct timeval * now,const struct timeval * start)91 timeout_subtract_elapsed (struct timeval * result,
92 const struct timeval * timeout,
93 const struct timeval * now,
94 const struct timeval * start)
95 {
96 struct timeval elapsed;
97
98 timeval_subtract (&elapsed, now, start);
99
100 if ((elapsed.tv_sec | elapsed.tv_usec) > 0) {
101 timeval_subtract (result, timeout, &elapsed);
102
103 if ((result->tv_sec | result->tv_usec) < 0) {
104 result->tv_sec = 0;
105 result->tv_usec = 0;
106 }
107 } else {
108 *result = *timeout;
109 }
110 }
111
112 static ssize_t
select_read(vbi_capture_dvb * dvb,struct timeval * now,const struct timeval * start,const struct timeval * timeout)113 select_read (vbi_capture_dvb * dvb,
114 struct timeval * now,
115 const struct timeval * start,
116 const struct timeval * timeout)
117 {
118 struct timeval tv;
119 ssize_t actual;
120
121 select_again:
122 /* tv = timeout - (now - start). */
123 timeout_subtract_elapsed (&tv, timeout, now, start);
124
125 /* Shortcut: don't wait if timeout is zero or elapsed. */
126 if ((tv.tv_sec | tv.tv_usec) > 0) {
127 fd_set set;
128 int r;
129
130 select_again_with_timeout:
131 FD_ZERO (&set);
132 FD_SET (dvb->fd, &set);
133
134 /* Note Linux select() may change tv. */
135 r = select (dvb->fd + 1,
136 /* readable */ &set,
137 /* writeable */ NULL,
138 /* in exception */ NULL,
139 &tv);
140
141 switch (r) {
142 case -1: /* error */
143 switch (errno) {
144 case EINTR:
145 gettimeofday (now, /* timezone */ NULL);
146 goto select_again;
147
148 default:
149 return -1; /* error */
150 }
151
152 case 0: /* timeout */
153 if (dvb->bug_compatible)
154 return -1; /* error */
155
156 return 0; /* timeout */
157
158 default:
159 break;
160 }
161 }
162
163 read_again:
164 /* Non-blocking. */
165 actual = read (dvb->fd,
166 dvb->pes_buffer,
167 sizeof (dvb->pes_buffer));
168
169 switch (actual) {
170 case -1: /* error */
171 switch (errno) {
172 case EAGAIN:
173 if (dvb->bug_compatible)
174 return -1; /* error */
175
176 if ((timeout->tv_sec | timeout->tv_usec) <= 0)
177 return 0; /* timeout */
178
179 gettimeofday (now, /* timezone */ NULL);
180 timeout_subtract_elapsed (&tv, timeout, now, start);
181
182 if ((tv.tv_sec | tv.tv_usec) <= 0)
183 return 0; /* timeout */
184
185 goto select_again_with_timeout;
186
187 case EINTR:
188 goto read_again;
189
190 default:
191 return -1; /* error */
192 }
193
194 case 0: /* EOF? */
195 printv ("End of file\n");
196
197 errno = 0;
198
199 return -1; /* error */
200
201 default:
202 break;
203 }
204
205 return actual;
206 }
207
208 static int
dvb_read(vbi_capture * cap,vbi_capture_buffer ** raw,vbi_capture_buffer ** sliced,const struct timeval * timeout)209 dvb_read (vbi_capture * cap,
210 vbi_capture_buffer ** raw,
211 vbi_capture_buffer ** sliced,
212 const struct timeval * timeout)
213 {
214 vbi_capture_dvb *dvb = PARENT (cap, vbi_capture_dvb, capture);
215 vbi_capture_buffer *sb;
216 struct timeval start;
217 struct timeval now;
218 unsigned int n_lines;
219 int64_t pts;
220
221 if (!sliced || !(sb = *sliced)) {
222 sb = &dvb->sliced_buffer;
223 sb->data = dvb->sliced_data;
224 }
225
226 start.tv_sec = 0;
227 start.tv_usec = 0;
228
229 /* When timeout is zero elapsed time doesn't matter. */
230 if ((timeout->tv_sec | timeout->tv_usec) > 0)
231 gettimeofday (&start, /* timezone */ NULL);
232
233 now = start;
234
235 for (;;) {
236 if (0 == dvb->b_left) {
237 ssize_t actual;
238
239 actual = select_read (dvb, &now, &start, timeout);
240 if (actual <= 0)
241 return actual;
242
243 gettimeofday (&now, /* timezone */ NULL);
244
245 /* XXX inaccurate. Should be the time when we
246 received the first byte of the first packet
247 containing data of the returned frame. Or so. */
248 dvb->sample_time = now.tv_sec
249 + now.tv_usec * (1 / 1e6);
250
251 dvb->bp = dvb->pes_buffer;
252 dvb->b_left = actual;
253 }
254
255 /* Demultiplexer coroutine. Returns when one frame is complete
256 or the buffer is empty, advancing bp and b_left. Don't
257 change sb->data in flight. */
258 /* XXX max sliced lines needs an API change. Currently this
259 value is determined by vbi_raw_decoder line count below,
260 256 / 2 because fields don't really apply here and in
261 practice even 32 should be enough. */
262 n_lines = vbi_dvb_demux_cor (dvb->demux,
263 sb->data,
264 /* max sliced lines */ 128,
265 &pts,
266 &dvb->bp,
267 &dvb->b_left);
268 if (n_lines > 0)
269 break;
270
271 if (dvb->bug_compatible) {
272 /* Only one read(), timeout ignored. */
273 return 0; /* timeout */
274 } else {
275 /* Read until EAGAIN, another error or the
276 timeout expires, in this order. */
277 }
278 }
279
280 if (sliced) {
281 sb->size = n_lines * sizeof (vbi_sliced);
282 sb->timestamp = dvb->sample_time;
283
284 /* XXX PTS needs an API change.
285 sb->sample_time = dvb->sample_time;
286 sb->stream_time = pts; (first sliced line) */
287 dvb->last_pts = pts;
288
289 *sliced = sb;
290 }
291
292 if (raw && *raw) {
293 /* Not implemented yet. */
294 sb = *raw;
295 sb->size = 0;
296 }
297
298 return 1; /* success */
299 }
300
301 static vbi_raw_decoder *
dvb_parameters(vbi_capture * cap)302 dvb_parameters (vbi_capture * cap)
303 {
304 /* This is kinda silly but we keep it for compatibility
305 with earlier versions of the library. */
306 static vbi_raw_decoder raw = {
307 .count = { 128, 128 }, /* see dvb_read() */
308 };
309
310 cap = cap; /* unused, no warning please */
311
312 return &raw;
313 }
314
315 static unsigned int
dvb_update_services(vbi_capture * cap,vbi_bool reset,vbi_bool commit,unsigned int services,int strict,char ** errstr)316 dvb_update_services (vbi_capture * cap,
317 vbi_bool reset,
318 vbi_bool commit,
319 unsigned int services,
320 int strict,
321 char ** errstr)
322 {
323 cap = cap; /* unused, no warning please */
324 reset = reset;
325 commit = commit;
326 services = services;
327 strict = strict;
328 errstr = errstr;
329
330 return (VBI_SLICED_TELETEXT_B |
331 VBI_SLICED_VPS |
332 VBI_SLICED_CAPTION_625 |
333 VBI_SLICED_WSS_625);
334 }
335
336 static void
dvb_flush(vbi_capture * cap)337 dvb_flush (vbi_capture * cap)
338 {
339 vbi_capture_dvb *dvb = PARENT (cap, vbi_capture_dvb, capture);
340
341 vbi_dvb_demux_reset (dvb->demux);
342
343 dvb->bp = dvb->pes_buffer;
344 dvb->b_left = 0;
345 }
346
347 static VBI_CAPTURE_FD_FLAGS
dvb_get_fd_flags(vbi_capture * cap)348 dvb_get_fd_flags (vbi_capture * cap)
349 {
350 cap = cap; /* unused, no warning please */
351
352 return (VBI_FD_HAS_SELECT |
353 VBI_FD_IS_DEVICE);
354 }
355
356 static int
dvb_get_fd(vbi_capture * cap)357 dvb_get_fd (vbi_capture * cap)
358 {
359 vbi_capture_dvb *dvb = PARENT (cap, vbi_capture_dvb, capture);
360
361 return dvb->fd;
362 }
363
364 int64_t
vbi_capture_dvb_last_pts(const vbi_capture * cap)365 vbi_capture_dvb_last_pts (const vbi_capture * cap)
366 {
367 const vbi_capture_dvb *dvb =
368 CONST_PARENT (cap, vbi_capture_dvb, capture);
369
370 return dvb->last_pts;
371 }
372
373 int
vbi_capture_dvb_filter(vbi_capture * cap,int pid)374 vbi_capture_dvb_filter (vbi_capture * cap,
375 int pid)
376 {
377 vbi_capture_dvb *dvb = PARENT (cap, vbi_capture_dvb, capture);
378 struct dmx_pes_filter_params filter;
379
380 CLEAR (filter);
381
382 filter.pid = pid;
383 filter.input = DMX_IN_FRONTEND;
384 filter.output = DMX_OUT_TAP;
385 filter.pes_type = DMX_PES_OTHER;
386 filter.flags = DMX_IMMEDIATE_START;
387
388 if (-1 == ioctl (dvb->fd, DMX_SET_PES_FILTER, &filter))
389 return -1;
390
391 printv ("Capturing PES packets with PID %d\n", pid);
392
393 return 0;
394 }
395
396 static void
dvb_delete(vbi_capture * cap)397 dvb_delete (vbi_capture * cap)
398 {
399 vbi_capture_dvb *dvb;
400
401 if (NULL == cap)
402 return;
403
404 dvb = PARENT (cap, vbi_capture_dvb, capture);
405
406 if (-1 != dvb->fd) {
407 /* Error ignored. */
408 device_close (dvb->capture.sys_log_fp, dvb->fd);
409 }
410
411 vbi_dvb_demux_delete (dvb->demux);
412
413 /* Make unusable. */
414 CLEAR (*dvb);
415
416 free (dvb);
417 }
418
419 static vbi_bool
open_device(vbi_capture_dvb * dvb,const char * device_name,char ** errstr)420 open_device (vbi_capture_dvb * dvb,
421 const char * device_name,
422 char ** errstr)
423 {
424 int saved_errno;
425 struct stat st;
426
427 if (-1 == stat (device_name, &st))
428 goto io_error;
429
430 if (!S_ISCHR (st.st_mode)) {
431 asprintf (errstr, _("%s is not a device."),
432 device_name);
433 saved_errno = 0;
434 goto failed;
435 }
436
437 /* XXX Can we check if this is really a DVB demux device? */
438
439 dvb->fd = device_open (dvb->capture.sys_log_fp,
440 device_name,
441 O_RDONLY | O_NONBLOCK,
442 /* mode */ 0);
443 if (-1 == dvb->fd)
444 goto io_error;
445
446 return TRUE;
447
448 io_error:
449 saved_errno = errno;
450
451 asprintf (errstr, _("Cannot open '%s': %s."),
452 device_name, strerror (saved_errno));
453
454 /* fall through */
455
456 failed:
457 dvb->fd = -1;
458
459 errno = saved_errno;
460
461 return FALSE;
462 }
463
464 vbi_capture *
vbi_capture_dvb_new2(const char * device_name,unsigned int pid,char ** errstr,vbi_bool trace)465 vbi_capture_dvb_new2 (const char * device_name,
466 unsigned int pid,
467 char ** errstr,
468 vbi_bool trace)
469 {
470 char *error = NULL;
471 int saved_errno;
472 vbi_capture_dvb *dvb;
473
474 pthread_once (&vbi_init_once, vbi_init);
475
476 if (NULL == errstr)
477 errstr = &error;
478 *errstr = NULL;
479
480 dvb = vbi_malloc (sizeof (*dvb));
481 if (NULL == dvb)
482 goto no_memory;
483
484 CLEAR (*dvb);
485
486 dvb->capture.read = dvb_read;
487 dvb->capture.sampling_point = NULL;
488 dvb->capture.debug = NULL;
489 dvb->capture.parameters = dvb_parameters;
490 dvb->capture.update_services = dvb_update_services;
491 dvb->capture.get_scanning = NULL;
492 dvb->capture.flush = dvb_flush;
493 dvb->capture.get_fd = dvb_get_fd;
494 dvb->capture.get_fd_flags = dvb_get_fd_flags;
495 dvb->capture.set_video_path = NULL;
496 dvb->capture._delete = dvb_delete;
497
498 dvb->fd = -1;
499
500 dvb->do_trace = trace;
501
502 dvb->demux = vbi_dvb_pes_demux_new (/* callback */ NULL,
503 /* user_data */ NULL);
504 if (NULL == dvb->demux)
505 goto no_memory;
506
507 if (!open_device (dvb, device_name, errstr)) {
508 saved_errno = errno;
509 goto failed;
510 }
511
512 printv ("Opened device %s\n", device_name);
513
514 if (0 != pid) {
515 if (-1 == vbi_capture_dvb_filter (&dvb->capture, pid)) {
516 saved_errno = errno;
517 asprintf (errstr, _("DMX_SET_PES_FILTER failed: %s."),
518 strerror (errno));
519 goto failed;
520 }
521 }
522
523 dvb_flush (&dvb->capture);
524
525 if (errstr == &error) {
526 free (error);
527 error = NULL;
528 }
529
530 return &dvb->capture;
531
532 no_memory:
533 asprintf (errstr, _("Virtual memory exhausted."));
534
535 saved_errno = ENOMEM;
536
537 /* fall through */
538
539 failed:
540 if (NULL != dvb) {
541 dvb_delete (&dvb->capture);
542 dvb = NULL;
543 }
544
545 if (errstr == &error) {
546 free (error);
547 error = NULL;
548 }
549
550 errno = saved_errno;
551
552 return NULL;
553 }
554
555 vbi_capture *
vbi_capture_dvb_new(char * dev,int scanning,unsigned int * services,int strict,char ** errstr,vbi_bool trace)556 vbi_capture_dvb_new (char * dev,
557 int scanning,
558 unsigned int * services,
559 int strict,
560 char ** errstr,
561 vbi_bool trace)
562 {
563 char *error = NULL;
564 vbi_capture *cap;
565 vbi_capture_dvb *dvb;
566
567 scanning = scanning; /* unused, no warning please */
568 services = services;
569 strict = strict;
570
571 if (NULL == errstr)
572 errstr = &error;
573 *errstr = NULL;
574
575 cap = vbi_capture_dvb_new2 (dev, /* pid */ 0, errstr, trace);
576 if (NULL == cap)
577 goto failed;
578
579 dvb = PARENT (cap, vbi_capture_dvb, capture);
580
581 dvb->bug_compatible = TRUE;
582
583 failed:
584 if (errstr == &error) {
585 free (error);
586 error = NULL;
587 }
588
589 return cap;
590 }
591
592 #else /* !ENABLE_DVB */
593
594 #include "io.h"
595 #include "vbi.h"
596
597 /**
598 * @param cap Initialized DVB vbi_capture context.
599 *
600 * Returns the presentation time stamp associated with the data
601 * last read from the context. The PTS refers to the first sliced
602 * VBI line, not the last packet containing data of that frame.
603 *
604 * Note timestamps returned by vbi_capture read functions contain
605 * the system time (gettimeofday()) when the packet containing the
606 * first sliced line was captured, not the PTS.
607 *
608 * @returns
609 * Presentation time stamp (33 bits).
610 *
611 * @bug
612 * The read functions should return the PTS along with
613 * the capture timestamp.
614 *
615 * @since 0.2.13
616 */
617 int64_t
vbi_capture_dvb_last_pts(const vbi_capture * cap)618 vbi_capture_dvb_last_pts (const vbi_capture * cap)
619 {
620 cap = cap; /* unused, no warning please */
621
622 return 0;
623 }
624
625 /**
626 * @param cap Initialized DVB vbi_capture context.
627 * @param pid Filter out a stream with this PID.
628 *
629 * Programs the DVB device transport stream demultiplexer on the
630 * DVB capture device to filter out packets with this PID.
631 *
632 * @returns
633 * -1 on failure, 0 on success.
634 */
635 int
vbi_capture_dvb_filter(vbi_capture * cap,int pid)636 vbi_capture_dvb_filter (vbi_capture * cap,
637 int pid)
638 {
639 cap = cap; /* unused, no warning please */
640 pid = pid;
641
642 return -1;
643 }
644
645 /**
646 * @param device_name Name of the DVB device to open.
647 * @param pid Filter out a stream with this PID. You can pass 0 here
648 * and set or change the PID later with vbi_capture_dvb_filter().
649 * @param errstr If not @c NULL the function stores a pointer to an error
650 * description here. You must free() this string when no longer needed.
651 * @param trace If @c TRUE print progress and warning messages on stderr.
652 *
653 * Initializes a vbi_capture context reading from a Linux DVB device.
654 *
655 * @returns
656 * Initialized vbi_capture context, @c NULL on failure.
657 *
658 * @since 0.2.13
659 */
660 vbi_capture *
vbi_capture_dvb_new2(const char * device_name,unsigned int pid,char ** errstr,vbi_bool trace)661 vbi_capture_dvb_new2 (const char * device_name,
662 unsigned int pid,
663 char ** errstr,
664 vbi_bool trace)
665 {
666 device_name = device_name; /* unused, no warning please */
667 pid = pid;
668 trace = trace;
669
670 if (NULL != errstr)
671 asprintf (errstr, _("DVB interface not compiled."));
672
673 return NULL;
674 }
675
676 /**
677 * @param dev Name of the DVB device to open.
678 * @param scanning Ignored.
679 * @param services Ignored.
680 * @param strict Ignored.
681 * @param errstr If not @c NULL the function stores a pointer to an error
682 * description here. You must free() this string when no longer needed.
683 * @param trace If @c TRUE print progress and warning messages on stderr.
684 *
685 * @deprecated
686 * This function is deprecated. Use vbi_capture_dvb_new2() instead.
687 *
688 * Initializes a vbi_capture context reading from a Linux DVB device.
689 * You must call vbi_capture_dvb_filter() before you can read.
690 *
691 * @returns
692 * Initialized vbi_capture context, @c NULL on failure.
693 *
694 * @bug
695 * This function ignores the scanning, services and strict parameter.
696 * The read method of this DVB capture context returns -1 on timeout
697 * instead of 0. It returns 0 when a single read() does not complete
698 * a frame, regardless if the timeout expired. (Decoding resumes with
699 * the next call.) Older versions pass select or read EINTR errors
700 * back to the caller. They may return partial frames when VBI data
701 * of one frame is distributed across multiple PES packets. They will
702 * not return VPS, CC, or WSS data and can malfunction or segfault
703 * given unusual PES streams. On error and select timeout older versions
704 * invariably print a warning on stderr.
705 */
706 vbi_capture *
vbi_capture_dvb_new(char * dev,int scanning,unsigned int * services,int strict,char ** errstr,vbi_bool trace)707 vbi_capture_dvb_new (char * dev,
708 int scanning,
709 unsigned int * services,
710 int strict,
711 char ** errstr,
712 vbi_bool trace)
713 {
714 dev = dev; /* unused, no warning please */
715 scanning = scanning;
716 services = services;
717 strict = strict;
718 trace = trace;
719
720 if (NULL != errstr)
721 asprintf (errstr, _("DVB interface not compiled."));
722
723 return NULL;
724 }
725
726 #endif /* !ENABLE_DVB */
727
728 /*
729 Local variables:
730 c-set-style: K&R
731 c-basic-offset: 8
732 End:
733 */
734