diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 3aae75aa..be7d9815 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -35,6 +35,26 @@ static int psi_parse_pmt(mpegts_service_t *t, const uint8_t *ptr, int len); +/* ************************************************************************** + * Lookup tables + * *************************************************************************/ + +static const int dvb_servicetype_map[][2] = { + { 0x01, ST_SDTV }, /* SDTV (MPEG2) */ + { 0x02, ST_RADIO }, + { 0x11, ST_HDTV }, /* HDTV (MPEG2) */ + { 0x16, ST_SDTV }, /* Advanced codec SDTV */ + { 0x19, ST_HDTV }, /* Advanced codec HDTV */ + { 0x80, ST_SDTV }, /* NET POA - Cabo SDTV */ + { 0x91, ST_HDTV }, /* Bell TV HDTV */ + { 0x96, ST_SDTV }, /* Bell TV SDTV */ + { 0xA0, ST_HDTV }, /* Bell TV tiered HDTV */ + { 0xA4, ST_HDTV }, /* DN HDTV */ + { 0xA6, ST_HDTV }, /* Bell TV tiered HDTV */ + { 0xA8, ST_SDTV }, /* DN advanced SDTV */ + { 0xD3, ST_SDTV }, /* SKY TV SDTV */ +}; + /* ************************************************************************** * Descriptors * *************************************************************************/ @@ -843,8 +863,15 @@ dvb_sdt_callback /* Update service type */ if (stype && s->s_dvb_servicetype != stype) { + int i; s->s_dvb_servicetype = stype; save = 1; + + /* Set tvh service type */ + for (i = 0; i < ARRAY_SIZE(dvb_servicetype_map); i++) { + if (dvb_servicetype_map[i][0] == stype) + s->s_servicetype = dvb_servicetype_map[i][1]; + } } /* Update scrambled state */ diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index fa07c490..f3d83810 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -91,7 +91,7 @@ const idclass_t mpegts_service_class = }, { .type = PT_U16, - .id = "servicetype", + .id = "dvb_servicetype", .name = "Service Type", .opts = PO_RDONLY, .off = offsetof(mpegts_service_t, s_dvb_servicetype), diff --git a/src/service.c b/src/service.c index 0798351f..43277ecf 100644 --- a/src/service.c +++ b/src/service.c @@ -273,10 +273,9 @@ service_start(service_t *t, int instance) * Main entry point for starting a service based on a channel */ service_instance_t * -service_find_instance(channel_t *ch, struct service_instance_list *sil, +service_find_instance(service_t *s, channel_t *ch, struct service_instance_list *sil, int *error, int weight) { - service_t *s; channel_service_mapping_t *csm; service_instance_t *si, *next; @@ -287,9 +286,13 @@ service_find_instance(channel_t *ch, struct service_instance_list *sil, LIST_FOREACH(si, sil, si_link) si->si_mark = 1; - LIST_FOREACH(csm, &ch->ch_services, csm_chn_link) { - s = csm->csm_svc; - if (!s->s_is_enabled(s)) continue; + if (ch) { + LIST_FOREACH(csm, &ch->ch_services, csm_chn_link) { + s = csm->csm_svc; + if (!s->s_is_enabled(s)) continue; + s->s_enlist(s, sil); + } + } else { s->s_enlist(s, sil); } diff --git a/src/service.h b/src/service.h index 0f6e5451..c38491f4 100644 --- a/src/service.h +++ b/src/service.h @@ -435,7 +435,8 @@ void service_ref(service_t *t); service_t *service_find_by_identifier(const char *identifier); -service_instance_t *service_find_instance(struct channel *ch, +service_instance_t *service_find_instance(struct service *s, + struct channel *ch, struct service_instance_list *sil, int *error, int weight); diff --git a/src/service_mapper.c b/src/service_mapper.c index 16c35507..f4292466 100644 --- a/src/service_mapper.c +++ b/src/service_mapper.c @@ -30,6 +30,7 @@ #include "service_mapper.h" #include "streaming.h" #include "service.h" +#include "plumbing/tsfix.h" static pthread_cond_t service_mapper_cond; static struct service_queue service_mapper_queue; @@ -78,8 +79,6 @@ service_mapper_start ( const service_mapper_conf_t *conf ) /* Check each service */ TAILQ_FOREACH(s, &service_all, s_all_link) { -printf("name = %s\n", s->s_channel_name(s)); - /* Disabled */ if (!s->s_is_enabled(s)) continue; @@ -91,7 +90,6 @@ printf("name = %s\n", s->s_channel_name(s)); e = service_is_encrypted(s); tr = service_is_tv(s) || service_is_radio(s); pthread_mutex_unlock(&s->s_stream_mutex); -printf(" tr = %d, e = %d\n", tr, e); /* Skip non-TV / Radio */ if (!tr) continue; @@ -104,11 +102,11 @@ printf(" tr = %d, e = %d\n", tr, e); if (!s->s_sm_onqueue) { qd = 1; TAILQ_INSERT_TAIL(&service_mapper_queue, s, s_sm_link); + s->s_sm_onqueue = 1; } /* Process */ } else { -printf(" map\n"); service_mapper_process(s); } } @@ -247,6 +245,7 @@ service_mapper_thread ( void *aux ) streaming_queue_t sq; streaming_message_t *sm; const char *err; + streaming_target_t *st; streaming_queue_init(&sq, 0); @@ -262,6 +261,7 @@ service_mapper_thread ( void *aux ) } pthread_cond_wait(&service_mapper_cond, &global_lock); } + service_mapper_remove(s); if (!working) { working = 1; @@ -270,12 +270,12 @@ service_mapper_thread ( void *aux ) /* Subscribe */ tvhinfo("service_mapper", "%s: checking availability", s->s_nicename); - sub = subscription_create_from_service(s, "service_mapper", &sq.sq_st, + st = tsfix_create(&sq.sq_st); + sub = subscription_create_from_service(s, 2, "service_mapper", st, 0, NULL, NULL, "service_mapper"); /* Failed */ if (!sub) { - service_mapper_remove(s); tvhinfo("service_mapper", "%s: could not subscribe", s->s_nicename); continue; } @@ -294,13 +294,13 @@ service_mapper_thread ( void *aux ) TAILQ_REMOVE(&sq.sq_queue, sm, sm_link); pthread_mutex_unlock(&sq.sq_mutex); - if(sm->sm_type == SMT_SERVICE_STATUS) { + if(sm->sm_type == SMT_PACKET) { + run = 0; + err = NULL; + } else if (sm->sm_type == SMT_SERVICE_STATUS) { int status = sm->sm_code; - if(status & TSS_PACKETS) { - run = 0; - err = NULL; - } else if(status & (TSS_GRACEPERIOD | TSS_ERRORS)) { + if(status & (TSS_GRACEPERIOD | TSS_ERRORS)) { run = 0; err = service_tss2text(status); } @@ -315,6 +315,7 @@ service_mapper_thread ( void *aux ) pthread_mutex_lock(&global_lock); subscription_unsubscribe(sub); + tsfix_destroy(st); if(err) tvhinfo("service_mapper", "%s: failed %s", s->s_nicename, err); diff --git a/src/subscriptions.c b/src/subscriptions.c index a980badb..7de155ba 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -164,10 +164,12 @@ subscription_reschedule(void) subscription_reschedule_cb, NULL, 2); LIST_FOREACH(s, &subscriptions, ths_global_link) { +#if 0 if(s->ths_channel == NULL) continue; /* stale entry, channel has been destroyed */ +#endif - if(s->ths_service != NULL) { + if(s->ths_service != NULL && s->ths_current_instance != NULL) { /* Already got a service */ if(s->ths_state != SUBSCRIPTION_BAD_SERVICE) @@ -180,8 +182,11 @@ subscription_reschedule(void) time(&si->si_error_time); } - tvhtrace("subscription", "find service for %s weight %d", s->ths_channel->ch_name, s->ths_weight); - si = service_find_instance(s->ths_channel, &s->ths_instances, &error, + if (s->ths_channel) + tvhtrace("subscription", "find service for %s weight %d", s->ths_channel->ch_name, s->ths_weight); + else + tvhtrace("subscription", "find instance for %s weight %d", s->ths_service->s_nicename, s->ths_weight); + si = service_find_instance(s->ths_service, s->ths_channel, &s->ths_instances, &error, s->ths_weight); s->ths_current_instance = si; @@ -370,22 +375,26 @@ subscription_create(int weight, const char *name, streaming_target_t *st, /** * */ -th_subscription_t * -subscription_create_from_channel(channel_t *ch, unsigned int weight, - const char *name, streaming_target_t *st, - int flags, const char *hostname, - const char *username, const char *client) +static th_subscription_t * +subscription_create_from_channel_or_service + (channel_t *ch, service_t *t, unsigned int weight, + const char *name, streaming_target_t *st, + int flags, const char *hostname, + const char *username, const char *client) { th_subscription_t *s; + assert(!ch || !t); - tvhtrace("subscription", "creating subscription for %s weight %d", - ch->ch_name, weight); + if (ch) + tvhtrace("subscription", "creating subscription for %s weight %d", + ch->ch_name, weight); s = subscription_create(weight, name, st, flags, subscription_input, hostname, username, client); s->ths_channel = ch; - LIST_INSERT_HEAD(&ch->ch_subscriptions, s, ths_channel_link); - s->ths_service = NULL; + if (ch) + LIST_INSERT_HEAD(&ch->ch_subscriptions, s, ths_channel_link); + s->ths_service = t; subscription_reschedule(); @@ -393,7 +402,7 @@ subscription_create_from_channel(channel_t *ch, unsigned int weight, tvhlog(LOG_NOTICE, "subscription", "No transponder available for subscription \"%s\" " "to channel \"%s\"", - s->ths_title, ch->ch_name); + s->ths_title, ch ? ch->ch_name : "none"); } else { source_info_t si; @@ -403,7 +412,7 @@ subscription_create_from_channel(channel_t *ch, unsigned int weight, "\"%s\" subscribing on \"%s\", weight: %d, adapter: \"%s\", " "network: \"%s\", mux: \"%s\", provider: \"%s\", " "service: \"%s\"", - s->ths_title, ch->ch_name, weight, + s->ths_title, ch ? ch->ch_name : "none", weight, si.si_adapter ?: "", si.si_network ?: "", si.si_mux ?: "", @@ -416,58 +425,30 @@ subscription_create_from_channel(channel_t *ch, unsigned int weight, return s; } +th_subscription_t * +subscription_create_from_channel(channel_t *ch, unsigned int weight, + const char *name, streaming_target_t *st, + int flags, const char *hostname, + const char *username, const char *client) +{ + return subscription_create_from_channel_or_service + (ch, NULL, weight, name, st, flags, hostname, username, client); +} /** * */ th_subscription_t * -subscription_create_from_service(service_t *t, const char *name, +subscription_create_from_service(service_t *t, unsigned int weight, + const char *name, streaming_target_t *st, int flags, const char *hostname, const char *username, const char *client) { -#if 0 - th_subscription_t *s; - source_info_t si; - int r; - - s = subscription_create(INT32_MAX, name, st, flags, - subscription_input_direct, - hostname, username, client); - - if(t->s_status != SERVICE_RUNNING) { - if((r = service_start(t, INT32_MAX, 1)) != 0) { - subscription_unsubscribe(s); - - tvhlog(LOG_INFO, "subscription", - "\"%s\" direct subscription failed -- %s", name, - streaming_code2txt(r)); - return NULL; - } - } - - t->s_setsourceinfo(t, &si); - - tvhlog(LOG_INFO, "subscription", - "\"%s\" direct subscription to adapter: \"%s\", " - "network: \"%s\", mux: \"%s\", provider: \"%s\", " - "service: \"%s\"", - s->ths_title, - si.si_adapter ?: "", - si.si_network ?: "", - si.si_mux ?: "", - si.si_provider ?: "", - si.si_service ?: ""); - service_source_info_free(&si); - - subscription_link_service(s, t); - notify_reload("subscriptions"); - return s; -#endif - abort(); + return subscription_create_from_channel_or_service + (NULL, t, weight, name, st, flags, hostname, username, client); } - /** * */ @@ -546,7 +527,7 @@ subscription_dummy_join(const char *id, int first) st = calloc(1, sizeof(streaming_target_t)); streaming_target_init(st, dummy_callback, NULL, 0); - subscription_create_from_service(t, "dummy", st, 0, NULL, NULL, "dummy"); + subscription_create_from_service(t, 1, "dummy", st, 0, NULL, NULL, "dummy"); tvhlog(LOG_NOTICE, "subscription", "Dummy join %s ok", id); diff --git a/src/subscriptions.h b/src/subscriptions.h index 5f66bcfc..f229158a 100644 --- a/src/subscriptions.h +++ b/src/subscriptions.h @@ -105,6 +105,7 @@ th_subscription_t *subscription_create_from_channel(struct channel *ch, th_subscription_t *subscription_create_from_service(struct service *t, + unsigned int weight, const char *name, streaming_target_t *st, int flags, diff --git a/src/webui/static/app/chconf.js b/src/webui/static/app/chconf.js index 0c274230..cf723e78 100644 --- a/src/webui/static/app/chconf.js +++ b/src/webui/static/app/chconf.js @@ -54,7 +54,7 @@ tvheadend.mapServices = function() /* Form fields */ var availCheck = new Ext.form.Checkbox({ - name : 'check_availbility', + name : 'check_availability', fieldLabel : 'Check availability', checked : false }); diff --git a/src/webui/webui.c b/src/webui/webui.c index 31248e81..36ac4d07 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -591,7 +591,7 @@ http_stream_service(http_connection_t *hc, service_t *service) } tcp_get_ip_str((struct sockaddr*)hc->hc_peer, addrbuf, 50); - s = subscription_create_from_service(service, "HTTP", st, flags, + s = subscription_create_from_service(service, 100, "HTTP", st, flags, addrbuf, hc->hc_username, http_arg_get(&hc->hc_args, "User-Agent"));