]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
linuxdvb: try to improve the rotor logic (finish the movement), issue #5307
authorJaroslav Kysela <perex@perex.cz>
Thu, 1 Nov 2018 14:28:25 +0000 (15:28 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 1 Nov 2018 14:28:25 +0000 (15:28 +0100)
src/input/mpegts/linuxdvb/linuxdvb_frontend.c
src/input/mpegts/linuxdvb/linuxdvb_private.h
src/input/mpegts/linuxdvb/linuxdvb_rotor.c
src/input/mpegts/linuxdvb/linuxdvb_satconf.c

index 3b468f48ea3e675dfda74b1ca4df1fec78b57cbf..113a90735862b746ab8e5b333302b45eea5631fa 100644 (file)
@@ -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;
   }
index 5956c08fcd1a48f175bc6f7f3240ce437c135076..2ace1d746e528d7c1c934a90d12bca16a0f5dc99 100644 (file)
@@ -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 );
 
index 68b95879dae79ac7d3ad98dfe1a88881dce48bfe..86b2791de58920664c7cf59e521b97b2b8adc446 100644 (file)
@@ -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;
index 52f502b2b2d6cc432044105e69725a3b16179b86..673ad759a34791df0a5f989de9cafe9ed2ceb55b 100644 (file)
@@ -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);
 }