| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /* test_dvr.c - Test recording a TS from the dvr device.
- * usage: test_dvr PID [more PIDs...]
- *
- * Copyright (C) 2003 convergence GmbH
- * Johannes Stezenbach <js@convergence.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public License
- * as published by the Free Software Foundation; either version 2.1
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- //hm, I haven't tested writing large files yet... maybe it works
- #define _LARGEFILE64_SOURCE
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <errno.h>
- #include <inttypes.h>
- #include <linux/dvb/dmx.h>
- static unsigned long BUF_SIZE = 64 * 1024;
- static unsigned long long total_bytes;
- static void usage(void)
- {
- fprintf(stderr, "usage: test_dvb file PID [more PIDs...]\n"
- " record a partial TS stream consisting of TS packets\n"
- " with the selected PIDs to the given file.\n"
- " Use PID 0x2000 to record the full TS stream (if\n"
- " the hardware supports it).\n"
- " The demux and dvr devices used can be changed by setting\n"
- " the environment variables DEMUX and DVR.\n"
- " You can override the input buffer size by setting BUF_SIZE to\n"
- " the number of bytes wanted.\n"
- " Note: There is no output buffering, so writing to stdout is\n"
- " not really supported, but you can try something like:\n"
- " BUF_SIZE=188 ./test_dvr /dev/stdout 0 2>/dev/null | xxd\n"
- " ./test_dvr /dev/stdout 0x100 0x110 2>/dev/null| xine stdin://mpeg2\n"
- "\n");
- exit(1);
- }
- static void process_data(int dvrfd, int tsfd)
- {
- uint8_t buf[BUF_SIZE];
- int bytes, b2;
- bytes = read(dvrfd, buf, sizeof(buf));
- if (bytes < 0) {
- perror("read");
- if (errno == EOVERFLOW)
- return;
- fprintf(stderr, "exiting due to read() error\n");
- exit(1);
- }
- total_bytes += bytes;
- b2 = write(tsfd, buf, bytes);
- if (b2 == -1) {
- perror("write");
- exit(1);
- } else if (b2 < bytes)
- fprintf(stderr, "warning: read %d, but wrote only %d bytes\n", bytes, b2);
- else
- fprintf(stderr, "got %d bytes (%llu total)\n", bytes, total_bytes);
- }
- static int add_filter(unsigned int pid, const char* dmxdev)
- {
- int fd;
- struct dmx_pes_filter_params f;
- fd = open(dmxdev, O_RDONLY);
- if (fd == -1) {
- perror("cannot open demux device");
- return 1;
- }
- memset(&f, 0, sizeof(f));
- f.pid = (uint16_t) pid;
- f.input = DMX_IN_FRONTEND;
- f.output = DMX_OUT_TS_TAP;
- f.pes_type = DMX_PES_OTHER;
- f.flags = DMX_IMMEDIATE_START;
- if (ioctl(fd, DMX_SET_PES_FILTER, &f) == -1) {
- perror("DMX_SET_PES_FILTER");
- return 1;
- }
- fprintf(stderr, "set filter for PID 0x%04x on fd %d\n", pid, fd);
- //FIXME: don't leak the fd
- return 0;
- }
- int main(int argc, char *argv[])
- {
- int dvrfd, tsfd;
- unsigned int pid;
- char *dmxdev = "/dev/dvb/adapter0/demux0";
- char *dvrdev = "/dev/dvb/adapter0/dvr0";
- int i;
- char *chkp;
- if (argc < 3)
- usage();
- if (getenv("DEMUX"))
- dmxdev = getenv("DEMUX");
- if (getenv("DVR"))
- dvrdev = getenv("DVR");
- fprintf(stderr, "using '%s' and '%s'\n"
- "writing to '%s'\n", dmxdev, dvrdev, argv[1]);
- tsfd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0664);
- if (tsfd == -1) {
- perror("cannot write output file");
- return 1;
- }
- dvrfd = open(dvrdev, O_RDONLY);
- if (dvrfd == -1) {
- perror("cannot open dvr device");
- return 1;
- }
- if (getenv("BUF_SIZE") && ((BUF_SIZE = strtoul(getenv("BUF_SIZE"), NULL, 0)) > 0))
- fprintf(stderr, "BUF_SIZE = %lu\n", BUF_SIZE);
- for (i = 2; i < argc; i++) {
- pid = strtoul(argv[i], &chkp, 0);
- if (pid > 0x2000 || chkp == argv[i])
- usage();
- fprintf(stderr, "adding filter for PID 0x%04x\n", pid);
- //FIXME: stop & close filters later...
- if (add_filter(pid, dmxdev) != 0)
- return 1;
- }
- for (;;) {
- process_data(dvrfd, tsfd);
- }
- close(dvrfd);
- return 0;
- }
|