changeset 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
files recpt1/decoder.c recpt1/decoder.h recpt1/recpt1.c recpt1/recpt1.h
diffstat 4 files changed, 243 insertions(+), 93 deletions(-) [+]
line wrap: on
line diff
--- a/recpt1/decoder.c	Tue Feb 17 01:46:54 2009 +0900
+++ b/recpt1/decoder.c	Tue Feb 17 05:58:36 2009 +0900
@@ -1,22 +1,62 @@
 #include <stdlib.h>
+#include <stdio.h>
 
 #include "decoder.h"
 
 decoder *
-b25_startup(void)
+b25_startup(decoder_options *opt)
 {
     decoder *dec = calloc(1, sizeof(decoder));
     int code;
+    const char *err = NULL;
 
     dec->b25 = create_arib_std_b25();
-    dec->b25->set_multi2_round(dec->b25, 4); //xxx round should be configurable
-    dec->b25->set_strip(dec->b25, 0); //ditto
-    dec->b25->set_emm_proc(dec->b25, 0); //ditto
+    if(!dec->b25) {
+        err = "create_arib_std_b25 failed";
+        goto error;
+    }
+
+    code = dec->b25->set_multi2_round(dec->b25, opt->round);
+    if(code < 0) {
+        err = "set_multi2_round failed";
+        goto error;
+    }
+
+    code = dec->b25->set_strip(dec->b25, opt->strip);
+    if(code < 0) {
+        err = "set_strip failed";
+        goto error;
+    }
+
+    code = dec->b25->set_emm_proc(dec->b25, opt->emm);
+    if(code < 0) {
+        err = "set_emm_proc failed";
+        goto error;
+    }
+
     dec->bcas = create_b_cas_card();
+    if(!dec->bcas) {
+        err = "create_b_cas_card failed";
+        goto error;
+    }
     code = dec->bcas->init(dec->bcas);
+    if(code < 0) {
+        err = "bcas->init failed";
+        goto error;
+    }
+
     code = dec->b25->set_b_cas_card(dec->b25, dec->bcas);
+    if(code < 0) {
+        err = "set_b_cas_card failed";
+        goto error;
+    }
 
     return dec;
+
+error:
+    fprintf(stderr, "%s\n", err);
+    free(dec);
+    return NULL;
 }
 
 int
@@ -32,25 +72,39 @@
 int
 b25_decode(decoder *dec, ARIB_STD_B25_BUFFER *sbuf, ARIB_STD_B25_BUFFER *dbuf)
 {
-    int code;
+  int code;
+
+  code = dec->b25->put(dec->b25, sbuf);
+  if(code < 0) {
+      fprintf(stderr, "b25->put failed\n");
+      return code;
+  }
 
-    code = dec->b25->put(dec->b25, sbuf);
-    if(code < 0)
-        return code;
+  code = dec->b25->get(dec->b25, dbuf);
+  if(code < 0) {
+      fprintf(stderr, "b25->get failed\n");
+      return code;
+  }
 
-    code = dec->b25->get(dec->b25, dbuf);
-    return code;
+  return code;
 }
 
 int
 b25_finish(decoder *dec, ARIB_STD_B25_BUFFER *sbuf, ARIB_STD_B25_BUFFER *dbuf)
 {
-    int code;
+  int code;
+
+  code = dec->b25->flush(dec->b25);
+  if(code < 0) {
+      fprintf(stderr, "b25->flush failed\n");
+      return code;
+  }
 
-    code = dec->b25->flush(dec->b25);
-    if(code < 0)
-        return code;
+  code = dec->b25->get(dec->b25, dbuf);
+  if(code < 0) {
+      fprintf(stderr, "b25->get failed\n");
+      return code;
+  }
 
-    code = dec->b25->get(dec->b25, dbuf);
-    return code;
+  return code;
 }
--- a/recpt1/decoder.h	Tue Feb 17 01:46:54 2009 +0900
+++ b/recpt1/decoder.h	Tue Feb 17 05:58:36 2009 +0900
@@ -4,14 +4,19 @@
 #include "../arib25v023/arib25/src/arib_std_b25.h"
 #include "../arib25v023/arib25/src/b_cas_card.h"
 
-typedef struct decoder
-{
+typedef struct decoder {
     ARIB_STD_B25 *b25;
     B_CAS_CARD *bcas;
 } decoder;
 
+typedef struct decoder_options {
+    int round;
+    int strip;
+    int emm;
+} decoder_options;
+
 /* prototypes */
-decoder *b25_startup(void);
+decoder *b25_startup(decoder_options *opt);
 int b25_shutdown(decoder *dec);
 int b25_decode(decoder *dec,
                ARIB_STD_B25_BUFFER *sbuf,
--- a/recpt1/recpt1.c	Tue Feb 17 01:46:54 2009 +0900
+++ b/recpt1/recpt1.c	Tue Feb 17 05:58:36 2009 +0900
@@ -1,3 +1,4 @@
+#include <stdio.h>
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -6,7 +7,7 @@
 #include <string.h>
 #include <pthread.h>
 #include <unistd.h>
-#include <stdio.h>
+#include <getopt.h>
 
 #include <sys/ioctl.h>
 #include "pt1_ioctl.h"
@@ -15,29 +16,29 @@
 #include "decoder.h"
 
 /* globals */
-int wfd;                /* for output file */
-int f_exit = FALSE ;
+int f_exit = FALSE;
 
 typedef struct thread_data {
     QUEUE_T *queue;
     decoder *decoder;
+    int fd;
 } thread_data;
 
 // 周波数テーブル変換
 ISDB_T_FREQ_CONV_TABLE *
 searchrecoff(char *channel)
 {
-    int lp ;
+    int lp;
 
-    for(lp = 0 ; lp < 113 ; lp++){
+    for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++){
         // 文字列&長さ一致したら周波数テーブル番号を返却する
         if((memcmp(isdb_t_conv_table[lp].parm_freq, channel,
                    strlen(channel)) == 0) &&
            (strlen(channel) == strlen(isdb_t_conv_table[lp].parm_freq))){
-            return &isdb_t_conv_table[lp] ;
+            return &isdb_t_conv_table[lp];
         }
     }
-    return NULL ;
+    return NULL;
 }
 
 QUEUE_T *
@@ -48,7 +49,7 @@
 
     p_queue = (QUEUE_T*)calloc(memsize, sizeof(char));
 
-    if(p_queue != NULL){
+    if(p_queue != NULL) {
         p_queue->size = size;
         p_queue->no_full = size;
         p_queue->no_empty = 0;
@@ -63,12 +64,13 @@
 void
 destroy_queue(QUEUE_T *p_queue)
 {
-    if(p_queue != NULL) {
-        pthread_mutex_destroy(&p_queue->mutex);
-        pthread_cond_destroy(&p_queue->cond_full);
-        pthread_cond_destroy(&p_queue->cond_empty);
-        free(p_queue);
-    }
+    if(!p_queue)
+        return;
+
+    pthread_mutex_destroy(&p_queue->mutex);
+    pthread_cond_destroy(&p_queue->cond_full);
+    pthread_cond_destroy(&p_queue->cond_empty);
+    free(p_queue);
 }
 
 /* enqueue data. this function will block if queue is full. */
@@ -81,7 +83,7 @@
     /* wait until queue is not full */
     while(!p_queue->no_full) {
         pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex);
-        printf("Full\n");
+        fprintf(stderr, "Full\n");
     }
 
     p_queue->buffer[p_queue->in] = data;
@@ -136,31 +138,51 @@
     thread_data *data = (thread_data *)p;
     QUEUE_T *p_queue = data->queue;
     decoder *dec = data->decoder;
-    BUFSZ	*buf ;
+    int wfd = data->fd;
+    int use_b25 = dec ? 1 : 0;
+    BUFSZ	*buf;
     ARIB_STD_B25_BUFFER sbuf, dbuf;
+    int code;
 
     while(1) {
         buf = dequeue(p_queue);
         /* no entry in the queue */
         if(buf == NULL){
             close(wfd);
-            break ;
+            break;
         }
 
         sbuf.data = buf->buffer;
         sbuf.size = buf->size;
 
-        /* write data to output file*/
-        b25_decode(dec, &sbuf, &dbuf);
-        write(wfd, dbuf.data, dbuf.size);
-        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");
+                close(wfd);
+                break;
+            }
+            write(wfd, dbuf.data, dbuf.size);
+            free(buf);
+        } else {
+            write(wfd, sbuf.data, sbuf.size);
+            free(buf);
+        }
 
         /* normal exit */
-        if((f_exit) && (!p_queue->no_empty)){
-            b25_finish(dec, &sbuf, &dbuf);
-            write(wfd, dbuf.data, dbuf.size);
+        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);
+                    break;
+                }
+                write(wfd, dbuf.data, dbuf.size);
+            }
             close(wfd);
-            break ;
+            break;
         }
     }
 
@@ -170,25 +192,70 @@
 int
 main(int argc, char **argv)
 {
-    int fd ;
-    int lp ;
-    int recsec ;
-    time_t start_time ;
-    time_t cur_time ;
+    int fd, wfd;
+    int lp;
+    int recsec;
+    time_t start_time, cur_time;
     FREQUENCY freq;
-    ISDB_T_FREQ_CONV_TABLE *ptr ;
+    ISDB_T_FREQ_CONV_TABLE *ptr;
     pthread_t dequeue_threads;
     QUEUE_T *p_queue = create_queue(MAX_QUEUE);
-    BUFSZ   *bufptr ;
-    decoder *dec;
+    BUFSZ   *bufptr;
+    decoder *dec = NULL;
     thread_data tdata;
+    decoder_options dopt;
 
-    if(argc < 4) {
-        printf("Usage %s: channel recsec destfile\n", argv[0]);
+    int use_b25 = 0;
+    int result;
+    int option_index;
+    struct option long_options[] = {
+        { "b25",       0, NULL, 'b'},
+        { "B25",       0, NULL, 'b'},
+        { "round",     1, NULL, 'r'},
+        { "strip",     0, NULL, 's'},
+        { "emm",       0, NULL, 'm'},
+        { "EMM",       0, NULL, 'm'}
+    };
+
+    dopt.round = 4;
+    dopt.strip = 0;
+    dopt.emm = 0;
+
+    while((result = getopt_long(argc, argv, "br:sm", long_options, &option_index)) != -1) {
+        switch(result) {
+        case 'b':
+			use_b25 = 1;
+            fprintf(stderr, "using B25...\n");
+			break;
+        case 's':
+			dopt.strip = 1;
+            fprintf(stderr, "enable B25 strip\n");
+			break;
+        case 'm':
+			dopt.emm = 1;
+            fprintf(stderr, "enable B25 emm processing\n");
+			break;
+        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 '?':
+            fprintf(stderr, "Usage: [--b25 [--round N] [--strip] [--EMM]] channel recsec destfile\n");
+            break;
+        }
+    }
+
+	if(argc - optind < 3) {
+        printf("Usage %s: [--b25 [--round N] [--strip] [--EMM]] channel recsec destfile\n", 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");
@@ -196,66 +263,74 @@
         printf("101ch:NHK衛星第1放送(BS1)\n");
         printf("102ch:NHK衛星第2放送(BS2)\n");
         printf("103ch:NHKハイビジョン(BShi)\n");
+        printf("CS2-CS24:CSチャンネル\n");
         return 1;
     }
-    ptr = searchrecoff(argv[1]);
-    if(ptr == NULL) {
-        printf("Channel Select Error(%s)\n", argv[1]);
-        return 1 ;
-    }
+	ptr = searchrecoff(argv[optind]);
+	if(ptr == NULL){
+		printf("Channel Select Error(%s)\n", argv[optind]);
+		return 1;
+	}
 
-    freq.frequencyno = ptr->set_freq ;
-    freq.slot = ptr->add_freq ;
+    freq.frequencyno = ptr->set_freq;
+    freq.slot = ptr->add_freq;
 
     if(ptr->type == CHTYPE_SATELLITE) {
-        for(lp = 0 ; lp < 2 ; lp++) {
+        for(lp = 0; lp < 2; lp++) {
             fd = open(bsdev[lp], O_RDONLY);
             if(fd >= 0) {
-                break ;
+                break;
             }
         }
         if(fd < 0) {
-            printf("Device Open Error\n");
+            fprintf(stderr, "Device Open Error\n");
             return 1;
         }
     } else {
-        for(lp = 0 ; lp < 2 ; lp++) {
+        for(lp = 0; lp < 2; lp++) {
             fd = open(isdb_t_dev[lp], O_RDONLY);
             if(fd >= 0) {
-                break ;
+                break;
             }
         }
         if(fd < 0) {
-            printf("Device Open Error\n");
+            fprintf(stderr, "Device Open Error\n");
+            return 1;
+        }
+    }
+	recsec = atoi(argv[optind + 1]);
+
+    /* initialize decoder */
+    if(use_b25) {
+        dec = b25_startup(&dopt);
+        if(!dec) {
+            fprintf(stderr, "cannot start b25 decoder\n");
             return 1;
         }
     }
-    recsec = atoi(argv[2]);
-
-    /* initialize decoder */
-    dec = b25_startup();
 
     /* open output file */
-    wfd = open(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666);
+    wfd = open(argv[optind + 2], (O_RDWR | O_CREAT | O_TRUNC), 0666);
     if(wfd < 0) {
-        printf("Output File Open Error(%s)\n", argv[3]);
-        return 0;
+        fprintf(stderr, "Output File Open Error(%s)\n", argv[optind + 2]);
+        return 1;
     }
 
     if(ioctl(fd, SET_CHANNEL, &freq) < 0) {
-        printf("Tuner Select Error\n");
-        return 0 ;
+        fprintf(stderr, "Tuner Select Error\n");
+        return 1;
     }
 
-    /* make reading thread */
+    /* make reader thread */
     tdata.queue = p_queue;
     tdata.decoder = dec;
+    tdata.fd = wfd;
     pthread_create(&dequeue_threads, NULL, write_func, &tdata);
 
-    /* start recording*/
+    /* start recording */
     if(ioctl(fd, START_REC, 0) < 0) {
-        printf("Tuner Start Error\n");
-        return 0 ;
+        fprintf(stderr, "Tuner Start Error\n");
+        return 1;
     }
 
     time(&start_time);
@@ -267,11 +342,11 @@
         bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE);
         if(bufptr->size <= 0) {
             if((cur_time - start_time) >= recsec) {
-                f_exit = TRUE ;
+                f_exit = TRUE;
                 enqueue(p_queue, NULL);
-                break ;
+                break;
             } else {
-                continue ;
+                continue;
             }
         }
         enqueue(p_queue, bufptr);
@@ -284,13 +359,13 @@
                 bufptr = malloc(sizeof(BUFSZ));
                 bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE);
                 if(bufptr->size <= 0) {
-                    f_exit = TRUE ;
+                    f_exit = TRUE;
                     enqueue(p_queue, NULL);
-                    break ;
+                    break;
                 }
                 enqueue(p_queue, bufptr);
             }
-            break ;
+            break;
         }
     }
     /* close tuner */
@@ -301,7 +376,9 @@
     destroy_queue(p_queue);
 
     /* release decoder */
-    b25_shutdown(dec);
+    if(use_b25) {
+        b25_shutdown(dec);
+    }
 
-    return 0 ;
+    return 0;
 }
--- a/recpt1/recpt1.h	Tue Feb 17 01:46:54 2009 +0900
+++ b/recpt1/recpt1.h	Tue Feb 17 05:58:36 2009 +0900
@@ -19,7 +19,7 @@
 #define FALSE	0
 
 typedef struct _BUFSZ {
-    int	 size ;
+    int size ;
     u_char buffer[MAX_READ_SIZE];
 } BUFSZ;
 
@@ -43,23 +43,36 @@
 } ISDB_T_FREQ_CONV_TABLE;
 
 // 変換テーブル(ISDB-T用)
-#define		MAX_CHANNEL_SELECT		123
 // 実際にioctl()を行う値の部分はREADMEを参照の事。
 // BS/CSの設定値およびスロット番号は
 // http://www5e.biglobe.ne.jp/~kazu_f/digital-sat/index.htmlより取得。
 //
 
-ISDB_T_FREQ_CONV_TABLE	isdb_t_conv_table[MAX_CHANNEL_SELECT] = {
+ISDB_T_FREQ_CONV_TABLE	isdb_t_conv_table[] = {
 	{   0, CHTYPE_SATELLITE, 0, "151"},	// 151ch:BS朝日
 	{   0, CHTYPE_SATELLITE, 1, "161"},	// 161ch:BS-i
+	{   1, CHTYPE_SATELLITE, 0, "191"},	// 191ch:WOWOW
 	{   1, CHTYPE_SATELLITE, 1, "171"},	// 171ch:BSジャパン
 	{   4, CHTYPE_SATELLITE, 0, "211"},	// 211ch:BS11デジタル
+	{   4, CHTYPE_SATELLITE, 1, "200"},	// 200ch:スターチャンネル
 	{   4, CHTYPE_SATELLITE, 2, "222"},	// 222ch:TwellV
 	{   6, CHTYPE_SATELLITE, 0, "141"},	// 141ch:BS日テレ
-	{   6, CHTYPE_SATELLITE, 1, "181"},	// 181ch:BSフジ
+	{   6, CHTYPE_SATELLITE, 1, "181"}, // 181ch:BSフジ
 	{   7, CHTYPE_SATELLITE, 0, "101"},	// 101ch:NHK衛星第1放送(BS1)
 	{   7, CHTYPE_SATELLITE, 0, "102"},	// 102ch:NHK衛星第2放送(BS2)
 	{   7, CHTYPE_SATELLITE, 1, "103"}, // 103ch:NHKハイビジョン(BShi)
+	{  12, CHTYPE_SATELLITE, 0, "CS2"},	// ND2:237ch:スター・チャンネル プラス 239ch:日本映画専門チャンネルHD 306ch:フジテレビCSHD
+	{  13, CHTYPE_SATELLITE, 0, "CS4"},	// ND4:100ch:e2プロモ 256ch:J sports ESPN 312ch:FOX 322ch:スペースシャワーTV 331ch:カートゥーン ネットワーク 194ch:インターローカルTV 334ch:トゥーン・ディズニー
+	{  14, CHTYPE_SATELLITE, 0, "CS6"},	// ND6:221ch:東映チャンネル 222ch:衛星劇場 223ch:チャンネルNECO 224ch:洋画★シネフィル・イマジカ 292ch:時代劇専門チャンネル 238ch:スター・チャンネル クラシック 310ch:スーパー!ドラマTV 311ch:AXN 343ch:ナショナル ジオグラフィック チャンネル
+	{  15, CHTYPE_SATELLITE, 0, "CS8"},	// ND8:055ch:ショップ チャンネル
+	{  16, CHTYPE_SATELLITE, 0, "CS10"},	// ND10:228ch:ザ・シネマ 800ch:スカチャンHD800 801ch:スカチャン801 802ch:スカチャン802
+	{  17, CHTYPE_SATELLITE, 0, "CS12"},	// ND12:260ch:ザ・ゴルフ・チャンネル 303ch:テレ朝チャンネル 323ch:MTV 324ch:大人の音楽専門TV◆ミュージック・エア 352ch:朝日ニュースター 353ch:BBCワールドニュース 354ch:CNNj 361ch:ジャスト・アイ インフォメーション
+	{  18, CHTYPE_SATELLITE, 0, "CS14"},	// ND14:251ch:J sports 1 252ch:J sports 2 253ch:J sports Plus 254ch:GAORA 255ch:スカイ・A sports+
+	{  19, CHTYPE_SATELLITE, 0, "CS16"},	// ND16:305ch:チャンネル銀河 333ch:アニメシアターX(AT-X) 342ch:ヒストリーチャンネル 290ch:TAKARAZUKA SKY STAGE 803ch:スカチャン803 804ch:スカチャン804
+	{  20, CHTYPE_SATELLITE, 0, "CS18"},	// ND18:240ch:ムービープラスHD 262ch:ゴルフネットワーク 314ch:LaLa HDHV
+	{  21, CHTYPE_SATELLITE, 0, "CS20"},	// ND20:258ch:フジテレビ739 302ch:フジテレビ721 332ch:アニマックス 340ch:ディスカバリーチャンネル 341ch:アニマルプラネット
+	{  22, CHTYPE_SATELLITE, 0, "CS22"},	// ND22:160ch:C-TBSウェルカムチャンネル 161ch:QVC 185ch:プライム365.TV 293ch:ファミリー劇場 301ch:TBSチャンネル 304ch:ディズニー・チャンネル 325ch:MUSIC ON! TV 330ch:キッズステーション 351ch:TBSニュースバード
+	{  23, CHTYPE_SATELLITE, 0, "CS24"},	// ND24:257ch:日テレG+ 291ch:fashiontv 300ch:日テレプラス 320ch:安らぎの音楽と風景/エコミュージックTV 321ch:Music Japan TV 350ch:日テレNEWS24
 	{   0, CHTYPE_GROUND, 0,   "1"}, {   1, CHTYPE_GROUND, 0,   "2"},
 	{   2, CHTYPE_GROUND, 0,   "3"}, {   3, CHTYPE_GROUND, 0, "C13"},
 	{   4, CHTYPE_GROUND, 0, "C14"}, {   5, CHTYPE_GROUND, 0, "C15"},
@@ -116,7 +129,8 @@
 	{ 106, CHTYPE_GROUND, 0,  "56"}, { 107, CHTYPE_GROUND, 0,  "57"},
 	{ 108, CHTYPE_GROUND, 0,  "58"}, { 109, CHTYPE_GROUND, 0,  "59"},
 	{ 110, CHTYPE_GROUND, 0,  "60"}, { 111, CHTYPE_GROUND, 0,  "61"},
-	{ 112, CHTYPE_GROUND, 0,  "62"}
+	{ 112, CHTYPE_GROUND, 0,  "62"},
+	{ 0, 0, 0, NULL} /* terminator */
 };
 
 #endif