linuxdvb: ensure that the enabled flag is properly honoured

This commit is contained in:
Adam Sutton 2014-04-14 21:29:56 +01:00
parent 30b3c0506c
commit fe06fb6fd5
5 changed files with 67 additions and 13 deletions

View file

@ -487,6 +487,7 @@ struct mpegts_input
* Functions
*/
int (*mi_is_enabled) (mpegts_input_t*);
void (*mi_enabled_updated)(mpegts_input_t*);
void (*mi_display_name) (mpegts_input_t*, char *buf, size_t len);
int (*mi_is_free) (mpegts_input_t*);
int (*mi_get_weight) (mpegts_input_t*);

View file

@ -183,6 +183,7 @@ linux_dvb_get_type(int linux_type)
static void
linuxdvb_adapter_add ( const char *path )
{
#define MAX_DEV_OPEN_ATTEMPTS 20
extern int linuxdvb_adapter_mask;
int a, i, j, r, fd;
char fe_path[512], dmx_path[512], dvr_path[512];
@ -226,7 +227,7 @@ linuxdvb_adapter_add ( const char *path )
/* Wait for access (first FE can take a fe ms to be setup) */
if (!i) {
for (j = 0; j < 10; j++) {
for (j = 0; j < MAX_DEV_OPEN_ATTEMPTS; j++) {
if (!access(fe_path, R_OK | W_OK)) break;
usleep(100000);
}
@ -234,7 +235,7 @@ linuxdvb_adapter_add ( const char *path )
if (access(fe_path, R_OK | W_OK)) continue;
/* Get frontend info */
for (j = 0; j < 10; j++) {
for (j = 0; j < MAX_DEV_OPEN_ATTEMPTS; j++) {
if ((fd = tvh_open(fe_path, O_RDWR, 0)) > 0) break;
usleep(100000);
}
@ -310,6 +311,7 @@ linuxdvb_adapter_add ( const char *path )
htsmsg_destroy(conf);
return; // Note: save to return here as global_lock is held
}
tvhinfo("linuxdvb", "adapter added %s", path);
}
/* Create frontend */
@ -418,6 +420,7 @@ devdvb_create ( fsmonitor_t *fsm, const char *path )
static void
devdvb_delete ( fsmonitor_t *fsm, const char *path )
{
tvhinfo("linuxdvb", "adapter removed %s", path);
linuxdvb_adapter_del(path);
}

View file

@ -93,9 +93,9 @@ const idclass_t linuxdvb_frontend_class =
},
{
.type = PT_BOOL,
.id = "noclosefe",
.name = "Keep FE open",
.off = offsetof(linuxdvb_frontend_t, lfe_noclosefe),
.id = "powersave",
.name = "Power Save",
.off = offsetof(linuxdvb_frontend_t, lfe_powersave),
},
{}
}
@ -192,6 +192,29 @@ const idclass_t linuxdvb_frontend_atsc_class =
* Class methods
* *************************************************************************/
static void
linuxdvb_frontend_enabled_updated ( mpegts_input_t *mi )
{
char buf[512];
linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi;
mi->mi_display_name(mi, buf, sizeof(buf));
/* Ensure disabled */
if (!mi->mi_enabled) {
tvhtrace("linuxdvb", "%s - disabling tuner", buf);
if (lfe->lfe_fe_fd > 0)
close(lfe->lfe_fe_fd);
gtimer_disarm(&lfe->lfe_monitor_timer);
/* Ensure FE opened (if not powersave) */
} else if (!lfe->lfe_powersave && lfe->lfe_fe_fd <= 0 && lfe->lfe_fe_path) {
lfe->lfe_fe_fd = tvh_open(lfe->lfe_fe_path, O_RDWR | O_NONBLOCK, 0);
tvhtrace("linuxdvb", "%s - opening FE %s (%d)",
buf, lfe->lfe_fe_path, lfe->lfe_fe_fd);
}
}
static int
linuxdvb_frontend_is_free ( mpegts_input_t *mi )
{
@ -416,9 +439,13 @@ linuxdvb_frontend_monitor ( void *aux )
lfe->mi_display_name((mpegts_input_t*)lfe, buf, sizeof(buf));
tvhtrace("linuxdvb", "%s - checking FE status", buf);
/* Disabled */
if (!lfe->mi_enabled && mmi)
mmi->mmi_mux->mm_stop(mmi->mmi_mux, 1);
/* Close FE */
if (lfe->lfe_fe_fd > 0 && !mmi && !lfe->lfe_noclosefe) {
if (lfe->lfe_fe_fd > 0 && !mmi && lfe->lfe_powersave) {
tvhtrace("linuxdvb", "%s - closing frontend", buf);
close(lfe->lfe_fe_fd);
lfe->lfe_fe_fd = -1;
@ -433,9 +460,12 @@ linuxdvb_frontend_monitor ( void *aux )
}
}
gtimer_arm(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 1);
/* Stop timer */
if (!mmi) return;
/* re-arm */
gtimer_arm(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, 1);
/* Get current status */
if (ioctl(lfe->lfe_fe_fd, FE_READ_STATUS, &fe_status) == -1) {
tvhwarn("linuxdvb", "%s - FE_READ_STATUS error %s", buf, strerror(errno));
@ -1173,11 +1203,12 @@ linuxdvb_frontend_create
lfe->lfe_dvr_path = strdup(dvr_path);
/* Input callbacks */
lfe->mi_is_enabled = linuxdvb_frontend_is_enabled;
lfe->mi_start_mux = linuxdvb_frontend_start_mux;
lfe->mi_stop_mux = linuxdvb_frontend_stop_mux;
lfe->mi_network_list = linuxdvb_frontend_network_list;
lfe->mi_open_pid = linuxdvb_frontend_open_pid;
lfe->mi_is_enabled = linuxdvb_frontend_is_enabled;
lfe->mi_start_mux = linuxdvb_frontend_start_mux;
lfe->mi_stop_mux = linuxdvb_frontend_stop_mux;
lfe->mi_network_list = linuxdvb_frontend_network_list;
lfe->mi_open_pid = linuxdvb_frontend_open_pid;
lfe->mi_enabled_updated = linuxdvb_frontend_enabled_updated;
/* Adapter link */
lfe->lfe_adapter = la;
@ -1199,6 +1230,9 @@ linuxdvb_frontend_create
if (lfe->lfe_type == DVB_TYPE_S && !lfe->lfe_satconf)
lfe->lfe_satconf = linuxdvb_satconf_create(lfe, sctype, scuuid, scconf);
/* Double check enabled */
linuxdvb_frontend_enabled_updated((mpegts_input_t*)lfe);
return lfe;
}

View file

@ -108,7 +108,7 @@ struct linuxdvb_frontend
* Configuration
*/
int lfe_fullmux;
int lfe_noclosefe;
int lfe_powersave;
/*
* Satconf (DVB-S only)

View file

@ -99,6 +99,21 @@ mpegts_input_class_network_rend ( void *obj )
return str;
}
static void
mpegts_input_enabled_notify ( void *p )
{
mpegts_input_t *mi = p;
mpegts_mux_instance_t *mmi;
/* Stop */
LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link)
mmi->mmi_mux->mm_stop(mmi->mmi_mux, 1);
/* Alert */
if (mi->mi_enabled_updated)
mi->mi_enabled_updated(mi);
}
const idclass_t mpegts_input_class =
{
.ic_class = "mpegts_input",
@ -110,6 +125,7 @@ const idclass_t mpegts_input_class =
.id = "enabled",
.name = "Enabled",
.off = offsetof(mpegts_input_t, mi_enabled),
.notify = mpegts_input_enabled_notify,
.def.i = 1,
},
{