diff recpt1/recpt1.c @ 13:003fe2470af8

reorganized options: - 0 as recsec means indefinite recording. - now --udp option works as switch to enable udp broadcasting. - --host option has been added. this option specifies hostname to connect via udp socket. - when --udp option is specified, output file may not be specified.
author Yoshiki Yazawa <yaz@honeyplanet.jp>
date Tue, 24 Feb 2009 17:22:06 +0900
parents 4615eaf04415
children cad940a903f5
line wrap: on
line diff
--- a/recpt1/recpt1.c	Tue Feb 24 17:16:05 2009 +0900
+++ b/recpt1/recpt1.c	Tue Feb 24 17:22:06 2009 +0900
@@ -151,75 +151,134 @@
     QUEUE_T *p_queue = data->queue;
     decoder *dec = data->decoder;
     int wfd = data->wfd;
-    int use_b25 = dec ? 1 : 0;
-    int use_udp = data->sock_data ? 1 : 0;
-    int sfd = 0;
+    int use_b25 = dec ? TRUE : FALSE;
+    int use_udp = data->sock_data ? TRUE : FALSE;
+    int fileless = FALSE;
+    int sfd = -1;
     struct sockaddr *addr = NULL;
     BUFSZ *buf;
     ARIB_STD_B25_BUFFER sbuf, dbuf;
     int code;
 
+    if(wfd == -1)
+        fileless = TRUE;
+
     if(use_udp) {
         sfd = data->sock_data->sfd;
         addr = (struct sockaddr *)&data->sock_data->addr;
     }
 
     while(1) {
-        buf = dequeue(p_queue);
-        /* no entry in the queue */
-        if(buf == NULL){
-            close(wfd);
-            break;
-        }
+
+        if(fileless) {
+
+            buf = dequeue(p_queue);
+            /* no entry in the queue */
+            if(buf == NULL) {
+                break;
+            }
+
+            sbuf.data = buf->buffer;
+            sbuf.size = buf->size;
+
+            if(use_b25) {
+                /* write data to output file*/
+                code = b25_decode(dec, &sbuf, &dbuf);
+                if(code < 0) {
+                    fprintf(stderr, "b25_decode failed\n");
+                    break;
+                }
 
-        sbuf.data = buf->buffer;
-        sbuf.size = buf->size;
+                if(use_udp && sfd != -1) {
+                    sendto(sfd, dbuf.data, dbuf.size, 0,
+                           addr, sizeof(struct sockaddr_in));
+                }
+                free(buf);
+            } else {
+                if(use_udp && sfd != -1) {
+                    sendto(sfd, sbuf.data, sbuf.size, 0,
+                           addr, sizeof(struct sockaddr_in));
+                }
+                free(buf);
+            }
 
-        if(use_b25) {
-            /* write data to output file*/
-            code = b25_decode(dec, &sbuf, &dbuf);
-            if(code < 0) {
-                fprintf(stderr, "b25_decode failed\n");
+            /* normal exit */
+            if((f_exit) && (!p_queue->no_empty)) {
+                if(use_b25) {
+                    code = b25_finish(dec, &sbuf, &dbuf);
+                    if(code < 0) {
+                        fprintf(stderr, "b25_finish failed\n");
+                        close(sfd);
+                        break;
+                    }
+
+                    if(use_udp && sfd != -1) {
+                        sendto(sfd, dbuf.data, dbuf.size, 0,
+                               addr, sizeof(struct sockaddr_in));
+                    }
+                }
+                close(sfd);
+                break;
+            }
+        } /* fileless */
+        else {
+
+            buf = dequeue(p_queue);
+            /* no entry in the queue */
+            if(buf == NULL) {
                 close(wfd);
                 break;
             }
-            write(wfd, dbuf.data, dbuf.size);
 
-            if(use_udp && sfd) {
-                sendto(sfd, dbuf.data, dbuf.size, 0,
-                       addr, sizeof(struct sockaddr_in));
-            }
-            free(buf);
-        } else {
-            write(wfd, sbuf.data, sbuf.size);
+            sbuf.data = buf->buffer;
+            sbuf.size = buf->size;
 
-            if(use_udp && sfd) {
-                sendto(sfd, sbuf.data, sbuf.size, 0,
-                       addr, sizeof(struct sockaddr_in));
-            }
-            free(buf);
-        }
-
-        /* normal exit */
-        if((f_exit) && (!p_queue->no_empty)) {
             if(use_b25) {
-                code = b25_finish(dec, &sbuf, &dbuf);
+                /* write data to output file*/
+                code = b25_decode(dec, &sbuf, &dbuf);
                 if(code < 0) {
-                    fprintf(stderr, "b25_finish failed\n");
+                    fprintf(stderr, "b25_decode failed\n");
                     close(wfd);
-                    close(sfd);
                     break;
                 }
                 write(wfd, dbuf.data, dbuf.size);
 
-                if(use_udp && sfd) {
+                if(use_udp && sfd != -1) {
                     sendto(sfd, dbuf.data, dbuf.size, 0,
                            addr, sizeof(struct sockaddr_in));
                 }
+                free(buf);
+            } else {
+                write(wfd, sbuf.data, sbuf.size);
+
+                if(use_udp && sfd != -1) {
+                    sendto(sfd, sbuf.data, sbuf.size, 0,
+                           addr, sizeof(struct sockaddr_in));
+                }
+                free(buf);
             }
-            close(wfd);
-            close(sfd);
-            break;
+
+            /* normal exit */
+            if((f_exit) && (!p_queue->no_empty)) {
+                if(use_b25) {
+                    code = b25_finish(dec, &sbuf, &dbuf);
+                    if(code < 0) {
+                        fprintf(stderr, "b25_finish failed\n");
+                        close(wfd);
+                        close(sfd);
+                        break;
+                    }
+                    write(wfd, dbuf.data, dbuf.size);
+
+                    if(use_udp && sfd != -1) {
+                        sendto(sfd, dbuf.data, dbuf.size, 0,
+                               addr, sizeof(struct sockaddr_in));
+                    }
+                }
+                close(wfd);
+                close(sfd);
+                break;
+            }
         }
     }
 
@@ -229,13 +288,32 @@
 void
 show_usage(char *cmd)
 {
-    fprintf(stderr, "Usage: %s [--b25 [--round N] [--strip] [--EMM]] [--udp hostname [--port port]] channel recsec destfile\n", cmd);
+    fprintf(stderr, "Usage: %s [--b25 [--round N] [--strip] [--EMM]] [--udp [--host hostname --port port]] channel recsec destfile\n", cmd);
+}
+
+void
+show_channels(void)
+{
+        printf("Channel List:\n");
+        printf("151ch:BS Asahi\n");
+        printf("161ch:BS-i\n");
+        printf("191ch:WOWOW\n");
+        printf("171ch:BS Japan\n");
+        printf("200ch:Star Channel\n");
+        printf("211ch:BS11 Digital\n");
+        printf("222ch:TwellV\n");
+        printf("141ch:BS Nittele\n");
+        printf("181ch:BS Fuji\n");
+        printf("101ch:NHK BS1\n");
+        printf("102ch:NHK BS2\n");
+        printf("103ch:NHK BShi\n");
+        printf("CS2-CS24:CS Channels\n");
 }
 
 float
 getsignal_isdb_s(int signal)
 {
-    // 線形補完で近似する
+    /* apply linear interpolation */
     static const float afLevelTable[] = {
         24.07f,    // 00    00    0        24.07dB
         24.07f,    // 10    00    4096     24.07dB
@@ -258,15 +336,15 @@
     sigbuf[0] =  (((signal & 0xFF00) >> 8) & 0XFF);
     sigbuf[1] =  (signal & 0xFF);
 
-    // 信号レベル計算
+    /* calculate signal level */
     if(sigbuf[0] <= 0x10U){
-        // 最大クリップ
+        /* clipped maximum */
         return 24.07f;
     } else if (sigbuf[0] >= 0xB0U) {
-        // 最小クリップ
+        /* clipped minimum */
         return 0.0f;
     } else {
-        // 線形補完
+        /* linear interpolation */
         const float fMixRate =
             (float)(((unsigned short)(sigbuf[0] & 0x0FU) << 8) |
                     (unsigned short)sigbuf[0]) / 4096.0f;
@@ -278,7 +356,6 @@
 void
 calc_cn(int fd, int type)
 {
-
     int     rc ;
     double  P ;
     double  CNR;
@@ -305,6 +382,7 @@
     int tfd, wfd;
     int lp;
     int recsec;
+    int indefinite = FALSE;
     time_t start_time, cur_time;
     FREQUENCY freq;
     ISDB_T_FREQ_CONV_TABLE *ptr;
@@ -328,42 +406,55 @@
         { "strip",     0, NULL, 's'},
         { "emm",       0, NULL, 'm'},
         { "EMM",       0, NULL, 'm'},
-        { "udp",       1, NULL, 'u'},
-        { "port",      1, NULL, 'p'}
+        { "udp",       0, NULL, 'u'},
+        { "host",      1, NULL, 'h'},
+        { "port",      1, NULL, 'p'},
+        {0, 0, 0, 0} /* terminate */
     };
 
-    int use_b25 = 0;
-    int use_udp = 0;
+    int use_b25 = FALSE;
+    int use_udp = FALSE;
+    int fileless = FALSE;
     char *host_to = NULL;
     int port_to = 1234;
     sock_data *sdata = NULL;
 
-    while((result = getopt_long(argc, argv, "br:sm" "u:p:", long_options, &option_index)) != -1) {
+    while((result = getopt_long(argc, argv, "br:smuh:p:", long_options, &option_index)) != -1) {
         switch(result) {
         case 'b':
-            use_b25 = 1;
+            use_b25 = TRUE;
             fprintf(stderr, "using B25...\n");
             break;
         case 's':
-            dopt.strip = 1;
+            dopt.strip = TRUE;
             fprintf(stderr, "enable B25 strip\n");
             break;
         case 'm':
-            dopt.emm = 1;
+            dopt.emm = TRUE;
             fprintf(stderr, "enable B25 emm processing\n");
             break;
+        case 'u':
+            use_udp = TRUE;
+            host_to = "localhost";
+            fprintf(stderr, "enable UDP broadcasting\n");
+            break;
+/*
+        case ':':
+            fprintf(stderr, "%c needs value\n", result);
+            break;
+*/
+        case '?':
+            show_usage(argv[0]);
+            break;
+
+
+        /* following options require argument */
         case 'r':
             dopt.round = atoi(optarg);
             fprintf(stderr, "set round %d\n", dopt.round);
             break;
-        case ':':
-            fprintf(stderr, "%c needs value\n", result);
-            break;
-        case '?':
-            show_usage(argv[0]);
-            break;
-        case 'u':
-            use_udp = 1;
+        case 'h':
+            use_udp = TRUE;
             host_to = optarg;
             fprintf(stderr, "UDP destination address: %s\n", host_to);
             break;
@@ -375,26 +466,22 @@
     }
 
     if(argc - optind < 3) {
-        show_usage(argv[0]);
-        printf("channel =\n");
-        printf("151ch:BS朝日\n");
-        printf("161ch:BS-i\n");
-        printf("191ch:WOWOW\n");
-        printf("171ch:BSジャパン\n");
-        printf("200ch:スターチャンネル\n");
-        printf("211ch:BS11デジタル\n");
-        printf("222ch:TwellV\n");
-        printf("141ch:BS日テレ\n");
-        printf("181ch:BSフジ\n");
-        printf("101ch:NHK衛星第1放送(BS1)\n");
-        printf("102ch:NHK衛星第2放送(BS2)\n");
-        printf("103ch:NHKハイビジョン(BShi)\n");
-        printf("CS2-CS24:CSチャンネル\n");
-        return 1;
+        if(argc - optind == 2 && use_udp) {
+            fprintf(stderr, "fileless udp broadcasting\n");
+            fileless = TRUE;
+            wfd = -1;
+        }
+        else {
+            show_usage(argv[0]);
+            show_channels();
+            return 1;
+        }
     }
+
+    /* get channel */
     ptr = searchrecoff(argv[optind]);
     if(ptr == NULL){
-        printf("Channel Select Error(%s)\n", argv[optind]);
+        fprintf(stderr, "Channel Select Error(%s)\n", argv[optind]);
         return 1;
     }
 
@@ -424,7 +511,11 @@
             return 1;
         }
     }
+
+    /* get recsec */
     recsec = atoi(argv[optind + 1]);
+    if(recsec == 0)
+        indefinite = TRUE;
 
     /* initialize decoder */
     if(use_b25) {
@@ -459,12 +550,13 @@
     }
 
     /* open output file */
-    wfd = open(argv[optind + 2], (O_RDWR | O_CREAT | O_TRUNC), 0666);
-    if(wfd < 0) {
-        fprintf(stderr, "Output File Open Error(%s)\n", argv[optind + 2]);
-        return 1;
+    if(!fileless) {
+        wfd = open(argv[optind + 2], (O_RDWR | O_CREAT | O_TRUNC), 0666);
+        if(wfd < 0) {
+            fprintf(stderr, "Output File Open Error(%s)\n", argv[optind + 2]);
+            return 1;
+        }
     }
-
     if(ptr->type == CHTYPE_SATELLITE){
         if(ioctl(tfd, LNB_ENABLE, 0) < 0){
             return 0 ;
@@ -499,7 +591,7 @@
         bufptr = malloc(sizeof(BUFSZ));
         bufptr->size = read(tfd, bufptr->buffer, MAX_READ_SIZE);
         if(bufptr->size <= 0) {
-            if((cur_time - start_time) >= recsec) {
+            if((cur_time - start_time) >= recsec && !indefinite) {
                 f_exit = TRUE;
                 enqueue(p_queue, NULL);
                 break;
@@ -510,7 +602,7 @@
         enqueue(p_queue, bufptr);
 
         /* stop recording */
-        if((cur_time - start_time) >= recsec) {
+        if((cur_time - start_time) >= recsec && !indefinite) {
             ioctl(tfd, STOP_REC, 0);
             /* read remaining data */
             while(1) {