diff --git a/src/dvb/dvb_multiplex.c b/src/dvb/dvb_multiplex.c index abce0ec8..37d3ca17 100644 --- a/src/dvb/dvb_multiplex.c +++ b/src/dvb/dvb_multiplex.c @@ -1299,7 +1299,11 @@ dvb_subscription_create_from_tdmi(th_dvb_mux_instance_t *tdmi, const char *client) { th_subscription_t *s; + streaming_message_t *sm; + streaming_start_t *ss; + int r; th_dvb_adapter_t *tda = tdmi->tdmi_adapter; + char buf[100]; s = subscription_create(INT32_MAX, name, st, SUBSCRIPTION_RAW_MPEGTS, NULL, hostname, username, client); @@ -1308,10 +1312,36 @@ dvb_subscription_create_from_tdmi(th_dvb_mux_instance_t *tdmi, s->ths_tdmi = tdmi; LIST_INSERT_HEAD(&tdmi->tdmi_subscriptions, s, ths_tdmi_link); - dvb_fe_tune(tdmi, "Full mux subscription"); + r = dvb_fe_tune(tdmi, "Full mux subscription"); pthread_mutex_lock(&tda->tda_delivery_mutex); + streaming_target_connect(&tda->tda_streaming_pad, &s->ths_input); + + if(r) { + sm = streaming_msg_create_code(SMT_NOSTART, SM_CODE_NO_INPUT); + streaming_target_deliver(s->ths_output, sm); + } else { + ss = calloc(1, sizeof(streaming_start_t)); + ss->ss_num_components = 0; + ss->ss_refcount = 1; + + ss->ss_si.si_type = S_MPEG_TS; + ss->ss_si.si_device = strdup(tdmi->tdmi_adapter->tda_rootpath); + ss->ss_si.si_adapter = strdup(tdmi->tdmi_adapter->tda_displayname); + ss->ss_si.si_service = strdup("Full mux subscription"); + + if(tdmi->tdmi_network != NULL) + ss->ss_si.si_network = strdup(tdmi->tdmi_network); + + dvb_mux_nicename(buf, sizeof(buf), tdmi); + ss->ss_si.si_mux = strdup(buf); + + + sm = streaming_msg_create_data(SMT_START, ss); + streaming_target_deliver(s->ths_output, sm); + } + pthread_mutex_unlock(&tda->tda_delivery_mutex); notify_reload("subscriptions"); diff --git a/src/muxer.c b/src/muxer.c index ecf5618c..e252a53b 100644 --- a/src/muxer.c +++ b/src/muxer.c @@ -36,6 +36,7 @@ static struct strtab container_audio_mime[] = { { "audio/x-mpegts", MC_MPEGTS }, { "audio/mpeg", MC_MPEGPS }, { "application/octet-stream", MC_PASS }, + { "application/octet-stream", MC_RAW }, }; @@ -48,6 +49,7 @@ static struct strtab container_video_mime[] = { { "video/x-mpegts", MC_MPEGTS }, { "video/mpeg", MC_MPEGPS }, { "application/octet-stream", MC_PASS }, + { "application/octet-stream", MC_RAW }, }; @@ -60,6 +62,7 @@ static struct strtab container_name[] = { { "mpegts", MC_MPEGTS }, { "mpegps", MC_MPEGPS }, { "pass", MC_PASS }, + { "raw", MC_RAW }, }; @@ -72,6 +75,7 @@ static struct strtab container_audio_file_suffix[] = { { "ts", MC_MPEGTS }, { "mpeg", MC_MPEGPS }, { "bin", MC_PASS }, + { "bin", MC_RAW }, }; @@ -84,6 +88,7 @@ static struct strtab container_video_file_suffix[] = { { "ts", MC_MPEGTS }, { "mpeg", MC_MPEGPS }, { "bin", MC_PASS }, + { "bin", MC_RAW }, }; diff --git a/src/muxer.h b/src/muxer.h index 7894c3fc..1cfc947a 100644 --- a/src/muxer.h +++ b/src/muxer.h @@ -27,6 +27,7 @@ typedef enum { MC_MPEGTS = 2, MC_MPEGPS = 3, MC_PASS = 4, + MC_RAW = 5, } muxer_container_type_t; diff --git a/src/muxer/muxer_pass.c b/src/muxer/muxer_pass.c index ca21c8dd..50dd5e23 100644 --- a/src/muxer/muxer_pass.c +++ b/src/muxer/muxer_pass.c @@ -49,6 +49,7 @@ typedef struct pass_muxer { char *pm_filename; /* TS muxing */ + uint8_t pm_injection; uint8_t *pm_pat; uint8_t *pm_pmt; uint16_t pm_pmt_version; @@ -221,7 +222,9 @@ pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb) pass_muxer_t *pm = (pass_muxer_t*)m; int rem; - if(pm->pm_pat != NULL) { + if(pm->pm_pat != NULL && + pm->pm_pmt != NULL && + pm->pm_injection) { // Inject pmt and pat into the stream rem = pm->pm_pc % TS_INJECTION_RATE; if(!rem) { @@ -324,7 +327,7 @@ pass_muxer_create(muxer_container_type_t mc) { pass_muxer_t *pm; - if(mc != MC_PASS) + if(mc != MC_PASS && mc != MC_RAW) return NULL; pm = calloc(1, sizeof(pass_muxer_t)); @@ -338,7 +341,8 @@ pass_muxer_create(muxer_container_type_t mc) pm->m_close = pass_muxer_close; pm->m_destroy = pass_muxer_destroy; pm->pm_fd = -1; - + pm->pm_injection = (mc == MC_PASS); + return (muxer_t *)pm; } diff --git a/src/webui/webui.c b/src/webui/webui.c index d5c8357b..0257010e 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -155,7 +155,7 @@ page_static_file(http_connection_t *hc, const char *remain, void *opaque) */ static void http_stream_run(http_connection_t *hc, streaming_queue_t *sq, - const char *name, muxer_container_type_t mc, int raw) + const char *name, muxer_container_type_t mc) { streaming_message_t *sm; int run = 1; @@ -167,11 +167,9 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq, int err = 0; socklen_t errlen = sizeof(err); - if (!raw) { - mux = muxer_create(mc); - if(muxer_open_stream(mux, hc->hc_fd)) - run = 0; - } + mux = muxer_create(mc); + if(muxer_open_stream(mux, hc->hc_fd)) + run = 0; /* reduce timeout on write() for streaming */ tp.tv_sec = 5; @@ -207,16 +205,6 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq, TAILQ_REMOVE(&sq->sq_queue, sm, sm_link); pthread_mutex_unlock(&sq->sq_mutex); - if (raw) { - if (sm->sm_type == SMT_MPEGTS) { - pktbuf_t *pb = sm->sm_data; - if (tvh_write(hc->hc_fd, pb->pb_data, pb->pb_size)) - run = 0; - } - streaming_msg_free(sm); - continue; - } - switch(sm->sm_type) { case SMT_MPEGTS: case SMT_PACKET: @@ -280,12 +268,10 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq, } } + if(started) + muxer_close(mux); - if(mux != NULL){ - if(started) - muxer_close(mux); - muxer_destroy(mux); - } + muxer_destroy(mux); } @@ -587,7 +573,7 @@ http_stream_service(http_connection_t *hc, service_t *service) else qsize = 1500000; - if(mc == MC_PASS) { + if(mc == MC_PASS || mc == MC_RAW) { streaming_queue_init2(&sq, SMT_PACKET, qsize); gh = NULL; tsfix = NULL; @@ -609,7 +595,7 @@ http_stream_service(http_connection_t *hc, service_t *service) name = strdupa(service->s_ch ? service->s_ch->ch_name : service->s_nicename); pthread_mutex_unlock(&global_lock); - http_stream_run(hc, &sq, name, mc, 0); + http_stream_run(hc, &sq, name, mc); pthread_mutex_lock(&global_lock); subscription_unsubscribe(s); } @@ -644,7 +630,7 @@ http_stream_tdmi(http_connection_t *hc, th_dvb_mux_instance_t *tdmi) http_arg_get(&hc->hc_args, "User-Agent")); name = strdupa(tdmi->tdmi_identifier); pthread_mutex_unlock(&global_lock); - http_stream_run(hc, &sq, name, MC_PASS, 1); + http_stream_run(hc, &sq, name, MC_RAW); pthread_mutex_lock(&global_lock); subscription_unsubscribe(s); @@ -685,7 +671,7 @@ http_stream_channel(http_connection_t *hc, channel_t *ch) else qsize = 1500000; - if(mc == MC_PASS) { + if(mc == MC_PASS || mc == MC_RAW) { streaming_queue_init2(&sq, SMT_PACKET, qsize); gh = NULL; tsfix = NULL; @@ -707,7 +693,7 @@ http_stream_channel(http_connection_t *hc, channel_t *ch) if(s) { name = strdupa(ch->ch_name); pthread_mutex_unlock(&global_lock); - http_stream_run(hc, &sq, name, mc, 0); + http_stream_run(hc, &sq, name, mc); pthread_mutex_lock(&global_lock); subscription_unsubscribe(s); }