]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
dvb: Move low level DVB table reception to dvb_input_filtered.c
authorAndreas Öman <andreas@lonelycoder.com>
Fri, 19 Oct 2012 11:00:17 +0000 (13:00 +0200)
committerAndreas Öman <andreas@lonelycoder.com>
Thu, 25 Oct 2012 11:06:05 +0000 (13:06 +0200)
src/dvb/dvb.h
src/dvb/dvb_adapter.c
src/dvb/dvb_input_filtered.c
src/dvb/dvb_tables.c

index 63cbae670772d66f00cc71efb523710bddfda88b..8afe3ae5991e4ae4660f5e0eec133b25c498250b 100644 (file)
@@ -25,6 +25,8 @@
 #include "htsmsg.h"
 
 struct service;
+struct th_dvb_table;
+struct th_dvb_mux_instance;
 
 #define DVB_VER_INT(maj,min) (((maj) << 16) + (min))
 
@@ -235,6 +237,8 @@ typedef struct th_dvb_adapter {
 
   void (*tda_open_service)(struct th_dvb_adapter *tda, struct service *s);
   void (*tda_close_service)(struct th_dvb_adapter *tda, struct service *s);
+  void (*tda_open_table)(struct th_dvb_mux_instance *tdmi, struct th_dvb_table *s);
+  void (*tda_close_table)(struct th_dvb_mux_instance *tdmi, struct th_dvb_table *s);
 
 } th_dvb_adapter_t;
 
@@ -458,6 +462,8 @@ void dvb_table_add_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid);
 
 void dvb_table_rem_pmt(th_dvb_mux_instance_t *tdmi, int pmt_pid);
 
+void dvb_table_fastswitch(th_dvb_mux_instance_t *tdmi);
+
 void tdt_add(th_dvb_mux_instance_t *tdmi, int table, int mask,
             int (*callback)(th_dvb_mux_instance_t *tdmi, uint8_t *buf, int len,
                             uint8_t tableid, void *opaque), void *opaque,
index 83e2d4d0caa043e7f75ffb5a2c98fdd8ea5c8ee7..8f136540d57791699c9021555945c179c4377257 100644 (file)
@@ -68,8 +68,6 @@ tda_alloc(void)
   tda->tda_allpids_dmx_fd = -1;
   tda->tda_dump_fd = -1;
 
-  dvb_input_filtered_setup(tda);
-
   return tda;
 }
 
@@ -479,8 +477,7 @@ tda_add(int adapter_num)
 
   TAILQ_INSERT_TAIL(&dvb_adapters, tda, tda_global_link);
 
-
-  dvb_table_init(tda);
+  dvb_input_filtered_setup(tda);
 
   if(tda->tda_sat)
     dvb_satconf_init(tda);
index 59d934f8d26085849ba801f230907b9d0a50a808..468b524f938eabd6cbeedf23296687500d75722d 100644 (file)
@@ -19,7 +19,7 @@
 /**
  * DVB input using hardware filters
  */
-
+#include <assert.h>
 #include <sys/ioctl.h>
 #include <unistd.h>
 #include <string.h>
@@ -27,6 +27,7 @@
 #include <fcntl.h>
 #include <linux/dvb/frontend.h>
 #include <linux/dvb/dmx.h>
+#include <sys/epoll.h>
 
 #include "tvheadend.h"
 #include "dvb.h"
@@ -105,11 +106,197 @@ close_service(th_dvb_adapter_t *tda, service_t *s)
 
 
 
+/**
+ *
+ */
+static void
+open_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
+{
+  th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
+  struct epoll_event e;
+  static int tdt_id_tally;
+
+  assert(tdt->tdt_fd == -1);
+  TAILQ_REMOVE(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
+
+  tdt->tdt_fd = tvh_open(tda->tda_demux_path, O_RDWR, 0);
+
+  if(tdt->tdt_fd != -1) {
+
+    tdt->tdt_id = ++tdt_id_tally;
+
+    e.events = EPOLLIN;
+    e.data.u64 = ((uint64_t)tdt->tdt_fd << 32) | tdt->tdt_id;
+
+    if(epoll_ctl(tda->tda_table_epollfd, EPOLL_CTL_ADD, tdt->tdt_fd, &e)) {
+      close(tdt->tdt_fd);
+      tdt->tdt_fd = -1;
+    } else {
+
+      struct dmx_sct_filter_params fp = {0};
+  
+      fp.filter.filter[0] = tdt->tdt_table;
+      fp.filter.mask[0]   = tdt->tdt_mask;
+
+      if(tdt->tdt_flags & TDT_CRC)
+       fp.flags |= DMX_CHECK_CRC;
+      fp.flags |= DMX_IMMEDIATE_START;
+      fp.pid = tdt->tdt_pid;
+
+      if(ioctl(tdt->tdt_fd, DMX_SET_FILTER, &fp)) {
+       close(tdt->tdt_fd);
+       tdt->tdt_fd = -1;
+      }
+    }
+  }
+
+  if(tdt->tdt_fd == -1)
+    TAILQ_INSERT_TAIL(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
+}
+
+
+/**
+ * Close FD for the given table and put table on the pending list
+ */
+static void
+tdt_close_fd(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
+{
+  th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
+
+  assert(tdt->tdt_fd != -1);
+
+  epoll_ctl(tda->tda_table_epollfd, EPOLL_CTL_DEL, tdt->tdt_fd, NULL);
+  close(tdt->tdt_fd);
+
+  tdt->tdt_fd = -1;
+  TAILQ_INSERT_TAIL(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
+}
+
+
+/**
+ *
+ */
+static void
+dvb_proc_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt, uint8_t *sec,
+              int r)
+{
+  int chkcrc = tdt->tdt_flags & TDT_CRC;
+  int tableid, len;
+  uint8_t *ptr;
+  int ret;
+
+  /* It seems some hardware (or is it the dvb API?) does not
+     honour the DMX_CHECK_CRC flag, so we check it again */
+  if(chkcrc && tvh_crc32(sec, r, 0xffffffff))
+    return;
+      
+  r -= 3;
+  tableid = sec[0];
+  len = ((sec[1] & 0x0f) << 8) | sec[2];
+  
+  if(len < r)
+    return;
+
+  ptr = &sec[3];
+  if(chkcrc) len -= 4;   /* Strip trailing CRC */
+
+  if(tdt->tdt_flags & TDT_CA)
+    ret = tdt->tdt_callback((th_dvb_mux_instance_t *)tdt,
+                                sec, len + 3, tableid, tdt->tdt_opaque);
+  else if(tdt->tdt_flags & TDT_TDT)
+    ret = tdt->tdt_callback(tdmi, ptr, len, tableid, tdt);
+  else
+    ret = tdt->tdt_callback(tdmi, ptr, len, tableid, tdt->tdt_opaque);
+  
+  if(ret == 0)
+    tdt->tdt_count++;
+
+  if(tdt->tdt_flags & TDT_QUICKREQ)
+    dvb_table_fastswitch(tdmi);
+}
+
+/**
+ *
+ */
+static void *
+dvb_table_input(void *aux)
+{
+  th_dvb_adapter_t *tda = aux;
+  int r, i, tid, fd, x;
+  struct epoll_event ev[1];
+  uint8_t sec[4096];
+  th_dvb_mux_instance_t *tdmi;
+  th_dvb_table_t *tdt;
+  int64_t cycle_barrier = 0; 
+
+  while(1) {
+    x = epoll_wait(tda->tda_table_epollfd, ev, sizeof(ev) / sizeof(ev[0]), -1);
+
+    for(i = 0; i < x; i++) {
+    
+      tid = ev[i].data.u64 & 0xffffffff;
+      fd  = ev[i].data.u64 >> 32; 
+
+      if(!(ev[i].events & EPOLLIN))
+       continue;
+
+      if((r = read(fd, sec, sizeof(sec))) < 3)
+       continue;
+
+      pthread_mutex_lock(&global_lock);
+      if((tdmi = tda->tda_mux_current) != NULL) {
+       LIST_FOREACH(tdt, &tdmi->tdmi_tables, tdt_link)
+         if(tdt->tdt_id == tid)
+           break;
 
+       if(tdt != NULL) {
+         dvb_proc_table(tdmi, tdt, sec, r);
+
+         /* Any tables pending (that wants a filter/fd), close this one */
+         if(TAILQ_FIRST(&tdmi->tdmi_table_queue) != NULL &&
+            cycle_barrier < getmonoclock()) {
+           tdt_close_fd(tdmi, tdt);
+           cycle_barrier = getmonoclock() + 100000;
+           tdt = TAILQ_FIRST(&tdmi->tdmi_table_queue);
+           assert(tdt != NULL);
+
+           open_table(tdmi, tdt);
+         }
+       }
+      }
+      pthread_mutex_unlock(&global_lock);
+    }
+  }
+  return NULL;
+}
+
+
+static void
+close_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
+{
+  th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
+
+  if(tdt->tdt_fd == -1) {
+    TAILQ_REMOVE(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
+  } else {
+    epoll_ctl(tda->tda_table_epollfd, EPOLL_CTL_DEL, tdt->tdt_fd, NULL);
+    close(tdt->tdt_fd);
+  }
+}
+
+/**
+ *
+ */
 void
 dvb_input_filtered_setup(th_dvb_adapter_t *tda)
 {
   tda->tda_open_service  = open_service;
   tda->tda_close_service = close_service;
+  tda->tda_open_table    = open_table;
+  tda->tda_close_table   = close_table;
+
+  pthread_t ptid;
+  tda->tda_table_epollfd = epoll_create(50);
+  pthread_create(&ptid, NULL, dvb_table_input, tda);
 }
 
index 5e8da3383774b6dd9dc8a8456ab05a59466ebf84..f292b4e588879f9be05356c830b696e4ed2bb4c9 100644 (file)
 #include "notify.h"
 #include "cwc.h"
 
-static int tdt_id_tally;
 
 /**
  *
  */
-static void
+void
 dvb_table_fastswitch(th_dvb_mux_instance_t *tdmi)
 {
   th_dvb_table_t *tdt;
@@ -73,183 +72,6 @@ dvb_table_fastswitch(th_dvb_mux_instance_t *tdmi)
 }
 
 
-/**
- *
- */
-static void
-tdt_open_fd(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
-{
-  th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
-  struct epoll_event e;
-  
-  assert(tdt->tdt_fd == -1);
-  TAILQ_REMOVE(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
-
-  tdt->tdt_fd = tvh_open(tda->tda_demux_path, O_RDWR, 0);
-
-  if(tdt->tdt_fd != -1) {
-
-    tdt->tdt_id = ++tdt_id_tally;
-
-    e.events = EPOLLIN;
-    e.data.u64 = ((uint64_t)tdt->tdt_fd << 32) | tdt->tdt_id;
-
-    if(epoll_ctl(tda->tda_table_epollfd, EPOLL_CTL_ADD, tdt->tdt_fd, &e)) {
-      close(tdt->tdt_fd);
-      tdt->tdt_fd = -1;
-    } else {
-
-      struct dmx_sct_filter_params fp = {0};
-  
-      fp.filter.filter[0] = tdt->tdt_table;
-      fp.filter.mask[0]   = tdt->tdt_mask;
-
-      if(tdt->tdt_flags & TDT_CRC)
-       fp.flags |= DMX_CHECK_CRC;
-      fp.flags |= DMX_IMMEDIATE_START;
-      fp.pid = tdt->tdt_pid;
-
-      if(ioctl(tdt->tdt_fd, DMX_SET_FILTER, &fp)) {
-       close(tdt->tdt_fd);
-       tdt->tdt_fd = -1;
-      }
-    }
-  }
-
-  if(tdt->tdt_fd == -1)
-    TAILQ_INSERT_TAIL(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
-}
-
-
-/**
- * Close FD for the given table and put table on the pending list
- */
-static void
-tdt_close_fd(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt)
-{
-  th_dvb_adapter_t *tda = tdmi->tdmi_adapter;
-
-  assert(tdt->tdt_fd != -1);
-
-  epoll_ctl(tda->tda_table_epollfd, EPOLL_CTL_DEL, tdt->tdt_fd, NULL);
-  close(tdt->tdt_fd);
-
-  tdt->tdt_fd = -1;
-  TAILQ_INSERT_TAIL(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
-}
-
-
-/**
- *
- */
-static void
-dvb_proc_table(th_dvb_mux_instance_t *tdmi, th_dvb_table_t *tdt, uint8_t *sec,
-              int r)
-{
-  int chkcrc = tdt->tdt_flags & TDT_CRC;
-  int tableid, len;
-  uint8_t *ptr;
-  int ret;
-
-  /* It seems some hardware (or is it the dvb API?) does not
-     honour the DMX_CHECK_CRC flag, so we check it again */
-  if(chkcrc && tvh_crc32(sec, r, 0xffffffff))
-    return;
-      
-  r -= 3;
-  tableid = sec[0];
-  len = ((sec[1] & 0x0f) << 8) | sec[2];
-  
-  if(len < r)
-    return;
-
-  ptr = &sec[3];
-  if(chkcrc) len -= 4;   /* Strip trailing CRC */
-
-  if(tdt->tdt_flags & TDT_CA)
-    ret = tdt->tdt_callback((th_dvb_mux_instance_t *)tdt,
-                                sec, len + 3, tableid, tdt->tdt_opaque);
-  else if(tdt->tdt_flags & TDT_TDT)
-    ret = tdt->tdt_callback(tdmi, ptr, len, tableid, tdt);
-  else
-    ret = tdt->tdt_callback(tdmi, ptr, len, tableid, tdt->tdt_opaque);
-  
-  if(ret == 0)
-    tdt->tdt_count++;
-
-  if(tdt->tdt_flags & TDT_QUICKREQ)
-    dvb_table_fastswitch(tdmi);
-}
-
-/**
- *
- */
-static void *
-dvb_table_input(void *aux)
-{
-  th_dvb_adapter_t *tda = aux;
-  int r, i, tid, fd, x;
-  struct epoll_event ev[1];
-  uint8_t sec[4096];
-  th_dvb_mux_instance_t *tdmi;
-  th_dvb_table_t *tdt;
-  int64_t cycle_barrier = 0; 
-
-  while(1) {
-    x = epoll_wait(tda->tda_table_epollfd, ev, sizeof(ev) / sizeof(ev[0]), -1);
-
-    for(i = 0; i < x; i++) {
-    
-      tid = ev[i].data.u64 & 0xffffffff;
-      fd  = ev[i].data.u64 >> 32; 
-
-      if(!(ev[i].events & EPOLLIN))
-       continue;
-
-      if((r = read(fd, sec, sizeof(sec))) < 3)
-       continue;
-
-      pthread_mutex_lock(&global_lock);
-      if((tdmi = tda->tda_mux_current) != NULL) {
-       LIST_FOREACH(tdt, &tdmi->tdmi_tables, tdt_link)
-         if(tdt->tdt_id == tid)
-           break;
-
-       if(tdt != NULL) {
-         dvb_proc_table(tdmi, tdt, sec, r);
-
-         /* Any tables pending (that wants a filter/fd), close this one */
-         if(TAILQ_FIRST(&tdmi->tdmi_table_queue) != NULL &&
-            cycle_barrier < getmonoclock()) {
-           tdt_close_fd(tdmi, tdt);
-           cycle_barrier = getmonoclock() + 100000;
-           tdt = TAILQ_FIRST(&tdmi->tdmi_table_queue);
-           assert(tdt != NULL);
-
-           tdt_open_fd(tdmi, tdt);
-         }
-       }
-      }
-      pthread_mutex_unlock(&global_lock);
-    }
-  }
-  return NULL;
-}
-
-
-
-/**
- *
- */
-void
-dvb_table_init(th_dvb_adapter_t *tda)
-{
-  pthread_t ptid;
-  tda->tda_table_epollfd = epoll_create(50);
-  pthread_create(&ptid, NULL, dvb_table_input, tda);
-}
-
-
 /**
  *
  */
@@ -258,14 +80,7 @@ dvb_tdt_destroy(th_dvb_adapter_t *tda, th_dvb_mux_instance_t *tdmi,
                th_dvb_table_t *tdt)
 {
   LIST_REMOVE(tdt, tdt_link);
-
-  if(tdt->tdt_fd == -1) {
-    TAILQ_REMOVE(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
-  } else {
-    epoll_ctl(tda->tda_table_epollfd, EPOLL_CTL_DEL, tdt->tdt_fd, NULL);
-    close(tdt->tdt_fd);
-  }
-
+  tda->tda_close_table(tdmi, tdt);
   free(tdt->tdt_name);
   free(tdt);
 }
@@ -311,7 +126,7 @@ tdt_add(th_dvb_mux_instance_t *tdmi, int tableid, int mask,
   tdt->tdt_fd = -1;
   TAILQ_INSERT_TAIL(&tdmi->tdmi_table_queue, tdt, tdt_pending_link);
 
-  tdt_open_fd(tdmi, tdt);
+  tdmi->tdmi_adapter->tda_open_table(tdmi, tdt);
 }
 
 /**