diff src/recpt1.c @ 164:7d8a5bb874ad

EXPERIMENTAL: Change phisical channel by mq_recv(). KNOWN ISSUE: Cannnot split BS-TBS(BS1_1). enable compile recpt1ctl. SID can specified by recpt1ctl.
author Naoya OYAMA <naoya.oyama@gmail.com>
date Mon, 01 Oct 2012 21:52:05 +0900
parents 57eae2aec60d
children 726fe10d9e4a
line wrap: on
line diff
--- 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!<H/@8(B */
                         fprintf(stderr, "split_select malloc failed\n");
                         use_splitter = FALSE;
                         goto fin;
                     }
-                    else if(split_select_finish != TSS_SUCCESS) {
+                    else if(data->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<BAu<B83(B
          */
         if ( use_dlna && buf.size > 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);