linuxdvb: add nodata and signal retune code
Sometimes, the linux drivers requires "re-tune" requests to stabilize or re-trigger reception which may hang. The two checks were added: nodata - when no data are available for a little time period, issue re-tune signal - when signal is lost for a little time period, issue re-tune
This commit is contained in:
parent
93aac31870
commit
4df20c2b6a
2 changed files with 45 additions and 8 deletions
|
@ -33,6 +33,7 @@
|
|||
#include <linux/dvb/dmx.h>
|
||||
#include <linux/dvb/frontend.h>
|
||||
|
||||
#define NOSIGNAL(x) (((x) & FE_HAS_SIGNAL) == 0)
|
||||
|
||||
static void
|
||||
linuxdvb_frontend_monitor ( void *aux );
|
||||
|
@ -303,9 +304,10 @@ linuxdvb_frontend_stop_mux
|
|||
}
|
||||
|
||||
/* Not locked */
|
||||
lfe->lfe_ready = 0;
|
||||
lfe->lfe_locked = 0;
|
||||
lfe->lfe_status = 0;
|
||||
lfe->lfe_ready = 0;
|
||||
lfe->lfe_locked = 0;
|
||||
lfe->lfe_status = 0;
|
||||
lfe->lfe_status2 = 0;
|
||||
|
||||
/* Ensure it won't happen immediately */
|
||||
gtimer_arm(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 2);
|
||||
|
@ -314,6 +316,7 @@ linuxdvb_frontend_stop_mux
|
|||
linuxdvb_satconf_post_stop_mux(lfe->lfe_satconf);
|
||||
|
||||
lfe->lfe_in_setup = 0;
|
||||
lfe->lfe_freq = 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -480,7 +483,7 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
signal_status_t sigstat;
|
||||
streaming_message_t sm;
|
||||
service_t *s;
|
||||
int logit = 0;
|
||||
int logit = 0, retune;
|
||||
#if DVB_VER_ATLEAST(5,10)
|
||||
struct dtv_property fe_properties[6];
|
||||
struct dtv_properties dtv_prop;
|
||||
|
@ -546,8 +549,20 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
} else {
|
||||
tvhtrace("linuxdvb", "%s - status %d (%04X)", buf, status, fe_status);
|
||||
}
|
||||
retune = NOSIGNAL(fe_status) && NOSIGNAL(lfe->lfe_status) && !NOSIGNAL(lfe->lfe_status2);
|
||||
lfe->lfe_status2 = lfe->lfe_status;
|
||||
lfe->lfe_status = fe_status;
|
||||
|
||||
/* Retune check - we lost signal or no data were received */
|
||||
if (retune || lfe->lfe_nodata) {
|
||||
lfe->lfe_nodata = 0;
|
||||
if (lfe->lfe_freq > 0) {
|
||||
tvhlog(LOG_WARNING, "linuxdvb", "%s - %s", buf, retune ? "retune" : "retune nodata");
|
||||
linuxdvb_frontend_tune0(lfe, mmi, lfe->lfe_freq);
|
||||
gtimer_arm_ms(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 50);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get current mux */
|
||||
mm = mmi->mmi_mux;
|
||||
|
||||
|
@ -586,6 +601,11 @@ linuxdvb_frontend_monitor ( void *aux )
|
|||
return;
|
||||
lfe->lfe_monitor = dispatch_clock + 1;
|
||||
}
|
||||
} else {
|
||||
/* Monitor 1 per sec */
|
||||
if (dispatch_clock < lfe->lfe_monitor)
|
||||
return;
|
||||
lfe->lfe_monitor = dispatch_clock + 1;
|
||||
}
|
||||
|
||||
/* Statistics - New API */
|
||||
|
@ -839,6 +859,7 @@ linuxdvb_frontend_input_thread ( void *aux )
|
|||
size_t skip = (MIN(lfe->lfe_skip_bytes, 1024*1024) / 188) * 188;
|
||||
size_t counter = 0;
|
||||
sbuf_t sb;
|
||||
int nodata = 8;
|
||||
|
||||
/* Get MMI */
|
||||
pthread_mutex_lock(&lfe->lfe_dvr_lock);
|
||||
|
@ -869,9 +890,21 @@ linuxdvb_frontend_input_thread ( void *aux )
|
|||
|
||||
/* Read */
|
||||
while (tvheadend_running) {
|
||||
nfds = tvhpoll_wait(efd, ev, 1, -1);
|
||||
nfds = tvhpoll_wait(efd, ev, 1, 15);
|
||||
if (nfds == 0) { /* timeout */
|
||||
if (nodata == 0) {
|
||||
tvhlog(LOG_WARNING, "linuxdvb", "%s - poll TIMEOUT", buf);
|
||||
nodata = 50;
|
||||
lfe->lfe_nodata = 1;
|
||||
} else {
|
||||
nodata--;
|
||||
}
|
||||
}
|
||||
if (nfds < 1) continue;
|
||||
if (ev[0].data.fd != dvr) break;
|
||||
|
||||
nodata = 50;
|
||||
lfe->lfe_nodata = 0;
|
||||
|
||||
/* Read */
|
||||
if ((n = sbuf_tsdebug_read(mmi->mmi_mux, &sb, dvr)) < 0) {
|
||||
|
@ -1002,8 +1035,9 @@ linuxdvb_frontend_clear
|
|||
return SM_CODE_TUNING_FAILED;
|
||||
}
|
||||
}
|
||||
lfe->lfe_locked = 0;
|
||||
lfe->lfe_status = 0;
|
||||
lfe->lfe_locked = 0;
|
||||
lfe->lfe_status = 0;
|
||||
lfe->lfe_status2 = 0;
|
||||
|
||||
#if DVB_API_VERSION >= 5
|
||||
static struct dtv_property clear_p[] = {
|
||||
|
@ -1206,7 +1240,7 @@ linuxdvb_frontend_tune0
|
|||
}
|
||||
|
||||
if (freq != (uint32_t)-1)
|
||||
p.frequency = freq;
|
||||
p.frequency = lfe->lfe_freq = freq;
|
||||
|
||||
if (dmc->dmc_fe_type != lfe->lfe_type) {
|
||||
tvherror("linuxdvb", "%s - failed to tune [type does not match %i != %i]", buf1, dmc->dmc_fe_type, lfe->lfe_type);
|
||||
|
|
|
@ -102,7 +102,10 @@ struct linuxdvb_frontend
|
|||
int lfe_in_setup;
|
||||
int lfe_locked;
|
||||
int lfe_status;
|
||||
int lfe_status2;
|
||||
int lfe_ioctls;
|
||||
int lfe_nodata;
|
||||
int lfe_freq;
|
||||
time_t lfe_monitor;
|
||||
gtimer_t lfe_monitor_timer;
|
||||
tvhlog_limit_t lfe_status_log;
|
||||
|
|
Loading…
Add table
Reference in a new issue