diff --git a/Makefile b/Makefile index 338a18a0..3ecf2a8e 100644 --- a/Makefile +++ b/Makefile @@ -48,7 +48,7 @@ SRCS = src/main.c \ src/teletext.c \ src/channels.c \ src/subscriptions.c \ - src/transports.c \ + src/service.c \ src/psi.c \ src/parsers.c \ src/parser_h264.c \ diff --git a/src/capmt.c b/src/capmt.c index 939250bb..041efc82 100644 --- a/src/capmt.c +++ b/src/capmt.c @@ -41,10 +41,9 @@ #include "psi.h" #include "tsdemux.h" #include "ffdecsa/FFdecsa.h" -#include "transports.h" #include "capmt.h" #include "notify.h" - +#include "subscriptions.h" #include "dtable.h" // ca_pmt_list_management values: @@ -73,7 +72,7 @@ * */ TAILQ_HEAD(capmt_queue, capmt); -LIST_HEAD(capmt_transport_list, capmt_transport); +LIST_HEAD(capmt_service_list, capmt_service); LIST_HEAD(capmt_caid_ecm_list, capmt_caid_ecm); static struct capmt_queue capmts; static pthread_cond_t capmt_config_changed; @@ -121,14 +120,14 @@ typedef struct capmt_caid_ecm { /** * */ -typedef struct capmt_transport { +typedef struct capmt_service { th_descrambler_t ct_head; - th_transport_t *ct_transport; + service_t *ct_service; struct capmt *ct_capmt; - LIST_ENTRY(capmt_transport) ct_link; + LIST_ENTRY(capmt_service) ct_link; /* list of used ca-systems with ids and last ecm */ struct capmt_caid_ecm_list ct_caid_ecm; @@ -155,7 +154,7 @@ typedef struct capmt_transport { /* sending requests will be based on this caid */ int ct_caid_last; -} capmt_transport_t; +} capmt_service_t; /** @@ -166,7 +165,7 @@ typedef struct capmt { TAILQ_ENTRY(capmt) capmt_link; /* Linkage protected via global_lock */ - struct capmt_transport_list capmt_transports; + struct capmt_service_list capmt_services; /* from capmt configuration */ char *capmt_sockfile; @@ -199,7 +198,7 @@ capmt_send_msg(capmt_t *capmt, const uint8_t *buf, size_t len) } static void -capmt_send_stop(capmt_transport_t *t) +capmt_send_stop(capmt_service_t *t) { /* buffer for capmt */ int pos = 0; @@ -208,7 +207,7 @@ capmt_send_stop(capmt_transport_t *t) capmt_header_t head = { .capmt_indicator = { 0x9F, 0x80, 0x32, 0x82, 0x00, 0x00 }, .capmt_list_management = CAPMT_LIST_ONLY, - .program_number = t->ct_transport->tht_dvb_service_id, + .program_number = t->ct_service->s_dvb_service_id, .version_number = 0, .current_next_indicator = 0, .program_info_length = 0, @@ -223,8 +222,8 @@ capmt_send_stop(capmt_transport_t *t) pos += sizeof(end); buf[4] = ((pos - 6) >> 8); buf[5] = ((pos - 6) & 0xFF); - buf[7] = t->ct_transport->tht_dvb_service_id >> 8; - buf[8] = t->ct_transport->tht_dvb_service_id & 0xFF; + buf[7] = t->ct_service->s_dvb_service_id >> 8; + buf[8] = t->ct_service->s_dvb_service_id & 0xFF; buf[9] = 1; buf[10] = ((pos - 5 - 12) & 0xF00) >> 8; buf[11] = ((pos - 5 - 12) & 0xFF); @@ -234,14 +233,14 @@ capmt_send_stop(capmt_transport_t *t) /** * global_lock is held - * tht_stream_mutex is held + * s_stream_mutex is held */ static void -capmt_transport_destroy(th_descrambler_t *td) +capmt_service_destroy(th_descrambler_t *td) { tvhlog(LOG_INFO, "capmt", "Removing CAPMT Server from service"); - capmt_transport_t *ct = (capmt_transport_t *)td; + capmt_service_t *ct = (capmt_service_t *)td; /* send stop to client */ capmt_send_stop(ct); @@ -255,7 +254,7 @@ capmt_transport_destroy(th_descrambler_t *td) free(cce); } - LIST_REMOVE(td, td_transport_link); + LIST_REMOVE(td, td_service_link); LIST_REMOVE(ct, ct_link); @@ -266,8 +265,8 @@ capmt_transport_destroy(th_descrambler_t *td) static void handle_ca0(capmt_t* capmt) { - capmt_transport_t *ct; - th_transport_t *t; + capmt_service_t *ct; + service_t *t; int ret; uint8_t invalid[8], buffer[20], *even, *odd; @@ -293,12 +292,12 @@ handle_ca0(capmt_t* capmt) { even = &buffer[2]; odd = &buffer[10]; - LIST_FOREACH(ct, &capmt->capmt_transports, ct_link) { - t = ct->ct_transport; + LIST_FOREACH(ct, &capmt->capmt_services, ct_link) { + t = ct->ct_service; if(ret < 18) { if(ct->ct_keystate != CT_FORBIDDEN) { - tvhlog(LOG_ERR, "capmt", "Can not descramble service \"%s\", access denied", t->tht_svcname); + tvhlog(LOG_ERR, "capmt", "Can not descramble service \"%s\", access denied", t->s_svcname); ct->ct_keystate = CT_FORBIDDEN; } @@ -315,7 +314,7 @@ handle_ca0(capmt_t* capmt) { set_odd_control_word(ct->ct_keys, odd); if(ct->ct_keystate != CT_RESOLVED) - tvhlog(LOG_INFO, "capmt", "Obtained key for service \"%s\"",t->tht_svcname); + tvhlog(LOG_INFO, "capmt", "Obtained key for service \"%s\"",t->s_svcname); ct->ct_keystate = CT_RESOLVED; } @@ -404,12 +403,12 @@ capmt_thread(void *aux) * */ static void -capmt_table_input(struct th_descrambler *td, struct th_transport *t, +capmt_table_input(struct th_descrambler *td, struct service *t, struct th_stream *st, const uint8_t *data, int len) { - capmt_transport_t *ct = (capmt_transport_t *)td; + capmt_service_t *ct = (capmt_service_t *)td; capmt_t *capmt = ct->ct_capmt; - int adapter_num = t->tht_dvb_mux_instance->tdmi_adapter->tda_adapter_num; + int adapter_num = t->s_dvb_mux_instance->tdmi_adapter->tda_adapter_num; caid_t *c; @@ -438,7 +437,7 @@ capmt_table_input(struct th_descrambler *td, struct th_transport *t, if (!cce) { tvhlog(LOG_DEBUG, "capmt", - "New caid 0x%04X for service \"%s\"", c->caid, t->tht_svcname); + "New caid 0x%04X for service \"%s\"", c->caid, t->s_svcname); /* ecmpid not already seen, add it to list */ cce = calloc(1, sizeof(capmt_caid_ecm_t)); @@ -456,7 +455,7 @@ capmt_table_input(struct th_descrambler *td, struct th_transport *t, break; } - uint16_t sid = t->tht_dvb_service_id; + uint16_t sid = t->s_dvb_service_id; uint16_t ecmpid = st->st_pid; uint16_t transponder = 0; @@ -537,7 +536,7 @@ capmt_table_input(struct th_descrambler *td, struct th_transport *t, if(ct->ct_keystate != CT_RESOLVED) tvhlog(LOG_INFO, "capmt", - "Trying to obtain key for service \"%s\"",t->tht_svcname); + "Trying to obtain key for service \"%s\"",t->s_svcname); buf[9] = pmtversion; pmtversion = (pmtversion + 1) & 0x1F; @@ -556,10 +555,10 @@ capmt_table_input(struct th_descrambler *td, struct th_transport *t, * */ static int -capmt_descramble(th_descrambler_t *td, th_transport_t *t, struct th_stream *st, +capmt_descramble(th_descrambler_t *td, service_t *t, struct th_stream *st, const uint8_t *tsb) { - capmt_transport_t *ct = (capmt_transport_t *)td; + capmt_service_t *ct = (capmt_service_t *)td; int r, i; unsigned char *vec[3]; uint8_t *t0; @@ -601,10 +600,10 @@ capmt_descramble(th_descrambler_t *td, th_transport_t *t, struct th_stream *st, * global_lock is held */ void -capmt_transport_start(th_transport_t *t) +capmt_service_start(service_t *t) { capmt_t *capmt; - capmt_transport_t *ct; + capmt_service_t *ct; capmt_caid_ecm_t *cce; th_descrambler_t *td; @@ -613,24 +612,24 @@ capmt_transport_start(th_transport_t *t) TAILQ_FOREACH(capmt, &capmts, capmt_link) { tvhlog(LOG_INFO, "capmt", "Starting capmt server for service \"%s\" on tuner %d", - t->tht_svcname, - t->tht_dvb_mux_instance->tdmi_adapter->tda_adapter_num); + t->s_svcname, + t->s_dvb_mux_instance->tdmi_adapter->tda_adapter_num); th_stream_t *st; - /* create new capmt transport */ - ct = calloc(1, sizeof(capmt_transport_t)); + /* create new capmt service */ + ct = calloc(1, sizeof(capmt_service_t)); ct->ct_cluster_size = get_suggested_cluster_size(); ct->ct_tsbcluster = malloc(ct->ct_cluster_size * 188); ct->ct_seq = capmt->capmt_seq++; - TAILQ_FOREACH(st, &t->tht_components, st_link) { + TAILQ_FOREACH(st, &t->s_components, st_link) { caid_t *c = LIST_FIRST(&st->st_caids); if(c == NULL) continue; tvhlog(LOG_DEBUG, "capmt", - "New caid 0x%04X for service \"%s\"", c->caid, t->tht_svcname); + "New caid 0x%04X for service \"%s\"", c->caid, t->s_svcname); /* add it to list */ cce = calloc(1, sizeof(capmt_caid_ecm_t)); @@ -644,15 +643,15 @@ capmt_transport_start(th_transport_t *t) ct->ct_keys = get_key_struct(); ct->ct_capmt = capmt; - ct->ct_transport = t; + ct->ct_service = t; td = &ct->ct_head; - td->td_stop = capmt_transport_destroy; + td->td_stop = capmt_service_destroy; td->td_table = capmt_table_input; td->td_descramble = capmt_descramble; - LIST_INSERT_HEAD(&t->tht_descramblers, td, td_transport_link); + LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link); - LIST_INSERT_HEAD(&capmt->capmt_transports, ct, ct_link); + LIST_INSERT_HEAD(&capmt->capmt_services, ct, ct_link); } } diff --git a/src/capmt.h b/src/capmt.h index 94bcf664..5cbf159a 100644 --- a/src/capmt.h +++ b/src/capmt.h @@ -21,6 +21,6 @@ void capmt_init(void); -void capmt_transport_start(th_transport_t *t); +void capmt_service_start(struct service *t); #endif /* CAPMT_H_ */ diff --git a/src/channels.c b/src/channels.c index d4ee932d..8dd409f9 100644 --- a/src/channels.c +++ b/src/channels.c @@ -33,7 +33,6 @@ #include "tvheadend.h" #include "psi.h" #include "channels.h" -#include "transports.h" #include "epg.h" #include "xmltv.h" #include "dtable.h" @@ -344,12 +343,12 @@ channel_save(channel_t *ch) } /** - * Rename a channel and all tied transports + * Rename a channel and all tied services */ int channel_rename(channel_t *ch, const char *newname) { - th_transport_t *t; + service_t *t; lock_assert(&global_lock); @@ -362,8 +361,8 @@ channel_rename(channel_t *ch, const char *newname) RB_REMOVE(&channel_name_tree, ch, ch_name_link); channel_set_name(ch, newname); - LIST_FOREACH(t, &ch->ch_transports, tht_ch_link) - t->tht_config_save(t); + LIST_FOREACH(t, &ch->ch_services, s_ch_link) + t->s_config_save(t); channel_save(ch); htsp_channel_update(ch); @@ -376,7 +375,7 @@ channel_rename(channel_t *ch, const char *newname) void channel_delete(channel_t *ch) { - th_transport_t *t; + service_t *t; th_subscription_t *s; channel_tag_mapping_t *ctm; @@ -392,8 +391,8 @@ channel_delete(channel_t *ch) dvr_destroy_by_channel(ch); - while((t = LIST_FIRST(&ch->ch_transports)) != NULL) - transport_map_channel(t, NULL, 1); + while((t = LIST_FIRST(&ch->ch_services)) != NULL) + service_map_channel(t, NULL, 1); while((s = LIST_FIRST(&ch->ch_subscriptions)) != NULL) { LIST_REMOVE(s, ths_channel_link); @@ -423,22 +422,22 @@ channel_delete(channel_t *ch) /** - * Merge transports from channel 'src' to channel 'dst' + * Merge services from channel 'src' to channel 'dst' * * Then, destroy the 'src' channel */ void channel_merge(channel_t *dst, channel_t *src) { - th_transport_t *t; + service_t *t; lock_assert(&global_lock); tvhlog(LOG_NOTICE, "channels", "Channel \"%s\" merged into \"%s\"", src->ch_name, dst->ch_name); - while((t = LIST_FIRST(&src->ch_transports)) != NULL) - transport_map_channel(t, dst, 1); + while((t = LIST_FIRST(&src->ch_services)) != NULL) + service_map_channel(t, dst, 1); channel_delete(src); } diff --git a/src/channels.h b/src/channels.h index bcb9517a..9cb02fdc 100644 --- a/src/channels.h +++ b/src/channels.h @@ -40,7 +40,7 @@ typedef struct channel { RB_ENTRY(channel) ch_identifier_link; int ch_id; - LIST_HEAD(, th_transport) ch_transports; + LIST_HEAD(, service) ch_services; LIST_HEAD(, th_subscription) ch_subscriptions; struct event_tree ch_epg_events; diff --git a/src/cwc.c b/src/cwc.c index ef774de4..55decd70 100644 --- a/src/cwc.c +++ b/src/cwc.c @@ -34,11 +34,11 @@ #include "psi.h" #include "tsdemux.h" #include "ffdecsa/FFdecsa.h" -#include "transports.h" #include "cwc.h" #include "notify.h" #include "atomic.h" #include "dtable.h" +#include "subscriptions.h" /** * @@ -87,7 +87,7 @@ typedef enum { * */ TAILQ_HEAD(cwc_queue, cwc); -LIST_HEAD(cwc_transport_list, cwc_transport); +LIST_HEAD(cwc_service_list, cwc_service); TAILQ_HEAD(cwc_message_queue, cwc_message); LIST_HEAD(ecm_section_list, ecm_section); static struct cwc_queue cwcs; @@ -126,42 +126,42 @@ typedef struct ecm_pid { /** * */ -typedef struct cwc_transport { - th_descrambler_t ct_head; +typedef struct cwc_service { + th_descrambler_t cs_head; - th_transport_t *ct_transport; + service_t *cs_service; - struct cwc *ct_cwc; + struct cwc *cs_cwc; - LIST_ENTRY(cwc_transport) ct_link; + LIST_ENTRY(cwc_service) cs_link; - int ct_okchannel; + int cs_okchannel; /** - * Status of the key(s) in ct_keys + * Status of the key(s) in cs_keys */ enum { - CT_UNKNOWN, - CT_RESOLVED, - CT_FORBIDDEN - } ct_keystate; + CS_UNKNOWN, + CS_RESOLVED, + CS_FORBIDDEN + } cs_keystate; - void *ct_keys; + void *cs_keys; - uint8_t ct_cw[16]; - int ct_pending_cw_update; + uint8_t cs_cw[16]; + int cs_pending_cw_update; /** * CSA */ - int ct_cluster_size; - uint8_t *ct_tsbcluster; - int ct_fill; + int cs_cluster_size; + uint8_t *cs_tsbcluster; + int cs_fill; - LIST_HEAD(, ecm_pid) ct_pids; + LIST_HEAD(, ecm_pid) cs_pids; -} cwc_transport_t; +} cwc_service_t; /** @@ -200,7 +200,7 @@ typedef struct cwc { TAILQ_ENTRY(cwc) cwc_link; /* Linkage protected via global_lock */ - struct cwc_transport_list cwc_transports; + struct cwc_service_list cwc_services; uint16_t cwc_caid; @@ -248,9 +248,9 @@ typedef struct cwc { * */ -static void cwc_transport_destroy(th_descrambler_t *td); +static void cwc_service_destroy(th_descrambler_t *td); extern char *cwc_krypt(const char *key, const char *salt); -static void cwc_detect_card_type(cwc_t *cwc); +static void cwc_detecs_card_type(cwc_t *cwc); void cwc_emm_conax(cwc_t *cwc, uint8_t *data, int len); void cwc_emm_irdeto(cwc_t *cwc, uint8_t *data, int len); void cwc_emm_seca(cwc_t *cwc, uint8_t *data, int len); @@ -548,7 +548,7 @@ cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len) cwc->cwc_ua[0], cwc->cwc_ua[1], cwc->cwc_ua[2], cwc->cwc_ua[3], cwc->cwc_ua[4], cwc->cwc_ua[5], cwc->cwc_ua[6], cwc->cwc_ua[7], nprov); - cwc_detect_card_type(cwc); + cwc_detecs_card_type(cwc); msg += 15; plen -= 12; @@ -614,7 +614,7 @@ cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len) * based on the equivalent in sasc-ng */ static void -cwc_detect_card_type(cwc_t *cwc) +cwc_detecs_card_type(cwc_t *cwc) { uint8_t c_sys = cwc->cwc_caid >> 8; @@ -663,10 +663,10 @@ cwc_send_login(cwc_t *cwc) static void -handle_ecm_reply(cwc_transport_t *ct, ecm_section_t *es, uint8_t *msg, +handle_ecm_reply(cwc_service_t *ct, ecm_section_t *es, uint8_t *msg, int len, int seq) { - th_transport_t *t = ct->ct_transport; + service_t *t = ct->cs_service; ecm_pid_t *ep; char chaninfo[32]; int i; @@ -684,18 +684,18 @@ handle_ecm_reply(cwc_transport_t *ct, ecm_section_t *es, uint8_t *msg, /* ERROR */ - if(ct->ct_okchannel == es->es_channel) - ct->ct_okchannel = -1; + if(ct->cs_okchannel == es->es_channel) + ct->cs_okchannel = -1; - if(ct->ct_keystate == CT_FORBIDDEN) + if(ct->cs_keystate == CS_FORBIDDEN) return; // We already know it's bad es->es_nok = 1; tvhlog(LOG_DEBUG, "cwc", "Received NOK for service \"%s\"%s (seqno: %d " - "Req delay: %lld ms)", t->tht_svcname, chaninfo, seq, delay); + "Req delay: %lld ms)", t->s_svcname, chaninfo, seq, delay); - LIST_FOREACH(ep, &ct->ct_pids, ep_link) { + LIST_FOREACH(ep, &ct->cs_pids, ep_link) { for(i = 0; i <= ep->ep_last_section; i++) if(ep->ep_sections[i] == NULL || ep->ep_sections[i]->es_pending || @@ -705,13 +705,13 @@ handle_ecm_reply(cwc_transport_t *ct, ecm_section_t *es, uint8_t *msg, tvhlog(LOG_ERR, "cwc", "Can not descramble service \"%s\", access denied (seqno: %d " "Req delay: %lld ms)", - t->tht_svcname, seq, delay); - ct->ct_keystate = CT_FORBIDDEN; + t->s_svcname, seq, delay); + ct->cs_keystate = CS_FORBIDDEN; return; } else { - ct->ct_okchannel = es->es_channel; + ct->cs_okchannel = es->es_channel; es->es_nok = 0; tvhlog(LOG_DEBUG, "cwc", @@ -720,22 +720,22 @@ handle_ecm_reply(cwc_transport_t *ct, ecm_section_t *es, uint8_t *msg, " odd: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x (seqno: %d " "Req delay: %lld ms)", chaninfo, - t->tht_svcname, + t->s_svcname, msg[3 + 0], msg[3 + 1], msg[3 + 2], msg[3 + 3], msg[3 + 4], msg[3 + 5], msg[3 + 6], msg[3 + 7], msg[3 + 8], msg[3 + 9], msg[3 + 10],msg[3 + 11],msg[3 + 12],msg[3 + 13],msg[3 + 14], msg[3 + 15], seq, delay); - if(ct->ct_keystate != CT_RESOLVED) + if(ct->cs_keystate != CS_RESOLVED) tvhlog(LOG_INFO, "cwc", "Obtained key for for service \"%s\" in %lld ms, from %s", - t->tht_svcname, delay, ct->ct_cwc->cwc_hostname); + t->s_svcname, delay, ct->cs_cwc->cwc_hostname); - pthread_mutex_lock(&t->tht_stream_mutex); - ct->ct_keystate = CT_RESOLVED; - memcpy(ct->ct_cw, msg + 3, 16); - ct->ct_pending_cw_update = 1; - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + ct->cs_keystate = CS_RESOLVED; + memcpy(ct->cs_cw, msg + 3, 16); + ct->cs_pending_cw_update = 1; + pthread_mutex_unlock(&t->s_stream_mutex); } } @@ -747,7 +747,7 @@ handle_ecm_reply(cwc_transport_t *ct, ecm_section_t *es, uint8_t *msg, static int cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len) { - cwc_transport_t *ct; + cwc_service_t *ct; ecm_pid_t *ep; ecm_section_t *es; uint16_t seq = (msg[2] << 8) | msg[3]; @@ -759,8 +759,8 @@ cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len) switch(msgtype) { case 0x80: case 0x81: - LIST_FOREACH(ct, &cwc->cwc_transports, ct_link) { - LIST_FOREACH(ep, &ct->ct_pids, ep_link) { + LIST_FOREACH(ct, &cwc->cwc_services, cs_link) { + LIST_FOREACH(ep, &ct->cs_pids, ep_link) { for(i = 0; i <= ep->ep_last_section; i++) { es = ep->ep_sections[i]; if(es != NULL) { @@ -982,11 +982,11 @@ cwc_session(cwc_t *cwc) static void * cwc_thread(void *aux) { - cwc_transport_t *ct; + cwc_service_t *ct; cwc_t *cwc = aux; int fd, d; char errbuf[100]; - th_transport_t *t; + service_t *t; char hostname[256]; int port; struct timespec ts; @@ -1058,11 +1058,11 @@ cwc_thread(void *aux) tvhlog(LOG_INFO, "cwc", "%s destroyed", cwc->cwc_hostname); - while((ct = LIST_FIRST(&cwc->cwc_transports)) != NULL) { - t = ct->ct_transport; - pthread_mutex_lock(&t->tht_stream_mutex); - cwc_transport_destroy(&ct->ct_head); - pthread_mutex_unlock(&t->tht_stream_mutex); + while((ct = LIST_FIRST(&cwc->cwc_services)) != NULL) { + t = ct->cs_service; + pthread_mutex_lock(&t->s_stream_mutex); + cwc_service_destroy(&ct->cs_head); + pthread_mutex_unlock(&t->s_stream_mutex); } free((void *)cwc->cwc_password); @@ -1209,12 +1209,12 @@ cwc_emm_seca(cwc_t *cwc, uint8_t *data, int len) * */ static void -cwc_table_input(struct th_descrambler *td, struct th_transport *t, +cwc_table_input(struct th_descrambler *td, struct service *t, struct th_stream *st, const uint8_t *data, int len) { - cwc_transport_t *ct = (cwc_transport_t *)td; - uint16_t sid = t->tht_dvb_service_id; - cwc_t *cwc = ct->ct_cwc; + cwc_service_t *ct = (cwc_service_t *)td; + uint16_t sid = t->s_dvb_service_id; + cwc_t *cwc = ct->cs_cwc; int channel; int section; ecm_pid_t *ep; @@ -1228,7 +1228,7 @@ cwc_table_input(struct th_descrambler *td, struct th_transport *t, if((data[0] & 0xf0) != 0x80) return; - LIST_FOREACH(ep, &ct->ct_pids, ep_link) { + LIST_FOREACH(ep, &ct->cs_pids, ep_link) { if(ep->ep_pid == st->st_pid) break; } @@ -1236,7 +1236,7 @@ cwc_table_input(struct th_descrambler *td, struct th_transport *t, if(ep == NULL) { ep = calloc(1, sizeof(ecm_pid_t)); ep->ep_pid = st->st_pid; - LIST_INSERT_HEAD(&ct->ct_pids, ep, ep_link); + LIST_INSERT_HEAD(&ct->cs_pids, ep, ep_link); } @@ -1278,7 +1278,7 @@ cwc_table_input(struct th_descrambler *td, struct th_transport *t, if(cwc->cwc_fd == -1) { // New key, but we are not connected (anymore), can not descramble - ct->ct_keystate = CT_UNKNOWN; + ct->cs_keystate = CS_UNKNOWN; break; } @@ -1289,8 +1289,8 @@ cwc_table_input(struct th_descrambler *td, struct th_transport *t, memcpy(es->es_ecm, data, len); es->es_ecmsize = len; - if(ct->ct_okchannel != -1 && channel != -1 && - ct->ct_okchannel != channel) { + if(ct->cs_okchannel != -1 && channel != -1 && + ct->cs_okchannel != channel) { tvhlog(LOG_DEBUG, "cwc", "Filtering ECM channel %d", channel); return; } @@ -1299,7 +1299,7 @@ cwc_table_input(struct th_descrambler *td, struct th_transport *t, tvhlog(LOG_DEBUG, "cwc", "Sending ECM%s section=%d/%d, for service %s (seqno: %d) PID %d", - chaninfo, section, ep->ep_last_section, t->tht_svcname, es->es_seq, + chaninfo, section, ep->ep_last_section, t->s_svcname, es->es_seq, st->st_pid); es->es_time = getmonoclock(); break; @@ -1317,19 +1317,19 @@ cwc_table_input(struct th_descrambler *td, struct th_transport *t, * */ static void -update_keys(cwc_transport_t *ct) +update_keys(cwc_service_t *ct) { int i; - ct->ct_pending_cw_update = 0; + ct->cs_pending_cw_update = 0; for(i = 0; i < 8; i++) - if(ct->ct_cw[i]) { - set_even_control_word(ct->ct_keys, ct->ct_cw); + if(ct->cs_cw[i]) { + set_even_control_word(ct->cs_keys, ct->cs_cw); break; } for(i = 0; i < 8; i++) - if(ct->ct_cw[8 + i]) { - set_odd_control_word(ct->ct_keys, ct->ct_cw + 8); + if(ct->cs_cw[8 + i]) { + set_odd_control_word(ct->cs_keys, ct->cs_cw + 8); break; } } @@ -1339,59 +1339,59 @@ update_keys(cwc_transport_t *ct) * */ static int -cwc_descramble(th_descrambler_t *td, th_transport_t *t, struct th_stream *st, +cwc_descramble(th_descrambler_t *td, service_t *t, struct th_stream *st, const uint8_t *tsb) { - cwc_transport_t *ct = (cwc_transport_t *)td; + cwc_service_t *ct = (cwc_service_t *)td; int r; unsigned char *vec[3]; - if(ct->ct_keystate == CT_FORBIDDEN) + if(ct->cs_keystate == CS_FORBIDDEN) return 1; - if(ct->ct_keystate != CT_RESOLVED) + if(ct->cs_keystate != CS_RESOLVED) return -1; - if(ct->ct_fill == 0 && ct->ct_pending_cw_update) + if(ct->cs_fill == 0 && ct->cs_pending_cw_update) update_keys(ct); - memcpy(ct->ct_tsbcluster + ct->ct_fill * 188, tsb, 188); - ct->ct_fill++; + memcpy(ct->cs_tsbcluster + ct->cs_fill * 188, tsb, 188); + ct->cs_fill++; - if(ct->ct_fill != ct->ct_cluster_size) + if(ct->cs_fill != ct->cs_cluster_size) return 0; while(1) { - vec[0] = ct->ct_tsbcluster; - vec[1] = ct->ct_tsbcluster + ct->ct_fill * 188; + vec[0] = ct->cs_tsbcluster; + vec[1] = ct->cs_tsbcluster + ct->cs_fill * 188; vec[2] = NULL; - r = decrypt_packets(ct->ct_keys, vec); + r = decrypt_packets(ct->cs_keys, vec); if(r > 0) { int i; - const uint8_t *t0 = ct->ct_tsbcluster; + const uint8_t *t0 = ct->cs_tsbcluster; for(i = 0; i < r; i++) { ts_recv_packet2(t, t0); t0 += 188; } - r = ct->ct_fill - r; + r = ct->cs_fill - r; assert(r >= 0); if(r > 0) - memmove(ct->ct_tsbcluster, t0, r * 188); - ct->ct_fill = r; + memmove(ct->cs_tsbcluster, t0, r * 188); + ct->cs_fill = r; - if(ct->ct_pending_cw_update && r > 0) + if(ct->cs_pending_cw_update && r > 0) continue; } else { - ct->ct_fill = 0; + ct->cs_fill = 0; } break; } - if(ct->ct_pending_cw_update) + if(ct->cs_pending_cw_update) update_keys(ct); return 0; @@ -1399,28 +1399,28 @@ cwc_descramble(th_descrambler_t *td, th_transport_t *t, struct th_stream *st, /** * global_lock is held - * tht_stream_mutex is held + * s_stream_mutex is held */ static void -cwc_transport_destroy(th_descrambler_t *td) +cwc_service_destroy(th_descrambler_t *td) { - cwc_transport_t *ct = (cwc_transport_t *)td; + cwc_service_t *ct = (cwc_service_t *)td; ecm_pid_t *ep; int i; - while((ep = LIST_FIRST(&ct->ct_pids)) != NULL) { + while((ep = LIST_FIRST(&ct->cs_pids)) != NULL) { for(i = 0; i < 256; i++) free(ep->ep_sections[i]); LIST_REMOVE(ep, ep_link); free(ep); } - LIST_REMOVE(td, td_transport_link); + LIST_REMOVE(td, td_service_link); - LIST_REMOVE(ct, ct_link); + LIST_REMOVE(ct, cs_link); - free_key_struct(ct->ct_keys); - free(ct->ct_tsbcluster); + free_key_struct(ct->cs_keys); + free(ct->cs_tsbcluster); free(ct); } @@ -1428,12 +1428,12 @@ cwc_transport_destroy(th_descrambler_t *td) * */ static inline th_stream_t * -cwc_find_stream_by_caid(th_transport_t *t, int caid) +cwc_find_stream_by_caid(service_t *t, int caid) { th_stream_t *st; caid_t *c; - TAILQ_FOREACH(st, &t->tht_components, st_link) { + TAILQ_FOREACH(st, &t->s_components, st_link) { LIST_FOREACH(c, &st->st_caids, link) { if(c->caid == caid) return st; @@ -1449,10 +1449,10 @@ cwc_find_stream_by_caid(th_transport_t *t, int caid) * global_lock is held */ void -cwc_transport_start(th_transport_t *t) +cwc_service_start(service_t *t) { cwc_t *cwc; - cwc_transport_t *ct; + cwc_service_t *ct; th_descrambler_t *td; lock_assert(&global_lock); @@ -1463,25 +1463,25 @@ cwc_transport_start(th_transport_t *t) if(cwc_find_stream_by_caid(t, cwc->cwc_caid) == NULL) continue; - ct = calloc(1, sizeof(cwc_transport_t)); - ct->ct_cluster_size = get_suggested_cluster_size(); - ct->ct_tsbcluster = malloc(ct->ct_cluster_size * 188); + ct = calloc(1, sizeof(cwc_service_t)); + ct->cs_cluster_size = get_suggested_cluster_size(); + ct->cs_tsbcluster = malloc(ct->cs_cluster_size * 188); - ct->ct_keys = get_key_struct(); - ct->ct_cwc = cwc; - ct->ct_transport = t; - ct->ct_okchannel = -1; + ct->cs_keys = get_key_struct(); + ct->cs_cwc = cwc; + ct->cs_service = t; + ct->cs_okchannel = -1; - td = &ct->ct_head; - td->td_stop = cwc_transport_destroy; + td = &ct->cs_head; + td->td_stop = cwc_service_destroy; td->td_table = cwc_table_input; td->td_descramble = cwc_descramble; - LIST_INSERT_HEAD(&t->tht_descramblers, td, td_transport_link); + LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link); - LIST_INSERT_HEAD(&cwc->cwc_transports, ct, ct_link); + LIST_INSERT_HEAD(&cwc->cwc_services, ct, cs_link); tvhlog(LOG_DEBUG, "cwc", "%s using CWC %s:%d", - transport_nicename(t), cwc->cwc_hostname, cwc->cwc_port); + service_nicename(t), cwc->cwc_hostname, cwc->cwc_port); } } diff --git a/src/cwc.h b/src/cwc.h index 3f963e57..fa3cede9 100644 --- a/src/cwc.h +++ b/src/cwc.h @@ -21,7 +21,7 @@ void cwc_init(void); -void cwc_transport_start(th_transport_t *t); +void cwc_service_start(struct service *t); void cwc_emm(uint8_t *data, int len); diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index 663fb746..347fe31a 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -128,7 +128,7 @@ typedef struct th_dvb_mux_instance { char *tdmi_identifier; char *tdmi_network; /* Name of network, from NIT table */ - struct th_transport_list tdmi_transports; /* via tht_mux_link */ + struct service_list tdmi_transports; /* via s_mux_link */ TAILQ_ENTRY(th_dvb_mux_instance) tdmi_scan_link; @@ -183,7 +183,7 @@ typedef struct th_dvb_adapter { gtimer_t tda_mux_scanner_timer; pthread_mutex_t tda_delivery_mutex; - struct th_transport_list tda_transports; /* Currently bound transports */ + struct service_list tda_transports; /* Currently bound transports */ gtimer_t tda_fe_monitor_timer; int tda_fe_monitor_hold; @@ -297,17 +297,17 @@ int dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src); */ void dvb_transport_load(th_dvb_mux_instance_t *tdmi); -th_transport_t *dvb_transport_find(th_dvb_mux_instance_t *tdmi, +struct service *dvb_transport_find(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, const char *identifier); -void dvb_transport_notify(th_transport_t *t); +void dvb_transport_notify(struct service *t); void dvb_transport_notify_by_adapter(th_dvb_adapter_t *tda); -htsmsg_t *dvb_transport_build_msg(th_transport_t *t); +htsmsg_t *dvb_transport_build_msg(struct service *t); -int dvb_transport_get_signal_status(th_transport_t *t, +int dvb_transport_get_signal_status(struct service *t, signal_status_t *status); /** diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index f5317939..9f6afd56 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -36,11 +36,11 @@ #include "settings.h" #include "tvheadend.h" -#include "transports.h" #include "dvb.h" #include "dvb_support.h" #include "tsdemux.h" #include "notify.h" +#include "service.h" struct th_dvb_adapter_queue dvb_adapters; struct th_dvb_mux_instance_tree dvb_muxes; @@ -411,7 +411,7 @@ dvb_adapter_mux_scanner(void *aux) if(LIST_FIRST(&tda->tda_muxes) == NULL) return; // No muxes configured - if(transport_compute_weight(&tda->tda_transports) > 0) + if(service_compute_weight(&tda->tda_transports) > 0) return; /* someone is here */ /* Check if we have muxes pending for quickscan, if so, choose them */ @@ -499,13 +499,13 @@ dvb_adapter_destroy(th_dvb_adapter_t *tda) void dvb_adapter_clean(th_dvb_adapter_t *tda) { - th_transport_t *t; + service_t *t; lock_assert(&global_lock); while((t = LIST_FIRST(&tda->tda_transports)) != NULL) /* Flush all subscribers */ - transport_remove_subscriber(t, NULL, SM_CODE_SUBSCRIPTION_OVERRIDDEN); + service_remove_subscriber(t, NULL, SM_CODE_SUBSCRIPTION_OVERRIDDEN); } @@ -520,7 +520,7 @@ dvb_adapter_input_dvr(void *aux) th_dvb_adapter_t *tda = aux; int fd, i, r; uint8_t tsb[188 * 10]; - th_transport_t *t; + service_t *t; fd = tvh_open(tda->tda_dvr_path, O_RDONLY, 0); if(fd == -1) { @@ -535,8 +535,8 @@ dvb_adapter_input_dvr(void *aux) pthread_mutex_lock(&tda->tda_delivery_mutex); for(i = 0; i < r; i += 188) { - LIST_FOREACH(t, &tda->tda_transports, tht_active_link) - if(t->tht_dvb_mux_instance == tda->tda_mux_current) + LIST_FOREACH(t, &tda->tda_transports, s_active_link) + if(t->s_dvb_mux_instance == tda->tda_mux_current) ts_recv_packet1(t, tsb + i, NULL); } @@ -565,7 +565,7 @@ dvb_adapter_build_msg(th_dvb_adapter_t *tda) char buf[100]; htsmsg_t *m = htsmsg_create_map(); th_dvb_mux_instance_t *tdmi; - th_transport_t *t; + service_t *t; int nummux = 0; int numsvc = 0; int fdiv; @@ -576,7 +576,7 @@ dvb_adapter_build_msg(th_dvb_adapter_t *tda) // XXX: bad bad bad slow slow slow LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link) { nummux++; - LIST_FOREACH(t, &tdmi->tdmi_transports, tht_group_link) { + LIST_FOREACH(t, &tdmi->tdmi_transports, s_group_link) { numsvc++; } } diff --git a/src/dvb/dvb_fe.c b/src/dvb/dvb_fe.c index c4e4d15f..23821134 100644 --- a/src/dvb/dvb_fe.c +++ b/src/dvb/dvb_fe.c @@ -38,7 +38,6 @@ #include "dvb_support.h" #include "diseqc.h" #include "notify.h" -#include "transports.h" #include "dvr/dvr.h" /** diff --git a/src/dvb/dvb_multiplex.c b/src/dvb/dvb_multiplex.c index 6c81cba2..4ed2ec8a 100644 --- a/src/dvb/dvb_multiplex.c +++ b/src/dvb/dvb_multiplex.c @@ -39,11 +39,11 @@ #include "tvheadend.h" #include "dvb.h" #include "channels.h" -#include "transports.h" #include "teletext.h" #include "psi.h" #include "dvb_support.h" #include "notify.h" +#include "subscriptions.h" struct th_dvb_mux_instance_tree dvb_muxes; @@ -294,7 +294,7 @@ void dvb_mux_destroy(th_dvb_mux_instance_t *tdmi) { th_dvb_adapter_t *tda = tdmi->tdmi_adapter; - th_transport_t *t; + service_t *t; lock_assert(&global_lock); @@ -303,9 +303,9 @@ dvb_mux_destroy(th_dvb_mux_instance_t *tdmi) while((t = LIST_FIRST(&tdmi->tdmi_transports)) != NULL) { hts_settings_remove("dvbtransports/%s/%s", - t->tht_dvb_mux_instance->tdmi_identifier, - t->tht_identifier); - transport_destroy(t); + t->s_dvb_mux_instance->tdmi_identifier, + t->s_identifier); + service_destroy(t); } dvb_transport_notify_by_adapter(tda); @@ -1074,7 +1074,7 @@ int dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src) { th_dvb_mux_instance_t *tdmi_dst; - th_transport_t *t_src, *t_dst; + service_t *t_src, *t_dst; th_stream_t *st_src, *st_dst; caid_t *caid_src, *caid_dst; @@ -1088,34 +1088,34 @@ dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src) if(tdmi_dst == NULL) return -1; // Already exist - LIST_FOREACH(t_src, &tdmi_src->tdmi_transports, tht_group_link) { + LIST_FOREACH(t_src, &tdmi_src->tdmi_transports, s_group_link) { t_dst = dvb_transport_find(tdmi_dst, - t_src->tht_dvb_service_id, - t_src->tht_pmt_pid, NULL); + t_src->s_dvb_service_id, + t_src->s_pmt_pid, NULL); - t_dst->tht_pcr_pid = t_src->tht_pcr_pid; - t_dst->tht_enabled = t_src->tht_enabled; - t_dst->tht_servicetype = t_src->tht_servicetype; - t_dst->tht_scrambled = t_src->tht_scrambled; + t_dst->s_pcr_pid = t_src->s_pcr_pid; + t_dst->s_enabled = t_src->s_enabled; + t_dst->s_servicetype = t_src->s_servicetype; + t_dst->s_scrambled = t_src->s_scrambled; - if(t_src->tht_provider != NULL) - t_dst->tht_provider = strdup(t_src->tht_provider); + if(t_src->s_provider != NULL) + t_dst->s_provider = strdup(t_src->s_provider); - if(t_src->tht_svcname != NULL) - t_dst->tht_svcname = strdup(t_src->tht_svcname); + if(t_src->s_svcname != NULL) + t_dst->s_svcname = strdup(t_src->s_svcname); - if(t_src->tht_ch != NULL) - transport_map_channel(t_dst, t_src->tht_ch, 0); + if(t_src->s_ch != NULL) + service_map_channel(t_dst, t_src->s_ch, 0); - pthread_mutex_lock(&t_src->tht_stream_mutex); - pthread_mutex_lock(&t_dst->tht_stream_mutex); + pthread_mutex_lock(&t_src->s_stream_mutex); + pthread_mutex_lock(&t_dst->s_stream_mutex); - TAILQ_FOREACH(st_src, &t_src->tht_components, st_link) { + TAILQ_FOREACH(st_src, &t_src->s_components, st_link) { - st_dst = transport_stream_create(t_dst, - st_src->st_pid, - st_src->st_type); + st_dst = service_stream_create(t_dst, + st_src->st_pid, + st_src->st_type); memcpy(st_dst->st_lang, st_src->st_lang, 4); st_dst->st_frame_duration = st_src->st_frame_duration; @@ -1130,10 +1130,10 @@ dvb_mux_copy(th_dvb_adapter_t *dst, th_dvb_mux_instance_t *tdmi_src) } } - pthread_mutex_unlock(&t_dst->tht_stream_mutex); - pthread_mutex_unlock(&t_src->tht_stream_mutex); + pthread_mutex_unlock(&t_dst->s_stream_mutex); + pthread_mutex_unlock(&t_src->s_stream_mutex); - t_dst->tht_config_save(t_dst); // Save config + t_dst->s_config_save(t_dst); // Save config } dvb_mux_save(tdmi_dst); diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index 253623c8..de18cd02 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -37,7 +37,6 @@ #include "dvb.h" #include "dvb_support.h" #include "epg.h" -#include "transports.h" #include "channels.h" #include "psi.h" #include "notify.h" @@ -478,7 +477,7 @@ static int dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, uint8_t tableid, void *opaque) { - th_transport_t *t; + service_t *t; channel_t *ch; th_dvb_adapter_t *tda = tdmi->tdmi_adapter; @@ -539,7 +538,7 @@ dvb_eit_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, return -1; t = dvb_transport_find(tdmi, serviceid, 0, NULL); - if(t == NULL || !t->tht_enabled || (ch = t->tht_ch) == NULL) + if(t == NULL || !t->s_enabled || (ch = t->s_ch) == NULL) return 0; while(len >= 12) { @@ -640,7 +639,7 @@ static int dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, uint8_t tableid, void *opaque) { - th_transport_t *t; + service_t *t; int version; uint8_t section_number; uint8_t last_section_number; @@ -733,26 +732,26 @@ dvb_sdt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, if(t == NULL) break; - if(t->tht_servicetype != stype || - t->tht_scrambled != free_ca_mode || - strcmp(t->tht_provider ?: "", provider) || - strcmp(t->tht_svcname ?: "", chname)) { + if(t->s_servicetype != stype || + t->s_scrambled != free_ca_mode || + strcmp(t->s_provider ?: "", provider) || + strcmp(t->s_svcname ?: "", chname)) { - t->tht_servicetype = stype; - t->tht_scrambled = free_ca_mode; + t->s_servicetype = stype; + t->s_scrambled = free_ca_mode; - free(t->tht_provider); - t->tht_provider = strdup(provider); + free(t->s_provider); + t->s_provider = strdup(provider); - free(t->tht_svcname); - t->tht_svcname = strdup(chname); + free(t->s_svcname); + t->s_svcname = strdup(chname); - pthread_mutex_lock(&t->tht_stream_mutex); - transport_make_nicename(t); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + service_make_nicename(t); + pthread_mutex_unlock(&t->s_stream_mutex); - t->tht_config_save(t); - transport_refresh_channel(t); + t->s_config_save(t); + service_refresh_channel(t); } } break; @@ -1045,7 +1044,7 @@ dvb_table_local_channel(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, { uint16_t sid, chan; th_dvb_adapter_t *tda = tdmi->tdmi_adapter; - th_transport_t *t; + service_t *t; LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link) if(tdmi->tdmi_transport_stream_id == tsid) @@ -1062,10 +1061,10 @@ dvb_table_local_channel(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, t = dvb_transport_find(tdmi, sid, 0, NULL); if(t != NULL) { - if(t->tht_channel_number != chan) { - t->tht_channel_number = chan; - t->tht_config_save(t); - transport_refresh_channel(t); + if(t->s_channel_number != chan) { + t->s_channel_number = chan; + t->s_config_save(t); + service_refresh_channel(t); } } } @@ -1190,7 +1189,7 @@ atsc_vct_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, uint8_t tableid, void *opaque) { th_dvb_adapter_t *tda = tdmi->tdmi_adapter; - th_transport_t *t; + service_t *t; int numch; char chname[256]; uint8_t atsc_stype; @@ -1250,13 +1249,13 @@ atsc_vct_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, dptr += dptr[1] + 2; } - if(t->tht_servicetype != stype || - strcmp(t->tht_svcname ?: "", chname)) { + if(t->s_servicetype != stype || + strcmp(t->s_svcname ?: "", chname)) { - t->tht_servicetype = stype; - tvh_str_set(&t->tht_svcname, chname); + t->s_servicetype = stype; + tvh_str_set(&t->s_svcname, chname); - t->tht_config_save(t); + t->s_config_save(t); } } return 0; @@ -1272,12 +1271,12 @@ static int dvb_pmt_callback(th_dvb_mux_instance_t *tdmi, uint8_t *ptr, int len, uint8_t tableid, void *opaque) { - th_transport_t *t; + service_t *t; - LIST_FOREACH(t, &tdmi->tdmi_transports, tht_group_link) { - pthread_mutex_lock(&t->tht_stream_mutex); + LIST_FOREACH(t, &tdmi->tdmi_transports, s_group_link) { + pthread_mutex_lock(&t->s_stream_mutex); psi_parse_pmt(t, ptr, len, 1, 1); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_unlock(&t->s_stream_mutex); } return 0; } diff --git a/src/dvb/dvb_transport.c b/src/dvb/dvb_transport.c index 8acaec75..ff424716 100644 --- a/src/dvb/dvb_transport.c +++ b/src/dvb/dvb_transport.c @@ -39,7 +39,6 @@ #include "tvheadend.h" #include "dvb.h" #include "channels.h" -#include "transports.h" #include "subscriptions.h" #include "psi.h" #include "dvb_support.h" @@ -49,13 +48,13 @@ * */ static void -dvb_transport_open_demuxers(th_dvb_adapter_t *tda, th_transport_t *t) +dvb_transport_open_demuxers(th_dvb_adapter_t *tda, service_t *t) { struct dmx_pes_filter_params dmx_param; int fd; th_stream_t *st; - TAILQ_FOREACH(st, &t->tht_components, st_link) { + TAILQ_FOREACH(st, &t->s_components, st_link) { if(st->st_pid >= 0x2000) continue; @@ -69,7 +68,7 @@ dvb_transport_open_demuxers(th_dvb_adapter_t *tda, th_transport_t *t) st->st_demuxer_fd = -1; tvhlog(LOG_ERR, "dvb", "\"%s\" unable to open demuxer \"%s\" for pid %d -- %s", - t->tht_identifier, tda->tda_demux_path, + t->s_identifier, tda->tda_demux_path, st->st_pid, strerror(errno)); continue; } @@ -84,7 +83,7 @@ dvb_transport_open_demuxers(th_dvb_adapter_t *tda, th_transport_t *t) if(ioctl(fd, DMX_SET_PES_FILTER, &dmx_param)) { tvhlog(LOG_ERR, "dvb", "\"%s\" unable to configure demuxer \"%s\" for pid %d -- %s", - t->tht_identifier, tda->tda_demux_path, + t->s_identifier, tda->tda_demux_path, st->st_pid, strerror(errno)); close(fd); fd = -1; @@ -104,10 +103,10 @@ dvb_transport_open_demuxers(th_dvb_adapter_t *tda, th_transport_t *t) * transports that is subscribing to the adapter */ static int -dvb_transport_start(th_transport_t *t, unsigned int weight, int force_start) +dvb_transport_start(service_t *t, unsigned int weight, int force_start) { int w, r; - th_dvb_adapter_t *tda = t->tht_dvb_mux_instance->tdmi_adapter; + th_dvb_adapter_t *tda = t->s_dvb_mux_instance->tdmi_adapter; th_dvb_mux_instance_t *tdmi = tda->tda_mux_current; lock_assert(&global_lock); @@ -115,16 +114,16 @@ dvb_transport_start(th_transport_t *t, unsigned int weight, int force_start) if(tda->tda_rootpath == NULL) return SM_CODE_NO_HW_ATTACHED; - if(t->tht_dvb_mux_instance && !t->tht_dvb_mux_instance->tdmi_enabled) + if(t->s_dvb_mux_instance && !t->s_dvb_mux_instance->tdmi_enabled) return SM_CODE_MUX_NOT_ENABLED; /* Mux is disabled */ /* Check if adapter is idle, or already tuned */ if(tdmi != NULL && - (tdmi != t->tht_dvb_mux_instance || + (tdmi != t->s_dvb_mux_instance || tda->tda_hostconnection == HOSTCONNECTION_USB12)) { - w = transport_compute_weight(&tda->tda_transports); + w = service_compute_weight(&tda->tda_transports); if(w && w >= weight && !force_start) /* We are outranked by weight, cant use it */ return SM_CODE_NOT_FREE; @@ -134,9 +133,9 @@ dvb_transport_start(th_transport_t *t, unsigned int weight, int force_start) pthread_mutex_lock(&tda->tda_delivery_mutex); - r = dvb_fe_tune(t->tht_dvb_mux_instance, "Transport start"); + r = dvb_fe_tune(t->s_dvb_mux_instance, "Transport start"); if(!r) - LIST_INSERT_HEAD(&tda->tda_transports, t, tht_active_link); + LIST_INSERT_HEAD(&tda->tda_transports, t, s_active_link); pthread_mutex_unlock(&tda->tda_delivery_mutex); @@ -151,24 +150,24 @@ dvb_transport_start(th_transport_t *t, unsigned int weight, int force_start) * */ static void -dvb_transport_stop(th_transport_t *t) +dvb_transport_stop(service_t *t) { - th_dvb_adapter_t *tda = t->tht_dvb_mux_instance->tdmi_adapter; + th_dvb_adapter_t *tda = t->s_dvb_mux_instance->tdmi_adapter; th_stream_t *st; lock_assert(&global_lock); pthread_mutex_lock(&tda->tda_delivery_mutex); - LIST_REMOVE(t, tht_active_link); + LIST_REMOVE(t, s_active_link); pthread_mutex_unlock(&tda->tda_delivery_mutex); - TAILQ_FOREACH(st, &t->tht_components, st_link) { + TAILQ_FOREACH(st, &t->s_components, st_link) { if(st->st_demuxer_fd != -1) { close(st->st_demuxer_fd); st->st_demuxer_fd = -1; } } - t->tht_status = TRANSPORT_IDLE; + t->s_status = SERVICE_IDLE; } @@ -176,9 +175,9 @@ dvb_transport_stop(th_transport_t *t) * */ static void -dvb_transport_refresh(th_transport_t *t) +dvb_transport_refresh(service_t *t) { - th_dvb_adapter_t *tda = t->tht_dvb_mux_instance->tdmi_adapter; + th_dvb_adapter_t *tda = t->s_dvb_mux_instance->tdmi_adapter; lock_assert(&global_lock); dvb_transport_open_demuxers(tda, t); @@ -197,7 +196,7 @@ dvb_transport_load(th_dvb_mux_instance_t *tdmi) uint32_t sid, pmt; const char *s; unsigned int u32; - th_transport_t *t; + service_t *t; lock_assert(&global_lock); @@ -216,32 +215,32 @@ dvb_transport_load(th_dvb_mux_instance_t *tdmi) t = dvb_transport_find(tdmi, sid, pmt, f->hmf_name); - htsmsg_get_u32(c, "stype", &t->tht_servicetype); + htsmsg_get_u32(c, "stype", &t->s_servicetype); if(htsmsg_get_u32(c, "scrambled", &u32)) u32 = 0; - t->tht_scrambled = u32; + t->s_scrambled = u32; if(htsmsg_get_u32(c, "channel", &u32)) u32 = 0; - t->tht_channel_number = u32; + t->s_channel_number = u32; s = htsmsg_get_str(c, "provider"); - t->tht_provider = s ? strdup(s) : NULL; + t->s_provider = s ? strdup(s) : NULL; s = htsmsg_get_str(c, "servicename"); - t->tht_svcname = s ? strdup(s) : NULL; + t->s_svcname = s ? strdup(s) : NULL; - pthread_mutex_lock(&t->tht_stream_mutex); - transport_make_nicename(t); - psi_load_transport_settings(c, t); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + service_make_nicename(t); + psi_load_service_settings(c, t); + pthread_mutex_unlock(&t->s_stream_mutex); s = htsmsg_get_str(c, "channelname"); if(htsmsg_get_u32(c, "mapped", &u32)) u32 = 0; if(s && u32) - transport_map_channel(t, channel_find_by_name(s, 1, 0), 0); + service_map_channel(t, channel_find_by_name(s, 1, 0), 0); } htsmsg_destroy(l); } @@ -250,36 +249,36 @@ dvb_transport_load(th_dvb_mux_instance_t *tdmi) * */ static void -dvb_transport_save(th_transport_t *t) +dvb_transport_save(service_t *t) { htsmsg_t *m = htsmsg_create_map(); lock_assert(&global_lock); - htsmsg_add_u32(m, "service_id", t->tht_dvb_service_id); - htsmsg_add_u32(m, "pmt", t->tht_pmt_pid); - htsmsg_add_u32(m, "stype", t->tht_servicetype); - htsmsg_add_u32(m, "scrambled", t->tht_scrambled); - htsmsg_add_u32(m, "channel", t->tht_channel_number); + htsmsg_add_u32(m, "service_id", t->s_dvb_service_id); + htsmsg_add_u32(m, "pmt", t->s_pmt_pid); + htsmsg_add_u32(m, "stype", t->s_servicetype); + htsmsg_add_u32(m, "scrambled", t->s_scrambled); + htsmsg_add_u32(m, "channel", t->s_channel_number); - if(t->tht_provider != NULL) - htsmsg_add_str(m, "provider", t->tht_provider); + if(t->s_provider != NULL) + htsmsg_add_str(m, "provider", t->s_provider); - if(t->tht_svcname != NULL) - htsmsg_add_str(m, "servicename", t->tht_svcname); + if(t->s_svcname != NULL) + htsmsg_add_str(m, "servicename", t->s_svcname); - if(t->tht_ch != NULL) { - htsmsg_add_str(m, "channelname", t->tht_ch->ch_name); + if(t->s_ch != NULL) { + htsmsg_add_str(m, "channelname", t->s_ch->ch_name); htsmsg_add_u32(m, "mapped", 1); } - pthread_mutex_lock(&t->tht_stream_mutex); - psi_save_transport_settings(m, t); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + psi_save_service_settings(m, t); + pthread_mutex_unlock(&t->s_stream_mutex); hts_settings_save(m, "dvbtransports/%s/%s", - t->tht_dvb_mux_instance->tdmi_identifier, - t->tht_identifier); + t->s_dvb_mux_instance->tdmi_identifier, + t->s_identifier); htsmsg_destroy(m); dvb_transport_notify(t); @@ -293,9 +292,9 @@ dvb_transport_save(th_transport_t *t) * return that value */ static int -dvb_transport_quality(th_transport_t *t) +dvb_transport_quality(service_t *t) { - th_dvb_mux_instance_t *tdmi = t->tht_dvb_mux_instance; + th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance; lock_assert(&global_lock); @@ -307,9 +306,9 @@ dvb_transport_quality(th_transport_t *t) * Generate a descriptive name for the source */ static void -dvb_transport_setsourceinfo(th_transport_t *t, struct source_info *si) +dvb_transport_setsourceinfo(service_t *t, struct source_info *si) { - th_dvb_mux_instance_t *tdmi = t->tht_dvb_mux_instance; + th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance; char buf[100]; memset(si, 0, sizeof(struct source_info)); @@ -327,11 +326,11 @@ dvb_transport_setsourceinfo(th_transport_t *t, struct source_info *si) dvb_mux_nicename(buf, sizeof(buf), tdmi); si->si_mux = strdup(buf); - if(t->tht_provider != NULL) - si->si_provider = strdup(t->tht_provider); + if(t->s_provider != NULL) + si->si_provider = strdup(t->s_provider); - if(t->tht_svcname != NULL) - si->si_service = strdup(t->tht_svcname); + if(t->s_svcname != NULL) + si->si_service = strdup(t->s_svcname); } @@ -339,7 +338,7 @@ dvb_transport_setsourceinfo(th_transport_t *t, struct source_info *si) * */ static int -dvb_grace_period(th_transport_t *t) +dvb_grace_period(service_t *t) { return 10; } @@ -350,18 +349,18 @@ dvb_grace_period(th_transport_t *t) * * If it cannot be found we create it if 'pmt_pid' is also set */ -th_transport_t * +service_t * dvb_transport_find(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, const char *identifier) { - th_transport_t *t; + service_t *t; char tmp[200]; char buf[200]; lock_assert(&global_lock); - LIST_FOREACH(t, &tdmi->tdmi_transports, tht_group_link) { - if(t->tht_dvb_service_id == sid) + LIST_FOREACH(t, &tdmi->tdmi_transports, s_group_link) { + if(t->s_dvb_service_id == sid) return t; } @@ -376,25 +375,25 @@ dvb_transport_find(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, dvb_mux_nicename(buf, sizeof(buf), tdmi); tvhlog(LOG_DEBUG, "dvb", "Add service \"%s\" on \"%s\"", identifier, buf); - t = transport_create(identifier, TRANSPORT_DVB, THT_MPEG_TS); + t = service_create(identifier, SERVICE_TYPE_DVB, S_MPEG_TS); - t->tht_dvb_service_id = sid; - t->tht_pmt_pid = pmt_pid; + t->s_dvb_service_id = sid; + t->s_pmt_pid = pmt_pid; - t->tht_start_feed = dvb_transport_start; - t->tht_refresh_feed = dvb_transport_refresh; - t->tht_stop_feed = dvb_transport_stop; - t->tht_config_save = dvb_transport_save; - t->tht_setsourceinfo = dvb_transport_setsourceinfo; - t->tht_quality_index = dvb_transport_quality; - t->tht_grace_period = dvb_grace_period; + t->s_start_feed = dvb_transport_start; + t->s_refresh_feed = dvb_transport_refresh; + t->s_stop_feed = dvb_transport_stop; + t->s_config_save = dvb_transport_save; + t->s_setsourceinfo = dvb_transport_setsourceinfo; + t->s_quality_index = dvb_transport_quality; + t->s_grace_period = dvb_grace_period; - t->tht_dvb_mux_instance = tdmi; - LIST_INSERT_HEAD(&tdmi->tdmi_transports, t, tht_group_link); + t->s_dvb_mux_instance = tdmi; + LIST_INSERT_HEAD(&tdmi->tdmi_transports, t, s_group_link); - pthread_mutex_lock(&t->tht_stream_mutex); - transport_make_nicename(t); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + service_make_nicename(t); + pthread_mutex_unlock(&t->s_stream_mutex); dvb_adapter_notify(tdmi->tdmi_adapter); return t; @@ -405,32 +404,32 @@ dvb_transport_find(th_dvb_mux_instance_t *tdmi, uint16_t sid, int pmt_pid, * */ htsmsg_t * -dvb_transport_build_msg(th_transport_t *t) +dvb_transport_build_msg(service_t *t) { - th_dvb_mux_instance_t *tdmi = t->tht_dvb_mux_instance; + th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance; htsmsg_t *m = htsmsg_create_map(); char buf[100]; - htsmsg_add_str(m, "id", t->tht_identifier); - htsmsg_add_u32(m, "enabled", t->tht_enabled); - htsmsg_add_u32(m, "channel", t->tht_channel_number); + htsmsg_add_str(m, "id", t->s_identifier); + htsmsg_add_u32(m, "enabled", t->s_enabled); + htsmsg_add_u32(m, "channel", t->s_channel_number); - htsmsg_add_u32(m, "sid", t->tht_dvb_service_id); - htsmsg_add_u32(m, "pmt", t->tht_pmt_pid); - htsmsg_add_u32(m, "pcr", t->tht_pcr_pid); + htsmsg_add_u32(m, "sid", t->s_dvb_service_id); + htsmsg_add_u32(m, "pmt", t->s_pmt_pid); + htsmsg_add_u32(m, "pcr", t->s_pcr_pid); - htsmsg_add_str(m, "type", transport_servicetype_txt(t)); + htsmsg_add_str(m, "type", service_servicetype_txt(t)); - htsmsg_add_str(m, "svcname", t->tht_svcname ?: ""); - htsmsg_add_str(m, "provider", t->tht_provider ?: ""); + htsmsg_add_str(m, "svcname", t->s_svcname ?: ""); + htsmsg_add_str(m, "provider", t->s_provider ?: ""); htsmsg_add_str(m, "network", tdmi->tdmi_network ?: ""); dvb_mux_nicefreq(buf, sizeof(buf), tdmi); htsmsg_add_str(m, "mux", buf); - if(t->tht_ch != NULL) - htsmsg_add_str(m, "channelname", t->tht_ch->ch_name); + if(t->s_ch != NULL) + htsmsg_add_str(m, "channelname", t->s_ch->ch_name); return m; } @@ -452,9 +451,9 @@ dvb_transport_notify_by_adapter(th_dvb_adapter_t *tda) * */ void -dvb_transport_notify(th_transport_t *t) +dvb_transport_notify(service_t *t) { - th_dvb_mux_instance_t *tdmi = t->tht_dvb_mux_instance; + th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance; htsmsg_t *m = htsmsg_create_map(); htsmsg_add_str(m, "adapterId", tdmi->tdmi_adapter->tda_identifier); @@ -466,9 +465,9 @@ dvb_transport_notify(th_transport_t *t) * Get the signal status from a DVB transport */ int -dvb_transport_get_signal_status(th_transport_t *t, signal_status_t *status) +dvb_transport_get_signal_status(service_t *t, signal_status_t *status) { - th_dvb_mux_instance_t *tdmi = t->tht_dvb_mux_instance; + th_dvb_mux_instance_t *tdmi = t->s_dvb_mux_instance; status->status_text = dvb_mux_status(tdmi); status->snr = tdmi->tdmi_snr; diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 190d55d2..6bf667fd 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -29,8 +29,7 @@ #include "streaming.h" #include "dvr.h" #include "spawn.h" -#include "transports.h" - +#include "service.h" #include "plumbing/tsfix.h" #include "plumbing/globalheaders.h" @@ -445,7 +444,7 @@ dvr_thread(void *aux) dvr_thread_epilog(de); break; - case SMT_TRANSPORT_STATUS: + case SMT_SERVICE_STATUS: if(sm->sm_code & TSS_PACKETS) { } else if(sm->sm_code & (TSS_GRACEPERIOD | TSS_ERRORS)) { diff --git a/src/htsp.c b/src/htsp.c index c37c0281..9a49ad21 100644 --- a/src/htsp.c +++ b/src/htsp.c @@ -37,7 +37,6 @@ #include "access.h" #include "htsp.h" #include "streaming.h" -#include "transports.h" #include "psi.h" #include "htsmsg_binary.h" @@ -295,7 +294,7 @@ htsp_build_channel(channel_t *ch, const char *method) { channel_tag_mapping_t *ctm; channel_tag_t *ct; - th_transport_t *t; + service_t *t; htsmsg_t *out = htsmsg_create_map(); htsmsg_t *tags = htsmsg_create_list(); @@ -317,12 +316,12 @@ htsp_build_channel(channel_t *ch, const char *method) htsmsg_add_u32(tags, NULL, ct->ct_identifier); } - LIST_FOREACH(t, &ch->ch_transports, tht_ch_link) { + LIST_FOREACH(t, &ch->ch_services, s_ch_link) { htsmsg_t *svcmsg = htsmsg_create_map(); uint16_t caid; - htsmsg_add_str(svcmsg, "name", transport_nicename(t)); - htsmsg_add_str(svcmsg, "type", transport_servicetype_txt(t)); - if((caid = transport_get_encryption(t)) != 0) { + htsmsg_add_str(svcmsg, "name", service_nicename(t)); + htsmsg_add_str(svcmsg, "type", service_servicetype_txt(t)); + if((caid = service_get_encryption(t)) != 0) { htsmsg_add_u32(svcmsg, "caid", caid); htsmsg_add_str(svcmsg, "caname", psi_caid2name(caid)); } @@ -1380,7 +1379,7 @@ const static char frametypearray[PKT_NTYPES] = { }; /** - * Build a htsmsg from a th_pkt and enqueue it on our HTSP transport + * Build a htsmsg from a th_pkt and enqueue it on our HTSP service */ static void htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) @@ -1470,7 +1469,7 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) htsp_send_message(hs->hs_htsp, m, &hs->hs_htsp->htsp_hmq_qstatus); - if(!transport_get_signal_status(hs->hs_s->ths_transport, &status)) { + if(!service_get_signal_status(hs->hs_s->ths_service, &status)) { m = htsmsg_create_map(); htsmsg_add_str(m, "method", "signalStatus"); @@ -1585,12 +1584,12 @@ htsp_subscription_status(htsp_subscription_t *hs, const char *err) * */ static void -htsp_subscription_transport_status(htsp_subscription_t *hs, int status) +htsp_subscription_service_status(htsp_subscription_t *hs, int status) { if(status & TSS_PACKETS) { htsp_subscription_status(hs, NULL); } else if(status & (TSS_GRACEPERIOD | TSS_ERRORS)) { - htsp_subscription_status(hs, transport_tss2text(status)); + htsp_subscription_status(hs, service_tss2text(status)); } } @@ -1616,8 +1615,8 @@ htsp_streaming_input(void *opaque, streaming_message_t *sm) htsp_subscription_stop(hs, streaming_code2txt(sm->sm_code)); break; - case SMT_TRANSPORT_STATUS: - htsp_subscription_transport_status(hs, sm->sm_code); + case SMT_SERVICE_STATUS: + htsp_subscription_service_status(hs, sm->sm_code); break; case SMT_NOSTART: diff --git a/src/iptv_input.c b/src/iptv_input.c index 4d83efa3..70bdb6f4 100644 --- a/src/iptv_input.c +++ b/src/iptv_input.c @@ -36,7 +36,6 @@ #include "tvheadend.h" #include "htsmsg.h" #include "channels.h" -#include "transports.h" #include "iptv_input.h" #include "tsdemux.h" #include "psi.h" @@ -46,8 +45,8 @@ static int iptv_thread_running; static int iptv_epollfd; static pthread_mutex_t iptv_recvmutex; -struct th_transport_list iptv_all_transports; /* All IPTV transports */ -static struct th_transport_list iptv_active_transports; /* Currently enabled */ +struct service_list iptv_all_services; /* All IPTV services */ +static struct service_list iptv_active_services; /* Currently enabled */ /** * PAT parser. We only parse a single program. CRC has already been verified @@ -55,7 +54,7 @@ static struct th_transport_list iptv_active_transports; /* Currently enabled */ static void iptv_got_pat(const uint8_t *ptr, size_t len, void *aux) { - th_transport_t *t = aux; + service_t *t = aux; uint16_t prognum, pmt; len -= 8; @@ -67,7 +66,7 @@ iptv_got_pat(const uint8_t *ptr, size_t len, void *aux) prognum = ptr[0] << 8 | ptr[1]; pmt = (ptr[2] & 0x1f) << 8 | ptr[3]; - t->tht_pmt_pid = pmt; + t->s_pmt_pid = pmt; } @@ -77,36 +76,36 @@ iptv_got_pat(const uint8_t *ptr, size_t len, void *aux) static void iptv_got_pmt(const uint8_t *ptr, size_t len, void *aux) { - th_transport_t *t = aux; + service_t *t = aux; if(len < 3 || ptr[0] != 2) return; - pthread_mutex_lock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); psi_parse_pmt(t, ptr + 3, len - 3, 0, 1); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_unlock(&t->s_stream_mutex); } /** - * Handle a single TS packet for the given IPTV transport + * Handle a single TS packet for the given IPTV service */ static void -iptv_ts_input(th_transport_t *t, const uint8_t *tsb) +iptv_ts_input(service_t *t, const uint8_t *tsb) { uint16_t pid = ((tsb[1] & 0x1f) << 8) | tsb[2]; if(pid == 0) { - if(t->tht_pat_section == NULL) - t->tht_pat_section = calloc(1, sizeof(psi_section_t)); - psi_section_reassemble(t->tht_pat_section, tsb, 1, iptv_got_pat, t); + if(t->s_pat_section == NULL) + t->s_pat_section = calloc(1, sizeof(psi_section_t)); + psi_section_reassemble(t->s_pat_section, tsb, 1, iptv_got_pat, t); - } else if(pid == t->tht_pmt_pid) { + } else if(pid == t->s_pmt_pid) { - if(t->tht_pmt_section == NULL) - t->tht_pmt_section = calloc(1, sizeof(psi_section_t)); - psi_section_reassemble(t->tht_pmt_section, tsb, 1, iptv_got_pmt, t); + if(t->s_pmt_section == NULL) + t->s_pmt_section = calloc(1, sizeof(psi_section_t)); + psi_section_reassemble(t->s_pmt_section, tsb, 1, iptv_got_pmt, t); } else { ts_recv_packet1(t, tsb, NULL); @@ -123,7 +122,7 @@ iptv_thread(void *aux) int nfds, fd, r, j; uint8_t tsb[65536], *buf; struct epoll_event ev; - th_transport_t *t; + service_t *t; while(1) { nfds = epoll_wait(iptv_epollfd, &ev, 1, -1); @@ -165,8 +164,8 @@ iptv_thread(void *aux) pthread_mutex_lock(&iptv_recvmutex); - LIST_FOREACH(t, &iptv_active_transports, tht_active_link) { - if(t->tht_iptv_fd != fd) + LIST_FOREACH(t, &iptv_active_services, s_active_link) { + if(t->s_iptv_fd != fd) continue; for(j = 0; j < r; j += 188) @@ -182,7 +181,7 @@ iptv_thread(void *aux) * */ static int -iptv_transport_start(th_transport_t *t, unsigned int weight, int force_start) +iptv_service_start(service_t *t, unsigned int weight, int force_start) { pthread_t tid; int fd; @@ -194,7 +193,7 @@ iptv_transport_start(th_transport_t *t, unsigned int weight, int force_start) struct ifreq ifr; struct epoll_event ev; - assert(t->tht_iptv_fd == -1); + assert(t->s_iptv_fd == -1); if(iptv_thread_running == 0) { iptv_thread_running = 1; @@ -203,7 +202,7 @@ iptv_transport_start(th_transport_t *t, unsigned int weight, int force_start) } /* Now, open the real socket for UDP */ - if(t->tht_iptv_group.s_addr!=0) { + if(t->s_iptv_group.s_addr!=0) { fd = tvh_socket(AF_INET, SOCK_DGRAM, 0); } @@ -211,44 +210,44 @@ iptv_transport_start(th_transport_t *t, unsigned int weight, int force_start) fd = tvh_socket(AF_INET6, SOCK_DGRAM, 0); } if(fd == -1) { - tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot open socket", t->tht_identifier); + tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot open socket", t->s_identifier); return -1; } /* First, resolve interface name */ memset(&ifr, 0, sizeof(ifr)); - snprintf(ifr.ifr_name, IFNAMSIZ, "%s", t->tht_iptv_iface); + snprintf(ifr.ifr_name, IFNAMSIZ, "%s", t->s_iptv_iface); ifr.ifr_name[IFNAMSIZ - 1] = 0; if(ioctl(fd, SIOCGIFINDEX, &ifr)) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot find interface %s", - t->tht_identifier, t->tht_iptv_iface); + t->s_identifier, t->s_iptv_iface); close(fd); return -1; } /* Bind to IPv4 multicast group */ - if(t->tht_iptv_group.s_addr!=0) { + if(t->s_iptv_group.s_addr!=0) { memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; - sin.sin_port = htons(t->tht_iptv_port); - sin.sin_addr.s_addr = t->tht_iptv_group.s_addr; + sin.sin_port = htons(t->s_iptv_port); + sin.sin_addr.s_addr = t->s_iptv_group.s_addr; if(bind(fd, (struct sockaddr *)&sin, sizeof(sin)) == -1) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot bind %s:%d -- %s", - t->tht_identifier, inet_ntoa(sin.sin_addr), t->tht_iptv_port, + t->s_identifier, inet_ntoa(sin.sin_addr), t->s_iptv_port, strerror(errno)); close(fd); return -1; } /* Join IPv4 group */ memset(&m, 0, sizeof(m)); - m.imr_multiaddr.s_addr = t->tht_iptv_group.s_addr; + m.imr_multiaddr.s_addr = t->s_iptv_group.s_addr; m.imr_address.s_addr = 0; m.imr_ifindex = ifr.ifr_ifindex; if(setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &m, sizeof(struct ip_mreqn)) == -1) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot join %s -- %s", - t->tht_identifier, inet_ntoa(m.imr_multiaddr), strerror(errno)); + t->s_identifier, inet_ntoa(m.imr_multiaddr), strerror(errno)); close(fd); return -1; } @@ -256,19 +255,19 @@ iptv_transport_start(th_transport_t *t, unsigned int weight, int force_start) /* Bind to IPv6 multicast group */ memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; - sin6.sin6_port = htons(t->tht_iptv_port); - sin6.sin6_addr = t->tht_iptv_group6; + sin6.sin6_port = htons(t->s_iptv_port); + sin6.sin6_addr = t->s_iptv_group6; if(bind(fd, (struct sockaddr *)&sin6, sizeof(sin6)) == -1) { inet_ntop(AF_INET6, &sin6.sin6_addr, straddr, sizeof(straddr)); tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot bind %s:%d -- %s", - t->tht_identifier, straddr, t->tht_iptv_port, + t->s_identifier, straddr, t->s_iptv_port, strerror(errno)); close(fd); return -1; } /* Join IPv6 group */ memset(&m6, 0, sizeof(m6)); - m6.ipv6mr_multiaddr = t->tht_iptv_group6; + m6.ipv6mr_multiaddr = t->s_iptv_group6; m6.ipv6mr_interface = ifr.ifr_ifindex; if(setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &m6, @@ -276,7 +275,7 @@ iptv_transport_start(th_transport_t *t, unsigned int weight, int force_start) inet_ntop(AF_INET6, m6.ipv6mr_multiaddr.s6_addr, straddr, sizeof(straddr)); tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot join %s -- %s", - t->tht_identifier, straddr, strerror(errno)); + t->s_identifier, straddr, strerror(errno)); close(fd); return -1; } @@ -294,15 +293,15 @@ iptv_transport_start(th_transport_t *t, unsigned int weight, int force_start) ev.data.fd = fd; if(epoll_ctl(iptv_epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot add to epoll set -- %s", - t->tht_identifier, strerror(errno)); + t->s_identifier, strerror(errno)); close(fd); return -1; } - t->tht_iptv_fd = fd; + t->s_iptv_fd = fd; pthread_mutex_lock(&iptv_recvmutex); - LIST_INSERT_HEAD(&iptv_active_transports, t, tht_active_link); + LIST_INSERT_HEAD(&iptv_active_services, t, s_active_link); pthread_mutex_unlock(&iptv_recvmutex); return 0; } @@ -312,7 +311,7 @@ iptv_transport_start(th_transport_t *t, unsigned int weight, int force_start) * */ static void -iptv_transport_refresh(th_transport_t *t) +iptv_service_refresh(service_t *t) { } @@ -322,38 +321,38 @@ iptv_transport_refresh(th_transport_t *t) * */ static void -iptv_transport_stop(th_transport_t *t) +iptv_service_stop(service_t *t) { struct ifreq ifr; pthread_mutex_lock(&iptv_recvmutex); - LIST_REMOVE(t, tht_active_link); + LIST_REMOVE(t, s_active_link); pthread_mutex_unlock(&iptv_recvmutex); - assert(t->tht_iptv_fd >= 0); + assert(t->s_iptv_fd >= 0); /* First, resolve interface name */ memset(&ifr, 0, sizeof(ifr)); - snprintf(ifr.ifr_name, IFNAMSIZ, "%s", t->tht_iptv_iface); + snprintf(ifr.ifr_name, IFNAMSIZ, "%s", t->s_iptv_iface); ifr.ifr_name[IFNAMSIZ - 1] = 0; - if(ioctl(t->tht_iptv_fd, SIOCGIFINDEX, &ifr)) { + if(ioctl(t->s_iptv_fd, SIOCGIFINDEX, &ifr)) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot find interface %s", - t->tht_identifier, t->tht_iptv_iface); + t->s_identifier, t->s_iptv_iface); } - if(t->tht_iptv_group.s_addr != 0) { + if(t->s_iptv_group.s_addr != 0) { struct ip_mreqn m; memset(&m, 0, sizeof(m)); /* Leave multicast group */ - m.imr_multiaddr.s_addr = t->tht_iptv_group.s_addr; + m.imr_multiaddr.s_addr = t->s_iptv_group.s_addr; m.imr_address.s_addr = 0; m.imr_ifindex = ifr.ifr_ifindex; - if(setsockopt(t->tht_iptv_fd, SOL_IP, IP_DROP_MEMBERSHIP, &m, + if(setsockopt(t->s_iptv_fd, SOL_IP, IP_DROP_MEMBERSHIP, &m, sizeof(struct ip_mreqn)) == -1) { tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot leave %s -- %s", - t->tht_identifier, inet_ntoa(m.imr_multiaddr), strerror(errno)); + t->s_identifier, inet_ntoa(m.imr_multiaddr), strerror(errno)); } } else { char straddr[INET6_ADDRSTRLEN]; @@ -361,24 +360,24 @@ iptv_transport_stop(th_transport_t *t) struct ipv6_mreq m6; memset(&m6, 0, sizeof(m6)); - m6.ipv6mr_multiaddr = t->tht_iptv_group6; + m6.ipv6mr_multiaddr = t->s_iptv_group6; m6.ipv6mr_interface = ifr.ifr_ifindex; - if(setsockopt(t->tht_iptv_fd, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &m6, + if(setsockopt(t->s_iptv_fd, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &m6, sizeof(struct ipv6_mreq)) == -1) { inet_ntop(AF_INET6, m6.ipv6mr_multiaddr.s6_addr, straddr, sizeof(straddr)); tvhlog(LOG_ERR, "IPTV", "\"%s\" cannot leave %s -- %s", - t->tht_identifier, straddr, strerror(errno)); + t->s_identifier, straddr, strerror(errno)); } } - close(t->tht_iptv_fd); // Automatically removes fd from epoll set + close(t->s_iptv_fd); // Automatically removes fd from epoll set - t->tht_iptv_fd = -1; + t->s_iptv_fd = -1; } @@ -386,7 +385,7 @@ iptv_transport_stop(th_transport_t *t) * */ static void -iptv_transport_save(th_transport_t *t) +iptv_service_save(service_t *t) { htsmsg_t *m = htsmsg_create_map(); char abuf[INET_ADDRSTRLEN]; @@ -394,33 +393,33 @@ iptv_transport_save(th_transport_t *t) lock_assert(&global_lock); - htsmsg_add_u32(m, "pmt", t->tht_pmt_pid); + htsmsg_add_u32(m, "pmt", t->s_pmt_pid); - if(t->tht_iptv_port) - htsmsg_add_u32(m, "port", t->tht_iptv_port); + if(t->s_iptv_port) + htsmsg_add_u32(m, "port", t->s_iptv_port); - if(t->tht_iptv_iface) - htsmsg_add_str(m, "interface", t->tht_iptv_iface); + if(t->s_iptv_iface) + htsmsg_add_str(m, "interface", t->s_iptv_iface); - if(t->tht_iptv_group.s_addr!= 0) { - inet_ntop(AF_INET, &t->tht_iptv_group, abuf, sizeof(abuf)); + if(t->s_iptv_group.s_addr!= 0) { + inet_ntop(AF_INET, &t->s_iptv_group, abuf, sizeof(abuf)); htsmsg_add_str(m, "group", abuf); } - if(IN6_IS_ADDR_MULTICAST(t->tht_iptv_group6.s6_addr) ) { - inet_ntop(AF_INET6, &t->tht_iptv_group6, abuf6, sizeof(abuf6)); + if(IN6_IS_ADDR_MULTICAST(t->s_iptv_group6.s6_addr) ) { + inet_ntop(AF_INET6, &t->s_iptv_group6, abuf6, sizeof(abuf6)); htsmsg_add_str(m, "group", abuf6); } - if(t->tht_ch != NULL) { - htsmsg_add_str(m, "channelname", t->tht_ch->ch_name); + if(t->s_ch != NULL) { + htsmsg_add_str(m, "channelname", t->s_ch->ch_name); htsmsg_add_u32(m, "mapped", 1); } - pthread_mutex_lock(&t->tht_stream_mutex); - psi_save_transport_settings(m, t); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + psi_save_service_settings(m, t); + pthread_mutex_unlock(&t->s_stream_mutex); - hts_settings_save(m, "iptvtransports/%s", - t->tht_identifier); + hts_settings_save(m, "iptvservices/%s", + t->s_identifier); htsmsg_destroy(m); } @@ -430,11 +429,11 @@ iptv_transport_save(th_transport_t *t) * */ static int -iptv_transport_quality(th_transport_t *t) +iptv_service_quality(service_t *t) { - if(t->tht_iptv_iface == NULL || - (t->tht_iptv_group.s_addr == 0 && t->tht_iptv_group6.s6_addr == 0) || - t->tht_iptv_port == 0) + if(t->s_iptv_iface == NULL || + (t->s_iptv_group.s_addr == 0 && t->s_iptv_group6.s6_addr == 0) || + t->s_iptv_port == 0) return 0; return 100; @@ -445,17 +444,17 @@ iptv_transport_quality(th_transport_t *t) * Generate a descriptive name for the source */ static void -iptv_transport_setsourceinfo(th_transport_t *t, struct source_info *si) +iptv_service_setsourceinfo(service_t *t, struct source_info *si) { char straddr[INET6_ADDRSTRLEN]; memset(si, 0, sizeof(struct source_info)); - si->si_adapter = t->tht_iptv_iface ? strdup(t->tht_iptv_iface) : NULL; - if(t->tht_iptv_group.s_addr != 0) { - si->si_mux = strdup(inet_ntoa(t->tht_iptv_group)); + si->si_adapter = t->s_iptv_iface ? strdup(t->s_iptv_iface) : NULL; + if(t->s_iptv_group.s_addr != 0) { + si->si_mux = strdup(inet_ntoa(t->s_iptv_group)); } else { - inet_ntop(AF_INET6, &t->tht_iptv_group6, straddr, sizeof(straddr)); + inet_ntop(AF_INET6, &t->s_iptv_group6, straddr, sizeof(straddr)); si->si_mux = strdup(straddr); } } @@ -465,7 +464,7 @@ iptv_transport_setsourceinfo(th_transport_t *t, struct source_info *si) * */ static int -iptv_grace_period(th_transport_t *t) +iptv_grace_period(service_t *t) { return 3; } @@ -475,20 +474,20 @@ iptv_grace_period(th_transport_t *t) * */ static void -iptv_transport_dtor(th_transport_t *t) +iptv_service_dtor(service_t *t) { - hts_settings_remove("iptvtransports/%s", t->tht_identifier); + hts_settings_remove("iptvservices/%s", t->s_identifier); } /** * */ -th_transport_t * -iptv_transport_find(const char *id, int create) +service_t * +iptv_service_find(const char *id, int create) { static int tally; - th_transport_t *t; + service_t *t; char buf[20]; if(id != NULL) { @@ -496,8 +495,8 @@ iptv_transport_find(const char *id, int create) if(strncmp(id, "iptv_", 5)) return NULL; - LIST_FOREACH(t, &iptv_all_transports, tht_group_link) - if(!strcmp(t->tht_identifier, id)) + LIST_FOREACH(t, &iptv_all_services, s_group_link) + if(!strcmp(t->s_identifier, id)) return t; } @@ -512,23 +511,23 @@ iptv_transport_find(const char *id, int create) tally = MAX(atoi(id + 5), tally); } - t = transport_create(id, TRANSPORT_IPTV, THT_MPEG_TS); + t = service_create(id, SERVICE_TYPE_IPTV, S_MPEG_TS); - t->tht_start_feed = iptv_transport_start; - t->tht_refresh_feed = iptv_transport_refresh; - t->tht_stop_feed = iptv_transport_stop; - t->tht_config_save = iptv_transport_save; - t->tht_setsourceinfo = iptv_transport_setsourceinfo; - t->tht_quality_index = iptv_transport_quality; - t->tht_grace_period = iptv_grace_period; - t->tht_dtor = iptv_transport_dtor; - t->tht_iptv_fd = -1; + t->s_start_feed = iptv_service_start; + t->s_refresh_feed = iptv_service_refresh; + t->s_stop_feed = iptv_service_stop; + t->s_config_save = iptv_service_save; + t->s_setsourceinfo = iptv_service_setsourceinfo; + t->s_quality_index = iptv_service_quality; + t->s_grace_period = iptv_grace_period; + t->s_dtor = iptv_service_dtor; + t->s_iptv_fd = -1; - LIST_INSERT_HEAD(&iptv_all_transports, t, tht_group_link); + LIST_INSERT_HEAD(&iptv_all_services, t, s_group_link); - pthread_mutex_lock(&t->tht_stream_mutex); - transport_make_nicename(t); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + service_make_nicename(t); + pthread_mutex_unlock(&t->s_stream_mutex); return t; } @@ -538,18 +537,18 @@ iptv_transport_find(const char *id, int create) * Load config for the given mux */ static void -iptv_transport_load(void) +iptv_service_load(void) { htsmsg_t *l, *c; htsmsg_field_t *f; uint32_t pmt; const char *s; unsigned int u32; - th_transport_t *t; + service_t *t; lock_assert(&global_lock); - if((l = hts_settings_load("iptvtransports")) == NULL) + if((l = hts_settings_load("iptvservices")) == NULL) return; HTSMSG_FOREACH(f, l) { @@ -559,31 +558,31 @@ iptv_transport_load(void) if(htsmsg_get_u32(c, "pmt", &pmt)) continue; - t = iptv_transport_find(f->hmf_name, 1); - t->tht_pmt_pid = pmt; + t = iptv_service_find(f->hmf_name, 1); + t->s_pmt_pid = pmt; - tvh_str_update(&t->tht_iptv_iface, htsmsg_get_str(c, "interface")); + tvh_str_update(&t->s_iptv_iface, htsmsg_get_str(c, "interface")); if((s = htsmsg_get_str(c, "group")) != NULL){ - if (!inet_pton(AF_INET, s, &t->tht_iptv_group.s_addr)) { - inet_pton(AF_INET6, s, &t->tht_iptv_group6.s6_addr); + if (!inet_pton(AF_INET, s, &t->s_iptv_group.s_addr)) { + inet_pton(AF_INET6, s, &t->s_iptv_group6.s6_addr); } } if(!htsmsg_get_u32(c, "port", &u32)) - t->tht_iptv_port = u32; + t->s_iptv_port = u32; - pthread_mutex_lock(&t->tht_stream_mutex); - transport_make_nicename(t); - psi_load_transport_settings(c, t); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + service_make_nicename(t); + psi_load_service_settings(c, t); + pthread_mutex_unlock(&t->s_stream_mutex); s = htsmsg_get_str(c, "channelname"); if(htsmsg_get_u32(c, "mapped", &u32)) u32 = 0; if(s && u32) - transport_map_channel(t, channel_find_by_name(s, 1, 0), 0); + service_map_channel(t, channel_find_by_name(s, 1, 0), 0); } htsmsg_destroy(l); } @@ -596,5 +595,5 @@ void iptv_input_init(void) { pthread_mutex_init(&iptv_recvmutex, NULL); - iptv_transport_load(); + iptv_service_load(); } diff --git a/src/iptv_input.h b/src/iptv_input.h index d5020b1e..a3cdde9a 100644 --- a/src/iptv_input.h +++ b/src/iptv_input.h @@ -21,8 +21,8 @@ void iptv_input_init(void); -th_transport_t *iptv_transport_find(const char *id, int create); +struct service *iptv_service_find(const char *id, int create); -extern struct th_transport_list iptv_all_transports; +extern struct service_list iptv_all_services; #endif /* IPTV_INPUT_H_ */ diff --git a/src/main.c b/src/main.c index b8ba18a0..71afd566 100644 --- a/src/main.c +++ b/src/main.c @@ -53,7 +53,7 @@ #include "rawtsinput.h" #include "avahi.h" #include "iptv_input.h" -#include "transports.h" +#include "service.h" #include "v4l.h" #include "trap.h" #include "settings.h" @@ -364,7 +364,7 @@ main(int argc, char **argv) */ xmltv_init(); /* Must be initialized before channels */ - transport_init(); + service_init(); channels_init(); diff --git a/src/parser_h264.c b/src/parser_h264.c index 7137172d..0f813a62 100644 --- a/src/parser_h264.c +++ b/src/parser_h264.c @@ -32,6 +32,7 @@ #include "parsers.h" #include "parser_h264.h" #include "bitstream.h" +#include "service.h" /** * H.264 parser, nal escaper diff --git a/src/parser_h264.h b/src/parser_h264.h index ac63fbdb..0bc9fedc 100644 --- a/src/parser_h264.h +++ b/src/parser_h264.h @@ -23,11 +23,11 @@ void *h264_nal_deescape(bitstream_t *bs, const uint8_t *data, int size); -int h264_decode_seq_parameter_set(th_stream_t *st, bitstream_t *bs); +int h264_decode_seq_parameter_set(struct th_stream *st, bitstream_t *bs); -int h264_decode_pic_parameter_set(th_stream_t *st, bitstream_t *bs); +int h264_decode_pic_parameter_set(struct th_stream *st, bitstream_t *bs); -int h264_decode_slice_header(th_stream_t *st, bitstream_t *bs, int *pkttype, - int *duration, int *isfield); +int h264_decode_slice_header(struct th_stream *st, bitstream_t *bs, + int *pkttype, int *duration, int *isfield); #endif /* PARSER_H264_H_ */ diff --git a/src/parser_latm.c b/src/parser_latm.c index 6097d2c4..255a7f98 100644 --- a/src/parser_latm.c +++ b/src/parser_latm.c @@ -34,7 +34,7 @@ #include "parsers.h" #include "parser_latm.h" #include "bitstream.h" - +#include "service.h" typedef struct latm_private { @@ -159,7 +159,7 @@ read_stream_mux_config(th_stream_t *st, latm_private_t *latm, bitstream_t *bs) * Parse AAC LATM */ th_pkt_t * -parse_latm_audio_mux_element(th_transport_t *t, th_stream_t *st, +parse_latm_audio_mux_element(service_t *t, th_stream_t *st, const uint8_t *data, int len) { latm_private_t *latm; @@ -196,7 +196,7 @@ parse_latm_audio_mux_element(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt = pkt_alloc(NULL, slot_len + 7, st->st_curdts, st->st_curdts); - pkt->pkt_commercial = t->tht_tt_commercial_advice; + pkt->pkt_commercial = t->s_tt_commercial_advice; pkt->pkt_duration = st->st_frame_duration; pkt->pkt_sri = latm->sample_rate_index; pkt->pkt_channels = latm->channel_config; diff --git a/src/parser_latm.h b/src/parser_latm.h index 94816869..664d356c 100644 --- a/src/parser_latm.h +++ b/src/parser_latm.h @@ -19,7 +19,8 @@ #ifndef PARSER_LATM_H_ #define PARSER_LATM_H_ -th_pkt_t *parse_latm_audio_mux_element(th_transport_t *t, th_stream_t *st, +th_pkt_t *parse_latm_audio_mux_element(struct service *t, + struct th_stream *st, const uint8_t *data, int len); #endif /* PARSER_LATM_H_ */ diff --git a/src/parsers.c b/src/parsers.c index 28213358..f7d15a06 100644 --- a/src/parsers.c +++ b/src/parsers.c @@ -26,12 +26,12 @@ #include #include "tvheadend.h" +#include "service.h" #include "parsers.h" #include "parser_h264.h" #include "parser_latm.h" #include "bitstream.h" #include "packet.h" -#include "transports.h" #include "streaming.h" #define PTS_MASK 0x1ffffffffLL @@ -81,48 +81,48 @@ getpts(const uint8_t *p) } -static int parse_mpeg2video(th_transport_t *t, th_stream_t *st, size_t len, +static int parse_mpeg2video(service_t *t, th_stream_t *st, size_t len, uint32_t next_startcode, int sc_offset); -static int parse_h264(th_transport_t *t, th_stream_t *st, size_t len, +static int parse_h264(service_t *t, th_stream_t *st, size_t len, uint32_t next_startcode, int sc_offset); -typedef int (packet_parser_t)(th_transport_t *t, th_stream_t *st, size_t len, +typedef int (packet_parser_t)(service_t *t, th_stream_t *st, size_t len, uint32_t next_startcode, int sc_offset); -typedef void (aparser_t)(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt); +typedef void (aparser_t)(service_t *t, th_stream_t *st, th_pkt_t *pkt); -static void parse_sc(th_transport_t *t, th_stream_t *st, const uint8_t *data, +static void parse_sc(service_t *t, th_stream_t *st, const uint8_t *data, int len, packet_parser_t *vp); -static void parse_aac(th_transport_t *t, th_stream_t *st, const uint8_t *data, +static void parse_aac(service_t *t, th_stream_t *st, const uint8_t *data, int len, int start); -static void parse_subtitles(th_transport_t *t, th_stream_t *st, +static void parse_subtitles(service_t *t, th_stream_t *st, const uint8_t *data, int len, int start); -static int parse_mpa(th_transport_t *t, th_stream_t *st, size_t len, +static int parse_mpa(service_t *t, th_stream_t *st, size_t len, uint32_t next_startcode, int sc_offset); -static int parse_mpa2(th_transport_t *t, th_stream_t *st); +static int parse_mpa2(service_t *t, th_stream_t *st); -static int parse_ac3(th_transport_t *t, th_stream_t *st, size_t len, +static int parse_ac3(service_t *t, th_stream_t *st, size_t len, uint32_t next_startcode, int sc_offset); -static int parse_eac3(th_transport_t *t, th_stream_t *st, size_t len, +static int parse_eac3(service_t *t, th_stream_t *st, size_t len, uint32_t next_startcode, int sc_offset); -static void parser_deliver(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt); +static void parser_deliver(service_t *t, th_stream_t *st, th_pkt_t *pkt); -static int parse_pes_header(th_transport_t *t, th_stream_t *st, +static int parse_pes_header(service_t *t, th_stream_t *st, const uint8_t *buf, size_t len); /** * Parse raw mpeg data */ void -parse_mpeg_ts(th_transport_t *t, th_stream_t *st, const uint8_t *data, +parse_mpeg_ts(service_t *t, th_stream_t *st, const uint8_t *data, int len, int start, int err) { @@ -170,7 +170,7 @@ parse_mpeg_ts(th_transport_t *t, th_stream_t *st, const uint8_t *data, * Note: data does not include startcode and packet length */ void -parse_mpeg_ps(th_transport_t *t, th_stream_t *st, uint8_t *data, int len) +parse_mpeg_ps(service_t *t, th_stream_t *st, uint8_t *data, int len) { int hlen; @@ -206,7 +206,7 @@ parse_mpeg_ps(th_transport_t *t, th_stream_t *st, uint8_t *data, int len) * Parse AAC LATM */ static void -parse_aac(th_transport_t *t, th_stream_t *st, const uint8_t *data, +parse_aac(service_t *t, th_stream_t *st, const uint8_t *data, int len, int start) { int l, muxlen, p; @@ -273,7 +273,7 @@ parse_aac(th_transport_t *t, th_stream_t *st, const uint8_t *data, * derive further information. */ static void -parse_sc(th_transport_t *t, th_stream_t *st, const uint8_t *data, int len, +parse_sc(service_t *t, th_stream_t *st, const uint8_t *data, int len, packet_parser_t *vp) { uint32_t sc = st->st_startcond; @@ -373,7 +373,7 @@ parse_sc(th_transport_t *t, th_stream_t *st, const uint8_t *data, int len, * */ static int -depacketize(th_transport_t *t, th_stream_t *st, size_t len, +depacketize(service_t *t, th_stream_t *st, size_t len, uint32_t next_startcode, int sc_offset) { const uint8_t *buf = st->st_buf.sb_data + sc_offset; @@ -413,13 +413,13 @@ depacketize(th_transport_t *t, th_stream_t *st, size_t len, * */ static void -makeapkt(th_transport_t *t, th_stream_t *st, const void *buf, +makeapkt(service_t *t, th_stream_t *st, const void *buf, int len, int64_t dts, int duration, int channels, int sri) { th_pkt_t *pkt = pkt_alloc(buf, len, dts, dts); - pkt->pkt_commercial = t->tht_tt_commercial_advice; + pkt->pkt_commercial = t->s_tt_commercial_advice; pkt->pkt_duration = duration; pkt->pkt_channels = channels; pkt->pkt_sri = sri; @@ -453,7 +453,7 @@ mpa_valid_frame(const uint8_t *buf) * */ static int -parse_mpa2(th_transport_t *t, th_stream_t *st) +parse_mpa2(service_t *t, th_stream_t *st) { int i, len; const uint8_t *buf; @@ -495,7 +495,7 @@ parse_mpa2(th_transport_t *t, th_stream_t *st) * */ static int -parse_mpa(th_transport_t *t, th_stream_t *st, size_t ilen, +parse_mpa(service_t *t, th_stream_t *st, size_t ilen, uint32_t next_startcode, int sc_offset) { int r; @@ -567,7 +567,7 @@ static const char acmodtab[8] = {2,1,2,3,3,4,4,5}; static int -parse_ac3(th_transport_t *t, th_stream_t *st, size_t ilen, +parse_ac3(service_t *t, th_stream_t *st, size_t ilen, uint32_t next_startcode, int sc_offset) { int i, len; @@ -646,7 +646,7 @@ eac3_valid_frame(const uint8_t *buf) } static int -parse_eac3(th_transport_t *t, th_stream_t *st, size_t ilen, +parse_eac3(service_t *t, th_stream_t *st, size_t ilen, uint32_t next_startcode, int sc_offset) { int i, len; @@ -709,7 +709,7 @@ parse_eac3(th_transport_t *t, th_stream_t *st, size_t ilen, * Extract DTS and PTS and update current values in stream */ static int -parse_pes_header(th_transport_t *t, th_stream_t *st, +parse_pes_header(service_t *t, th_stream_t *st, const uint8_t *buf, size_t len) { int64_t dts, pts, d; @@ -754,7 +754,7 @@ parse_pes_header(th_transport_t *t, th_stream_t *st, err: st->st_curdts = PTS_UNSET; st->st_curpts = PTS_UNSET; - limitedlog(&st->st_loglimit_pes, "TS", transport_component_nicename(st), + limitedlog(&st->st_loglimit_pes, "TS", service_component_nicename(st), "Corrupted PES header"); return -1; } @@ -780,7 +780,7 @@ const unsigned int mpeg2video_framedurations[16] = { * Parse mpeg2video picture start */ static int -parse_mpeg2video_pic_start(th_transport_t *t, th_stream_t *st, int *frametype, +parse_mpeg2video_pic_start(service_t *t, th_stream_t *st, int *frametype, bitstream_t *bs) { int v, pct; @@ -829,7 +829,7 @@ parser_set_stream_vsize(th_stream_t *st, int width, int height) if(need_save) { st->st_width = width; st->st_height = height; - transport_request_save(st->st_transport, 1); + service_request_save(st->st_service, 1); } } @@ -858,7 +858,7 @@ static const uint8_t mpeg2_aspect[16][2]={ * Parse mpeg2video sequence start */ static int -parse_mpeg2video_seq_start(th_transport_t *t, th_stream_t *st, +parse_mpeg2video_seq_start(service_t *t, th_stream_t *st, bitstream_t *bs) { int v, width, height, aspect; @@ -926,7 +926,7 @@ parser_global_data_move(th_stream_t *st, const uint8_t *data, size_t len) * */ static int -parse_mpeg2video(th_transport_t *t, th_stream_t *st, size_t len, +parse_mpeg2video(service_t *t, th_stream_t *st, size_t len, uint32_t next_startcode, int sc_offset) { const uint8_t *buf = st->st_buf.sb_data + sc_offset; @@ -961,7 +961,7 @@ parse_mpeg2video(th_transport_t *t, th_stream_t *st, size_t len, st->st_curpkt = pkt_alloc(NULL, 0, st->st_curpts, st->st_curdts); st->st_curpkt->pkt_frametype = frametype; st->st_curpkt->pkt_duration = st->st_frame_duration; - st->st_curpkt->pkt_commercial = t->tht_tt_commercial_advice; + st->st_curpkt->pkt_commercial = t->s_tt_commercial_advice; break; case 0x000001b3: @@ -1054,7 +1054,7 @@ parse_mpeg2video(th_transport_t *t, th_stream_t *st, size_t len, * H.264 parser */ static int -parse_h264(th_transport_t *t, th_stream_t *st, size_t len, +parse_h264(service_t *t, th_stream_t *st, size_t len, uint32_t next_startcode, int sc_offset) { const uint8_t *buf = st->st_buf.sb_data + sc_offset; @@ -1130,7 +1130,7 @@ parse_h264(th_transport_t *t, th_stream_t *st, size_t len, st->st_curpkt->pkt_frametype = pkttype; st->st_curpkt->pkt_field = isfield; st->st_curpkt->pkt_duration = duration ?: st->st_frame_duration; - st->st_curpkt->pkt_commercial = t->tht_tt_commercial_advice; + st->st_curpkt->pkt_commercial = t->s_tt_commercial_advice; break; default: @@ -1172,7 +1172,7 @@ parse_h264(th_transport_t *t, th_stream_t *st, size_t len, * http://broadcasting.ru/pdf-standard-specifications/subtitling/dvb-sub/en300743.v1.2.1.pdf */ static void -parse_subtitles(th_transport_t *t, th_stream_t *st, const uint8_t *data, +parse_subtitles(service_t *t, th_stream_t *st, const uint8_t *data, int len, int start) { th_pkt_t *pkt; @@ -1226,7 +1226,7 @@ parse_subtitles(th_transport_t *t, th_stream_t *st, const uint8_t *data, // end_of_PES_data_field_marker if(buf[psize - 1] == 0xff) { pkt = pkt_alloc(buf, psize - 1, st->st_curpts, st->st_curdts); - pkt->pkt_commercial = t->tht_tt_commercial_advice; + pkt->pkt_commercial = t->s_tt_commercial_advice; parser_deliver(t, st, pkt); } } @@ -1237,13 +1237,13 @@ parse_subtitles(th_transport_t *t, th_stream_t *st, const uint8_t *data, * */ static void -parser_deliver(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt) +parser_deliver(service_t *t, th_stream_t *st, th_pkt_t *pkt) { if(SCT_ISAUDIO(st->st_type) && pkt->pkt_pts != PTS_UNSET && - (t->tht_current_pts == PTS_UNSET || - pkt->pkt_pts > t->tht_current_pts || - pkt->pkt_pts < t->tht_current_pts - 180000)) - t->tht_current_pts = pkt->pkt_pts; + (t->s_current_pts == PTS_UNSET || + pkt->pkt_pts > t->s_current_pts || + pkt->pkt_pts < t->s_current_pts - 180000)) + t->s_current_pts = pkt->pkt_pts; #if 0 printf("PARSE: %-12s %d %10"PRId64" %10"PRId64" %10d %10d\n", @@ -1263,14 +1263,14 @@ parser_deliver(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt) /** * Input is ok */ - transport_set_streaming_status_flags(t, TSS_PACKETS); + service_set_streaming_status_flags(t, TSS_PACKETS); /* Forward packet */ pkt->pkt_componentindex = st->st_index; streaming_message_t *sm = streaming_msg_create_pkt(pkt); - streaming_pad_deliver(&t->tht_streaming_pad, sm); + streaming_pad_deliver(&t->s_streaming_pad, sm); streaming_msg_free(sm); /* Decrease our own reference to the packet */ diff --git a/src/parsers.h b/src/parsers.h index ff7b6fcc..4fa0b3c9 100644 --- a/src/parsers.h +++ b/src/parsers.h @@ -21,14 +21,17 @@ #include "packet.h" -void parse_mpeg_ts(th_transport_t *t, th_stream_t *st, const uint8_t *data, +void parse_mpeg_ts(struct service *t, struct th_stream *st, + const uint8_t *data, int len, int start, int err); -void parse_mpeg_ps(th_transport_t *t, th_stream_t *st, uint8_t *data, int len); +void parse_mpeg_ps(struct service *t, struct th_stream *st, + uint8_t *data, int len); -void parser_enqueue_packet(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt); +void parser_enqueue_packet(struct service *t, struct th_stream *st, + th_pkt_t *pkt); -void parser_set_stream_vsize(th_stream_t *st, int width, int height); +void parser_set_stream_vsize(struct th_stream *st, int width, int height); extern const unsigned int mpeg2video_framedurations[16]; diff --git a/src/plumbing/globalheaders.c b/src/plumbing/globalheaders.c index 2c5df1f7..703591bd 100644 --- a/src/plumbing/globalheaders.c +++ b/src/plumbing/globalheaders.c @@ -242,7 +242,7 @@ gh_hold(globalheaders_t *gh, streaming_message_t *sm) break; case SMT_EXIT: - case SMT_TRANSPORT_STATUS: + case SMT_SERVICE_STATUS: case SMT_NOSTART: case SMT_MPEGTS: streaming_target_deliver2(gh->gh_output, sm); @@ -269,7 +269,7 @@ gh_pass(globalheaders_t *gh, streaming_message_t *sm) gh_flush(gh); // FALLTHRU case SMT_EXIT: - case SMT_TRANSPORT_STATUS: + case SMT_SERVICE_STATUS: case SMT_NOSTART: case SMT_MPEGTS: streaming_target_deliver2(gh->gh_output, sm); diff --git a/src/plumbing/tsfix.c b/src/plumbing/tsfix.c index c88d52d9..9bd26338 100644 --- a/src/plumbing/tsfix.c +++ b/src/plumbing/tsfix.c @@ -362,7 +362,7 @@ tsfix_input(void *opaque, streaming_message_t *sm) break; case SMT_EXIT: - case SMT_TRANSPORT_STATUS: + case SMT_SERVICE_STATUS: case SMT_NOSTART: case SMT_MPEGTS: break; diff --git a/src/psi.c b/src/psi.c index 84fab16c..acde9838 100644 --- a/src/psi.c +++ b/src/psi.c @@ -24,7 +24,6 @@ #include "tvheadend.h" #include "psi.h" -#include "transports.h" #include "dvb/dvb_support.h" #include "tsdemux.h" #include "parsers.h" @@ -114,14 +113,14 @@ psi_section_reassemble(psi_section_t *ps, const uint8_t *tsb, int crc, * PAT parser, from ISO 13818-1 */ int -psi_parse_pat(th_transport_t *t, uint8_t *ptr, int len, +psi_parse_pat(service_t *t, uint8_t *ptr, int len, pid_section_callback_t *pmt_callback) { uint16_t prognum; uint16_t pid; th_stream_t *st; - lock_assert(&t->tht_stream_mutex); + lock_assert(&t->s_stream_mutex); if(len < 5) return -1; @@ -135,8 +134,8 @@ psi_parse_pat(th_transport_t *t, uint8_t *ptr, int len, pid = (ptr[2] & 0x1f) << 8 | ptr[3]; if(prognum != 0) { - if(transport_stream_find(t, pid) == NULL) { - st = transport_stream_create(t, pid, SCT_PMT); + if(service_stream_find(t, pid) == NULL) { + st = service_stream_create(t, pid, SCT_PMT); st->st_section_docrc = 1; st->st_got_section = pmt_callback; } @@ -178,7 +177,7 @@ psi_append_crc32(uint8_t *buf, int offset, int maxlen) */ int -psi_build_pat(th_transport_t *t, uint8_t *buf, int maxlen, int pmtpid) +psi_build_pat(service_t *t, uint8_t *buf, int maxlen, int pmtpid) { if(maxlen < 12) return -1; @@ -225,14 +224,14 @@ psi_build_pat(th_transport_t *t, uint8_t *buf, int maxlen, int pmtpid) * Add a CA descriptor */ static int -psi_desc_add_ca(th_transport_t *t, uint16_t caid, uint32_t provid, uint16_t pid) +psi_desc_add_ca(service_t *t, uint16_t caid, uint32_t provid, uint16_t pid) { th_stream_t *st; caid_t *c; int r = 0; - if((st = transport_stream_find(t, pid)) == NULL) { - st = transport_stream_create(t, pid, SCT_CA); + if((st = service_stream_find(t, pid)) == NULL) { + st = service_stream_create(t, pid, SCT_CA); r |= PMT_UPDATE_NEW_CA_STREAM; } @@ -267,7 +266,7 @@ psi_desc_add_ca(th_transport_t *t, uint16_t caid, uint32_t provid, uint16_t pid) * Parser for CA descriptors */ static int -psi_desc_ca(th_transport_t *t, const uint8_t *buffer, int size) +psi_desc_ca(service_t *t, const uint8_t *buffer, int size) { int r = 0; int i; @@ -321,7 +320,7 @@ psi_desc_ca(th_transport_t *t, const uint8_t *buffer, int size) * Parser for teletext descriptor */ static int -psi_desc_teletext(th_transport_t *t, const uint8_t *ptr, int size, +psi_desc_teletext(service_t *t, const uint8_t *ptr, int size, int parent_pid, int *position) { int r = 0; @@ -338,9 +337,9 @@ psi_desc_teletext(th_transport_t *t, const uint8_t *ptr, int size, // higher than normal MPEG TS (0x2000 ++) int pid = PID_TELETEXT_BASE + page; - if((st = transport_stream_find(t, pid)) == NULL) { + if((st = service_stream_find(t, pid)) == NULL) { r |= PMT_UPDATE_NEW_STREAM; - st = transport_stream_create(t, pid, SCT_TEXTSUB); + st = service_stream_create(t, pid, SCT_TEXTSUB); } st->st_delete_me = 0; @@ -384,23 +383,23 @@ pidcmp(const void *A, const void *B) * */ static void -sort_pids(th_transport_t *t) +sort_pids(service_t *t) { th_stream_t *st, **v; int num = 0, i = 0; - TAILQ_FOREACH(st, &t->tht_components, st_link) + TAILQ_FOREACH(st, &t->s_components, st_link) num++; v = alloca(num * sizeof(th_stream_t *)); - TAILQ_FOREACH(st, &t->tht_components, st_link) + TAILQ_FOREACH(st, &t->s_components, st_link) v[i++] = st; qsort(v, num, sizeof(th_stream_t *), pidcmp); - TAILQ_INIT(&t->tht_components); + TAILQ_INIT(&t->s_components); for(i = 0; i < num; i++) - TAILQ_INSERT_TAIL(&t->tht_components, v[i], st_link); + TAILQ_INSERT_TAIL(&t->s_components, v[i], st_link); } @@ -408,7 +407,7 @@ sort_pids(th_transport_t *t) * PMT parser, from ISO 13818-1 and ETSI EN 300 468 */ int -psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, +psi_parse_pmt(service_t *t, const uint8_t *ptr, int len, int chksvcid, int delete) { uint16_t pcr_pid, pid; @@ -432,9 +431,9 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, if(len < 9) return -1; - lock_assert(&t->tht_stream_mutex); + lock_assert(&t->s_stream_mutex); - had_components = !!TAILQ_FIRST(&t->tht_components); + had_components = !!TAILQ_FIRST(&t->s_components); sid = ptr[0] << 8 | ptr[1]; version = ptr[2] >> 1 & 0x1f; @@ -447,11 +446,11 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, pcr_pid = (ptr[5] & 0x1f) << 8 | ptr[6]; dllen = (ptr[7] & 0xf) << 8 | ptr[8]; - if(chksvcid && sid != t->tht_dvb_service_id) + if(chksvcid && sid != t->s_dvb_service_id) return -1; - if(t->tht_pcr_pid != pcr_pid) { - t->tht_pcr_pid = pcr_pid; + if(t->s_pcr_pid != pcr_pid) { + t->s_pcr_pid = pcr_pid; update |= PMT_UPDATE_PCR; } @@ -460,7 +459,7 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, /* Mark all streams for deletion */ if(delete) { - TAILQ_FOREACH(st, &t->tht_components, st_link) { + TAILQ_FOREACH(st, &t->s_components, st_link) { st->st_delete_me = 1; LIST_FOREACH(c, &st->st_caids, link) @@ -593,16 +592,16 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, if(hts_stream_type == SCT_UNKNOWN && estype == 0x06 && - pid == 3401 && t->tht_dvb_service_id == 10510) { + pid == 3401 && t->s_dvb_service_id == 10510) { // Workaround for ITV HD hts_stream_type = SCT_H264; } if(hts_stream_type != SCT_UNKNOWN) { - if((st = transport_stream_find(t, pid)) == NULL) { + if((st = service_stream_find(t, pid)) == NULL) { update |= PMT_UPDATE_NEW_STREAM; - st = transport_stream_create(t, pid, hts_stream_type); + st = service_stream_create(t, pid, hts_stream_type); } st->st_delete_me = 0; @@ -631,7 +630,7 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, } /* Scan again to see if any streams should be deleted */ - for(st = TAILQ_FIRST(&t->tht_components); st != NULL; st = next) { + for(st = TAILQ_FIRST(&t->s_components); st != NULL; st = next) { next = TAILQ_NEXT(st, st_link); for(c = LIST_FIRST(&st->st_caids); c != NULL; c = cn) { @@ -645,7 +644,7 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, if(st->st_delete_me) { - transport_stream_destroy(t, st); + service_stream_destroy(t, st); update |= PMT_UPDATE_STREAM_DELETED; } } @@ -654,9 +653,9 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, sort_pids(t); if(update) { - tvhlog(LOG_DEBUG, "PSI", "Transport \"%s\" PMT (version %d) updated" + tvhlog(LOG_DEBUG, "PSI", "Service \"%s\" PMT (version %d) updated" "%s%s%s%s%s%s%s%s%s%s%s%s%s", - transport_nicename(t), version, + service_nicename(t), version, update&PMT_UPDATE_PCR ? ", PCR PID changed":"", update&PMT_UPDATE_NEW_STREAM ? ", New elementary stream":"", update&PMT_UPDATE_LANGUAGE ? ", Language changed":"", @@ -671,15 +670,15 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, update&PMT_UPDATE_CAID_DELETED ? ", CAID deleted":"", update&PMT_REORDERED ? ", PIDs reordered":""); - transport_request_save(t, 0); + service_request_save(t, 0); // Only restart if something that our clients worry about did change if(update & !(PMT_UPDATE_NEW_CA_STREAM | PMT_UPDATE_NEW_CAID | PMT_UPDATE_CA_PROVIDER_CHANGE | PMT_UPDATE_CAID_DELETED)) { - if(t->tht_status == TRANSPORT_RUNNING) - transport_restart(t, had_components); + if(t->s_status == SERVICE_RUNNING) + service_restart(t, had_components); } } return 0; @@ -865,21 +864,21 @@ streaming_component_type2txt(streaming_component_type_t s) /** - * Store transport settings into message + * Store service settings into message */ void -psi_save_transport_settings(htsmsg_t *m, th_transport_t *t) +psi_save_service_settings(htsmsg_t *m, service_t *t) { th_stream_t *st; htsmsg_t *sub; - htsmsg_add_u32(m, "pcr", t->tht_pcr_pid); + htsmsg_add_u32(m, "pcr", t->s_pcr_pid); - htsmsg_add_u32(m, "disabled", !t->tht_enabled); + htsmsg_add_u32(m, "disabled", !t->s_enabled); - lock_assert(&t->tht_stream_mutex); + lock_assert(&t->s_stream_mutex); - TAILQ_FOREACH(st, &t->tht_components, st_link) { + TAILQ_FOREACH(st, &t->s_components, st_link) { sub = htsmsg_create_map(); htsmsg_add_u32(sub, "pid", st->st_pid); @@ -995,10 +994,10 @@ load_caid(htsmsg_t *m, th_stream_t *st) /** - * Load transport info from htsmsg + * Load service info from htsmsg */ void -psi_load_transport_settings(htsmsg_t *m, th_transport_t *t) +psi_load_service_settings(htsmsg_t *m, service_t *t) { htsmsg_t *c; htsmsg_field_t *f; @@ -1008,12 +1007,12 @@ psi_load_transport_settings(htsmsg_t *m, th_transport_t *t) const char *v; if(!htsmsg_get_u32(m, "pcr", &u32)) - t->tht_pcr_pid = u32; + t->s_pcr_pid = u32; if(!htsmsg_get_u32(m, "disabled", &u32)) - t->tht_enabled = !u32; + t->s_enabled = !u32; else - t->tht_enabled = 1; + t->s_enabled = 1; HTSMSG_FOREACH(f, m) { if(strcmp(f->hmf_name, "stream")) @@ -1032,7 +1031,7 @@ psi_load_transport_settings(htsmsg_t *m, th_transport_t *t) if(htsmsg_get_u32(c, "pid", &pid)) continue; - st = transport_stream_create(t, pid, type); + st = service_stream_create(t, pid, type); if((v = htsmsg_get_str(c, "language")) != NULL) snprintf(st->st_lang, 4, "%s", v); diff --git a/src/psi.h b/src/psi.h index 0e45a05b..49910e66 100644 --- a/src/psi.h +++ b/src/psi.h @@ -21,6 +21,7 @@ #include "htsmsg.h" #include "streaming.h" +#include "service.h" #define PSI_SECTION_SIZE 5000 @@ -36,19 +37,19 @@ typedef struct psi_section { void psi_section_reassemble(psi_section_t *ps, const uint8_t *tsb, int crc, section_handler_t *cb, void *opaque); -int psi_parse_pat(th_transport_t *t, uint8_t *ptr, int len, +int psi_parse_pat(struct service *t, uint8_t *ptr, int len, pid_section_callback_t *pmt_callback); -int psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, +int psi_parse_pmt(struct service *t, const uint8_t *ptr, int len, int chksvcid, int delete); -int psi_build_pat(th_transport_t *t, uint8_t *buf, int maxlen, int pmtpid); +int psi_build_pat(struct service *t, uint8_t *buf, int maxlen, int pmtpid); int psi_build_pmt(streaming_start_t *ss, uint8_t *buf, int maxlen, int pcrpid); const char *psi_caid2name(uint16_t caid); -void psi_load_transport_settings(htsmsg_t *m, th_transport_t *t); -void psi_save_transport_settings(htsmsg_t *m, th_transport_t *t); +void psi_load_service_settings(htsmsg_t *m, struct service *t); +void psi_save_service_settings(htsmsg_t *m, struct service *t); #endif /* PSI_H_ */ diff --git a/src/rawtsinput.c b/src/rawtsinput.c index 0d86ce15..2c45e844 100644 --- a/src/rawtsinput.c +++ b/src/rawtsinput.c @@ -29,10 +29,10 @@ #include #include "tvheadend.h" -#include "transports.h" #include "rawtsinput.h" #include "psi.h" #include "tsdemux.h" +#include "channels.h" typedef struct rawts { int rt_fd; @@ -40,7 +40,7 @@ typedef struct rawts { char *rt_identifier; psi_section_t rt_pat; - struct th_transport_list rt_transports; + struct service_list rt_services; int rt_pcr_pid; @@ -51,7 +51,7 @@ typedef struct rawts { * */ static int -rawts_transport_start(th_transport_t *t, unsigned int weight, int force_start) +rawts_service_start(service_t *t, unsigned int weight, int force_start) { return 0; // Always ok } @@ -60,7 +60,7 @@ rawts_transport_start(th_transport_t *t, unsigned int weight, int force_start) * */ static void -rawts_transport_stop(th_transport_t *t) +rawts_service_stop(service_t *t) { } @@ -68,14 +68,14 @@ rawts_transport_stop(th_transport_t *t) * */ static void -rawts_transport_save(th_transport_t *t) +rawts_service_save(service_t *t) { htsmsg_t *m = htsmsg_create_map(); - printf("SAVE %s\n", transport_nicename(t)); + printf("SAVE %s\n", service_nicename(t)); - pthread_mutex_lock(&t->tht_stream_mutex); - psi_save_transport_settings(m, t); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + psi_save_service_settings(m, t); + pthread_mutex_unlock(&t->s_stream_mutex); htsmsg_print(m); htsmsg_destroy(m); @@ -87,7 +87,7 @@ rawts_transport_save(th_transport_t *t) * */ static int -rawts_transport_quality(th_transport_t *t) +rawts_service_quality(service_t *t) { return 100; } @@ -97,7 +97,7 @@ rawts_transport_quality(th_transport_t *t) * Generate a descriptive name for the source */ static void -rawts_transport_setsourceinfo(th_transport_t *t, struct source_info *si) +rawts_service_setsourceinfo(service_t *t, struct source_info *si) { memset(si, 0, sizeof(struct source_info)); } @@ -107,46 +107,46 @@ rawts_transport_setsourceinfo(th_transport_t *t, struct source_info *si) /** * */ -static th_transport_t * -rawts_transport_add(rawts_t *rt, uint16_t sid, int pmt_pid) +static service_t * +rawts_service_add(rawts_t *rt, uint16_t sid, int pmt_pid) { - th_transport_t *t; - channel_t *ch; + service_t *t; + struct channel *ch; char tmp[200]; - LIST_FOREACH(t, &rt->rt_transports, tht_group_link) { - if(t->tht_dvb_service_id == sid) + LIST_FOREACH(t, &rt->rt_services, s_group_link) { + if(t->s_dvb_service_id == sid) return t; } snprintf(tmp, sizeof(tmp), "%s_%04x", rt->rt_identifier, sid); - t = transport_create(tmp, TRANSPORT_DVB, THT_MPEG_TS); - t->tht_flags |= THT_DEBUG; + t = service_create(tmp, SERVICE_TYPE_DVB, S_MPEG_TS); + t->s_flags |= S_DEBUG; - t->tht_dvb_service_id = sid; - t->tht_pmt_pid = pmt_pid; + t->s_dvb_service_id = sid; + t->s_pmt_pid = pmt_pid; - t->tht_start_feed = rawts_transport_start; - t->tht_stop_feed = rawts_transport_stop; - t->tht_config_save = rawts_transport_save; - t->tht_setsourceinfo = rawts_transport_setsourceinfo; - t->tht_quality_index = rawts_transport_quality; + t->s_start_feed = rawts_service_start; + t->s_stop_feed = rawts_service_stop; + t->s_config_save = rawts_service_save; + t->s_setsourceinfo = rawts_service_setsourceinfo; + t->s_quality_index = rawts_service_quality; - t->tht_svcname = strdup(tmp); + t->s_svcname = strdup(tmp); - pthread_mutex_lock(&t->tht_stream_mutex); - transport_make_nicename(t); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + service_make_nicename(t); + pthread_mutex_unlock(&t->s_stream_mutex); tvhlog(LOG_NOTICE, "rawts", "Added service %d (pmt: %d)", sid, pmt_pid); - LIST_INSERT_HEAD(&rt->rt_transports, t, tht_group_link); + LIST_INSERT_HEAD(&rt->rt_services, t, s_group_link); ch = channel_find_by_name(tmp, 1, 0); - transport_map_channel(t, ch, 0); + service_map_channel(t, ch, 0); return t; } @@ -156,7 +156,7 @@ rawts_transport_add(rawts_t *rt, uint16_t sid, int pmt_pid) */ static void -got_pmt(struct th_transport *t, th_stream_t *st, +got_pmt(struct service *t, th_stream_t *st, const uint8_t *table, int table_len) { if(table[0] != 2) @@ -176,7 +176,7 @@ static void got_pat(const uint8_t *ptr, size_t len, void *opaque) { rawts_t *rt = opaque; - th_transport_t *t; + service_t *t; th_stream_t *st; uint16_t prognum; uint16_t pid; @@ -195,17 +195,17 @@ got_pat(const uint8_t *ptr, size_t len, void *opaque) pid = (ptr[2] & 0x1f) << 8 | ptr[3]; if(prognum != 0) { - t = rawts_transport_add(rt, prognum, pid); + t = rawts_service_add(rt, prognum, pid); if(t != NULL) { - pthread_mutex_lock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); - if(transport_stream_find(t, pid) == NULL) { - st = transport_stream_create(t, pid, SCT_PMT); + if(service_stream_find(t, pid) == NULL) { + st = service_stream_create(t, pid, SCT_PMT); st->st_section_docrc = 1; st->st_got_section = got_pmt; } - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_unlock(&t->s_stream_mutex); } } ptr += 4; @@ -231,7 +231,7 @@ static void process_ts_packet(rawts_t *rt, uint8_t *tsb) { uint16_t pid; - th_transport_t *t; + service_t *t; int64_t pcr, d; int didsleep = 0; @@ -242,7 +242,7 @@ process_ts_packet(rawts_t *rt, uint8_t *tsb) return; } - LIST_FOREACH(t, &rt->rt_transports, tht_group_link) { + LIST_FOREACH(t, &rt->rt_services, s_group_link) { pcr = PTS_UNSET; ts_recv_packet1(t, tsb, &pcr); @@ -253,24 +253,24 @@ process_ts_packet(rawts_t *rt, uint8_t *tsb) rt->rt_pcr_pid = pid; if(rt->rt_pcr_pid == pid) { - if(t->tht_pcr_last != PTS_UNSET && didsleep == 0) { + if(t->s_pcr_last != PTS_UNSET && didsleep == 0) { struct timespec slp; - int64_t delta = pcr - t->tht_pcr_last; + int64_t delta = pcr - t->s_pcr_last; if(delta > 90000) delta = 90000; delta *= 11; - d = delta + t->tht_pcr_last_realtime; + d = delta + t->s_pcr_last_realtime; slp.tv_sec = d / 1000000; slp.tv_nsec = (d % 1000000) * 1000; clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &slp, NULL); didsleep = 1; } - t->tht_pcr_last = pcr; - t->tht_pcr_last_realtime = getmonoclock(); + t->s_pcr_last = pcr; + t->s_pcr_last_realtime = getmonoclock(); } } } diff --git a/src/service.c b/src/service.c new file mode 100644 index 00000000..b213b3b1 --- /dev/null +++ b/src/service.c @@ -0,0 +1,1069 @@ +/* + * Services + * Copyright (C) 2010 Andreas Öman + * + * 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 + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "tvheadend.h" +#include "service.h" +#include "subscriptions.h" +#include "tsdemux.h" +#include "streaming.h" +#include "v4l.h" +#include "psi.h" +#include "packet.h" +#include "channels.h" +#include "cwc.h" +#include "capmt.h" +#include "notify.h" +#include "serviceprobe.h" +#include "atomic.h" +#include "dvb/dvb.h" +#include "htsp.h" + +#define SERVICE_HASH_WIDTH 101 + +static struct service_list servicehash[SERVICE_HASH_WIDTH]; + +static void service_data_timeout(void *aux); + +/** + * + */ +static void +stream_init(th_stream_t *st) +{ + st->st_cc_valid = 0; + + st->st_startcond = 0xffffffff; + st->st_curdts = PTS_UNSET; + st->st_curpts = PTS_UNSET; + st->st_prevdts = PTS_UNSET; + + st->st_pcr_real_last = PTS_UNSET; + st->st_pcr_last = PTS_UNSET; + st->st_pcr_drift = 0; + st->st_pcr_recovery_fails = 0; + + st->st_blank = 0; +} + + +/** + * + */ +static void +stream_clean(th_stream_t *st) +{ + if(st->st_demuxer_fd != -1) { + // XXX: Should be in DVB-code perhaps + close(st->st_demuxer_fd); + st->st_demuxer_fd = -1; + } + + free(st->st_priv); + st->st_priv = NULL; + + /* Clear reassembly buffers */ + + st->st_startcode = 0; + + sbuf_free(&st->st_buf); + sbuf_free(&st->st_buf_ps); + sbuf_free(&st->st_buf_a); + + if(st->st_curpkt != NULL) { + pkt_ref_dec(st->st_curpkt); + st->st_curpkt = NULL; + } + + free(st->st_global_data); + st->st_global_data = NULL; + st->st_global_data_len = 0; +} + + +/** + * + */ +void +service_stream_destroy(service_t *t, th_stream_t *st) +{ + if(t->s_status == SERVICE_RUNNING) + stream_clean(st); + TAILQ_REMOVE(&t->s_components, st, st_link); + free(st->st_nicename); + free(st); +} + +/** + * Service lock must be held + */ +static void +service_stop(service_t *t) +{ + th_descrambler_t *td; + th_stream_t *st; + + gtimer_disarm(&t->s_receive_timer); + + t->s_stop_feed(t); + + pthread_mutex_lock(&t->s_stream_mutex); + + while((td = LIST_FIRST(&t->s_descramblers)) != NULL) + td->td_stop(td); + + t->s_tt_commercial_advice = COMMERCIAL_UNKNOWN; + + assert(LIST_FIRST(&t->s_streaming_pad.sp_targets) == NULL); + assert(LIST_FIRST(&t->s_subscriptions) == NULL); + + /** + * Clean up each stream + */ + TAILQ_FOREACH(st, &t->s_components, st_link) + stream_clean(st); + + t->s_status = SERVICE_IDLE; + + pthread_mutex_unlock(&t->s_stream_mutex); +} + + +/** + * Remove the given subscriber from the service + * + * if s == NULL all subscribers will be removed + * + * Global lock must be held + */ +void +service_remove_subscriber(service_t *t, th_subscription_t *s, + int reason) +{ + lock_assert(&global_lock); + + if(s == NULL) { + while((s = LIST_FIRST(&t->s_subscriptions)) != NULL) { + subscription_unlink_service(s, reason); + } + } else { + subscription_unlink_service(s, reason); + } + + if(LIST_FIRST(&t->s_subscriptions) == NULL) + service_stop(t); +} + + +/** + * + */ +int +service_start(service_t *t, unsigned int weight, int force_start) +{ + th_stream_t *st; + int r, timeout = 2; + + lock_assert(&global_lock); + + assert(t->s_status != SERVICE_RUNNING); + t->s_streaming_status = 0; + t->s_pcr_drift = 0; + + if((r = t->s_start_feed(t, weight, force_start))) + return r; + + cwc_service_start(t); + capmt_service_start(t); + + pthread_mutex_lock(&t->s_stream_mutex); + + t->s_status = SERVICE_RUNNING; + t->s_current_pts = PTS_UNSET; + + /** + * Initialize stream + */ + TAILQ_FOREACH(st, &t->s_components, st_link) + stream_init(st); + + pthread_mutex_unlock(&t->s_stream_mutex); + + if(t->s_grace_period != NULL) + timeout = t->s_grace_period(t); + + gtimer_arm(&t->s_receive_timer, service_data_timeout, t, timeout); + return 0; +} + +/** + * + */ +static int +dvb_extra_prio(th_dvb_adapter_t *tda) +{ + return tda->tda_hostconnection * 10; +} + +/** + * Return prio for the given service + */ +static int +service_get_prio(service_t *t) +{ + switch(t->s_type) { + case SERVICE_TYPE_DVB: + return (t->s_scrambled ? 300 : 100) + + dvb_extra_prio(t->s_dvb_mux_instance->tdmi_adapter); + + case SERVICE_TYPE_IPTV: + return 200; + + case SERVICE_TYPE_V4L: + return 400; + + default: + return 500; + } +} + +/** + * Return quality index for given service + * + * We invert the result (providers say that negative numbers are worse) + * + * But for sorting, we want low numbers first + * + * Also, we bias and trim with an offset of two to avoid counting any + * transient errors. + */ + +static int +service_get_quality(service_t *t) +{ + return t->s_quality_index ? -MIN(t->s_quality_index(t) + 2, 0) : 0; +} + + + + +/** + * a - b -> lowest number first + */ +static int +servicecmp(const void *A, const void *B) +{ + service_t *a = *(service_t **)A; + service_t *b = *(service_t **)B; + + int q = service_get_quality(a) - service_get_quality(b); + + if(q != 0) + return q; /* Quality precedes priority */ + + return service_get_prio(a) - service_get_prio(b); +} + + +/** + * + */ +service_t * +service_find(channel_t *ch, unsigned int weight, const char *loginfo, + int *errorp, service_t *skip) +{ + service_t *t, **vec; + int cnt = 0, i, r, off; + int err = 0; + + lock_assert(&global_lock); + + /* First, sort all services in order */ + + LIST_FOREACH(t, &ch->ch_services, s_ch_link) + cnt++; + + vec = alloca(cnt * sizeof(service_t *)); + cnt = 0; + LIST_FOREACH(t, &ch->ch_services, s_ch_link) { + + if(!t->s_enabled) { + if(loginfo != NULL) { + tvhlog(LOG_NOTICE, "Service", "%s: Skipping \"%s\" -- not enabled", + loginfo, service_nicename(t)); + err = SM_CODE_SVC_NOT_ENABLED; + } + continue; + } + + if(t->s_quality_index(t) < 10) { + if(loginfo != NULL) { + tvhlog(LOG_NOTICE, "Service", + "%s: Skipping \"%s\" -- Quality below 10%", + loginfo, service_nicename(t)); + err = SM_CODE_BAD_SIGNAL; + } + continue; + } + vec[cnt++] = t; + } + + /* Sort services, lower priority should come come earlier in the vector + (i.e. it will be more favoured when selecting a service */ + + qsort(vec, cnt, sizeof(service_t *), servicecmp); + + // Skip up to the service that the caller didn't want + // If the sorting above is not stable that might mess up things + // temporary. But it should resolve itself eventually + if(skip != NULL) { + for(i = 0; i < cnt; i++) { + if(skip == t) + break; + } + off = i + 1; + } else { + off = 0; + } + + /* First, try all services without stealing */ + for(i = off; i < cnt; i++) { + t = vec[i]; + if(t->s_status == SERVICE_RUNNING) + return t; + if((r = service_start(t, 0, 0)) == 0) + return t; + if(loginfo != NULL) + tvhlog(LOG_DEBUG, "Service", "%s: Unable to use \"%s\" -- %s", + loginfo, service_nicename(t), streaming_code2txt(r)); + } + + /* Ok, nothing, try again, but supply our weight and thus, try to steal + transponders */ + + for(i = off; i < cnt; i++) { + t = vec[i]; + if((r = service_start(t, weight, 0)) == 0) + return t; + *errorp = r; + } + if(err) + *errorp = err; + else if(*errorp == 0) + *errorp = SM_CODE_NO_SERVICE; + return NULL; +} + + +/** + * + */ +unsigned int +service_compute_weight(struct service_list *head) +{ + service_t *t; + th_subscription_t *s; + int w = 0; + + lock_assert(&global_lock); + + LIST_FOREACH(t, head, s_active_link) { + LIST_FOREACH(s, &t->s_subscriptions, ths_service_link) { + if(s->ths_weight > w) + w = s->ths_weight; + } + } + return w; +} + + +/** + * + */ +void +service_unref(service_t *t) +{ + if((atomic_add(&t->s_refcount, -1)) == 1) + free(t); +} + + +/** + * + */ +void +service_ref(service_t *t) +{ + atomic_add(&t->s_refcount, 1); +} + + + +/** + * Destroy a service + */ +void +service_destroy(service_t *t) +{ + th_stream_t *st; + th_subscription_t *s; + channel_t *ch = t->s_ch; + + if(t->s_dtor != NULL) + t->s_dtor(t); + + lock_assert(&global_lock); + + serviceprobe_delete(t); + + while((s = LIST_FIRST(&t->s_subscriptions)) != NULL) { + subscription_unlink_service(s, SM_CODE_SOURCE_DELETED); + } + + if(t->s_ch != NULL) { + t->s_ch = NULL; + LIST_REMOVE(t, s_ch_link); + } + + LIST_REMOVE(t, s_group_link); + LIST_REMOVE(t, s_hash_link); + + if(t->s_status != SERVICE_IDLE) + service_stop(t); + + t->s_status = SERVICE_ZOMBIE; + + free(t->s_identifier); + free(t->s_svcname); + free(t->s_provider); + + while((st = TAILQ_FIRST(&t->s_components)) != NULL) { + TAILQ_REMOVE(&t->s_components, st, st_link); + free(st->st_nicename); + free(st); + } + + free(t->s_pat_section); + free(t->s_pmt_section); + + service_unref(t); + + if(ch != NULL) { + if(LIST_FIRST(&ch->ch_services) == NULL) + channel_delete(ch); + } +} + + +/** + * Create and initialize a new service struct + */ +service_t * +service_create(const char *identifier, int type, int source_type) +{ + unsigned int hash = tvh_strhash(identifier, SERVICE_HASH_WIDTH); + service_t *t = calloc(1, sizeof(service_t)); + + lock_assert(&global_lock); + + pthread_mutex_init(&t->s_stream_mutex, NULL); + pthread_cond_init(&t->s_tss_cond, NULL); + t->s_identifier = strdup(identifier); + t->s_type = type; + t->s_source_type = source_type; + t->s_refcount = 1; + t->s_enabled = 1; + t->s_pcr_last = PTS_UNSET; + TAILQ_INIT(&t->s_components); + + streaming_pad_init(&t->s_streaming_pad); + + LIST_INSERT_HEAD(&servicehash[hash], t, s_hash_link); + return t; +} + +/** + * Find a service based on the given identifier + */ +service_t * +service_find_by_identifier(const char *identifier) +{ + service_t *t; + unsigned int hash = tvh_strhash(identifier, SERVICE_HASH_WIDTH); + + lock_assert(&global_lock); + + LIST_FOREACH(t, &servicehash[hash], s_hash_link) + if(!strcmp(t->s_identifier, identifier)) + break; + return t; +} + + +/** + * + */ +static void +service_stream_make_nicename(service_t *t, th_stream_t *st) +{ + char buf[200]; + if(st->st_pid != -1) + snprintf(buf, sizeof(buf), "%s: %s @ #%d", + service_nicename(t), + streaming_component_type2txt(st->st_type), st->st_pid); + else + snprintf(buf, sizeof(buf), "%s: %s", + service_nicename(t), + streaming_component_type2txt(st->st_type)); + + free(st->st_nicename); + st->st_nicename = strdup(buf); +} + + +/** + * + */ +void +service_make_nicename(service_t *t) +{ + char buf[200]; + source_info_t si; + th_stream_t *st; + + lock_assert(&t->s_stream_mutex); + + t->s_setsourceinfo(t, &si); + + snprintf(buf, sizeof(buf), + "%s%s%s%s%s", + si.si_adapter ?: "", si.si_adapter && si.si_mux ? "/" : "", + si.si_mux ?: "", si.si_mux && si.si_service ? "/" : "", + si.si_service ?: ""); + + service_source_info_free(&si); + + free(t->s_nicename); + t->s_nicename = strdup(buf); + + TAILQ_FOREACH(st, &t->s_components, st_link) + service_stream_make_nicename(t, st); +} + + +/** + * Add a new stream to a service + */ +th_stream_t * +service_stream_create(service_t *t, int pid, + streaming_component_type_t type) +{ + th_stream_t *st; + int i = 0; + int idx = 0; + lock_assert(&t->s_stream_mutex); + + TAILQ_FOREACH(st, &t->s_components, st_link) { + if(st->st_index > idx) + idx = st->st_index; + i++; + if(pid != -1 && st->st_pid == pid) + return st; + } + + st = calloc(1, sizeof(th_stream_t)); + st->st_index = idx + 1; + st->st_type = type; + + TAILQ_INSERT_TAIL(&t->s_components, st, st_link); + st->st_service = t; + + st->st_pid = pid; + st->st_demuxer_fd = -1; + + avgstat_init(&st->st_rate, 10); + avgstat_init(&st->st_cc_errors, 10); + + service_stream_make_nicename(t, st); + + if(t->s_flags & S_DEBUG) + tvhlog(LOG_DEBUG, "service", "Add stream %s", st->st_nicename); + + if(t->s_status == SERVICE_RUNNING) + stream_init(st); + + return st; +} + + + +/** + * Add a new stream to a service + */ +th_stream_t * +service_stream_find(service_t *t, int pid) +{ + th_stream_t *st; + + lock_assert(&t->s_stream_mutex); + + TAILQ_FOREACH(st, &t->s_components, st_link) { + if(st->st_pid == pid) + return st; + } + return NULL; +} + + + +/** + * + */ +void +service_map_channel(service_t *t, channel_t *ch, int save) +{ + lock_assert(&global_lock); + + if(t->s_ch != NULL) { + LIST_REMOVE(t, s_ch_link); + htsp_channel_update(t->s_ch); + t->s_ch = NULL; + } + + + if(ch != NULL) { + + avgstat_init(&t->s_cc_errors, 3600); + avgstat_init(&t->s_rate, 10); + + t->s_ch = ch; + LIST_INSERT_HEAD(&ch->ch_services, t, s_ch_link); + htsp_channel_update(t->s_ch); + } + + if(save) + t->s_config_save(t); +} + +/** + * + */ +static void +service_data_timeout(void *aux) +{ + service_t *t = aux; + + pthread_mutex_lock(&t->s_stream_mutex); + + if(!(t->s_streaming_status & TSS_PACKETS)) + service_set_streaming_status_flags(t, TSS_GRACEPERIOD); + + pthread_mutex_unlock(&t->s_stream_mutex); +} + +/** + * + */ +static struct strtab stypetab[] = { + { "SDTV", ST_SDTV }, + { "Radio", ST_RADIO }, + { "HDTV", ST_HDTV }, + { "SDTV-AC", ST_AC_SDTV }, + { "HDTV-AC", ST_AC_HDTV }, +}; + +const char * +service_servicetype_txt(service_t *t) +{ + return val2str(t->s_servicetype, stypetab) ?: "Other"; +} + +/** + * + */ +int +service_is_tv(service_t *t) +{ + return + t->s_servicetype == ST_SDTV || + t->s_servicetype == ST_HDTV || + t->s_servicetype == ST_AC_SDTV || + t->s_servicetype == ST_AC_HDTV; +} + + +/** + * + */ +void +service_set_streaming_status_flags(service_t *t, int set) +{ + int n; + streaming_message_t *sm; + lock_assert(&t->s_stream_mutex); + + n = t->s_streaming_status; + + n |= set; + + if(n == t->s_streaming_status) + return; // Already set + + t->s_streaming_status = n; + + tvhlog(LOG_DEBUG, "Service", "%s: Status changed to %s%s%s%s%s%s%s", + service_nicename(t), + n & TSS_INPUT_HARDWARE ? "[Hardware input] " : "", + n & TSS_INPUT_SERVICE ? "[Input on service] " : "", + n & TSS_MUX_PACKETS ? "[Demuxed packets] " : "", + n & TSS_PACKETS ? "[Reassembled packets] " : "", + n & TSS_NO_DESCRAMBLER ? "[No available descrambler] " : "", + n & TSS_NO_ACCESS ? "[No access] " : "", + n & TSS_GRACEPERIOD ? "[Graceperiod expired] " : ""); + + sm = streaming_msg_create_code(SMT_SERVICE_STATUS, + t->s_streaming_status); + streaming_pad_deliver(&t->s_streaming_pad, sm); + streaming_msg_free(sm); + + pthread_cond_broadcast(&t->s_tss_cond); +} + + +/** + * Restart output on a service. + * Happens if the stream composition changes. + * (i.e. an AC3 stream disappears, etc) + */ +void +service_restart(service_t *t, int had_components) +{ + streaming_message_t *sm; + lock_assert(&t->s_stream_mutex); + + if(had_components) { + sm = streaming_msg_create_code(SMT_STOP, SM_CODE_SOURCE_RECONFIGURED); + streaming_pad_deliver(&t->s_streaming_pad, sm); + streaming_msg_free(sm); + } + + if(t->s_refresh_feed != NULL) + t->s_refresh_feed(t); + + if(TAILQ_FIRST(&t->s_components) != NULL) { + + sm = streaming_msg_create_data(SMT_START, + service_build_stream_start(t)); + streaming_pad_deliver(&t->s_streaming_pad, sm); + streaming_msg_free(sm); + } +} + + +/** + * Generate a message containing info about all components + */ +streaming_start_t * +service_build_stream_start(service_t *t) +{ + th_stream_t *st; + int n = 0; + streaming_start_t *ss; + + lock_assert(&t->s_stream_mutex); + + TAILQ_FOREACH(st, &t->s_components, st_link) + n++; + + ss = calloc(1, sizeof(streaming_start_t) + + sizeof(streaming_start_component_t) * n); + + ss->ss_num_components = n; + + n = 0; + TAILQ_FOREACH(st, &t->s_components, st_link) { + streaming_start_component_t *ssc = &ss->ss_components[n++]; + ssc->ssc_index = st->st_index; + ssc->ssc_type = st->st_type; + memcpy(ssc->ssc_lang, st->st_lang, 4); + ssc->ssc_composition_id = st->st_composition_id; + ssc->ssc_ancillary_id = st->st_ancillary_id; + ssc->ssc_pid = st->st_pid; + ssc->ssc_width = st->st_width; + ssc->ssc_height = st->st_height; + } + + t->s_setsourceinfo(t, &ss->ss_si); + + ss->ss_refcount = 1; + ss->ss_pcr_pid = t->s_pcr_pid; + return ss; +} + + +/** + * + */ +void +service_set_enable(service_t *t, int enabled) +{ + if(t->s_enabled == enabled) + return; + + t->s_enabled = enabled; + t->s_config_save(t); + subscription_reschedule(); +} + + +static pthread_mutex_t pending_save_mutex; +static pthread_cond_t pending_save_cond; +static struct service_queue pending_save_queue; + +/** + * + */ +void +service_request_save(service_t *t, int restart) +{ + pthread_mutex_lock(&pending_save_mutex); + + if(!t->s_ps_onqueue) { + t->s_ps_onqueue = 1 + !!restart; + TAILQ_INSERT_TAIL(&pending_save_queue, t, s_ps_link); + service_ref(t); + pthread_cond_signal(&pending_save_cond); + } else if(restart) { + t->s_ps_onqueue = 2; // upgrade to restart too + } + + pthread_mutex_unlock(&pending_save_mutex); +} + + +/** + * + */ +static void * +service_saver(void *aux) +{ + service_t *t; + int restart; + pthread_mutex_lock(&pending_save_mutex); + + while(1) { + + if((t = TAILQ_FIRST(&pending_save_queue)) == NULL) { + pthread_cond_wait(&pending_save_cond, &pending_save_mutex); + continue; + } + assert(t->s_ps_onqueue != 0); + restart = t->s_ps_onqueue == 2; + + TAILQ_REMOVE(&pending_save_queue, t, s_ps_link); + t->s_ps_onqueue = 0; + + pthread_mutex_unlock(&pending_save_mutex); + pthread_mutex_lock(&global_lock); + + if(t->s_status != SERVICE_ZOMBIE) + t->s_config_save(t); + if(t->s_status == SERVICE_RUNNING && restart) { + pthread_mutex_lock(&t->s_stream_mutex); + service_restart(t, 1); + pthread_mutex_unlock(&t->s_stream_mutex); + } + service_unref(t); + + pthread_mutex_unlock(&global_lock); + pthread_mutex_lock(&pending_save_mutex); + } + return NULL; +} + + +/** + * + */ +void +service_init(void) +{ + pthread_t tid; + TAILQ_INIT(&pending_save_queue); + pthread_mutex_init(&pending_save_mutex, NULL); + pthread_cond_init(&pending_save_cond, NULL); + pthread_create(&tid, NULL, service_saver, NULL); +} + + +/** + * + */ +void +service_source_info_free(struct source_info *si) +{ + free(si->si_device); + free(si->si_adapter); + free(si->si_network); + free(si->si_mux); + free(si->si_provider); + free(si->si_service); +} + + +void +service_source_info_copy(source_info_t *dst, const source_info_t *src) +{ +#define COPY(x) dst->si_##x = src->si_##x ? strdup(src->si_##x) : NULL + COPY(device); + COPY(adapter); + COPY(network); + COPY(mux); + COPY(provider); + COPY(service); +#undef COPY +} + + +/** + * + */ +const char * +service_nicename(service_t *t) +{ + return t->s_nicename; +} + +const char * +service_component_nicename(th_stream_t *st) +{ + return st->st_nicename; +} + +const char * +service_tss2text(int flags) +{ + if(flags & TSS_NO_ACCESS) + return "No access"; + + if(flags & TSS_NO_DESCRAMBLER) + return "No descrambler"; + + if(flags & TSS_PACKETS) + return "Got valid packets"; + + if(flags & TSS_MUX_PACKETS) + return "Got multiplexed packets but could not decode further"; + + if(flags & TSS_INPUT_SERVICE) + return "Got packets for this service but could not decode further"; + + if(flags & TSS_INPUT_HARDWARE) + return "Sensed input from hardware but nothing for the service"; + + if(flags & TSS_GRACEPERIOD) + return "No input detected"; + + return "No status"; +} + + +/** + * + */ +int +tss2errcode(int tss) +{ + if(tss & TSS_NO_ACCESS) + return SM_CODE_NO_ACCESS; + + if(tss & TSS_NO_DESCRAMBLER) + return SM_CODE_NO_DESCRAMBLER; + + if(tss & TSS_GRACEPERIOD) + return SM_CODE_NO_INPUT; + + return SM_CODE_OK; +} + + +/** + * + */ +void +service_refresh_channel(service_t *t) +{ + if(t->s_ch != NULL) + htsp_channel_update(t->s_ch); +} + + +/** + * Get the encryption CAID from a service + * only the first CA stream in a service is returned + */ +uint16_t +service_get_encryption(service_t *t) +{ + th_stream_t *st; + caid_t *c; + + TAILQ_FOREACH(st, &t->s_components, st_link) { + switch(st->st_type) { + case SCT_CA: + LIST_FOREACH(c, &st->st_caids, link) + if(c->caid != 0) + return c->caid; + break; + default: + break; + } + } + return 0; +} + + +/** + * Get the signal status from a service + */ +int +service_get_signal_status(service_t *t, signal_status_t *status) +{ + // get signal status from the service + switch(t->s_type) { + case SERVICE_TYPE_DVB: + return dvb_transport_get_signal_status(t, status); + default: + return -1; + } +} + diff --git a/src/serviceprobe.c b/src/serviceprobe.c index c13fe8ac..5b144396 100644 --- a/src/serviceprobe.c +++ b/src/serviceprobe.c @@ -31,31 +31,30 @@ #include "channels.h" #include "subscriptions.h" #include "serviceprobe.h" -#include "transports.h" #include "streaming.h" - +#include "service.h" /* List of transports to be probed, protected with global_lock */ -static struct th_transport_queue serviceprobe_queue; +static struct service_queue serviceprobe_queue; static pthread_cond_t serviceprobe_cond; /** * */ void -serviceprobe_enqueue(th_transport_t *t) +serviceprobe_enqueue(service_t *t) { - if(!transport_is_tv(t)) + if(!service_is_tv(t)) return; /* Don't even consider non-tv channels */ - if(t->tht_sp_onqueue) + if(t->s_sp_onqueue) return; - if(t->tht_ch != NULL) + if(t->s_ch != NULL) return; /* Already mapped */ - t->tht_sp_onqueue = 1; - TAILQ_INSERT_TAIL(&serviceprobe_queue, t, tht_sp_link); + t->s_sp_onqueue = 1; + TAILQ_INSERT_TAIL(&serviceprobe_queue, t, s_sp_link); pthread_cond_signal(&serviceprobe_cond); } @@ -64,12 +63,12 @@ serviceprobe_enqueue(th_transport_t *t) * */ void -serviceprobe_delete(th_transport_t *t) +serviceprobe_delete(service_t *t) { - if(!t->tht_sp_onqueue) + if(!t->s_sp_onqueue) return; - TAILQ_REMOVE(&serviceprobe_queue, t, tht_sp_link); - t->tht_sp_onqueue = 0; + TAILQ_REMOVE(&serviceprobe_queue, t, s_sp_link); + t->s_sp_onqueue = 0; } @@ -79,7 +78,7 @@ serviceprobe_delete(th_transport_t *t) static void * serviceprobe_thread(void *aux) { - th_transport_t *t; + service_t *t; th_subscription_t *s; int was_doing_work = 0; streaming_queue_t sq; @@ -110,18 +109,18 @@ serviceprobe_thread(void *aux) } tvhlog(LOG_INFO, "serviceprobe", "%20s: checking...", - t->tht_svcname); + t->s_svcname); - s = subscription_create_from_transport(t, "serviceprobe", &sq.sq_st, 0); + s = subscription_create_from_service(t, "serviceprobe", &sq.sq_st, 0); if(s == NULL) { - t->tht_sp_onqueue = 0; - TAILQ_REMOVE(&serviceprobe_queue, t, tht_sp_link); + t->s_sp_onqueue = 0; + TAILQ_REMOVE(&serviceprobe_queue, t, s_sp_link); tvhlog(LOG_INFO, "serviceprobe", "%20s: could not subscribe", - t->tht_svcname); + t->s_svcname); continue; } - transport_ref(t); + service_ref(t); pthread_mutex_unlock(&global_lock); run = 1; @@ -135,7 +134,7 @@ serviceprobe_thread(void *aux) pthread_mutex_unlock(&sq.sq_mutex); - if(sm->sm_type == SMT_TRANSPORT_STATUS) { + if(sm->sm_type == SMT_SERVICE_STATUS) { int status = sm->sm_code; if(status & TSS_PACKETS) { @@ -143,7 +142,7 @@ serviceprobe_thread(void *aux) err = NULL; } else if(status & (TSS_GRACEPERIOD | TSS_ERRORS)) { run = 0; - err = transport_tss2text(status); + err = service_tss2text(status); } } @@ -157,25 +156,25 @@ serviceprobe_thread(void *aux) pthread_mutex_lock(&global_lock); subscription_unsubscribe(s); - if(t->tht_status != TRANSPORT_ZOMBIE) { + if(t->s_status != SERVICE_ZOMBIE) { if(err != NULL) { tvhlog(LOG_INFO, "serviceprobe", "%20s: skipped: %s", - t->tht_svcname, err); - } else if(t->tht_ch == NULL) { + t->s_svcname, err); + } else if(t->s_ch == NULL) { const char *str; - ch = channel_find_by_name(t->tht_svcname, 1, t->tht_channel_number); - transport_map_channel(t, ch, 1); + ch = channel_find_by_name(t->s_svcname, 1, t->s_channel_number); + service_map_channel(t, ch, 1); tvhlog(LOG_INFO, "serviceprobe", "%20s: mapped to channel \"%s\"", - t->tht_svcname, t->tht_svcname); + t->s_svcname, t->s_svcname); channel_tag_map(ch, channel_tag_find_by_name("TV channels", 1), 1); tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", - t->tht_svcname, "TV channels"); + t->s_svcname, "TV channels"); - switch(t->tht_servicetype) { + switch(t->s_servicetype) { case ST_SDTV: case ST_AC_SDTV: str = "SDTV"; @@ -191,21 +190,21 @@ serviceprobe_thread(void *aux) if(str != NULL) { channel_tag_map(ch, channel_tag_find_by_name(str, 1), 1); tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", - t->tht_svcname, str); + t->s_svcname, str); } - if(t->tht_provider != NULL) { - channel_tag_map(ch, channel_tag_find_by_name(t->tht_provider, 1), 1); + if(t->s_provider != NULL) { + channel_tag_map(ch, channel_tag_find_by_name(t->s_provider, 1), 1); tvhlog(LOG_INFO, "serviceprobe", "%20s: joined tag \"%s\"", - t->tht_svcname, t->tht_provider); + t->s_svcname, t->s_provider); } channel_save(ch); } - t->tht_sp_onqueue = 0; - TAILQ_REMOVE(&serviceprobe_queue, t, tht_sp_link); + t->s_sp_onqueue = 0; + TAILQ_REMOVE(&serviceprobe_queue, t, s_sp_link); } - transport_unref(t); + service_unref(t); } return NULL; } diff --git a/src/serviceprobe.h b/src/serviceprobe.h index f39ef835..aa5451cd 100644 --- a/src/serviceprobe.h +++ b/src/serviceprobe.h @@ -21,8 +21,8 @@ void serviceprobe_init(void); -void serviceprobe_enqueue(th_transport_t *t); +void serviceprobe_enqueue(struct service *t); -void serviceprobe_delete(th_transport_t *t); +void serviceprobe_delete(struct service *t); #endif /* SERVICEPROBE_H_ */ diff --git a/src/streaming.c b/src/streaming.c index 66b1f3f6..fde3be29 100644 --- a/src/streaming.c +++ b/src/streaming.c @@ -22,7 +22,7 @@ #include "streaming.h" #include "packet.h" #include "atomic.h" -#include "transports.h" +#include "service.h" void streaming_pad_init(streaming_pad_t *sp) @@ -183,7 +183,7 @@ streaming_msg_clone(streaming_message_t *src) break; case SMT_STOP: - case SMT_TRANSPORT_STATUS: + case SMT_SERVICE_STATUS: case SMT_NOSTART: dst->sm_code = src->sm_code; break; @@ -214,7 +214,7 @@ streaming_start_unref(streaming_start_t *ss) if((atomic_add(&ss->ss_refcount, -1)) != 1) return; - transport_source_info_free(&ss->ss_si); + service_source_info_free(&ss->ss_si); for(i = 0; i < ss->ss_num_components; i++) if(ss->ss_components[i].ssc_gh) pktbuf_ref_dec(ss->ss_components[i].ssc_gh); @@ -244,7 +244,7 @@ streaming_msg_free(streaming_message_t *sm) case SMT_EXIT: break; - case SMT_TRANSPORT_STATUS: + case SMT_SERVICE_STATUS: break; case SMT_NOSTART: @@ -355,8 +355,8 @@ streaming_code2txt(int code) return "Too bad signal quality"; case SM_CODE_NO_SOURCE: return "No source available"; - case SM_CODE_NO_TRANSPORT: - return "No transport assigned to channel"; + case SM_CODE_NO_SERVICE: + return "No service assigned to channel"; case SM_CODE_ABORTED: return "Aborted by user"; @@ -388,7 +388,7 @@ streaming_start_copy(const streaming_start_t *src) streaming_start_t *dst = malloc(siz); memcpy(dst, src, siz); - transport_source_info_copy(&dst->ss_si, &src->ss_si); + service_source_info_copy(&dst->ss_si, &src->ss_si); for(i = 0; i < dst->ss_num_components; i++) { streaming_start_component_t *ssc = &dst->ss_components[i]; diff --git a/src/subscriptions.c b/src/subscriptions.c index 2f4ca1b1..4249a382 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -32,9 +32,10 @@ #include #include "tvheadend.h" -#include "transports.h" #include "subscriptions.h" #include "streaming.h" +#include "channels.h" +#include "service.h" struct th_subscription_list subscriptions; static gtimer_t subscription_reschedule_timer; @@ -61,70 +62,70 @@ subscription_sort(th_subscription_t *a, th_subscription_t *b) /** - * The transport is producing output. + * The service is producing output. */ static void -subscription_link_transport(th_subscription_t *s, th_transport_t *t) +subscription_link_service(th_subscription_t *s, service_t *t) { streaming_message_t *sm; - s->ths_state = SUBSCRIPTION_TESTING_TRANSPORT; + s->ths_state = SUBSCRIPTION_TESTING_SERVICE; - s->ths_transport = t; - LIST_INSERT_HEAD(&t->tht_subscriptions, s, ths_transport_link); + s->ths_service = t; + LIST_INSERT_HEAD(&t->s_subscriptions, s, ths_service_link); - pthread_mutex_lock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); - if(TAILQ_FIRST(&t->tht_components) != NULL) + if(TAILQ_FIRST(&t->s_components) != NULL) s->ths_start_message = - streaming_msg_create_data(SMT_START, transport_build_stream_start(t)); + streaming_msg_create_data(SMT_START, service_build_stream_start(t)); - // Link to transport output - streaming_target_connect(&t->tht_streaming_pad, &s->ths_input); + // Link to service output + streaming_target_connect(&t->s_streaming_pad, &s->ths_input); - if(s->ths_start_message != NULL && t->tht_streaming_status & TSS_PACKETS) { + if(s->ths_start_message != NULL && t->s_streaming_status & TSS_PACKETS) { - s->ths_state = SUBSCRIPTION_GOT_TRANSPORT; + s->ths_state = SUBSCRIPTION_GOT_SERVICE; // Send a START message to the subscription client streaming_target_deliver(s->ths_output, s->ths_start_message); s->ths_start_message = NULL; // Send status report - sm = streaming_msg_create_code(SMT_TRANSPORT_STATUS, - t->tht_streaming_status); + sm = streaming_msg_create_code(SMT_SERVICE_STATUS, + t->s_streaming_status); streaming_target_deliver(s->ths_output, sm); } - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_unlock(&t->s_stream_mutex); } /** - * Called from transport code + * Called from service code */ void -subscription_unlink_transport(th_subscription_t *s, int reason) +subscription_unlink_service(th_subscription_t *s, int reason) { streaming_message_t *sm; - th_transport_t *t = s->ths_transport; + service_t *t = s->ths_service; - pthread_mutex_lock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); - // Unlink from transport output - streaming_target_disconnect(&t->tht_streaming_pad, &s->ths_input); + // Unlink from service output + streaming_target_disconnect(&t->s_streaming_pad, &s->ths_input); - if(TAILQ_FIRST(&t->tht_components) != NULL && - s->ths_state == SUBSCRIPTION_GOT_TRANSPORT) { + if(TAILQ_FIRST(&t->s_components) != NULL && + s->ths_state == SUBSCRIPTION_GOT_SERVICE) { // Send a STOP message to the subscription client sm = streaming_msg_create_code(SMT_STOP, reason); streaming_target_deliver(s->ths_output, sm); } - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_unlock(&t->s_stream_mutex); - LIST_REMOVE(s, ths_transport_link); - s->ths_transport = NULL; + LIST_REMOVE(s, ths_service_link); + s->ths_service = NULL; } @@ -141,7 +142,7 @@ void subscription_reschedule(void) { th_subscription_t *s; - th_transport_t *t, *skip; + service_t *t, *skip; streaming_message_t *sm; char buf[128]; int error; @@ -155,31 +156,31 @@ subscription_reschedule(void) if(s->ths_channel == NULL) continue; /* stale entry, channel has been destroyed */ - if(s->ths_transport != NULL) { - /* Already got a transport */ + if(s->ths_service != NULL) { + /* Already got a service */ - if(s->ths_state != SUBSCRIPTION_BAD_TRANSPORT) + if(s->ths_state != SUBSCRIPTION_BAD_SERVICE) continue; /* And it seems to work ok, so we're happy */ - skip = s->ths_transport; + skip = s->ths_service; error = s->ths_testing_error; - transport_remove_subscriber(s->ths_transport, s, s->ths_testing_error); + service_remove_subscriber(s->ths_service, s, s->ths_testing_error); } else { error = 0; skip = NULL; } snprintf(buf, sizeof(buf), "Subscription \"%s\"", s->ths_title); - t = transport_find(s->ths_channel, s->ths_weight, buf, &error, skip); + t = service_find(s->ths_channel, s->ths_weight, buf, &error, skip); if(t == NULL) { - /* No transport available */ + /* No service available */ sm = streaming_msg_create_code(SMT_NOSTART, error); streaming_target_deliver(s->ths_output, sm); continue; } - subscription_link_transport(s, t); + subscription_link_service(s, t); } } @@ -189,7 +190,7 @@ subscription_reschedule(void) void subscription_unsubscribe(th_subscription_t *s) { - th_transport_t *t = s->ths_transport; + service_t *t = s->ths_service; lock_assert(&global_lock); @@ -205,7 +206,7 @@ subscription_unsubscribe(th_subscription_t *s) } if(t != NULL) - transport_remove_subscriber(t, s, SM_CODE_OK); + service_remove_subscriber(t, s, SM_CODE_OK); if(s->ths_start_message != NULL) streaming_msg_free(s->ths_start_message); @@ -219,15 +220,15 @@ subscription_unsubscribe(th_subscription_t *s) /** * This callback is invoked when we receive data and status updates from - * the currently bound transport + * the currently bound service */ static void subscription_input(void *opauqe, streaming_message_t *sm) { th_subscription_t *s = opauqe; - if(s->ths_state == SUBSCRIPTION_TESTING_TRANSPORT) { - // We are just testing if this transport is good + if(s->ths_state == SUBSCRIPTION_TESTING_SERVICE) { + // We are just testing if this service is good if(sm->sm_type == SMT_START) { if(s->ths_start_message != NULL) @@ -236,27 +237,27 @@ subscription_input(void *opauqe, streaming_message_t *sm) return; } - if(sm->sm_type == SMT_TRANSPORT_STATUS && + if(sm->sm_type == SMT_SERVICE_STATUS && sm->sm_code & (TSS_GRACEPERIOD | TSS_ERRORS)) { - // No, mark our subscription as bad_transport + // No, mark our subscription as bad_service // the scheduler will take care of things s->ths_testing_error = tss2errcode(sm->sm_code); - s->ths_state = SUBSCRIPTION_BAD_TRANSPORT; + s->ths_state = SUBSCRIPTION_BAD_SERVICE; streaming_msg_free(sm); return; } - if(sm->sm_type == SMT_TRANSPORT_STATUS && + if(sm->sm_type == SMT_SERVICE_STATUS && sm->sm_code & TSS_PACKETS) { if(s->ths_start_message != NULL) { streaming_target_deliver(s->ths_output, s->ths_start_message); s->ths_start_message = NULL; } - s->ths_state = SUBSCRIPTION_GOT_TRANSPORT; + s->ths_state = SUBSCRIPTION_GOT_SERVICE; } } - if(s->ths_state != SUBSCRIPTION_GOT_TRANSPORT) { + if(s->ths_state != SUBSCRIPTION_GOT_SERVICE) { streaming_msg_free(sm); return; } @@ -320,11 +321,11 @@ subscription_create_from_channel(channel_t *ch, unsigned int weight, s->ths_channel = ch; LIST_INSERT_HEAD(&ch->ch_subscriptions, s, ths_channel_link); - s->ths_transport = NULL; + s->ths_service = NULL; subscription_reschedule(); - if(s->ths_transport == NULL) { + if(s->ths_service == NULL) { tvhlog(LOG_NOTICE, "subscription", "No transponder available for subscription \"%s\" " "to channel \"%s\"", @@ -332,7 +333,7 @@ subscription_create_from_channel(channel_t *ch, unsigned int weight, } else { source_info_t si; - s->ths_transport->tht_setsourceinfo(s->ths_transport, &si); + s->ths_service->s_setsourceinfo(s->ths_service, &si); tvhlog(LOG_INFO, "subscription", "\"%s\" subscribing on \"%s\", weight: %d, adapter: \"%s\", " @@ -344,9 +345,9 @@ subscription_create_from_channel(channel_t *ch, unsigned int weight, si.si_mux ?: "", si.si_provider ?: "", si.si_service ?: "", - s->ths_transport->tht_quality_index(s->ths_transport)); + s->ths_service->s_quality_index(s->ths_service)); - transport_source_info_free(&si); + service_source_info_free(&si); } return s; } @@ -356,15 +357,15 @@ subscription_create_from_channel(channel_t *ch, unsigned int weight, * */ th_subscription_t * -subscription_create_from_transport(th_transport_t *t, const char *name, +subscription_create_from_service(service_t *t, const char *name, streaming_target_t *st, int flags) { th_subscription_t *s = subscription_create(INT32_MAX, name, st, flags, 1); source_info_t si; int r; - if(t->tht_status != TRANSPORT_RUNNING) { - if((r = transport_start(t, INT32_MAX, 1)) != 0) { + if(t->s_status != SERVICE_RUNNING) { + if((r = service_start(t, INT32_MAX, 1)) != 0) { subscription_unsubscribe(s); tvhlog(LOG_INFO, "subscription", @@ -374,7 +375,7 @@ subscription_create_from_transport(th_transport_t *t, const char *name, } } - t->tht_setsourceinfo(t, &si); + t->s_setsourceinfo(t, &si); tvhlog(LOG_INFO, "subscription", "\"%s\" direct subscription to adapter: \"%s\", " @@ -386,10 +387,10 @@ subscription_create_from_transport(th_transport_t *t, const char *name, si.si_mux ?: "", si.si_provider ?: "", si.si_service ?: "", - t->tht_quality_index(t)); - transport_source_info_free(&si); + t->s_quality_index(t)); + service_source_info_free(&si); - subscription_link_transport(s, t); + subscription_link_service(s, t); return s; } @@ -426,7 +427,7 @@ dummy_callback(void *opauqe, streaming_message_t *sm) fprintf(stderr, "dummysubscription STOP\n"); break; - case SMT_TRANSPORT_STATUS: + case SMT_SERVICE_STATUS: fprintf(stderr, "dummsubscription: %x\n", sm->sm_code); break; default: @@ -454,7 +455,7 @@ dummy_retry(void *opaque) void subscription_dummy_join(const char *id, int first) { - th_transport_t *t = transport_find_by_identifier(id); + service_t *t = service_find_by_identifier(id); streaming_target_t *st; if(first) { @@ -464,7 +465,7 @@ subscription_dummy_join(const char *id, int first) if(t == NULL) { tvhlog(LOG_ERR, "subscription", - "Unable to dummy join %s, transport not found, retrying...", id); + "Unable to dummy join %s, service not found, retrying...", id); gtimer_arm(&dummy_sub_timer, dummy_retry, strdup(id), 1); return; @@ -472,7 +473,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_transport(t, "dummy", st, 0); + subscription_create_from_service(t, "dummy", st, 0); tvhlog(LOG_NOTICE, "subscription", "Dummy join %s ok", id); diff --git a/src/subscriptions.h b/src/subscriptions.h index 65f147a3..52738041 100644 --- a/src/subscriptions.h +++ b/src/subscriptions.h @@ -27,9 +27,9 @@ typedef struct th_subscription { enum { SUBSCRIPTION_IDLE, - SUBSCRIPTION_TESTING_TRANSPORT, - SUBSCRIPTION_GOT_TRANSPORT, - SUBSCRIPTION_BAD_TRANSPORT, + SUBSCRIPTION_TESTING_SERVICE, + SUBSCRIPTION_GOT_SERVICE, + SUBSCRIPTION_BAD_SERVICE, } ths_state; int ths_testing_error; @@ -39,8 +39,8 @@ typedef struct th_subscription { destroyed during the subscription */ - LIST_ENTRY(th_subscription) ths_transport_link; - struct th_transport *ths_transport; /* if NULL, ths_transport_link + LIST_ENTRY(th_subscription) ths_service_link; + struct service *ths_service; /* if NULL, ths_service_link is not linked */ char *ths_title; /* display title */ @@ -67,23 +67,23 @@ void subscription_set_weight(th_subscription_t *s, unsigned int weight); void subscription_reschedule(void); -th_subscription_t *subscription_create_from_channel(channel_t *ch, +th_subscription_t *subscription_create_from_channel(struct channel *ch, unsigned int weight, const char *name, streaming_target_t *st, int flags); -th_subscription_t *subscription_create_from_transport(th_transport_t *t, - const char *name, - streaming_target_t *st, - int flags); +th_subscription_t *subscription_create_from_service(struct service *t, + const char *name, + streaming_target_t *st, + int flags); void subscription_change_weight(th_subscription_t *s, int weight); void subscription_stop(th_subscription_t *s); -void subscription_unlink_transport(th_subscription_t *s, int reason); +void subscription_unlink_service(th_subscription_t *s, int reason); void subscription_dummy_join(const char *id, int first); diff --git a/src/teletext.c b/src/teletext.c index 7356dbe7..0ce1c391 100644 --- a/src/teletext.c +++ b/src/teletext.c @@ -31,9 +31,9 @@ #include "tvheadend.h" #include "teletext.h" -#include "transports.h" #include "packet.h" #include "streaming.h" +#include "service.h" /** * @@ -61,7 +61,7 @@ typedef struct tt_private { static void teletext_rundown_copy(tt_private_t *ttp, tt_mag_t *ttm); -static void teletext_rundown_scan(th_transport_t *t, tt_private_t *ttp); +static void teletext_rundown_scan(service_t *t, tt_private_t *ttp); #define bitreverse(b) \ (((b) * 0x0202020202ULL & 0x010884422010ULL) % 1023) @@ -236,7 +236,7 @@ is_tt_clock(const uint8_t *str) * */ static int -update_tt_clock(th_transport_t *t, const uint8_t *buf) +update_tt_clock(service_t *t, const uint8_t *buf) { uint8_t str[10]; int i; @@ -250,17 +250,17 @@ update_tt_clock(th_transport_t *t, const uint8_t *buf) return 0; ti = tt_construct_unix_time(str); - if(t->tht_tt_clock == ti) + if(t->s_tt_clock == ti) return 0; - t->tht_tt_clock = ti; + t->s_tt_clock = ti; // printf("teletext clock is: %s", ctime(&ti)); return 1; } static void -extract_subtitle(th_transport_t *t, th_stream_t *st, +extract_subtitle(service_t *t, th_stream_t *st, tt_mag_t *ttm, int64_t pts) { int i, j, off = 0; @@ -315,7 +315,7 @@ extract_subtitle(th_transport_t *t, th_stream_t *st, pkt->pkt_componentindex = st->st_index; streaming_message_t *sm = streaming_msg_create_pkt(pkt); - streaming_pad_deliver(&t->tht_streaming_pad, sm); + streaming_pad_deliver(&t->s_streaming_pad, sm); streaming_msg_free(sm); /* Decrease our own reference to the packet */ @@ -354,14 +354,14 @@ dump_page(tt_mag_t *ttm) static void -tt_subtitle_deliver(th_transport_t *t, th_stream_t *parent, tt_mag_t *ttm) +tt_subtitle_deliver(service_t *t, th_stream_t *parent, tt_mag_t *ttm) { th_stream_t *st; if(ttm->ttm_current_pts == PTS_UNSET) return; - TAILQ_FOREACH(st, &t->tht_components, st_link) { + TAILQ_FOREACH(st, &t->s_components, st_link) { if(parent->st_pid == st->st_parent_pid && ttm->ttm_curpage == st->st_pid - PID_TELETEXT_BASE) { extract_subtitle(t, st, ttm, ttm->ttm_current_pts); @@ -373,7 +373,7 @@ tt_subtitle_deliver(th_transport_t *t, th_stream_t *parent, tt_mag_t *ttm) * */ static void -tt_decode_line(th_transport_t *t, th_stream_t *st, uint8_t *buf) +tt_decode_line(service_t *t, th_stream_t *st, uint8_t *buf) { uint8_t mpag, line, s12, s34, c; int page, magidx, i; @@ -429,7 +429,7 @@ tt_decode_line(th_transport_t *t, th_stream_t *st, uint8_t *buf) if(update_tt_clock(t, buf + 34)) teletext_rundown_scan(t, ttp); - ttm->ttm_current_pts = t->tht_current_pts; + ttm->ttm_current_pts = t->s_current_pts; ttm->ttm_inactive = 0; break; @@ -453,7 +453,7 @@ tt_decode_line(th_transport_t *t, th_stream_t *st, uint8_t *buf) * */ static void -teletext_scan_stream(th_transport_t *t, th_stream_t *st) +teletext_scan_stream(service_t *t, th_stream_t *st) { tt_private_t *ttp = st->st_priv; tt_mag_t *ttm; @@ -475,7 +475,7 @@ teletext_scan_stream(th_transport_t *t, th_stream_t *st) * */ void -teletext_input(th_transport_t *t, th_stream_t *st, const uint8_t *tsb) +teletext_input(service_t *t, th_stream_t *st, const uint8_t *tsb) { int i, j; const uint8_t *x; @@ -562,11 +562,11 @@ teletext_rundown_copy(tt_private_t *ttp, tt_mag_t *ttm) static void -teletext_rundown_scan(th_transport_t *t, tt_private_t *ttp) +teletext_rundown_scan(service_t *t, tt_private_t *ttp) { int i; uint8_t *l; - time_t now = t->tht_tt_clock, start, stop, last = 0; + time_t now = t->s_tt_clock, start, stop, last = 0; th_commercial_advice_t ca; if(ttp->ttp_rundown_valid == 0) @@ -586,9 +586,9 @@ teletext_rundown_scan(th_transport_t *t, tt_private_t *ttp) stop = start + tt_time_to_len(l + 32); if(start <= now && stop > now) - t->tht_tt_commercial_advice = ca; + t->s_tt_commercial_advice = ca; - if(start > now && ca != t->tht_tt_commercial_advice && last == 0) + if(start > now && ca != t->s_tt_commercial_advice && last == 0) last = start; } } diff --git a/src/teletext.h b/src/teletext.h index e826aea2..9256b72c 100644 --- a/src/teletext.h +++ b/src/teletext.h @@ -19,6 +19,7 @@ #ifndef TELETEXT_H #define TELETEXT_H -void teletext_input(th_transport_t *t, th_stream_t *st, const uint8_t *tsb); +void teletext_input(struct service *t, struct th_stream *st, + const uint8_t *tsb); #endif /* TELETEXT_H */ diff --git a/src/transports.c b/src/transports.c deleted file mode 100644 index 57850e57..00000000 --- a/src/transports.c +++ /dev/null @@ -1,1069 +0,0 @@ -/* - * tvheadend, transport and subscription functions - * Copyright (C) 2007 Andreas Öman - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tvheadend.h" -#include "transports.h" -#include "subscriptions.h" -#include "tsdemux.h" -#include "streaming.h" -#include "v4l.h" -#include "psi.h" -#include "packet.h" -#include "channels.h" -#include "cwc.h" -#include "capmt.h" -#include "notify.h" -#include "serviceprobe.h" -#include "atomic.h" -#include "dvb/dvb.h" -#include "htsp.h" - -#define TRANSPORT_HASH_WIDTH 101 - -static struct th_transport_list transporthash[TRANSPORT_HASH_WIDTH]; - -static void transport_data_timeout(void *aux); - -/** - * - */ -static void -stream_init(th_stream_t *st) -{ - st->st_cc_valid = 0; - - st->st_startcond = 0xffffffff; - st->st_curdts = PTS_UNSET; - st->st_curpts = PTS_UNSET; - st->st_prevdts = PTS_UNSET; - - st->st_pcr_real_last = PTS_UNSET; - st->st_pcr_last = PTS_UNSET; - st->st_pcr_drift = 0; - st->st_pcr_recovery_fails = 0; - - st->st_blank = 0; -} - - -/** - * - */ -static void -stream_clean(th_stream_t *st) -{ - if(st->st_demuxer_fd != -1) { - // XXX: Should be in DVB-code perhaps - close(st->st_demuxer_fd); - st->st_demuxer_fd = -1; - } - - free(st->st_priv); - st->st_priv = NULL; - - /* Clear reassembly buffers */ - - st->st_startcode = 0; - - sbuf_free(&st->st_buf); - sbuf_free(&st->st_buf_ps); - sbuf_free(&st->st_buf_a); - - if(st->st_curpkt != NULL) { - pkt_ref_dec(st->st_curpkt); - st->st_curpkt = NULL; - } - - free(st->st_global_data); - st->st_global_data = NULL; - st->st_global_data_len = 0; -} - - -/** - * - */ -void -transport_stream_destroy(th_transport_t *t, th_stream_t *st) -{ - if(t->tht_status == TRANSPORT_RUNNING) - stream_clean(st); - TAILQ_REMOVE(&t->tht_components, st, st_link); - free(st->st_nicename); - free(st); -} - -/** - * Transport lock must be held - */ -static void -transport_stop(th_transport_t *t) -{ - th_descrambler_t *td; - th_stream_t *st; - - gtimer_disarm(&t->tht_receive_timer); - - t->tht_stop_feed(t); - - pthread_mutex_lock(&t->tht_stream_mutex); - - while((td = LIST_FIRST(&t->tht_descramblers)) != NULL) - td->td_stop(td); - - t->tht_tt_commercial_advice = COMMERCIAL_UNKNOWN; - - assert(LIST_FIRST(&t->tht_streaming_pad.sp_targets) == NULL); - assert(LIST_FIRST(&t->tht_subscriptions) == NULL); - - /** - * Clean up each stream - */ - TAILQ_FOREACH(st, &t->tht_components, st_link) - stream_clean(st); - - t->tht_status = TRANSPORT_IDLE; - - pthread_mutex_unlock(&t->tht_stream_mutex); -} - - -/** - * Remove the given subscriber from the transport - * - * if s == NULL all subscribers will be removed - * - * Global lock must be held - */ -void -transport_remove_subscriber(th_transport_t *t, th_subscription_t *s, - int reason) -{ - lock_assert(&global_lock); - - if(s == NULL) { - while((s = LIST_FIRST(&t->tht_subscriptions)) != NULL) { - subscription_unlink_transport(s, reason); - } - } else { - subscription_unlink_transport(s, reason); - } - - if(LIST_FIRST(&t->tht_subscriptions) == NULL) - transport_stop(t); -} - - -/** - * - */ -int -transport_start(th_transport_t *t, unsigned int weight, int force_start) -{ - th_stream_t *st; - int r, timeout = 2; - - lock_assert(&global_lock); - - assert(t->tht_status != TRANSPORT_RUNNING); - t->tht_streaming_status = 0; - t->tht_pcr_drift = 0; - - if((r = t->tht_start_feed(t, weight, force_start))) - return r; - - cwc_transport_start(t); - capmt_transport_start(t); - - pthread_mutex_lock(&t->tht_stream_mutex); - - t->tht_status = TRANSPORT_RUNNING; - t->tht_current_pts = PTS_UNSET; - - /** - * Initialize stream - */ - TAILQ_FOREACH(st, &t->tht_components, st_link) - stream_init(st); - - pthread_mutex_unlock(&t->tht_stream_mutex); - - if(t->tht_grace_period != NULL) - timeout = t->tht_grace_period(t); - - gtimer_arm(&t->tht_receive_timer, transport_data_timeout, t, timeout); - return 0; -} - -/** - * - */ -static int -dvb_extra_prio(th_dvb_adapter_t *tda) -{ - return tda->tda_hostconnection * 10; -} - -/** - * Return prio for the given transport - */ -static int -transport_get_prio(th_transport_t *t) -{ - switch(t->tht_type) { - case TRANSPORT_DVB: - return (t->tht_scrambled ? 300 : 100) + - dvb_extra_prio(t->tht_dvb_mux_instance->tdmi_adapter); - - case TRANSPORT_IPTV: - return 200; - - case TRANSPORT_V4L: - return 400; - - default: - return 500; - } -} - -/** - * Return quality index for given transport - * - * We invert the result (providers say that negative numbers are worse) - * - * But for sorting, we want low numbers first - * - * Also, we bias and trim with an offset of two to avoid counting any - * transient errors. - */ - -static int -transport_get_quality(th_transport_t *t) -{ - return t->tht_quality_index ? -MIN(t->tht_quality_index(t) + 2, 0) : 0; -} - - - - -/** - * a - b -> lowest number first - */ -static int -transportcmp(const void *A, const void *B) -{ - th_transport_t *a = *(th_transport_t **)A; - th_transport_t *b = *(th_transport_t **)B; - - int q = transport_get_quality(a) - transport_get_quality(b); - - if(q != 0) - return q; /* Quality precedes priority */ - - return transport_get_prio(a) - transport_get_prio(b); -} - - -/** - * - */ -th_transport_t * -transport_find(channel_t *ch, unsigned int weight, const char *loginfo, - int *errorp, th_transport_t *skip) -{ - th_transport_t *t, **vec; - int cnt = 0, i, r, off; - int err = 0; - - lock_assert(&global_lock); - - /* First, sort all transports in order */ - - LIST_FOREACH(t, &ch->ch_transports, tht_ch_link) - cnt++; - - vec = alloca(cnt * sizeof(th_transport_t *)); - cnt = 0; - LIST_FOREACH(t, &ch->ch_transports, tht_ch_link) { - - if(!t->tht_enabled) { - if(loginfo != NULL) { - tvhlog(LOG_NOTICE, "Transport", "%s: Skipping \"%s\" -- not enabled", - loginfo, transport_nicename(t)); - err = SM_CODE_SVC_NOT_ENABLED; - } - continue; - } - - if(t->tht_quality_index(t) < 10) { - if(loginfo != NULL) { - tvhlog(LOG_NOTICE, "Transport", - "%s: Skipping \"%s\" -- Quality below 10%", - loginfo, transport_nicename(t)); - err = SM_CODE_BAD_SIGNAL; - } - continue; - } - vec[cnt++] = t; - } - - /* Sort transports, lower priority should come come earlier in the vector - (i.e. it will be more favoured when selecting a transport */ - - qsort(vec, cnt, sizeof(th_transport_t *), transportcmp); - - // Skip up to the transport that the caller didn't want - // If the sorting above is not stable that might mess up things - // temporary. But it should resolve itself eventually - if(skip != NULL) { - for(i = 0; i < cnt; i++) { - if(skip == t) - break; - } - off = i + 1; - } else { - off = 0; - } - - /* First, try all transports without stealing */ - for(i = off; i < cnt; i++) { - t = vec[i]; - if(t->tht_status == TRANSPORT_RUNNING) - return t; - if((r = transport_start(t, 0, 0)) == 0) - return t; - if(loginfo != NULL) - tvhlog(LOG_DEBUG, "Transport", "%s: Unable to use \"%s\" -- %s", - loginfo, transport_nicename(t), streaming_code2txt(r)); - } - - /* Ok, nothing, try again, but supply our weight and thus, try to steal - transponders */ - - for(i = off; i < cnt; i++) { - t = vec[i]; - if((r = transport_start(t, weight, 0)) == 0) - return t; - *errorp = r; - } - if(err) - *errorp = err; - else if(*errorp == 0) - *errorp = SM_CODE_NO_TRANSPORT; - return NULL; -} - - -/** - * - */ -unsigned int -transport_compute_weight(struct th_transport_list *head) -{ - th_transport_t *t; - th_subscription_t *s; - int w = 0; - - lock_assert(&global_lock); - - LIST_FOREACH(t, head, tht_active_link) { - LIST_FOREACH(s, &t->tht_subscriptions, ths_transport_link) { - if(s->ths_weight > w) - w = s->ths_weight; - } - } - return w; -} - - -/** - * - */ -void -transport_unref(th_transport_t *t) -{ - if((atomic_add(&t->tht_refcount, -1)) == 1) - free(t); -} - - -/** - * - */ -void -transport_ref(th_transport_t *t) -{ - atomic_add(&t->tht_refcount, 1); -} - - - -/** - * Destroy a transport - */ -void -transport_destroy(th_transport_t *t) -{ - th_stream_t *st; - th_subscription_t *s; - channel_t *ch = t->tht_ch; - - if(t->tht_dtor != NULL) - t->tht_dtor(t); - - lock_assert(&global_lock); - - serviceprobe_delete(t); - - while((s = LIST_FIRST(&t->tht_subscriptions)) != NULL) { - subscription_unlink_transport(s, SM_CODE_SOURCE_DELETED); - } - - if(t->tht_ch != NULL) { - t->tht_ch = NULL; - LIST_REMOVE(t, tht_ch_link); - } - - LIST_REMOVE(t, tht_group_link); - LIST_REMOVE(t, tht_hash_link); - - if(t->tht_status != TRANSPORT_IDLE) - transport_stop(t); - - t->tht_status = TRANSPORT_ZOMBIE; - - free(t->tht_identifier); - free(t->tht_svcname); - free(t->tht_provider); - - while((st = TAILQ_FIRST(&t->tht_components)) != NULL) { - TAILQ_REMOVE(&t->tht_components, st, st_link); - free(st->st_nicename); - free(st); - } - - free(t->tht_pat_section); - free(t->tht_pmt_section); - - transport_unref(t); - - if(ch != NULL) { - if(LIST_FIRST(&ch->ch_transports) == NULL) - channel_delete(ch); - } -} - - -/** - * Create and initialize a new transport struct - */ -th_transport_t * -transport_create(const char *identifier, int type, int source_type) -{ - unsigned int hash = tvh_strhash(identifier, TRANSPORT_HASH_WIDTH); - th_transport_t *t = calloc(1, sizeof(th_transport_t)); - - lock_assert(&global_lock); - - pthread_mutex_init(&t->tht_stream_mutex, NULL); - pthread_cond_init(&t->tht_tss_cond, NULL); - t->tht_identifier = strdup(identifier); - t->tht_type = type; - t->tht_source_type = source_type; - t->tht_refcount = 1; - t->tht_enabled = 1; - t->tht_pcr_last = PTS_UNSET; - TAILQ_INIT(&t->tht_components); - - streaming_pad_init(&t->tht_streaming_pad); - - LIST_INSERT_HEAD(&transporthash[hash], t, tht_hash_link); - return t; -} - -/** - * Find a transport based on the given identifier - */ -th_transport_t * -transport_find_by_identifier(const char *identifier) -{ - th_transport_t *t; - unsigned int hash = tvh_strhash(identifier, TRANSPORT_HASH_WIDTH); - - lock_assert(&global_lock); - - LIST_FOREACH(t, &transporthash[hash], tht_hash_link) - if(!strcmp(t->tht_identifier, identifier)) - break; - return t; -} - - -/** - * - */ -static void -transport_stream_make_nicename(th_transport_t *t, th_stream_t *st) -{ - char buf[200]; - if(st->st_pid != -1) - snprintf(buf, sizeof(buf), "%s: %s @ #%d", - transport_nicename(t), - streaming_component_type2txt(st->st_type), st->st_pid); - else - snprintf(buf, sizeof(buf), "%s: %s", - transport_nicename(t), - streaming_component_type2txt(st->st_type)); - - free(st->st_nicename); - st->st_nicename = strdup(buf); -} - - -/** - * - */ -void -transport_make_nicename(th_transport_t *t) -{ - char buf[200]; - source_info_t si; - th_stream_t *st; - - lock_assert(&t->tht_stream_mutex); - - t->tht_setsourceinfo(t, &si); - - snprintf(buf, sizeof(buf), - "%s%s%s%s%s", - si.si_adapter ?: "", si.si_adapter && si.si_mux ? "/" : "", - si.si_mux ?: "", si.si_mux && si.si_service ? "/" : "", - si.si_service ?: ""); - - transport_source_info_free(&si); - - free(t->tht_nicename); - t->tht_nicename = strdup(buf); - - TAILQ_FOREACH(st, &t->tht_components, st_link) - transport_stream_make_nicename(t, st); -} - - -/** - * Add a new stream to a transport - */ -th_stream_t * -transport_stream_create(th_transport_t *t, int pid, - streaming_component_type_t type) -{ - th_stream_t *st; - int i = 0; - int idx = 0; - lock_assert(&t->tht_stream_mutex); - - TAILQ_FOREACH(st, &t->tht_components, st_link) { - if(st->st_index > idx) - idx = st->st_index; - i++; - if(pid != -1 && st->st_pid == pid) - return st; - } - - st = calloc(1, sizeof(th_stream_t)); - st->st_index = idx + 1; - st->st_type = type; - - TAILQ_INSERT_TAIL(&t->tht_components, st, st_link); - st->st_transport = t; - - st->st_pid = pid; - st->st_demuxer_fd = -1; - - avgstat_init(&st->st_rate, 10); - avgstat_init(&st->st_cc_errors, 10); - - transport_stream_make_nicename(t, st); - - if(t->tht_flags & THT_DEBUG) - tvhlog(LOG_DEBUG, "transport", "Add stream %s", st->st_nicename); - - if(t->tht_status == TRANSPORT_RUNNING) - stream_init(st); - - return st; -} - - - -/** - * Add a new stream to a transport - */ -th_stream_t * -transport_stream_find(th_transport_t *t, int pid) -{ - th_stream_t *st; - - lock_assert(&t->tht_stream_mutex); - - TAILQ_FOREACH(st, &t->tht_components, st_link) { - if(st->st_pid == pid) - return st; - } - return NULL; -} - - - -/** - * - */ -void -transport_map_channel(th_transport_t *t, channel_t *ch, int save) -{ - lock_assert(&global_lock); - - if(t->tht_ch != NULL) { - LIST_REMOVE(t, tht_ch_link); - htsp_channel_update(t->tht_ch); - t->tht_ch = NULL; - } - - - if(ch != NULL) { - - avgstat_init(&t->tht_cc_errors, 3600); - avgstat_init(&t->tht_rate, 10); - - t->tht_ch = ch; - LIST_INSERT_HEAD(&ch->ch_transports, t, tht_ch_link); - htsp_channel_update(t->tht_ch); - } - - if(save) - t->tht_config_save(t); -} - -/** - * - */ -static void -transport_data_timeout(void *aux) -{ - th_transport_t *t = aux; - - pthread_mutex_lock(&t->tht_stream_mutex); - - if(!(t->tht_streaming_status & TSS_PACKETS)) - transport_set_streaming_status_flags(t, TSS_GRACEPERIOD); - - pthread_mutex_unlock(&t->tht_stream_mutex); -} - -/** - * - */ -static struct strtab stypetab[] = { - { "SDTV", ST_SDTV }, - { "Radio", ST_RADIO }, - { "HDTV", ST_HDTV }, - { "SDTV-AC", ST_AC_SDTV }, - { "HDTV-AC", ST_AC_HDTV }, -}; - -const char * -transport_servicetype_txt(th_transport_t *t) -{ - return val2str(t->tht_servicetype, stypetab) ?: "Other"; -} - -/** - * - */ -int -transport_is_tv(th_transport_t *t) -{ - return - t->tht_servicetype == ST_SDTV || - t->tht_servicetype == ST_HDTV || - t->tht_servicetype == ST_AC_SDTV || - t->tht_servicetype == ST_AC_HDTV; -} - - -/** - * - */ -void -transport_set_streaming_status_flags(th_transport_t *t, int set) -{ - int n; - streaming_message_t *sm; - lock_assert(&t->tht_stream_mutex); - - n = t->tht_streaming_status; - - n |= set; - - if(n == t->tht_streaming_status) - return; // Already set - - t->tht_streaming_status = n; - - tvhlog(LOG_DEBUG, "Transport", "%s: Status changed to %s%s%s%s%s%s%s", - transport_nicename(t), - n & TSS_INPUT_HARDWARE ? "[Hardware input] " : "", - n & TSS_INPUT_SERVICE ? "[Input on service] " : "", - n & TSS_MUX_PACKETS ? "[Demuxed packets] " : "", - n & TSS_PACKETS ? "[Reassembled packets] " : "", - n & TSS_NO_DESCRAMBLER ? "[No available descrambler] " : "", - n & TSS_NO_ACCESS ? "[No access] " : "", - n & TSS_GRACEPERIOD ? "[Graceperiod expired] " : ""); - - sm = streaming_msg_create_code(SMT_TRANSPORT_STATUS, - t->tht_streaming_status); - streaming_pad_deliver(&t->tht_streaming_pad, sm); - streaming_msg_free(sm); - - pthread_cond_broadcast(&t->tht_tss_cond); -} - - -/** - * Restart output on a transport. - * Happens if the stream composition changes. - * (i.e. an AC3 stream disappears, etc) - */ -void -transport_restart(th_transport_t *t, int had_components) -{ - streaming_message_t *sm; - lock_assert(&t->tht_stream_mutex); - - if(had_components) { - sm = streaming_msg_create_code(SMT_STOP, SM_CODE_SOURCE_RECONFIGURED); - streaming_pad_deliver(&t->tht_streaming_pad, sm); - streaming_msg_free(sm); - } - - if(t->tht_refresh_feed != NULL) - t->tht_refresh_feed(t); - - if(TAILQ_FIRST(&t->tht_components) != NULL) { - - sm = streaming_msg_create_data(SMT_START, - transport_build_stream_start(t)); - streaming_pad_deliver(&t->tht_streaming_pad, sm); - streaming_msg_free(sm); - } -} - - -/** - * Generate a message containing info about all components - */ -streaming_start_t * -transport_build_stream_start(th_transport_t *t) -{ - th_stream_t *st; - int n = 0; - streaming_start_t *ss; - - lock_assert(&t->tht_stream_mutex); - - TAILQ_FOREACH(st, &t->tht_components, st_link) - n++; - - ss = calloc(1, sizeof(streaming_start_t) + - sizeof(streaming_start_component_t) * n); - - ss->ss_num_components = n; - - n = 0; - TAILQ_FOREACH(st, &t->tht_components, st_link) { - streaming_start_component_t *ssc = &ss->ss_components[n++]; - ssc->ssc_index = st->st_index; - ssc->ssc_type = st->st_type; - memcpy(ssc->ssc_lang, st->st_lang, 4); - ssc->ssc_composition_id = st->st_composition_id; - ssc->ssc_ancillary_id = st->st_ancillary_id; - ssc->ssc_pid = st->st_pid; - ssc->ssc_width = st->st_width; - ssc->ssc_height = st->st_height; - } - - t->tht_setsourceinfo(t, &ss->ss_si); - - ss->ss_refcount = 1; - ss->ss_pcr_pid = t->tht_pcr_pid; - return ss; -} - - -/** - * - */ -void -transport_set_enable(th_transport_t *t, int enabled) -{ - if(t->tht_enabled == enabled) - return; - - t->tht_enabled = enabled; - t->tht_config_save(t); - subscription_reschedule(); -} - - -static pthread_mutex_t pending_save_mutex; -static pthread_cond_t pending_save_cond; -static struct th_transport_queue pending_save_queue; - -/** - * - */ -void -transport_request_save(th_transport_t *t, int restart) -{ - pthread_mutex_lock(&pending_save_mutex); - - if(!t->tht_ps_onqueue) { - t->tht_ps_onqueue = 1 + !!restart; - TAILQ_INSERT_TAIL(&pending_save_queue, t, tht_ps_link); - transport_ref(t); - pthread_cond_signal(&pending_save_cond); - } else if(restart) { - t->tht_ps_onqueue = 2; // upgrade to restart too - } - - pthread_mutex_unlock(&pending_save_mutex); -} - - -/** - * - */ -static void * -transport_saver(void *aux) -{ - th_transport_t *t; - int restart; - pthread_mutex_lock(&pending_save_mutex); - - while(1) { - - if((t = TAILQ_FIRST(&pending_save_queue)) == NULL) { - pthread_cond_wait(&pending_save_cond, &pending_save_mutex); - continue; - } - assert(t->tht_ps_onqueue != 0); - restart = t->tht_ps_onqueue == 2; - - TAILQ_REMOVE(&pending_save_queue, t, tht_ps_link); - t->tht_ps_onqueue = 0; - - pthread_mutex_unlock(&pending_save_mutex); - pthread_mutex_lock(&global_lock); - - if(t->tht_status != TRANSPORT_ZOMBIE) - t->tht_config_save(t); - if(t->tht_status == TRANSPORT_RUNNING && restart) { - pthread_mutex_lock(&t->tht_stream_mutex); - transport_restart(t, 1); - pthread_mutex_unlock(&t->tht_stream_mutex); - } - transport_unref(t); - - pthread_mutex_unlock(&global_lock); - pthread_mutex_lock(&pending_save_mutex); - } - return NULL; -} - - -/** - * - */ -void -transport_init(void) -{ - pthread_t tid; - TAILQ_INIT(&pending_save_queue); - pthread_mutex_init(&pending_save_mutex, NULL); - pthread_cond_init(&pending_save_cond, NULL); - pthread_create(&tid, NULL, transport_saver, NULL); -} - - -/** - * - */ -void -transport_source_info_free(struct source_info *si) -{ - free(si->si_device); - free(si->si_adapter); - free(si->si_network); - free(si->si_mux); - free(si->si_provider); - free(si->si_service); -} - - -void -transport_source_info_copy(source_info_t *dst, const source_info_t *src) -{ -#define COPY(x) dst->si_##x = src->si_##x ? strdup(src->si_##x) : NULL - COPY(device); - COPY(adapter); - COPY(network); - COPY(mux); - COPY(provider); - COPY(service); -#undef COPY -} - - -/** - * - */ -const char * -transport_nicename(th_transport_t *t) -{ - return t->tht_nicename; -} - -const char * -transport_component_nicename(th_stream_t *st) -{ - return st->st_nicename; -} - -const char * -transport_tss2text(int flags) -{ - if(flags & TSS_NO_ACCESS) - return "No access"; - - if(flags & TSS_NO_DESCRAMBLER) - return "No descrambler"; - - if(flags & TSS_PACKETS) - return "Got valid packets"; - - if(flags & TSS_MUX_PACKETS) - return "Got multiplexed packets but could not decode further"; - - if(flags & TSS_INPUT_SERVICE) - return "Got packets for this service but could not decode further"; - - if(flags & TSS_INPUT_HARDWARE) - return "Sensed input from hardware but nothing for the service"; - - if(flags & TSS_GRACEPERIOD) - return "No input detected"; - - return "No status"; -} - - -/** - * - */ -int -tss2errcode(int tss) -{ - if(tss & TSS_NO_ACCESS) - return SM_CODE_NO_ACCESS; - - if(tss & TSS_NO_DESCRAMBLER) - return SM_CODE_NO_DESCRAMBLER; - - if(tss & TSS_GRACEPERIOD) - return SM_CODE_NO_INPUT; - - return SM_CODE_OK; -} - - -/** - * - */ -void -transport_refresh_channel(th_transport_t *t) -{ - if(t->tht_ch != NULL) - htsp_channel_update(t->tht_ch); -} - - -/** - * Get the encryption CAID from a transport - * only the first CA stream in a transport is returned - */ -uint16_t -transport_get_encryption(th_transport_t *t) -{ - th_stream_t *st; - caid_t *c; - - TAILQ_FOREACH(st, &t->tht_components, st_link) { - switch(st->st_type) { - case SCT_CA: - LIST_FOREACH(c, &st->st_caids, link) - if(c->caid != 0) - return c->caid; - break; - default: - break; - } - } - return 0; -} - - -/** - * Get the signal status from a transport - */ -int -transport_get_signal_status(th_transport_t *t, signal_status_t *status) -{ - // get signal status from the transport - switch(t->tht_type) { - case TRANSPORT_DVB: - return dvb_transport_get_signal_status(t, status); - default: - return -1; - } -} - diff --git a/src/transports.h b/src/transports.h deleted file mode 100644 index ee5767a4..00000000 --- a/src/transports.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * tvheadend, transport functions - * Copyright (C) 2007 Andreas Öman - * - * 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 - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef TRANSPORTS_H -#define TRANSPORTS_H - -#define PID_TELETEXT_BASE 0x2000 - -#include "channels.h" -#include "htsmsg.h" -#include "subscriptions.h" - -void transport_init(void); - -unsigned int transport_compute_weight(struct th_transport_list *head); - -int transport_start(th_transport_t *t, unsigned int weight, int force_start); - -th_transport_t *transport_create(const char *identifier, int type, - int source_type); - -void transport_unref(th_transport_t *t); - -void transport_ref(th_transport_t *t); - -th_transport_t *transport_find_by_identifier(const char *identifier); - -void transport_map_channel(th_transport_t *t, channel_t *ch, int save); - -th_transport_t *transport_find(channel_t *ch, unsigned int weight, - const char *loginfo, int *errorp, - th_transport_t *skip); - -th_stream_t *transport_stream_find(th_transport_t *t, int pid); - -th_stream_t *transport_stream_create(th_transport_t *t, int pid, - streaming_component_type_t type); - -void transport_set_priority(th_transport_t *t, int prio); - -void transport_settings_write(th_transport_t *t); - -const char *transport_servicetype_txt(th_transport_t *t); - -int transport_is_tv(th_transport_t *t); - -void transport_destroy(th_transport_t *t); - -void transport_remove_subscriber(th_transport_t *t, th_subscription_t *s, - int reason); - -void transport_set_streaming_status_flags(th_transport_t *t, int flag); - -struct streaming_start; -struct streaming_start *transport_build_stream_start(th_transport_t *t); - -void transport_set_enable(th_transport_t *t, int enabled); - -void transport_restart(th_transport_t *t, int had_components); - -void transport_stream_destroy(th_transport_t *t, th_stream_t *st); - -void transport_request_save(th_transport_t *t, int restart); - -void transport_source_info_free(source_info_t *si); - -void transport_source_info_copy(source_info_t *dst, const source_info_t *src); - -void transport_make_nicename(th_transport_t *t); - -const char *transport_nicename(th_transport_t *t); - -const char *transport_component_nicename(th_stream_t *st); - -const char *transport_tss2text(int flags); - -static inline int transport_tss_is_error(int flags) -{ - return flags & TSS_ERRORS ? 1 : 0; -} - -void transport_refresh_channel(th_transport_t *t); - -int tss2errcode(int tss); - -uint16_t transport_get_encryption(th_transport_t *t); - -int transport_get_signal_status(th_transport_t *t, signal_status_t *status); - -#endif /* TRANSPORTS_H */ diff --git a/src/tsdemux.c b/src/tsdemux.c index 3a686809..e02bcc12 100644 --- a/src/tsdemux.c +++ b/src/tsdemux.c @@ -34,14 +34,13 @@ #include "tvheadend.h" #include "teletext.h" -#include "transports.h" #include "subscriptions.h" #include "psi.h" #include "tsdemux.h" #include "parsers.h" #include "streaming.h" -static void ts_remux(th_transport_t *t, const uint8_t *tsb); +static void ts_remux(service_t *t, const uint8_t *tsb); /** * Code for dealing with a complete section @@ -51,10 +50,10 @@ got_section(const uint8_t *data, size_t len, void *opaque) { th_descrambler_t *td; th_stream_t *st = opaque; - th_transport_t *t = st->st_transport; + service_t *t = st->st_service; if(st->st_type == SCT_CA) { - LIST_FOREACH(td, &t->tht_descramblers, td_transport_link) + LIST_FOREACH(td, &t->s_descramblers, td_service_link) td->td_table(td, t, st, data, len); } else if(st->st_got_section != NULL) { st->st_got_section(t, st, data, len); @@ -66,13 +65,13 @@ got_section(const uint8_t *data, size_t len, void *opaque) * Continue processing of transport stream packets */ static void -ts_recv_packet0(th_transport_t *t, th_stream_t *st, const uint8_t *tsb) +ts_recv_packet0(service_t *t, th_stream_t *st, const uint8_t *tsb) { int off, pusi, cc, error; - transport_set_streaming_status_flags(t, TSS_MUX_PACKETS); + service_set_streaming_status_flags(t, TSS_MUX_PACKETS); - if(streaming_pad_probe_type(&t->tht_streaming_pad, SMT_MPEGTS)) + if(streaming_pad_probe_type(&t->s_streaming_pad, SMT_MPEGTS)) ts_remux(t, tsb); error = !!(tsb[1] & 0x80); @@ -84,9 +83,9 @@ ts_recv_packet0(th_transport_t *t, th_stream_t *st, const uint8_t *tsb) cc = tsb[3] & 0xf; if(st->st_cc_valid && cc != st->st_cc) { /* Incorrect CC */ - limitedlog(&st->st_loglimit_cc, "TS", transport_component_nicename(st), + limitedlog(&st->st_loglimit_cc, "TS", service_component_nicename(st), "Continuity counter error"); - avgstat_add(&t->tht_cc_errors, 1, dispatch_clock); + avgstat_add(&t->s_cc_errors, 1, dispatch_clock); avgstat_add(&st->st_cc_errors, 1, dispatch_clock); // Mark as error if this is not the first packet of a payload @@ -119,7 +118,7 @@ ts_recv_packet0(th_transport_t *t, th_stream_t *st, const uint8_t *tsb) if(off > 188) break; - if(t->tht_status == TRANSPORT_RUNNING) + if(t->s_status == SERVICE_RUNNING) parse_mpeg_ts(t, st, tsb + off, 188 - off, pusi, error); break; } @@ -132,7 +131,7 @@ ts_recv_packet0(th_transport_t *t, th_stream_t *st, const uint8_t *tsb) * than the stream PCR */ static void -ts_extract_pcr(th_transport_t *t, th_stream_t *st, const uint8_t *tsb, +ts_extract_pcr(service_t *t, th_stream_t *st, const uint8_t *tsb, int64_t *pcrp) { int64_t real, pcr, d; @@ -167,11 +166,11 @@ ts_extract_pcr(th_transport_t *t, th_stream_t *st, const uint8_t *tsb, st->st_pcr_recovery_fails = 0; st->st_pcr_drift += d; - if(t->tht_pcr_pid == st->st_pid) { - /* This is the registered PCR PID, adjust transport PCR drift + if(t->s_pcr_pid == st->st_pid) { + /* This is the registered PCR PID, adjust service PCR drift via an IIR filter */ - t->tht_pcr_drift = (t->tht_pcr_drift * 255 + st->st_pcr_drift) / 256; + t->s_pcr_drift = (t->s_pcr_drift * 255 + st->st_pcr_drift) / 256; } } st->st_pcr_last = pcr; @@ -179,67 +178,67 @@ ts_extract_pcr(th_transport_t *t, th_stream_t *st, const uint8_t *tsb, } /** - * Process transport stream packets, extract PCR and optionally descramble + * Process service stream packets, extract PCR and optionally descramble */ void -ts_recv_packet1(th_transport_t *t, const uint8_t *tsb, int64_t *pcrp) +ts_recv_packet1(service_t *t, const uint8_t *tsb, int64_t *pcrp) { th_stream_t *st; int pid, n, m, r; th_descrambler_t *td; int error = 0; - if(t->tht_status != TRANSPORT_RUNNING) + if(t->s_status != SERVICE_RUNNING) return; - pthread_mutex_lock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); - transport_set_streaming_status_flags(t, TSS_INPUT_HARDWARE); + service_set_streaming_status_flags(t, TSS_INPUT_HARDWARE); if(tsb[1] & 0x80) { /* Transport Error Indicator */ - limitedlog(&t->tht_loglimit_tei, "TS", transport_nicename(t), + limitedlog(&t->s_loglimit_tei, "TS", service_nicename(t), "Transport error indicator"); error = 1; } pid = (tsb[1] & 0x1f) << 8 | tsb[2]; - st = transport_stream_find(t, pid); + st = service_stream_find(t, pid); /* Extract PCR */ if(tsb[3] & 0x20 && tsb[4] > 0 && tsb[5] & 0x10 && !error) ts_extract_pcr(t, st, tsb, pcrp); if(st == NULL) { - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_unlock(&t->s_stream_mutex); return; } if(!error) - transport_set_streaming_status_flags(t, TSS_INPUT_SERVICE); + service_set_streaming_status_flags(t, TSS_INPUT_SERVICE); - avgstat_add(&t->tht_rate, 188, dispatch_clock); + avgstat_add(&t->s_rate, 188, dispatch_clock); if((tsb[3] & 0xc0) || - (t->tht_scrambled_seen && st->st_type != SCT_CA && + (t->s_scrambled_seen && st->st_type != SCT_CA && st->st_type != SCT_PAT && st->st_type != SCT_PMT)) { /** * Lock for descrambling, but only if packet was not in error */ if(!error) - t->tht_scrambled_seen = t->tht_scrambled; + t->s_scrambled_seen = t->s_scrambled; /* scrambled stream */ n = m = 0; - LIST_FOREACH(td, &t->tht_descramblers, td_transport_link) { + LIST_FOREACH(td, &t->s_descramblers, td_service_link) { n++; r = td->td_descramble(td, t, st, tsb); if(r == 0) { - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_unlock(&t->s_stream_mutex); return; } @@ -249,16 +248,16 @@ ts_recv_packet1(th_transport_t *t, const uint8_t *tsb, int64_t *pcrp) if(!error) { if(n == 0) { - transport_set_streaming_status_flags(t, TSS_NO_DESCRAMBLER); + service_set_streaming_status_flags(t, TSS_NO_DESCRAMBLER); } else if(m == n) { - transport_set_streaming_status_flags(t, TSS_NO_ACCESS); + service_set_streaming_status_flags(t, TSS_NO_ACCESS); } } } else { ts_recv_packet0(t, st, tsb); } - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_unlock(&t->s_stream_mutex); } @@ -266,12 +265,12 @@ ts_recv_packet1(th_transport_t *t, const uint8_t *tsb, int64_t *pcrp) * Process transport stream packets, simple version */ void -ts_recv_packet2(th_transport_t *t, const uint8_t *tsb) +ts_recv_packet2(service_t *t, const uint8_t *tsb) { th_stream_t *st; int pid = (tsb[1] & 0x1f) << 8 | tsb[2]; - if((st = transport_stream_find(t, pid)) != NULL) + if((st = service_stream_find(t, pid)) != NULL) ts_recv_packet0(t, st, tsb); } @@ -280,7 +279,7 @@ ts_recv_packet2(th_transport_t *t, const uint8_t *tsb) * */ static void -ts_remux(th_transport_t *t, const uint8_t *src) +ts_remux(service_t *t, const uint8_t *src) { uint8_t tsb[188]; memcpy(tsb, src, 188); @@ -288,5 +287,5 @@ ts_remux(th_transport_t *t, const uint8_t *src) streaming_message_t sm; sm.sm_type = SMT_MPEGTS; sm.sm_data = tsb; - streaming_pad_deliver(&t->tht_streaming_pad, &sm); + streaming_pad_deliver(&t->s_streaming_pad, &sm); } diff --git a/src/tsdemux.h b/src/tsdemux.h index 17e4176f..77f1b4dd 100644 --- a/src/tsdemux.h +++ b/src/tsdemux.h @@ -19,8 +19,8 @@ #ifndef TSDEMUX_H #define TSDEMUX_H -void ts_recv_packet1(th_transport_t *t, const uint8_t *tsb, int64_t *pcrp); +void ts_recv_packet1(struct service *t, const uint8_t *tsb, int64_t *pcrp); -void ts_recv_packet2(th_transport_t *t, const uint8_t *tsb); +void ts_recv_packet2(struct service *t, const uint8_t *tsb); #endif /* TSDEMUX_H */ diff --git a/src/tsmux.c b/src/tsmux.c index 014674c0..ebdae3ce 100644 --- a/src/tsmux.c +++ b/src/tsmux.c @@ -193,11 +193,11 @@ ts_check_deliver(tsmuxer_t *tsm, tsmuxer_es_t *te) if(ts->ts_pcr_start == AV_NOPTS_VALUE) return; /* dont know anything yet */ - ts->ts_pcr_ref = now - ts->ts_pcr_start + t->tht_pcr_drift; + ts->ts_pcr_ref = now - ts->ts_pcr_start + t->s_pcr_drift; } f = TAILQ_FIRST(&tmf->tmf_queue); /* next packet we are going to send */ - next = f->tm_deadline + ts->ts_pcr_ref - t->tht_pcr_drift; + next = f->tm_deadline + ts->ts_pcr_ref - t->s_pcr_drift; if(next < now + 100) next = now + 100; @@ -691,7 +691,7 @@ ts_muxer_send_packet(ts_muxer_t *ts) int i; int64_t t, tlow, pcr; uint8_t *d; - th_transport_t *tr; + service_t *tr; if(ts->ts_block == 0) return; @@ -706,7 +706,7 @@ ts_muxer_send_packet(ts_muxer_t *ts) if((d[3] & 0xf0) == 0x30 && d[4] >= 7 && d[5] & 0x10) { tr = ts->ts_muxer->tm_subscription->ths_transport; - pcr = getclock_hires() - ts->ts_pcr_ref - tr->tht_pcr_drift; + pcr = getclock_hires() - ts->ts_pcr_ref - tr->s_pcr_drift; t = av_rescale_q(pcr, AV_TIME_BASE_Q, mpeg_tc_27M); tlow = t % 300LL; t = t / 300LL; @@ -802,7 +802,7 @@ ts_muxer_generate_tables(void *aux, int64_t now) { ts_muxer_t *ts = aux; th_muxer_t *tm = ts->ts_muxer; - th_transport_t *t; + service_t *t; th_muxstream_t *tms; uint8_t table[180]; int l, pcrpid; @@ -824,7 +824,7 @@ ts_muxer_generate_tables(void *aux, int64_t now) t = tm->tm_subscription->ths_transport; LIST_FOREACH(tms, &tm->tm_streams, tms_muxer_link0) - if(tms->tms_stream->st_pid == t->tht_pcr_pid) + if(tms->tms_stream->st_pid == t->s_pcr_pid) break; pcrpid = tms ? tms->tms_index : 0x1fff; @@ -905,11 +905,11 @@ ts_deliver(void *opaque, int64_t now) { th_muxstream_t *tms = opaque; th_muxer_t *tm = tms->tms_muxer; - th_transport_t *t = tm->tm_subscription->ths_transport; + service_t *t = tm->tm_subscription->ths_transport; ts_muxer_t *ts = tm->tm_opaque; th_muxpkt_t *f; th_muxfifo_t *tmf = &tms->tms_delivery_fifo; - int64_t pcr = now - ts->ts_pcr_ref - t->tht_pcr_drift; + int64_t pcr = now - ts->ts_pcr_ref - t->s_pcr_drift; int64_t dl, next, delta; f = tmf_deq(tmf); @@ -928,7 +928,7 @@ ts_deliver(void *opaque, int64_t now) return; } - next = f->tm_deadline + ts->ts_pcr_ref - t->tht_pcr_drift; + next = f->tm_deadline + ts->ts_pcr_ref - t->s_pcr_drift; if(next < now + 100) next = now + 100; @@ -949,7 +949,7 @@ ts_check_deliver(ts_muxer_t *ts, th_muxstream_t *tms) int64_t now; th_muxpkt_t *f; th_muxfifo_t *tmf = &tms->tms_delivery_fifo; - th_transport_t *t = ts->ts_muxer->tm_subscription->ths_transport; + service_t *t = ts->ts_muxer->tm_subscription->ths_transport; int64_t next; if(dtimer_isarmed(&tms->tms_mux_timer)) @@ -964,11 +964,11 @@ ts_check_deliver(ts_muxer_t *ts, th_muxstream_t *tms) if(ts->ts_pcr_start == AV_NOPTS_VALUE) return; /* dont know anything yet */ - ts->ts_pcr_ref = now - ts->ts_pcr_start + t->tht_pcr_drift; + ts->ts_pcr_ref = now - ts->ts_pcr_start + t->s_pcr_drift; } f = TAILQ_FIRST(&tmf->tmf_queue); /* next packet we are going to send */ - next = f->tm_deadline + ts->ts_pcr_ref - t->tht_pcr_drift; + next = f->tm_deadline + ts->ts_pcr_ref - t->s_pcr_drift; if(next < now + 100) next = now + 100; @@ -1367,7 +1367,7 @@ ts_muxer_play(ts_muxer_t *ts, int64_t toffset) th_subscription_t *s = ts->ts_muxer->tm_subscription; if(!(ts->ts_flags & TS_SEEK) && - s->ths_transport->tht_source_type == THT_MPEG_TS) { + s->ths_transport->s_source_type == S_MPEG_TS) { /* We dont need to seek and source is MPEG TS, we can use a shortcut to avoid remuxing stream */ diff --git a/src/tvheadend.h b/src/tvheadend.h index 318d3d83..95dbc6a9 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -107,9 +107,9 @@ RB_HEAD(event_tree, event); LIST_HEAD(dvr_config_list, dvr_config); LIST_HEAD(dvr_entry_list, dvr_entry); TAILQ_HEAD(ref_update_queue, ref_update); -LIST_HEAD(th_transport_list, th_transport); -RB_HEAD(th_transport_tree, th_transport); -TAILQ_HEAD(th_transport_queue, th_transport); +LIST_HEAD(service_list, service); +RB_HEAD(service_tree, service); +TAILQ_HEAD(service_queue, service); LIST_HEAD(th_stream_list, th_stream); TAILQ_HEAD(th_stream_queue, th_stream); LIST_HEAD(th_muxer_list, th_muxer); @@ -222,11 +222,11 @@ typedef enum { SMT_START, /** - * Transport status + * Service status * * Notification about status of source, see TSS_ flags */ - SMT_TRANSPORT_STATUS, + SMT_SERVICE_STATUS, /** * Streaming stop. @@ -275,7 +275,7 @@ typedef enum { #define SM_CODE_SVC_NOT_ENABLED 204 #define SM_CODE_BAD_SIGNAL 205 #define SM_CODE_NO_SOURCE 206 -#define SM_CODE_NO_TRANSPORT 207 +#define SM_CODE_NO_SERVICE 207 #define SM_CODE_ABORTED 300 @@ -339,461 +339,6 @@ typedef struct sbuf { -/** - * Descrambler superclass - * - * Created/Destroyed on per-transport basis upon transport start/stop - */ -typedef struct th_descrambler { - LIST_ENTRY(th_descrambler) td_transport_link; - - void (*td_table)(struct th_descrambler *d, struct th_transport *t, - struct th_stream *st, - const uint8_t *section, int section_len); - - int (*td_descramble)(struct th_descrambler *d, struct th_transport *t, - struct th_stream *st, const uint8_t *tsb); - - void (*td_stop)(struct th_descrambler *d); - -} th_descrambler_t; - - - -/* - * Section callback, called when a PSI table is fully received - */ -typedef void (pid_section_callback_t)(struct th_transport *t, - struct th_stream *pi, - const uint8_t *section, int section_len); - -LIST_HEAD(caid_list, caid); -/** - * - */ -typedef struct caid { - LIST_ENTRY(caid) link; - - uint8_t delete_me; - uint16_t caid; - uint32_t providerid; - -} caid_t; - -/* - * Stream, one media component for a transport. - * - * XXX: This should be renamed to 'elementary_stream' or something - */ -typedef struct th_stream { - - TAILQ_ENTRY(th_stream) st_link; - int st_position; - struct th_transport *st_transport; - - streaming_component_type_t st_type; - int st_index; - - uint16_t st_aspect_num; - uint16_t st_aspect_den; - - char st_lang[4]; /* ISO 639 3-letter language code */ - uint16_t st_composition_id; - uint16_t st_ancillary_id; - - int16_t st_pid; - uint16_t st_parent_pid; /* For subtitle streams originating from - a teletext stream. this is the pid - of the teletext stream */ - - uint8_t st_cc; /* Last CC */ - uint8_t st_cc_valid; /* Is CC valid at all? */ - - avgstat_t st_cc_errors; - avgstat_t st_rate; - - int st_demuxer_fd; - int st_peak_presentation_delay; /* Max seen diff. of DTS and PTS */ - - struct psi_section *st_section; - int st_section_docrc; /* Set if we should verify CRC on tables */ - pid_section_callback_t *st_got_section; - void *st_got_section_opaque; - - /* PCR recovery */ - - int st_pcr_recovery_fails; - int64_t st_pcr_real_last; /* realtime clock when we saw last PCR */ - int64_t st_pcr_last; /* PCR clock when we saw last PCR */ - int64_t st_pcr_drift; - - /* For transport stream packet reassembly */ - - sbuf_t st_buf; - - uint32_t st_startcond; - uint32_t st_startcode; - uint32_t st_startcode_offset; - int st_parser_state; - int st_parser_ptr; - void *st_priv; /* Parser private data */ - - sbuf_t st_buf_ps; // program stream reassembly (analogue adapters) - sbuf_t st_buf_a; // Audio packet reassembly - - uint8_t *st_global_data; - int st_global_data_len; - int st_incomplete; - int st_ssc_intercept; - int st_ssc_ptr; - uint8_t st_ssc_buf[32]; - - struct th_pkt *st_curpkt; - int64_t st_curpts; - int64_t st_curdts; - int64_t st_prevdts; - int64_t st_nextdts; - int st_frame_duration; - int st_width; - int st_height; - - int st_meta_change; - - /* CA ID's on this stream */ - struct caid_list st_caids; - - int st_vbv_size; /* Video buffer size (in bytes) */ - int st_vbv_delay; /* -1 if CBR */ - - /* */ - - int st_delete_me; /* Temporary flag for deleting streams */ - - /* Error log limiters */ - - loglimiter_t st_loglimit_cc; - loglimiter_t st_loglimit_pes; - - char *st_nicename; - - /* Teletext subtitle */ - char st_blank; // Last subtitle was blank - - -} th_stream_t; - - -/** - * A Transport (or in MPEG TS terms: a 'service') - */ -typedef struct th_transport { - - LIST_ENTRY(th_transport) tht_hash_link; - - enum { - TRANSPORT_DVB, - TRANSPORT_IPTV, - TRANSPORT_V4L, - } tht_type; - - enum { - /** - * Transport is idle. - */ - TRANSPORT_IDLE, - - /** - * Transport producing output - */ - TRANSPORT_RUNNING, - - /** - * Destroyed, but pointer is till valid. - * This would be the case if transport_destroy() did not actually free - * the transport because there are references held to it. - * - * Reference counts can be used so that code can hold a pointer to - * a transport without having the global lock. - * - * Note: No fields in the transport may be accessed without the - * global lock held. Thus, the global_lock must be reaquired and - * then tht_status must be checked. If it is ZOMBIE the code must - * just drop the refcount and pretend that the transport never - * was there in the first place. - */ - TRANSPORT_ZOMBIE, - } tht_status; - - /** - * Refcount, operated using atomic.h ops. - */ - int tht_refcount; - - /** - * - */ - int tht_flags; - -#define THT_DEBUG 0x1 - - /** - * Source type is used to determine if an output requesting - * MPEG-TS can shortcut all the parsing and remuxing. - */ - enum { - THT_MPEG_TS, - THT_OTHER, - } tht_source_type; - - - /** - * PID carrying the programs PCR. - * XXX: We don't support transports that does not carry - * the PCR in one of the content streams. - */ - uint16_t tht_pcr_pid; - - /** - * PID for the PMT of this MPEG-TS stream. - */ - uint16_t tht_pmt_pid; - - /** - * Set if transport is enabled (the default). If disabled it should - * not be considered when chasing for available transports during - * subscription scheduling. - */ - int tht_enabled; - - /** - * Last PCR seen, we use it for a simple clock for rawtsinput.c - */ - int64_t tht_pcr_last; - int64_t tht_pcr_last_realtime; - - LIST_ENTRY(th_transport) tht_group_link; - - LIST_ENTRY(th_transport) tht_active_link; - - LIST_HEAD(, th_subscription) tht_subscriptions; - - int (*tht_start_feed)(struct th_transport *t, unsigned int weight, - int force_start); - - void (*tht_refresh_feed)(struct th_transport *t); - - void (*tht_stop_feed)(struct th_transport *t); - - void (*tht_config_save)(struct th_transport *t); - - void (*tht_setsourceinfo)(struct th_transport *t, struct source_info *si); - - int (*tht_quality_index)(struct th_transport *t); - - int (*tht_grace_period)(struct th_transport *t); - - void (*tht_dtor)(struct th_transport *t); - - /* - * Per source type structs - */ - struct th_dvb_mux_instance *tht_dvb_mux_instance; - - /** - * Unique identifer (used for storing on disk, etc) - */ - char *tht_identifier; - - /** - * Name usable for displaying to user - */ - char *tht_nicename; - - /** - * Service ID according to EN 300 468 - */ - uint16_t tht_dvb_service_id; - - uint16_t tht_channel_number; - - /** - * Service name (eg. DVB service name as specified by EN 300 468) - */ - char *tht_svcname; - - /** - * Provider name (eg. DVB provider name as specified by EN 300 468) - */ - char *tht_provider; - - enum { - /* Service types defined in EN 300 468 */ - - ST_SDTV = 0x1, /* SDTV (MPEG2) */ - ST_RADIO = 0x2, - ST_HDTV = 0x11, /* HDTV (MPEG2) */ - ST_AC_SDTV = 0x16, /* Advanced codec SDTV */ - ST_AC_HDTV = 0x19, /* Advanced codec HDTV */ - } tht_servicetype; - - - /** - * Teletext... - */ - th_commercial_advice_t tht_tt_commercial_advice; - int tht_tt_rundown_content_length; - time_t tht_tt_clock; /* Network clock as determined by teletext decoder */ - - /** - * Channel mapping - */ - LIST_ENTRY(th_transport) tht_ch_link; - struct channel *tht_ch; - - /** - * Service probe, see serviceprobe.c for details - */ - int tht_sp_onqueue; - TAILQ_ENTRY(th_transport) tht_sp_link; - - /** - * Pending save. - * - * transport_request_save() will enqueue the transport here. - * We need to do this if we don't hold the global lock. - * This happens when we update PMT from within the TS stream itself. - * Then we hold the stream mutex, and thus, can not obtain the global lock - * as it would cause lock inversion. - */ - int tht_ps_onqueue; - TAILQ_ENTRY(th_transport) tht_ps_link; - - /** - * Timer which is armed at transport start. Once it fires - * it will check if any packets has been parsed. If not the status - * will be set to TRANSPORT_STATUS_NO_INPUT - */ - gtimer_t tht_receive_timer; - - /** - * IPTV members - */ - char *tht_iptv_iface; - struct in_addr tht_iptv_group; - struct in6_addr tht_iptv_group6; - uint16_t tht_iptv_port; - int tht_iptv_fd; - - /** - * For per-transport PAT/PMT parsers, allocated on demand - * Free'd by transport_destroy - */ - struct psi_section *tht_pat_section; - struct psi_section *tht_pmt_section; - - /** - * V4l members - */ - - struct v4l_adapter *tht_v4l_adapter; - int tht_v4l_frequency; // In Hz - - - /********************************************************* - * - * Streaming part of transport - * - * All access to fields below this must be protected with - * tht_stream_mutex held. - * - * Note: Code holding tht_stream_mutex should _never_ - * acquire global_lock while already holding tht_stream_mutex. - * - */ - - /** - * Mutex to be held during streaming. - * This mutex also protects all th_stream_t instances for this - * transport. - */ - pthread_mutex_t tht_stream_mutex; - - - /** - * Condition variable to singal when streaming_status changes - * interlocked with tht_stream_mutex - */ - pthread_cond_t tht_tss_cond; - /** - * - */ - int tht_streaming_status; - - // Progress -#define TSS_INPUT_HARDWARE 0x1 -#define TSS_INPUT_SERVICE 0x2 -#define TSS_MUX_PACKETS 0x4 -#define TSS_PACKETS 0x8 - -#define TSS_GRACEPERIOD 0x8000 - - // Errors -#define TSS_NO_DESCRAMBLER 0x10000 -#define TSS_NO_ACCESS 0x20000 - -#define TSS_ERRORS 0xffff0000 - - - /** - * For simple streaming sources (such as video4linux) keeping - * track of the video and audio stream is convenient. - */ - th_stream_t *tht_video; - th_stream_t *tht_audio; - - /** - * Average continuity errors - */ - avgstat_t tht_cc_errors; - - /** - * Average bitrate - */ - avgstat_t tht_rate; - - /** - * Descrambling support - */ - - struct th_descrambler_list tht_descramblers; - int tht_scrambled; - int tht_scrambled_seen; - int tht_caid; - - /** - * PCR drift compensation. This should really be per-packet. - */ - int64_t tht_pcr_drift; - - /** - * List of all components. - */ - struct th_stream_queue tht_components; - - - /** - * Delivery pad, this is were we finally deliver all streaming output - */ - streaming_pad_t tht_streaming_pad; - - - loglimiter_t tht_loglimit_tei; - - - int64_t tht_current_pts; - -} th_transport_t; - const char *streaming_component_type2txt(streaming_component_type_t s); static inline unsigned int tvh_strhash(const char *s, unsigned int mod) @@ -846,7 +391,7 @@ int rate_to_sri(int rate); extern time_t dispatch_clock; -extern struct th_transport_list all_transports; +extern struct service_list all_transports; extern struct channel_tree channel_name_tree; extern void scopedunlock(pthread_mutex_t **mtxp); diff --git a/src/v4l.c b/src/v4l.c index 7fb52217..8cabc848 100644 --- a/src/v4l.c +++ b/src/v4l.c @@ -34,12 +34,12 @@ #include "settings.h" #include "tvheadend.h" -#include "transports.h" +#include "service.h" #include "v4l.h" #include "parsers.h" #include "notify.h" #include "psi.h" - +#include "channels.h" struct v4l_adapter_queue v4l_adapters; @@ -52,7 +52,7 @@ static void v4l_adapter_notify(v4l_adapter_t *va); static void v4l_input(v4l_adapter_t *va) { - th_transport_t *t = va->va_current_transport; + service_t *t = va->va_current_service; th_stream_t *st; uint8_t buf[4000]; uint8_t *ptr, *pkt; @@ -64,9 +64,9 @@ v4l_input(v4l_adapter_t *va) ptr = buf; - pthread_mutex_lock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); - transport_set_streaming_status_flags(t, + service_set_streaming_status_flags(t, TSS_INPUT_HARDWARE | TSS_INPUT_SERVICE); while(len > 0) { @@ -79,10 +79,10 @@ v4l_input(v4l_adapter_t *va) continue; case 0x000001e0: - st = t->tht_video; + st = t->s_video; break; case 0x000001c0: - st = t->tht_audio; + st = t->s_audio; break; } @@ -101,7 +101,7 @@ v4l_input(v4l_adapter_t *va) st->st_buf_ps.sb_ptr += r; if(st->st_buf_ps.sb_ptr == l) { - transport_set_streaming_status_flags(t, TSS_MUX_PACKETS); + service_set_streaming_status_flags(t, TSS_MUX_PACKETS); parse_mpeg_ps(t, st, pkt + 6, l - 6); @@ -121,7 +121,7 @@ v4l_input(v4l_adapter_t *va) ptr++; len--; } } - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_unlock(&t->s_stream_mutex); } @@ -170,16 +170,16 @@ v4l_thread(void *aux) * */ static int -v4l_transport_start(th_transport_t *t, unsigned int weight, int force_start) +v4l_service_start(service_t *t, unsigned int weight, int force_start) { - v4l_adapter_t *va = t->tht_v4l_adapter; - int frequency = t->tht_v4l_frequency; + v4l_adapter_t *va = t->s_v4l_adapter; + int frequency = t->s_v4l_frequency; struct v4l2_frequency vf; int result; v4l2_std_id std = 0xff; int fd; - if(va->va_current_transport != NULL) + if(va->va_current_service != NULL) return 1; // Adapter busy fd = tvh_open(va->va_path, O_RDWR | O_NONBLOCK, 0); @@ -225,7 +225,7 @@ v4l_transport_start(th_transport_t *t, unsigned int weight, int force_start) va->va_fd = fd; - va->va_current_transport = t; + va->va_current_service = t; pthread_create(&va->va_thread, NULL, v4l_thread, va); v4l_adapter_notify(va); return 0; @@ -236,7 +236,7 @@ v4l_transport_start(th_transport_t *t, unsigned int weight, int force_start) * */ static void -v4l_transport_refresh(th_transport_t *t) +v4l_service_refresh(service_t *t) { } @@ -246,12 +246,12 @@ v4l_transport_refresh(th_transport_t *t) * */ static void -v4l_transport_stop(th_transport_t *t) +v4l_service_stop(service_t *t) { char c = 'q'; - v4l_adapter_t *va = t->tht_v4l_adapter; + v4l_adapter_t *va = t->s_v4l_adapter; - assert(va->va_current_transport != NULL); + assert(va->va_current_service != NULL); if(write(va->va_pipe[1], &c, 1) != 1) tvhlog(LOG_ERR, "v4l", "Unable to close video thread -- %s", @@ -262,7 +262,7 @@ v4l_transport_stop(th_transport_t *t) close(va->va_pipe[1]); close(va->va_fd); - va->va_current_transport = NULL; + va->va_current_service = NULL; v4l_adapter_notify(va); } @@ -271,25 +271,25 @@ v4l_transport_stop(th_transport_t *t) * */ static void -v4l_transport_save(th_transport_t *t) +v4l_service_save(service_t *t) { - v4l_adapter_t *va = t->tht_v4l_adapter; + v4l_adapter_t *va = t->s_v4l_adapter; htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_u32(m, "frequency", t->tht_v4l_frequency); + htsmsg_add_u32(m, "frequency", t->s_v4l_frequency); - if(t->tht_ch != NULL) { - htsmsg_add_str(m, "channelname", t->tht_ch->ch_name); + if(t->s_ch != NULL) { + htsmsg_add_str(m, "channelname", t->s_ch->ch_name); htsmsg_add_u32(m, "mapped", 1); } - pthread_mutex_lock(&t->tht_stream_mutex); - psi_save_transport_settings(m, t); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + psi_save_service_settings(m, t); + pthread_mutex_unlock(&t->s_stream_mutex); hts_settings_save(m, "v4lservices/%s/%s", - va->va_identifier, t->tht_identifier); + va->va_identifier, t->s_identifier); htsmsg_destroy(m); } @@ -299,7 +299,7 @@ v4l_transport_save(th_transport_t *t) * */ static int -v4l_transport_quality(th_transport_t *t) +v4l_service_quality(service_t *t) { return 100; } @@ -309,7 +309,7 @@ v4l_transport_quality(th_transport_t *t) * */ static int -v4l_grace_period(th_transport_t *t) +v4l_grace_period(service_t *t) { return 2; } @@ -319,14 +319,14 @@ v4l_grace_period(th_transport_t *t) * Generate a descriptive name for the source */ static void -v4l_transport_setsourceinfo(th_transport_t *t, struct source_info *si) +v4l_service_setsourceinfo(service_t *t, struct source_info *si) { char buf[64]; memset(si, 0, sizeof(struct source_info)); - si->si_adapter = strdup(t->tht_v4l_adapter->va_displayname); + si->si_adapter = strdup(t->s_v4l_adapter->va_displayname); - snprintf(buf, sizeof(buf), "%d Hz", t->tht_v4l_frequency); + snprintf(buf, sizeof(buf), "%d Hz", t->s_v4l_frequency); si->si_mux = strdup(buf); } @@ -334,10 +334,10 @@ v4l_transport_setsourceinfo(th_transport_t *t, struct source_info *si) /** * */ -th_transport_t * -v4l_transport_find(v4l_adapter_t *va, const char *id, int create) +service_t * +v4l_service_find(v4l_adapter_t *va, const char *id, int create) { - th_transport_t *t; + service_t *t; char buf[200]; int vaidlen = strlen(va->va_identifier); @@ -347,8 +347,8 @@ v4l_transport_find(v4l_adapter_t *va, const char *id, int create) if(strncmp(id, va->va_identifier, vaidlen)) return NULL; - LIST_FOREACH(t, &va->va_transports, tht_group_link) - if(!strcmp(t->tht_identifier, id)) + LIST_FOREACH(t, &va->va_services, s_group_link) + if(!strcmp(t->s_identifier, id)) return t; } @@ -363,25 +363,25 @@ v4l_transport_find(v4l_adapter_t *va, const char *id, int create) va->va_tally = MAX(atoi(id + vaidlen + 1), va->va_tally); } - t = transport_create(id, TRANSPORT_V4L, 0); + t = service_create(id, SERVICE_TYPE_V4L, 0); - t->tht_start_feed = v4l_transport_start; - t->tht_refresh_feed = v4l_transport_refresh; - t->tht_stop_feed = v4l_transport_stop; - t->tht_config_save = v4l_transport_save; - t->tht_setsourceinfo = v4l_transport_setsourceinfo; - t->tht_quality_index = v4l_transport_quality; - t->tht_grace_period = v4l_grace_period; - t->tht_iptv_fd = -1; - t->tht_v4l_adapter = va; + t->s_start_feed = v4l_service_start; + t->s_refresh_feed = v4l_service_refresh; + t->s_stop_feed = v4l_service_stop; + t->s_config_save = v4l_service_save; + t->s_setsourceinfo = v4l_service_setsourceinfo; + t->s_quality_index = v4l_service_quality; + t->s_grace_period = v4l_grace_period; + t->s_iptv_fd = -1; + t->s_v4l_adapter = va; - pthread_mutex_lock(&t->tht_stream_mutex); - transport_make_nicename(t); - t->tht_video = transport_stream_create(t, -1, SCT_MPEG2VIDEO); - t->tht_audio = transport_stream_create(t, -1, SCT_MPEG2AUDIO); - pthread_mutex_unlock(&t->tht_stream_mutex); + pthread_mutex_lock(&t->s_stream_mutex); + service_make_nicename(t); + t->s_video = service_stream_create(t, -1, SCT_MPEG2VIDEO); + t->s_audio = service_stream_create(t, -1, SCT_MPEG2AUDIO); + pthread_mutex_unlock(&t->s_stream_mutex); - LIST_INSERT_HEAD(&va->va_transports, t, tht_group_link); + LIST_INSERT_HEAD(&va->va_services, t, s_group_link); return t; } @@ -614,10 +614,10 @@ v4l_adapter_build_msg(v4l_adapter_t *va) if(va->va_devicename) htsmsg_add_str(m, "devicename", va->va_devicename); - if(va->va_current_transport != NULL) { + if(va->va_current_service != NULL) { char buf[100]; snprintf(buf, sizeof(buf), "%d Hz", - va->va_current_transport->tht_v4l_frequency); + va->va_current_service->s_v4l_frequency); htsmsg_add_str(m, "currentMux", buf); } else { htsmsg_add_str(m, "currentMux", "- inactive -"); @@ -702,7 +702,7 @@ v4l_service_create_by_msg(v4l_adapter_t *va, htsmsg_t *c, const char *name) const char *s; unsigned int u32; - th_transport_t *t = v4l_transport_find(va, name, 1); + service_t *t = v4l_service_find(va, name, 1); if(t == NULL) return; @@ -712,10 +712,10 @@ v4l_service_create_by_msg(v4l_adapter_t *va, htsmsg_t *c, const char *name) u32 = 0; if(!htsmsg_get_u32(c, "frequency", &u32)) - t->tht_v4l_frequency = u32; + t->s_v4l_frequency = u32; if(s && u32) - transport_map_channel(t, channel_find_by_name(s, 1, 0), 0); + service_map_channel(t, channel_find_by_name(s, 1, 0), 0); } /** diff --git a/src/v4l.h b/src/v4l.h index 80ad9108..e2d81182 100644 --- a/src/v4l.h +++ b/src/v4l.h @@ -46,9 +46,9 @@ typedef struct v4l_adapter { // struct v4l2_capability va_caps; - struct th_transport *va_current_transport; + struct service *va_current_service; - struct th_transport_list va_transports; + struct service_list va_services; int va_tally; /** Receiver thread stuff */ @@ -74,8 +74,8 @@ void v4l_adapter_set_logging(v4l_adapter_t *va, int on); htsmsg_t *v4l_adapter_build_msg(v4l_adapter_t *va); -th_transport_t *v4l_transport_find(v4l_adapter_t *va, const char *id, - int create); +service_t *v4l_service_find(v4l_adapter_t *va, const char *id, + int create); void v4l_init(void); diff --git a/src/webui/extjs.c b/src/webui/extjs.c index 3ab99384..35432091 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -38,7 +38,6 @@ #include "psi.h" #include "dvr/dvr.h" -#include "transports.h" #include "serviceprobe.h" #include "xmltv.h" #include "epg.h" @@ -1069,16 +1068,16 @@ extjs_dvrlist(http_connection_t *hc, const char *remain, void *opaque) * */ void -extjs_transport_delete(htsmsg_t *in) +extjs_service_delete(htsmsg_t *in) { htsmsg_field_t *f; - th_transport_t *t; + service_t *t; const char *id; TAILQ_FOREACH(f, &in->hm_fields, hmf_link) { if((id = htsmsg_field_get_string(f)) != NULL && - (t = transport_find_by_identifier(id)) != NULL) - transport_destroy(t); + (t = service_find_by_identifier(id)) != NULL) + service_destroy(t); } } @@ -1087,11 +1086,11 @@ extjs_transport_delete(htsmsg_t *in) * */ static void -transport_update(htsmsg_t *in) +service_update(htsmsg_t *in) { htsmsg_field_t *f; htsmsg_t *c; - th_transport_t *t; + service_t *t; uint32_t u32; const char *id; const char *chname; @@ -1101,14 +1100,14 @@ transport_update(htsmsg_t *in) (id = htsmsg_get_str(c, "id")) == NULL) continue; - if((t = transport_find_by_identifier(id)) == NULL) + if((t = service_find_by_identifier(id)) == NULL) continue; if(!htsmsg_get_u32(c, "enabled", &u32)) - transport_set_enable(t, u32); + service_set_enable(t, u32); if((chname = htsmsg_get_str(c, "channelname")) != NULL) - transport_map_channel(t, channel_find_by_name(chname, 1, 0), 1); + service_map_channel(t, channel_find_by_name(chname, 1, 0), 1); } } @@ -1122,21 +1121,21 @@ extjs_servicedetails(http_connection_t *hc, { htsbuf_queue_t *hq = &hc->hc_reply; htsmsg_t *out, *streams, *c; - th_transport_t *t; + service_t *t; th_stream_t *st; caid_t *ca; char buf[128]; pthread_mutex_lock(&global_lock); - if(remain == NULL || (t = transport_find_by_identifier(remain)) == NULL) { + if(remain == NULL || (t = service_find_by_identifier(remain)) == NULL) { pthread_mutex_unlock(&global_lock); return 404; } streams = htsmsg_create_list(); - TAILQ_FOREACH(st, &t->tht_components, st_link) { + TAILQ_FOREACH(st, &t->s_components, st_link) { c = htsmsg_create_map(); htsmsg_add_u32(c, "pid", st->st_pid); @@ -1186,7 +1185,7 @@ extjs_servicedetails(http_connection_t *hc, } out = htsmsg_create_map(); - htsmsg_add_str(out, "title", t->tht_svcname ?: "unnamed transport"); + htsmsg_add_str(out, "title", t->s_svcname ?: "unnamed service"); htsmsg_add_msg(out, "streams", streams); @@ -1249,11 +1248,11 @@ extjs_mergechannel(http_connection_t *hc, const char *remain, void *opaque) * */ static void -transport_update_iptv(htsmsg_t *in) +service_update_iptv(htsmsg_t *in) { htsmsg_field_t *f; htsmsg_t *c; - th_transport_t *t; + service_t *t; uint32_t u32; const char *id, *s; int save; @@ -1263,27 +1262,27 @@ transport_update_iptv(htsmsg_t *in) (id = htsmsg_get_str(c, "id")) == NULL) continue; - if((t = transport_find_by_identifier(id)) == NULL) + if((t = service_find_by_identifier(id)) == NULL) continue; save = 0; if(!htsmsg_get_u32(c, "port", &u32)) { - t->tht_iptv_port = u32; + t->s_iptv_port = u32; save = 1; } if((s = htsmsg_get_str(c, "group")) != NULL) { - if(!inet_pton(AF_INET, s, &t->tht_iptv_group.s_addr)){ - inet_pton(AF_INET6, s, &t->tht_iptv_group6.s6_addr); + if(!inet_pton(AF_INET, s, &t->s_iptv_group.s_addr)){ + inet_pton(AF_INET6, s, &t->s_iptv_group6.s6_addr); } save = 1; } - save |= tvh_str_update(&t->tht_iptv_iface, htsmsg_get_str(c, "interface")); + save |= tvh_str_update(&t->s_iptv_iface, htsmsg_get_str(c, "interface")); if(save) - t->tht_config_save(t); // Save config + t->s_config_save(t); // Save config } } @@ -1293,27 +1292,27 @@ transport_update_iptv(htsmsg_t *in) * */ static htsmsg_t * -build_record_iptv(th_transport_t *t) +build_record_iptv(service_t *t) { htsmsg_t *r = htsmsg_create_map(); char abuf[INET_ADDRSTRLEN]; char abuf6[INET6_ADDRSTRLEN]; - htsmsg_add_str(r, "id", t->tht_identifier); + htsmsg_add_str(r, "id", t->s_identifier); - htsmsg_add_str(r, "channelname", t->tht_ch ? t->tht_ch->ch_name : ""); - htsmsg_add_str(r, "interface", t->tht_iptv_iface ?: ""); + htsmsg_add_str(r, "channelname", t->s_ch ? t->s_ch->ch_name : ""); + htsmsg_add_str(r, "interface", t->s_iptv_iface ?: ""); - if(t->tht_iptv_group.s_addr != 0){ - inet_ntop(AF_INET, &t->tht_iptv_group, abuf, sizeof(abuf)); - htsmsg_add_str(r, "group", t->tht_iptv_group.s_addr ? abuf : ""); + if(t->s_iptv_group.s_addr != 0){ + inet_ntop(AF_INET, &t->s_iptv_group, abuf, sizeof(abuf)); + htsmsg_add_str(r, "group", t->s_iptv_group.s_addr ? abuf : ""); } else { - inet_ntop(AF_INET6, &t->tht_iptv_group6, abuf6, sizeof(abuf6)); - htsmsg_add_str(r, "group", t->tht_iptv_group6.s6_addr ? abuf6 : ""); + inet_ntop(AF_INET6, &t->s_iptv_group6, abuf6, sizeof(abuf6)); + htsmsg_add_str(r, "group", t->s_iptv_group6.s6_addr ? abuf6 : ""); } - htsmsg_add_u32(r, "port", t->tht_iptv_port); - htsmsg_add_u32(r, "enabled", t->tht_enabled); + htsmsg_add_u32(r, "port", t->s_iptv_port); + htsmsg_add_u32(r, "enabled", t->s_enabled); return r; } @@ -1321,12 +1320,12 @@ build_record_iptv(th_transport_t *t) * */ static int -iptv_transportcmp(const void *A, const void *B) +iptv_servicecmp(const void *A, const void *B) { - th_transport_t *a = *(th_transport_t **)A; - th_transport_t *b = *(th_transport_t **)B; + service_t *a = *(service_t **)A; + service_t *b = *(service_t **)B; - return memcmp(&a->tht_iptv_group, &b->tht_iptv_group, 4); + return memcmp(&a->s_iptv_group, &b->s_iptv_group, 4); } /** @@ -1339,7 +1338,7 @@ extjs_iptvservices(http_connection_t *hc, const char *remain, void *opaque) htsmsg_t *out, *in, *array; const char *op = http_arg_get(&hc->hc_req_args, "op"); const char *entries = http_arg_get(&hc->hc_req_args, "entries"); - th_transport_t *t, **tvec; + service_t *t, **tvec; int count = 0, i = 0; pthread_mutex_lock(&global_lock); @@ -1347,16 +1346,16 @@ extjs_iptvservices(http_connection_t *hc, const char *remain, void *opaque) in = entries != NULL ? htsmsg_json_deserialize(entries) : NULL; if(!strcmp(op, "get")) { - LIST_FOREACH(t, &iptv_all_transports, tht_group_link) + LIST_FOREACH(t, &iptv_all_services, s_group_link) count++; - tvec = alloca(sizeof(th_transport_t *) * count); - LIST_FOREACH(t, &iptv_all_transports, tht_group_link) + tvec = alloca(sizeof(service_t *) * count); + LIST_FOREACH(t, &iptv_all_services, s_group_link) tvec[i++] = t; out = htsmsg_create_map(); array = htsmsg_create_list(); - qsort(tvec, count, sizeof(th_transport_t *), iptv_transportcmp); + qsort(tvec, count, sizeof(service_t *), iptv_servicecmp); for(i = 0; i < count; i++) htsmsg_add_msg(array, NULL, build_record_iptv(tvec[i])); @@ -1365,19 +1364,19 @@ extjs_iptvservices(http_connection_t *hc, const char *remain, void *opaque) } else if(!strcmp(op, "update")) { if(in != NULL) { - transport_update(in); // Generic transport parameters - transport_update_iptv(in); // IPTV speicifc + service_update(in); // Generic service parameters + service_update_iptv(in); // IPTV speicifc } out = htsmsg_create_map(); } else if(!strcmp(op, "create")) { - out = build_record_iptv(iptv_transport_find(NULL, 1)); + out = build_record_iptv(iptv_service_find(NULL, 1)); } else if(!strcmp(op, "delete")) { if(in != NULL) - extjs_transport_delete(in); + extjs_service_delete(in); out = htsmsg_create_map(); @@ -1403,11 +1402,11 @@ extjs_iptvservices(http_connection_t *hc, const char *remain, void *opaque) * */ void -extjs_transport_update(htsmsg_t *in) +extjs_service_update(htsmsg_t *in) { htsmsg_field_t *f; htsmsg_t *c; - th_transport_t *t; + service_t *t; uint32_t u32; const char *id; const char *chname; @@ -1417,14 +1416,14 @@ extjs_transport_update(htsmsg_t *in) (id = htsmsg_get_str(c, "id")) == NULL) continue; - if((t = transport_find_by_identifier(id)) == NULL) + if((t = service_find_by_identifier(id)) == NULL) continue; if(!htsmsg_get_u32(c, "enabled", &u32)) - transport_set_enable(t, u32); + service_set_enable(t, u32); if((chname = htsmsg_get_str(c, "channelname")) != NULL) - transport_map_channel(t, channel_find_by_name(chname, 1, 0), 1); + service_map_channel(t, channel_find_by_name(chname, 1, 0), 1); } } diff --git a/src/webui/extjs_dvb.c b/src/webui/extjs_dvb.c index b87804fe..c0d9c7f0 100644 --- a/src/webui/extjs_dvb.c +++ b/src/webui/extjs_dvb.c @@ -36,7 +36,6 @@ #include "dtable.h" #include "channels.h" #include "psi.h" -#include "transports.h" #include "serviceprobe.h" #include "dvb/dvb.h" @@ -113,7 +112,7 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) const char *sibling = http_arg_get(&hc->hc_req_args, "sibling"); const char *s, *sc; th_dvb_mux_instance_t *tdmi; - th_transport_t *t; + service_t *t; pthread_mutex_lock(&global_lock); @@ -204,8 +203,8 @@ extjs_dvbadapter(http_connection_t *hc, const char *remain, void *opaque) "Service probe started on \"%s\"", tda->tda_displayname); LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link) { - LIST_FOREACH(t, &tdmi->tdmi_transports, tht_group_link) { - if(t->tht_enabled) + LIST_FOREACH(t, &tdmi->tdmi_transports, s_group_link) { + if(t->s_enabled) serviceprobe_enqueue(t); } } @@ -345,10 +344,10 @@ extjs_dvbmuxes(http_connection_t *hc, const char *remain, void *opaque) static int transportcmp(const void *A, const void *B) { - th_transport_t *a = *(th_transport_t **)A; - th_transport_t *b = *(th_transport_t **)B; + service_t *a = *(service_t **)A; + service_t *b = *(service_t **)B; - return strcasecmp(a->tht_svcname ?: "\0377", b->tht_svcname ?: "\0377"); + return strcasecmp(a->s_svcname ?: "\0377", b->s_svcname ?: "\0377"); } /** @@ -363,7 +362,7 @@ extjs_dvbservices(http_connection_t *hc, const char *remain, void *opaque) const char *op = http_arg_get(&hc->hc_req_args, "op"); const char *entries = http_arg_get(&hc->hc_req_args, "entries"); th_dvb_mux_instance_t *tdmi; - th_transport_t *t, **tvec; + service_t *t, **tvec; int count = 0, i = 0; pthread_mutex_lock(&global_lock); @@ -382,20 +381,20 @@ extjs_dvbservices(http_connection_t *hc, const char *remain, void *opaque) array = htsmsg_create_list(); LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link) { - LIST_FOREACH(t, &tdmi->tdmi_transports, tht_group_link) { + LIST_FOREACH(t, &tdmi->tdmi_transports, s_group_link) { count++; } } - tvec = alloca(sizeof(th_transport_t *) * count); + tvec = alloca(sizeof(service_t *) * count); LIST_FOREACH(tdmi, &tda->tda_muxes, tdmi_adapter_link) { - LIST_FOREACH(t, &tdmi->tdmi_transports, tht_group_link) { + LIST_FOREACH(t, &tdmi->tdmi_transports, s_group_link) { tvec[i++] = t; } } - qsort(tvec, count, sizeof(th_transport_t *), transportcmp); + qsort(tvec, count, sizeof(service_t *), transportcmp); for(i = 0; i < count; i++) htsmsg_add_msg(array, NULL, dvb_transport_build_msg(tvec[i])); @@ -404,7 +403,7 @@ extjs_dvbservices(http_connection_t *hc, const char *remain, void *opaque) } else if(!strcmp(op, "update")) { if(in != NULL) - extjs_transport_update(in); + extjs_service_update(in); out = htsmsg_create_map(); diff --git a/src/webui/extjs_v4l.c b/src/webui/extjs_v4l.c index 734ad20a..f7e02630 100644 --- a/src/webui/extjs_v4l.c +++ b/src/webui/extjs_v4l.c @@ -37,7 +37,6 @@ #include "psi.h" #include "v4l.h" -#include "transports.h" #include "serviceprobe.h" @@ -133,11 +132,11 @@ extjs_v4ladapter(http_connection_t *hc, const char *remain, void *opaque) * */ static void -transport_update_v4l(htsmsg_t *in) +service_update_v4l(htsmsg_t *in) { htsmsg_field_t *f; htsmsg_t *c; - th_transport_t *t; + service_t *t; uint32_t u32; const char *id; int save; @@ -147,17 +146,17 @@ transport_update_v4l(htsmsg_t *in) (id = htsmsg_get_str(c, "id")) == NULL) continue; - if((t = transport_find_by_identifier(id)) == NULL) + if((t = service_find_by_identifier(id)) == NULL) continue; save = 0; if(!htsmsg_get_u32(c, "frequency", &u32)) { - t->tht_v4l_frequency = u32; + t->s_v4l_frequency = u32; save = 1; } if(save) - t->tht_config_save(t); // Save config + t->s_config_save(t); // Save config } } @@ -167,15 +166,15 @@ transport_update_v4l(htsmsg_t *in) * */ static htsmsg_t * -build_record_v4l(th_transport_t *t) +build_record_v4l(service_t *t) { htsmsg_t *r = htsmsg_create_map(); - htsmsg_add_str(r, "id", t->tht_identifier); + htsmsg_add_str(r, "id", t->s_identifier); - htsmsg_add_str(r, "channelname", t->tht_ch ? t->tht_ch->ch_name : ""); - htsmsg_add_u32(r, "frequency", t->tht_v4l_frequency); - htsmsg_add_u32(r, "enabled", t->tht_enabled); + htsmsg_add_str(r, "channelname", t->s_ch ? t->s_ch->ch_name : ""); + htsmsg_add_u32(r, "frequency", t->s_v4l_frequency); + htsmsg_add_u32(r, "enabled", t->s_enabled); return r; } @@ -183,12 +182,12 @@ build_record_v4l(th_transport_t *t) * */ static int -v4l_transportcmp(const void *A, const void *B) +v4l_servicecmp(const void *A, const void *B) { - th_transport_t *a = *(th_transport_t **)A; - th_transport_t *b = *(th_transport_t **)B; + service_t *a = *(service_t **)A; + service_t *b = *(service_t **)B; - return (int)a->tht_v4l_frequency - (int)b->tht_v4l_frequency; + return (int)a->s_v4l_frequency - (int)b->s_v4l_frequency; } /** @@ -202,7 +201,7 @@ extjs_v4lservices(http_connection_t *hc, const char *remain, void *opaque) htsmsg_t *out, *in, *array; const char *op = http_arg_get(&hc->hc_req_args, "op"); const char *entries = http_arg_get(&hc->hc_req_args, "entries"); - th_transport_t *t, **tvec; + service_t *t, **tvec; int count = 0, i = 0; pthread_mutex_lock(&global_lock); @@ -216,16 +215,16 @@ extjs_v4lservices(http_connection_t *hc, const char *remain, void *opaque) if(!strcmp(op, "get")) { - LIST_FOREACH(t, &va->va_transports, tht_group_link) + LIST_FOREACH(t, &va->va_services, s_group_link) count++; - tvec = alloca(sizeof(th_transport_t *) * count); - LIST_FOREACH(t, &va->va_transports, tht_group_link) + tvec = alloca(sizeof(service_t *) * count); + LIST_FOREACH(t, &va->va_services, s_group_link) tvec[i++] = t; out = htsmsg_create_map(); array = htsmsg_create_list(); - qsort(tvec, count, sizeof(th_transport_t *), v4l_transportcmp); + qsort(tvec, count, sizeof(service_t *), v4l_servicecmp); for(i = 0; i < count; i++) htsmsg_add_msg(array, NULL, build_record_v4l(tvec[i])); @@ -234,19 +233,19 @@ extjs_v4lservices(http_connection_t *hc, const char *remain, void *opaque) } else if(!strcmp(op, "update")) { if(in != NULL) { - extjs_transport_update(in); // Generic transport parameters - transport_update_v4l(in); // V4L speicifc + extjs_service_update(in); // Generic service parameters + service_update_v4l(in); // V4L speicifc } out = htsmsg_create_map(); } else if(!strcmp(op, "create")) { - out = build_record_v4l(v4l_transport_find(va, NULL, 1)); + out = build_record_v4l(v4l_service_find(va, NULL, 1)); } else if(!strcmp(op, "delete")) { if(in != NULL) - extjs_transport_delete(in); + extjs_service_delete(in); out = htsmsg_create_map(); diff --git a/src/webui/statedump.c b/src/webui/statedump.c index caa9b4bd..debae41a 100644 --- a/src/webui/statedump.c +++ b/src/webui/statedump.c @@ -36,8 +36,6 @@ #include "dvb/dvb_support.h" #endif -#include "transports.h" - extern char tvh_binshasum[20]; extern char *htsversion_full; @@ -83,16 +81,16 @@ dumpchannels(htsbuf_queue_t *hq) #if ENABLE_LINUXDVB static void -dumptransports(htsbuf_queue_t *hq, struct th_transport_list *l, int indent) +dumptransports(htsbuf_queue_t *hq, struct service_list *l, int indent) { - th_transport_t *t; + service_t *t; th_stream_t *st; outputtitle(hq, indent, "Transports (or services)"); - LIST_FOREACH(t, l, tht_group_link) { + LIST_FOREACH(t, l, s_group_link) { htsbuf_qprintf(hq, "%*.s%s (%s)\n", indent + 2, "", - transport_nicename(t), t->tht_identifier); + service_nicename(t), t->s_identifier); htsbuf_qprintf(hq, "%*.s%-16s %-5s %-5s %-5s %-5s %-10s\n", indent + 4, "", @@ -106,7 +104,7 @@ dumptransports(htsbuf_queue_t *hq, struct th_transport_list *l, int indent) htsbuf_qprintf(hq, "%*.s-------------------------------------------\n", indent + 4, ""); - TAILQ_FOREACH(st, &t->tht_components, st_link) { + TAILQ_FOREACH(st, &t->s_components, st_link) { caid_t *caid; htsbuf_qprintf(hq, "%*.s%-16s %-5d %-5d %-5s\n", indent + 4, "", streaming_component_type2txt(st->st_type), diff --git a/src/webui/webui.c b/src/webui/webui.c index 49576373..eda7f4bd 100644 --- a/src/webui/webui.c +++ b/src/webui/webui.c @@ -237,7 +237,7 @@ http_stream_run(http_connection_t *hc, streaming_queue_t *sq) run = 0; break; - case SMT_TRANSPORT_STATUS: + case SMT_SERVICE_STATUS: //printf("SMT_TRANSPORT_STATUS\n"); break; diff --git a/src/webui/webui.h b/src/webui/webui.h index 498ef6e2..5ae6a40a 100644 --- a/src/webui/webui.h +++ b/src/webui/webui.h @@ -37,9 +37,9 @@ void extjs_list_v4l_adapters(htsmsg_t *array); void extjs_start_v4l(void); #endif -void extjs_transport_update(htsmsg_t *in); +void extjs_service_update(htsmsg_t *in); -void extjs_transport_delete(htsmsg_t *in); +void extjs_service_delete(htsmsg_t *in); /**