# HG changeset patch # User Yoshiki Yazawa # Date 1234817916 -32400 # Node ID 97fd2315114eebc281a50b7bf2fc714d45aafa6a # Parent 43d177fa65c948d95e9daefe9d4dfdeae468f60e - now it can handle options. - applied channel patch. - some cleanups. diff -r 43d177fa65c9 -r 97fd2315114e recpt1/decoder.c --- 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 +#include #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; } diff -r 43d177fa65c9 -r 97fd2315114e recpt1/decoder.h --- 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, diff -r 43d177fa65c9 -r 97fd2315114e recpt1/recpt1.c --- 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 #include #include #include @@ -6,7 +7,7 @@ #include #include #include -#include +#include #include #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; } diff -r 43d177fa65c9 -r 97fd2315114e recpt1/recpt1.h --- 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