Mercurial > pt1
comparison recpt1/recpt1.c @ 3:6801fe7e04ff
updated to ariv25v023
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Tue, 17 Feb 2009 01:40:56 +0900 |
parents | 8ac7c59fefc9 |
children | 43d177fa65c9 |
comparison
equal
deleted
inserted
replaced
2:8ac7c59fefc9 | 3:6801fe7e04ff |
---|---|
1 #include <stdio.h> | 1 #include <fcntl.h> |
2 #include <sys/types.h> | 2 #include <sys/types.h> |
3 #include <sys/stat.h> | 3 #include <sys/stat.h> |
4 #include <fcntl.h> | 4 #include <time.h> |
5 #include <time.h> | 5 #include <stdlib.h> |
6 #include <stdlib.h> | 6 #include <string.h> |
7 #include <string.h> | 7 #include <pthread.h> |
8 #include <pthread.h> | 8 #include <unistd.h> |
9 #include <unistd.h> | 9 #include <stdio.h> |
10 | 10 |
11 #include <sys/ioctl.h> | 11 #include <sys/ioctl.h> |
12 #include "pt1_ioctl.h" | 12 #include "pt1_ioctl.h" |
13 | 13 |
14 #include "recpt1.h" | 14 #include "recpt1.h" |
15 #include "decoder.h" | 15 #include "decoder.h" |
16 | 16 |
17 /* globals */ | 17 /* globals */ |
18 int wfd; // ファイル書き込み用 | 18 int wfd; /* for output file */ |
19 int f_exit = FALSE ; | 19 int f_exit = FALSE ; |
20 decoder *dec; | 20 |
21 | 21 typedef struct thread_data { |
22 QUEUE_T *queue; | |
23 decoder *decoder; | |
24 } thread_data; | |
22 | 25 |
23 // 周波数テーブル変換 | 26 // 周波数テーブル変換 |
24 ISDB_T_FREQ_CONV_TABLE * | 27 ISDB_T_FREQ_CONV_TABLE * |
25 searchrecoff(char *channel) | 28 searchrecoff(char *channel) |
26 { | 29 { |
39 | 42 |
40 QUEUE_T * | 43 QUEUE_T * |
41 create_queue(size_t size) | 44 create_queue(size_t size) |
42 { | 45 { |
43 QUEUE_T* p_queue; | 46 QUEUE_T* p_queue; |
44 int memsize = sizeof(QUEUE_T) + (size * sizeof(BUFSZ)); | 47 int memsize = sizeof(QUEUE_T) + size * sizeof(BUFSZ); |
45 | 48 |
46 p_queue = (QUEUE_T*)calloc(memsize, sizeof(char)); | 49 p_queue = (QUEUE_T*)calloc(memsize, sizeof(char)); |
47 | 50 |
48 if(p_queue != NULL){ | 51 if(p_queue != NULL){ |
49 p_queue->size = size; | 52 p_queue->size = size; |
66 pthread_cond_destroy(&p_queue->cond_empty); | 69 pthread_cond_destroy(&p_queue->cond_empty); |
67 free(p_queue); | 70 free(p_queue); |
68 } | 71 } |
69 } | 72 } |
70 | 73 |
71 // 関数名: enqueue | 74 /* enqueue data. this function will block if queue is full. */ |
72 // キューにデータを入れる | |
73 // データが満タンな場合は、ブロックします | |
74 void | 75 void |
75 enqueue(QUEUE_T *p_queue, BUFSZ *data) | 76 enqueue(QUEUE_T *p_queue, BUFSZ *data) |
76 { | 77 { |
77 pthread_mutex_lock(&p_queue->mutex); | 78 pthread_mutex_lock(&p_queue->mutex); |
78 // -- ここから、クリティカルセクション -- | 79 /* entered critical section */ |
79 | 80 |
80 // 満タンじゃなくなるまで待つ | 81 /* wait until queue is not full */ |
81 while(!p_queue->no_full) { | 82 while(!p_queue->no_full) { |
82 pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex); | 83 pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex); |
83 printf("Full\n"); | 84 printf("Full\n"); |
84 } | 85 } |
85 | 86 |
89 p_queue->in %= p_queue->size; | 90 p_queue->in %= p_queue->size; |
90 | 91 |
91 p_queue->no_full--; | 92 p_queue->no_full--; |
92 p_queue->no_empty++; | 93 p_queue->no_empty++; |
93 | 94 |
95 /* leaving critical section */ | |
94 pthread_mutex_unlock(&p_queue->mutex); | 96 pthread_mutex_unlock(&p_queue->mutex); |
95 pthread_cond_signal(&p_queue->cond_empty); | 97 pthread_cond_signal(&p_queue->cond_empty); |
96 } | 98 } |
97 | 99 |
98 // 関数名: dequeue | 100 /* dequeue data. this function will block if queue is empty. */ |
99 // キューにデータを入れる | |
100 // データが満タンな場合は、ブロックします | |
101 BUFSZ * | 101 BUFSZ * |
102 dequeue(QUEUE_T *p_queue) | 102 dequeue(QUEUE_T *p_queue) |
103 { | 103 { |
104 void *result; | 104 BUFSZ *buffer; |
105 | 105 |
106 pthread_mutex_lock(&p_queue->mutex); | 106 pthread_mutex_lock(&p_queue->mutex); |
107 // -- ここから、クリティカルセクション -- | 107 /* entered the critical section*/ |
108 | 108 |
109 // 空っぽじゃなくなるまで待つ | 109 /* wait until queue is filled */ |
110 while (!p_queue->no_empty) { | 110 while (!p_queue->no_empty) { |
111 pthread_cond_wait(&p_queue->cond_empty, &p_queue->mutex); | 111 pthread_cond_wait(&p_queue->cond_empty, &p_queue->mutex); |
112 } | 112 } |
113 | 113 |
114 // データを取り出す | 114 /* take buffer address */ |
115 result = p_queue->buffer[p_queue->out]; | 115 buffer = p_queue->buffer[p_queue->out]; |
116 | 116 |
117 // 次にデータを取り出す場所をインクリメント | 117 // 次にデータを取り出す場所をインクリメント |
118 p_queue->out++; | 118 p_queue->out++; |
119 p_queue->out %= p_queue->size; | 119 p_queue->out %= p_queue->size; |
120 | 120 |
121 // フラグの更新 | 121 /* update flags */ |
122 p_queue->no_full++; | 122 p_queue->no_full++; |
123 p_queue->no_empty--; | 123 p_queue->no_empty--; |
124 | 124 |
125 // -- ここまで、クリティカルセクション -- | 125 /* leaving the critical section */ |
126 pthread_mutex_unlock(&p_queue->mutex); | 126 pthread_mutex_unlock(&p_queue->mutex); |
127 pthread_cond_signal(&p_queue->cond_full); | 127 pthread_cond_signal(&p_queue->cond_full); |
128 | 128 |
129 return result; | 129 return buffer; |
130 } | 130 } |
131 | 131 |
132 /* this function will be a writing thread */ | 132 /* this function will be a writing thread */ |
133 void * | 133 void * |
134 write_func(void *p) | 134 write_func(void *p) |
135 { | 135 { |
136 QUEUE_T *p_queue = (QUEUE_T*)p; | 136 thread_data *data = (thread_data *)p; |
137 BUFSZ *ptr ; | 137 QUEUE_T *p_queue = data->queue; |
138 decoder *dec = data->decoder; | |
139 BUFSZ *buf ; | |
138 ARIB_STD_B25_BUFFER sbuf, dbuf; | 140 ARIB_STD_B25_BUFFER sbuf, dbuf; |
139 | 141 |
140 while(1){ | 142 while(1){ |
141 ptr = dequeue(p_queue); | 143 buf = dequeue(p_queue); |
142 /* no entry in the queue */ | 144 /* no entry in the queue */ |
143 if(ptr == NULL){ | 145 if(buf == NULL){ |
144 close(wfd); | 146 close(wfd); |
145 break ; | 147 break ; |
146 } | 148 } |
147 | 149 |
148 sbuf.data = ptr->buffer; | 150 sbuf.data = buf->buffer; |
149 sbuf.size = ptr->size; | 151 sbuf.size = buf->size; |
150 | 152 |
151 /* write data to output file*/ | 153 /* write data to output file*/ |
152 b25_decode(dec, &sbuf, &dbuf); | 154 b25_decode(dec, &sbuf, &dbuf); |
153 write(wfd, dbuf.data, dbuf.size); | 155 write(wfd, dbuf.data, dbuf.size); |
154 free(ptr); | 156 free(buf); |
155 | 157 |
156 /* normal exit */ | 158 /* normal exit */ |
157 if((f_exit) && (!p_queue->no_empty)){ | 159 if((f_exit) && (!p_queue->no_empty)){ |
158 b25_finish(dec, &sbuf, &dbuf); | 160 b25_finish(dec, &sbuf, &dbuf); |
159 write(wfd, dbuf.data, dbuf.size); | 161 write(wfd, dbuf.data, dbuf.size); |
176 FREQUENCY freq; | 178 FREQUENCY freq; |
177 ISDB_T_FREQ_CONV_TABLE *ptr ; | 179 ISDB_T_FREQ_CONV_TABLE *ptr ; |
178 pthread_t dequeue_threads; | 180 pthread_t dequeue_threads; |
179 QUEUE_T *p_queue = create_queue(MAX_QUEUE); | 181 QUEUE_T *p_queue = create_queue(MAX_QUEUE); |
180 BUFSZ *bufptr ; | 182 BUFSZ *bufptr ; |
181 | 183 decoder *dec; |
182 if(argc < 4){ | 184 thread_data tdata; |
185 | |
186 if(argc < 4) { | |
183 printf("Usage %s: channel recsec destfile\n", argv[0]); | 187 printf("Usage %s: channel recsec destfile\n", argv[0]); |
184 printf("channel =\n"); | 188 printf("channel =\n"); |
185 printf("151ch:BS朝日\n"); | 189 printf("151ch:BS朝日\n"); |
186 printf("161ch:BS-i\n"); | 190 printf("161ch:BS-i\n"); |
187 printf("171ch:BSジャパン\n"); | 191 printf("171ch:BSジャパン\n"); |
193 printf("102ch:NHK衛星第2放送(BS2)\n"); | 197 printf("102ch:NHK衛星第2放送(BS2)\n"); |
194 printf("103ch:NHKハイビジョン(BShi)\n"); | 198 printf("103ch:NHKハイビジョン(BShi)\n"); |
195 return 1; | 199 return 1; |
196 } | 200 } |
197 ptr = searchrecoff(argv[1]); | 201 ptr = searchrecoff(argv[1]); |
198 if(ptr == NULL){ | 202 if(ptr == NULL) { |
199 printf("Channel Select Error(%s)\n", argv[1]); | 203 printf("Channel Select Error(%s)\n", argv[1]); |
200 return 1 ; | 204 return 1 ; |
201 } | 205 } |
202 | 206 |
203 freq.frequencyno = ptr->set_freq ; | 207 freq.frequencyno = ptr->set_freq ; |
204 freq.slot = ptr->add_freq ; | 208 freq.slot = ptr->add_freq ; |
205 | 209 |
206 if(ptr->type == CHTYPE_SATELLITE){ | 210 if(ptr->type == CHTYPE_SATELLITE) { |
207 for(lp = 0 ; lp < 2 ; lp++){ | 211 for(lp = 0 ; lp < 2 ; lp++) { |
208 fd = open(bsdev[lp], O_RDONLY); | 212 fd = open(bsdev[lp], O_RDONLY); |
209 if(fd >= 0){ | 213 if(fd >= 0) { |
210 break ; | 214 break ; |
211 } | 215 } |
212 } | 216 } |
213 if(fd < 0){ | 217 if(fd < 0) { |
214 printf("Device Open Error\n"); | 218 printf("Device Open Error\n"); |
215 return 1; | 219 return 1; |
216 } | 220 } |
217 }else{ | 221 } else { |
218 for(lp = 0 ; lp < 2 ; lp++){ | 222 for(lp = 0 ; lp < 2 ; lp++) { |
219 fd = open(isdb_t_dev[lp], O_RDONLY); | 223 fd = open(isdb_t_dev[lp], O_RDONLY); |
220 if(fd >= 0){ | 224 if(fd >= 0) { |
221 break ; | 225 break ; |
222 } | 226 } |
223 } | 227 } |
224 if(fd < 0){ | 228 if(fd < 0) { |
225 printf("Device Open Error\n"); | 229 printf("Device Open Error\n"); |
226 return 1; | 230 return 1; |
227 } | 231 } |
228 } | 232 } |
229 recsec = atoi(argv[2]); | 233 recsec = atoi(argv[2]); |
230 | 234 |
231 /* initialize decoder */ | 235 /* initialize decoder */ |
232 dec = b25_startup(); | 236 dec = b25_startup(); |
233 | 237 |
234 /* open output file */ | 238 /* open output file */ |
235 wfd = open64(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666); | 239 wfd = open(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666); |
236 if(wfd < 0){ | 240 if(wfd < 0) { |
237 printf("Output File Open Error(%s)\n", argv[3]); | 241 printf("Output File Open Error(%s)\n", argv[3]); |
238 return 0; | 242 return 0; |
239 } | 243 } |
240 | 244 |
241 if(ioctl(fd, SET_CHANNEL, &freq) < 0){ | 245 if(ioctl(fd, SET_CHANNEL, &freq) < 0) { |
242 printf("Tuner Select Error\n"); | 246 printf("Tuner Select Error\n"); |
243 return 0 ; | 247 return 0 ; |
244 } | 248 } |
245 | 249 |
246 /* make reading thread */ | 250 /* make reading thread */ |
247 pthread_create(&dequeue_threads, NULL, write_func, p_queue); | 251 tdata.queue = p_queue; |
248 if(ioctl(fd, START_REC, 0) < 0){ | 252 tdata.decoder = dec; |
253 pthread_create(&dequeue_threads, NULL, write_func, &tdata); | |
254 | |
255 /* start recording*/ | |
256 if(ioctl(fd, START_REC, 0) < 0) { | |
249 printf("Tuner Start Error\n"); | 257 printf("Tuner Start Error\n"); |
250 return 0 ; | 258 return 0 ; |
251 } | 259 } |
252 | 260 |
253 time(&start_time); | 261 time(&start_time); |
254 | 262 |
255 /* read-write loop */ | 263 /* read from tuner */ |
256 while(1){ | 264 while(1) { |
257 time(&cur_time); | 265 time(&cur_time); |
258 bufptr = calloc(1, sizeof(BUFSZ)); | 266 bufptr = malloc(sizeof(BUFSZ)); |
259 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); | 267 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); |
260 if(bufptr->size <= 0){ | 268 if(bufptr->size <= 0) { |
261 if((cur_time - start_time) >= recsec){ | 269 if((cur_time - start_time) >= recsec) { |
262 f_exit = TRUE ; | 270 f_exit = TRUE ; |
263 enqueue(p_queue, NULL); | 271 enqueue(p_queue, NULL); |
264 break ; | 272 break ; |
265 }else{ | 273 } else { |
266 continue ; | 274 continue ; |
267 } | 275 } |
268 } | 276 } |
269 enqueue(p_queue, bufptr); | 277 enqueue(p_queue, bufptr); |
270 | 278 |
271 if((cur_time - start_time) >= recsec){ | 279 /* stop recording */ |
280 if((cur_time - start_time) >= recsec) { | |
272 ioctl(fd, STOP_REC, 0); | 281 ioctl(fd, STOP_REC, 0); |
273 //なくなるまでデータを読み出す | 282 /* read remaining data */ |
274 while(1){ | 283 while(1) { |
275 bufptr = calloc(1, sizeof(BUFSZ)); | 284 bufptr = malloc(sizeof(BUFSZ)); |
276 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); | 285 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); |
277 if(bufptr->size <= 0){ | 286 if(bufptr->size <= 0) { |
278 f_exit = TRUE ; | 287 f_exit = TRUE ; |
279 enqueue(p_queue, NULL); | 288 enqueue(p_queue, NULL); |
280 break ; | 289 break ; |
281 } | 290 } |
282 enqueue(p_queue, bufptr); | 291 enqueue(p_queue, bufptr); |
283 } | 292 } |
284 break ; | 293 break ; |
285 } | 294 } |
286 } | 295 } |
287 close(fd); /* close tuner */ | 296 /* close tuner */ |
297 close(fd); | |
288 | 298 |
289 /* wait reading thread */ | 299 /* wait reading thread */ |
290 pthread_join(dequeue_threads, NULL); | 300 pthread_join(dequeue_threads, NULL); |
291 destroy_queue(p_queue); | 301 destroy_queue(p_queue); |
292 | 302 |