diff options
Diffstat (limited to 'util/szap')
-rw-r--r-- | util/szap/Makefile | 2 | ||||
-rw-r--r-- | util/szap/azap.c | 27 | ||||
-rw-r--r-- | util/szap/czap.c | 91 | ||||
-rw-r--r-- | util/szap/szap.c | 97 | ||||
-rw-r--r-- | util/szap/tzap.c | 73 | ||||
-rw-r--r-- | util/szap/util.c | 126 | ||||
-rw-r--r-- | util/szap/util.h | 24 |
7 files changed, 253 insertions, 187 deletions
diff --git a/util/szap/Makefile b/util/szap/Makefile index b341c74..48d7149 100644 --- a/util/szap/Makefile +++ b/util/szap/Makefile @@ -1,6 +1,6 @@ # Makefile for linuxtv.org dvb-apps/util/szap -objects = lnb.o +objects = lnb.o util.o binaries = azap \ czap \ diff --git a/util/szap/azap.c b/util/szap/azap.c index 5bd7f33..93addf8 100644 --- a/util/szap/azap.c +++ b/util/szap/azap.c @@ -13,6 +13,8 @@ #include <linux/dvb/frontend.h> #include <linux/dvb/dmx.h> +#include "util.h" + static char FRONTEND_DEV [80]; static char DEMUX_DEV [80]; @@ -209,31 +211,6 @@ int parse(const char *fname, const char *channel, static -int set_pesfilter (int fd, int pid, dmx_pes_type_t type, int dvr) -{ - struct dmx_pes_filter_params pesfilter; - - if (pid <= 0 || pid >= 0x1fff) - return 0; - - pesfilter.pid = pid; - pesfilter.input = DMX_IN_FRONTEND; - pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER; - pesfilter.pes_type = type; - pesfilter.flags = DMX_IMMEDIATE_START; - - if (ioctl(fd, DMX_SET_PES_FILTER, &pesfilter) < 0) { - PERROR ("ioctl(DMX_SET_PES_FILTER) for %s PID failed", - type == DMX_PES_AUDIO ? "Audio" : - type == DMX_PES_VIDEO ? "Video" : "??"); - return -1; - } - - return 0; -} - - -static int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend) { struct dvb_frontend_info fe_info; diff --git a/util/szap/czap.c b/util/szap/czap.c index 469df56..e04ed4b 100644 --- a/util/szap/czap.c +++ b/util/szap/czap.c @@ -13,6 +13,8 @@ #include <linux/dvb/frontend.h> #include <linux/dvb/dmx.h> +#include "util.h" + static char FRONTEND_DEV [80]; static char DEMUX_DEV [80]; @@ -118,7 +120,7 @@ char *find_channel(FILE *f, int list_channels, int *chan_no, const char *channel int parse(const char *fname, int list_channels, int chan_no, const char *channel, - struct dvb_frontend_parameters *frontend, int *vpid, int *apid) + struct dvb_frontend_parameters *frontend, int *vpid, int *apid, int *sid) { FILE *f; char *chan; @@ -141,10 +143,10 @@ int parse(const char *fname, int list_channels, int chan_no, const char *channel } printf("%3d %s", chan_no, chan); - if ((sscanf(chan, "%a[^:]:%d:%a[^:]:%d:%a[^:]:%a[^:]:%d:%d\n", + if ((sscanf(chan, "%m[^:]:%d:%m[^:]:%d:%m[^:]:%m[^:]:%d:%d:%d\n", &name, &frontend->frequency, &inv, &frontend->u.qam.symbol_rate, - &fec, &mod, vpid, apid) != 8) + &fec, &mod, vpid, apid, sid) != 9) || !name || !inv || !fec | !mod) { ERROR("cannot parse service data"); return -3; @@ -165,10 +167,10 @@ int parse(const char *fname, int list_channels, int chan_no, const char *channel ERROR("modulation field syntax '%s'", mod); return -6; } - printf("%3d %s: f %d, s %d, i %d, fec %d, qam %d, v %#x, a %#x\n", + printf("%3d %s: f %d, s %d, i %d, fec %d, qam %d, v %#x, a %#x, s %#x \n", chan_no, name, frontend->frequency, frontend->u.qam.symbol_rate, frontend->inversion, frontend->u.qam.fec_inner, - frontend->u.qam.modulation, *vpid, *apid); + frontend->u.qam.modulation, *vpid, *apid, *sid); free(name); free(inv); free(fec); @@ -178,31 +180,6 @@ int parse(const char *fname, int list_channels, int chan_no, const char *channel } - -static -int set_pesfilter (int fd, int pid, dmx_pes_type_t type, int dvr) -{ - struct dmx_pes_filter_params pesfilter; - - if (pid <= 0 || pid >= 0x1fff) - return 0; - - pesfilter.pid = pid; - pesfilter.input = DMX_IN_FRONTEND; - pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER; - pesfilter.pes_type = type; - pesfilter.flags = DMX_IMMEDIATE_START; - - if (ioctl(fd, DMX_SET_PES_FILTER, &pesfilter) < 0) { - PERROR ("ioctl(DMX_SET_PES_FILTER) for %s PID failed", - type == DMX_PES_AUDIO ? "Audio" : - type == DMX_PES_VIDEO ? "Video" : "??"); - return -1; - } - - return 0; -} - static int setup_frontend(int fe_fd, struct dvb_frontend_parameters *frontend) { @@ -264,9 +241,20 @@ int check_frontend (int fe_fd, int human_readable) } -static const char *usage = "\nusage: %s [-a adapter_num] [-f frontend_id] [-d demux_id] [-c conf_file] [ -H ] {<channel name>| -n channel_num} [-x]\n" - " or: %s [-c conf_file] -l\n\n"; - +static const char *usage = + "\nusage: %s [options] -l\n" + " list known channels\n" + " %s [options] {-n channel-number|channel_name}\n" + " zap to channel via number or full name (case insensitive)\n" + " -a number : use given adapter (default 0)\n" + " -f number : use given frontend (default 0)\n" + " -d number : use given demux (default 0)\n" + " -c file : read channels list from 'file'\n" + " -x : exit after tuning\n" + " -H : human readable output\n" + " -r : set up /dev/dvb/adapterX/dvr0 for TS recording\n" + " -p : add pat and pmt to TS recording (implies -r)\n" +; int main(int argc, char **argv) { @@ -275,12 +263,12 @@ int main(int argc, char **argv) char *confname = NULL; char *channel = NULL; int adapter = 0, frontend = 0, demux = 0, dvr = 0; - int vpid, apid; - int frontend_fd, video_fd, audio_fd; + int vpid, apid, sid, pmtpid = 0; + int frontend_fd, video_fd, audio_fd, pat_fd, pmt_fd; int opt, list_channels = 0, chan_no = 0; - int human_readable = 0; + int human_readable = 0, rec_psi = 0; - while ((opt = getopt(argc, argv, "Hln:hrn:a:f:d:c:x")) != -1) { + while ((opt = getopt(argc, argv, "Hln:hrn:a:f:d:c:x:p")) != -1) { switch (opt) { case 'a': adapter = strtoul(optarg, NULL, 0); @@ -300,6 +288,9 @@ int main(int argc, char **argv) case 'n': chan_no = strtoul(optarg, NULL, 0); break; + case 'p': + rec_psi = 1; + break; case 'x': exit_after_tuning = 1; break; @@ -352,7 +343,7 @@ int main(int argc, char **argv) memset(&frontend_param, 0, sizeof(struct dvb_frontend_parameters)); - if (parse(confname, list_channels, chan_no, channel, &frontend_param, &vpid, &apid)) + if (parse(confname, list_channels, chan_no, channel, &frontend_param, &vpid, &apid, &sid)) return -1; if (list_channels) return 0; @@ -365,6 +356,28 @@ int main(int argc, char **argv) if (setup_frontend(frontend_fd, &frontend_param) < 0) return -1; + if (rec_psi) { + pmtpid = get_pmt_pid(DEMUX_DEV, sid); + if (pmtpid <= 0) { + fprintf(stderr,"couldn't find pmt-pid for sid %04x\n",sid); + return -1; + } + + if ((pat_fd = open(DEMUX_DEV, O_RDWR)) < 0) { + perror("opening pat demux failed"); + return -1; + } + if (set_pesfilter(pat_fd, 0, DMX_PES_OTHER, dvr) < 0) + return -1; + + if ((pmt_fd = open(DEMUX_DEV, O_RDWR)) < 0) { + perror("opening pmt demux failed"); + return -1; + } + if (set_pesfilter(pmt_fd, pmtpid, DMX_PES_OTHER, dvr) < 0) + return -1; + } + if ((video_fd = open(DEMUX_DEV, O_RDWR)) < 0) { PERROR("failed opening '%s'", DEMUX_DEV); return -1; @@ -383,6 +396,8 @@ int main(int argc, char **argv) check_frontend (frontend_fd, human_readable); + close (pat_fd); + close (pmt_fd); close (audio_fd); close (video_fd); close (frontend_fd); diff --git a/util/szap/szap.c b/util/szap/szap.c index ed1aa51..78da3a6 100644 --- a/util/szap/szap.c +++ b/util/szap/szap.c @@ -48,6 +48,7 @@ #include <linux/dvb/dmx.h> #include <linux/dvb/audio.h> #include "lnb.h" +#include "util.h" #ifndef TRUE #define TRUE (1==1) @@ -92,94 +93,6 @@ static char *usage_str = " -p : add pat and pmt to TS recording (implies -r)\n" " or -n numbers for zapping\n"; -static int set_demux(int dmxfd, int pid, int pes_type, int dvr) -{ - struct dmx_pes_filter_params pesfilter; - - if (pid < 0 || pid >= 0x1fff) /* ignore this pid to allow radio services */ - return TRUE; - - if (dvr) { - int buffersize = 64 * 1024; - if (ioctl(dmxfd, DMX_SET_BUFFER_SIZE, buffersize) == -1) - perror("DMX_SET_BUFFER_SIZE failed"); - } - - pesfilter.pid = pid; - pesfilter.input = DMX_IN_FRONTEND; - pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER; - pesfilter.pes_type = pes_type; - pesfilter.flags = DMX_IMMEDIATE_START; - - if (ioctl(dmxfd, DMX_SET_PES_FILTER, &pesfilter) == -1) { - fprintf(stderr, "DMX_SET_PES_FILTER failed " - "(PID = 0x%04x): %d %m\n", pid, errno); - return FALSE; - } - - return TRUE; -} - -int get_pmt_pid(char *dmxdev, int sid) -{ - int patfd, count; - int pmt_pid = 0; - int patread = 0; - int section_length; - unsigned char buft[4096]; - unsigned char *buf = buft; - struct dmx_sct_filter_params f; - - memset(&f, 0, sizeof(f)); - f.pid = 0; - f.filter.filter[0] = 0x00; - f.filter.mask[0] = 0xff; - f.timeout = 0; - f.flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC; - - if ((patfd = open(dmxdev, O_RDWR)) < 0) { - perror("openening pat demux failed"); - return -1; - } - - if (ioctl(patfd, DMX_SET_FILTER, &f) == -1) { - perror("ioctl DMX_SET_FILTER failed"); - close(patfd); - return -1; - } - - while (!patread){ - if (((count = read(patfd, buf, sizeof(buft))) < 0) && errno == EOVERFLOW) - count = read(patfd, buf, sizeof(buft)); - if (count < 0) { - perror("read_sections: read error"); - close(patfd); - return -1; - } - - section_length = ((buf[1] & 0x0f) << 8) | buf[2]; - if (count != section_length + 3) - continue; - - buf += 8; - section_length -= 8; - - patread = 1; /* assumes one section contains the whole pat */ - while (section_length > 0) { - int service_id = (buf[0] << 8) | buf[1]; - if (service_id == sid) { - pmt_pid = ((buf[2] & 0x1f) << 8) | buf[3]; - section_length = 0; - } - buf += 4; - section_length -= 4; - } - } - - close(patfd); - return pmt_pid; -} - struct diseqc_cmd { struct dvb_diseqc_master_cmd cmd; uint32_t wait; @@ -390,10 +303,10 @@ int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux, if (diseqc(fefd, sat_no, pol, hiband)) if (do_tune(fefd, ifreq, sr)) - if (set_demux(dmxfdv, vpid, DMX_PES_VIDEO, dvr)) + if (set_pesfilter(dmxfdv, vpid, DMX_PES_VIDEO, dvr)) if (audiofd >= 0) (void)ioctl(audiofd, AUDIO_SET_BYPASS_MODE, bypass); - if (set_demux(dmxfda, apid, DMX_PES_AUDIO, dvr)) { + if (set_pesfilter(dmxfda, apid, DMX_PES_AUDIO, dvr)) { if (rec_psi) { pmtpid = get_pmt_pid(dmxdev, sid); if (pmtpid < 0) { @@ -403,8 +316,8 @@ int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux, fprintf(stderr,"couldn't find pmt-pid for sid %04x\n",sid); result = FALSE; } - if (set_demux(patfd, 0, DMX_PES_OTHER, dvr)) - if (set_demux(pmtfd, pmtpid, DMX_PES_OTHER, dvr)) + if (set_pesfilter(patfd, 0, DMX_PES_OTHER, dvr)) + if (set_pesfilter(pmtfd, pmtpid, DMX_PES_OTHER, dvr)) result = TRUE; } else { result = TRUE; diff --git a/util/szap/tzap.c b/util/szap/tzap.c index cd87bfa..b24bc2c 100644 --- a/util/szap/tzap.c +++ b/util/szap/tzap.c @@ -35,6 +35,8 @@ #include <linux/dvb/frontend.h> #include <linux/dvb/dmx.h> +#include "util.h" + static char FRONTEND_DEV [80]; static char DEMUX_DEV [80]; static char DVR_DEV [80]; @@ -269,7 +271,8 @@ static int check_fec(fe_code_rate_t *fec) int parse(const char *fname, const char *channel, - struct dvb_frontend_parameters *frontend, int *vpid, int *apid) + struct dvb_frontend_parameters *frontend, int *vpid, int *apid, + int *sid) { int fd; int err; @@ -343,7 +346,11 @@ int parse(const char *fname, const char *channel, if ((err = try_parse_int(fd, apid, "Audio PID"))) return -13; - + + if ((err = try_parse_int(fd, sid, "Service ID"))) + return -14; + + close(fd); return 0; @@ -351,31 +358,6 @@ int parse(const char *fname, const char *channel, static -int set_pesfilter (int fd, int pid, dmx_pes_type_t type, int dvr) -{ - struct dmx_pes_filter_params pesfilter; - - if (pid <= 0 || pid >= 0x1fff) - return 0; - - pesfilter.pid = pid; - pesfilter.input = DMX_IN_FRONTEND; - pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER; - pesfilter.pes_type = type; - pesfilter.flags = DMX_IMMEDIATE_START; - - if (ioctl(fd, DMX_SET_PES_FILTER, &pesfilter) < 0) { - PERROR ("ioctl(DMX_SET_PES_FILTER) for %s PID failed", - type == DMX_PES_AUDIO ? "Audio" : - type == DMX_PES_VIDEO ? "Video" : "??"); - return -1; - } - - return 0; -} - - -static int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend) { struct dvb_frontend_info fe_info; @@ -503,6 +485,7 @@ static char *usage = " -c file : read channels list from 'file'\n" " -x : exit after tuning\n" " -r : set up /dev/dvb/adapterX/dvr0 for TS recording\n" + " -p : add pat and pmt to TS recording (implies -r)\n" " -s : only print summary\n" " -S : run silently (no output)\n" " -H : human readable output\n" @@ -519,15 +502,16 @@ int main(int argc, char **argv) char *confname = NULL; char *channel = NULL; int adapter = 0, frontend = 0, demux = 0, dvr = 0; - int vpid, apid; + int vpid, apid, sid, pmtpid = 0; + int pat_fd, pmt_fd; int frontend_fd, audio_fd = 0, video_fd = 0, dvr_fd, file_fd; int opt; int record = 0; int frontend_only = 0; char *filename = NULL; - int human_readable = 0; + int human_readable = 0, rec_psi = 0; - while ((opt = getopt(argc, argv, "H?hrxRsFSn:a:f:d:c:t:o:")) != -1) { + while ((opt = getopt(argc, argv, "H?hrpxRsFSn:a:f:d:c:t:o:")) != -1) { switch (opt) { case 'a': adapter = strtoul(optarg, NULL, 0); @@ -548,6 +532,9 @@ int main(int argc, char **argv) case 'r': dvr = 1; break; + case 'p': + rec_psi = 1; + break; case 'x': exit_after_tuning = 1; break; @@ -610,7 +597,7 @@ int main(int argc, char **argv) memset(&frontend_param, 0, sizeof(struct dvb_frontend_parameters)); - if (parse (confname, channel, &frontend_param, &vpid, &apid)) + if (parse (confname, channel, &frontend_param, &vpid, &apid, &sid)) return -1; if ((frontend_fd = open(FRONTEND_DEV, O_RDWR)) < 0) { @@ -624,6 +611,28 @@ int main(int argc, char **argv) if (frontend_only) goto just_the_frontend_dude; + if (rec_psi) { + pmtpid = get_pmt_pid(DEMUX_DEV, sid); + if (pmtpid <= 0) { + fprintf(stderr,"couldn't find pmt-pid for sid %04x\n",sid); + return -1; + } + + if ((pat_fd = open(DEMUX_DEV, O_RDWR)) < 0) { + perror("opening pat demux failed"); + return -1; + } + if (set_pesfilter(pat_fd, 0, DMX_PES_OTHER, dvr) < 0) + return -1; + + if ((pmt_fd = open(DEMUX_DEV, O_RDWR)) < 0) { + perror("opening pmt demux failed"); + return -1; + } + if (set_pesfilter(pmt_fd, pmtpid, DMX_PES_OTHER, dvr) < 0) + return -1; + } + if ((video_fd = open(DEMUX_DEV, O_RDWR)) < 0) { PERROR("failed opening '%s'", DEMUX_DEV); return -1; @@ -689,6 +698,8 @@ just_the_frontend_dude: check_frontend (frontend_fd, human_readable); } + close (pat_fd); + close (pmt_fd); close (audio_fd); close (video_fd); close (frontend_fd); diff --git a/util/szap/util.c b/util/szap/util.c new file mode 100644 index 0000000..301d666 --- /dev/null +++ b/util/szap/util.c @@ -0,0 +1,126 @@ +/* + * util functions for various ?zap implementations + * + * Copyright (C) 2001 Johannes Stezenbach (js@convergence.de) + * for convergence integrated media + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <string.h> +#include <unistd.h> +#include <stdio.h> +#include <errno.h> + +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <linux/dvb/frontend.h> +#include <linux/dvb/dmx.h> + + +int set_pesfilter(int dmxfd, int pid, int pes_type, int dvr) +{ + struct dmx_pes_filter_params pesfilter; + + /* ignore this pid to allow radio services */ + if (pid < 0 || + pid >= 0x1fff || + (pid == 0 && pes_type != DMX_PES_OTHER)) + return 0; + + if (dvr) { + int buffersize = 64 * 1024; + if (ioctl(dmxfd, DMX_SET_BUFFER_SIZE, buffersize) == -1) + perror("DMX_SET_BUFFER_SIZE failed"); + } + + pesfilter.pid = pid; + pesfilter.input = DMX_IN_FRONTEND; + pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER; + pesfilter.pes_type = pes_type; + pesfilter.flags = DMX_IMMEDIATE_START; + + if (ioctl(dmxfd, DMX_SET_PES_FILTER, &pesfilter) == -1) { + fprintf(stderr, "DMX_SET_PES_FILTER failed " + "(PID = 0x%04x): %d %m\n", pid, errno); + return -1; + } + + return 0; +} + + +int get_pmt_pid(char *dmxdev, int sid) +{ + int patfd, count; + int pmt_pid = 0; + int patread = 0; + int section_length; + unsigned char buft[4096]; + unsigned char *buf = buft; + struct dmx_sct_filter_params f; + + memset(&f, 0, sizeof(f)); + f.pid = 0; + f.filter.filter[0] = 0x00; + f.filter.mask[0] = 0xff; + f.timeout = 0; + f.flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC; + + if ((patfd = open(dmxdev, O_RDWR)) < 0) { + perror("openening pat demux failed"); + return -1; + } + + if (ioctl(patfd, DMX_SET_FILTER, &f) == -1) { + perror("ioctl DMX_SET_FILTER failed"); + close(patfd); + return -1; + } + + while (!patread){ + if (((count = read(patfd, buf, sizeof(buft))) < 0) && errno == EOVERFLOW) + count = read(patfd, buf, sizeof(buft)); + if (count < 0) { + perror("read_sections: read error"); + close(patfd); + return -1; + } + + section_length = ((buf[1] & 0x0f) << 8) | buf[2]; + if (count != section_length + 3) + continue; + + buf += 8; + section_length -= 8; + + patread = 1; /* assumes one section contains the whole pat */ + while (section_length > 0) { + int service_id = (buf[0] << 8) | buf[1]; + if (service_id == sid) { + pmt_pid = ((buf[2] & 0x1f) << 8) | buf[3]; + section_length = 0; + } + buf += 4; + section_length -= 4; + } + } + + close(patfd); + return pmt_pid; +} diff --git a/util/szap/util.h b/util/szap/util.h new file mode 100644 index 0000000..f4b7f12 --- /dev/null +++ b/util/szap/util.h @@ -0,0 +1,24 @@ +/* + * util functions for various ?zap implementations + * + * Copyright (C) 2001 Johannes Stezenbach (js@convergence.de) + * for convergence integrated media + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 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 General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +int set_pesfilter(int dmxfd, int pid, int pes_type, int dvr); + +int get_pmt_pid(char *dmxdev, int sid); |