[linux-dvb] dvr device reading hangs - patch

Perceval Anichini perceval.anichini at streamvision.fr
Thu Apr 28 22:54:33 CEST 2005


	Hello !
I had the same problem. To work around this problem, i managed to add
a new ioctl which can tell me how many bytes are present in the
DVR buffer.

After that i just perform the following operations :
	select () to check if data are pending.
	ioctl (FMX_FIONREAD) to check how many bytes might be read.
	and read ().

Please be indulgent with this patch, i'm not used to kernel programming.

Hope that will help...
Perceval.

diff -Naur linux-2.6.11.7-orig/drivers/media/dvb/dvb-core/dmxdev.c
linux-2.6.11.7/drivers/media/dvb/dvb-core/dmxdev.c
--- linux-2.6.11.7-orig/drivers/media/dvb/dvb-core/dmxdev.c	2005-04-07
20:57:57.000000000 +0200
+++ linux-2.6.11.7/drivers/media/dvb/dvb-core/dmxdev.c	2005-04-28
13:38:23.000000000 +0200
@@ -1015,6 +1015,7 @@
 	struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv;
 
 	int ret=0;
+	int val = 0;
 
 	if (down_interruptible (&dmxdev->mutex))
 		return -ERESTARTSYS;
@@ -1024,6 +1025,40 @@
 		// FIXME: implement
 		ret=0;
 		break;
+
+		/**
+		 * StreamVision's power ! New IOCTL. Ain't that rock ?
+		 */
+	case DMX_FIONREAD:
+	  if (! dmxdev->dvr)
+	    {
+	      ret = -EBADF;
+	      break ;
+	    }
+	  if (wait_event_interruptible (dmxdev->dvr_buffer.queue,
+					(dmxdev->dvr_buffer.pread != dmxdev->dvr_buffer.pwrite) ||
+					(dmxdev->dvr_buffer.error)) < 0)
+	    {
+/* 	      printk (KERN_INFO "wait_event_interruptible returned 0\n");
*/
+	      // No data in queue, no error.
+	      *((int*) parg) = 0;
+	      ret = 0;
+	      break ;
+	    }
+
+	  if (dmxdev->dvr_buffer.error)
+	    {
+/* 	      printk (KERN_INFO "dvb_buffer declared an error.\n"); */
+	      dmxdev->dvr_buffer.pwrite = dmxdev->dvr_buffer.pread;
+	      dmxdev->dvr_buffer.error = 0;
+	      ret = -EFAULT;
+	      break ;
+	    }
+	  val = dmxdev->dvr_buffer.pwrite - dmxdev->dvr_buffer.pread;
+/* 	  printk (KERN_INFO "Computed %d bytes in buffer.\n", val); */
+	  *((int*) parg) = val;
+	  ret = 0;
+	  break ;
 		
 	default:
 		ret=-EINVAL;
diff -Naur linux-2.6.11.7-orig/include/linux/dvb/dmx.h
linux-2.6.11.7/include/linux/dvb/dmx.h
--- linux-2.6.11.7-orig/include/linux/dvb/dmx.h	2005-04-07
20:58:20.000000000 +0200
+++ linux-2.6.11.7/include/linux/dvb/dmx.h	2005-04-28 02:27:07.000000000
+0200
@@ -175,6 +175,7 @@
 #define DMX_GET_CAPS             _IOR('o',48,dmx_caps_t)
 #define DMX_SET_SOURCE           _IOW('o',49,dmx_source_t)
 #define DMX_GET_STC              _IOWR('o',50,struct dmx_stc)
+#define DMX_FIONREAD		 _IOR('o', 51, int)
 
 #endif /*_DVBDMX_H_*/
 





More information about the linux-dvb mailing list