OSDN Git Service

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