From: Jaroslav Kysela Date: Thu, 1 Nov 2018 14:28:25 +0000 (+0100) Subject: linuxdvb: try to improve the rotor logic (finish the movement), issue #5307 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c4f22d84a09f9b154a236dca1617ec0169499c54;p=thirdparty%2Ftvheadend.git linuxdvb: try to improve the rotor logic (finish the movement), issue #5307 --- diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index 3b468f48e..113a90735 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -874,6 +874,11 @@ linuxdvb_frontend_monitor ( void *aux ) /* Close FE */ if (lfe->lfe_fe_fd > 0 && !lfe->lfe_refcount && lfe->lfe_powersave) { + if (linuxdvb_satconf_power_save(lfe->lfe_satconf) > 0) { + /* re-arm */ + mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, sec2mono(1)); + return; + } linuxdvb_frontend_close_fd(lfe, buf); return; } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index 5956c08fc..2ace1d746 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -275,12 +275,14 @@ struct linuxdvb_satconf */ linuxdvb_satconf_ele_list_t ls_elements; linuxdvb_satconf_ele_t *ls_last_switch; + linuxdvb_diseqc_t *ls_active_diseqc; int ls_last_switch_pol; int ls_last_switch_band; int ls_last_vol; int ls_last_toneburst; int ls_last_tone_off; int ls_last_orbital_pos; + int ls_last_queued_pos; }; /* @@ -324,10 +326,12 @@ struct linuxdvb_diseqc int (*ld_grace) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm); int (*ld_freq) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm, int freq); int (*ld_match) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm1, dvb_mux_t *lm2); + int (*ld_start) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm, + linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls); int (*ld_tune) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, int vol, int pol, int band, int freq); - int (*ld_post) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm, + int (*ld_post) (linuxdvb_diseqc_t *ld, linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls); }; @@ -553,6 +557,8 @@ int linuxdvb_satconf_lnb_freq void linuxdvb_satconf_post_stop_mux( linuxdvb_satconf_t *ls ); +int linuxdvb_satconf_power_save( linuxdvb_satconf_t *ls ); + int linuxdvb_satconf_start_mux ( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi, int skip_diseqc ); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c index 68b95879d..86b2791de 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c @@ -432,6 +432,7 @@ linuxdvb_rotor_tune int vol, int pol, int band, int freq ) { linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld; + int res; if (linuxdvb_rotor_check_orbital_pos(lr, lm, ls)) return 0; @@ -442,20 +443,40 @@ linuxdvb_rotor_tune /* GotoX */ if (idnode_is_instance(&lr->ld_id, &linuxdvb_rotor_gotox_class)) - return linuxdvb_rotor_gotox_tune(lr, lm, lsp, ls); - + res = linuxdvb_rotor_gotox_tune(lr, lm, lsp, ls); /* USALS */ - return linuxdvb_rotor_usals_tune(lr, lm, lsp, ls); + else + res = linuxdvb_rotor_usals_tune(lr, lm, lsp, ls); + + if (res < 0) + return res; + + lsp->ls_last_queued_pos = pos_to_integer(lr->lr_sat_lon); + return res; } static int -linuxdvb_rotor_post +linuxdvb_rotor_start ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls ) { linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld; + int pos = pos_to_integer(lr->lr_sat_lon); + if (lsp->ls_last_queued_pos == pos) + return 1; + lsp->ls_last_queued_pos = 0; + return 0; +} + +static int +linuxdvb_rotor_post + ( linuxdvb_diseqc_t *ld, + linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls ) +{ + linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld; lsp->ls_last_orbital_pos = pos_to_integer(lr->lr_sat_lon); + lsp->ls_last_queued_pos = 0; return 0; } @@ -502,6 +523,7 @@ linuxdvb_rotor_create0 NULL, linuxdvb_rotor_all[i].idc, conf, linuxdvb_rotor_all[i].name, ls); if (ld) { + ld->ld_start = linuxdvb_rotor_start; ld->ld_tune = linuxdvb_rotor_tune; ld->ld_grace = linuxdvb_rotor_grace; ld->ld_post = linuxdvb_rotor_post; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 52f502b2b..673ad759a 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -872,11 +872,20 @@ linuxdvb_satconf_post_stop_mux ( linuxdvb_satconf_t *ls ) { ls->ls_mmi = NULL; +} + +int +linuxdvb_satconf_power_save + ( linuxdvb_satconf_t *ls ) +{ + if (ls->ls_active_diseqc) /* wait for the timer to finish things */ + return 1; mtimer_disarm(&ls->ls_diseqc_timer); if (ls->ls_frontend && ls->ls_lnb_poweroff) { linuxdvb_diseqc_set_volt(ls, -1); linuxdvb_satconf_reset(ls); } + return 0; } int @@ -937,6 +946,16 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) /* Get beans in a row */ mpegts_mux_instance_t *mmi = ls->ls_mmi; + + if (mmi == NULL && ls->ls_active_diseqc) { + /* handle the rotor position update */ + if (ls->ls_active_diseqc == lse->lse_rotor) + lse->lse_rotor->ld_post(lse->lse_rotor, ls, lse); + ls->ls_active_diseqc = NULL; + linuxdvb_satconf_power_save(ls); + return 0; + } + linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend; dvb_mux_t *lm = (dvb_mux_t*)mmi->mmi_mux; linuxdvb_diseqc_t *lds[] = { @@ -978,6 +997,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) } /* Diseqc */ + ls->ls_active_diseqc = NULL; for (i = ls->ls_diseqc_idx; i < ARRAY_SIZE(lds); i++) { if (!lds[i]) continue; r = lds[i]->ld_tune(lds[i], lm, ls, lse, vol, pol, band, freq); @@ -987,6 +1007,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) /* Pending */ if (r != 0) { + ls->ls_active_diseqc = lds[i]; tvhtrace(LS_DISEQC, "waiting %d seconds to finish setup for %s", r, lds[i]->ld_type); mtimer_arm_rel(&ls->ls_diseqc_timer, linuxdvb_satconf_ele_tune_cb, lse, sec2mono(r)); ls->ls_diseqc_idx = i + 1; @@ -996,7 +1017,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) /* Do post things (store position for rotor) */ if (lse->lse_rotor) - lse->lse_rotor->ld_post(lse->lse_rotor, lm, ls, lse); + lse->lse_rotor->ld_post(lse->lse_rotor, ls, lse); /* LNB settings */ /* EN50494 devices have another mechanism to select polarization */ @@ -1100,6 +1121,10 @@ linuxdvb_satconf_start_mux /* Diseqc */ ls->ls_mmi = mmi; ls->ls_diseqc_idx = 0; + if (lse->lse_rotor) + if (lse->lse_rotor->ld_start(lse->lse_rotor, (dvb_mux_t *)mmi->mmi_mux, ls, lse)) + return 0; + return linuxdvb_satconf_ele_tune(lse); }