diff --git a/dvb.c b/dvb.c index 810514f1..3c47985c 100644 --- a/dvb.c +++ b/dvb.c @@ -339,6 +339,7 @@ dvb_fec_monitor(void *aux, int64_t now) { th_dvb_adapter_t *tda = aux; th_dvb_mux_instance_t *tdmi; + int i, v, vv; dtimer_arm(&tda->tda_fec_monitor_timer, dvb_fec_monitor, tda, 1); @@ -346,12 +347,22 @@ dvb_fec_monitor(void *aux, int64_t now) if(tdmi != NULL && tdmi->tdmi_status == NULL) { - if(tdmi->tdmi_fec_err_per_sec > DVB_FEC_ERROR_LIMIT) { + 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; + if(v == TDMI_FEC_ERR_HISTOGRAM_SIZE) { if(LIST_FIRST(&tda->tda_transports) != NULL) { - syslog(LOG_ERR, "\"%s\": Too many FEC errors (%d / s), " - "flushing subscribers\n", - tdmi->tdmi_uniquename, tdmi->tdmi_fec_err_per_sec); + syslog(LOG_ERR, + "\"%s\": Constant rate of FEC errors (average at %d / s), " + "last %d seconds, flushing subscribers\n", + tdmi->tdmi_uniquename, vv, + TDMI_FEC_ERR_HISTOGRAM_SIZE); + dvb_adapter_clean(tdmi->tdmi_adapter); } } diff --git a/dvb.h b/dvb.h index 4468dbf0..7d2c3a42 100644 --- a/dvb.h +++ b/dvb.h @@ -19,7 +19,7 @@ #ifndef DVB_H_ #define DVB_H_ -#define DVB_FEC_ERROR_LIMIT 10 +#define DVB_FEC_ERROR_LIMIT 20 extern struct th_dvb_adapter_list dvb_adapters_probing; extern struct th_dvb_adapter_list dvb_adapters_running; diff --git a/dvb_dvr.c b/dvb_dvr.c index f36aceeb..c07e15bb 100644 --- a/dvb_dvr.c +++ b/dvb_dvr.c @@ -141,7 +141,7 @@ dvb_start_feed(th_transport_t *t, unsigned int weight, int status) { struct dmx_pes_filter_params dmx_param; th_stream_t *st; - int w, fd, pid; + int w, fd, pid, i; th_dvb_adapter_t *tda = t->tht_dvb_mux_instance->tdmi_adapter; th_dvb_mux_instance_t *tdmi = tda->tda_mux_current; @@ -154,8 +154,9 @@ dvb_start_feed(th_transport_t *t, unsigned int weight, int status) if(tdmi->tdmi_status != NULL) return 1; /* no lock on adapter, cant use it */ - if(tdmi->tdmi_fec_err_per_sec > DVB_FEC_ERROR_LIMIT / 3) - return 1; /* too many errors for using it */ + for(i = 0; i < TDMI_FEC_ERR_HISTOGRAM_SIZE; i++) + if(tdmi->tdmi_fec_err_histogram[i] > DVB_FEC_ERROR_LIMIT) + return 1; /* too many errors for using it */ w = transport_compute_weight(&tdmi->tdmi_adapter->tda_transports); if(w > weight) diff --git a/dvb_fe.c b/dvb_fe.c index 01bc6eb4..561d551f 100644 --- a/dvb_fe.c +++ b/dvb_fe.c @@ -135,8 +135,12 @@ dvb_fe_manager(void *aux) ioctl(tda->tda_fe_fd, FE_READ_UNCORRECTED_BLOCKS, &v); - if(fe_status & FE_HAS_LOCK) - tdmi->tdmi_fec_err_per_sec = (tdmi->tdmi_fec_err_per_sec * 7 + v) / 8; + if(fe_status & FE_HAS_LOCK) { + tdmi->tdmi_fec_err_histogram[tdmi->tdmi_fec_err_ptr] = v; + tdmi->tdmi_fec_err_ptr++; + if(tdmi->tdmi_fec_err_ptr == TDMI_FEC_ERR_HISTOGRAM_SIZE) + tdmi->tdmi_fec_err_ptr = 0; + } } } diff --git a/htmlui.c b/htmlui.c index 22c2909e..41a43920 100644 --- a/htmlui.c +++ b/htmlui.c @@ -1206,6 +1206,7 @@ page_status(http_connection_t *hc, const char *remain, void *opaque) th_stream_t *st; const char *txt, *t1, *t2; char tmptxt[100]; + int i, v, vv; if(!html_verify_access(hc, "system-status")) return HTTP_STATUS_UNAUTHORIZED; @@ -1250,8 +1251,19 @@ page_status(http_connection_t *hc, const char *remain, void *opaque) tdmi->tdmi_shortname); txt = tdmi->tdmi_status ?: "Ok"; - if(tdmi->tdmi_fec_err_per_sec > DVB_FEC_ERROR_LIMIT) - txt = "Too high FEC rate"; + + 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; + + if(v == TDMI_FEC_ERR_HISTOGRAM_SIZE) + txt = "Constant high FEC rate"; + else if(v > 0) + txt = "Bursty FEC rate"; tcp_qprintf(&tq, "" "%d" "
", - tdmi->tdmi_fec_err_per_sec); + vv); } } } diff --git a/htsclient.c b/htsclient.c index 90f803e6..95a070ec 100644 --- a/htsclient.c +++ b/htsclient.c @@ -180,7 +180,7 @@ print_tdmi(client_t *c, th_dvb_mux_instance_t *tdmi) return; } - cprintf(c, "locked, %d errors / second\n", tdmi->tdmi_fec_err_per_sec); + cprintf(c, "locked\n"); } /* diff --git a/tvhead.h b/tvhead.h index 379d3d59..30cd2a65 100644 --- a/tvhead.h +++ b/tvhead.h @@ -155,7 +155,9 @@ typedef struct th_dvb_mux_instance { uint16_t tdmi_snr, tdmi_signal; uint32_t tdmi_ber, tdmi_uncorrected_blocks; - uint32_t tdmi_fec_err_per_sec; +#define TDMI_FEC_ERR_HISTOGRAM_SIZE 10 + uint32_t tdmi_fec_err_histogram[TDMI_FEC_ERR_HISTOGRAM_SIZE]; + int tdmi_fec_err_ptr; time_t tdmi_time; LIST_HEAD(, th_dvb_table) tdmi_tables;