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