Index: /trunk/tvheadend/src/transports.c
===================================================================
--- /trunk/tvheadend/src/transports.c (revision 3078)
+++ /trunk/tvheadend/src/transports.c (revision 3083)
@@ -472,14 +472,12 @@
 /**
  * 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);
 
@@ -491,6 +489,6 @@
 
   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));
@@ -507,6 +505,27 @@
   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: /trunk/tvheadend/src/rawtsinput.c
===================================================================
--- /trunk/tvheadend/src/rawtsinput.c (revision 3081)
+++ /trunk/tvheadend/src/rawtsinput.c (revision 3083)
@@ -196,7 +196,10 @@
       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: /trunk/tvheadend/src/transports.h
===================================================================
--- /trunk/tvheadend/src/transports.h (revision 3026)
+++ /trunk/tvheadend/src/transports.h (revision 3083)
@@ -43,6 +43,8 @@
 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: /trunk/tvheadend/src/tvhead.h
===================================================================
--- /trunk/tvheadend/src/tvhead.h (revision 3077)
+++ /trunk/tvheadend/src/tvhead.h (revision 3083)
@@ -579,12 +579,6 @@
 
   /**
-   * 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
-   */
-  int tht_pmt_seen;
-
-
+   * List of all components.
+   */
   struct th_stream_list tht_components;
 
Index: /trunk/tvheadend/src/dvb/dvb_adapter.c
===================================================================
--- /trunk/tvheadend/src/dvb/dvb_adapter.c (revision 3040)
+++ /trunk/tvheadend/src/dvb/dvb_adapter.c (revision 3083)
@@ -372,7 +372,7 @@
       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: /trunk/tvheadend/src/psi.c
===================================================================
--- /trunk/tvheadend/src/psi.c (revision 3077)
+++ /trunk/tvheadend/src/psi.c (revision 3083)
@@ -93,8 +93,9 @@
 
     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;
@@ -165,9 +166,30 @@
 
 
+/**
+ * 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)
@@ -182,4 +204,6 @@
   char lang[4];
   int frameduration;
+  int need_save = 0;
+
   if(len < 9)
     return -1;
@@ -191,11 +215,14 @@
   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) {
@@ -209,6 +236,5 @@
     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;
 
@@ -263,6 +289,5 @@
       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;
 
@@ -297,17 +322,27 @@
 
     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;
-    }
-  }
-
-  if(t->tht_pmt_seen == 0)
+	need_save = 1;
+      }
+    }
+  }
+
+  if(need_save)
     t->tht_config_change(t);
 
-  t->tht_pmt_seen = 1;
   return 0;
 }
@@ -636,5 +671,5 @@
       continue;
 
-    st = transport_add_stream(t, pid, type);
+    st = transport_stream_create(t, pid, type);
     st->st_tb = (AVRational){1, 90000};
     
