Mercurial > pt1.oyama
comparison recpt1/recpt1.c @ 1:29f3b2bbbd67
- rename test.c to recpt1.c
- divide definitions into recpt1.h
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Mon, 16 Feb 2009 15:55:46 +0900 |
parents | recpt1/test.c@67e8eca28a80 |
children | 8ac7c59fefc9 |
comparison
equal
deleted
inserted
replaced
0:67e8eca28a80 | 1:29f3b2bbbd67 |
---|---|
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 #include "recpt1.h" | |
15 | |
16 | |
17 // 周波数テーブル変換 | |
18 ISDB_T_FREQ_CONV_TABLE *searchrecoff(char *channel) | |
19 { | |
20 int lp ; | |
21 | |
22 for(lp = 0 ; lp < 113 ; lp++){ | |
23 // 文字列&長さ一致したら周波数テーブル番号を返却する | |
24 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, strlen(channel)) == 0) && | |
25 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){ | |
26 return &isdb_t_conv_table[lp] ; | |
27 } | |
28 } | |
29 return NULL ; | |
30 } | |
31 | |
32 QUEUE_T* create_queue(size_t size) | |
33 { | |
34 QUEUE_T* p_queue; | |
35 int memsize = sizeof(QUEUE_T) + (size * sizeof(BUFSZ)); | |
36 | |
37 p_queue = (QUEUE_T*)calloc(memsize, sizeof(char)); | |
38 | |
39 if(p_queue != NULL){ | |
40 p_queue->size = size; | |
41 p_queue->no_full = size; | |
42 p_queue->no_empty = 0; | |
43 pthread_mutex_init(&p_queue->mutex, NULL); | |
44 pthread_cond_init(&p_queue->cond_full, NULL); | |
45 pthread_cond_init(&p_queue->cond_empty, NULL); | |
46 } | |
47 | |
48 return p_queue; | |
49 } | |
50 | |
51 void destroy_queue(QUEUE_T *p_queue) | |
52 { | |
53 if(p_queue != NULL){ | |
54 pthread_mutex_destroy(&p_queue->mutex); | |
55 pthread_cond_destroy(&p_queue->cond_full); | |
56 pthread_cond_destroy(&p_queue->cond_empty); | |
57 free(p_queue); | |
58 } | |
59 } | |
60 | |
61 // 関数名: enqueue | |
62 // キューにデータを入れる | |
63 // データが満タンな場合は、ブロックします | |
64 void enqueue(QUEUE_T *p_queue, BUFSZ *data) | |
65 { | |
66 pthread_mutex_lock(&p_queue->mutex); | |
67 // -- ここから、クリティカルセクション -- | |
68 | |
69 // 満タンじゃなくなるまで待つ | |
70 while(!p_queue->no_full) { | |
71 pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex); | |
72 printf("Full\n"); | |
73 } | |
74 | |
75 p_queue->buffer[p_queue->in] = data; | |
76 | |
77 p_queue->in++; | |
78 p_queue->in %= p_queue->size; | |
79 | |
80 p_queue->no_full--; | |
81 p_queue->no_empty++; | |
82 | |
83 pthread_mutex_unlock(&p_queue->mutex); | |
84 pthread_cond_signal(&p_queue->cond_empty); | |
85 } | |
86 | |
87 // 関数名: dequeue | |
88 // キューにデータを入れる | |
89 // データが満タンな場合は、ブロックします | |
90 BUFSZ *dequeue(QUEUE_T *p_queue) | |
91 { | |
92 void *result; | |
93 | |
94 pthread_mutex_lock(&p_queue->mutex); | |
95 // -- ここから、クリティカルセクション -- | |
96 | |
97 // 空っぽじゃなくなるまで待つ | |
98 while (!p_queue->no_empty) { | |
99 pthread_cond_wait(&p_queue->cond_empty, &p_queue->mutex); | |
100 } | |
101 | |
102 // データを取り出す | |
103 result = p_queue->buffer[p_queue->out]; | |
104 | |
105 // 次にデータを取り出す場所をインクリメント | |
106 p_queue->out++; | |
107 p_queue->out %= p_queue->size; | |
108 | |
109 // フラグの更新 | |
110 p_queue->no_full++; | |
111 p_queue->no_empty--; | |
112 | |
113 // -- ここまで、クリティカルセクション -- | |
114 pthread_mutex_unlock(&p_queue->mutex); | |
115 pthread_cond_signal(&p_queue->cond_full); | |
116 | |
117 return result; | |
118 } | |
119 | |
120 | |
121 void *write_func(void *p) | |
122 { | |
123 QUEUE_T *p_queue = (QUEUE_T*)p; | |
124 int size = 0 ; | |
125 BUFSZ *ptr ; | |
126 #if 0 | |
127 u_char *buffer ; | |
128 | |
129 buffer = calloc(WRITE_SIZE, sizeof(char)); | |
130 if(buffer == NULL){ | |
131 return NULL ; | |
132 } | |
133 #endif | |
134 | |
135 while(1){ | |
136 ptr = dequeue(p_queue); | |
137 if(ptr == NULL){ | |
138 close(wfd); | |
139 break ; | |
140 } | |
141 #if 0 | |
142 if((size + ptr->size) < WRITE_SIZE){ | |
143 memcpy((buffer + size) , ptr->buffer, ptr->size); | |
144 size += ptr->size ; | |
145 }else{ | |
146 write(wfd, buffer, size); | |
147 size = ptr->size ; | |
148 } | |
149 #endif | |
150 write(wfd, ptr->buffer, ptr->size); | |
151 free(ptr); | |
152 if((f_exit) && (!p_queue->no_empty)){ | |
153 #if 0 | |
154 if(size){ | |
155 write(wfd, buffer, size); | |
156 } | |
157 #endif | |
158 close(wfd); | |
159 break ; | |
160 } | |
161 } | |
162 return NULL; | |
163 } | |
164 | |
165 int main(int argc, char **argv) | |
166 { | |
167 int fd ; | |
168 int rc ; | |
169 int lp ; | |
170 int channel ; | |
171 int recsec ; | |
172 time_t start_time ; | |
173 time_t cur_time ; | |
174 FREQUENCY freq; | |
175 ISDB_T_FREQ_CONV_TABLE *ptr ; | |
176 pthread_t dequeue_threads; | |
177 QUEUE_T *p_queue = create_queue(MAX_QUEUE); | |
178 BUFSZ *bufptr ; | |
179 | |
180 if(argc < 4){ | |
181 printf("Usage %s: channel recsec destfile\n", argv[0]); | |
182 printf("channel =\n"); | |
183 printf("151ch:BS朝日\n"); | |
184 printf("161ch:BS-i\n"); | |
185 printf("171ch:BSジャパン\n"); | |
186 printf("211ch:BS11デジタル\n"); | |
187 printf("222ch:TwellV\n"); | |
188 printf("141ch:BS日テレ\n"); | |
189 printf("181ch:BSフジ\n"); | |
190 printf("101ch:NHK衛星第1放送(BS1)\n"); | |
191 printf("102ch:NHK衛星第2放送(BS2)\n"); | |
192 printf("103ch:NHKハイビジョン(BShi)\n"); | |
193 return 1; | |
194 } | |
195 ptr = searchrecoff(argv[1]); | |
196 if(ptr == NULL){ | |
197 printf("Channel Select Error(%s)\n", argv[1]); | |
198 return 1 ; | |
199 } | |
200 | |
201 freq.frequencyno = ptr->set_freq ; | |
202 freq.slot = ptr->add_freq ; | |
203 | |
204 if(ptr->type == CHTYPE_SATELLITE){ | |
205 for(lp = 0 ; lp < 2 ; lp++){ | |
206 fd = open(bsdev[lp], O_RDONLY); | |
207 if(fd >= 0){ | |
208 break ; | |
209 } | |
210 } | |
211 if(fd < 0){ | |
212 printf("Device Open Error\n"); | |
213 return 1; | |
214 } | |
215 }else{ | |
216 for(lp = 0 ; lp < 2 ; lp++){ | |
217 fd = open(isdb_t_dev[lp], O_RDONLY); | |
218 if(fd >= 0){ | |
219 break ; | |
220 } | |
221 } | |
222 if(fd < 0){ | |
223 printf("Device Open Error\n"); | |
224 return 1; | |
225 } | |
226 } | |
227 recsec = atoi(argv[2]); | |
228 | |
229 wfd = open64(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666); | |
230 if(wfd < 0){ | |
231 printf("Output File Open Error(%s)\n", argv[3]); | |
232 return 0; | |
233 } | |
234 | |
235 if(ioctl(fd, SET_CHANNEL, &freq) < 0){ | |
236 printf("Tuner Select Error\n"); | |
237 return 0 ; | |
238 } | |
239 pthread_create(&dequeue_threads, NULL, write_func, p_queue); | |
240 if(ioctl(fd, START_REC, 0) < 0){ | |
241 printf("Tuner Start Error\n"); | |
242 return 0 ; | |
243 } | |
244 | |
245 time(&start_time); | |
246 while(1){ | |
247 time(&cur_time); | |
248 bufptr = calloc(1, sizeof(BUFSZ)); | |
249 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); | |
250 if(bufptr->size <= 0){ | |
251 if((cur_time - start_time) >= recsec){ | |
252 f_exit = TRUE ; | |
253 enqueue(p_queue, NULL); | |
254 break ; | |
255 }else{ | |
256 continue ; | |
257 } | |
258 } | |
259 enqueue(p_queue, bufptr); | |
260 | |
261 if((cur_time - start_time) >= recsec){ | |
262 ioctl(fd, STOP_REC, 0); | |
263 //なくなるまでデータを読み出す | |
264 while(1){ | |
265 bufptr = calloc(1, sizeof(BUFSZ)); | |
266 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); | |
267 if(bufptr->size <= 0){ | |
268 f_exit = TRUE ; | |
269 enqueue(p_queue, NULL); | |
270 break ; | |
271 } | |
272 enqueue(p_queue, bufptr); | |
273 } | |
274 break ; | |
275 } | |
276 } | |
277 close(fd); | |
278 pthread_join(dequeue_threads, NULL); | |
279 destroy_queue(p_queue); | |
280 return 0 ; | |
281 } |