OSDN Git Service

tunerec: fix while(), helpmsg
[rec10/rec10-git.git] / tunerec / tunerec.c
1 #include <linux/dvb/frontend.h>
2 #include <linux/dvb/dmx.h>
3 #include <linux/dvb/audio.h>
4 #include <linux/dvb/version.h>
5 #include <sys/ioctl.h>
6 #include <fcntl.h>
7 #include <unistd.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <time.h>
11
12 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
13
14 static int search(int adapter_nr, unsigned int frequency, unsigned int ts_id)
15 {
16         char file[256];
17         int fd;
18         struct dvb_frontend_info info;
19         struct dtv_property prop[3];
20         struct dtv_properties props;
21         int i;
22         fe_status_t status;
23
24         sprintf(file, "/dev/dvb/adapter%d/frontend0", adapter_nr);
25         if ((fd = open(file, (O_RDWR | O_CREAT | O_TRUNC), 0666)) < 0) {
26                 perror("open");
27                 return -1;
28         }
29
30         if (ioctl(fd, FE_GET_INFO, &info) < 0) {
31                 perror("ioctl FE_GET_INFO");
32                 goto out;
33         }
34
35         if (info.type == FE_QPSK || info.type == FE_OFDM) {
36         } else {
37                 fprintf(stderr, "Unknown type of adapter\n");
38                 goto out;
39         }
40
41         prop[0].cmd = DTV_FREQUENCY;
42         prop[0].u.data = frequency;
43         prop[1].cmd = DTV_STREAM_ID;
44         prop[1].u.data = ts_id;
45         prop[2].cmd = DTV_TUNE;
46
47         props.props = prop;
48         props.num = 3;
49
50         if ((ioctl(fd, FE_SET_PROPERTY, &props)) < 0) {
51                 perror("ioctl FE_SET_PROPERTY");
52                 goto out;
53         }
54
55         for (i = 0; i < 4; i++) {
56                 if (ioctl(fd, FE_READ_STATUS, &status) < 0) {
57                         perror("ioctl FE_READ_STATUS");
58                         goto out;
59                 }
60                 if (status & FE_HAS_LOCK) {
61                         fprintf(stderr, "Successfully tuned to %d(%d).\n",
62                                 frequency, ts_id);
63                         return 0;
64                 }
65                 usleep(250 * 1000);
66         }
67
68         fprintf(stderr, "Failed to tune (status %02x).\n", status);
69
70 out:
71         close(fd);
72         return -1;
73 }
74
75 static int track(int adapter_nr)
76 {
77         char file[256];
78         int fd;
79         struct dmx_pes_filter_params filter;
80
81         filter.pid = 0x2000;
82         filter.input = DMX_IN_FRONTEND;
83         filter.output = DMX_OUT_TS_TAP;
84         filter.pes_type =  DMX_PES_VIDEO;
85         filter.flags = DMX_IMMEDIATE_START;
86
87         sprintf(file, "/dev/dvb/adapter%d/demux0", adapter_nr);
88         if ((fd = open(file, O_RDWR)) < 0) {
89                 perror("open");
90                 return -1;
91         }
92
93         if (ioctl(fd, DMX_SET_PES_FILTER, &filter) < 0) {
94                 perror("ioctl DMX_SET_PES_FILTER");
95                 close(fd);
96                 return -1;
97         }
98         return 0;
99 }
100
101 void record(int adapter_nr, char* output, int rectime) {
102         int fin, fout;
103         char input[256];
104         time_t start_time, current_time;
105         char buf[1316];
106         ssize_t rt, wt, shift;
107
108         fout = open(output, (O_WRONLY | O_CREAT | O_TRUNC), 0666);
109         if ( fout < 0 ) {
110                 printf("output file open failed\n");
111                 return;
112         }
113         sprintf(input, "/dev/dvb/adapter%d/dvr0", adapter_nr);
114         start_time = time(NULL);
115         fin = open(input, (O_RDONLY));
116         while ( ( rt = read(fin, buf, 1316) ) > 0 ) {
117                 shift = 0;
118                 while ( ( wt = write(fout, buf + shift, rt) ) > 0) {
119                         rt -= wt;
120                         if ( rt == 0 ) break;
121                         shift += wt;
122                 }
123                 if ( rt > 0 ) {
124                         // [buf] is not correctly written to [fout]
125                         printf("output file write failed\n");
126                         goto error;
127                 }
128
129                 // TODO: time() at each 1316 bytes read is not efficient, reduce frequency
130                 current_time = time(NULL);
131                 if ( current_time - start_time > rectime ) {
132                         break;
133                 }
134         }
135
136         error:
137         close(fin);
138         close(fout);
139 }
140
141 int main(int argc, char *argv[]) {
142         int adapter_nr;
143         int channel_freq;
144         int channel_id;
145         int fd;
146         int ret;
147         int rectime;
148
149         if (argc <= 2) {
150                 fprintf(stderr, "Usage: %s adapter_nr freq tsid rectime output\n", argv[0]);
151                 return 1;
152         }
153         adapter_nr = strtol(argv[1], NULL, 0);
154         channel_freq = strtol(argv[2], NULL, 10);
155         channel_id = strtol(argv[3], NULL, 10);
156         rectime = atoi(argv[4]);
157         fd = search(adapter_nr, channel_freq, channel_id);
158         if (fd < 0)
159                 return 1;
160
161         ret = track(adapter_nr);
162         record(adapter_nr, argv[5], rectime);
163         close(fd);
164
165         return ret < 0;
166 }
167