Mercurial > pt1
comparison recpt1/recpt1.c @ 140:c9b1d21c5035
separate common function to core library
author | Yoshiki Yazawa <yaz@honeyplanet.jp> |
---|---|
date | Thu, 25 Apr 2013 16:06:15 +0900 |
parents | 61ff9cabf962 |
children | 1e7718cc2556 |
comparison
equal
deleted
inserted
replaced
139:61ff9cabf962 | 140:c9b1d21c5035 |
---|---|
18 | 18 |
19 #include <netdb.h> | 19 #include <netdb.h> |
20 #include <arpa/inet.h> | 20 #include <arpa/inet.h> |
21 #include <netinet/in.h> | 21 #include <netinet/in.h> |
22 | 22 |
23 #include <sys/ipc.h> | |
24 #include <sys/msg.h> | |
25 | |
23 #include <sys/ioctl.h> | 26 #include <sys/ioctl.h> |
24 #include "pt1_ioctl.h" | 27 #include "pt1_ioctl.h" |
25 | 28 |
26 #include "config.h" | 29 #include "config.h" |
27 #include "decoder.h" | 30 #include "decoder.h" |
31 #include "recpt1core.h" | |
28 #include "recpt1.h" | 32 #include "recpt1.h" |
29 #include "version.h" | |
30 #include "mkpath.h" | 33 #include "mkpath.h" |
31 | 34 |
32 #include <sys/ipc.h> | |
33 #include <sys/msg.h> | |
34 #include "pt1_dev.h" | |
35 #include "tssplitter_lite.h" | 35 #include "tssplitter_lite.h" |
36 | 36 |
37 /* maximum write length at once */ | 37 /* maximum write length at once */ |
38 #define SIZE_CHANK 1316 | 38 #define SIZE_CHANK 1316 |
39 | 39 |
40 /* ipc message size */ | 40 /* ipc message size */ |
41 #define MSGSZ 255 | 41 #define MSGSZ 255 |
42 | 42 |
43 #define ISDB_T_NODE_LIMIT 24 // 32:ARIB limit 24:program maximum | |
44 #define ISDB_T_SLOT_LIMIT 8 | |
45 | |
46 /* type definitions */ | |
47 typedef int boolean; | |
48 | |
49 typedef struct sock_data { | |
50 int sfd; /* socket fd */ | |
51 struct sockaddr_in addr; | |
52 } sock_data; | |
53 | |
54 typedef struct thread_data { | |
55 QUEUE_T *queue; | |
56 decoder *decoder; | |
57 decoder_options *dopt; | |
58 int ch; | |
59 int lnb; /* LNB voltage */ | |
60 int tfd; /* tuner fd */ | |
61 int wfd; /* output file fd */ | |
62 ISDB_T_FREQ_CONV_TABLE *table; | |
63 sock_data *sock_data; | |
64 pthread_t signal_thread; | |
65 int recsec; | |
66 time_t start_time; | |
67 boolean indefinite; | |
68 int msqid; | |
69 splitter *splitter; | |
70 } thread_data; | |
71 | |
72 typedef struct msgbuf { | |
73 long mtype; | |
74 char mtext[MSGSZ]; | |
75 } message_buf; | |
76 | |
77 /* globals */ | 43 /* globals */ |
78 boolean f_exit = FALSE; | 44 extern boolean f_exit; |
79 char bs_channel_buf[8]; | 45 |
80 ISDB_T_FREQ_CONV_TABLE isdb_t_conv_set = { 0, CHTYPE_SATELLITE, 0, bs_channel_buf }; | 46 |
81 | 47 /* will be ipc message receive thread */ |
82 /* prototypes */ | |
83 ISDB_T_FREQ_CONV_TABLE *searchrecoff(char *channel); | |
84 void calc_cn(int fd, int type); | |
85 int tune(char *channel, thread_data *tdata, char *device); | |
86 int close_tuner(thread_data *tdata); | |
87 | |
88 | |
89 /* ipc message receive */ | |
90 void * | 48 void * |
91 mq_recv(void *t) | 49 mq_recv(void *t) |
92 { | 50 { |
93 thread_data *tdata = (thread_data *)t; | 51 thread_data *tdata = (thread_data *)t; |
94 message_buf rbuf; | 52 message_buf rbuf; |
95 char channel[16]; | 53 char channel[16]; |
96 int ch = 0, recsec = 0, time_to_add = 0; | 54 int recsec = 0, time_to_add = 0; |
97 | 55 |
98 while(1) { | 56 while(1) { |
99 if(msgrcv(tdata->msqid, &rbuf, MSGSZ, 1, 0) < 0) { | 57 if(msgrcv(tdata->msqid, &rbuf, MSGSZ, 1, 0) < 0) { |
100 return NULL; | 58 return NULL; |
101 } | 59 } |
102 | 60 |
103 sscanf(rbuf.mtext, "ch=%s t=%d e=%d", channel, &recsec, &time_to_add); | 61 sscanf(rbuf.mtext, "ch=%s t=%d e=%d", channel, &recsec, &time_to_add); |
104 ch = atoi(channel); | 62 |
105 // fprintf(stderr, "ch=%d time=%d extend=%d\n", ch, recsec, time_to_add); | 63 if(strcmp(channel, tdata->table->parm_freq)) { |
106 | |
107 if(ch && tdata->ch != ch) { | |
108 #if 0 | |
109 /* re-initialize decoder */ | |
110 if(tdata->decoder) { | |
111 // b25_finish(tdata->decoder); | |
112 b25_shutdown(tdata->decoder); | |
113 tdata->decoder = b25_startup(tdata->dopt); | |
114 if(!tdata->decoder) { | |
115 fprintf(stderr, "Cannot start b25 decoder\n"); | |
116 fprintf(stderr, "Fall back to encrypted recording\n"); | |
117 } | |
118 } | |
119 #endif | |
120 int current_type = tdata->table->type; | 64 int current_type = tdata->table->type; |
121 ISDB_T_FREQ_CONV_TABLE *table = searchrecoff(channel); | 65 ISDB_T_FREQ_CONV_TABLE *table = searchrecoff(channel); |
122 if (table == NULL) { | 66 if (table == NULL) { |
123 fprintf(stderr, "Invalid Channel: %s\n", channel); | 67 fprintf(stderr, "Invalid Channel: %s\n", channel); |
124 goto CHECK_TIME_TO_ADD; | 68 goto CHECK_TIME_TO_ADD; |
145 .frequencyno = tdata->table->set_freq, | 89 .frequencyno = tdata->table->set_freq, |
146 .slot = tdata->table->add_freq, | 90 .slot = tdata->table->add_freq, |
147 }; | 91 }; |
148 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { | 92 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { |
149 fprintf(stderr, "Cannot tune to the specified channel\n"); | 93 fprintf(stderr, "Cannot tune to the specified channel\n"); |
150 tdata->ch = 0; | |
151 goto CHECK_TIME_TO_ADD; | 94 goto CHECK_TIME_TO_ADD; |
152 } | 95 } |
153 tdata->ch = ch; | 96 calc_cn(tdata->tfd, tdata->table->type, FALSE); |
154 calc_cn(tdata->tfd, tdata->table->type); | |
155 } | 97 } |
156 /* restart recording */ | 98 /* restart recording */ |
157 if(ioctl(tdata->tfd, START_REC, 0) < 0) { | 99 if(ioctl(tdata->tfd, START_REC, 0) < 0) { |
158 fprintf(stderr, "Tuner cannot start recording\n"); | 100 fprintf(stderr, "Tuner cannot start recording\n"); |
159 return NULL; | 101 return NULL; |
181 if(f_exit) | 123 if(f_exit) |
182 return NULL; | 124 return NULL; |
183 } | 125 } |
184 } | 126 } |
185 | 127 |
186 | |
187 /* lookup frequency conversion table*/ | |
188 ISDB_T_FREQ_CONV_TABLE * | |
189 searchrecoff(char *channel) | |
190 { | |
191 int lp; | |
192 | |
193 if(channel[0] == 'B' && channel[1] == 'S') { | |
194 int node = 0; | |
195 int slot = 0; | |
196 char *bs_ch; | |
197 | |
198 bs_ch = channel + 2; | |
199 while(isdigit(*bs_ch)) { | |
200 node *= 10; | |
201 node += *bs_ch++ - '0'; | |
202 } | |
203 if(*bs_ch == '_' && (node&0x01) && node < ISDB_T_NODE_LIMIT) { | |
204 if(isdigit(*++bs_ch)) { | |
205 slot = *bs_ch - '0'; | |
206 if(*++bs_ch == '\0' && slot < ISDB_T_SLOT_LIMIT) { | |
207 isdb_t_conv_set.set_freq = node / 2; | |
208 isdb_t_conv_set.add_freq = slot; | |
209 sprintf(bs_channel_buf, "BS%d_%d", node, slot); | |
210 return &isdb_t_conv_set; | |
211 } | |
212 } | |
213 } | |
214 return NULL; | |
215 } | |
216 for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++) { | |
217 /* return entry number in the table when strings match and | |
218 * lengths are same. */ | |
219 if((memcmp(isdb_t_conv_table[lp].parm_freq, channel, | |
220 strlen(channel)) == 0) && | |
221 (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))) { | |
222 return &isdb_t_conv_table[lp]; | |
223 } | |
224 } | |
225 return NULL; | |
226 } | |
227 | 128 |
228 QUEUE_T * | 129 QUEUE_T * |
229 create_queue(size_t size) | 130 create_queue(size_t size) |
230 { | 131 { |
231 QUEUE_T *p_queue; | 132 QUEUE_T *p_queue; |
353 | 254 |
354 /* this function will be reader thread */ | 255 /* this function will be reader thread */ |
355 void * | 256 void * |
356 reader_func(void *p) | 257 reader_func(void *p) |
357 { | 258 { |
358 thread_data *data = (thread_data *)p; | 259 thread_data *tdata = (thread_data *)p; |
359 QUEUE_T *p_queue = data->queue; | 260 QUEUE_T *p_queue = tdata->queue; |
360 decoder *dec = data->decoder; | 261 decoder *dec = tdata->decoder; |
361 splitter *splitter = data->splitter; | 262 splitter *splitter = tdata->splitter; |
362 int wfd = data->wfd; | 263 int wfd = tdata->wfd; |
363 boolean use_b25 = dec ? TRUE : FALSE; | 264 boolean use_b25 = dec ? TRUE : FALSE; |
364 boolean use_udp = data->sock_data ? TRUE : FALSE; | 265 boolean use_udp = tdata->sock_data ? TRUE : FALSE; |
365 boolean fileless = FALSE; | 266 boolean fileless = FALSE; |
366 boolean use_splitter = splitter ? TRUE : FALSE; | 267 boolean use_splitter = splitter ? TRUE : FALSE; |
367 int sfd = -1; | 268 int sfd = -1; |
368 pthread_t signal_thread = data->signal_thread; | 269 pthread_t signal_thread = tdata->signal_thread; |
369 struct sockaddr_in *addr = NULL; | 270 struct sockaddr_in *addr = NULL; |
370 BUFSZ *qbuf; | 271 BUFSZ *qbuf; |
371 static splitbuf_t splitbuf; | 272 static splitbuf_t splitbuf; |
372 ARIB_STD_B25_BUFFER sbuf, dbuf, buf; | 273 ARIB_STD_B25_BUFFER sbuf, dbuf, buf; |
373 int code; | 274 int code; |
380 | 281 |
381 if(wfd == -1) | 282 if(wfd == -1) |
382 fileless = TRUE; | 283 fileless = TRUE; |
383 | 284 |
384 if(use_udp) { | 285 if(use_udp) { |
385 sfd = data->sock_data->sfd; | 286 sfd = tdata->sock_data->sfd; |
386 addr = &data->sock_data->addr; | 287 addr = &tdata->sock_data->addr; |
387 } | 288 } |
388 | 289 |
389 while(1) { | 290 while(1) { |
390 ssize_t wc = 0; | 291 ssize_t wc = 0; |
391 int file_err = 0; | 292 int file_err = 0; |
438 /* $BJ,N%BP>](BPID$B$,40A4$KCj=P$G$-$k$^$G=PNO$7$J$$(B | 339 /* $BJ,N%BP>](BPID$B$,40A4$KCj=P$G$-$k$^$G=PNO$7$J$$(B |
439 * 1$BICDxEYM>M5$r8+$k$H$$$$$+$b(B | 340 * 1$BICDxEYM>M5$r8+$k$H$$$$$+$b(B |
440 */ | 341 */ |
441 time_t cur_time; | 342 time_t cur_time; |
442 time(&cur_time); | 343 time(&cur_time); |
443 if(cur_time - data->start_time > 4) { | 344 if(cur_time - tdata->start_time > 4) { |
444 use_splitter = FALSE; | 345 use_splitter = FALSE; |
445 goto fin; | 346 goto fin; |
446 } | 347 } |
447 break; | 348 break; |
448 } | 349 } |
567 } | 468 } |
568 | 469 |
569 time_t cur_time; | 470 time_t cur_time; |
570 time(&cur_time); | 471 time(&cur_time); |
571 fprintf(stderr, "Recorded %dsec\n", | 472 fprintf(stderr, "Recorded %dsec\n", |
572 (int)(cur_time - data->start_time)); | 473 (int)(cur_time - tdata->start_time)); |
573 | 474 |
574 return NULL; | 475 return NULL; |
575 } | 476 } |
576 | 477 |
577 void | 478 void |
608 fprintf(stderr, "--version: Show version\n"); | 509 fprintf(stderr, "--version: Show version\n"); |
609 fprintf(stderr, "--list: Show channel list\n"); | 510 fprintf(stderr, "--list: Show channel list\n"); |
610 } | 511 } |
611 | 512 |
612 void | 513 void |
613 show_channels(void) | |
614 { | |
615 FILE *f; | |
616 char *home; | |
617 char buf[255], filename[255]; | |
618 | |
619 fprintf(stderr, "Available Channels:\n"); | |
620 | |
621 home = getenv("HOME"); | |
622 sprintf(filename, "%s/.recpt1-channels", home); | |
623 f = fopen(filename, "r"); | |
624 if(f) { | |
625 while(fgets(buf, 255, f)) | |
626 fprintf(stderr, "%s", buf); | |
627 fclose(f); | |
628 } | |
629 else | |
630 fprintf(stderr, "13-62: Terrestrial Channels\n"); | |
631 | |
632 fprintf(stderr, "101ch: NHK BS1\n"); | |
633 fprintf(stderr, "102ch: NHK BS2\n"); | |
634 fprintf(stderr, "103ch: NHK BShi\n"); | |
635 fprintf(stderr, "141ch: BS Nittele\n"); | |
636 fprintf(stderr, "151ch: BS Asahi\n"); | |
637 fprintf(stderr, "161ch: BS-TBS\n"); | |
638 fprintf(stderr, "171ch: BS Japan\n"); | |
639 fprintf(stderr, "181ch: BS Fuji\n"); | |
640 fprintf(stderr, "191ch: WOWOW\n"); | |
641 fprintf(stderr, "192ch: WOWOW2\n"); | |
642 fprintf(stderr, "193ch: WOWOW3\n"); | |
643 fprintf(stderr, "200ch: Star Channel\n"); | |
644 fprintf(stderr, "211ch: BS11 Digital\n"); | |
645 fprintf(stderr, "222ch: TwellV\n"); | |
646 fprintf(stderr, "C13-C63: CATV Channels\n"); | |
647 fprintf(stderr, "CS2-CS24: CS Channels\n"); | |
648 } | |
649 | |
650 float | |
651 getsignal_isdb_s(int signal) | |
652 { | |
653 /* apply linear interpolation */ | |
654 static const float afLevelTable[] = { | |
655 24.07f, // 00 00 0 24.07dB | |
656 24.07f, // 10 00 4096 24.07dB | |
657 18.61f, // 20 00 8192 18.61dB | |
658 15.21f, // 30 00 12288 15.21dB | |
659 12.50f, // 40 00 16384 12.50dB | |
660 10.19f, // 50 00 20480 10.19dB | |
661 8.140f, // 60 00 24576 8.140dB | |
662 6.270f, // 70 00 28672 6.270dB | |
663 4.550f, // 80 00 32768 4.550dB | |
664 3.730f, // 88 00 34816 3.730dB | |
665 3.630f, // 88 FF 35071 3.630dB | |
666 2.940f, // 90 00 36864 2.940dB | |
667 1.420f, // A0 00 40960 1.420dB | |
668 0.000f // B0 00 45056 -0.01dB | |
669 }; | |
670 | |
671 unsigned char sigbuf[4]; | |
672 memset(sigbuf, '\0', sizeof(sigbuf)); | |
673 sigbuf[0] = (((signal & 0xFF00) >> 8) & 0XFF); | |
674 sigbuf[1] = (signal & 0xFF); | |
675 | |
676 /* calculate signal level */ | |
677 if(sigbuf[0] <= 0x10U) { | |
678 /* clipped maximum */ | |
679 return 24.07f; | |
680 } | |
681 else if (sigbuf[0] >= 0xB0U) { | |
682 /* clipped minimum */ | |
683 return 0.0f; | |
684 } | |
685 else { | |
686 /* linear interpolation */ | |
687 const float fMixRate = | |
688 (float)(((unsigned short)(sigbuf[0] & 0x0FU) << 8) | | |
689 (unsigned short)sigbuf[0]) / 4096.0f; | |
690 return afLevelTable[sigbuf[0] >> 4] * (1.0f - fMixRate) + | |
691 afLevelTable[(sigbuf[0] >> 4) + 0x01U] * fMixRate; | |
692 } | |
693 } | |
694 | |
695 void | |
696 calc_cn(int fd, int type) | |
697 { | |
698 int rc ; | |
699 double P ; | |
700 double CNR; | |
701 | |
702 if(ioctl(fd, GET_SIGNAL_STRENGTH, &rc) < 0) { | |
703 fprintf(stderr, "Tuner Select Error\n"); | |
704 return ; | |
705 } | |
706 | |
707 if(type == CHTYPE_GROUND) { | |
708 P = log10(5505024/(double)rc) * 10; | |
709 CNR = (0.000024 * P * P * P * P) - (0.0016 * P * P * P) + | |
710 (0.0398 * P * P) + (0.5491 * P)+3.0965; | |
711 fprintf(stderr, "C/N = %fdB\n", CNR); | |
712 } | |
713 else { | |
714 CNR = getsignal_isdb_s(rc); | |
715 fprintf(stderr, "C/N = %fdB\n", CNR); | |
716 } | |
717 } | |
718 | |
719 void | |
720 cleanup(thread_data *tdata) | 514 cleanup(thread_data *tdata) |
721 { | 515 { |
722 /* stop recording */ | 516 /* stop recording */ |
723 ioctl(tdata->tfd, STOP_REC, 0); | 517 ioctl(tdata->tfd, STOP_REC, 0); |
724 | 518 |
725 /* xxx need mutex? */ | |
726 f_exit = TRUE; | 519 f_exit = TRUE; |
727 | 520 |
728 pthread_cond_signal(&tdata->queue->cond_avail); | 521 pthread_cond_signal(&tdata->queue->cond_avail); |
729 pthread_cond_signal(&tdata->queue->cond_used); | 522 pthread_cond_signal(&tdata->queue->cond_used); |
730 } | 523 } |
731 | 524 |
732 /* will be signal handler thread */ | 525 /* will be signal handler thread */ |
733 void * | 526 void * |
734 process_signals(void *data) | 527 process_signals(void *t) |
735 { | 528 { |
736 sigset_t waitset; | 529 sigset_t waitset; |
737 int sig; | 530 int sig; |
738 thread_data *tdata = (thread_data *)data; | 531 thread_data *tdata = (thread_data *)t; |
739 | 532 |
740 sigemptyset(&waitset); | 533 sigemptyset(&waitset); |
741 sigaddset(&waitset, SIGPIPE); | 534 sigaddset(&waitset, SIGPIPE); |
742 sigaddset(&waitset, SIGINT); | 535 sigaddset(&waitset, SIGINT); |
743 sigaddset(&waitset, SIGTERM); | 536 sigaddset(&waitset, SIGTERM); |
788 | 581 |
789 pthread_create(signal_thread, NULL, process_signals, tdata); | 582 pthread_create(signal_thread, NULL, process_signals, tdata); |
790 } | 583 } |
791 | 584 |
792 int | 585 int |
793 tune(char *channel, thread_data *tdata, char *device) | |
794 { | |
795 char **tuner; | |
796 int num_devs; | |
797 int lp; | |
798 FREQUENCY freq; | |
799 | |
800 /* get channel */ | |
801 tdata->table = searchrecoff(channel); | |
802 if(tdata->table == NULL) { | |
803 fprintf(stderr, "Invalid Channel: %s\n", channel); | |
804 return 1; | |
805 } | |
806 | |
807 freq.frequencyno = tdata->table->set_freq; | |
808 freq.slot = tdata->table->add_freq; | |
809 | |
810 /* open tuner */ | |
811 /* case 1: specified tuner device */ | |
812 if(device) { | |
813 tdata->tfd = open(device, O_RDONLY); | |
814 if(tdata->tfd < 0) { | |
815 fprintf(stderr, "Cannot open tuner device: %s\n", device); | |
816 return 1; | |
817 } | |
818 | |
819 /* power on LNB */ | |
820 if(tdata->table->type == CHTYPE_SATELLITE) { | |
821 if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) { | |
822 fprintf(stderr, "Power on LNB failed: %s\n", device); | |
823 } | |
824 } | |
825 | |
826 /* tune to specified channel */ | |
827 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { | |
828 close(tdata->tfd); | |
829 fprintf(stderr, "Cannot tune to the specified channel: %s\n", device); | |
830 return 1; | |
831 } | |
832 else { | |
833 tdata->ch = atoi(channel); | |
834 } | |
835 } | |
836 else { | |
837 /* case 2: loop around available devices */ | |
838 if(tdata->table->type == CHTYPE_SATELLITE) { | |
839 tuner = bsdev; | |
840 num_devs = NUM_BSDEV; | |
841 } | |
842 else { | |
843 tuner = isdb_t_dev; | |
844 num_devs = NUM_ISDB_T_DEV; | |
845 } | |
846 | |
847 for(lp = 0; lp < num_devs; lp++) { | |
848 tdata->tfd = open(tuner[lp], O_RDONLY); | |
849 if(tdata->tfd >= 0) { | |
850 /* power on LNB */ | |
851 if(tdata->table->type == CHTYPE_SATELLITE) { | |
852 if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) { | |
853 fprintf(stderr, "Warning: Power on LNB failed: %s\n", tuner[lp]); | |
854 } | |
855 } | |
856 | |
857 /* tune to specified channel */ | |
858 if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { | |
859 close(tdata->tfd); | |
860 tdata->tfd = -1; | |
861 continue; | |
862 } | |
863 | |
864 break; /* found suitable tuner */ | |
865 } | |
866 } | |
867 | |
868 /* all tuners cannot be used */ | |
869 if(tdata->tfd < 0) { | |
870 fprintf(stderr, "Cannot tune to the specified channel\n"); | |
871 return 1; | |
872 } | |
873 else { | |
874 tdata->ch = atoi(channel); | |
875 } | |
876 } | |
877 | |
878 /* show signal strength */ | |
879 calc_cn(tdata->tfd, tdata->table->type); | |
880 | |
881 return 0; /* success */ | |
882 } | |
883 | |
884 int | |
885 parse_time(char *rectimestr, thread_data *tdata) | |
886 { | |
887 /* indefinite */ | |
888 if(!strcmp("-", rectimestr)) { | |
889 tdata->indefinite = TRUE; | |
890 tdata->recsec = -1; | |
891 } | |
892 /* colon */ | |
893 else if(strchr(rectimestr, ':')) { | |
894 int n1, n2, n3; | |
895 if(sscanf(rectimestr, "%d:%d:%d", &n1, &n2, &n3) == 3) | |
896 tdata->recsec = n1 * 3600 + n2 * 60 + n3; | |
897 else if(sscanf(rectimestr, "%d:%d", &n1, &n2) == 2) | |
898 tdata->recsec = n1 * 3600 + n2 * 60; | |
899 } | |
900 /* HMS */ | |
901 else { | |
902 char *tmpstr; | |
903 char *p1, *p2; | |
904 | |
905 tmpstr = strdup(rectimestr); | |
906 p1 = tmpstr; | |
907 while(*p1 && !isdigit(*p1)) | |
908 p1++; | |
909 | |
910 /* hour */ | |
911 if((p2 = strchr(p1, 'H')) || (p2 = strchr(p1, 'h'))) { | |
912 *p2 = '\0'; | |
913 tdata->recsec += atoi(p1) * 3600; | |
914 p1 = p2 + 1; | |
915 while(*p1 && !isdigit(*p1)) | |
916 p1++; | |
917 } | |
918 | |
919 /* minute */ | |
920 if((p2 = strchr(p1, 'M')) || (p2 = strchr(p1, 'm'))) { | |
921 *p2 = '\0'; | |
922 tdata->recsec += atoi(p1) * 60; | |
923 p1 = p2 + 1; | |
924 while(*p1 && !isdigit(*p1)) | |
925 p1++; | |
926 } | |
927 | |
928 /* second */ | |
929 tdata->recsec += atoi(p1); | |
930 | |
931 free(tmpstr); | |
932 } | |
933 | |
934 return 0; /* success */ | |
935 } | |
936 | |
937 int | |
938 close_tuner(thread_data *tdata) | |
939 { | |
940 int rv = 0; | |
941 | |
942 if(tdata->table->type == CHTYPE_SATELLITE) { | |
943 if(ioctl(tdata->tfd, LNB_DISABLE, 0) < 0) { | |
944 rv = 1; | |
945 } | |
946 } | |
947 close(tdata->tfd); | |
948 | |
949 return rv; | |
950 } | |
951 | |
952 int | |
953 main(int argc, char **argv) | 586 main(int argc, char **argv) |
954 { | 587 { |
955 time_t cur_time; | 588 time_t cur_time; |
956 pthread_t signal_thread; | 589 pthread_t signal_thread; |
957 pthread_t reader_thread; | 590 pthread_t reader_thread; |
958 pthread_t ipc_thread; | 591 pthread_t ipc_thread; |
959 QUEUE_T *p_queue = create_queue(MAX_QUEUE); | 592 QUEUE_T *p_queue = create_queue(MAX_QUEUE); |
960 BUFSZ *bufptr; | 593 BUFSZ *bufptr; |
961 decoder *dec = NULL; | 594 decoder *decoder = NULL; |
962 splitter *splitter = NULL; | 595 splitter *splitter = NULL; |
963 static thread_data tdata; | 596 static thread_data tdata; |
964 decoder_options dopt = { | 597 decoder_options dopt = { |
965 4, /* round */ | 598 4, /* round */ |
966 0, /* strip */ | 599 0, /* strip */ |
1103 /* tune */ | 736 /* tune */ |
1104 if(tune(argv[optind], &tdata, device) != 0) | 737 if(tune(argv[optind], &tdata, device) != 0) |
1105 return 1; | 738 return 1; |
1106 | 739 |
1107 /* set recsec */ | 740 /* set recsec */ |
1108 if(parse_time(argv[optind + 1], &tdata) != 0) | 741 if(parse_time(argv[optind + 1], &tdata.recsec) != 0) // no other thread --yaz |
1109 return 1; | 742 return 1; |
743 | |
744 if(tdata.recsec == -1) | |
745 tdata.indefinite = TRUE; | |
1110 | 746 |
1111 /* open output file */ | 747 /* open output file */ |
1112 char *destfile = argv[optind + 2]; | 748 char *destfile = argv[optind + 2]; |
1113 if(destfile && !strcmp("-", destfile)) { | 749 if(destfile && !strcmp("-", destfile)) { |
1114 use_stdout = TRUE; | 750 use_stdout = TRUE; |
1133 } | 769 } |
1134 } | 770 } |
1135 | 771 |
1136 /* initialize decoder */ | 772 /* initialize decoder */ |
1137 if(use_b25) { | 773 if(use_b25) { |
1138 dec = b25_startup(&dopt); | 774 decoder = b25_startup(&dopt); |
1139 if(!dec) { | 775 if(!decoder) { |
1140 fprintf(stderr, "Cannot start b25 decoder\n"); | 776 fprintf(stderr, "Cannot start b25 decoder\n"); |
1141 fprintf(stderr, "Fall back to encrypted recording\n"); | 777 fprintf(stderr, "Fall back to encrypted recording\n"); |
1142 use_b25 = FALSE; | 778 use_b25 = FALSE; |
1143 } | 779 } |
1144 } | 780 } |
1180 } | 816 } |
1181 } | 817 } |
1182 | 818 |
1183 /* prepare thread data */ | 819 /* prepare thread data */ |
1184 tdata.queue = p_queue; | 820 tdata.queue = p_queue; |
1185 tdata.decoder = dec; | 821 tdata.decoder = decoder; |
1186 tdata.splitter = splitter; | 822 tdata.splitter = splitter; |
1187 tdata.sock_data = sockdata; | 823 tdata.sock_data = sockdata; |
824 tdata.tune_persistent = FALSE; | |
1188 | 825 |
1189 /* spawn signal handler thread */ | 826 /* spawn signal handler thread */ |
1190 init_signal_handlers(&signal_thread, &tdata); | 827 init_signal_handlers(&signal_thread, &tdata); |
1191 | 828 |
1192 /* spawn reader thread */ | 829 /* spawn reader thread */ |
1206 if(ioctl(tdata.tfd, START_REC, 0) < 0) { | 843 if(ioctl(tdata.tfd, START_REC, 0) < 0) { |
1207 fprintf(stderr, "Tuner cannot start recording\n"); | 844 fprintf(stderr, "Tuner cannot start recording\n"); |
1208 return 1; | 845 return 1; |
1209 } | 846 } |
1210 | 847 |
1211 fprintf(stderr, "Recording...\n"); | 848 fprintf(stderr, "\nRecording...\n"); |
1212 | 849 |
1213 time(&tdata.start_time); | 850 time(&tdata.start_time); |
1214 | 851 |
1215 /* read from tuner */ | 852 /* read from tuner */ |
1216 while(1) { | 853 while(1) { |
1287 free(sockdata); | 924 free(sockdata); |
1288 } | 925 } |
1289 | 926 |
1290 /* release decoder */ | 927 /* release decoder */ |
1291 if(use_b25) { | 928 if(use_b25) { |
1292 b25_shutdown(dec); | 929 b25_shutdown(decoder); |
1293 } | 930 } |
1294 if(use_splitter) { | 931 if(use_splitter) { |
1295 split_shutdown(splitter); | 932 split_shutdown(splitter); |
1296 } | 933 } |
1297 | 934 |