Mercurial > pt1.mumumu
comparison recpt1/test.c @ 0:67e8eca28a80
initial import
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 16 Feb 2009 15:41:49 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:67e8eca28a80 |
---|---|
1 #include <stdio.h> | |
2 #include <sys/types.h> | |
3 #include <sys/stat.h> | |
4 #include <fcntl.h> | |
5 #include <time.h> | |
6 #include <stdlib.h> | |
7 #include <string.h> | |
8 #include <pthread.h> | |
9 #include <unistd.h> | |
10 | |
11 #include <sys/ioctl.h> | |
12 #include "pt1_ioctl.h" | |
13 | |
14 char *bsdev[2] = { | |
15 "/dev/pt1video1", | |
16 "/dev/pt1video0" | |
17 }; | |
18 char *isdb_t_dev[2] = { | |
19 "/dev/pt1video2", | |
20 "/dev/pt1video3" | |
21 }; | |
22 | |
23 #define CHTYPE_SATELLITE 0 // 衛星デジタル放送 | |
24 #define CHTYPE_GROUND 1 // 地上デジタル放送 | |
25 #define MAX_QUEUE 8192 | |
26 | |
27 #define MAX_READ_SIZE (1024 * 16) | |
28 #define WRITE_SIZE (1024 * 1024 * 2) | |
29 #define TRUE 1 | |
30 #define FALSE 0 | |
31 | |
32 typedef struct _BUFSZ{ | |
33 int size ; | |
34 u_char buffer[MAX_READ_SIZE]; | |
35 }BUFSZ; | |
36 | |
37 typedef struct _QUEUE_T{ | |
38 unsigned int in; // 次に入れるインデックス | |
39 unsigned int out; // 次に出すインデックス | |
40 unsigned int size; // キューのサイズ | |
41 unsigned int no_full; // 満タンになると 0 になる | |
42 unsigned int no_empty; // 空っぽになると 0 になる | |
43 pthread_mutex_t mutex; | |
44 pthread_cond_t cond_full; // データが満タンのときに待つための cond | |
45 pthread_cond_t cond_empty; // データが空のときに待つための cond | |
46 BUFSZ *buffer[1]; // バッファポインタ | |
47 }QUEUE_T; | |
48 | |
49 int wfd; // ファイル書き込み用 | |
50 int f_exit = FALSE ; | |
51 | |
52 typedef struct _ISDB_T_FREQ_CONV_TABLE { | |
53 int set_freq ; // 実際にioctl()を行う値 | |
54 int type ; // チャンネルタイプ | |
55 int add_freq ; // 追加する周波数(BS/CSの場合はスロット番号) | |
56 char *parm_freq ; // パラメータで受ける値 | |
57 }ISDB_T_FREQ_CONV_TABLE; | |
58 | |
59 // 変換テーブル(ISDB-T用) | |
60 #define MAX_CHANNEL_SELECT 123 | |
61 // 実際にioctl()を行う値の部分はREADMEを参照の事。 | |
62 // BS/CSの設定値およびスロット番号は | |
63 // http://www5e.biglobe.ne.jp/~kazu_f/digital-sat/index.htmlより取得。 | |
64 // | |
65 | |
66 ISDB_T_FREQ_CONV_TABLE isdb_t_conv_table[MAX_CHANNEL_SELECT] = { | |
67 { 0, CHTYPE_SATELLITE, 0, "151"}, // 151ch:BS朝日 | |
68 { 0, CHTYPE_SATELLITE, 1, "161"}, // 161ch:BS-i | |
69 { 1, CHTYPE_SATELLITE, 1, "171"}, // 171ch:BSジャパン | |
70 { 4, CHTYPE_SATELLITE, 0, "211"}, // 211ch:BS11デジタル | |
71 { 4, CHTYPE_SATELLITE, 2, "222"}, // 222ch:TwellV | |
72 { 6, CHTYPE_SATELLITE, 0, "141"}, // 141ch:BS日テレ | |
73 { 6, CHTYPE_SATELLITE, 1, "181"}, // 181ch:BSフジ | |
74 { 7, CHTYPE_SATELLITE, 0, "101"}, // 101ch:NHK衛星第1放送(BS1) | |
75 { 7, CHTYPE_SATELLITE, 0, "102"}, // 102ch:NHK衛星第2放送(BS2) | |
76 { 7, CHTYPE_SATELLITE, 1, "103"}, // 103ch:NHKハイビジョン(BShi) | |
77 { 0, CHTYPE_GROUND, 0, "1"}, { 1, CHTYPE_GROUND, 0, "2"}, | |
78 { 2, CHTYPE_GROUND, 0, "3"}, { 3, CHTYPE_GROUND, 0, "C13"}, | |
79 { 4, CHTYPE_GROUND, 0, "C14"}, { 5, CHTYPE_GROUND, 0, "C15"}, | |
80 { 6, CHTYPE_GROUND, 0, "C16"}, { 7, CHTYPE_GROUND, 0, "C17"}, | |
81 { 8, CHTYPE_GROUND, 0, "C18"}, { 9, CHTYPE_GROUND, 0, "C19"}, | |
82 { 10, CHTYPE_GROUND, 0, "C20"}, { 11, CHTYPE_GROUND, 0, "C21"}, | |
83 { 12, CHTYPE_GROUND, 0, "C22"}, { 13, CHTYPE_GROUND, 0, "4"}, | |
84 { 14, CHTYPE_GROUND, 0, "5"}, { 15, CHTYPE_GROUND, 0, "6"}, | |
85 { 16, CHTYPE_GROUND, 0, "7"}, { 17, CHTYPE_GROUND, 0, "8"}, | |
86 { 18, CHTYPE_GROUND, 0, "9"}, { 19, CHTYPE_GROUND, 0, "10"}, | |
87 { 20, CHTYPE_GROUND, 0, "11"}, { 21, CHTYPE_GROUND, 0, "12"}, | |
88 { 22, CHTYPE_GROUND, 0, "C23"}, { 23, CHTYPE_GROUND, 0, "C24"}, | |
89 { 24, CHTYPE_GROUND, 0, "C25"}, { 25, CHTYPE_GROUND, 0, "C26"}, | |
90 { 26, CHTYPE_GROUND, 0, "C27"}, { 27, CHTYPE_GROUND, 0, "C28"}, | |
91 { 28, CHTYPE_GROUND, 0, "C29"}, { 29, CHTYPE_GROUND, 0, "C30"}, | |
92 { 30, CHTYPE_GROUND, 0, "C31"}, { 31, CHTYPE_GROUND, 0, "C32"}, | |
93 { 32, CHTYPE_GROUND, 0, "C33"}, { 33, CHTYPE_GROUND, 0, "C34"}, | |
94 { 34, CHTYPE_GROUND, 0, "C35"}, { 35, CHTYPE_GROUND, 0, "C36"}, | |
95 { 36, CHTYPE_GROUND, 0, "C37"}, { 37, CHTYPE_GROUND, 0, "C38"}, | |
96 { 38, CHTYPE_GROUND, 0, "C39"}, { 39, CHTYPE_GROUND, 0, "C40"}, | |
97 { 40, CHTYPE_GROUND, 0, "C41"}, { 41, CHTYPE_GROUND, 0, "C42"}, | |
98 { 42, CHTYPE_GROUND, 0, "C43"}, { 43, CHTYPE_GROUND, 0, "C44"}, | |
99 { 44, CHTYPE_GROUND, 0, "C45"}, { 45, CHTYPE_GROUND, 0, "C46"}, | |
100 { 46, CHTYPE_GROUND, 0, "C47"}, { 47, CHTYPE_GROUND, 0, "C48"}, | |
101 { 48, CHTYPE_GROUND, 0, "C49"}, { 49, CHTYPE_GROUND, 0, "C50"}, | |
102 { 50, CHTYPE_GROUND, 0, "C51"}, { 51, CHTYPE_GROUND, 0, "C52"}, | |
103 { 52, CHTYPE_GROUND, 0, "C53"}, { 53, CHTYPE_GROUND, 0, "C54"}, | |
104 { 54, CHTYPE_GROUND, 0, "C55"}, { 55, CHTYPE_GROUND, 0, "C56"}, | |
105 { 56, CHTYPE_GROUND, 0, "C57"}, { 57, CHTYPE_GROUND, 0, "C58"}, | |
106 { 58, CHTYPE_GROUND, 0, "C59"}, { 59, CHTYPE_GROUND, 0, "C60"}, | |
107 { 60, CHTYPE_GROUND, 0, "C61"}, { 61, CHTYPE_GROUND, 0, "C62"}, | |
108 { 62, CHTYPE_GROUND, 0, "C63"}, { 63, CHTYPE_GROUND, 0, "13"}, | |
109 { 64, CHTYPE_GROUND, 0, "14"}, { 65, CHTYPE_GROUND, 0, "15"}, | |
110 { 66, CHTYPE_GROUND, 0, "16"}, { 67, CHTYPE_GROUND, 0, "17"}, | |
111 { 68, CHTYPE_GROUND, 0, "18"}, { 69, CHTYPE_GROUND, 0, "19"}, | |
112 { 70, CHTYPE_GROUND, 0, "20"}, { 71, CHTYPE_GROUND, 0, "21"}, | |
113 { 72, CHTYPE_GROUND, 0, "22"}, { 73, CHTYPE_GROUND, 0, "23"}, | |
114 { 74, CHTYPE_GROUND, 0, "24"}, { 75, CHTYPE_GROUND, 0, "25"}, | |
115 { 76, CHTYPE_GROUND, 0, "26"}, { 77, CHTYPE_GROUND, 0, "27"}, | |
116 { 78, CHTYPE_GROUND, 0, "28"}, { 79, CHTYPE_GROUND, 0, "29"}, | |
117 { 80, CHTYPE_GROUND, 0, "30"}, { 81, CHTYPE_GROUND, 0, "31"}, | |
118 { 82, CHTYPE_GROUND, 0, "32"}, { 83, CHTYPE_GROUND, 0, "33"}, | |
119 { 84, CHTYPE_GROUND, 0, "34"}, { 85, CHTYPE_GROUND, 0, "35"}, | |
120 { 86, CHTYPE_GROUND, 0, "36"}, { 87, CHTYPE_GROUND, 0, "37"}, | |
121 { 88, CHTYPE_GROUND, 0, "38"}, { 89, CHTYPE_GROUND, 0, "39"}, | |
122 { 90, CHTYPE_GROUND, 0, "40"}, { 91, CHTYPE_GROUND, 0, "41"}, | |
123 { 92, CHTYPE_GROUND, 0, "42"}, { 93, CHTYPE_GROUND, 0, "43"}, | |
124 { 94, CHTYPE_GROUND, 0, "44"}, { 95, CHTYPE_GROUND, 0, "45"}, | |
125 { 96, CHTYPE_GROUND, 0, "46"}, { 97, CHTYPE_GROUND, 0, "47"}, | |
126 { 98, CHTYPE_GROUND, 0, "48"}, { 99, CHTYPE_GROUND, 0, "49"}, | |
127 { 100, CHTYPE_GROUND, 0, "50"}, { 101, CHTYPE_GROUND, 0, "51"}, | |
128 { 102, CHTYPE_GROUND, 0, "52"}, { 103, CHTYPE_GROUND, 0, "53"}, | |
129 { 104, CHTYPE_GROUND, 0, "54"}, { 105, CHTYPE_GROUND, 0, "55"}, | |
130 { 106, CHTYPE_GROUND, 0, "56"}, { 107, CHTYPE_GROUND, 0, "57"}, | |
131 { 108, CHTYPE_GROUND, 0, "58"}, { 109, CHTYPE_GROUND, 0, "59"}, | |
132 { 110, CHTYPE_GROUND, 0, "60"}, { 111, CHTYPE_GROUND, 0, "61"}, | |
133 { 112, CHTYPE_GROUND, 0, "62"} | |
134 }; | |
135 | |
136 // 周波数テーブル変換 | |
137 ISDB_T_FREQ_CONV_TABLE *searchrecoff(char *channel) | |
138 { | |
139 int lp ; | |
140 | |
141 for(lp = 0 ; lp < 113 ; lp++){ | |
142 // 文字列&長さ一致したら周波数テーブル番号を返却する | |
143 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, strlen(channel)) == 0) && | |
144 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){ | |
145 return &isdb_t_conv_table[lp] ; | |
146 } | |
147 } | |
148 return NULL ; | |
149 } | |
150 | |
151 QUEUE_T* create_queue(size_t size) | |
152 { | |
153 QUEUE_T* p_queue; | |
154 int memsize = sizeof(QUEUE_T) + (size * sizeof(BUFSZ)); | |
155 | |
156 p_queue = (QUEUE_T*)calloc(memsize, sizeof(char)); | |
157 | |
158 if(p_queue != NULL){ | |
159 p_queue->size = size; | |
160 p_queue->no_full = size; | |
161 p_queue->no_empty = 0; | |
162 pthread_mutex_init(&p_queue->mutex, NULL); | |
163 pthread_cond_init(&p_queue->cond_full, NULL); | |
164 pthread_cond_init(&p_queue->cond_empty, NULL); | |
165 } | |
166 | |
167 return p_queue; | |
168 } | |
169 | |
170 void destroy_queue(QUEUE_T *p_queue) | |
171 { | |
172 if(p_queue != NULL){ | |
173 pthread_mutex_destroy(&p_queue->mutex); | |
174 pthread_cond_destroy(&p_queue->cond_full); | |
175 pthread_cond_destroy(&p_queue->cond_empty); | |
176 free(p_queue); | |
177 } | |
178 } | |
179 | |
180 // 関数名: enqueue | |
181 // キューにデータを入れる | |
182 // データが満タンな場合は、ブロックします | |
183 void enqueue(QUEUE_T *p_queue, BUFSZ *data) | |
184 { | |
185 pthread_mutex_lock(&p_queue->mutex); | |
186 // -- ここから、クリティカルセクション -- | |
187 | |
188 // 満タンじゃなくなるまで待つ | |
189 while(!p_queue->no_full) { | |
190 pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex); | |
191 printf("Full\n"); | |
192 } | |
193 | |
194 p_queue->buffer[p_queue->in] = data; | |
195 | |
196 p_queue->in++; | |
197 p_queue->in %= p_queue->size; | |
198 | |
199 p_queue->no_full--; | |
200 p_queue->no_empty++; | |
201 | |
202 pthread_mutex_unlock(&p_queue->mutex); | |
203 pthread_cond_signal(&p_queue->cond_empty); | |
204 } | |
205 | |
206 // 関数名: dequeue | |
207 // キューにデータを入れる | |
208 // データが満タンな場合は、ブロックします | |
209 BUFSZ *dequeue(QUEUE_T *p_queue) | |
210 { | |
211 void *result; | |
212 | |
213 pthread_mutex_lock(&p_queue->mutex); | |
214 // -- ここから、クリティカルセクション -- | |
215 | |
216 // 空っぽじゃなくなるまで待つ | |
217 while (!p_queue->no_empty) { | |
218 pthread_cond_wait(&p_queue->cond_empty, &p_queue->mutex); | |
219 } | |
220 | |
221 // データを取り出す | |
222 result = p_queue->buffer[p_queue->out]; | |
223 | |
224 // 次にデータを取り出す場所をインクリメント | |
225 p_queue->out++; | |
226 p_queue->out %= p_queue->size; | |
227 | |
228 // フラグの更新 | |
229 p_queue->no_full++; | |
230 p_queue->no_empty--; | |
231 | |
232 // -- ここまで、クリティカルセクション -- | |
233 pthread_mutex_unlock(&p_queue->mutex); | |
234 pthread_cond_signal(&p_queue->cond_full); | |
235 | |
236 return result; | |
237 } | |
238 | |
239 | |
240 void *write_func(void *p) | |
241 { | |
242 QUEUE_T *p_queue = (QUEUE_T*)p; | |
243 int size = 0 ; | |
244 BUFSZ *ptr ; | |
245 #if 0 | |
246 u_char *buffer ; | |
247 | |
248 buffer = calloc(WRITE_SIZE, sizeof(char)); | |
249 if(buffer == NULL){ | |
250 return NULL ; | |
251 } | |
252 #endif | |
253 | |
254 while(1){ | |
255 ptr = dequeue(p_queue); | |
256 if(ptr == NULL){ | |
257 close(wfd); | |
258 break ; | |
259 } | |
260 #if 0 | |
261 if((size + ptr->size) < WRITE_SIZE){ | |
262 memcpy((buffer + size) , ptr->buffer, ptr->size); | |
263 size += ptr->size ; | |
264 }else{ | |
265 write(wfd, buffer, size); | |
266 size = ptr->size ; | |
267 } | |
268 #endif | |
269 write(wfd, ptr->buffer, ptr->size); | |
270 free(ptr); | |
271 if((f_exit) && (!p_queue->no_empty)){ | |
272 #if 0 | |
273 if(size){ | |
274 write(wfd, buffer, size); | |
275 } | |
276 #endif | |
277 close(wfd); | |
278 break ; | |
279 } | |
280 } | |
281 return NULL; | |
282 } | |
283 | |
284 int main(int argc, char **argv) | |
285 { | |
286 int fd ; | |
287 int rc ; | |
288 int lp ; | |
289 int channel ; | |
290 int recsec ; | |
291 time_t start_time ; | |
292 time_t cur_time ; | |
293 FREQUENCY freq; | |
294 ISDB_T_FREQ_CONV_TABLE *ptr ; | |
295 pthread_t dequeue_threads; | |
296 QUEUE_T *p_queue = create_queue(MAX_QUEUE); | |
297 BUFSZ *bufptr ; | |
298 | |
299 if(argc < 4){ | |
300 printf("Usage %s: channel recsec destfile\n", argv[0]); | |
301 printf("channel =\n"); | |
302 printf("151ch:BS朝日\n"); | |
303 printf("161ch:BS-i\n"); | |
304 printf("171ch:BSジャパン\n"); | |
305 printf("211ch:BS11デジタル\n"); | |
306 printf("222ch:TwellV\n"); | |
307 printf("141ch:BS日テレ\n"); | |
308 printf("181ch:BSフジ\n"); | |
309 printf("101ch:NHK衛星第1放送(BS1)\n"); | |
310 printf("102ch:NHK衛星第2放送(BS2)\n"); | |
311 printf("103ch:NHKハイビジョン(BShi)\n"); | |
312 return 1; | |
313 } | |
314 ptr = searchrecoff(argv[1]); | |
315 if(ptr == NULL){ | |
316 printf("Channel Select Error(%s)\n", argv[1]); | |
317 return 1 ; | |
318 } | |
319 | |
320 freq.frequencyno = ptr->set_freq ; | |
321 freq.slot = ptr->add_freq ; | |
322 | |
323 if(ptr->type == CHTYPE_SATELLITE){ | |
324 for(lp = 0 ; lp < 2 ; lp++){ | |
325 fd = open(bsdev[lp], O_RDONLY); | |
326 if(fd >= 0){ | |
327 break ; | |
328 } | |
329 } | |
330 if(fd < 0){ | |
331 printf("Device Open Error\n"); | |
332 return 1; | |
333 } | |
334 }else{ | |
335 for(lp = 0 ; lp < 2 ; lp++){ | |
336 fd = open(isdb_t_dev[lp], O_RDONLY); | |
337 if(fd >= 0){ | |
338 break ; | |
339 } | |
340 } | |
341 if(fd < 0){ | |
342 printf("Device Open Error\n"); | |
343 return 1; | |
344 } | |
345 } | |
346 recsec = atoi(argv[2]); | |
347 | |
348 wfd = open64(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666); | |
349 if(wfd < 0){ | |
350 printf("Output File Open Error(%s)\n", argv[3]); | |
351 return 0; | |
352 } | |
353 | |
354 if(ioctl(fd, SET_CHANNEL, &freq) < 0){ | |
355 printf("Tuner Select Error\n"); | |
356 return 0 ; | |
357 } | |
358 pthread_create(&dequeue_threads, NULL, write_func, p_queue); | |
359 if(ioctl(fd, START_REC, 0) < 0){ | |
360 printf("Tuner Start Error\n"); | |
361 return 0 ; | |
362 } | |
363 | |
364 time(&start_time); | |
365 while(1){ | |
366 time(&cur_time); | |
367 bufptr = calloc(1, sizeof(BUFSZ)); | |
368 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); | |
369 if(bufptr->size <= 0){ | |
370 if((cur_time - start_time) >= recsec){ | |
371 f_exit = TRUE ; | |
372 enqueue(p_queue, NULL); | |
373 break ; | |
374 }else{ | |
375 continue ; | |
376 } | |
377 } | |
378 enqueue(p_queue, bufptr); | |
379 | |
380 if((cur_time - start_time) >= recsec){ | |
381 ioctl(fd, STOP_REC, 0); | |
382 //なくなるまでデータを読み出す | |
383 while(1){ | |
384 bufptr = calloc(1, sizeof(BUFSZ)); | |
385 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); | |
386 if(bufptr->size <= 0){ | |
387 f_exit = TRUE ; | |
388 enqueue(p_queue, NULL); | |
389 break ; | |
390 } | |
391 enqueue(p_queue, bufptr); | |
392 } | |
393 break ; | |
394 } | |
395 } | |
396 close(fd); | |
397 pthread_join(dequeue_threads, NULL); | |
398 destroy_queue(p_queue); | |
399 return 0 ; | |
400 } |