[mythtv] Re: One HDTV channel not giving me data, recently

Boleslaw Ciesielski bolek-mythtv at curl.com
Wed Apr 20 21:23:43 UTC 2005


Doug Larrick wrote:
> I have a crappy not-quite-right PSIP parser that I wrote as an exercise.
>  If you'd like it, get the source from
> http://jekyl.no-ip.org/doug/psipguide.C
> 
> It needs access to the raw TS stream, so it's much easier to use with
> the v4l driver than the DVB one.

I modified your psipguide tool to read directly from the DVB device if 
the input filename is not specified (stole some code from dvbtraffic). 
This makes it easy to use with the DVB driver.

A patch is attached.

Bolek
-------------- next part --------------
--- psipguide.C.org	2004-12-30 06:21:47.000000000 -0500
+++ psipguide.C	2005-04-20 17:14:07.652517236 -0400
@@ -10,10 +10,13 @@
 #include <map>
 #include <string>
 #include <list>
 #include <set>
 #include <time.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/dvb/dmx.h>
 
 using namespace std;
 
 typedef unsigned int uint32_t;
 typedef unsigned char uint8_t;
@@ -1072,21 +1075,60 @@
 
 int main(int argc, char *argv[])
 {
     unsigned char buffer[188*1361];
     int picnum=0, gopnum=0;
-    
     int pktnum = 0;
-    if (argc != 2) 
+    int fd = 0, fd_demux = 0;
+    
+    if (argc > 2) 
     {
-	cout << "Usage: psipguide filename" << endl;
+	cout << "Usage: psipguide [filename]" << endl;
 	exit(EXIT_FAILURE);
     }
-    FILE *fp = fopen64(argv[1], "r");
-    if (fp == NULL) {
-	perror(argv[1]);
+
+    if (argc == 2) {
+      // Read from a file
+      fd = open(argv[1], O_RDONLY);
+      if (fd < 0) {
+        perror(argv[1]);
+	exit(EXIT_FAILURE);
+      }
+    } else {
+      // Read from DVB
+      struct dmx_pes_filter_params flt;
+
+      fd = open("/dev/dvb/adapter0/dvr0", O_RDONLY);
+      if (fd < 0) {
+        perror("/dev/dvb/adapter0/dvr0");
+	exit(EXIT_FAILURE);
+      }
+
+      ioctl(fd, DMX_SET_BUFFER_SIZE, 1024 * 1024);
+
+      fd_demux = open("/dev/dvb/adapter0/demux0", O_RDWR);
+      if (fd_demux < 0) {
+        perror("/dev/dvb/adapter0/demux0");
 	exit(EXIT_FAILURE);
+      }
+
+      // setup filter to get all packets
+      flt.pid = 0x2000;
+      flt.input = DMX_IN_FRONTEND;
+      flt.output = DMX_OUT_TS_TAP;
+      flt.pes_type = DMX_PES_OTHER;
+      flt.flags = 0;
+
+      if (ioctl(fd_demux, DMX_SET_PES_FILTER, &flt) < 0) {
+        perror("DMX_SET_PES_FILTER");
+	exit(EXIT_FAILURE);
+      }
+
+      if (ioctl(fd_demux, DMX_START, 0) < 0) {
+        perror("DMX_START");
+	exit(EXIT_FAILURE);
+      }
     }
     
     memset(g_pid_map, 0, MAX_PIDS);
     g_pid_map[0] = PID_PAT;
     g_pid_map[0x1ffb] = PID_PSIP;
@@ -1096,13 +1138,14 @@
     // January 6, 1980, 00:00:00
     g_psip_epoch = ((((80-70)*365+(80-69)/4+5)*24)*60)*60; 
     // This will be fixed up with offset in ParseSTT
     
     int remainder = 0;
-    while (!feof(fp)) {
-	size_t size = fread(&(buffer[remainder]), 1, 
-			    188*1361-remainder, fp);
+    while (1) {
+	ssize_t size = read(fd, &(buffer[remainder]), 188*1361-remainder);
+        if (size == 0) break;
+
 	remainder = ProcessData(buffer, size);
 	//cout << "Remainder: " << remainder << endl;
 	if (g_needed_pids.empty())
 	    break;
 	else {
@@ -1128,10 +1171,13 @@
 	if (remainder < 0)
 	    exit(EXIT_FAILURE);
 	memmove(&(buffer[0]), &(buffer[188*1361-remainder]),
 		remainder);
     }
+
+    if (fd_demux) close(fd_demux);
+    close(fd);
     
     // We saw all the PIDs we wanted... final report
     for (map<uint32_t, PSIP_Channel>::const_iterator cit = 
 	     g_channel_map.begin();
 	 cit != g_channel_map.end(); cit++) {


More information about the mythtv-dev mailing list