]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Figure out if we need to re-save a transport configuration instead of relying on...
authorAndreas Öman <andreas@lonelycoder.com>
Mon, 22 Jun 2009 19:51:10 +0000 (19:51 +0000)
committerAndreas Öman <andreas@lonelycoder.com>
Mon, 22 Jun 2009 19:51:10 +0000 (19:51 +0000)
src/dvb/dvb_adapter.c
src/psi.c
src/rawtsinput.c
src/transports.c
src/transports.h
src/tvhead.h

index b8440fd5125aa2fc9692f9a04472f0d21329eb96..ea45e4bf77e18fc003b69984b4a6c9f3e14f2cef 100644 (file)
@@ -371,9 +371,9 @@ dvb_adapter_clone(th_dvb_adapter_t *dst, th_dvb_adapter_t *src)
 
       LIST_FOREACH(st_src, &t_src->tht_components, st_link) {
 
-       st_dst = transport_add_stream(t_dst, 
-                                     st_src->st_pid,
-                                     st_src->st_type);
+       st_dst = transport_stream_create(t_dst, 
+                                        st_src->st_pid,
+                                        st_src->st_type);
        
        st_dst->st_tb = (AVRational){1, 90000};
        
index c6d9066a0c57364abe698053c6ed55993fc8a20c..9f9ed21bccd3acfe1028dee5a6cdd9d27807668c 100644 (file)
--- a/src/psi.c
+++ b/src/psi.c
@@ -92,10 +92,11 @@ psi_parse_pat(th_transport_t *t, uint8_t *ptr, int len,
     pid     = (ptr[2] & 0x1f) << 8 | ptr[3];
 
     if(prognum != 0) {
-      st = transport_add_stream(t, pid, SCT_PMT);
-      st->st_section_docrc = 1;
-      st->st_got_section = pmt_callback;
-
+      if(transport_stream_find(t, pid) == NULL) {
+       st = transport_stream_create(t, pid, SCT_PMT);
+       st->st_section_docrc = 1;
+       st->st_got_section = pmt_callback;
+      }
     }
     ptr += 4;
     len -= 4;
@@ -164,11 +165,32 @@ psi_build_pat(th_transport_t *t, uint8_t *buf, int maxlen, int pmtpid)
 
 
 
+/**
+ * Parser for CA descriptor
+ */
+static int
+psi_desc_ca(th_transport_t *t, uint8_t *ptr)
+{
+  uint16_t pid = (ptr[2] & 0x1f) << 8 | ptr[3];
+  th_stream_t *st;
+  int r = 0;
+  uint16_t caid = (ptr[0] << 8) | ptr[1];
+
+  if((st = transport_stream_find(t, pid)) == NULL) {
+    st = transport_stream_create(t, pid, SCT_CA);
+    r = 1;
+  }
+
+  if(st->st_caid != caid) {
+    st->st_caid = caid;
+    r = 1;
+  }
+  return r;
+}
 
 /** 
  * PMT parser, from ISO 13818-1 and ETSI EN 300 468
  */
-
 int
 psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid)
 {
@@ -181,6 +203,8 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid)
   th_stream_t *st;
   char lang[4];
   int frameduration;
+  int need_save = 0;
+
   if(len < 9)
     return -1;
 
@@ -190,14 +214,17 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid)
   pcr_pid = (ptr[5] & 0x1f) << 8 | ptr[6];
   dllen   = (ptr[7] & 0xf) << 8 | ptr[8];
   
-  t->tht_pcr_pid = pcr_pid;
+  if(chksvcid && sid != t->tht_dvb_service_id)
+    return -1;
+
+  if(t->tht_pcr_pid != pcr_pid) {
+    t->tht_pcr_pid = pcr_pid;
+    need_save = 1;
+  }
 
   ptr += 9;
   len -= 9;
 
-  if(chksvcid && sid != t->tht_dvb_service_id)
-    return -1;
-
   while(dllen > 1) {
     dtag = ptr[0];
     dlen = ptr[1];
@@ -208,8 +235,7 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid)
 
     switch(dtag) {
     case DVB_DESC_CA:
-      st = transport_add_stream(t, (ptr[2] & 0x1f) << 8 | ptr[3], SCT_CA);
-      st->st_caid = (ptr[0] << 8) | ptr[1];
+      need_save |= psi_desc_ca(t, ptr);
       break;
 
     default:
@@ -262,8 +288,7 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid)
 
       switch(dtag) {
       case DVB_DESC_CA:
-       st = transport_add_stream(t, (ptr[2] & 0x1f) << 8 | ptr[3], SCT_CA);
-       st->st_caid = (ptr[0] << 8) | ptr[1];
+       need_save |= psi_desc_ca(t, ptr);
        break;
 
       case DVB_DESC_VIDEO_STREAM:
@@ -296,19 +321,29 @@ psi_parse_pmt(th_transport_t *t, uint8_t *ptr, int len, int chksvcid)
     }
 
     if(hts_stream_type != 0) {
-      st = transport_add_stream(t, pid, hts_stream_type);
+
+      if((st = transport_stream_find(t, pid)) == NULL) {
+       need_save = 1;
+       st = transport_stream_create(t, pid, hts_stream_type);
+      }
+
       st->st_tb = (AVRational){1, 90000};
-      memcpy(st->st_lang, lang, 4);
 
-      if(st->st_frame_duration == 0)
+      if(memcmp(st->st_lang, lang, 4)) {
+       need_save = 1;
+       memcpy(st->st_lang, lang, 4);
+      }
+
+      if(st->st_frame_duration == 0 && frameduration != 0) {
        st->st_frame_duration = frameduration;
+       need_save = 1;
+      }
     }
   }
 
-  if(t->tht_pmt_seen == 0)
+  if(need_save)
     t->tht_config_change(t);
 
-  t->tht_pmt_seen = 1;
   return 0;
 }
 
@@ -635,7 +670,7 @@ psi_load_transport_settings(htsmsg_t *m, th_transport_t *t)
     if(htsmsg_get_u32(c, "pid", &pid))
       continue;
 
-    st = transport_add_stream(t, pid, type);
+    st = transport_stream_create(t, pid, type);
     st->st_tb = (AVRational){1, 90000};
     
     if((v = htsmsg_get_str(c, "language")) != NULL)
index ba99d4d7fc038d2fc457ce9fef55523200f1f515..f0029888a53a112e56abab4ca24e778b5ee8ab75 100644 (file)
@@ -195,9 +195,12 @@ got_pat(rawts_t *rt)
 
       if(t != NULL) {
        pthread_mutex_lock(&t->tht_stream_mutex);
-       st = transport_add_stream(t, pid, SCT_PMT);
-       st->st_section_docrc = 1;
-       st->st_got_section = got_pmt;
+
+       if(transport_stream_find(t, pid) == NULL) {
+         st = transport_stream_create(t, pid, SCT_PMT);
+         st->st_section_docrc = 1;
+         st->st_got_section = got_pmt;
+       }
        pthread_mutex_unlock(&t->tht_stream_mutex);
       }
     }
index 688187f610929464c24795523453679b6409f37f..853379bfed04ab65759a365c4d34731e9c3f4966 100644 (file)
@@ -471,16 +471,14 @@ transport_find_by_identifier(const char *identifier)
 
 /**
  * Add a new stream to a transport
- *
- * 
  */
 th_stream_t *
-transport_add_stream(th_transport_t *t, int pid,
-                    streaming_component_type_t type)
+transport_stream_create(th_transport_t *t, int pid,
+                       streaming_component_type_t type)
 {
   th_stream_t *st;
   int i = 0;
-
   lock_assert(&t->tht_stream_mutex);
 
   LIST_FOREACH(st, &t->tht_components, st_link) {
@@ -490,8 +488,8 @@ transport_add_stream(th_transport_t *t, int pid,
   }
 
   if(t->tht_flags & THT_DEBUG)
-      tvhlog(LOG_DEBUG, "transport", "%s: Add stream \"%s\", pid: %d",
-            t->tht_identifier, streaming_component_type2txt(type), pid);
+    tvhlog(LOG_DEBUG, "transport", "%s: Add stream \"%s\", pid: %d",
+          t->tht_identifier, streaming_component_type2txt(type), pid);
 
   st = calloc(1, sizeof(th_stream_t));
   st->st_index = i;
@@ -506,10 +504,31 @@ transport_add_stream(th_transport_t *t, int pid,
 
   avgstat_init(&st->st_rate, 10);
   avgstat_init(&st->st_cc_errors, 10);
+
   return st;
 }
 
 
+
+/**
+ * Add a new stream to a transport
+ */
+th_stream_t *
+transport_stream_find(th_transport_t *t, int pid)
+{
+  th_stream_t *st;
+  lock_assert(&t->tht_stream_mutex);
+
+  LIST_FOREACH(st, &t->tht_components, st_link) {
+    if(st->st_pid == pid)
+      return st;
+  }
+  return NULL;
+}
+
+
+
 /**
  *
  */
index efac9ecb9bd434929de223b14abae607ce95efb3..1a9d63f5292e0636d0a08936fe06e96f9ef165a9 100644 (file)
@@ -42,8 +42,10 @@ void transport_unmap_channel(th_transport_t *t);
 
 th_transport_t *transport_find(channel_t *ch, unsigned int weight);
 
-th_stream_t *transport_add_stream(th_transport_t *t, int pid,
-                                 streaming_component_type_t type);
+th_stream_t *transport_stream_find(th_transport_t *t, int pid);
+
+th_stream_t *transport_stream_create(th_transport_t *t, int pid,
+                                    streaming_component_type_t type);
 
 void transport_set_priority(th_transport_t *t, int prio);
 
index 644da8fb7d4eec4c7800af97d661136839962563..28f490a1bf882ca8b6c2ef0c29423575e372cb46 100644 (file)
@@ -578,14 +578,8 @@ typedef struct th_transport {
   int64_t  tht_pcr_drift;
 
   /**
-   * Set if we've seen the PMT. Used to avoid (re)saving the transport
-   * for everytime we see a PMT. 
-   * XXX: Not very good, should be replaced with more intelligent
-   * code in psi.c
+   * List of all components.
    */
-  int tht_pmt_seen;
-
-
   struct th_stream_list tht_components;