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