comparison recpt1/recpt1.c @ 5:97fd2315114e

- now it can handle options. - applied channel patch. - some cleanups.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 17 Feb 2009 05:58:36 +0900
parents 43d177fa65c9
children d898fd27547f
comparison
equal deleted inserted replaced
4:43d177fa65c9 5:97fd2315114e
1 #include <stdio.h>
1 #include <fcntl.h> 2 #include <fcntl.h>
2 #include <sys/types.h> 3 #include <sys/types.h>
3 #include <sys/stat.h> 4 #include <sys/stat.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 #include <getopt.h>
10 11
11 #include <sys/ioctl.h> 12 #include <sys/ioctl.h>
12 #include "pt1_ioctl.h" 13 #include "pt1_ioctl.h"
13 14
14 #include "recpt1.h" 15 #include "recpt1.h"
15 #include "decoder.h" 16 #include "decoder.h"
16 17
17 /* globals */ 18 /* globals */
18 int wfd; /* for output file */ 19 int f_exit = FALSE;
19 int f_exit = FALSE ;
20 20
21 typedef struct thread_data { 21 typedef struct thread_data {
22 QUEUE_T *queue; 22 QUEUE_T *queue;
23 decoder *decoder; 23 decoder *decoder;
24 int fd;
24 } thread_data; 25 } thread_data;
25 26
26 // 周波数テーブル変換 27 // 周波数テーブル変換
27 ISDB_T_FREQ_CONV_TABLE * 28 ISDB_T_FREQ_CONV_TABLE *
28 searchrecoff(char *channel) 29 searchrecoff(char *channel)
29 { 30 {
30 int lp ; 31 int lp;
31 32
32 for(lp = 0 ; lp < 113 ; lp++){ 33 for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++){
33 // 文字列&長さ一致したら周波数テーブル番号を返却する 34 // 文字列&長さ一致したら周波数テーブル番号を返却する
34 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, 35 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel,
35 strlen(channel)) == 0) && 36 strlen(channel)) == 0) &&
36 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){ 37 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){
37 return &isdb_t_conv_table[lp] ; 38 return &isdb_t_conv_table[lp];
38 } 39 }
39 } 40 }
40 return NULL ; 41 return NULL;
41 } 42 }
42 43
43 QUEUE_T * 44 QUEUE_T *
44 create_queue(size_t size) 45 create_queue(size_t size)
45 { 46 {
46 QUEUE_T *p_queue; 47 QUEUE_T *p_queue;
47 int memsize = sizeof(QUEUE_T) + size * sizeof(BUFSZ); 48 int memsize = sizeof(QUEUE_T) + size * sizeof(BUFSZ);
48 49
49 p_queue = (QUEUE_T*)calloc(memsize, sizeof(char)); 50 p_queue = (QUEUE_T*)calloc(memsize, sizeof(char));
50 51
51 if(p_queue != NULL){ 52 if(p_queue != NULL) {
52 p_queue->size = size; 53 p_queue->size = size;
53 p_queue->no_full = size; 54 p_queue->no_full = size;
54 p_queue->no_empty = 0; 55 p_queue->no_empty = 0;
55 pthread_mutex_init(&p_queue->mutex, NULL); 56 pthread_mutex_init(&p_queue->mutex, NULL);
56 pthread_cond_init(&p_queue->cond_full, NULL); 57 pthread_cond_init(&p_queue->cond_full, NULL);
61 } 62 }
62 63
63 void 64 void
64 destroy_queue(QUEUE_T *p_queue) 65 destroy_queue(QUEUE_T *p_queue)
65 { 66 {
66 if(p_queue != NULL) { 67 if(!p_queue)
67 pthread_mutex_destroy(&p_queue->mutex); 68 return;
68 pthread_cond_destroy(&p_queue->cond_full); 69
69 pthread_cond_destroy(&p_queue->cond_empty); 70 pthread_mutex_destroy(&p_queue->mutex);
70 free(p_queue); 71 pthread_cond_destroy(&p_queue->cond_full);
71 } 72 pthread_cond_destroy(&p_queue->cond_empty);
73 free(p_queue);
72 } 74 }
73 75
74 /* enqueue data. this function will block if queue is full. */ 76 /* enqueue data. this function will block if queue is full. */
75 void 77 void
76 enqueue(QUEUE_T *p_queue, BUFSZ *data) 78 enqueue(QUEUE_T *p_queue, BUFSZ *data)
79 /* entered critical section */ 81 /* entered critical section */
80 82
81 /* wait until queue is not full */ 83 /* wait until queue is not full */
82 while(!p_queue->no_full) { 84 while(!p_queue->no_full) {
83 pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex); 85 pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex);
84 printf("Full\n"); 86 fprintf(stderr, "Full\n");
85 } 87 }
86 88
87 p_queue->buffer[p_queue->in] = data; 89 p_queue->buffer[p_queue->in] = data;
88 90
89 p_queue->in++; 91 p_queue->in++;
134 write_func(void *p) 136 write_func(void *p)
135 { 137 {
136 thread_data *data = (thread_data *)p; 138 thread_data *data = (thread_data *)p;
137 QUEUE_T *p_queue = data->queue; 139 QUEUE_T *p_queue = data->queue;
138 decoder *dec = data->decoder; 140 decoder *dec = data->decoder;
139 BUFSZ *buf ; 141 int wfd = data->fd;
142 int use_b25 = dec ? 1 : 0;
143 BUFSZ *buf;
140 ARIB_STD_B25_BUFFER sbuf, dbuf; 144 ARIB_STD_B25_BUFFER sbuf, dbuf;
145 int code;
141 146
142 while(1) { 147 while(1) {
143 buf = dequeue(p_queue); 148 buf = dequeue(p_queue);
144 /* no entry in the queue */ 149 /* no entry in the queue */
145 if(buf == NULL){ 150 if(buf == NULL){
146 close(wfd); 151 close(wfd);
147 break ; 152 break;
148 } 153 }
149 154
150 sbuf.data = buf->buffer; 155 sbuf.data = buf->buffer;
151 sbuf.size = buf->size; 156 sbuf.size = buf->size;
152 157
153 /* write data to output file*/ 158 if(use_b25) {
154 b25_decode(dec, &sbuf, &dbuf); 159 /* write data to output file*/
155 write(wfd, dbuf.data, dbuf.size); 160 code = b25_decode(dec, &sbuf, &dbuf);
156 free(buf); 161 if(code < 0) {
162 fprintf(stderr, "b25_decode failed\n");
163 close(wfd);
164 break;
165 }
166 write(wfd, dbuf.data, dbuf.size);
167 free(buf);
168 } else {
169 write(wfd, sbuf.data, sbuf.size);
170 free(buf);
171 }
157 172
158 /* normal exit */ 173 /* normal exit */
159 if((f_exit) && (!p_queue->no_empty)){ 174 if((f_exit) && (!p_queue->no_empty)) {
160 b25_finish(dec, &sbuf, &dbuf); 175 if(use_b25) {
161 write(wfd, dbuf.data, dbuf.size); 176 code = b25_finish(dec, &sbuf, &dbuf);
177 if(code < 0) {
178 fprintf(stderr, "b25_finish failed\n");
179 close(wfd);
180 break;
181 }
182 write(wfd, dbuf.data, dbuf.size);
183 }
162 close(wfd); 184 close(wfd);
163 break ; 185 break;
164 } 186 }
165 } 187 }
166 188
167 return NULL; 189 return NULL;
168 } 190 }
169 191
170 int 192 int
171 main(int argc, char **argv) 193 main(int argc, char **argv)
172 { 194 {
173 int fd ; 195 int fd, wfd;
174 int lp ; 196 int lp;
175 int recsec ; 197 int recsec;
176 time_t start_time ; 198 time_t start_time, cur_time;
177 time_t cur_time ;
178 FREQUENCY freq; 199 FREQUENCY freq;
179 ISDB_T_FREQ_CONV_TABLE *ptr ; 200 ISDB_T_FREQ_CONV_TABLE *ptr;
180 pthread_t dequeue_threads; 201 pthread_t dequeue_threads;
181 QUEUE_T *p_queue = create_queue(MAX_QUEUE); 202 QUEUE_T *p_queue = create_queue(MAX_QUEUE);
182 BUFSZ *bufptr ; 203 BUFSZ *bufptr;
183 decoder *dec; 204 decoder *dec = NULL;
184 thread_data tdata; 205 thread_data tdata;
185 206 decoder_options dopt;
186 if(argc < 4) { 207
187 printf("Usage %s: channel recsec destfile\n", argv[0]); 208 int use_b25 = 0;
209 int result;
210 int option_index;
211 struct option long_options[] = {
212 { "b25", 0, NULL, 'b'},
213 { "B25", 0, NULL, 'b'},
214 { "round", 1, NULL, 'r'},
215 { "strip", 0, NULL, 's'},
216 { "emm", 0, NULL, 'm'},
217 { "EMM", 0, NULL, 'm'}
218 };
219
220 dopt.round = 4;
221 dopt.strip = 0;
222 dopt.emm = 0;
223
224 while((result = getopt_long(argc, argv, "br:sm", long_options, &option_index)) != -1) {
225 switch(result) {
226 case 'b':
227 use_b25 = 1;
228 fprintf(stderr, "using B25...\n");
229 break;
230 case 's':
231 dopt.strip = 1;
232 fprintf(stderr, "enable B25 strip\n");
233 break;
234 case 'm':
235 dopt.emm = 1;
236 fprintf(stderr, "enable B25 emm processing\n");
237 break;
238 case 'r':
239 dopt.round = atoi(optarg);
240 fprintf(stderr, "set round %d\n", dopt.round);
241 break;
242 case ':':
243 fprintf(stderr, "%c needs value\n", result);
244 break;
245 case '?':
246 fprintf(stderr, "Usage: [--b25 [--round N] [--strip] [--EMM]] channel recsec destfile\n");
247 break;
248 }
249 }
250
251 if(argc - optind < 3) {
252 printf("Usage %s: [--b25 [--round N] [--strip] [--EMM]] channel recsec destfile\n", argv[0]);
188 printf("channel =\n"); 253 printf("channel =\n");
189 printf("151ch:BS朝日\n"); 254 printf("151ch:BS朝日\n");
190 printf("161ch:BS-i\n"); 255 printf("161ch:BS-i\n");
256 printf("191ch:WOWOW\n");
191 printf("171ch:BSジャパン\n"); 257 printf("171ch:BSジャパン\n");
258 printf("200ch:スターチャンネル\n");
192 printf("211ch:BS11デジタル\n"); 259 printf("211ch:BS11デジタル\n");
193 printf("222ch:TwellV\n"); 260 printf("222ch:TwellV\n");
194 printf("141ch:BS日テレ\n"); 261 printf("141ch:BS日テレ\n");
195 printf("181ch:BSフジ\n"); 262 printf("181ch:BSフジ\n");
196 printf("101ch:NHK衛星第1放送(BS1)\n"); 263 printf("101ch:NHK衛星第1放送(BS1)\n");
197 printf("102ch:NHK衛星第2放送(BS2)\n"); 264 printf("102ch:NHK衛星第2放送(BS2)\n");
198 printf("103ch:NHKハイビジョン(BShi)\n"); 265 printf("103ch:NHKハイビジョン(BShi)\n");
266 printf("CS2-CS24:CSチャンネル\n");
199 return 1; 267 return 1;
200 } 268 }
201 ptr = searchrecoff(argv[1]); 269 ptr = searchrecoff(argv[optind]);
202 if(ptr == NULL) { 270 if(ptr == NULL){
203 printf("Channel Select Error(%s)\n", argv[1]); 271 printf("Channel Select Error(%s)\n", argv[optind]);
204 return 1 ; 272 return 1;
205 } 273 }
206 274
207 freq.frequencyno = ptr->set_freq ; 275 freq.frequencyno = ptr->set_freq;
208 freq.slot = ptr->add_freq ; 276 freq.slot = ptr->add_freq;
209 277
210 if(ptr->type == CHTYPE_SATELLITE) { 278 if(ptr->type == CHTYPE_SATELLITE) {
211 for(lp = 0 ; lp < 2 ; lp++) { 279 for(lp = 0; lp < 2; lp++) {
212 fd = open(bsdev[lp], O_RDONLY); 280 fd = open(bsdev[lp], O_RDONLY);
213 if(fd >= 0) { 281 if(fd >= 0) {
214 break ; 282 break;
215 } 283 }
216 } 284 }
217 if(fd < 0) { 285 if(fd < 0) {
218 printf("Device Open Error\n"); 286 fprintf(stderr, "Device Open Error\n");
219 return 1; 287 return 1;
220 } 288 }
221 } else { 289 } else {
222 for(lp = 0 ; lp < 2 ; lp++) { 290 for(lp = 0; lp < 2; lp++) {
223 fd = open(isdb_t_dev[lp], O_RDONLY); 291 fd = open(isdb_t_dev[lp], O_RDONLY);
224 if(fd >= 0) { 292 if(fd >= 0) {
225 break ; 293 break;
226 } 294 }
227 } 295 }
228 if(fd < 0) { 296 if(fd < 0) {
229 printf("Device Open Error\n"); 297 fprintf(stderr, "Device Open Error\n");
230 return 1; 298 return 1;
231 } 299 }
232 } 300 }
233 recsec = atoi(argv[2]); 301 recsec = atoi(argv[optind + 1]);
234 302
235 /* initialize decoder */ 303 /* initialize decoder */
236 dec = b25_startup(); 304 if(use_b25) {
305 dec = b25_startup(&dopt);
306 if(!dec) {
307 fprintf(stderr, "cannot start b25 decoder\n");
308 return 1;
309 }
310 }
237 311
238 /* open output file */ 312 /* open output file */
239 wfd = open(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666); 313 wfd = open(argv[optind + 2], (O_RDWR | O_CREAT | O_TRUNC), 0666);
240 if(wfd < 0) { 314 if(wfd < 0) {
241 printf("Output File Open Error(%s)\n", argv[3]); 315 fprintf(stderr, "Output File Open Error(%s)\n", argv[optind + 2]);
242 return 0; 316 return 1;
243 } 317 }
244 318
245 if(ioctl(fd, SET_CHANNEL, &freq) < 0) { 319 if(ioctl(fd, SET_CHANNEL, &freq) < 0) {
246 printf("Tuner Select Error\n"); 320 fprintf(stderr, "Tuner Select Error\n");
247 return 0 ; 321 return 1;
248 } 322 }
249 323
250 /* make reading thread */ 324 /* make reader thread */
251 tdata.queue = p_queue; 325 tdata.queue = p_queue;
252 tdata.decoder = dec; 326 tdata.decoder = dec;
327 tdata.fd = wfd;
253 pthread_create(&dequeue_threads, NULL, write_func, &tdata); 328 pthread_create(&dequeue_threads, NULL, write_func, &tdata);
254 329
255 /* start recording*/ 330 /* start recording */
256 if(ioctl(fd, START_REC, 0) < 0) { 331 if(ioctl(fd, START_REC, 0) < 0) {
257 printf("Tuner Start Error\n"); 332 fprintf(stderr, "Tuner Start Error\n");
258 return 0 ; 333 return 1;
259 } 334 }
260 335
261 time(&start_time); 336 time(&start_time);
262 337
263 /* read from tuner */ 338 /* read from tuner */
265 time(&cur_time); 340 time(&cur_time);
266 bufptr = malloc(sizeof(BUFSZ)); 341 bufptr = malloc(sizeof(BUFSZ));
267 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); 342 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE);
268 if(bufptr->size <= 0) { 343 if(bufptr->size <= 0) {
269 if((cur_time - start_time) >= recsec) { 344 if((cur_time - start_time) >= recsec) {
270 f_exit = TRUE ; 345 f_exit = TRUE;
271 enqueue(p_queue, NULL); 346 enqueue(p_queue, NULL);
272 break ; 347 break;
273 } else { 348 } else {
274 continue ; 349 continue;
275 } 350 }
276 } 351 }
277 enqueue(p_queue, bufptr); 352 enqueue(p_queue, bufptr);
278 353
279 /* stop recording */ 354 /* stop recording */
282 /* read remaining data */ 357 /* read remaining data */
283 while(1) { 358 while(1) {
284 bufptr = malloc(sizeof(BUFSZ)); 359 bufptr = malloc(sizeof(BUFSZ));
285 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); 360 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE);
286 if(bufptr->size <= 0) { 361 if(bufptr->size <= 0) {
287 f_exit = TRUE ; 362 f_exit = TRUE;
288 enqueue(p_queue, NULL); 363 enqueue(p_queue, NULL);
289 break ; 364 break;
290 } 365 }
291 enqueue(p_queue, bufptr); 366 enqueue(p_queue, bufptr);
292 } 367 }
293 break ; 368 break;
294 } 369 }
295 } 370 }
296 /* close tuner */ 371 /* close tuner */
297 close(fd); 372 close(fd);
298 373
299 /* wait reading thread */ 374 /* wait reading thread */
300 pthread_join(dequeue_threads, NULL); 375 pthread_join(dequeue_threads, NULL);
301 destroy_queue(p_queue); 376 destroy_queue(p_queue);
302 377
303 /* release decoder */ 378 /* release decoder */
304 b25_shutdown(dec); 379 if(use_b25) {
305 380 b25_shutdown(dec);
306 return 0 ; 381 }
307 } 382
383 return 0;
384 }