diff --git a/src/input/mpegts.h b/src/input/mpegts.h index fcbe2398..61b9408e 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -405,6 +405,7 @@ struct mpegts_input void (*mi_started_mux) (mpegts_input_t*,mpegts_mux_instance_t*); void (*mi_stopped_mux) (mpegts_input_t*,mpegts_mux_instance_t*); int (*mi_has_subscription) (mpegts_input_t*, mpegts_mux_t *mm); + int (*mi_grace_period) (mpegts_input_t*, mpegts_mux_t *mm); }; #endif /* __TVH_MPEGTS_H__ */ diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 1f2494ad..a1732eda 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -29,7 +29,6 @@ typedef struct linuxdvb_frontend linuxdvb_frontend_t; typedef struct linuxdvb_network linuxdvb_network_t; typedef struct linuxdvb_mux linuxdvb_mux_t; typedef struct linuxdvb_satconf linuxdvb_satconf_t; -typedef struct linuxdvb_lnb linuxdvb_lnb_t; typedef LIST_HEAD(,linuxdvb_hardware) linuxdvb_hardware_list_t; @@ -222,12 +221,21 @@ mpegts_service_t *linuxdvb_service_create0 const char *uuid, htsmsg_t *conf); /* - * LNB + * Diseqc gear */ +typedef struct linuxdvb_diseqc linuxdvb_diseqc_t; +typedef struct linuxdvb_lnb linuxdvb_lnb_t; + +struct linuxdvb_diseqc +{ + int (*ld_grace) (linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm); + int (*ld_tune) (linuxdvb_diseqc_t *ld, linuxdvb_mux_t *lm, int fd); +}; + struct linuxdvb_lnb { - uint32_t (*lnb_frequency)(linuxdvb_lnb_t*, linuxdvb_mux_t*); - int (*lnb_tune)(linuxdvb_lnb_t*, linuxdvb_mux_t *lm, int fd); + linuxdvb_diseqc_t; + uint32_t (*lnb_freq)(linuxdvb_lnb_t*, linuxdvb_mux_t*); }; /* @@ -237,9 +245,16 @@ struct linuxdvb_satconf { linuxdvb_frontend_t; - /* Links */ - mpegts_input_t *ls_frontend; - linuxdvb_lnb_t *ls_lnb; + mpegts_input_t *ls_frontend; + mpegts_mux_instance_t *ls_mmi; + + /* Diseqc gear */ + linuxdvb_lnb_t *ls_lnb; + linuxdvb_diseqc_t *ls_switch; + linuxdvb_diseqc_t *ls_rotor; + + gtimer_t ls_diseqc_timer; + int ls_diseqc_idx; }; void linuxdvb_satconf_init ( void ); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 56061173..c6abee71 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -231,6 +231,56 @@ linuxdvb_satconf_stop_mux { linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; ls->ls_frontend->mi_stop_mux(ls->ls_frontend, mmi); + gtimer_disarm(&ls->ls_diseqc_timer); +} + +static void linuxdvb_satconf_tune_cb ( void *o ); + +static int +linuxdvb_satconf_tune ( linuxdvb_satconf_t *ls ) +{ + int r, i; + uint32_t f; + + /* Get beans in a row */ + mpegts_mux_instance_t *mmi = ls->ls_mmi; + linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend; + linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mmi->mmi_mux; + linuxdvb_diseqc_t *lds[] = { + (linuxdvb_diseqc_t*)ls->ls_switch, + (linuxdvb_diseqc_t*)ls->ls_rotor, + (linuxdvb_diseqc_t*)ls->ls_lnb + }; + + /* Diseqc */ + i = ls->ls_diseqc_idx; + for (i = ls->ls_diseqc_idx; i < 3; i++) { + if (!lds[i]) continue; + r = lds[i]->ld_tune(lds[i], lm, lfe->lfe_fe_fd); + + /* Error */ + if (r < 0) return r; + + /* Pending */ + if (r != 0) { + gtimer_arm_ms(&ls->ls_diseqc_timer, linuxdvb_satconf_tune_cb, ls, r); + ls->ls_diseqc_idx = i + 1; + return 0; + } + } + + /* Frontend */ + f = ls->ls_lnb->lnb_freq(ls->ls_lnb, lm); + return linuxdvb_frontend_tune1(lfe, mmi, f); +} + +static void +linuxdvb_satconf_tune_cb ( void *o ) +{ + linuxdvb_satconf_t *ls = o; + if (linuxdvb_satconf_tune(ls) < 0) { + // TODO: how do we signal this? + } } static int @@ -239,9 +289,9 @@ linuxdvb_satconf_start_mux { int r; uint32_t f; - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)(mi = ls->ls_frontend); - linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mmi->mmi_mux; + linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; + linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend; + linuxdvb_mux_t *lm = (linuxdvb_mux_t*)mmi->mmi_mux; /* Test run */ // Note: basically this ensures the tuning params are acceptable @@ -249,22 +299,16 @@ linuxdvb_satconf_start_mux // for things like rotors and switches if (!ls->ls_lnb) return SM_CODE_TUNING_FAILED; - f = ls->ls_lnb->lnb_frequency(ls->ls_lnb, lm); + f = ls->ls_lnb->lnb_freq(ls->ls_lnb, lm); if (f == (uint32_t)-1) return SM_CODE_TUNING_FAILED; r = linuxdvb_frontend_tune0(lfe, mmi, f); if (r) return r; - - /* Switch */ - /* Rotor */ - - /* LNB */ - if (ls->ls_lnb->lnb_tune(ls->ls_lnb, lm, lfe->lfe_fe_fd)) - return SM_CODE_TUNING_FAILED; - - /* Tune */ - return linuxdvb_frontend_tune1(lfe, mmi, f); + /* Diseqc */ + ls->ls_mmi = mmi; + ls->ls_diseqc_idx = 0; + return linuxdvb_satconf_tune(ls); } static void @@ -307,6 +351,33 @@ linuxdvb_satconf_has_subscription return ls->ls_frontend->mi_has_subscription(ls->ls_frontend, mm); } +static int +linuxdvb_satconf_grace_period + ( mpegts_input_t *mi, mpegts_mux_t *mm ) +{ + int i, r; + linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)mi; + linuxdvb_diseqc_t *lds[] = { + (linuxdvb_diseqc_t*)ls->ls_switch, + (linuxdvb_diseqc_t*)ls->ls_rotor, + (linuxdvb_diseqc_t*)ls->ls_lnb + }; + + /* Get underlying value */ + if (ls->ls_frontend->mi_grace_period) + r = ls->ls_frontend->mi_grace_period(mi, mm); + else + r = 10; + + /* Add diseqc delay */ + for (i = 0; i < 3; i++) { + if (lds[i] && lds[i]->ld_grace) + r += lds[i]->ld_grace(lds[i], (linuxdvb_mux_t*)mm); + } + + return r; +} + static int linuxdvb_satconf_open_pid ( linuxdvb_frontend_t *lfe, int pid, const char *name ) @@ -320,27 +391,6 @@ linuxdvb_satconf_open_pid * Creation/Config * *************************************************************************/ -static uint32_t uni_freq - ( linuxdvb_lnb_t *lnb, linuxdvb_mux_t *lm ) -{ - dvb_mux_conf_t *dmc = &lm->lm_tuning; - struct dvb_frontend_parameters *p = &dmc->dmc_fe_params; - if (p->frequency > 11700000) - return abs(p->frequency - 10600000); - else - return abs(p->frequency - 9750000); -} - -static int uni_tune - ( linuxdvb_lnb_t *lnb, linuxdvb_mux_t *lm, int fd ) -{ - dvb_mux_conf_t *dmc = &lm->lm_tuning; - struct dvb_frontend_parameters *p = &dmc->dmc_fe_params; - int pol = dmc->dmc_fe_polarisation == POLARISATION_HORIZONTAL || - dmc->dmc_fe_polarisation == POLARISATION_CIRCULAR_LEFT; - return diseqc_setup(fd, 0, pol, p->frequency > 11700000, 0, 0); -} - linuxdvb_satconf_t * linuxdvb_satconf_create0 ( const char *uuid, htsmsg_t *conf ) @@ -361,13 +411,9 @@ linuxdvb_satconf_create0 ls->mi_started_mux = linuxdvb_satconf_started_mux; ls->mi_stopped_mux = linuxdvb_satconf_stopped_mux; ls->mi_has_subscription = linuxdvb_satconf_has_subscription; + ls->mi_grace_period = linuxdvb_satconf_grace_period; ls->lfe_open_pid = linuxdvb_satconf_open_pid; - /* Unoversal LMB */ - ls->ls_lnb = calloc(1, sizeof(linuxdvb_lnb_t)); - ls->ls_lnb->lnb_frequency = uni_freq; - ls->ls_lnb->lnb_tune = uni_tune; - return ls; } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_service.c b/src/input/mpegts/linuxdvb/linuxdvb_service.c index 168f2e4e..0081db56 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_service.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_service.c @@ -52,6 +52,6 @@ linuxdvb_service_create0 mpegts_service_t *s = mpegts_service_create1(uuid, (mpegts_mux_t*)mm, sid, pmt_pid, conf); if (s) - s->s_config_save = linuxdvb_service_config_save; + s->s_config_save = linuxdvb_service_config_save; return s; } diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index d20eb0ee..25aa36d4 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -248,6 +248,24 @@ mpegts_service_setsourceinfo(service_t *t, source_info_t *si) si->si_service = strdup(s->s_dvb_svcname); } +/* + * Grace period + */ +static int +mpegts_service_grace_period(service_t *t) +{ + int r = 0; + mpegts_service_t *ms = (mpegts_service_t*)t; + mpegts_mux_t *mm = ms->s_dvb_mux; + mpegts_input_t *mi = ms->s_dvb_active_input; + assert(mi != NULL); + + if (mi && mi->mi_grace_period) + r = mi->mi_grace_period(mi, mm); + + return r ?: 10; +} + /* ************************************************************************** * Creation/Location * *************************************************************************/ @@ -279,9 +297,7 @@ mpegts_service_create0 s->s_stop_feed = mpegts_service_stop; s->s_refresh_feed = mpegts_service_refresh; s->s_setsourceinfo = mpegts_service_setsourceinfo; -#if 0 s->s_grace_period = mpegts_service_grace_period; -#endif pthread_mutex_lock(&s->s_stream_mutex); service_make_nicename((service_t*)s);