]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
mpegts: another PID subscription shuffling
authorJaroslav Kysela <perex@perex.cz>
Tue, 5 May 2015 07:32:08 +0000 (09:32 +0200)
committerJaroslav Kysela <perex@perex.cz>
Tue, 5 May 2015 07:33:26 +0000 (09:33 +0200)
src/input/mpegts.h
src/input/mpegts/dvb_psi.c
src/input/mpegts/mpegts_input.c
src/input/mpegts/mpegts_mux.c
src/input/mpegts/mpegts_service.c

index 1204526f0413a760164bc75853f90f6f85f97a8e..f3c4378806bce31e9bca2a4c9a725ebc6ff4e9ef 100644 (file)
@@ -388,6 +388,9 @@ struct mpegts_mux
   uint16_t                mm_onid;
   uint16_t                mm_tsid;
 
+  int                     mm_update_pids_flag;
+  gtimer_t                mm_update_pids_timer;
+
   /*
    * Services
    */
@@ -868,6 +871,8 @@ mpegts_mux_find_pid(mpegts_mux_t *mm, int pid, int create)
     return mm->mm_last_mp;
 }
 
+void mpegts_mux_update_pids ( mpegts_mux_t *mm );
+
 void mpegts_input_recv_packets
   (mpegts_input_t *mi, mpegts_mux_instance_t *mmi, sbuf_t *sb,
    int64_t *pcr, uint16_t *pcr_pid);
index 2b4ed6f2ba248a68c459e2b6bb30125837ce6aeb..77228cabe3c5677747935d4ac93ade6c95fcc977 100644 (file)
@@ -2537,5 +2537,5 @@ psi_tables_install ( mpegts_input_t *mi, mpegts_mux_t *mm,
     break;
   }
 
-  mi->mi_update_pids(mi, mm);
+  mpegts_mux_update_pids(mm);
 }
index 63446348f72c278d8f97ba12469a8623b32071d2..541c24641a4f1bac73f69ced2a12739111462d92 100644 (file)
@@ -453,6 +453,7 @@ mpegts_input_open_pid
         mpegts_mux_nice_name(mm, buf, sizeof(buf));
         tvhdebug("mpegts", "%s - open PID %s subscription [%04x/%p]",
                  buf, (type & MPS_TABLES) ? "tables" : "fullmux", type, owner);
+        mm->mm_update_pids_flag = 1;
       }
     } else if (!RB_INSERT_SORTED(&mp->mp_subs, mps, mps_link, mpegts_mps_cmp)) {
       mp->mp_type |= type;
@@ -461,6 +462,7 @@ mpegts_input_open_pid
       mpegts_mux_nice_name(mm, buf, sizeof(buf));
       tvhdebug("mpegts", "%s - open PID %04X (%d) [%d/%p]",
                buf, mp->mp_pid, mp->mp_pid, type, owner);
+      mm->mm_update_pids_flag = 1;
     } else {
       free(mps);
       mp = NULL;
@@ -493,6 +495,7 @@ mpegts_input_close_pid
       mpegts_input_close_pids(mi, mm, owner, 0);
     LIST_REMOVE(mps, mps_svcraw_link);
     free(mps);
+    mm->mm_update_pids_flag = 1;
     mask = pid == MPEGTS_FULLMUX_PID ? MPS_ALL : MPS_TABLES;
     LIST_FOREACH(mps, &mm->mm_all_subs, mps_svcraw_link)
       if (mps->mps_type & mask) break;
@@ -514,6 +517,7 @@ mpegts_input_close_pid
         LIST_REMOVE(mps, mps_svcraw_link);
       RB_REMOVE(&mp->mp_subs, mps, mps_link);
       free(mps);
+      mm->mm_update_pids_flag = 1;
     }
   }
   if (!RB_FIRST(&mp->mp_subs)) {
@@ -623,9 +627,7 @@ mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags,
                        MT_CRC, s->s_pmt_pid, MPS_WEIGHT_PMT);
   }
 
-  pthread_mutex_lock(&mi->mi_output_lock);
-  mi->mi_update_pids(mi, mm);
-  pthread_mutex_unlock(&mi->mi_output_lock);
+  mpegts_mux_update_pids(mm);
 }
 
 void
@@ -681,9 +683,9 @@ mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s )
   }
 
   pthread_mutex_unlock(&s->s_stream_mutex);
-  mi->mi_update_pids(mi, mm);
   pthread_mutex_unlock(&mi->mi_output_lock);
 
+  mpegts_mux_update_pids(mm);
 
   /* Stop mux? */
   s->s_dvb_mux->mm_stop(s->s_dvb_mux, 0, SM_CODE_OK);
@@ -979,7 +981,6 @@ static void
 mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm )
 {
   mpegts_table_t *mt;
-  int update = 0;
 
   if (!mm || !mm->mm_active)
     return;
@@ -993,7 +994,6 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm )
         mt->mt_subscribed = 1;
         pthread_mutex_unlock(&mm->mm_tables_lock);
         mpegts_input_open_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
-        update = 1;
       } else {
         pthread_mutex_unlock(&mm->mm_tables_lock);
       }
@@ -1003,7 +1003,6 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm )
         mt->mt_subscribed = 0;
         pthread_mutex_unlock(&mm->mm_tables_lock);
         mpegts_input_close_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
-        update = 1;
       } else {
         pthread_mutex_unlock(&mm->mm_tables_lock);
       }
@@ -1015,8 +1014,6 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm )
   }
   mpegts_table_consistency_check(mm);
   pthread_mutex_unlock(&mm->mm_tables_lock);
-  if (update)
-    mi->mi_update_pids(mi, mm);
 }
 
 #if ENABLE_TSDEBUG
@@ -1258,8 +1255,20 @@ mpegts_input_thread ( void * p )
     /* Process */
     pthread_mutex_lock(&mi->mi_output_lock);
     mpegts_input_table_waiting(mi, mp->mp_mux);
+    if (mp->mp_mux && mp->mp_mux->mm_update_pids_flag) {
+      pthread_mutex_unlock(&mi->mi_output_lock);
+      pthread_mutex_lock(&global_lock);
+      mpegts_mux_update_pids(mp->mp_mux);
+      pthread_mutex_unlock(&global_lock);
+      pthread_mutex_lock(&mi->mi_output_lock);
+    }
     mpegts_input_process(mi, mp);
     pthread_mutex_unlock(&mi->mi_output_lock);
+    if (mp->mp_mux && mp->mp_mux->mm_update_pids_flag) {
+      pthread_mutex_lock(&global_lock);
+      mpegts_mux_update_pids(mp->mp_mux);
+      pthread_mutex_unlock(&global_lock);
+    }
 
     /* Cleanup */
     free(mp);
index 376913035b7ffd96ebba4dba167662cc8db5bbaf..2938097ae83f3e35a53a41d34cb6b080ad7eeb7f 100644 (file)
@@ -635,6 +635,9 @@ mpegts_mux_delete ( mpegts_mux_t *mm, int delconf )
     service_destroy((service_t*)s, delconf);
   }
 
+  /* Stop PID timer */
+  gtimer_disarm(&mm->mm_update_pids_timer);
+
   /* Free memory */
   idnode_unlink(&mm->mm_id);
   free(mm->mm_crid_authority);
@@ -775,6 +778,29 @@ mpegts_mux_stop ( mpegts_mux_t *mm, int force, int reason )
   mm->mm_fastscan_muxes = NULL;
 }
 
+static void
+mpegts_mux_update_pids_cb ( void *aux )
+{
+  mpegts_mux_t *mm = aux;
+  mpegts_input_t *mi;
+
+  if (mm && mm->mm_active) {
+    mi = mm->mm_active->mmi_input;
+    if (mi) {
+      pthread_mutex_lock(&mi->mi_output_lock);
+      mi->mi_update_pids(mi, mm);
+      pthread_mutex_unlock(&mi->mi_output_lock);
+    }
+  }
+}
+
+void
+mpegts_mux_update_pids ( mpegts_mux_t *mm )
+{
+  if (mm && mm->mm_active)
+    gtimer_arm(&mm->mm_update_pids_timer, mpegts_mux_update_pids_cb, mm, 0);
+}
+
 void
 mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe )
 {
@@ -809,7 +835,6 @@ mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe )
     pthread_mutex_unlock(&mm->mm_tables_lock);
     pthread_mutex_lock(&mi->mi_output_lock);
     mpegts_input_open_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
-    mi->mi_update_pids(mi, mm);
     pthread_mutex_unlock(&mi->mi_output_lock);
     pthread_mutex_lock(&mm->mm_tables_lock);
     mpegts_table_release(mt);
@@ -830,7 +855,6 @@ mpegts_mux_unsubscribe_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
     pthread_mutex_unlock(&mm->mm_tables_lock);
     pthread_mutex_lock(&mi->mi_output_lock);
     mpegts_input_close_pid(mi, mm, mt->mt_pid, mpegts_table_type(mt), mt->mt_weight, mt);
-    mi->mi_update_pids(mi, mm);
     pthread_mutex_unlock(&mi->mi_output_lock);
     pthread_mutex_lock(&mm->mm_tables_lock);
     mpegts_table_release(mt);
index 28d73ee2c0f19406202782eab423b0725a8c1b86..0a2f6a154dcc028af665cd1a5963fd554270c7ad 100644 (file)
@@ -776,8 +776,8 @@ mpegts_service_raw_update_pids(mpegts_service_t *t, mpegts_apids_t *pids)
       }
     }
     pthread_mutex_unlock(&t->s_stream_mutex);
-    mi->mi_update_pids(mi, mm);
     pthread_mutex_unlock(&mi->mi_output_lock);
+    mpegts_mux_update_pids(mm);
   } else {
     pthread_mutex_lock(&t->s_stream_mutex);
     x = t->s_pids;