diff --git a/dvb/dvb_adapter.c b/dvb/dvb_adapter.c index 99eb80d9..acfddaea 100644 --- a/dvb/dvb_adapter.c +++ b/dvb/dvb_adapter.c @@ -285,8 +285,9 @@ dvb_fec_monitor(void *aux, int64_t now) { th_dvb_adapter_t *tda = aux; th_dvb_mux_instance_t *tdmi; - int i, v, vv; + int i, v, vv, n; const char *s; + int savemux = 0; dtimer_arm(&tda->tda_fec_monitor_timer, dvb_fec_monitor, tda, 1); @@ -316,26 +317,32 @@ dvb_fec_monitor(void *aux, int64_t now) } } - - if(dvb_mux_status(tdmi, 1) != NULL) { + n = dvb_mux_badness(tdmi); + if(n > 0) { if(tdmi->tdmi_quality > -50) { - tdmi->tdmi_quality--; + tdmi->tdmi_quality -= n; dvb_notify_mux_quality(tdmi); + savemux = 1; } } else { if(tdmi->tdmi_quality < 0) { tdmi->tdmi_quality++; dvb_notify_mux_quality(tdmi); + savemux = 1; } } - s = dvb_mux_status(tdmi, 0); - - if(s != tdmi->tdmi_last_status) { - tdmi->tdmi_last_status = s; + s = dvb_mux_status(tdmi); + if(strcmp(s, tdmi->tdmi_last_status)) { + free(tdmi->tdmi_last_status); + tdmi->tdmi_last_status = strdup(s); dvb_notify_mux_status(tdmi); + savemux = 1; } + + if(savemux) + dvb_mux_save(tdmi); } diff --git a/dvb/dvb_multiplex.c b/dvb/dvb_multiplex.c index cb81d1f7..0a5fbcfc 100644 --- a/dvb/dvb_multiplex.c +++ b/dvb/dvb_multiplex.c @@ -119,6 +119,7 @@ dvb_mux_create(th_dvb_adapter_t *tda, struct dvb_frontend_parameters *fe_param, tdmi->tdmi_transport_stream_id = tsid; tdmi->tdmi_adapter = tda; tdmi->tdmi_network = network ? strdup(network) : NULL; + tdmi->tdmi_last_status = strdup("Initializing"); if(entries_before == 0 && tda->tda_rootpath != NULL) { /* First mux on adapter with backing hardware, start scanner */ @@ -321,6 +322,9 @@ dvb_mux_save(th_dvb_mux_instance_t *tdmi) htsmsg_t *m = htsmsg_create(); + htsmsg_add_u32(m, "quality", -tdmi->tdmi_quality); + htsmsg_add_str(m, "status", tdmi->tdmi_last_status); + htsmsg_add_u32(m, "transportstreamid", tdmi->tdmi_transport_stream_id); if(tdmi->tdmi_network != NULL) htsmsg_add_str(m, "network", tdmi->tdmi_network); @@ -389,12 +393,13 @@ dvb_mux_save(th_dvb_mux_instance_t *tdmi) static const char * tdmi_create_by_msg(th_dvb_adapter_t *tda, htsmsg_t *m) { + th_dvb_mux_instance_t *tdmi; struct dvb_frontend_parameters f; const char *s; int r; int polarisation = 0; unsigned int switchport = 0; - unsigned int tsid; + unsigned int tsid, u32; memset(&f, 0, sizeof(f)); @@ -481,8 +486,18 @@ tdmi_create_by_msg(th_dvb_adapter_t *tda, htsmsg_t *m) if(htsmsg_get_u32(m, "transportstreamid", &tsid)) tsid = 0xffff; - dvb_mux_create(tda, &f, polarisation, switchport, - tsid, htsmsg_get_str(m, "network"), NULL); + tdmi = dvb_mux_create(tda, &f, polarisation, switchport, + tsid, htsmsg_get_str(m, "network"), NULL); + if(tdmi != NULL) { + s = htsmsg_get_str(m, "status"); + if(s != NULL) { + free((void *)tdmi->tdmi_last_status); + tdmi->tdmi_last_status = strdup(s); + } + + if(!htsmsg_get_u32(m, "quality", &u32)) + tdmi->tdmi_quality = -u32; + } return NULL; } diff --git a/dvb/dvb_support.c b/dvb/dvb_support.c index feb4a6e8..a5945915 100644 --- a/dvb/dvb_support.c +++ b/dvb/dvb_support.c @@ -268,28 +268,45 @@ dvb_adapter_find_by_identifier(const char *identifier) /** - * + * Return a readable status text for the given mux */ const char * -dvb_mux_status(th_dvb_mux_instance_t *tdmi, int nullisok) +dvb_mux_status(th_dvb_mux_instance_t *tdmi) { - int i, v, vv; - const char *txt = tdmi->tdmi_status ?: (nullisok ? NULL : "Ok"); + int i, v = 0; - v = vv = 0; - for(i = 0; i < TDMI_FEC_ERR_HISTOGRAM_SIZE; i++) { - if(tdmi->tdmi_fec_err_histogram[i] > DVB_FEC_ERROR_LIMIT) - v++; - vv += tdmi->tdmi_fec_err_histogram[i]; - } - vv /= TDMI_FEC_ERR_HISTOGRAM_SIZE; + for(i = 0; i < TDMI_FEC_ERR_HISTOGRAM_SIZE; i++) + v += tdmi->tdmi_fec_err_histogram[i] > DVB_FEC_ERROR_LIMIT; if(v == TDMI_FEC_ERR_HISTOGRAM_SIZE) - txt = "Constant FEC"; + return "Constant FEC"; else if(v > 0) - txt = "Bursty FEC"; + return "Bursty FEC"; - return txt; + return tdmi->tdmi_status ?: "OK"; +} + + +/** + * Return a badness value (0-3) + */ +int +dvb_mux_badness(th_dvb_mux_instance_t *tdmi) +{ + int i, v = 0; + + if(tdmi->tdmi_status) + return 3; + + for(i = 0; i < TDMI_FEC_ERR_HISTOGRAM_SIZE; i++) + v += tdmi->tdmi_fec_err_histogram[i] > DVB_FEC_ERROR_LIMIT; + + if(v == TDMI_FEC_ERR_HISTOGRAM_SIZE) + return 2; + else if(v > 0) + return 1; + + return 0; } diff --git a/dvb/dvb_support.h b/dvb/dvb_support.h index 8927a79a..a7d04bbd 100644 --- a/dvb/dvb_support.h +++ b/dvb/dvb_support.h @@ -59,7 +59,9 @@ int dvb_str_to_adaptertype(const char *str); const char *dvb_polarisation_to_str(int pol); th_dvb_adapter_t *dvb_adapter_find_by_identifier(const char *identifier); th_dvb_mux_instance_t *dvb_mux_find_by_identifier(const char *identifier); -const char *dvb_mux_status(th_dvb_mux_instance_t *tdmi, int nullisok); void dvb_mux_nicename(char *buf, size_t size, th_dvb_mux_instance_t *tdmi); int dvb_quality_to_percent(int qual); +int dvb_mux_badness(th_dvb_mux_instance_t *tdmi); +const char *dvb_mux_status(th_dvb_mux_instance_t *tdmi); + #endif /* DVB_SUPPORT_H */ diff --git a/tvhead.h b/tvhead.h index 0f881635..50c47ad7 100644 --- a/tvhead.h +++ b/tvhead.h @@ -178,7 +178,7 @@ typedef struct th_dvb_mux_instance { dtimer_t tdmi_initial_scan_timer; const char *tdmi_status; - const char *tdmi_last_status; /* For notification updates */ + char *tdmi_last_status; /* For notification updates */ int tdmi_quality; diff --git a/webui/extjs.c b/webui/extjs.c index 61c6e872..de826bd5 100644 --- a/webui/extjs.c +++ b/webui/extjs.c @@ -263,7 +263,7 @@ extjs_dvbtree(http_connection_t *hc, http_reply_t *hr, extjs_dvbtree_node(out, 0, tdmi->tdmi_identifier, buf, "DVB Mux", - dvb_mux_status(tdmi, 0), + tdmi->tdmi_last_status, 100 + tdmi->tdmi_quality * 2, "mux"); } } else if((tdmi = dvb_mux_find_by_identifier(s)) != NULL) {