OSDN Git Service

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