# HG changeset patch # User Yoshiki Yazawa # Date 1234788016 -32400 # Node ID 8ac7c59fefc9ddbdc8b03e81f4362d1acf0a3f8f # Parent 29f3b2bbbd67543e8475fccea5ffd36d055552c0 added b25 decode functionality diff -r 29f3b2bbbd67 -r 8ac7c59fefc9 recpt1/Makefile --- a/recpt1/Makefile Mon Feb 16 15:55:46 2009 +0900 +++ b/recpt1/Makefile Mon Feb 16 21:40:16 2009 +0900 @@ -18,7 +18,7 @@ CFLAGS = -O2 -g -Wall -pthread -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 $(B25) -I../driver LDFLAGS = -OBJS = recpt1.o $(B25_OBJS_EXT) +OBJS = recpt1.o $(B25_OBJS_EXT) decoder.o LIBS = -lpthread TARGET = $(DIST)/recpt1 diff -r 29f3b2bbbd67 -r 8ac7c59fefc9 recpt1/decoder.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/recpt1/decoder.c Mon Feb 16 21:40:16 2009 +0900 @@ -0,0 +1,56 @@ +#include + +#include "decoder.h" + +decoder * +b25_startup(void) +{ + decoder *dec = calloc(1, sizeof(decoder)); + int code; + + 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 + dec->bcas = create_b_cas_card(); + code = dec->bcas->init(dec->bcas); + code = dec->b25->set_b_cas_card(dec->b25, dec->bcas); + + return dec; +} + +int +b25_shutdown(decoder *dec) +{ + dec->b25->release(dec->b25); + dec->bcas->release(dec->bcas); + free(dec); + + return 0; +} + +int +b25_decode(decoder *dec, ARIB_STD_B25_BUFFER *sbuf, ARIB_STD_B25_BUFFER *dbuf) +{ + int code; + + code = dec->b25->put(dec->b25, sbuf); + if(code < 0) + return code; + + code = dec->b25->get(dec->b25, dbuf); + return code; +} + +int +b25_finish(decoder *dec, ARIB_STD_B25_BUFFER *sbuf, ARIB_STD_B25_BUFFER *dbuf) +{ + int code; + + code = dec->b25->flush(dec->b25); + if(code < 0) + return code; + + code = dec->b25->get(dec->b25, dbuf); + return code; +} diff -r 29f3b2bbbd67 -r 8ac7c59fefc9 recpt1/decoder.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/recpt1/decoder.h Mon Feb 16 21:40:16 2009 +0900 @@ -0,0 +1,23 @@ +#ifndef _DECODER_H_ +#define _DECODER_H_ + +#include "../arib25v021/arib25/src/arib_std_b25.h" +#include "../arib25v021/arib25/src/b_cas_card.h" + +typedef struct decoder +{ + ARIB_STD_B25 *b25; + B_CAS_CARD *bcas; +} decoder; + +/* prototypes */ +decoder *b25_startup(void); +int b25_shutdown(decoder *dec); +int b25_decode(decoder *dec, + ARIB_STD_B25_BUFFER *sbuf, + ARIB_STD_B25_BUFFER *dbuf); +int b25_finish(decoder *dec, + ARIB_STD_B25_BUFFER *sbuf, + ARIB_STD_B25_BUFFER *dbuf); + +#endif diff -r 29f3b2bbbd67 -r 8ac7c59fefc9 recpt1/recpt1.c --- a/recpt1/recpt1.c Mon Feb 16 15:55:46 2009 +0900 +++ b/recpt1/recpt1.c Mon Feb 16 21:40:16 2009 +0900 @@ -11,271 +11,287 @@ #include #include "pt1_ioctl.h" -#include "recpt1.h" +#include "recpt1.h" +#include "decoder.h" + +/* globals */ +int wfd; // ファイル書き込み用 +int f_exit = FALSE ; +decoder *dec; // 周波数テーブル変換 -ISDB_T_FREQ_CONV_TABLE *searchrecoff(char *channel) +ISDB_T_FREQ_CONV_TABLE * +searchrecoff(char *channel) { - int lp ; + int lp ; - for(lp = 0 ; lp < 113 ; 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 NULL ; + for(lp = 0 ; lp < 113 ; 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 NULL ; } -QUEUE_T* create_queue(size_t size) +QUEUE_T * +create_queue(size_t size) { - QUEUE_T* p_queue; - int memsize = sizeof(QUEUE_T) + (size * sizeof(BUFSZ)); + QUEUE_T* p_queue; + int memsize = sizeof(QUEUE_T) + (size * sizeof(BUFSZ)); - p_queue = (QUEUE_T*)calloc(memsize, sizeof(char)); + p_queue = (QUEUE_T*)calloc(memsize, sizeof(char)); - if(p_queue != NULL){ - p_queue->size = size; - p_queue->no_full = size; - p_queue->no_empty = 0; - pthread_mutex_init(&p_queue->mutex, NULL); - pthread_cond_init(&p_queue->cond_full, NULL); - pthread_cond_init(&p_queue->cond_empty, NULL); - } + if(p_queue != NULL){ + p_queue->size = size; + p_queue->no_full = size; + p_queue->no_empty = 0; + pthread_mutex_init(&p_queue->mutex, NULL); + pthread_cond_init(&p_queue->cond_full, NULL); + pthread_cond_init(&p_queue->cond_empty, NULL); + } - return p_queue; + return p_queue; } -void destroy_queue(QUEUE_T *p_queue) +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 != NULL){ + pthread_mutex_destroy(&p_queue->mutex); + pthread_cond_destroy(&p_queue->cond_full); + pthread_cond_destroy(&p_queue->cond_empty); + free(p_queue); + } } // 関数名: enqueue // キューにデータを入れる // データが満タンな場合は、ブロックします -void enqueue(QUEUE_T *p_queue, BUFSZ *data) +void +enqueue(QUEUE_T *p_queue, BUFSZ *data) { - pthread_mutex_lock(&p_queue->mutex); - // -- ここから、クリティカルセクション -- - - // 満タンじゃなくなるまで待つ - while(!p_queue->no_full) { - pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex); - printf("Full\n"); - } + pthread_mutex_lock(&p_queue->mutex); + // -- ここから、クリティカルセクション -- - p_queue->buffer[p_queue->in] = data; + // 満タンじゃなくなるまで待つ + while(!p_queue->no_full) { + pthread_cond_wait(&p_queue->cond_full, &p_queue->mutex); + printf("Full\n"); + } - p_queue->in++; - p_queue->in %= p_queue->size; + p_queue->buffer[p_queue->in] = data; - p_queue->no_full--; - p_queue->no_empty++; + p_queue->in++; + p_queue->in %= p_queue->size; - pthread_mutex_unlock(&p_queue->mutex); - pthread_cond_signal(&p_queue->cond_empty); + p_queue->no_full--; + p_queue->no_empty++; + + pthread_mutex_unlock(&p_queue->mutex); + pthread_cond_signal(&p_queue->cond_empty); } // 関数名: dequeue // キューにデータを入れる // データが満タンな場合は、ブロックします -BUFSZ *dequeue(QUEUE_T *p_queue) +BUFSZ * +dequeue(QUEUE_T *p_queue) { - void *result; + void *result; - pthread_mutex_lock(&p_queue->mutex); - // -- ここから、クリティカルセクション -- + pthread_mutex_lock(&p_queue->mutex); + // -- ここから、クリティカルセクション -- - // 空っぽじゃなくなるまで待つ - while (!p_queue->no_empty) { - pthread_cond_wait(&p_queue->cond_empty, &p_queue->mutex); - } + // 空っぽじゃなくなるまで待つ + while (!p_queue->no_empty) { + pthread_cond_wait(&p_queue->cond_empty, &p_queue->mutex); + } - // データを取り出す - result = p_queue->buffer[p_queue->out]; + // データを取り出す + result = p_queue->buffer[p_queue->out]; - // 次にデータを取り出す場所をインクリメント - p_queue->out++; - p_queue->out %= p_queue->size; + // 次にデータを取り出す場所をインクリメント + p_queue->out++; + p_queue->out %= p_queue->size; - // フラグの更新 - p_queue->no_full++; - p_queue->no_empty--; + // フラグの更新 + p_queue->no_full++; + p_queue->no_empty--; - // -- ここまで、クリティカルセクション -- - pthread_mutex_unlock(&p_queue->mutex); - pthread_cond_signal(&p_queue->cond_full); + // -- ここまで、クリティカルセクション -- + pthread_mutex_unlock(&p_queue->mutex); + pthread_cond_signal(&p_queue->cond_full); - return result; + return result; } - -void *write_func(void *p) +/* this function will be a writing thread */ +void * +write_func(void *p) { - QUEUE_T *p_queue = (QUEUE_T*)p; - int size = 0 ; - BUFSZ *ptr ; -#if 0 - u_char *buffer ; + QUEUE_T *p_queue = (QUEUE_T*)p; + BUFSZ *ptr ; + ARIB_STD_B25_BUFFER sbuf, dbuf; - buffer = calloc(WRITE_SIZE, sizeof(char)); - if(buffer == NULL){ - return NULL ; - } -#endif + while(1){ + ptr = dequeue(p_queue); + /* no entry in the queue */ + if(ptr == NULL){ + close(wfd); + break ; + } - while(1){ - ptr = dequeue(p_queue); - if(ptr == NULL){ - close(wfd); - break ; - } -#if 0 - if((size + ptr->size) < WRITE_SIZE){ - memcpy((buffer + size) , ptr->buffer, ptr->size); - size += ptr->size ; - }else{ - write(wfd, buffer, size); - size = ptr->size ; - } -#endif - write(wfd, ptr->buffer, ptr->size); - free(ptr); - if((f_exit) && (!p_queue->no_empty)){ -#if 0 - if(size){ - write(wfd, buffer, size); - } -#endif - close(wfd); - break ; - } - } - return NULL; + sbuf.data = ptr->buffer; + sbuf.size = ptr->size; + + /* write data to output file*/ + b25_decode(dec, &sbuf, &dbuf); + write(wfd, dbuf.data, dbuf.size); + free(ptr); + + /* normal exit */ + if((f_exit) && (!p_queue->no_empty)){ + b25_finish(dec, &sbuf, &dbuf); + write(wfd, dbuf.data, dbuf.size); + close(wfd); + break ; + } + } + + return NULL; } -int main(int argc, char **argv) +int +main(int argc, char **argv) { - int fd ; - int rc ; - int lp ; - int channel ; - int recsec ; - time_t start_time ; - time_t cur_time ; - FREQUENCY freq; - ISDB_T_FREQ_CONV_TABLE *ptr ; - pthread_t dequeue_threads; - QUEUE_T *p_queue = create_queue(MAX_QUEUE); - BUFSZ *bufptr ; + int fd ; + int lp ; + int recsec ; + time_t start_time ; + time_t cur_time ; + FREQUENCY freq; + ISDB_T_FREQ_CONV_TABLE *ptr ; + pthread_t dequeue_threads; + QUEUE_T *p_queue = create_queue(MAX_QUEUE); + BUFSZ *bufptr ; - if(argc < 4){ - printf("Usage %s: channel recsec destfile\n", argv[0]); - printf("channel =\n"); - printf("151ch:BS朝日\n"); - printf("161ch:BS-i\n"); - printf("171ch:BSジャパン\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"); - return 1; - } - ptr = searchrecoff(argv[1]); - if(ptr == NULL){ - printf("Channel Select Error(%s)\n", argv[1]); - return 1 ; - } + if(argc < 4){ + printf("Usage %s: channel recsec destfile\n", argv[0]); + printf("channel =\n"); + printf("151ch:BS朝日\n"); + printf("161ch:BS-i\n"); + printf("171ch:BSジャパン\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"); + return 1; + } + ptr = searchrecoff(argv[1]); + if(ptr == NULL){ + printf("Channel Select Error(%s)\n", argv[1]); + 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++){ + fd = open(bsdev[lp], O_RDONLY); + if(fd >= 0){ + break ; + } + } + if(fd < 0){ + printf("Device Open Error\n"); + return 1; + } + }else{ + for(lp = 0 ; lp < 2 ; lp++){ + fd = open(isdb_t_dev[lp], O_RDONLY); + if(fd >= 0){ + break ; + } + } + if(fd < 0){ + printf("Device Open Error\n"); + return 1; + } + } + recsec = atoi(argv[2]); - if(ptr->type == CHTYPE_SATELLITE){ - for(lp = 0 ; lp < 2 ; lp++){ - fd = open(bsdev[lp], O_RDONLY); - if(fd >= 0){ - break ; - } - } - if(fd < 0){ - printf("Device Open Error\n"); - return 1; - } - }else{ - for(lp = 0 ; lp < 2 ; lp++){ - fd = open(isdb_t_dev[lp], O_RDONLY); - if(fd >= 0){ - break ; - } - } - if(fd < 0){ - printf("Device Open Error\n"); - return 1; - } - } - recsec = atoi(argv[2]); + /* initialize decoder */ + dec = b25_startup(); + + /* open output file */ + wfd = open64(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666); + if(wfd < 0){ + printf("Output File Open Error(%s)\n", argv[3]); + return 0; + } + + if(ioctl(fd, SET_CHANNEL, &freq) < 0){ + printf("Tuner Select Error\n"); + return 0 ; + } + + /* make reading thread */ + pthread_create(&dequeue_threads, NULL, write_func, p_queue); + if(ioctl(fd, START_REC, 0) < 0){ + printf("Tuner Start Error\n"); + return 0 ; + } + + time(&start_time); - wfd = open64(argv[3], (O_RDWR | O_CREAT | O_TRUNC), 0666); - if(wfd < 0){ - printf("Output File Open Error(%s)\n", argv[3]); - return 0; - } + /* read-write loop */ + while(1){ + time(&cur_time); + bufptr = calloc(1, sizeof(BUFSZ)); + bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); + if(bufptr->size <= 0){ + if((cur_time - start_time) >= recsec){ + f_exit = TRUE ; + enqueue(p_queue, NULL); + break ; + }else{ + continue ; + } + } + enqueue(p_queue, bufptr); - if(ioctl(fd, SET_CHANNEL, &freq) < 0){ - printf("Tuner Select Error\n"); - return 0 ; + if((cur_time - start_time) >= recsec){ + ioctl(fd, STOP_REC, 0); + //なくなるまでデータを読み出す + while(1){ + bufptr = calloc(1, sizeof(BUFSZ)); + bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); + if(bufptr->size <= 0){ + f_exit = TRUE ; + enqueue(p_queue, NULL); + break ; } - pthread_create(&dequeue_threads, NULL, write_func, p_queue); - if(ioctl(fd, START_REC, 0) < 0){ - printf("Tuner Start Error\n"); - return 0 ; - } - - time(&start_time); - while(1){ - time(&cur_time); - bufptr = calloc(1, sizeof(BUFSZ)); - bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); - if(bufptr->size <= 0){ - if((cur_time - start_time) >= recsec){ - f_exit = TRUE ; - enqueue(p_queue, NULL); - break ; - }else{ - continue ; - } - } - enqueue(p_queue, bufptr); + enqueue(p_queue, bufptr); + } + break ; + } + } + close(fd); /* close tuner */ - if((cur_time - start_time) >= recsec){ - ioctl(fd, STOP_REC, 0); - //なくなるまでデータを読み出す - while(1){ - bufptr = calloc(1, sizeof(BUFSZ)); - bufptr->size = read(fd, bufptr->buffer, MAX_READ_SIZE); - if(bufptr->size <= 0){ - f_exit = TRUE ; - enqueue(p_queue, NULL); - break ; - } - enqueue(p_queue, bufptr); - } - break ; - } - } - close(fd); - pthread_join(dequeue_threads, NULL); - destroy_queue(p_queue); - return 0 ; + /* wait reading thread */ + pthread_join(dequeue_threads, NULL); + destroy_queue(p_queue); + + /* release decoder */ + b25_shutdown(dec); + + return 0 ; } diff -r 29f3b2bbbd67 -r 8ac7c59fefc9 recpt1/recpt1.h --- a/recpt1/recpt1.h Mon Feb 16 15:55:46 2009 +0900 +++ b/recpt1/recpt1.h Mon Feb 16 21:40:16 2009 +0900 @@ -10,12 +10,12 @@ "/dev/pt1video3" }; -#define CHTYPE_SATELLITE 0 // 衛星デジタル放送 -#define CHTYPE_GROUND 1 // 地上デジタル放送 -#define MAX_QUEUE 8192 +#define CHTYPE_SATELLITE 0 // 衛星デジタル放送 +#define CHTYPE_GROUND 1 // 地上デジタル放送 +#define MAX_QUEUE 8192 #define MAX_READ_SIZE (1024 * 16) -#define WRITE_SIZE (1024 * 1024 * 2) +#define WRITE_SIZE (1024 * 1024 * 2) #define TRUE 1 #define FALSE 0 @@ -25,20 +25,17 @@ }BUFSZ; typedef struct _QUEUE_T{ - unsigned int in; // 次に入れるインデックス - unsigned int out; // 次に出すインデックス - unsigned int size; // キューのサイズ - unsigned int no_full; // 満タンになると 0 になる - unsigned int no_empty; // 空っぽになると 0 になる - pthread_mutex_t mutex; - pthread_cond_t cond_full; // データが満タンのときに待つための cond - pthread_cond_t cond_empty; // データが空のときに待つための cond - BUFSZ *buffer[1]; // バッファポインタ + unsigned int in; // 次に入れるインデックス + unsigned int out; // 次に出すインデックス + unsigned int size; // キューのサイズ + unsigned int no_full; // 満タンになると 0 になる + unsigned int no_empty; // 空っぽになると 0 になる + pthread_mutex_t mutex; + pthread_cond_t cond_full; // データが満タンのときに待つための cond + pthread_cond_t cond_empty; // データが空のときに待つための cond + BUFSZ *buffer[1]; // バッファポインタ }QUEUE_T; -int wfd; // ファイル書き込み用 -int f_exit = FALSE ; - typedef struct _ISDB_T_FREQ_CONV_TABLE { int set_freq ; // 実際にioctl()を行う値 int type ; // チャンネルタイプ