# HG changeset patch # User Naoya OYAMA # Date 1345490471 -32400 # Node ID 066f33b2213a6defe2064c43940b160d3e9dcfb5 # Parent 4e39ce051c57af9f0a50c5403cc0dcebd72bdf65 EXPERIMENTAL: Select a particular program from multi-channel. diff -r 4e39ce051c57 -r 066f33b2213a src/http.c --- 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: diff -r 4e39ce051c57 -r 066f33b2213a src/metadata.c --- 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/"); diff -r 4e39ce051c57 -r 066f33b2213a src/recpt1.c --- 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 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 ) { diff -r 4e39ce051c57 -r 066f33b2213a src/tssplitter_lite.c --- 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); diff -r 4e39ce051c57 -r 066f33b2213a src/tssplitter_lite.h --- 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 + Copyright 2010-2012 Naoya OYAMA 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. ループ開始〜終了の間に処理したパケット数を数える diff -r 4e39ce051c57 -r 066f33b2213a src/ushare.c --- 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); diff -r 4e39ce051c57 -r 066f33b2213a src/ushare.h --- 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 {