Mercurial > pt1
diff 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 |
line wrap: on
line diff
--- a/recpt1/recpt1.c Thu Apr 25 15:08:35 2013 +0900 +++ b/recpt1/recpt1.c Thu Apr 25 16:06:15 2013 +0900 @@ -20,18 +20,18 @@ #include <arpa/inet.h> #include <netinet/in.h> +#include <sys/ipc.h> +#include <sys/msg.h> + #include <sys/ioctl.h> #include "pt1_ioctl.h" #include "config.h" #include "decoder.h" +#include "recpt1core.h" #include "recpt1.h" -#include "version.h" #include "mkpath.h" -#include <sys/ipc.h> -#include <sys/msg.h> -#include "pt1_dev.h" #include "tssplitter_lite.h" /* maximum write length at once */ @@ -40,60 +40,18 @@ /* ipc message size */ #define MSGSZ 255 -#define ISDB_T_NODE_LIMIT 24 // 32:ARIB limit 24:program maximum -#define ISDB_T_SLOT_LIMIT 8 - -/* type definitions */ -typedef int boolean; - -typedef struct sock_data { - int sfd; /* socket fd */ - struct sockaddr_in addr; -} sock_data; - -typedef struct thread_data { - QUEUE_T *queue; - decoder *decoder; - decoder_options *dopt; - int ch; - int lnb; /* LNB voltage */ - int tfd; /* tuner fd */ - int wfd; /* output file fd */ - ISDB_T_FREQ_CONV_TABLE *table; - sock_data *sock_data; - pthread_t signal_thread; - int recsec; - time_t start_time; - boolean indefinite; - int msqid; - splitter *splitter; -} thread_data; - -typedef struct msgbuf { - long mtype; - char mtext[MSGSZ]; -} message_buf; - /* globals */ -boolean f_exit = FALSE; -char bs_channel_buf[8]; -ISDB_T_FREQ_CONV_TABLE isdb_t_conv_set = { 0, CHTYPE_SATELLITE, 0, bs_channel_buf }; - -/* prototypes */ -ISDB_T_FREQ_CONV_TABLE *searchrecoff(char *channel); -void calc_cn(int fd, int type); -int tune(char *channel, thread_data *tdata, char *device); -int close_tuner(thread_data *tdata); +extern boolean f_exit; -/* ipc message receive */ +/* will be ipc message receive thread */ void * mq_recv(void *t) { thread_data *tdata = (thread_data *)t; message_buf rbuf; char channel[16]; - int ch = 0, recsec = 0, time_to_add = 0; + int recsec = 0, time_to_add = 0; while(1) { if(msgrcv(tdata->msqid, &rbuf, MSGSZ, 1, 0) < 0) { @@ -101,22 +59,8 @@ } sscanf(rbuf.mtext, "ch=%s t=%d e=%d", channel, &recsec, &time_to_add); - ch = atoi(channel); -// fprintf(stderr, "ch=%d time=%d extend=%d\n", ch, recsec, time_to_add); - if(ch && tdata->ch != ch) { -#if 0 - /* re-initialize decoder */ - if(tdata->decoder) { -// b25_finish(tdata->decoder); - b25_shutdown(tdata->decoder); - tdata->decoder = b25_startup(tdata->dopt); - if(!tdata->decoder) { - fprintf(stderr, "Cannot start b25 decoder\n"); - fprintf(stderr, "Fall back to encrypted recording\n"); - } - } -#endif + if(strcmp(channel, tdata->table->parm_freq)) { int current_type = tdata->table->type; ISDB_T_FREQ_CONV_TABLE *table = searchrecoff(channel); if (table == NULL) { @@ -147,11 +91,9 @@ }; if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { fprintf(stderr, "Cannot tune to the specified channel\n"); - tdata->ch = 0; goto CHECK_TIME_TO_ADD; } - tdata->ch = ch; - calc_cn(tdata->tfd, tdata->table->type); + calc_cn(tdata->tfd, tdata->table->type, FALSE); } /* restart recording */ if(ioctl(tdata->tfd, START_REC, 0) < 0) { @@ -184,47 +126,6 @@ } -/* lookup frequency conversion table*/ -ISDB_T_FREQ_CONV_TABLE * -searchrecoff(char *channel) -{ - int lp; - - if(channel[0] == 'B' && channel[1] == 'S') { - int node = 0; - int slot = 0; - char *bs_ch; - - bs_ch = channel + 2; - while(isdigit(*bs_ch)) { - node *= 10; - node += *bs_ch++ - '0'; - } - if(*bs_ch == '_' && (node&0x01) && node < ISDB_T_NODE_LIMIT) { - if(isdigit(*++bs_ch)) { - slot = *bs_ch - '0'; - if(*++bs_ch == '\0' && slot < ISDB_T_SLOT_LIMIT) { - isdb_t_conv_set.set_freq = node / 2; - isdb_t_conv_set.add_freq = slot; - sprintf(bs_channel_buf, "BS%d_%d", node, slot); - return &isdb_t_conv_set; - } - } - } - return NULL; - } - for(lp = 0; isdb_t_conv_table[lp].parm_freq != NULL; lp++) { - /* return entry number in the table when strings match and - * lengths are same. */ - 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) { @@ -355,17 +256,17 @@ void * reader_func(void *p) { - thread_data *data = (thread_data *)p; - QUEUE_T *p_queue = data->queue; - decoder *dec = data->decoder; - splitter *splitter = data->splitter; - int wfd = data->wfd; + thread_data *tdata = (thread_data *)p; + QUEUE_T *p_queue = tdata->queue; + decoder *dec = tdata->decoder; + splitter *splitter = tdata->splitter; + int wfd = tdata->wfd; boolean use_b25 = dec ? TRUE : FALSE; - boolean use_udp = data->sock_data ? TRUE : FALSE; + boolean use_udp = tdata->sock_data ? TRUE : FALSE; boolean fileless = FALSE; boolean use_splitter = splitter ? TRUE : FALSE; int sfd = -1; - pthread_t signal_thread = data->signal_thread; + pthread_t signal_thread = tdata->signal_thread; struct sockaddr_in *addr = NULL; BUFSZ *qbuf; static splitbuf_t splitbuf; @@ -382,8 +283,8 @@ fileless = TRUE; if(use_udp) { - sfd = data->sock_data->sfd; - addr = &data->sock_data->addr; + sfd = tdata->sock_data->sfd; + addr = &tdata->sock_data->addr; } while(1) { @@ -440,7 +341,7 @@ */ time_t cur_time; time(&cur_time); - if(cur_time - data->start_time > 4) { + if(cur_time - tdata->start_time > 4) { use_splitter = FALSE; goto fin; } @@ -569,7 +470,7 @@ time_t cur_time; time(&cur_time); fprintf(stderr, "Recorded %dsec\n", - (int)(cur_time - data->start_time)); + (int)(cur_time - tdata->start_time)); return NULL; } @@ -610,119 +511,11 @@ } void -show_channels(void) -{ - FILE *f; - char *home; - char buf[255], filename[255]; - - fprintf(stderr, "Available Channels:\n"); - - home = getenv("HOME"); - sprintf(filename, "%s/.recpt1-channels", home); - f = fopen(filename, "r"); - if(f) { - while(fgets(buf, 255, f)) - fprintf(stderr, "%s", buf); - fclose(f); - } - else - fprintf(stderr, "13-62: Terrestrial Channels\n"); - - fprintf(stderr, "101ch: NHK BS1\n"); - fprintf(stderr, "102ch: NHK BS2\n"); - fprintf(stderr, "103ch: NHK BShi\n"); - fprintf(stderr, "141ch: BS Nittele\n"); - fprintf(stderr, "151ch: BS Asahi\n"); - fprintf(stderr, "161ch: BS-TBS\n"); - fprintf(stderr, "171ch: BS Japan\n"); - fprintf(stderr, "181ch: BS Fuji\n"); - fprintf(stderr, "191ch: WOWOW\n"); - fprintf(stderr, "192ch: WOWOW2\n"); - fprintf(stderr, "193ch: WOWOW3\n"); - fprintf(stderr, "200ch: Star Channel\n"); - fprintf(stderr, "211ch: BS11 Digital\n"); - fprintf(stderr, "222ch: TwellV\n"); - fprintf(stderr, "C13-C63: CATV Channels\n"); - fprintf(stderr, "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 - 18.61f, // 20 00 8192 18.61dB - 15.21f, // 30 00 12288 15.21dB - 12.50f, // 40 00 16384 12.50dB - 10.19f, // 50 00 20480 10.19dB - 8.140f, // 60 00 24576 8.140dB - 6.270f, // 70 00 28672 6.270dB - 4.550f, // 80 00 32768 4.550dB - 3.730f, // 88 00 34816 3.730dB - 3.630f, // 88 FF 35071 3.630dB - 2.940f, // 90 00 36864 2.940dB - 1.420f, // A0 00 40960 1.420dB - 0.000f // B0 00 45056 -0.01dB - }; - - unsigned char sigbuf[4]; - memset(sigbuf, '\0', sizeof(sigbuf)); - 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; - return afLevelTable[sigbuf[0] >> 4] * (1.0f - fMixRate) + - afLevelTable[(sigbuf[0] >> 4) + 0x01U] * fMixRate; - } -} - -void -calc_cn(int fd, int type) -{ - int rc ; - double P ; - double CNR; - - if(ioctl(fd, GET_SIGNAL_STRENGTH, &rc) < 0) { - fprintf(stderr, "Tuner Select Error\n"); - return ; - } - - if(type == CHTYPE_GROUND) { - P = log10(5505024/(double)rc) * 10; - CNR = (0.000024 * P * P * P * P) - (0.0016 * P * P * P) + - (0.0398 * P * P) + (0.5491 * P)+3.0965; - fprintf(stderr, "C/N = %fdB\n", CNR); - } - else { - CNR = getsignal_isdb_s(rc); - fprintf(stderr, "C/N = %fdB\n", CNR); - } -} - -void cleanup(thread_data *tdata) { /* stop recording */ ioctl(tdata->tfd, STOP_REC, 0); - /* xxx need mutex? */ f_exit = TRUE; pthread_cond_signal(&tdata->queue->cond_avail); @@ -731,11 +524,11 @@ /* will be signal handler thread */ void * -process_signals(void *data) +process_signals(void *t) { sigset_t waitset; int sig; - thread_data *tdata = (thread_data *)data; + thread_data *tdata = (thread_data *)t; sigemptyset(&waitset); sigaddset(&waitset, SIGPIPE); @@ -790,166 +583,6 @@ } int -tune(char *channel, thread_data *tdata, char *device) -{ - char **tuner; - int num_devs; - int lp; - FREQUENCY freq; - - /* get channel */ - tdata->table = searchrecoff(channel); - if(tdata->table == NULL) { - fprintf(stderr, "Invalid Channel: %s\n", channel); - return 1; - } - - freq.frequencyno = tdata->table->set_freq; - freq.slot = tdata->table->add_freq; - - /* open tuner */ - /* case 1: specified tuner device */ - if(device) { - tdata->tfd = open(device, O_RDONLY); - if(tdata->tfd < 0) { - fprintf(stderr, "Cannot open tuner device: %s\n", device); - return 1; - } - - /* power on LNB */ - if(tdata->table->type == CHTYPE_SATELLITE) { - if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) { - fprintf(stderr, "Power on LNB failed: %s\n", device); - } - } - - /* tune to specified channel */ - if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { - close(tdata->tfd); - fprintf(stderr, "Cannot tune to the specified channel: %s\n", device); - return 1; - } - else { - tdata->ch = atoi(channel); - } - } - else { - /* case 2: loop around available devices */ - if(tdata->table->type == CHTYPE_SATELLITE) { - tuner = bsdev; - num_devs = NUM_BSDEV; - } - else { - tuner = isdb_t_dev; - num_devs = NUM_ISDB_T_DEV; - } - - for(lp = 0; lp < num_devs; lp++) { - tdata->tfd = open(tuner[lp], O_RDONLY); - if(tdata->tfd >= 0) { - /* power on LNB */ - if(tdata->table->type == CHTYPE_SATELLITE) { - if(ioctl(tdata->tfd, LNB_ENABLE, tdata->lnb) < 0) { - fprintf(stderr, "Warning: Power on LNB failed: %s\n", tuner[lp]); - } - } - - /* tune to specified channel */ - if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { - close(tdata->tfd); - tdata->tfd = -1; - continue; - } - - break; /* found suitable tuner */ - } - } - - /* all tuners cannot be used */ - if(tdata->tfd < 0) { - fprintf(stderr, "Cannot tune to the specified channel\n"); - return 1; - } - else { - tdata->ch = atoi(channel); - } - } - - /* show signal strength */ - calc_cn(tdata->tfd, tdata->table->type); - - return 0; /* success */ -} - -int -parse_time(char *rectimestr, thread_data *tdata) -{ - /* indefinite */ - if(!strcmp("-", rectimestr)) { - tdata->indefinite = TRUE; - tdata->recsec = -1; - } - /* colon */ - else if(strchr(rectimestr, ':')) { - int n1, n2, n3; - if(sscanf(rectimestr, "%d:%d:%d", &n1, &n2, &n3) == 3) - tdata->recsec = n1 * 3600 + n2 * 60 + n3; - else if(sscanf(rectimestr, "%d:%d", &n1, &n2) == 2) - tdata->recsec = n1 * 3600 + n2 * 60; - } - /* HMS */ - else { - char *tmpstr; - char *p1, *p2; - - tmpstr = strdup(rectimestr); - p1 = tmpstr; - while(*p1 && !isdigit(*p1)) - p1++; - - /* hour */ - if((p2 = strchr(p1, 'H')) || (p2 = strchr(p1, 'h'))) { - *p2 = '\0'; - tdata->recsec += atoi(p1) * 3600; - p1 = p2 + 1; - while(*p1 && !isdigit(*p1)) - p1++; - } - - /* minute */ - if((p2 = strchr(p1, 'M')) || (p2 = strchr(p1, 'm'))) { - *p2 = '\0'; - tdata->recsec += atoi(p1) * 60; - p1 = p2 + 1; - while(*p1 && !isdigit(*p1)) - p1++; - } - - /* second */ - tdata->recsec += atoi(p1); - - free(tmpstr); - } - - return 0; /* success */ -} - -int -close_tuner(thread_data *tdata) -{ - int rv = 0; - - if(tdata->table->type == CHTYPE_SATELLITE) { - if(ioctl(tdata->tfd, LNB_DISABLE, 0) < 0) { - rv = 1; - } - } - close(tdata->tfd); - - return rv; -} - -int main(int argc, char **argv) { time_t cur_time; @@ -958,7 +591,7 @@ pthread_t ipc_thread; QUEUE_T *p_queue = create_queue(MAX_QUEUE); BUFSZ *bufptr; - decoder *dec = NULL; + decoder *decoder = NULL; splitter *splitter = NULL; static thread_data tdata; decoder_options dopt = { @@ -1105,9 +738,12 @@ return 1; /* set recsec */ - if(parse_time(argv[optind + 1], &tdata) != 0) + if(parse_time(argv[optind + 1], &tdata.recsec) != 0) // no other thread --yaz return 1; + if(tdata.recsec == -1) + tdata.indefinite = TRUE; + /* open output file */ char *destfile = argv[optind + 2]; if(destfile && !strcmp("-", destfile)) { @@ -1135,8 +771,8 @@ /* initialize decoder */ if(use_b25) { - dec = b25_startup(&dopt); - if(!dec) { + decoder = b25_startup(&dopt); + if(!decoder) { fprintf(stderr, "Cannot start b25 decoder\n"); fprintf(stderr, "Fall back to encrypted recording\n"); use_b25 = FALSE; @@ -1182,9 +818,10 @@ /* prepare thread data */ tdata.queue = p_queue; - tdata.decoder = dec; + tdata.decoder = decoder; tdata.splitter = splitter; tdata.sock_data = sockdata; + tdata.tune_persistent = FALSE; /* spawn signal handler thread */ init_signal_handlers(&signal_thread, &tdata); @@ -1208,7 +845,7 @@ return 1; } - fprintf(stderr, "Recording...\n"); + fprintf(stderr, "\nRecording...\n"); time(&tdata.start_time); @@ -1289,7 +926,7 @@ /* release decoder */ if(use_b25) { - b25_shutdown(dec); + b25_shutdown(decoder); } if(use_splitter) { split_shutdown(splitter);