# HG changeset patch # User Naoya OYAMA # Date 1349095925 -32400 # Node ID 7d8a5bb874ad3688294adbd2ab10298a4a4ba5de # Parent 57eae2aec60dd73e33ff3e794125ec119cb3ee3a EXPERIMENTAL: Change phisical channel by mq_recv(). KNOWN ISSUE: Cannnot split BS-TBS(BS1_1). enable compile recpt1ctl. SID can specified by recpt1ctl. diff -r 57eae2aec60d -r 7d8a5bb874ad src/Makefile --- a/src/Makefile Mon Sep 24 20:49:17 2012 +0900 +++ b/src/Makefile Mon Oct 01 21:52:05 2012 +0900 @@ -6,6 +6,7 @@ PROG = recpt1 PROG2 = checksignal PROG3 = pt1_lnbd +PROG4 = recpt1ctl EXTRADIST = ushare.1 \ cds.h \ @@ -35,6 +36,7 @@ upnp_device.h \ upnp_main.h \ version.h \ + pt1_common.h \ SRCS = \ cds.c \ @@ -65,15 +67,19 @@ SRCS3 = \ pt1_lnbd.c +SRCS4 = \ + recpt1ctl.c + LIBS2 = -lpthread -lm OBJS = $(SRCS:.c=.o) OBJS2 = $(SRCS2:.c=.o) OBJS3 = $(SRCS3:.c=.o) +OBJS4 = $(SRCS4:.c=.o) .SUFFIXES: .c .o -all: depend $(PROG) $(PROG2) $(PROG3) +all: depend $(PROG) $(PROG2) $(PROG3) $(PROG4) .c.o: $(CC) -c $(CFLAGS) -g $(OPTFLAGS) -o $@ $< @@ -87,22 +93,27 @@ $(PROG3): $(OBJS3) $(CC) $(OBJS3) $(LDFLAGS) $(EXTRALIBS) -o $@ +$(PROG4): $(OBJS4) + $(CC) $(OBJS3) $(LDFLAGS) $(EXTRALIBS) -o $@ + clean: - -$(RM) -f *.o $(PROG) $(PROG2) $(PROG3) + -$(RM) -f *.o $(PROG) $(PROG2) $(PROG3) $(PROG4) -$(RM) -f .depend distclean: -install: $(PROG) $(PROG2) $(PROG3) +install: $(PROG) $(PROG2) $(PROG3) $(PROG4) $(INSTALL) -d $(bindir) $(INSTALL) $(PROG) $(bindir) $(INSTALL) $(PROG2) $(bindir) $(INSTALL) $(PROG3) $(bindir) + $(INSTALL) $(PROG4) $(bindir) $(INSTALL) channelscan_pt1.sh $(bindir) $(INSTALL) epgdump_xml_parse.pl $(bindir) $(STRIP) $(INSTALLSTRIP) $(bindir)/$(PROG) $(STRIP) $(INSTALLSTRIP) $(bindir)/$(PROG2) $(STRIP) $(INSTALLSTRIP) $(bindir)/$(PROG3) + $(STRIP) $(INSTALLSTRIP) $(bindir)/$(PROG4) depend: $(CC) -I.. -MM $(CFLAGS) $(SRCS) 1>.depend diff -r 57eae2aec60d -r 7d8a5bb874ad src/checksignal.c --- a/src/checksignal.c Mon Sep 24 20:49:17 2012 +0900 +++ b/src/checksignal.c Mon Oct 01 21:52:05 2012 +0900 @@ -36,9 +36,6 @@ #define MAX_RETRY (2) -/* type definitions */ -typedef int boolean; - /* globals */ boolean f_exit = FALSE; boolean use_bell = FALSE; @@ -48,18 +45,17 @@ int close_tuner(thread_data *tdata); void -cleanup(thread_data *tdata) +cleanup(void) { f_exit = TRUE; } /* will be signal handler thread */ void * -process_signals(void *data) +process_signals(void *p) { sigset_t waitset; int sig; - thread_data *tdata = (thread_data *)data; sigemptyset(&waitset); sigaddset(&waitset, SIGINT); @@ -71,14 +67,14 @@ switch(sig) { case SIGINT: fprintf(stderr, "\nSIGINT received. cleaning up...\n"); - cleanup(tdata); + cleanup(); break; case SIGTERM: fprintf(stderr, "\nSIGTERM received. cleaning up...\n"); - cleanup(tdata); + cleanup(); break; case SIGUSR1: /* normal exit*/ - cleanup(tdata); + cleanup(); break; } @@ -86,7 +82,7 @@ } void -init_signal_handlers(pthread_t *signal_thread, thread_data *tdata) +init_signal_handlers(pthread_t *signal_thread) { sigset_t blockset; @@ -98,7 +94,7 @@ if(pthread_sigmask(SIG_BLOCK, &blockset, NULL)) fprintf(stderr, "pthread_sigmask() failed.\n"); - pthread_create(signal_thread, NULL, process_signals, tdata); + pthread_create(signal_thread, NULL, process_signals, NULL); } /* lookup frequency conversion table*/ @@ -309,7 +305,7 @@ } fprintf(stderr, "device = %s\n", device); - tdata->ch = atoi(channel); + strncpy(tdata->ch, channel, sizeof(tdata->ch)); } else { /* case 2: loop around available devices */ @@ -362,7 +358,7 @@ return 1; } else { - tdata->ch = atoi(channel); + strncpy(tdata->ch, channel, sizeof(tdata->ch)); } } @@ -464,7 +460,7 @@ } /* spawn signal handler thread */ - init_signal_handlers(&signal_thread, &tdata); + init_signal_handlers(&signal_thread); /* tune */ if(tune(argv[optind], &tdata, device) != 0) diff -r 57eae2aec60d -r 7d8a5bb874ad src/recpt1.c --- a/src/recpt1.c Mon Sep 24 20:49:17 2012 +0900 +++ b/src/recpt1.c Mon Oct 01 21:52:05 2012 +0900 @@ -36,21 +36,14 @@ #include "tssplitter_lite.h" #include "ushare.h" #include "trace.h" +#include "pt1_common.h" /* maximum write length at once */ #define SIZE_CHANK 1316 -/* ipc message size */ -#define MSGSZ 255 - #define ISDB_T_NODE_LIMIT 24 // 32:ARIB limit 24:program maximum #define ISDB_T_SLOT_LIMIT 8 -typedef struct pt1_msgbuf { - long mtype; - char mtext[MSGSZ]; -} pt1_message_buf; - /* globals */ boolean f_exit = FALSE; struct channel_info_list *channel_list = NULL; @@ -167,19 +160,23 @@ { thread_data *tdata = (thread_data *)t; pt1_message_buf rbuf; - char channel[16]; - int ch = 0, recsec = 0, time_to_add = 0; + static char channel[16]; + static char sid_list[16]; + int recsec = 0, time_to_add = 0; + int current_type; + splitter *splitter = tdata->splitter; + boolean use_splitter = splitter ? TRUE : FALSE; + boolean use_dlna = tdata->streamer ? TRUE : FALSE; + ISDB_T_FREQ_CONV_TABLE *table = NULL; while(1) { if(msgrcv(tdata->msqid, &rbuf, MSGSZ, 1, 0) < 0) { return NULL; } - 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); + sscanf(rbuf.mtext, "ch=%s t=%d e=%d i=%s", channel, &recsec, &time_to_add, sid_list); - if(ch && tdata->ch != ch) { + if ((strcmp(channel, "")) && strcmp(tdata->ch, channel)) { #if 0 /* re-initialize decoder */ if(tdata->decoder) { @@ -192,8 +189,8 @@ } } #endif - int current_type = tdata->table->type; - ISDB_T_FREQ_CONV_TABLE *table = searchrecoff(channel); + current_type = tdata->table->type; + table = searchrecoff(channel); if (table == NULL) { fprintf(stderr, "Invalid Channel: %s\n", channel); goto CHECK_TIME_TO_ADD; @@ -207,7 +204,47 @@ while(tdata->queue->num_used > 0) { usleep(10000); } + } + if (use_splitter && + (strcmp(tdata->sid_list, sid_list) || + strcmp(tdata->ch, channel))) { + // $BJ*M}%A%c%s%M%kJQ99;~$K$O(B splitter $B$O6/@)E*$K:F5/F0$5$;$k(B + pthread_mutex_lock(&tdata->splitter_mutex); + split_shutdown(splitter); + splitter = split_startup(sid_list, NULL, NULL); + if (splitter->sid_list == NULL) { + fprintf (stderr, "reader_func() splitter RESTART FAILED.\n"); + tdata->splitter = NULL; + pthread_mutex_unlock(&tdata->splitter_mutex); + continue; + } + if (tdata->streamer) { + pthread_mutex_lock(&tdata->stream_queue->mutex); + while(1) { + STREAM_QUEUE_T *p_queue = tdata->stream_queue; + if (p_queue->num_used == 0) + break; + free(p_queue->buffer[p_queue->out]->data); + p_queue->buffer[p_queue->out]->data = NULL; + free(p_queue->buffer[p_queue->out]); + p_queue->buffer[p_queue->out] = NULL; + p_queue->out++; + p_queue->out %= p_queue->size; + /* update counters */ + p_queue->num_avail++; + p_queue->num_used--; + } + pthread_mutex_unlock(&tdata->stream_queue->mutex); + } + tdata->table = table; + tdata->splitter = splitter; + time(&splitter->split_start_time); + strncpy(tdata->sid_list, sid_list, sizeof(tdata->sid_list)); + pthread_mutex_unlock(&tdata->splitter_mutex); + } + + if (strcmp(tdata->ch, channel)) { if (tdata->table->type != current_type) { /* re-open device */ if(close_tuner(tdata) != 0) @@ -216,16 +253,15 @@ tune(channel, tdata, NULL); } else { /* SET_CHANNEL only */ - const FREQUENCY freq = { - .frequencyno = tdata->table->set_freq, - .slot = tdata->table->add_freq, - }; - 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; + const FREQUENCY freq = { + .frequencyno = tdata->table->set_freq, + .slot = tdata->table->add_freq, + }; + if(ioctl(tdata->tfd, SET_CHANNEL, &freq) < 0) { + fprintf(stderr, "Cannot tune to the specified channel\n"); + tdata->ch[0] = '\0'; + goto CHECK_TIME_TO_ADD; + } calc_cn(tdata->tfd, tdata->table->type); } /* restart recording */ @@ -233,6 +269,7 @@ fprintf(stderr, "Tuner cannot start recording\n"); return NULL; } + strncpy(tdata->ch, channel, sizeof(tdata->ch)); } CHECK_TIME_TO_ADD: @@ -252,7 +289,6 @@ fprintf(stderr, "Total recording time = %d sec\n", recsec); } } - if(f_exit) return NULL; } @@ -552,12 +588,11 @@ thread_data *data = (thread_data *)p; QUEUE_T *p_queue = data->queue; decoder *dec = data->decoder; - splitter *splitter = data->splitter; int wfd = data->wfd; boolean use_b25 = dec ? TRUE : FALSE; boolean use_udp = data->sock_data ? TRUE : FALSE; boolean fileless = FALSE; - boolean use_splitter = splitter ? TRUE : FALSE; + boolean use_splitter = data->splitter ? TRUE : FALSE; boolean use_dlna = data->streamer ? TRUE : FALSE; int sfd = -1; pthread_t signal_thread = data->signal_thread; @@ -567,12 +602,12 @@ splitbuf_t splitbuf; ARIB_STD_B25_BUFFER sbuf, dbuf, buf; int code; - int split_select_finish = TSS_ERROR; - int old_sid = 0, new_sid = 0; - char *old_tp = NULL, *new_tp = NULL; - time_t split_start_time; + pt1_message_buf mbuf; + int msqid; + int msgflg = IPC_CREAT | 0666; - time(&split_start_time); + if (use_splitter) + time(&data->splitter->split_start_time); buf.size = 0; buf.data = NULL; @@ -613,6 +648,7 @@ } if(use_splitter) { + pthread_mutex_lock(&data->splitter_mutex); splitbuf.size = 0; if(splitbuf.buffer_length < buf.size && buf.size > 0) { splitbuf.buffer = realloc(splitbuf.buffer, buf.size); @@ -626,21 +662,21 @@ while(buf.size) { /* $BJ,N%BP>](BPID$B$NCj=P(B */ - if(split_select_finish != TSS_SUCCESS) { - split_select_finish = split_select(splitter, &buf); - if(split_select_finish == TSS_NULL) { + if(data->splitter->split_select_finish != TSS_SUCCESS) { + data->splitter->split_select_finish = split_select(data->splitter, &buf); + if(data->splitter->split_select_finish == TSS_NULL) { /* malloc$B%(%i!splitter->split_select_finish != TSS_SUCCESS) { /* $BJ,N%BP>](BPID$B$,40A4$KCj=P$G$-$k$^$G=PNO$7$J$$(B * 1$BICDxEYM>M5$r8+$k$H$$$$$+$b(B */ time_t cur_time; time(&cur_time); - if(cur_time - split_start_time > 4) { + if(cur_time - data->splitter->split_start_time > 4) { fprintf(stderr, "split_select cur_time out.\n"); use_splitter = FALSE; goto fin; @@ -649,7 +685,7 @@ } } /* $BJ,N%BP>]0J30$r$U$k$$Mn$H$9(B */ - code = split_ts(splitter, &buf, &splitbuf); + code = split_ts(data->splitter, &buf, &splitbuf); if(code != TSS_SUCCESS) { fprintf(stderr, "split_ts failed\n"); break; @@ -661,7 +697,7 @@ buf.size = splitbuf.size; buf.data = splitbuf.buffer; fin: - ; + pthread_mutex_unlock(&data->splitter_mutex); } /* if */ /* @@ -678,100 +714,36 @@ * DLNA $B$G$NJ*M}%A%c%s%M%k!&(BSID$BJQ99$N 0 ) { - if ( use_splitter ) { - if (ut->tp) { - if (!old_tp) - old_tp = "0"; - new_tp = ut->tp; - } - if (ut->sid) - new_sid = atoi(ut->sid); - if ((new_tp) && (old_tp)) - if (strcmp(old_tp, new_tp)) { - int current_type = data->table->type; - ISDB_T_FREQ_CONV_TABLE *table = searchrecoff(new_tp); - if (table == NULL) { - fprintf(stderr, "Invalid Channel: %s\n", new_tp); - break; - } - data->table = table; - old_tp = new_tp; - - /* stop stream */ - ioctl(data->tfd, STOP_REC, 0); - pthread_mutex_lock(&data->queue->mutex); - while(data->queue->num_used > 0) { - while(1) { - QUEUE_T *p_queue = data->queue; - if (p_queue->num_used == 0) - break; - free(p_queue->buffer[p_queue->out]); - p_queue->buffer[p_queue->out] = NULL; - p_queue->out++; - p_queue->out %= p_queue->size; + if (use_splitter && (ut->tp) && (ut->sid)) { + if (strcmp(data->ch, ut->tp) || + strcmp(data->sid_list, ut->sid)) { + if ((msqid = msgget((key_t)getpid(), msgflg)) < 0) { + // $B%(%i!<;~$O%A%c%s%M%kJQ99%j%/%(%9%H$O$J$+$C$?$3$H$K$9$k(B + // $B$J$`$J$`(B + fprintf(stderr, "msgget error.\n"); + ut->tp = data->ch; + free(qbuf); + qbuf = NULL; + ut->sid = data->sid_list; + continue; + } - /* update counters */ - p_queue->num_avail++; - p_queue->num_used--; - } - } - pthread_mutex_unlock(&data->queue->mutex); - if (data->table->type != current_type) { - /* re-open device */ - if(close_tuner(data) != 0) - break; - tune(new_tp, data, NULL); - } else { - /* SET_CHANNEL only */ - const FREQUENCY freq = { - .frequencyno = data->table->set_freq, - .slot = data->table->add_freq, - }; - if(ioctl(data->tfd, SET_CHANNEL, &freq) < 0) { - fprintf(stderr, "Cannot tune to the specified channel\n"); - data->ch = 0; - break; - } - data->ch = atoi(new_tp); - calc_cn(data->tfd, data->table->type); - } - if(ioctl(data->tfd, START_REC, 0) < 0) { - // $B$3$3$N07$$$I$3$m$,LB$&$H$3$m!#(Bexit $B$7$F$b$$$$5$$,$9$k(B - fprintf(stderr, "Tuner cannot start recording\n"); - break; - } - time(&split_start_time); + mbuf.mtype = 1; + snprintf(mbuf.mtext, sizeof(mbuf.mtext), + "ch=%s t=%d e=%d i=%s", + ut->tp, 0, 0, ut->sid); + if (msgsnd(msqid, &mbuf, strlen(mbuf.mtext)+1, IPC_NOWAIT) < 0) { + // $B%(%i!<;~$O%A%c%s%M%kJQ99%j%/%(%9%H$O$J$+$C$?$3$H$K$9$k(B + // $B$J$`$J$`(B + fprintf(stderr, "msgsend error.\n"); + ut->tp = data->ch; + ut->sid = data->sid_list; + free(qbuf); + qbuf = NULL; + continue; } - if ( old_sid != new_sid ) { - old_sid = new_sid; - split_shutdown(splitter); - splitter = split_startup(ut->sid, NULL, NULL); - if ( splitter == NULL ) { - fprintf (stderr, "reader_func() splitter RESTART FAILED.\n"); - use_splitter = FALSE; - } - split_select_finish = TSS_ERROR; free(qbuf); qbuf = NULL; - - pthread_mutex_lock(&data->stream_queue->mutex); - while(1) { - STREAM_QUEUE_T *p_queue = data->stream_queue; - if (p_queue->num_used == 0) - break; - free(p_queue->buffer[p_queue->out]->data); - p_queue->buffer[p_queue->out]->data = NULL; - free(p_queue->buffer[p_queue->out]); - p_queue->buffer[p_queue->out] = NULL; - p_queue->out++; - p_queue->out %= p_queue->size; - - /* update counters */ - p_queue->num_avail++; - p_queue->num_used--; - } - pthread_mutex_unlock(&data->stream_queue->mutex); - time(&split_start_time); continue; } } @@ -851,7 +823,7 @@ if(use_splitter) { /* $BJ,N%BP>]0J30$r$U$k$$Mn$H$9(B */ - code = split_ts(splitter, &buf, &splitbuf); + code = split_ts(data->splitter, &buf, &splitbuf); if(code != TSS_SUCCESS) { break; } @@ -1242,7 +1214,7 @@ return 1; } else { - tdata->ch = atoi(channel); + strncpy(tdata->ch, channel, sizeof(tdata->ch)); } } else { @@ -1284,7 +1256,7 @@ return 1; } else { - tdata->ch = atoi(channel); + strncpy(tdata->ch, channel, sizeof(tdata->ch)); } } @@ -1601,6 +1573,7 @@ fprintf(stderr, "Cannot start TS splitter\n"); return 1; } + strncpy(tdata.sid_list, sid_list, sizeof(tdata.sid_list)); } /* initialize DLNA */ @@ -1621,6 +1594,7 @@ tdata.streamer->stream_nr = 0; tdata.streamer->stream_session[0] = NULL; pthread_mutex_init(&tdata.streamer->mutex, NULL); + pthread_mutex_init(&tdata.splitter_mutex, NULL); pthread_create(&stream_thread, NULL, stream_func, &tdata); pthread_create(&dlna_thread, NULL, dlna_startup, NULL); diff -r 57eae2aec60d -r 7d8a5bb874ad src/recpt1.h --- a/src/recpt1.h Mon Sep 24 20:49:17 2012 +0900 +++ b/src/recpt1.h Mon Oct 01 21:52:05 2012 +0900 @@ -85,7 +85,7 @@ QUEUE_T *stream_queue; decoder *decoder; decoder_options *dopt; - int ch; + char ch[16]; /* channel is one of the following. Number, C00, BS0_0, CS0 */ int lnb; /* LNB voltage */ int tfd; /* tuner fd */ int wfd; /* output file fd */ @@ -99,6 +99,8 @@ int msqid; splitter *splitter; streamer *streamer; + char sid_list[256]; + pthread_mutex_t splitter_mutex; } thread_data; struct channel_info { diff -r 57eae2aec60d -r 7d8a5bb874ad src/recpt1ctl.c --- a/src/recpt1ctl.c Mon Sep 24 20:49:17 2012 +0900 +++ b/src/recpt1ctl.c Mon Oct 01 21:52:05 2012 +0900 @@ -9,13 +9,7 @@ #include #include "version.h" - -#define MSGSZ 255 - -typedef struct msgbuf { - long mtype; - char mtext[MSGSZ]; -} message_buf; +#include "pt1_common.h" void show_usage(char *cmd) @@ -130,9 +124,11 @@ int msqid; int msgflg = IPC_CREAT | 0666; key_t key = 0; - int channel=0, recsec = 0, extsec=0; - message_buf sbuf; + int recsec = 0, extsec=0; + char *channel = NULL; + pt1_message_buf sbuf; size_t buf_length; + char *sid_list = NULL; int result; int option_index; @@ -144,10 +140,12 @@ { "help", 0, NULL, 'h'}, { "version", 0, NULL, 'v'}, { "list", 0, NULL, 'l'}, + { "sid", 1, NULL, 'i'}, + { "SID", 1, NULL, 'i'}, {0, 0, NULL, 0} /* terminate */ }; - while((result = getopt_long(argc, argv, "p:c:e:t:hvl", + while((result = getopt_long(argc, argv, "p:c:e:t:hvli", long_options, &option_index)) != -1) { switch(result) { case 'h': @@ -175,8 +173,8 @@ fprintf(stderr, "Pid = %d\n", key); break; case 'c': - channel = atoi(optarg); - fprintf(stderr, "Channel = %d\n", channel); + channel = optarg; + fprintf(stderr, "Channel = %s\n", channel); break; case 'e': parse_time(optarg, &extsec); @@ -186,6 +184,9 @@ parse_time(optarg, &recsec); fprintf(stderr, "Total recording time = %d sec\n", recsec); break; + case 'i': + sid_list = optarg; + break; } } @@ -201,7 +202,7 @@ } sbuf.mtype = 1; - sprintf(sbuf.mtext, "ch=%d t=%d e=%d", channel, recsec, extsec); + sprintf(sbuf.mtext, "ch=%s t=%d e=%d i=%s", channel, recsec, extsec, sid_list); buf_length = strlen(sbuf.mtext) + 1 ; diff -r 57eae2aec60d -r 7d8a5bb874ad src/tssplitter_lite.c --- a/src/tssplitter_lite.c Mon Sep 24 20:49:17 2012 +0900 +++ b/src/tssplitter_lite.c Mon Oct 01 21:52:05 2012 +0900 @@ -264,6 +264,7 @@ } else { sp->arg_cue = "00000000000000"; /* とりあえず最小値 */ } + sp->split_select_finish = TSS_ERROR; return sp; } diff -r 57eae2aec60d -r 7d8a5bb874ad src/tssplitter_lite.h --- a/src/tssplitter_lite.h Mon Sep 24 20:49:17 2012 +0900 +++ b/src/tssplitter_lite.h Mon Oct 01 21:52:05 2012 +0900 @@ -199,6 +199,8 @@ time_t time_cue; time_t time_tot; int tot_packet_nb; /* TOT受信時のパケット受信数 */ + time_t split_start_time; + int split_select_finish; } splitter; /* b25 decoder would hoard up large chank */