changeset 146:066f33b2213a

EXPERIMENTAL: Select a particular program from multi-channel.
author Naoya OYAMA <naoya.oyama@gmail.com>
date Tue, 21 Aug 2012 04:21:11 +0900
parents 4e39ce051c57
children f5e1ce2a62a6
files src/http.c src/metadata.c src/recpt1.c src/tssplitter_lite.c src/tssplitter_lite.h src/ushare.c src/ushare.h
diffstat 7 files changed, 127 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- a/src/http.c	Thu Aug 16 21:57:34 2012 +0900
+++ b/src/http.c	Tue Aug 21 04:21:11 2012 +0900
@@ -97,7 +97,7 @@
 {
     extern struct ushare_t *ut;
     struct upnp_entry_t *entry = NULL;
-    int upnp_id = 0;
+    int i, upnp_id = 0;
     char *content_type = NULL;
     char *protocol = NULL;
 
@@ -109,19 +109,28 @@
     upnp_id = atoi (strrchr (filename, '/') + 1);
     entry = upnp_get_entry (ut, upnp_id);
 
-#if 0
-    if ( (!strcmp (filename, STREAM_LOCATION)) ||
-          ( (entry->fullpath != NULL) &&
-            ( !strcmp(entry->fullpath, STREAM_LOCATION))) ) {
-#endif
-    if (!strcmp (filename, STREAM_LOCATION)) {
-        log_verbose ("http_get_info, stream location found.\n");
-        info->is_readable = 1;
-        info->file_length = get_streaming_length();
-        info->last_modified = time(NULL);
-        info->is_directory = 0;
-        info->content_type = ixmlCloneDOMString ("video/mpeg");
-        return 0;
+    if (ut->nr_channel == 0) {
+       if (!strcmp (filename, STREAM_LOCATION)) {
+           log_verbose ("http_get_info, stream location found.\n");
+           info->is_readable = 1;
+           info->file_length = get_streaming_length();
+           info->last_modified = time(NULL);
+           info->is_directory = 0;
+           info->content_type = ixmlCloneDOMString ("video/mpeg");
+           return 0;
+       }
+    } else {
+       for (i=0; i < ut->nr_channel; i++) {
+           if (!strcmp(filename, ut->location_name[i])) {
+              log_verbose ("http_get_info, stream location found [%s].\n", filename);
+              info->is_readable = 1;
+              info->file_length = get_streaming_length();
+              info->last_modified = time(NULL);
+              info->is_directory = 0;
+              info->content_type = ixmlCloneDOMString ("video/mpeg");
+              return 0;
+           }
+       }
     }
     if (!strcmp (filename, CDS_LOCATION))
     {
@@ -330,9 +339,10 @@
     extern struct ushare_t *ut;
     struct upnp_entry_t *entry = NULL;
     struct web_file_t *file;
-    int fd, upnp_id = 0;
+    int i, fd, upnp_id = 0;
     extern thread_data *gp_tdata;
     thread_data *tdata = gp_tdata;
+    int channel_length = 0;
 
     if (!filename)
         return NULL;
@@ -367,8 +377,18 @@
      * get_file_stream()$B$r8F$S=P$7%O%s%I%i$rJV5Q$9$k(B
      */
     log_verbose ("Fullpath : %s\n", entry->fullpath);
-    if (!strcmp (entry->fullpath, STREAM_LOCATION))
-        return get_file_stream (STREAM_LOCATION, tdata);
+    if (ut->nr_channel == 0) {
+        if (!strcmp (entry->fullpath, STREAM_LOCATION))
+            return get_file_stream (STREAM_LOCATION, tdata);
+    } else {
+        for (i=0; i < ut->nr_channel; i++)
+            if (!strcmp(entry->fullpath, ut->location_name[i])) {
+                channel_length = strspn(ut->channel_name[i], "0123456789");
+                strncpy(ut->request_channel, ut->channel_name[i], channel_length);
+                log_verbose ("http_open: request_channel[%s].\n", ut->request_channel);
+                return get_file_stream (ut->location_name[i], tdata);
+            }
+    }
 
     fd = open (entry->fullpath, O_RDONLY | O_NONBLOCK | O_SYNC | O_NDELAY);
     if (fd < 0)
@@ -528,6 +548,7 @@
     static int
 http_close (UpnpWebFileHandle fh)
 {
+    extern struct ushare_t *ut;
     struct web_file_t *file = (struct web_file_t *) fh;
     extern thread_data *gp_tdata;
     thread_data *tdata = gp_tdata;
@@ -569,6 +590,8 @@
                 pthread_mutex_unlock(&p_queue->mutex);
                 destroy_stream_queue(p_queue);
                 tdata->streamer->stream_session[id]->p_queue = NULL;
+                strcpy(ut->request_channel, "all");
+                ut->nr_channel = 0;
             }
             break;
         default:
--- a/src/metadata.c	Thu Aug 16 21:57:34 2012 +0900
+++ b/src/metadata.c	Tue Aug 21 04:21:11 2012 +0900
@@ -564,7 +564,12 @@
 #endif
   struct upnp_entry_t *entry = ut->root_entry;
   st.st_size = 100*1024*1024;
-  metadata_add_file (ut, ut->root_entry, STREAM_LOCATION, STREAM_FILE_NAME, &st);
+  if (ut->nr_channel == 0) {
+    metadata_add_file (ut, ut->root_entry, STREAM_LOCATION, STREAM_FILE_NAME, &st);
+  } else {
+    for (i=0; i < ut->nr_channel; i++)
+      metadata_add_file (ut, ut->root_entry, ut->location_name[i], ut->channel_name[i], &st);
+  }
   ut->contentlist = NULL;
   //metadata_add_container (ut, ut->root_entry, "/web/");
 
--- a/src/recpt1.c	Thu Aug 16 21:57:34 2012 +0900
+++ b/src/recpt1.c	Tue Aug 21 04:21:11 2012 +0900
@@ -50,6 +50,7 @@
 
 /* globals */
 boolean f_exit = FALSE;
+extern struct ushare_t *ut;
 
 /* prototypes */
 int tune(char *channel, thread_data *tdata, char *device);
@@ -414,6 +415,10 @@
     ARIB_STD_B25_BUFFER sbuf, dbuf, buf;
     int code;
     int split_select_finish = TSS_ERROR;
+    int old_sid = 0, new_sid = 0;
+    time_t split_start_time;
+
+    time(&split_start_time);
 
     buf.size = 0;
     buf.data = NULL;
@@ -453,7 +458,6 @@
                 buf = dbuf;
         }
 
-
         if(use_splitter) {
             splitbuf.size = 0;
             if(splitbuf.buffer_length < buf.size && buf.size > 0) {
@@ -482,7 +486,8 @@
                          */
                         time_t cur_time;
                         time(&cur_time);
-                        if(cur_time - data->start_time > 4) {
+                        if(cur_time - split_start_time > 4) {
+                            fprintf(stderr, "split_select cur_time out.\n");
                             use_splitter = FALSE;
                             goto fin;
                         }
@@ -515,8 +520,27 @@
          *      2.2.3 tdata->stream_queue $B$K(B 2.2.1 $B$N%]%$%s%?$r(B enqueue() $B$9$k(B
          *        2.2.3.1 enqueue() $B$O(B tdata->stream_queue->mutex $B$r(B lock/unlock $B$7$F=q$-9~$_;~$NF1;~99?7$rKI;_$7$F$$$k(B
          */
-        //fprintf (stderr, "reader_func() buf.size[%d]\n", buf.size);
+        /*
+         * DLNA $B$G$N(BSID$BJQ99$N<BAu<B83(B
+         */
         if ( use_dlna && buf.size > 0 ) {
+            if ( use_splitter ) {
+                new_sid = atoi(ut->request_channel);
+                if ( old_sid != new_sid ) {
+                    old_sid = new_sid;
+                    split_shutdown(splitter);
+                    splitter = split_startup(ut->request_channel, NULL, NULL);
+                    if ( splitter == NULL ) {
+                        fprintf (stderr, "reader_func() splitter RESTART FAILED.\n", old_sid, new_sid);
+                        use_splitter = FALSE;
+                    }
+                    split_select_finish = TSS_ERROR;
+                    free(qbuf);
+                    qbuf = NULL;
+                    time(&split_start_time);
+                    continue;
+                }
+            }
             do {
                 eqbuf = malloc(sizeof(ARIB_STD_B25_BUFFER));
                 if ( eqbuf == NULL ) {
--- a/src/tssplitter_lite.c	Thu Aug 16 21:57:34 2012 +0900
+++ b/src/tssplitter_lite.c	Tue Aug 21 04:21:11 2012 +0900
@@ -30,6 +30,8 @@
 #include "decoder.h"
 #include "recpt1.h"
 #include "tssplitter_lite.h"
+#include "ushare.h"
+#include "metadata.h"
 
 #ifndef AV_RB32
 #define AV_RB32(x)  ((((const uint8_t*)(x))[0] << 24) | \
@@ -52,6 +54,9 @@
 #define TSS_STREAM_TYPE_AUDIO (1)
 #define TSS_STREAM_TYPE_VIDEO (2)
 
+//global
+extern struct ushare_t *ut;
+
 /* prototypes */
 static int ReadTs(splitter *sp, ARIB_STD_B25_BUFFER *sbuf);
 static int AnalyzePat(splitter *sp, unsigned char *buf);
@@ -248,6 +253,8 @@
 		sp->program[i].cue = INT64_MAX;
 	}
 	memset(sp->pid_sid_table, 0, sizeof(int)*MAX_PID);
+	sp->filename = NULL;
+	sp->esout    = 0;
 	if ( filename != NULL ) {
 		sp->esout = 1;
 		sp->filename = filename;
@@ -282,6 +289,11 @@
 {
 	int i = 0;
 	if ( sp != NULL ) {
+		if ( sp->program != NULL )
+		{
+			free(sp->program);
+			sp->program = NULL;
+		}
 		if ( sp->pat != NULL )
 		{
 			free(sp->pat);
@@ -724,8 +736,32 @@
 
 		/* print SIDs */
 		fprintf(stderr, "Available sid = ");
-		for(k=0; k < sp->num_pmts; k++)
+		for(k=0; k < sp->num_pmts; k++) {
 			fprintf(stderr, "%d ", avail_sids[k]);
+			/* ut->channel_name にSID番号を入れる
+			 * ushare 側(TV表示上)には channel_name を表示させる
+			 * TODO 局名も含めて入れたいなぁ
+			 */
+#define CHANNEL_NAME_LENGTH (64)
+			ut->channel_name[ut->nr_channel] = malloc(CHANNEL_NAME_LENGTH);
+			if(!ut->channel_name[ut->nr_channel])
+				return TSS_NULL;
+			snprintf(ut->channel_name[ut->nr_channel],
+					CHANNEL_NAME_LENGTH,
+					"%d.ts",
+					avail_sids[k]);
+			ut->location_name[ut->nr_channel] = malloc(CHANNEL_NAME_LENGTH);
+			if(!ut->location_name[ut->nr_channel])
+				return TSS_NULL;
+			snprintf(ut->location_name[ut->nr_channel],
+					CHANNEL_NAME_LENGTH,
+					VIRTUAL_DIR "/%d.ts",
+					avail_sids[k]);
+			ut->nr_channel += 1;
+		}
+		// metadata list を作り直す
+		free_metadata_list(ut);
+		build_metadata_list(ut);
 		fprintf(stderr, "\n");
 		fprintf(stderr, "Chosen sid    =%s\n", chosen_sid);
 
--- a/src/tssplitter_lite.h	Thu Aug 16 21:57:34 2012 +0900
+++ b/src/tssplitter_lite.h	Tue Aug 21 04:21:11 2012 +0900
@@ -3,7 +3,7 @@
 /* tssplitter_lite.h  -- split TS stream program's header.
 
    Copyright 2009 querulous
-   Copyright 2010 Naoya OYAMA <naoya.oyama@gmail.com>
+   Copyright 2010-2012 Naoya OYAMA <naoya.oyama@gmail.com>
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -106,7 +106,7 @@
 };
 
 /*
- * PCRからSTCを生成する処理方式(案)
+ * PCRからSTCを生成する処理方式
  * 1. PCRを二つ取得するまでループ(1.から4.までは初期処理で実施すること)
  * 2. ループ開始時刻(PCR)と、ループ抜けた時刻(PCR)の差分を取る
  * 3. ループ開始〜終了の間に処理したパケット数を数える
--- a/src/ushare.c	Thu Aug 16 21:57:34 2012 +0900
+++ b/src/ushare.c	Tue Aug 21 04:21:11 2012 +0900
@@ -128,6 +128,16 @@
   pthread_mutex_init (&ut->termination_mutex, NULL);
   pthread_cond_init (&ut->termination_cond, NULL);
 
+#define MAX_CHANNELS 512
+  ut->channel_name = malloc(sizeof(char*)*MAX_CHANNELS);
+  if (!ut->channel_name)
+    return NULL;
+  ut->location_name = malloc(sizeof(char*)*MAX_CHANNELS);
+  if (!ut->location_name)
+    return NULL;
+  ut->request_channel[0] = '\0';
+  ut->nr_channel         = 0;
+
   return ut;
 }
 
@@ -737,7 +747,7 @@
 {
   printf (_("%s (version %s), Recoding DTV and a lightweight UPnP A/V and DLNA Media Server.\n"),
           PACKAGE_NAME, VERSION);
-  printf (_("Naoya OYAMA (C) 2010.\n"));
+  printf (_("Naoya OYAMA (C) 2010-2012.\n"));
   printf (_("See http://hg.honeyplanet.jp/pt1.oyama/ for updates.\n"));
 }
 
@@ -895,8 +905,6 @@
     return NULL;
   }
 
-  build_metadata_list (ut);
-
   /* Let main sleep until it's time to die... */
   pthread_mutex_lock (&ut->termination_mutex);
   pthread_cond_wait (&ut->termination_cond, &ut->termination_mutex);
--- a/src/ushare.h	Thu Aug 16 21:57:34 2012 +0900
+++ b/src/ushare.h	Tue Aug 21 04:21:11 2012 +0900
@@ -123,6 +123,10 @@
   char *cfg_file;
   pthread_mutex_t termination_mutex;
   pthread_cond_t termination_cond;
+  char **channel_name;
+  char **location_name;
+  char request_channel[64];
+  int  nr_channel;
 };
 
 struct action_event_t {