From f991e1376e110b9c159ad465d8f7299be3a6cdac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Wed, 5 Dec 2012 13:09:41 +0100 Subject: [PATCH] Migrate tables into dvb_mux. Also let some parts of the tuning work with dvb_mux --- Makefile | 1 + src/dvb/dvb.h | 49 ++++++++++------- src/dvb/dvb_adapter.c | 21 +++----- src/dvb/dvb_fe.c | 60 +++++++++++---------- src/dvb/dvb_input_filtered.c | 36 +++++++------ src/dvb/dvb_input_raw.c | 21 ++++---- src/dvb/dvb_multiplex.c | 57 ++++++++++---------- src/dvb/dvb_network.c | 102 +++++++++++++++++++++++++++++++++++ src/dvb/dvb_service.c | 4 +- src/dvb/dvb_tables.c | 35 ++++++------ src/epggrab.h | 4 +- src/epggrab/otamux.c | 10 ++-- 12 files changed, 259 insertions(+), 141 deletions(-) create mode 100644 src/dvb/dvb_network.c diff --git a/Makefile b/Makefile index 3da26556..a4e63011 100644 --- a/Makefile +++ b/Makefile @@ -153,6 +153,7 @@ SRCS-${CONFIG_LINUXDVB} += \ src/dvb/dvb_tables.c \ src/dvb/diseqc.c \ src/dvb/dvb_adapter.c \ + src/dvb/dvb_network.c \ src/dvb/dvb_multiplex.c \ src/dvb/dvb_service.c \ src/dvb/dvb_preconf.c \ diff --git a/src/dvb/dvb.h b/src/dvb/dvb.h index 806360e4..c1bc22f9 100644 --- a/src/dvb/dvb.h +++ b/src/dvb/dvb.h @@ -40,6 +40,7 @@ TAILQ_HEAD(th_dvb_mux_instance_queue, th_dvb_mux_instance); LIST_HEAD(th_dvb_mux_instance_list, th_dvb_mux_instance); TAILQ_HEAD(dvb_satconf_queue, dvb_satconf); LIST_HEAD(dvb_mux_list, dvb_mux); +TAILQ_HEAD(dvb_mux_queue, dvb_mux); /** * Satconf @@ -90,7 +91,7 @@ typedef struct dvb_network { struct th_dvb_mux_instance_list dn_mux_instances; // Should go away - struct th_dvb_mux_instance_queue dn_initial_scan_queue; + struct dvb_mux_queue dn_initial_scan_queue; int dn_initial_num_mux; struct dvb_mux *dn_mux_epg; @@ -99,6 +100,8 @@ typedef struct dvb_network { struct dvb_mux_list dn_muxes; + gtimer_t dn_mux_scanner_timer; + } dvb_network_t; @@ -124,6 +127,17 @@ typedef struct dvb_mux { struct th_dvb_mux_instance *dm_tdmi; // wrong + TAILQ_ENTRY(dvb_mux) dm_scan_link; + struct dvb_mux_queue *dm_scan_queue; + + LIST_HEAD(, th_dvb_table) dm_tables; + int dm_num_tables; + + TAILQ_HEAD(, th_dvb_table) dm_table_queue; + int dm_table_initial; + + struct th_dvb_mux_instance *dm_current_tdmi; + } dvb_mux_t; @@ -150,11 +164,6 @@ typedef struct th_dvb_mux_instance { uint32_t tdmi_fec_err_histogram[TDMI_FEC_ERR_HISTOGRAM_SIZE]; int tdmi_fec_err_ptr; - LIST_HEAD(, th_dvb_table) tdmi_tables; - int tdmi_num_tables; - - TAILQ_HEAD(, th_dvb_table) tdmi_table_queue; - int tdmi_table_initial; enum { TDMI_FE_UNKNOWN, @@ -173,9 +182,6 @@ typedef struct th_dvb_mux_instance { char *tdmi_identifier; - TAILQ_ENTRY(th_dvb_mux_instance) tdmi_scan_link; - struct th_dvb_mux_instance_queue *tdmi_scan_queue; - struct th_subscription_list tdmi_subscriptions; } th_dvb_mux_instance_t; @@ -210,7 +216,7 @@ typedef struct th_dvb_adapter { dvb_network_t *tda_dn; - th_dvb_mux_instance_t *tda_mux_current; + th_dvb_mux_instance_t *tda_current_tdmi; char *tda_tune_reason; // Reason for last tune int tda_table_epollfd; @@ -246,8 +252,6 @@ typedef struct th_dvb_adapter { int tda_hostconnection; - gtimer_t tda_mux_scanner_timer; - pthread_mutex_t tda_delivery_mutex; struct service_list tda_transports; /* Currently bound transports */ @@ -268,8 +272,8 @@ typedef struct th_dvb_adapter { void (*tda_open_service)(struct th_dvb_adapter *tda, struct service *s); void (*tda_close_service)(struct th_dvb_adapter *tda, struct service *s); - void (*tda_open_table)(struct th_dvb_mux_instance *tdmi, struct th_dvb_table *s); - void (*tda_close_table)(struct th_dvb_mux_instance *tdmi, struct th_dvb_table *s); + void (*tda_open_table)(struct dvb_mux *dm, struct th_dvb_table *s); + void (*tda_close_table)(struct dvb_mux *dm, struct th_dvb_table *s); int tda_rawmode; @@ -346,8 +350,6 @@ void dvb_init(uint32_t adapter_mask, const char *rawfile); */ void dvb_adapter_init(uint32_t adapter_mask, const char *rawfile); -void dvb_adapter_mux_scanner(void *aux); - void dvb_adapter_start (th_dvb_adapter_t *tda); void dvb_adapter_stop (th_dvb_adapter_t *tda); @@ -493,9 +495,9 @@ htsmsg_t *dvb_service_build_msg(struct service *t); /** * DVB Frontend */ -int dvb_fe_tune(th_dvb_mux_instance_t *tdmi, const char *reason); +int dvb_fe_tune(dvb_mux_t *dm, const char *reason); -void dvb_fe_stop(th_dvb_mux_instance_t *tdmi, int retune); +void dvb_fe_stop(th_dvb_adapter_t *tda, int retune); /** @@ -505,7 +507,7 @@ void dvb_table_init(th_dvb_adapter_t *tda); void dvb_table_add_default(dvb_mux_t *dm); -void dvb_table_flush_all(th_dvb_mux_instance_t *tdmi); +void dvb_table_flush_all(dvb_mux_t *dm); void dvb_table_add_pmt(dvb_mux_t *dm, int pmt_pid); @@ -528,6 +530,15 @@ void dvb_table_dispatch(uint8_t *sec, int r, th_dvb_table_t *tdt); void dvb_table_release(th_dvb_table_t *tdt); + +/** + * + */ +dvb_network_t *dvb_network_create(int fe_type); + +void dvb_network_mux_scanner(void *aux); + + /** * Satellite configuration */ diff --git a/src/dvb/dvb_adapter.c b/src/dvb/dvb_adapter.c index d1d12bb7..eeb9b749 100644 --- a/src/dvb/dvb_adapter.c +++ b/src/dvb/dvb_adapter.c @@ -57,11 +57,7 @@ static th_dvb_adapter_t * tda_alloc(void) { th_dvb_adapter_t *tda = calloc(1, sizeof(th_dvb_adapter_t)); - dvb_network_t *dn = calloc(1, sizeof(dvb_network_t)); pthread_mutex_init(&tda->tda_delivery_mutex, NULL); - - tda->tda_dn = dn; - TAILQ_INIT(&dn->dn_initial_scan_queue); TAILQ_INIT(&tda->tda_satconfs); streaming_pad_init(&tda->tda_streaming_pad); return tda; @@ -467,7 +463,7 @@ tda_add(int adapter_num) close(fe); tda->tda_fe_type = tda->tda_fe_info->type; - tda->tda_dn->dn_fe_type = tda->tda_fe_type; + tda->tda_dn = dvb_network_create(tda->tda_fe_type); snprintf(buf, sizeof(buf), "%s_%s", tda->tda_rootpath, tda->tda_fe_info->name); @@ -495,8 +491,6 @@ tda_add(int adapter_num) hostconnection2str(tda->tda_hostconnection)); TAILQ_INSERT_TAIL(&dvb_adapters, tda, tda_global_link); - - gtimer_arm(&tda->tda_mux_scanner_timer, dvb_adapter_mux_scanner, tda, 1); } @@ -587,7 +581,7 @@ dvb_adapter_start ( th_dvb_adapter_t *tda ) void dvb_adapter_stop ( th_dvb_adapter_t *tda ) { - assert(tda->tda_mux_current == NULL); + assert(tda->tda_current_tdmi == NULL); /* Poweroff */ dvb_adapter_poweroff(tda); @@ -696,7 +690,7 @@ dvb_adapter_init(uint32_t adapter_mask, const char *rawfile) } } - +#if 0 /** * If nobody is subscribing, cycle thru all muxes to get some stats * and EIT updates @@ -757,6 +751,7 @@ dvb_adapter_mux_scanner(void *aux) if (tda->tda_mux_current) dvb_fe_stop(tda->tda_mux_current, 0); } +#endif /** * @@ -945,7 +940,7 @@ dvb_adapter_input_dvr(void *aux) } } else { LIST_FOREACH(t, &tda->tda_transports, s_active_link) - if(t->s_dvb_mux_instance == tda->tda_mux_current) + if(t->s_dvb_mux_instance == tda->tda_current_tdmi) ts_recv_packet1(t, tsb + i, NULL); } @@ -1009,10 +1004,10 @@ dvb_adapter_build_msg(th_dvb_adapter_t *tda) htsmsg_add_u32(m, "muxes", nummux); htsmsg_add_u32(m, "initialMuxes", tda->tda_dn->dn_initial_num_mux); - if(tda->tda_mux_current != NULL) { - th_dvb_mux_instance_t *tdmi = tda->tda_mux_current; + if(tda->tda_current_tdmi != NULL) { + th_dvb_mux_instance_t *tdmi = tda->tda_current_tdmi; - dvb_mux_nicename(buf, sizeof(buf), tda->tda_mux_current); + dvb_mux_nicename(buf, sizeof(buf), tda->tda_current_tdmi); htsmsg_add_str(m, "currentMux", buf); htsmsg_add_u32(m, "signal", MIN(tdmi->tdmi_signal * 100 / 65535, 100)); diff --git a/src/dvb/dvb_fe.c b/src/dvb/dvb_fe.c index 97c1c042..09d52098 100644 --- a/src/dvb/dvb_fe.c +++ b/src/dvb/dvb_fe.c @@ -91,7 +91,7 @@ dvb_fe_monitor(void *aux) th_dvb_adapter_t *tda = aux; fe_status_t fe_status; int status, v, vv, i, fec, q; - th_dvb_mux_instance_t *tdmi = tda->tda_mux_current; + th_dvb_mux_instance_t *tdmi = tda->tda_current_tdmi; char buf[50]; signal_status_t sigstat; streaming_message_t sm; @@ -245,7 +245,8 @@ dvb_fe_monitor(void *aux) sm.sm_type = SMT_SIGNAL_STATUS; sm.sm_data = &sigstat; LIST_FOREACH(t, &tda->tda_transports, s_active_link) - if(t->s_dvb_mux_instance == tda->tda_mux_current && t->s_status == SERVICE_RUNNING ) { + if(t->s_dvb_mux_instance == tda->tda_current_tdmi && + t->s_status == SERVICE_RUNNING ) { pthread_mutex_lock(&t->s_stream_mutex); streaming_pad_deliver(&t->s_streaming_pad, &sm); pthread_mutex_unlock(&t->s_stream_mutex); @@ -258,31 +259,32 @@ dvb_fe_monitor(void *aux) * Stop the given TDMI */ void -dvb_fe_stop(th_dvb_mux_instance_t *tdmi, int retune) +dvb_fe_stop(th_dvb_adapter_t *tda, int retune) { - th_dvb_adapter_t *tda = tdmi->tdmi_adapter; - lock_assert(&global_lock); - assert(tdmi == tda->tda_mux_current); - tda->tda_mux_current = NULL; + th_dvb_mux_instance_t *tdmi = tda->tda_current_tdmi; + assert(tdmi != NULL); + dvb_mux_t *dm = tdmi->tdmi_mux; - if(tdmi->tdmi_table_initial) { - tdmi->tdmi_table_initial = 0; - tda->tda_dn->dn_initial_num_mux--; - dvb_mux_save(tdmi); + if(dm->dm_table_initial) { + dm->dm_table_initial = 0; + dm->dm_dn->dn_initial_num_mux--; + dvb_mux_save(dm->dm_tdmi); } - dvb_table_flush_all(tdmi); + dvb_table_flush_all(dm); - assert(tdmi->tdmi_scan_queue == NULL); + assert(dm->dm_scan_queue == NULL); - epggrab_mux_stop(tdmi->tdmi_mux, 0); + epggrab_mux_stop(dm, 0); - if (!retune) { +#if 0 /// XXX(dvbreorg) + if(!retune) { gtimer_disarm(&tda->tda_fe_monitor_timer); dvb_adapter_stop(tda); } +#endif } #if DVB_API_VERSION >= 5 @@ -391,12 +393,14 @@ dvb_fe_tune_s2(th_dvb_mux_instance_t *tdmi, dvb_mux_conf_t *dmc) * */ int -dvb_fe_tune(th_dvb_mux_instance_t *tdmi, const char *reason) +dvb_fe_tune(dvb_mux_t *dm, const char *reason) { - th_dvb_adapter_t *tda = tdmi->tdmi_adapter; + th_dvb_adapter_t *tda = dm->dm_tdmi->tdmi_adapter; + dvb_network_t *dn = dm->dm_dn; + + th_dvb_mux_instance_t *tdmi = dm->dm_tdmi; // copy dmc, cause frequency may be change with FE_QPSK - const dvb_mux_t *dm = tdmi->tdmi_mux; dvb_mux_conf_t dmc = dm->dm_conf; dvb_frontend_parameters_t* p = &dmc.dmc_fe_params; @@ -409,18 +413,18 @@ dvb_fe_tune(th_dvb_mux_instance_t *tdmi, const char *reason) free(tda->tda_tune_reason); tda->tda_tune_reason = strdup(reason); - if(tda->tda_mux_current == tdmi) { + if(tda->tda_current_tdmi == tdmi) { dvb_adapter_notify(tda); return 0; } - if(tdmi->tdmi_scan_queue != NULL) { - TAILQ_REMOVE(tdmi->tdmi_scan_queue, tdmi, tdmi_scan_link); - tdmi->tdmi_scan_queue = NULL; + if(dm->dm_scan_queue != NULL) { + TAILQ_REMOVE(dm->dm_scan_queue, dm, dm_scan_link); + dm->dm_scan_queue = NULL; } - if(tda->tda_mux_current != NULL) - dvb_fe_stop(tda->tda_mux_current, 1); + if(tda->tda_current_tdmi != NULL) + dvb_fe_stop(tda, 1); else dvb_adapter_start(tda); @@ -497,9 +501,9 @@ dvb_fe_tune(th_dvb_mux_instance_t *tdmi, const char *reason) tda->tda_rootpath, buf, strerror(errno), p->frequency); /* Remove from initial scan set */ - if(tdmi->tdmi_table_initial) { - tdmi->tdmi_table_initial = 0; - tda->tda_dn->dn_initial_num_mux--; + if(dm->dm_table_initial) { + dm->dm_table_initial = 0; + dn->dn_initial_num_mux--; } /* Mark as bad */ @@ -507,7 +511,7 @@ dvb_fe_tune(th_dvb_mux_instance_t *tdmi, const char *reason) return SM_CODE_TUNING_FAILED; } - tda->tda_mux_current = tdmi; + tda->tda_current_tdmi = tdmi; gtimer_arm(&tda->tda_fe_monitor_timer, dvb_fe_monitor, tda, 1); diff --git a/src/dvb/dvb_input_filtered.c b/src/dvb/dvb_input_filtered.c index a4dddf26..2943e4e1 100644 --- a/src/dvb/dvb_input_filtered.c +++ b/src/dvb/dvb_input_filtered.c @@ -110,9 +110,9 @@ close_service(th_dvb_adapter_t *tda, service_t *s) * */ static void -open_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) +open_table(dvb_mux_t *dm, th_dvb_table_t *tdt) { - th_dvb_adapter_t *tda = tdmi->tdmi_adapter; + th_dvb_adapter_t *tda = dm->dm_current_tdmi->tdmi_adapter; struct epoll_event e; static int tdt_id_tally; @@ -148,7 +148,7 @@ open_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) } if(tdt->tdt_fd == -1) - TAILQ_INSERT_TAIL(&tdmi->tdmi_table_queue, tdt, tdt_pending_link); + TAILQ_INSERT_TAIL(&dm->dm_table_queue, tdt, tdt_pending_link); } @@ -156,9 +156,9 @@ open_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) * Close FD for the given table and put table on the pending list */ static void -tdt_close_fd(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) +tdt_close_fd(dvb_mux_t *dm, th_dvb_table_t *tdt) { - th_dvb_adapter_t *tda = tdmi->tdmi_adapter; + th_dvb_adapter_t *tda = dm->dm_current_tdmi->tdmi_adapter; assert(tdt->tdt_fd != -1); @@ -166,7 +166,7 @@ tdt_close_fd(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) close(tdt->tdt_fd); tdt->tdt_fd = -1; - TAILQ_INSERT_TAIL(&tdmi->tdmi_table_queue, tdt, tdt_pending_link); + TAILQ_INSERT_TAIL(&dm->dm_table_queue, tdt, tdt_pending_link); } @@ -181,7 +181,7 @@ dvb_table_input(void *aux) int r, i, tid, fd, x; struct epoll_event ev[1]; uint8_t sec[4096]; - th_dvb_mux_instance_t *tdmi; + dvb_mux_t *dm; th_dvb_table_t *tdt; int64_t cycle_barrier = 0; @@ -200,8 +200,8 @@ dvb_table_input(void *aux) continue; pthread_mutex_lock(&global_lock); - if((tdmi = tda->tda_mux_current) != NULL) { - LIST_FOREACH(tdt, &tdmi->tdmi_tables, tdt_link) + if((dm = tda->tda_current_tdmi->tdmi_mux) != NULL) { + LIST_FOREACH(tdt, &dm->dm_tables, tdt_link) if(tdt->tdt_id == tid) break; @@ -209,15 +209,15 @@ dvb_table_input(void *aux) dvb_table_dispatch(sec, r, tdt); /* Any tables pending (that wants a filter/fd), close this one */ - if(TAILQ_FIRST(&tdmi->tdmi_table_queue) != NULL && + if(TAILQ_FIRST(&dm->dm_table_queue) != NULL && cycle_barrier < getmonoclock()) { - tdt_close_fd(tdmi, tdt); + tdt_close_fd(dm, tdt); cycle_barrier = getmonoclock() + 100000; - tdt = TAILQ_FIRST(&tdmi->tdmi_table_queue); + tdt = TAILQ_FIRST(&dm->dm_table_queue); assert(tdt != NULL); - TAILQ_REMOVE(&tdmi->tdmi_table_queue, tdt, tdt_pending_link); + TAILQ_REMOVE(&dm->dm_table_queue, tdt, tdt_pending_link); - open_table(tdmi, tdt); + open_table(dm, tdt); } } } @@ -229,13 +229,15 @@ dvb_table_input(void *aux) static void -close_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) +close_table(dvb_mux_t *dm, th_dvb_table_t *tdt) { - th_dvb_adapter_t *tda = tdmi->tdmi_adapter; if(tdt->tdt_fd == -1) { - TAILQ_REMOVE(&tdmi->tdmi_table_queue, tdt, tdt_pending_link); + TAILQ_REMOVE(&dm->dm_table_queue, tdt, tdt_pending_link); } else { + th_dvb_mux_instance_t *tdmi = dm->dm_current_tdmi; + th_dvb_adapter_t *tda = tdmi->tdmi_adapter; + epoll_ctl(tda->tda_table_epollfd, EPOLL_CTL_DEL, tdt->tdt_fd, NULL); close(tdt->tdt_fd); } diff --git a/src/dvb/dvb_input_raw.c b/src/dvb/dvb_input_raw.c index 0c3f2a56..7176e0ef 100644 --- a/src/dvb/dvb_input_raw.c +++ b/src/dvb/dvb_input_raw.c @@ -62,8 +62,9 @@ close_service(th_dvb_adapter_t *tda, service_t *s) * */ static void -open_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) +open_table(dvb_mux_t *dm, th_dvb_table_t *tdt) { + th_dvb_mux_instance_t *tdmi = dm->dm_current_tdmi; th_dvb_adapter_t *tda = tdmi->tdmi_adapter; assert(tdt->tdt_pid < 0x2000); tda->tda_table_filter[tdt->tdt_pid] = 1; @@ -74,8 +75,9 @@ open_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) * */ static void -close_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) +close_table(dvb_mux_t *dm, th_dvb_table_t *tdt) { + th_dvb_mux_instance_t *tdmi = dm->dm_current_tdmi; th_dvb_adapter_t *tda = tdmi->tdmi_adapter; assert(tdt->tdt_pid < 0x2000); tda->tda_table_filter[tdt->tdt_pid] = 0; @@ -99,18 +101,17 @@ got_section(const uint8_t *data, size_t len, void *opaque) * so we need to be a bit careful here */ static void -dvb_table_raw_dispatch(th_dvb_mux_instance_t *tdmi, - const dvb_table_feed_t *dtf) +dvb_table_raw_dispatch(dvb_mux_t *dm, const dvb_table_feed_t *dtf) { int pid = (dtf->dtf_tsb[1] & 0x1f) << 8 | dtf->dtf_tsb[2]; - th_dvb_table_t *vec[tdmi->tdmi_num_tables], *tdt; + th_dvb_table_t *vec[dm->dm_num_tables], *tdt; int i = 0; - LIST_FOREACH(tdt, &tdmi->tdmi_tables, tdt_link) { + LIST_FOREACH(tdt, &dm->dm_tables, tdt_link) { vec[i++] = tdt; tdt->tdt_refcount++; } - assert(i == tdmi->tdmi_num_tables); - int len = tdmi->tdmi_num_tables; // can change during callbacks + assert(i == dm->dm_num_tables); + int len = dm->dm_num_tables; // can change during callbacks for(i = 0; i < len; i++) { tdt = vec[i]; if(!tdt->tdt_destroyed) { @@ -144,8 +145,8 @@ dvb_table_input(void *aux) pthread_mutex_lock(&global_lock); - if((tdmi = tda->tda_mux_current) != NULL) - dvb_table_raw_dispatch(tdmi, dtf); + if((tdmi = tda->tda_current_tdmi) != NULL) + dvb_table_raw_dispatch(tdmi->tdmi_mux, dtf); pthread_mutex_unlock(&global_lock); free(dtf); diff --git a/src/dvb/dvb_multiplex.c b/src/dvb/dvb_multiplex.c index a85bf6fc..c3e1d096 100644 --- a/src/dvb/dvb_multiplex.c +++ b/src/dvb/dvb_multiplex.c @@ -65,16 +65,12 @@ static void tdmi_set_enable(th_dvb_mux_instance_t *tdmi, int enabled); * */ static void -mux_link_initial(th_dvb_adapter_t *tda, th_dvb_mux_instance_t *tdmi) +mux_link_initial(dvb_network_t *dn, dvb_mux_t *dm) { - int was_empty = TAILQ_FIRST(&tda->tda_dn->dn_initial_scan_queue) == NULL; + dm->dm_scan_queue = &dn->dn_initial_scan_queue; + TAILQ_INSERT_TAIL(dm->dm_scan_queue, dm, dm_scan_link); - tdmi->tdmi_scan_queue = &tda->tda_dn->dn_initial_scan_queue; - TAILQ_INSERT_TAIL(tdmi->tdmi_scan_queue, tdmi, tdmi_scan_link); - - if(was_empty && (tda->tda_mux_current == NULL || - tda->tda_mux_current->tdmi_table_initial == 0)) - gtimer_arm(&tda->tda_mux_scanner_timer, dvb_adapter_mux_scanner, tda, 0); + gtimer_arm(&dn->dn_mux_scanner_timer, dvb_network_mux_scanner, dn, 0); } /** @@ -155,6 +151,7 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc, uint16_t onid, uint16_t tsid, const char *network, const char *source, int enabled, int initialscan, const char *identifier) { + dvb_network_t *dn = tda->tda_dn; th_dvb_mux_instance_t *tdmi, *c; char buf[200]; @@ -229,6 +226,7 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc, dm->dm_transport_stream_id = tsid; dm->dm_network_name = network ? strdup(network) : NULL; TAILQ_INIT(&dm->dm_epg_grab); + TAILQ_INIT(&dm->dm_table_queue); dm->dm_dn = tda->tda_dn; LIST_INSERT_HEAD(&tda->tda_dn->dn_muxes, dm, dm_network_link); @@ -269,7 +267,6 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc, tdmi->tdmi_enabled = enabled; - TAILQ_INIT(&tdmi->tdmi_table_queue); tdmi->tdmi_adapter = tda; @@ -278,7 +275,7 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc, memcpy(&tdmi->tdmi_mux->dm_conf, dmc, sizeof(struct dvb_mux_conf)); LIST_INSERT_HEAD(&tda->tda_dn->dn_mux_instances, tdmi, tdmi_adapter_link); - tdmi->tdmi_table_initial = initialscan; + dm->dm_table_initial = initialscan; if(source != NULL) { dvb_mux_nicename(buf, sizeof(buf), tdmi); @@ -291,9 +288,9 @@ dvb_mux_create(th_dvb_adapter_t *tda, const struct dvb_mux_conf *dmc, dvb_service_load(tdmi, identifier); dvb_mux_notify(tdmi); - if(enabled && tdmi->tdmi_table_initial) { - tda->tda_dn->dn_initial_num_mux++; - mux_link_initial(tda, tdmi); + if(enabled && dm->dm_table_initial) { + dn->dn_initial_num_mux++; + mux_link_initial(dn, dm); } return tdmi; @@ -306,6 +303,7 @@ void dvb_mux_destroy(th_dvb_mux_instance_t *tdmi) { th_dvb_adapter_t *tda = tdmi->tdmi_adapter; + dvb_mux_t *dm = tdmi->tdmi_mux; service_t *t; lock_assert(&global_lock); @@ -322,19 +320,19 @@ dvb_mux_destroy(th_dvb_mux_instance_t *tdmi) dvb_service_notify_by_adapter(tda); - if(tda->tda_mux_current == tdmi) - dvb_fe_stop(tda->tda_mux_current, 0); + if(tda->tda_current_tdmi == tdmi) + dvb_fe_stop(tda, 0); RB_REMOVE(&dvb_muxes, tdmi, tdmi_global_link); LIST_REMOVE(tdmi, tdmi_adapter_link); - if(tdmi->tdmi_scan_queue != NULL) - TAILQ_REMOVE(tdmi->tdmi_scan_queue, tdmi, tdmi_scan_link); + if(dm->dm_scan_queue != NULL) + TAILQ_REMOVE(dm->dm_scan_queue, dm, dm_scan_link); - if(tdmi->tdmi_table_initial) - tda->tda_dn->dn_initial_num_mux--; + if(dm->dm_table_initial) + dm->dm_dn->dn_initial_num_mux--; - epggrab_mux_delete(tdmi->tdmi_mux); // XXX(dvbreorg) + epggrab_mux_delete(dm); hts_settings_remove("dvbmuxes/%s", tdmi->tdmi_identifier); @@ -562,7 +560,7 @@ dvb_mux_save(th_dvb_mux_instance_t *tdmi) htsmsg_add_u32(m, "frequency", f->frequency); - htsmsg_add_u32(m, "initialscan", tdmi->tdmi_table_initial); + htsmsg_add_u32(m, "initialscan", tdmi->tdmi_mux->dm_table_initial); if(tdmi->tdmi_mux->dm_default_authority) htsmsg_add_str(m, "default_authority", tdmi->tdmi_mux->dm_default_authority); @@ -877,26 +875,27 @@ dvb_mux_set_onid(dvb_mux_t *dm, uint16_t onid) static void tdmi_set_enable(th_dvb_mux_instance_t *tdmi, int enabled) { + dvb_mux_t *dm = tdmi->tdmi_mux; th_dvb_adapter_t *tda = tdmi->tdmi_adapter; - + if(tdmi->tdmi_enabled == enabled) return; if(tdmi->tdmi_enabled) { - if(tda->tda_mux_current == tdmi) - dvb_fe_stop(tdmi, 0); + if(tda->tda_current_tdmi == tdmi) + dvb_fe_stop(tda, 0); - if(tdmi->tdmi_scan_queue != NULL) { - TAILQ_REMOVE(tdmi->tdmi_scan_queue, tdmi, tdmi_scan_link); - tdmi->tdmi_scan_queue = NULL; + if(dm->dm_scan_queue != NULL) { + TAILQ_REMOVE(dm->dm_scan_queue, dm, dm_scan_link); + dm->dm_scan_queue = NULL; } } tdmi->tdmi_enabled = enabled; if(enabled) - mux_link_initial(tda, tdmi); + mux_link_initial(tda->tda_dn, dm); subscription_reschedule(); } @@ -1275,7 +1274,7 @@ dvb_subscription_create_from_tdmi(th_dvb_mux_instance_t *tdmi, s->ths_tdmi = tdmi; LIST_INSERT_HEAD(&tdmi->tdmi_subscriptions, s, ths_tdmi_link); - dvb_fe_tune(tdmi, "Full mux subscription"); + dvb_fe_tune(tdmi->tdmi_mux, "Full mux subscription"); pthread_mutex_lock(&tda->tda_delivery_mutex); streaming_target_connect(&tda->tda_streaming_pad, &s->ths_input); diff --git a/src/dvb/dvb_network.c b/src/dvb/dvb_network.c new file mode 100644 index 00000000..9dd2239a --- /dev/null +++ b/src/dvb/dvb_network.c @@ -0,0 +1,102 @@ +/* + * TV Input - Linux DVB interface + * Copyright (C) 2007 - 2012 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 "tvheadend.h" +#include "packet.h" +#include "dvb.h" +#include "epggrab.h" + + + +/** + * + */ +dvb_network_t * +dvb_network_create(int fe_type) +{ + dvb_network_t *dn = calloc(1, sizeof(dvb_network_t)); + dn->dn_fe_type = fe_type; + TAILQ_INIT(&dn->dn_initial_scan_queue); + gtimer_arm(&dn->dn_mux_scanner_timer, dvb_network_mux_scanner, dn, 1); + return dn; +} + + + +/** + * + */ +void +dvb_network_mux_scanner(void *aux) +{ + dvb_network_t *dn = aux; + dvb_mux_t *dm; + + // default period + gtimer_arm(&dn->dn_mux_scanner_timer, dvb_network_mux_scanner, dn, 20); + +#if 0 + /* No muxes */ + if(LIST_FIRST(&dn->dn_mux_instances) == NULL) { + dvb_adapter_poweroff(tda); + return; + } +#endif +#if 0 + /* Someone is actively using */ + if(service_compute_weight(&tda->tda_transports) > 0) + return; +#endif +#if 0 + if(tda->tda_mux_current != NULL && + LIST_FIRST(&tda->tda_mux_current->tdmi_subscriptions) != NULL) + return; // Someone is doing full mux dump +#endif + + /* Check if we have muxes pending for quickscan, if so, choose them */ + if((dm = TAILQ_FIRST(&dn->dn_initial_scan_queue)) != NULL) { + dvb_fe_tune(dm, "Initial autoscan"); + return; + } + + /* Check EPG */ + if (dn->dn_mux_epg) { + // timeout anything not complete + epggrab_mux_stop(dn->dn_mux_epg, 1); + dn->dn_mux_epg = NULL; // skip this time + } else { + dn->dn_mux_epg = epggrab_mux_next(dn); + } + + /* EPG */ + if (dn->dn_mux_epg) { + int period = epggrab_mux_period(dn->dn_mux_epg); + if (period > 20) + gtimer_arm(&dn->dn_mux_scanner_timer, + dvb_network_mux_scanner, dn, period); + dvb_fe_tune(dn->dn_mux_epg, "EPG scan"); + return; + + } + +#if 0 + /* Ensure we stop current mux and power off (if required) */ + if (tda->tda_mux_current) + dvb_fe_stop(tda->tda_mux_current, 0); +#endif +} diff --git a/src/dvb/dvb_service.c b/src/dvb/dvb_service.c index b5d55794..2399e50d 100644 --- a/src/dvb/dvb_service.c +++ b/src/dvb/dvb_service.c @@ -59,7 +59,7 @@ dvb_service_start(service_t *t, unsigned int weight, int force_start) { int w, r; th_dvb_adapter_t *tda = t->s_dvb_mux_instance->tdmi_adapter; - th_dvb_mux_instance_t *tdmi = tda->tda_mux_current; + th_dvb_mux_instance_t *tdmi = tda->tda_current_tdmi; lock_assert(&global_lock); @@ -88,7 +88,7 @@ dvb_service_start(service_t *t, unsigned int weight, int force_start) pthread_mutex_lock(&tda->tda_delivery_mutex); - r = dvb_fe_tune(t->s_dvb_mux_instance, "Transport start"); + r = dvb_fe_tune(t->s_dvb_mux_instance->tdmi_mux, "Transport start"); if(!r) LIST_INSERT_HEAD(&tda->tda_transports, t, s_active_link); diff --git a/src/dvb/dvb_tables.c b/src/dvb/dvb_tables.c index 3708d025..ff25f37d 100644 --- a/src/dvb/dvb_tables.c +++ b/src/dvb/dvb_tables.c @@ -51,24 +51,26 @@ dvb_table_fastswitch(th_dvb_mux_instance_t *tdmi) { th_dvb_table_t *tdt; th_dvb_adapter_t *tda = tdmi->tdmi_adapter; + dvb_mux_t *dm = tdmi->tdmi_mux; + dvb_network_t *dn = dm->dm_dn; char buf[100]; - if(!tdmi->tdmi_table_initial) + if(!dm->dm_table_initial) return; - LIST_FOREACH(tdt, &tdmi->tdmi_tables, tdt_link) + LIST_FOREACH(tdt, &dm->dm_tables, tdt_link) if((tdt->tdt_flags & TDT_QUICKREQ) && tdt->tdt_count == 0) return; - tdmi->tdmi_table_initial = 0; - tda->tda_dn->dn_initial_num_mux--; + dm->dm_table_initial = 0; + dn->dn_initial_num_mux--; dvb_mux_save(tdmi); dvb_mux_nicename(buf, sizeof(buf), tdmi); tvhlog(LOG_DEBUG, "dvb", "\"%s\" initial scan completed for \"%s\"", tda->tda_rootpath, buf); - dvb_adapter_mux_scanner(tda); + dvb_network_mux_scanner(dn); } @@ -140,11 +142,12 @@ static void dvb_tdt_destroy(th_dvb_adapter_t *tda, th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt) { + dvb_mux_t *dm = tdmi->tdmi_mux; lock_assert(&global_lock); assert(tdt->tdt_tdmi == tdmi); LIST_REMOVE(tdt, tdt_link); - tdmi->tdmi_num_tables--; - tda->tda_close_table(tdmi, tdt); + dm->dm_num_tables--; + tda->tda_close_table(dm, tdt); free(tdt->tdt_name); tdt->tdt_destroyed = 1; dvb_table_release(tdt); @@ -167,7 +170,7 @@ tdt_add(dvb_mux_t *dm, int tableid, int mask, // TODO: this could mean reading the same data multiple times, and not // sure how well this will work! I know Andreas has some thoughts on // this - LIST_FOREACH(t, &tdmi->tdmi_tables, tdt_link) { + LIST_FOREACH(t, &dm->dm_tables, tdt_link) { if(pid == t->tdt_pid && t->tdt_callback == callback && t->tdt_opaque == opaque) { return; @@ -184,11 +187,11 @@ tdt_add(dvb_mux_t *dm, int tableid, int mask, tdt->tdt_table = tableid; tdt->tdt_mask = mask; tdt->tdt_tdmi = tdmi; - LIST_INSERT_HEAD(&tdmi->tdmi_tables, tdt, tdt_link); - tdmi->tdmi_num_tables++; + LIST_INSERT_HEAD(&dm->dm_tables, tdt, tdt_link); + dm->dm_num_tables++; tdt->tdt_fd = -1; - tdmi->tdmi_adapter->tda_open_table(tdmi, tdt); + tdmi->tdmi_adapter->tda_open_table(dm, tdt); } /** @@ -1095,7 +1098,7 @@ dvb_table_rem_pmt(dvb_mux_t *dm, int pmt_pid) th_dvb_mux_instance_t *tdmi = dm->dm_tdmi; th_dvb_adapter_t *tda = tdmi->tdmi_adapter; th_dvb_table_t *tdt = NULL; - LIST_FOREACH(tdt, &tdmi->tdmi_tables, tdt_link) + LIST_FOREACH(tdt, &dm->dm_tables, tdt_link) if (tdt->tdt_pid == pmt_pid && tdt->tdt_callback == dvb_pmt_callback) break; if (tdt) @@ -1107,12 +1110,12 @@ dvb_table_rem_pmt(dvb_mux_t *dm, int pmt_pid) * */ void -dvb_table_flush_all(th_dvb_mux_instance_t *tdmi) +dvb_table_flush_all(dvb_mux_t *dm) { - th_dvb_adapter_t *tda = tdmi->tdmi_adapter; + th_dvb_adapter_t *tda = dm->dm_tdmi->tdmi_adapter; th_dvb_table_t *tdt; - while((tdt = LIST_FIRST(&tdmi->tdmi_tables)) != NULL) - dvb_tdt_destroy(tda, tdmi, tdt); + while((tdt = LIST_FIRST(&dm->dm_tables)) != NULL) + dvb_tdt_destroy(tda, dm->dm_tdmi, tdt); } diff --git a/src/epggrab.h b/src/epggrab.h index d72f98d6..cfc47ae0 100644 --- a/src/epggrab.h +++ b/src/epggrab.h @@ -26,7 +26,7 @@ * *************************************************************************/ struct th_dvb_mux_instance; -struct th_dvb_adapter; +struct dvb_network; typedef struct epggrab_module epggrab_module_t; typedef struct epggrab_module_int epggrab_module_int_t; @@ -263,7 +263,7 @@ void epggrab_mux_start ( struct dvb_mux *tdmi ); void epggrab_mux_stop ( struct dvb_mux *tdmi, int timeout ); void epggrab_mux_delete ( struct dvb_mux *tdmi ); int epggrab_mux_period ( struct dvb_mux *tdmi ); -struct dvb_mux *epggrab_mux_next ( struct th_dvb_adapter *tda ); +struct dvb_mux *epggrab_mux_next ( struct dvb_network *dn ); /* * Re-schedule diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c index 9fa07b67..93e4431d 100644 --- a/src/epggrab/otamux.c +++ b/src/epggrab/otamux.c @@ -83,7 +83,7 @@ int epggrab_mux_period ( dvb_mux_t *dm ) return period; } -dvb_mux_t *epggrab_mux_next ( th_dvb_adapter_t *tda ) +dvb_mux_t *epggrab_mux_next ( dvb_network_t *dn ) { time_t now; epggrab_ota_mux_t *ota; @@ -91,7 +91,7 @@ dvb_mux_t *epggrab_mux_next ( th_dvb_adapter_t *tda ) TAILQ_FOREACH(ota, &ota_mux_all, glob_link) { if (ota->interval + ota->completed > now) return NULL; if (!ota->is_reg) return NULL; - if (ota->dm->dm_tdmi->tdmi_adapter == tda) break; + if (ota->dm->dm_dn == dn) break; } return ota ? ota->dm : NULL; } @@ -373,9 +373,9 @@ void epggrab_ota_complete ( epggrab_ota_mux_t *ota ) /* All complete (bring timer forward) */ if (!ota) { - th_dvb_mux_instance_t *tdmi = dm->dm_tdmi; - gtimer_arm(&tdmi->tdmi_adapter->tda_mux_scanner_timer, - dvb_adapter_mux_scanner, tdmi->tdmi_adapter, 20); + dvb_network_t *dn = dm->dm_dn; + gtimer_arm(&dn->dn_mux_scanner_timer, + dvb_network_mux_scanner, dn, 20); } } }