changeset 7:2fce9e157b8d

Added some work around to work with kernel 2.6.27-rc3, added debug param.
author AngelCarpintero
date Sun, 24 Aug 2008 02:20:51 +0000
parents d3fdefea8bce
children 80590d10a596
files FAQ example/dummy.c example/feed.c example/invert.c example/resize.c vloopback.c
diffstat 6 files changed, 1242 insertions(+), 913 deletions(-) [+]
line wrap: on
line diff
--- a/FAQ	Sat Jul 12 17:12:25 2008 +0000
+++ b/FAQ	Sun Aug 24 02:20:51 2008 +0000
@@ -37,4 +37,11 @@
 
 You need to use Coriander (http://damien.douxchamps.net/ieee1394/coriander/ ) and set on services tab V4L (http://damien.douxchamps.net/ieee1394/coriander/win_v4l.png).
 
-And then you will have a V4L in /dev/video1. 
+And then you will have a V4L in /dev/video1.
+
+* Having problems running vloopback ?
+
+load vloopback with debug : 
+
+ modprobe vloopback debug=3
+
--- a/example/dummy.c	Sat Jul 12 17:12:25 2008 +0000
+++ b/example/dummy.c	Sun Aug 24 02:20:51 2008 +0000
@@ -29,31 +29,31 @@
 #define MAXHEIGHT 480
 int width;
 int height;
-int fmt=0;
+int fmt = 0;
 char ioctlbuf[MAXIOCTL];
 int v4ldev;
 char *image_out;
-	
+int noexit = 1;	
 
 int get_frame(void)
 {
 	int i;
 	char colour = 0;
 
-	memset(image_out, 0x128, width*height*3);
+	memset(image_out, 0x128, width * height * 3);
 	
-	for (i=10; i<width-10; i++) {
-		image_out[10*width*3+i*3]=colour++;
-		image_out[10*width*3+i*3+1]=0;
-		image_out[10*width*3+i*3+2]=-colour;
+	for (i = 10; i < width - 10; i++) {
+		image_out[10 *width *3 + i *3] = colour++;
+		image_out[10 *width *3 + i *3 + 1] = 0;
+		image_out[10 *width *3 + i *3 + 2] =-colour;
 	}
-	for (i=10; i<width-10; i++) {
-		image_out[(height-10)*width*3+i*3]=colour;
-		image_out[(height-10)*width*3+i*3+1]=0;
-		image_out[(height-10)*width*3+i*3+2]=-colour++;
+
+	for (i = 10; i < width - 10; i++) {
+		image_out[(height - 10) * width *3 + i * 3] = colour;
+		image_out[(height - 10) * width *3 + i * 3 + 1] = 0;
+		image_out[(height - 10) * width *3 + i * 3 + 2] =-colour++;
 	}
-	/*
-	*/
+
 	usleep(500); /* BIG XXX */
 	return 0;
 }
@@ -62,9 +62,11 @@
 {
 	char *map;
 	
-	map=mmap(0, memsize, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
+	map = mmap(0, memsize, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
+
 	if ((unsigned char *)-1 == (unsigned char *)map)
 		return NULL;
+
 	return map;	
 }
 
@@ -72,191 +74,201 @@
 {
 	int i;
 	switch (cmd) {
-		case VIDIOCGCAP:
-		{
-			struct video_capability *vidcap=arg;
+	case VIDIOCGCAP:
+	{
+		struct video_capability *vidcap = arg;
 
-			sprintf(vidcap->name, "Jeroen's dummy v4l driver");
-			vidcap->type= VID_TYPE_CAPTURE;
-			vidcap->channels=1;
-			vidcap->audios=0;
-			vidcap->maxwidth=MAXWIDTH;
-			vidcap->maxheight=MAXHEIGHT;
-			vidcap->minwidth=20;
-			vidcap->minheight=20;
-			return 0;
-		}
-		case VIDIOCGCHAN:
-		{
-			struct video_channel *vidchan= (struct video_channel *)arg;
-			
-			printf("VIDIOCGCHAN called\n");
-			if (vidchan->channel!=0)
-				;//return 1;
-			vidchan->channel=0;
-			vidchan->flags=0;
-			vidchan->tuners=0;
-			vidchan->norm=0;
-			vidchan->type=VIDEO_TYPE_CAMERA;
-			strcpy(vidchan->name, "Loopback");
-			
-			return 0;
-		}
-		case VIDIOCSCHAN:
-		{
-			int *v=arg;
+		sprintf(vidcap->name, "Jeroen's dummy v4l driver");
+		vidcap->type = VID_TYPE_CAPTURE;
+		vidcap->channels = 1;
+		vidcap->audios = 0;
+		vidcap->maxwidth = MAXWIDTH;
+		vidcap->maxheight = MAXHEIGHT;
+		vidcap->minwidth = 20;
+		vidcap->minheight = 20;
+		return 0;
+	}
+	case VIDIOCGCHAN:
+	{
+		struct video_channel *vidchan = (struct video_channel *)arg;
 			
-			if (v[0]!=0)
-				return 1;
-			return 0;
-		}
-		case VIDIOCGTUNER:
-		{
-			struct video_tuner *v = arg;
-
-			if(v->tuner) {
-				printf("VIDIOCGTUNER: Invalid Tuner, was %d\n", v->tuner);
-				//return -EINVAL;
-			}
-			v->tuner=0;
-			strcpy(v->name, "Format");
-			v->rangelow=0;
-			v->rangehigh=0;
-			v->flags=0;
-			v->mode=VIDEO_MODE_AUTO;
-			return 1;
-		}
-		case VIDIOCGPICT:
-		{
-			struct video_picture *vidpic=arg;
-
-			vidpic->colour=0x8000;
-			vidpic->hue=0x8000;
-			vidpic->brightness=0x8000;
-			vidpic->contrast=0x8000;
-			vidpic->whiteness=0x8000;
-			vidpic->depth=0x8000;
-			vidpic->palette=fmt;
-			return 0;
-		}
-		case VIDIOCSPICT:
-		{
-			struct video_picture *vidpic=arg;
+		printf("VIDIOCGCHAN called\n");
+		if (vidchan->channel != 0)
+				;//return 1;
+		vidchan->channel = 0;
+		vidchan->flags = 0;
+		vidchan->tuners = 0;
+		vidchan->norm = 0;
+		vidchan->type = VIDEO_TYPE_CAMERA;
+		strcpy(vidchan->name, "Loopback");
+			
+		return 0;
+	}
+	case VIDIOCSCHAN:
+	{
+		int *v = arg;
 			
-			if (vidpic->palette!=fmt)
-				return 1;
-			return 0;
-		}
-		case VIDIOCGWIN:
-		{
-			struct video_window *vidwin=arg;
+		if (v[0] != 0)
+			return 1;
+		return 0;
+	}
+	case VIDIOCGTUNER:
+	{
+		struct video_tuner *v = arg;
 
-			vidwin->x=0;
-			vidwin->y=0;
-			vidwin->width=width;
-			vidwin->height=height;
-			vidwin->chromakey=0;
-			vidwin->flags=0;
-			vidwin->clipcount=0;
-			return 0;
+		if (v->tuner) {
+			printf("VIDIOCGTUNER: Invalid Tuner, was %d\n", v->tuner);
+			//return -EINVAL;
 		}
-		case VIDIOCSWIN:
-		{
-			struct video_window *vidwin=arg;
-			
-			if (vidwin->width > MAXWIDTH ||
-			    vidwin->height > MAXHEIGHT )
-				return 1;
-			if (vidwin->flags)
-				return 1;
-			width=vidwin->width;
-			height=vidwin->height;
-			printf("new size: %dx%d\n", width, height);
-			return 0;
-		}
-		case VIDIOCGMBUF:
-		{
-			struct video_mbuf *vidmbuf=arg;
+		v->tuner = 0;
+		strcpy(v->name, "Format");
+		v->rangelow = 0;
+		v->rangehigh = 0;
+		v->flags = 0;
+		v->mode = VIDEO_MODE_AUTO;
+		return 1;
+	}
+	case VIDIOCGPICT:
+	{
+		struct video_picture *vidpic = arg;
+
+		vidpic->colour = 0x8000;
+		vidpic->hue = 0x8000;
+		vidpic->brightness = 0x8000;
+		vidpic->contrast = 0x8000;
+		vidpic->whiteness = 0x8000;
+		vidpic->depth = 0x8000;
+		vidpic->palette = fmt;
+		return 0;
+	}
+	case VIDIOCSPICT:
+	{
+		struct video_picture *vidpic = arg;
+		
+		if (vidpic->palette != fmt)
+			return 1;
+		return 0;
+	}
+	case VIDIOCGWIN:
+	{
+		struct video_window *vidwin = arg;
 
-			vidmbuf->size=width*height*3;
-			vidmbuf->frames=1;
-			for (i=0; i<vidmbuf->frames; i++)
-				vidmbuf->offsets[i]=i*vidmbuf->size;
-			return 0;
-		}
-		case VIDIOCMCAPTURE:
-		{
-			struct video_mmap *vidmmap=arg;
+		vidwin->x = 0;
+		vidwin->y = 0;
+		vidwin->width = width;
+		vidwin->height = height;
+		vidwin->chromakey = 0;
+		vidwin->flags = 0;
+		vidwin->clipcount = 0;
+		return 0;
+	}
+	case VIDIOCSWIN:
+	{
+		struct video_window *vidwin = arg;
+			
+		if (vidwin->width > MAXWIDTH ||
+		    vidwin->height > MAXHEIGHT )
+			return 1;
+		if (vidwin->flags)
+			return 1;
+		width = vidwin->width;
+		height = vidwin->height;
+		printf("new size: %dx%d\n", width, height);
+		return 0;
+	}
+	case VIDIOCGMBUF:
+	{
+		struct video_mbuf *vidmbuf = arg;
 
-			//return 0;
-			if (vidmmap->height>MAXHEIGHT ||
-			    vidmmap->width>MAXWIDTH ||
-			    vidmmap->format!=fmt )
-				return 1;
-			if (vidmmap->height!=height ||
-			    vidmmap->width!=width) {
-				height=vidmmap->height;
-				width=vidmmap->width;
-				printf("new size: %dx%d\n", width, height);
-			}
-			// check if 'vidmmap->frame' is valid
-			// initiate capture for 'vidmmap->frame' frames
-			return 0;
+		vidmbuf->size = width * height * 3;
+		vidmbuf->frames = 1;
+		for (i = 0; i < vidmbuf->frames; i++)
+			vidmbuf->offsets[i] = i * vidmbuf->size;
+		return 0;
+	}
+	case VIDIOCMCAPTURE:
+	{
+		struct video_mmap *vidmmap = arg;
+
+		//return 0;
+		if (vidmmap->height>MAXHEIGHT ||
+		    vidmmap->width>MAXWIDTH ||
+		    vidmmap->format != fmt )
+			return 1;
+		if (vidmmap->height != height ||
+		    vidmmap->width != width) {
+			height = vidmmap->height;
+			width = vidmmap->width;
+			printf("new size: %dx%d\n", width, height);
 		}
-		case VIDIOCSYNC:
-		{
-			//struct video_mmap *vidmmap=arg;
+		// check if 'vidmmap->frame' is valid
+		// initiate capture for 'vidmmap->frame' frames
+		return 0;
+	}
+	case VIDIOCSYNC:
+	
+		//struct video_mmap *vidmmap=arg;
 
-			// check if frames are ready.
-			// wait until ready.
-			get_frame();
-			return 0;
-		}
-		default:
-		{
-			printf("unknown ioctl: %ld\n", cmd & 0xff);
-			return 1;
-		}
+		// check if frames are ready.
+		// wait until ready.
+		get_frame();
+		return 0;
+	
+	default:
+		printf("unknown ioctl: %ld\n", cmd & 0xff);
+		return 1;
+	
 	}
 	return 0;
 }
 
 #define VIDIOCSINVALID	_IO('v',BASE_VIDIOCPRIVATE+1)
 
+void sighandler_exit(int signo)
+{
+    noexit = 0;
+}    
+
 void sighandler(int signo)
 {
 	int size, ret;
 	unsigned long int cmd;
 	struct pollfd ufds;
 
-	if (signo!=SIGIO)
+	if (signo != SIGIO)
 		return;
-	ufds.fd=v4ldev;
-	ufds.events=POLLIN;
-	ufds.revents=0;
+
+	ufds.fd = v4ldev;
+	ufds.events = POLLIN;
+	ufds.revents = 0;
 	poll(&ufds, 1, 1000);
+	
 	if (!ufds.revents & POLLIN) {
 		printf("Received signal but got negative on poll?!?!?!?\n");
 		return;
 	}
-	size=read(v4ldev, ioctlbuf, MAXIOCTL);
+
+	size = read(v4ldev, ioctlbuf, MAXIOCTL);
+
 	if (size >= sizeof(unsigned long int)) {
 		memcpy(&cmd, ioctlbuf, sizeof(unsigned long int));
-		if (cmd==0) {
+		if (cmd == 0) {
 			printf("Client closed device\n");
 			return;
 		}
-		ret=v4l_ioctl(cmd, ioctlbuf+sizeof(unsigned long int));
+		ret = v4l_ioctl(cmd, ioctlbuf+sizeof(unsigned long int));
 		if (ret) {
-			memset(ioctlbuf+sizeof(unsigned long int), MAXIOCTL-sizeof(unsigned long int), 0xff);
+			memset(ioctlbuf + sizeof(unsigned long int), MAXIOCTL - sizeof(unsigned long int), 0xff);
 			printf("ioctl %lx unsuccesfull, lets issue VIDIOCSINVALID (%x)\n", cmd, VIDIOCSINVALID);
 			ioctl(v4ldev, VIDIOCSINVALID);
-		} else
-			ioctl(v4ldev, cmd, ioctlbuf+sizeof(unsigned long int));
+		} else {
+			ioctl(v4ldev, cmd, ioctlbuf + sizeof(unsigned long int));
+        }
 	}
 	return;
 }
 
+
 int open_vidpipe(void)
 {
 	int pipe_fd = -1;
@@ -273,7 +285,7 @@
 	struct utsname uts;
 
 	if (uname(&uts) < 0) {
-		printf("Unable to execute uname\nError[%s]\n",strerror(errno));
+		printf("Unable to execute uname\nError[%s]\n", strerror(errno));
 		return -1;
 	}
 	
@@ -285,29 +297,34 @@
 	}
 
 	if (strcmp(minor, "5") < 0) {
-	
-		vloopbacks=fopen("/proc/video/vloopback/vloopbacks", "r");
+		vloopbacks = fopen("/proc/video/vloopback/vloopbacks", "r");
 		if (!vloopbacks) {
 			printf ("Failed to open '/proc/video/vloopback/vloopbacks");
 			return -1;
 		}
+
 		/* Read vloopback version */
 		fgets(buffer, 255, vloopbacks);
 		printf("%s", buffer);
+
 		/* Read explaination line */
 		fgets(buffer, 255, vloopbacks);
+
 		while (fgets(buffer, 255, vloopbacks)) {
-			if (strlen(buffer)>1) {
-				buffer[strlen(buffer)-1]=0;
-				loop=strtok(buffer, "\t");
-				input=strtok(NULL, "\t");
-				istatus=strtok(NULL, "\t");
-				output=strtok(NULL, "\t");
-				ostatus=strtok(NULL, "\t");
-				if (istatus[0]=='-') {
+			
+            if (strlen(buffer)>1) {
+				buffer[strlen(buffer)-1] = 0;
+				loop = strtok(buffer, "\t");
+				input = strtok(NULL, "\t");
+				istatus = strtok(NULL, "\t");
+				output = strtok(NULL, "\t");
+				ostatus = strtok(NULL, "\t");
+				
+                if (istatus[0] == '-') {
 					sprintf(pipepath, "/dev/%s", input);
-					pipe_fd=open(pipepath, O_RDWR);
-					if (pipe_fd>=0) {
+					pipe_fd = open(pipepath, O_RDWR);
+
+					if (pipe_fd >= 0) {
 						printf("Input: /dev/%s\n", input);
 						printf("Output: /dev/%s\n", output);
 						return pipe_fd;
@@ -315,84 +332,90 @@
 				}
 			} 
 		}
-
-	}else{
+	} else {
 		DIR *dir;
 		struct dirent *dirp;
-		const char prefix[]="/sys/class/video4linux/";
+		const char prefix[] = "/sys/class/video4linux/";
 		char *ptr, *io;
 		int fd;
-		int low=9999;
+		int low = 9999;
 		int tfd;
 		int tnum;
 
-		if ((dir=opendir(prefix))== NULL) {
+		if ((dir = opendir(prefix)) == NULL) {
 			printf( "Failed to open '%s'", prefix);
 			return -1;
 		}
 
-		while ((dirp=readdir(dir)) != NULL) {
-                        if (!strncmp(dirp->d_name, "video", 5)) {
-                                strcpy(buffer, prefix);
-                                strcat(buffer, dirp->d_name);
-                                strcat(buffer, "/name");
-                                if ((fd=open(buffer, O_RDONLY)) >= 0) {
-                                        if ((read(fd, buffer, sizeof(buffer)-1))<0) {
-                                                close(fd);
-                                                continue;
-                                        }
-                                        ptr = strtok(buffer, " ");
-                                        if (strcmp(ptr,"Video")) {
-                                                close(fd);
-                                                continue;
-                                        }
-                                        major = strtok(NULL, " ");
-                                        minor = strtok(NULL, " ");
-                                        io  = strtok(NULL, " \n");
-                                        if (strcmp(major, "loopback") || strcmp(io, "input")) {
-                                                close(fd);
-                                                continue;
-                                        }
-                                        if ((ptr=strtok(buffer, " "))==NULL) {
-                                                close(fd);
-                                                continue;
-                                        }
-                                        tnum = atoi(minor);
-                                        if (tnum < low) {
-                                                strcpy(buffer, "/dev/");
-                                                strcat(buffer, dirp->d_name);
-                                                if ((tfd=open(buffer, O_RDWR))>=0) {
-                                                        strcpy(pipepath, buffer);
-                                                        if (pipe_fd>=0) {
-                                                                close(pipe_fd);
-                                                        }
-                                                        pipe_fd = tfd;
-                                                        low = tnum;
-                                                }
-                                        }
-                                        close(fd);
-                                }
+		while ((dirp = readdir(dir)) != NULL) {
+            if (!strncmp(dirp->d_name, "video", 5)) {
+                strcpy(buffer, prefix);
+                strcat(buffer, dirp->d_name);
+                strcat(buffer, "/name");
+                
+                if ((fd = open(buffer, O_RDONLY)) >= 0) {
+                    if ((read(fd, buffer, sizeof(buffer)-1)) < 0) {
+                        close(fd);
+                        continue;
+                    }
+                    
+                    ptr = strtok(buffer, " ");
+                    
+                    if (strcmp(ptr, "Video")) {
+                        close(fd);
+                        continue;
+                    }
+                    
+                    major = strtok(NULL, " ");
+                    minor = strtok(NULL, " ");
+                    io  = strtok(NULL, " \n");
+
+                    if (strcmp(major, "loopback") || strcmp(io, "input")) {
+                        close(fd);
+                        continue;
+                    }
+
+                    if ((ptr=strtok(buffer, " ")) == NULL) {
+                        close(fd);
+                        continue;
+                    }
+
+                    tnum = atoi(minor);
+                    if (tnum < low) {
+                        strcpy(buffer, "/dev/");
+                        strcat(buffer, dirp->d_name);
+                        if ((tfd = open(buffer, O_RDWR)) >= 0) {
+                            strcpy(pipepath, buffer);
+                            if (pipe_fd >= 0) 
+                                close(pipe_fd);
+                                
+                             pipe_fd = tfd;
+                             low = tnum;
                         }
+                    }
+                    close(fd);
                 }
+            }
+        }
 		
 
 		closedir(dir);
-                if (pipe_fd >= 0)
-                        printf("Opened input of %s", pipepath);
-        }
+        if (pipe_fd >= 0)
+            printf("Opened input of %s", pipepath);
+    }
 	
 	return pipe_fd;
 }
 
 int main (int argc, char **argv)
 {
-	char palette[10]={'\0'};
+	char palette[10] = {'\0'};
 
 	if (argc != 3) {
 		printf("dummy.c\n");
 		printf("A example for using a video4linux loopback in zero-copy mode\n");
 		printf("Written by Jeroen Vreeken, 2000\n");
-		printf("Updated to vloopback API v0.97\n\n");
+		printf("Updated to vloopback API v1.1\n\n");
 		printf("Usage:\n\n");
 		printf("dummy widthxheight rgb24|yuv420p\n\n");
 		printf("example: dummy 352x288 yuv420p\n\n");
@@ -402,8 +425,10 @@
 	sscanf(argv[1], "%dx%d", &width, &height);
 	sscanf(argv[2], "%s", palette);
 
-	if (!strcmp(palette,"rgb24")) fmt = VIDEO_PALETTE_RGB24;
-	else if (!strcmp(palette,"yuv420p")) fmt = VIDEO_PALETTE_YUV420P;
+	if (!strcmp(palette, "rgb24")) 
+		fmt = VIDEO_PALETTE_RGB24;
+	else if (!strcmp(palette, "yuv420p")) 
+		fmt = VIDEO_PALETTE_YUV420P;
 	else fmt = VIDEO_PALETTE_RGB24;
 	
 	/* Default startup values, nothing special 
@@ -411,25 +436,33 @@
 	height=288;
 	*/
 
-	v4ldev=open_vidpipe();
+	v4ldev = open_vidpipe();
+
 	if (v4ldev < 0) {
-		printf ("Failed to open video loopback device\nError[%s]\n",strerror(errno));
+		printf ("Failed to open video loopback device\nError[%s]\n", strerror(errno));
 		exit(1);
 	}
-	image_out=v4l_create(v4ldev, MAXWIDTH*MAXHEIGHT*3);
+
+	image_out = v4l_create(v4ldev, MAXWIDTH * MAXHEIGHT * 3);
+	
 	if (!image_out) {
 		exit(1);
-		printf ("Failed to set device to zero-copy mode\nError[%s]\n",strerror(errno));
+		printf ("Failed to set device to zero-copy mode\nError[%s]\n", strerror(errno));
 	}
 
-	signal (SIGIO, sighandler);
+	signal(SIGIO, sighandler);
+    signal(SIGTERM, sighandler_exit);
+    signal(SIGINT, sighandler_exit);
 
 	printf("\nListening.\n");
-	while (1) {
+	
+	while (noexit) 
 		sleep(1000);
-	}
+	
+	close(v4ldev);
+	munmap(image_out, MAXWIDTH * MAXHEIGHT * 3);
 
-	close (v4ldev);
-	free(image_out);
+    printf("\nBye Bye ...\n");
+
 	exit(0);
 }
--- a/example/feed.c	Sat Jul 12 17:12:25 2008 +0000
+++ b/example/feed.c	Sun Aug 24 02:20:51 2008 +0000
@@ -20,52 +20,61 @@
 #include <linux/videodev.h>
 
 
-int fmt=0;
+int fmt = 0;
 int noexit = 1;
-int read_img=0;
+int read_img = 0;
 
 char *start_capture (int dev, int width, int height)
 {
-        struct video_capability vid_caps;
+    struct video_capability vid_caps;
 	struct video_window vid_win;
 	struct video_mbuf vid_buf;
 	char *map;
 
-	if (ioctl (dev, VIDIOCGCAP, &vid_caps) == -1) {
-		printf ("ioctl (VIDIOCGCAP)\nError[%s]\n",strerror(errno));
+	if (ioctl(dev, VIDIOCGCAP, &vid_caps) == -1) {
+		printf ("ioctl (VIDIOCGCAP)\nError[%s]\n", strerror(errno));
 		return (NULL);
 	}
-	if (vid_caps.type & VID_TYPE_MONOCHROME) fmt=VIDEO_PALETTE_GREY;
+
+	if (vid_caps.type & VID_TYPE_MONOCHROME) 
+		fmt=VIDEO_PALETTE_GREY;
+
 	if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) {
 		fprintf(stderr, "no mmap falling back on read\n");
+
 		if (ioctl (dev, VIDIOCGWIN, &vid_win)== -1) {
 			printf ("ioctl VIDIOCGWIN\nError[%s]\n",strerror(errno));
 			return (NULL);
 		}
-		vid_win.width=width;
-		vid_win.height=height;
+
+		vid_win.width  = width;
+		vid_win.height = height;
+
 		if (ioctl (dev, VIDIOCSWIN, &vid_win)== -1) {
 			printf ("ioctl VIDIOCSWIN\nError[%s]\n",strerror(errno));
 			return (NULL);
 		}
-		read_img=1;
-		map=malloc(width*height*3);
+
+		read_img = 1;
+		map = malloc(width * height * 3);
 		return (map);
 	}
+
 	/* If we are going to capture greyscale we need room to blow the image up */
-	if (fmt==VIDEO_PALETTE_GREY)
-		map=mmap(0, vid_buf.size*3, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
+	if (fmt == VIDEO_PALETTE_GREY)
+		map = mmap(0, vid_buf.size * 3, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
 	else
-		map=mmap(0, vid_buf.size, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
+		map = mmap(0, vid_buf.size, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
 	
 	if ((unsigned char *)-1 == (unsigned char *)map)
 		return (NULL);
+
 	return map;
 }
 
 int start_pipe (int dev, int width, int height)
 {
-        struct video_capability vid_caps;
+    struct video_capability vid_caps;
 	struct video_window vid_win;
 	struct video_picture vid_pic;
 
@@ -73,22 +82,28 @@
 		printf ("ioctl (VIDIOCGCAP)\nError[%s]\n",strerror(errno));
 		return (1);
 	}
-	if (ioctl (dev, VIDIOCGPICT, &vid_pic)== -1) {
+	
+	if (ioctl(dev, VIDIOCGPICT, &vid_pic) == -1) {
 		printf ("ioctl VIDIOCGPICT\nError[%s]\n",strerror(errno));
 		return (1);
 	}
-	vid_pic.palette=fmt;
-	if (ioctl (dev, VIDIOCSPICT, &vid_pic)== -1) {
+
+	vid_pic.palette = fmt;
+
+	if (ioctl (dev, VIDIOCSPICT, &vid_pic) == -1) {
 		printf ("ioctl VIDIOCSPICT\nError[%s]\n",strerror(errno));
 		return (1);
 	}
-	if (ioctl (dev, VIDIOCGWIN, &vid_win)== -1) {
+
+	if (ioctl (dev, VIDIOCGWIN, &vid_win) == -1) {
 		printf ("ioctl VIDIOCGWIN");
 		return (1);
 	}
-	vid_win.width=width;
-	vid_win.height=height;
-	if (ioctl (dev, VIDIOCSWIN, &vid_win)== -1) {
+
+	vid_win.width = width;
+	vid_win.height = height;
+	
+	if (ioctl (dev, VIDIOCSWIN, &vid_win) == -1) {
 		printf ("ioctl VIDIOCSWIN");
 		return (1);
 	}
@@ -101,47 +116,52 @@
 	char *grey, *rgb;
 	struct video_mmap vid_mmap;
 
-    	sigset_t    set, old;
+   	sigset_t set, old;
 
 	if (read_img) {
-		if (fmt==VIDEO_PALETTE_GREY) {
-			if (read(dev, map, width*height) != width*height)
+		
+		if (fmt == VIDEO_PALETTE_GREY) {
+			size_t size = width * height;
+			if (read(dev, map, size) != size)
 				return NULL;
 		} else {
-			if (read(dev, map, width*height*3) != width*height*3)
+			size_t size = width * height * 3;
+			if (read(dev, map, size) != size)
 				return NULL;
 		}
 	} else {
-		vid_mmap.format=fmt;
-		vid_mmap.frame=0;
-		vid_mmap.width=width;
-		vid_mmap.height=height;
+		vid_mmap.format = fmt;
+		vid_mmap.frame  = 0;
+		vid_mmap.width  = width;
+		vid_mmap.height = height;
     
-        	sigemptyset (&set);	     //BTTV hates signals during IOCTL
-	        sigaddset (&set, SIGCHLD);   //block SIGCHLD & SIGALRM
-       		sigaddset (&set, SIGALRM);   //for the time of ioctls
-        	sigprocmask (SIG_BLOCK, &set, &old);
+        sigemptyset (&set);	                 //BTTV hates signals during IOCTL
+	    sigaddset (&set, SIGCHLD);           //block SIGCHLD & SIGALRM
+       	sigaddset (&set, SIGALRM);           //for the time of ioctls
+        sigprocmask (SIG_BLOCK, &set, &old);
                     
 		if (ioctl(dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
-	        	sigprocmask (SIG_UNBLOCK, &old, NULL);
+            sigprocmask (SIG_UNBLOCK, &old, NULL);
 			return (NULL);
 		}
+
 		if (ioctl(dev, VIDIOCSYNC, &vid_mmap) == -1) {
-	        	sigprocmask (SIG_UNBLOCK, &old, NULL);
+	        sigprocmask (SIG_UNBLOCK, &old, NULL);
 			return (NULL);
 		}
 		
-        	sigprocmask (SIG_UNBLOCK, &old, NULL); //undo the signal blocking
+        sigprocmask(SIG_UNBLOCK, &old, NULL); //undo the signal blocking
 	}
 	/* Blow up a grey */
-	if (fmt==VIDEO_PALETTE_GREY) {
-		i=width*height;
-		grey=map+i-1;
-		rgb=map+i*3;
-		for (; i>=0; i--, grey--) {
-			*(rgb--)=*grey;
-			*(rgb--)=*grey;
-			*(rgb--)=*grey;
+	if (fmt == VIDEO_PALETTE_GREY) {
+		i= width * height;
+		grey=map + i - 1;
+		rgb=map + i * 3;
+
+		for (; i >= 0; i--, grey--) {
+			*(rgb--) =*grey;
+			*(rgb--) =*grey;
+			*(rgb--) =*grey;
 		}
 	}
 	return map;
@@ -149,10 +169,13 @@
 
 int put_image(int dev, char *image, int width, int height)
 {
-	if (write(dev, image, width*height*3)!=width*height*3) {
-		printf("Error writing image to pipe!\nError[%s]\n",strerror(errno));
+	size_t size = width * height * 3;
+
+	if (write(dev, image, size) != size) {
+		printf("Error writing image to pipe!\nError[%s]\n", strerror(errno));
 		return 0;
 	}
+
 	return 1;
 }
 
@@ -168,7 +191,7 @@
 	int width;
 	int height;
 	char *image_new;
-	char palette[10]={'\0'};
+	char palette[10] = {'\0'};
 	
 	if (argc != 5) {
 		printf("Usage:\n\n");
@@ -176,28 +199,34 @@
 		printf("example: feed /dev/video0 /dev/video1 352x288 yuv420p\n\n");
 		exit(1);
 	}
+
 	sscanf(argv[3], "%dx%d", &width, &height);
 	sscanf(argv[4], "%s", palette);
 
-	if (!strcmp(palette,"rgb24")) fmt = VIDEO_PALETTE_RGB24;
-	else if (!strcmp(palette,"yuv420p")) fmt = VIDEO_PALETTE_YUV420P;		
+	if (!strcmp(palette,"rgb24")) 
+		fmt = VIDEO_PALETTE_RGB24;
+	else if (!strcmp(palette,"yuv420p")) 
+		fmt = VIDEO_PALETTE_YUV420P;		
 	else fmt = VIDEO_PALETTE_RGB24; 
 		
-	devin=open (argv[1], O_RDWR);
+	devin = open (argv[1], O_RDWR);
+
 	if (devin < 0) {
-		printf ("Failed to open video device %s\nError[%s]\n",argv[1],strerror(errno));
+		printf ("Failed to open video device %s\nError[%s]\n", argv[1], strerror(errno));
 		exit(1);
 	}
 
-	devout=open (argv[2], O_RDWR);
+	devout = open (argv[2], O_RDWR);
+
 	if (devout < 0) {
-		printf ("Failed to open video device%s \nError[%s]\n",argv[2],strerror(errno));
+		printf ("Failed to open video device%s \nError[%s]\n", argv[2], strerror(errno));
 		exit(1);
 	}
 
-	image_new=start_capture (devin, width, height);
+	image_new = start_capture(devin, width, height);
+
 	if (!image_new) {
-		printf("Capture error\nError[%s]\n",strerror(errno));
+		printf("Capture error\nError[%s]\n", strerror(errno));
 		exit(1);
 	}
 
@@ -206,12 +235,25 @@
 	signal(SIGTERM, sig_handler);
 	
 	printf("Starting video stream.\n");
-	while ( (next_capture(devin, image_new, width, height)) && (noexit)) {
-		if (put_image(devout, image_new, width, height)==0)
+	
+	while ((next_capture(devin, image_new, width, height)) && (noexit)) {
+		if (put_image(devout, image_new, width, height) == 0) 
 			exit(1);
+			
 	}
-	printf("You bought vaporware!\nError[%s]\n",strerror(errno));
-	close (devin);
-	close (devout);
+
+	printf("You bought vaporware!\nError[%s]\n", strerror(errno));
+
+	close(devin);
+	close(devout);
+
+	if ((read_img) && (image_new))
+		free(image_new);
+	else if (fmt == VIDEO_PALETTE_GREY)
+		munmap(image_new, width * height * 3);
+	else
+		munmap(image_new, width * height);
+
+
 	exit(0);
 }
--- a/example/invert.c	Sat Jul 12 17:12:25 2008 +0000
+++ b/example/invert.c	Sun Aug 24 02:20:51 2008 +0000
@@ -21,76 +21,89 @@
 #include <linux/videodev.h>
 
 
-int fmt=0;
+int fmt = 0;
 int noexit = 1;
-int read_img=0;
+int read_img = 0;
 
 char *start_capture (int dev, int width, int height)
 {
-        struct video_capability vid_caps;
+    struct video_capability vid_caps;
 	struct video_window vid_win;
 	struct video_mbuf vid_buf;
 	char *map;
 
-	if (ioctl (dev, VIDIOCGCAP, &vid_caps) == -1) {
-		printf ("ioctl (VIDIOCGCAP)\nError[%s]\n",strerror(errno));
+	if (ioctl(dev, VIDIOCGCAP, &vid_caps) == -1) {
+		printf ("ioctl (VIDIOCGCAP)\nError[%s]\n", strerror(errno));
 		return (NULL);
 	}
-	if (vid_caps.type & VID_TYPE_MONOCHROME) fmt=VIDEO_PALETTE_GREY;
-	if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) {
+	if (vid_caps.type & VID_TYPE_MONOCHROME) 
+		fmt = VIDEO_PALETTE_GREY;
+
+	if (ioctl(dev, VIDIOCGMBUF, &vid_buf) == -1) {
 		fprintf(stderr, "no mmap falling back on read\n");
-		if (ioctl (dev, VIDIOCGWIN, &vid_win)== -1) {
-			printf ("ioctl VIDIOCGWIN\nError[%s]\n",strerror(errno));
+
+		if (ioctl(dev, VIDIOCGWIN, &vid_win) == -1) {
+			printf ("ioctl VIDIOCGWIN\nError[%s]\n", strerror(errno));
 			return (NULL);
 		}
-		vid_win.width=width;
-		vid_win.height=height;
-		if (ioctl (dev, VIDIOCSWIN, &vid_win)== -1) {
-			printf ("ioctl VIDIOCSWIN\nError[%s]\n",strerror(errno));
+
+		vid_win.width  = width;
+		vid_win.height = height;
+
+		if (ioctl (dev, VIDIOCSWIN, &vid_win) == -1) {
+			printf ("ioctl VIDIOCSWIN\nError[%s]\n", strerror(errno));
 			return (NULL);
 		}
-		read_img=1;
-		map=malloc(width*height*3);
+
+		read_img = 1;
+		map = malloc(width * height * 3);
 		return (map);
 	}
 	/* If we are going to capture greyscale we need room to blow the image up */
-	if (fmt==VIDEO_PALETTE_GREY)
-		map=mmap(0, vid_buf.size*3, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
+	if (fmt == VIDEO_PALETTE_GREY)
+		map = mmap(0, vid_buf.size * 3, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
 	else
-		map=mmap(0, vid_buf.size, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
+		map = mmap(0, vid_buf.size, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
 	
 	if ((unsigned char *)-1 == (unsigned char *)map)
 		return (NULL);
+
 	return map;
 }
 
 int start_pipe (int dev, int width, int height)
 {
-        struct video_capability vid_caps;
+    struct video_capability vid_caps;
 	struct video_window vid_win;
 	struct video_picture vid_pic;
 
-	if (ioctl (dev, VIDIOCGCAP, &vid_caps) == -1) {
-		printf ("ioctl (VIDIOCGCAP)\nError[%s]\n",strerror(errno));
+	if (ioctl(dev, VIDIOCGCAP, &vid_caps) == -1) {
+		printf ("ioctl (VIDIOCGCAP)\nError[%s]\n", strerror(errno));
 		return (1);
 	}
-	if (ioctl (dev, VIDIOCGPICT, &vid_pic)== -1) {
-		printf ("ioctl VIDIOCGPICT\nError[%s]\n",strerror(errno));
+
+	if (ioctl(dev, VIDIOCGPICT, &vid_pic)== -1) {
+		printf ("ioctl VIDIOCGPICT\nError[%s]\n", strerror(errno));
 		return (1);
 	}
-	vid_pic.palette=fmt;
-	if (ioctl (dev, VIDIOCSPICT, &vid_pic)== -1) {
-		printf ("ioctl VIDIOCSPICT\nError[%s]\n",strerror(errno));
+
+	vid_pic.palette = fmt;
+
+	if (ioctl(dev, VIDIOCSPICT, &vid_pic) == -1) {
+		printf ("ioctl VIDIOCSPICT\nError[%s]\n", strerror(errno));
 		return (1);
 	}
-	if (ioctl (dev, VIDIOCGWIN, &vid_win)== -1) {
-		printf ("ioctl VIDIOCGWIN\nError[%s]\n",strerror(errno));
+
+	if (ioctl (dev, VIDIOCGWIN, &vid_win) == -1) {
+		printf ("ioctl VIDIOCGWIN\nError[%s]\n", strerror(errno));
 		return (1);
 	}
-	vid_win.width=width;
-	vid_win.height=height;
-	if (ioctl (dev, VIDIOCSWIN, &vid_win)== -1) {
-		printf ("ioctl VIDIOCSWIN\nError[%s]\n",strerror(errno));
+
+	vid_win.width  = width;
+	vid_win.height = height;
+
+	if (ioctl(dev, VIDIOCSWIN, &vid_win)== -1) {
+		printf ("ioctl VIDIOCSWIN\nError[%s]\n", strerror(errno));
 		return (1);
 	}
 	return 0;
@@ -102,47 +115,50 @@
 	char *grey, *rgb;
 	struct video_mmap vid_mmap;
 
-    	sigset_t    set, old;
+    	sigset_t set, old;
 
 	if (read_img) {
-		if (fmt==VIDEO_PALETTE_GREY) {
-			if (read(dev, map, width*height) != width*height)
+		if (fmt == VIDEO_PALETTE_GREY) {
+			size_t size = width * height;
+			if (read(dev, map, size) != size)
 				return NULL;
 		} else {
-			if (read(dev, map, width*height*3) != width*height*3)
+			size_t size = width * height * 3;
+			if (read(dev, map, size) != size)
 				return NULL;
 		}
 	} else {
-		vid_mmap.format=fmt;
-		vid_mmap.frame=0;
-		vid_mmap.width=width;
-		vid_mmap.height=height;
+		vid_mmap.format = fmt;
+		vid_mmap.frame  = 0;
+		vid_mmap.width  = width;
+		vid_mmap.height = height;
     
-        	sigemptyset (&set);	     //BTTV hates signals during IOCTL
-	        sigaddset (&set, SIGCHLD);   //block SIGCHLD & SIGALRM
-       		sigaddset (&set, SIGALRM);   //for the time of ioctls
-        	sigprocmask (SIG_BLOCK, &set, &old);
+        sigemptyset (&set);	                  //BTTV hates signals during IOCTL
+	    sigaddset (&set, SIGCHLD);            //block SIGCHLD & SIGALRM
+       	sigaddset (&set, SIGALRM);            //for the time of ioctls
+        sigprocmask (SIG_BLOCK, &set, &old);
                     
 		if (ioctl(dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
-	        	sigprocmask (SIG_UNBLOCK, &old, NULL);
+	        sigprocmask (SIG_UNBLOCK, &old, NULL);
 			return (NULL);
 		}
+
 		if (ioctl(dev, VIDIOCSYNC, &vid_mmap) == -1) {
-	        	sigprocmask (SIG_UNBLOCK, &old, NULL);
+	        sigprocmask (SIG_UNBLOCK, &old, NULL);
 			return (NULL);
 		}
 		
-        	sigprocmask (SIG_UNBLOCK, &old, NULL); //undo the signal blocking
+        sigprocmask (SIG_UNBLOCK, &old, NULL); //undo the signal blocking
 	}
 	/* Blow up a grey */
-	if (fmt==VIDEO_PALETTE_GREY) {
-		i=width*height;
-		grey=map+i-1;
-		rgb=map+i*3;
-		for (; i>=0; i--, grey--) {
-			*(rgb--)=*grey;
-			*(rgb--)=*grey;
-			*(rgb--)=*grey;
+	if (fmt == VIDEO_PALETTE_GREY) {
+		i = width * height;
+		grey =map + i - 1;
+		rgb = map + i * 3;
+		for (; i >= 0; i--, grey--) {
+			*(rgb--) =*grey;
+			*(rgb--) =*grey;
+			*(rgb--) =*grey;
 		}
 	}
 	return map;
@@ -150,10 +166,11 @@
 
 int put_image(int dev, char *image, int width, int height)
 {
-	if (write(dev, image, width*height*3)!=width*height*3) {
-		printf("Error writing image to pipe!\nError[%s]\n",strerror(errno));
+	if (write(dev, image, width * height * 3) != width * height * 3) {
+		printf("Error writing image to pipe!\nError[%s]\n", strerror(errno));
 		return 0;
 	}
+
 	return 1;
 }
 
@@ -169,7 +186,7 @@
 	int width;
 	int height;
 	char *image_out, *image_new;
-	char palette[10]={'\0'};
+	char palette[10] = {'\0'};
 	
 	if (argc != 5) {
 		printf("Usage:\n\n");
@@ -180,28 +197,33 @@
 	sscanf(argv[3], "%dx%d", &width, &height);
 	sscanf(argv[4], "%s", palette);
 
-	if (!strcmp(palette,"rgb24")) fmt = VIDEO_PALETTE_RGB24;
-	else if (!strcmp(palette,"yuv420p")) fmt = VIDEO_PALETTE_YUV420P;
+	if (!strcmp(palette,"rgb24")) 
+		fmt = VIDEO_PALETTE_RGB24;
+	else if (!strcmp(palette,"yuv420p")) 
+		fmt = VIDEO_PALETTE_YUV420P;
 	else fmt = VIDEO_PALETTE_RGB24;
 
 	
-	image_out=malloc(width*height*3);
+	image_out = malloc(width * height * 3);
 
-	devin=open (argv[1], O_RDWR);
+	devin = open (argv[1], O_RDWR);
+
 	if (devin < 0) {
-		printf("Failed to open input video device [%s]\nError:[%s]\n",argv[1],strerror(errno));
+		printf("Failed to open input video device [%s]\nError:[%s]\n", argv[1], strerror(errno));
 		exit(1);
 	}
 
-	devout=open (argv[2], O_RDWR);
+	devout = open (argv[2], O_RDWR);
+
 	if (devout < 0) {
-		printf ("Failed to open output video device [%s]\nError:[%s]\n",argv[2],strerror(errno));
+		printf ("Failed to open output video device [%s]\nError:[%s]\n", argv[2], strerror(errno));
 		exit(1);
 	}
 
-	image_new=start_capture (devin, width, height);
+	image_new = start_capture(devin, width, height);
+
 	if (!image_new) {
-		printf("Capture error \n Error[%s]\n",strerror(errno));
+		printf("Capture error \n Error[%s]\n", strerror(errno));
 		exit(1);
 	}
 
@@ -210,14 +232,36 @@
 	signal(SIGTERM, sig_handler);
 	
 	printf("Starting video stream.\n");
-	while ( (next_capture(devin, image_new, width, height)) && (noexit) ){
-		for (i=width*height*3; i>=0; i--) image_out[i]=-image_new[i];
-		if (put_image(devout, image_out, width, height)==0)
+	
+	while ( (next_capture(devin, image_new, width, height)) && (noexit) ) {
+		for (i = width * height * 3; i >= 0; i--) 
+			image_out[i] =-image_new[i];
+
+		if (put_image(devout, image_out, width, height) == 0) {
+			if ((read_img) && (image_new))
+				free(image_new);
+			else if (fmt == VIDEO_PALETTE_GREY)
+				munmap(image_new, width * height * 3);
+			else
+				munmap(image_new, width * height);
+			free(image_out);
 			exit(1);
+		}	
 	}
-	printf("You bought vaporware!\nError[%s]\n",strerror(errno));
+
+	printf("You bought vaporware!\nError[%s]\n", strerror(errno));
+
 	close (devin);
 	close (devout);
+
+	if ((read_img) && (image_new))
+		free(image_new);
+	else if (fmt == VIDEO_PALETTE_GREY)
+		munmap(image_new, width * height * 3);			
+	else
+		munmap(image_new, width * height);
+
 	free(image_out);
+
 	exit(0);
 }
--- a/example/resize.c	Sat Jul 12 17:12:25 2008 +0000
+++ b/example/resize.c	Sun Aug 24 02:20:51 2008 +0000
@@ -21,41 +21,49 @@
 #include <linux/videodev.h>
 
 
-int fmt=0;
+int fmt = 0;
 int noexit = 1;
-int read_img=0;
+int read_img = 0;
 
 char *start_capture (int dev, int width, int height)
 {
-        struct video_capability vid_caps;
+    struct video_capability vid_caps;
 	struct video_window vid_win;
 	struct video_mbuf vid_buf;
 	char *map;
 
-	if (ioctl (dev, VIDIOCGCAP, &vid_caps) == -1) {
-		printf ("ioctl (VIDIOCGCAP)\nError[%s]\n",strerror(errno));
+	if (ioctl(dev, VIDIOCGCAP, &vid_caps) == -1) {
+		printf ("ioctl (VIDIOCGCAP)\nError[%s]\n", strerror(errno));
 		return (NULL);
 	}
-	if (vid_caps.type & VID_TYPE_MONOCHROME) fmt=VIDEO_PALETTE_GREY;
-	if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) {
+
+	if (vid_caps.type & VID_TYPE_MONOCHROME) 
+		fmt = VIDEO_PALETTE_GREY;
+
+	if (ioctl(dev, VIDIOCGMBUF, &vid_buf) == -1) {
 		fprintf(stderr, "no mmap falling back on read\n");
-		if (ioctl (dev, VIDIOCGWIN, &vid_win)== -1) {
-			printf ("ioctl VIDIOCGWIN\nError[%s]\n",strerror(errno));
+
+		if (ioctl(dev, VIDIOCGWIN, &vid_win)== -1) {
+			printf ("ioctl VIDIOCGWIN\nError[%s]\n", strerror(errno));
 			return (NULL);
 		}
-		vid_win.width=width;
-		vid_win.height=height;
-		if (ioctl (dev, VIDIOCSWIN, &vid_win)== -1) {
-			printf ("ioctl VIDIOCSWIN\nError[%s]\n",strerror(errno));
+
+		vid_win.width  = width;
+		vid_win.height = height;
+
+		if (ioctl(dev, VIDIOCSWIN, &vid_win)== -1) {
+			printf ("ioctl VIDIOCSWIN\nError[%s]\n", strerror(errno));
 			return (NULL);
 		}
-		read_img=1;
-		map=malloc(width*height*3);
+
+		read_img = 1;
+		map = malloc(width * height * 3);
+
 		return (map);
 	}
 	/* If we are going to capture greyscale we need room to blow the image up */
-	if (fmt==VIDEO_PALETTE_GREY)
-		map=mmap(0, vid_buf.size*3, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
+	if (fmt == VIDEO_PALETTE_GREY)
+		map=mmap(0, vid_buf.size * 3, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
 	else
 		map=mmap(0, vid_buf.size, PROT_READ|PROT_WRITE, MAP_SHARED, dev, 0);
 	
@@ -66,33 +74,40 @@
 
 int start_pipe (int dev, int width, int height)
 {
-        struct video_capability vid_caps;
+    struct video_capability vid_caps;
 	struct video_window vid_win;
 	struct video_picture vid_pic;
 
-	if (ioctl (dev, VIDIOCGCAP, &vid_caps) == -1) {
-		printf ("ioctl (VIDIOCGCAP)\nError[%s]\n",strerror(errno));
+	if (ioctl(dev, VIDIOCGCAP, &vid_caps) == -1) {
+		printf ("ioctl (VIDIOCGCAP)\nError[%s]\n", strerror(errno));
+		return (1);
+	}
+
+	if (ioctl(dev, VIDIOCGPICT, &vid_pic) == -1) {
+		printf ("ioctl VIDIOCGPICT\nError[%s]\n", strerror(errno));
 		return (1);
 	}
-	if (ioctl (dev, VIDIOCGPICT, &vid_pic)== -1) {
-		printf ("ioctl VIDIOCGPICT\nError[%s]\n",strerror(errno));
+
+	vid_pic.palette = fmt;
+
+	if (ioctl(dev, VIDIOCSPICT, &vid_pic) == -1) {
+		printf ("ioctl VIDIOCSPICT\nError[%s]\n", strerror(errno));
 		return (1);
 	}
-	vid_pic.palette=fmt;
-	if (ioctl (dev, VIDIOCSPICT, &vid_pic)== -1) {
-		printf ("ioctl VIDIOCSPICT\nError[%s]\n",strerror(errno));
-		return (1);
-	}
-	if (ioctl (dev, VIDIOCGWIN, &vid_win)== -1) {
+
+	if (ioctl(dev, VIDIOCGWIN, &vid_win) == -1) {
 		printf ("ioctl VIDIOCGWIN");
 		return (1);
 	}
-	vid_win.width=width;
-	vid_win.height=height;
-	if (ioctl (dev, VIDIOCSWIN, &vid_win)== -1) {
+
+	vid_win.width  = width;
+	vid_win.height = height;
+	
+	if (ioctl(dev, VIDIOCSWIN, &vid_win)== -1) {
 		printf ("ioctl VIDIOCSWIN");
 		return (1);
 	}
+
 	return 0;
 }
 
@@ -102,47 +117,49 @@
 	char *grey, *rgb;
 	struct video_mmap vid_mmap;
 
-    	sigset_t    set, old;
+   	sigset_t set, old;
 
 	if (read_img) {
-		if (fmt==VIDEO_PALETTE_GREY) {
-			if (read(dev, map, width*height) != width*height)
+		if (fmt == VIDEO_PALETTE_GREY) {
+			size_t size = width * height;
+			if (read(dev, map, size) != size)
 				return NULL;
 		} else {
-			if (read(dev, map, width*height*3) != width*height*3)
+			size_t size = width * height * 3;
+			if (read(dev, map, size) != size)
 				return NULL;
 		}
 	} else {
-		vid_mmap.format=fmt;
-		vid_mmap.frame=0;
-		vid_mmap.width=width;
-		vid_mmap.height=height;
+		vid_mmap.format = fmt;
+		vid_mmap.frame = 0;
+		vid_mmap.width = width;
+		vid_mmap.height = height;
     
-        	sigemptyset (&set);	     //BTTV hates signals during IOCTL
-	        sigaddset (&set, SIGCHLD);   //block SIGCHLD & SIGALRM
-       		sigaddset (&set, SIGALRM);   //for the time of ioctls
-        	sigprocmask (SIG_BLOCK, &set, &old);
+       	sigemptyset (&set);	                  //BTTV hates signals during IOCTL
+	    sigaddset (&set, SIGCHLD);            //block SIGCHLD & SIGALRM
+        sigaddset (&set, SIGALRM);            //for the time of ioctls
+        sigprocmask (SIG_BLOCK, &set, &old);
                     
 		if (ioctl(dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
-	        	sigprocmask (SIG_UNBLOCK, &old, NULL);
+	        sigprocmask (SIG_UNBLOCK, &old, NULL);
 			return (NULL);
 		}
 		if (ioctl(dev, VIDIOCSYNC, &vid_mmap) == -1) {
-	        	sigprocmask (SIG_UNBLOCK, &old, NULL);
+	        sigprocmask (SIG_UNBLOCK, &old, NULL);
 			return (NULL);
 		}
 		
-        	sigprocmask (SIG_UNBLOCK, &old, NULL); //undo the signal blocking
+        	sigprocmask(SIG_UNBLOCK, &old, NULL); //undo the signal blocking
 	}
 	/* Blow up a grey */
-	if (fmt==VIDEO_PALETTE_GREY) {
-		i=width*height;
-		grey=map+i-1;
-		rgb=map+i*3;
-		for (; i>=0; i--, grey--) {
-			*(rgb--)=*grey;
-			*(rgb--)=*grey;
-			*(rgb--)=*grey;
+	if (fmt == VIDEO_PALETTE_GREY) {
+		i = width * height;
+		grey = map + i - 1;
+		rgb = map + i * 3;
+		for (; i >= 0; i--, grey--) {
+			*(rgb--) =*grey;
+			*(rgb--) =*grey;
+			*(rgb--) =*grey;
 		}
 	}
 	return map;
@@ -150,8 +167,8 @@
 
 int put_image(int dev, char *image, int width, int height)
 {
-	if (write(dev, image, width*height*3)!=width*height*3) {
-		printf("Error writing image to pipe!\nError[%s]\n",strerror(errno));
+	if (write(dev, image, width * height * 3) != width * height * 3) {
+		printf("Error writing image to pipe!\nError[%s]\n", strerror(errno));
 		return 0;
 	}
 	return 1;
@@ -171,7 +188,7 @@
 	int heightout;
 	int **newy, **newx, **line;
 	char *image_out, *image_new;
-	char palette[10]={'\0'};
+	char palette[10] = {'\0'};
 	
 	if (argc != 6) {
 		printf("Usage:\n\n");
@@ -179,81 +196,88 @@
 		printf("example: resize /dev/video0 /dev/video1 352x288 176x144 yuv420p\n\n");
 		exit(1);
 	}
+	
 	sscanf(argv[3], "%dx%d", &width, &height);
 	sscanf(argv[4], "%dx%d", &widthout, &heightout);
 	sscanf(argv[5], "%s", palette);
 
-	if (!strcmp(palette,"rgb24")) fmt = VIDEO_PALETTE_RGB24;
-	else if (!strcmp(palette,"yuv420p")) fmt = VIDEO_PALETTE_YUV420P;		
+	if (!strcmp(palette,"rgb24")) 
+		fmt = VIDEO_PALETTE_RGB24;
+	else if (!strcmp(palette,"yuv420p")) 
+		fmt = VIDEO_PALETTE_YUV420P;		
 	else fmt = VIDEO_PALETTE_RGB24; 
 		
-	realwidth=width*3;
-	realwidthout=widthout*3;
+	realwidth = width * 3;
+	realwidthout = widthout * 3;
+
+	image_out = malloc(widthout * heightout * 3);
+	line = malloc(sizeof(int*) * heightout);
+	newy = malloc(sizeof(int*) * heightout);
+	newx = malloc(sizeof(int*) * realwidthout);
 
-	image_out=malloc(widthout*heightout*3);
-	line=malloc(sizeof(int*)*heightout);
-	newy=malloc(sizeof(int*)*heightout);
-	newx=malloc(sizeof(int*)*realwidthout);
-	for (y=0; y<heightout; y++) {
-		line[y]=malloc(sizeof(int));
-		line[y][0]=y*realwidthout;
-		newy[y]=malloc(sizeof(int));
-		newy[y][0]=y*height/heightout*realwidth;
+	for (y = 0; y < heightout; y++) {
+		line[y] = malloc(sizeof(int));
+		line[y][0] = y * realwidthout;
+		newy[y] = malloc(sizeof(int));
+		newy[y][0] = y * height / heightout * realwidth;
 	}
-	for (x=0; x<widthout; x++) {
-		newx[x*3]=malloc(sizeof(int));
-		newx[x*3+1]=malloc(sizeof(int));
-		newx[x*3+2]=malloc(sizeof(int));
-		newx[x*3][0]=x*width/widthout*3;
-		newx[x*3+1][0]=x*width/widthout*3+1;
-		newx[x*3+2][0]=x*width/widthout*3+2;
+
+	for (x = 0; x < widthout; x++) {
+		newx[x *3] = malloc(sizeof(int));
+		newx[x *3 + 1] = malloc(sizeof(int));
+		newx[x *3 + 2] = malloc(sizeof(int));
+		newx[x *3][0] = x * width / widthout * 3;
+		newx[x *3 + 1][0] = x * width / widthout * 3 + 1;
+		newx[x * 3 + 2][0] = x * width / widthout * 3 + 2;
 	}
 	
-	devin=open (argv[1], O_RDWR);
+	devin = open(argv[1], O_RDWR);
+
 	if (devin < 0) {
-		printf ("Failed to open video device %s\nError[%s]\n",argv[1],strerror(errno));
+		printf ("Failed to open video device %s\nError[%s]\n", argv[1], strerror(errno));
 		exit(1);
 	}
 
-	devout=open (argv[2], O_RDWR);
+	devout = open(argv[2], O_RDWR);
+
 	if (devout < 0) {
-		printf ("Failed to open video device%s \nError[%s]\n",argv[2],strerror(errno));
+		printf ("Failed to open video device%s \nError[%s]\n", argv[2], strerror(errno));
 		exit(1);
 	}
 
 	image_new=start_capture (devin, width, height);
+
 	if (!image_new) {
-		printf("Capture error\nError[%s]\n",strerror(errno));
+		printf("Capture error\nError[%s]\n", strerror(errno));
 		exit(1);
 	}
 
 	start_pipe(devout, widthout, heightout);
-
 	signal(SIGTERM, sig_handler);
-	
 	printf("Starting video stream.\n");
-	while ( (next_capture(devin, image_new, width, height)) && (noexit)) {
-		for (y=0; y<heightout; y++) {
-			for (x=0; x<realwidthout; x++) {
-				image_out[line[y][0]+x]=
-				    image_new[newy[y][0]+newx[x][0]];
-			}
+
+	while ((next_capture(devin, image_new, width, height)) && (noexit)) {
+		for (y = 0; y < heightout; y++) {
+			for (x = 0; x < realwidthout; x++) 
+				image_out[line[y][0] + x] = image_new[newy[y][0] + newx[x][0]];
 		}
-		if (put_image(devout, image_out, widthout, heightout)==0)
+
+		if (put_image(devout, image_out, widthout, heightout) == 0)
 			exit(1);
 	}
-	printf("You bought vaporware!\nError[%s]\n",strerror(errno));
-	close (devin);
-	close (devout);
 
-	for (y=0; y<heightout; y++) {
+	printf("You bought vaporware!\nError[%s]\n", strerror(errno));
+	close(devin);
+	close(devout);
+
+	for (y = 0; y < heightout; y++) {
 		free(line[y]);
 		free(newy[y]);
 	}
-	for (x=0; x<widthout; x++) {
-		free(newx[x*3]);
-		free(newx[x*3+1]);
-		free(newx[x*3+2]);
+	for (x = 0; x < widthout; x++) {
+		free(newx[x * 3]);
+		free(newx[x * 3 + 1]);
+		free(newx[x * 3 + 2]);
 	}
 
 	free(line);
--- a/vloopback.c	Sat Jul 12 17:12:25 2008 +0000
+++ b/vloopback.c	Sun Aug 24 02:20:51 2008 +0000
@@ -7,12 +7,12 @@
  *
  *	Published under the GNU Public License.
  *
- *	The Video Loopback Device is no longer systematically maintained.
+ *	The Video loopback Loopback Device is no longer systematically maintained.
  *	The project is a secondary project for the project "motion" found at
  *	http://motion.sourceforge.net/ and
  *	http://www.lavrsen.dk/twiki/bin/view/Motion/WebHome
  *	and with the vloopback stored at
- *	http://www.lavrsen.dk/twiki/bin/view/Motion/VideoFourLinuxLoopbackDevice
+ *	http://www.lavrsen.dk/twiki/bin/view/Motion/Video loopbackFourLinuxLoopbackDevice
  *
  *	CHANGE HISTORY
  *
@@ -136,7 +136,11 @@
  * 			Change -ENOIOCTLCMD by more appropiate error -ENOTTY.
  * 								
  * 18.05.08	(Angel Carpintero)
- * 			Release 1.1-rc1 as 1.1 stable working with 2.6.24								
+ * 			Release 1.1-rc1 as 1.1 stable working with 2.6.24
+ *
+ * 17.08.08	(Angel Carpintero)
+ * 			kill_proc() deprecated ,pid API changed , type and owner not available in 							
+ * 			video_device struct, added param debug.
  */
 
 
@@ -150,7 +154,7 @@
 #include <linux/pagemap.h>
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
-#include <media/v4l2-common.h>
+ #include <media/v4l2-common.h>
 #endif
 
 #include <linux/videodev.h>
@@ -183,12 +187,24 @@
  
 #define VIDIOCSINVALID	_IO('v',BASE_VIDIOCPRIVATE+1)
 
-#define info(format, arg...) printk(KERN_INFO __FILE__ ": " format "\n" "", ## arg)
+#define verbose(format, arg...) if (printk_ratelimit()) \
+        printk(KERN_INFO "[%s] %s: " format "\n" "", \
+                __FUNCTION__, __FILE__,  ## arg)
+
+#define info(format, arg...) if (printk_ratelimit()) \
+        printk(KERN_INFO "[%s] : " format "\n" "", \
+               __FUNCTION__, ## arg)
+
+#define LOG_NODEBUG   0 
+#define LOG_FUNCTIONS 1
+#define LOG_IOCTL     2
+#define LOG_VERBOSE   3
 
 struct vloopback_private {
 	int pipenr;
-	int in; /* bool */
+	int in; /* bool , is being feed ? */
 };
+
 typedef struct vloopback_private *priv_ptr;
 
 struct vloopback_pipe {
@@ -206,7 +222,11 @@
 	struct semaphore lock;
 	wait_queue_head_t wait;
 	unsigned int frame;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)    
 	unsigned int pid;
+#else
+    struct pid *pid;    
+#endif    
 	unsigned int zerocopy;
 	unsigned long int ioctlnr;
 	unsigned int invalid_ioctl; /* 0 .. none invalid; 1 .. invalid */
@@ -219,11 +239,12 @@
 #define	N_BUFFS	2	/* Number of buffers used for pipes */
 
 static struct vloopback_pipe *loops[MAX_PIPES];
-static int nr_o_pipes=0;
-static int pipes=-1;
-static int spares=0;
-static int pipesused=0;
-static int dev_offset=-1;
+static int nr_o_pipes = 0;
+static int pipes = -1;
+static int spares = 0;
+static int pipesused = 0;
+static int dev_offset = -1;
+static unsigned int debug = LOG_NODEBUG;
 
 /**********************************************************************
  *
@@ -237,7 +258,7 @@
  */
 static inline unsigned long kvirt_to_pa(unsigned long adr) 
 {
-        unsigned long kva;
+    unsigned long kva;
 
 	kva = (unsigned long)page_address(vmalloc_to_page((void *)adr));
 	kva |= adr & (PAGE_SIZE-1); /* restore the offset */
@@ -303,14 +324,23 @@
 static int fake_ioctl(int nr, unsigned long int cmd, void *arg)
 {
 	unsigned long fw;
-	
-	loops[nr]->ioctlnr=cmd;
+
+    if (debug > LOG_NODEBUG)
+        info("Video loopback %d cmd %lu", nr, cmd);
+
+	loops[nr]->ioctlnr = cmd;
 	memcpy(loops[nr]->ioctldata, arg, _IOC_SIZE(cmd));
-	loops[nr]->ioctllength=_IOC_SIZE(cmd);
-	kill_proc(loops[nr]->pid, SIGIO, 1);	/* Signal the pipe feeder */
+	loops[nr]->ioctllength = _IOC_SIZE(cmd);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+    kill_proc(loops[nr]->pid, SIGIO, 1);    /* Signal the pipe feeder */
+#else
+    kill_pid(loops[nr]->pid, SIGIO, 1);
+#endif
+
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	fw = loops[nr]->frameswrite;
-	wait_event_interruptible(loops[nr]->wait, fw!=loops[nr]->frameswrite);
+	wait_event_interruptible(loops[nr]->wait, fw != loops[nr]->frameswrite);
 #else
 	interruptible_sleep_on(&loops[nr]->wait);
 #endif	
@@ -325,28 +355,31 @@
 
 static int vloopback_open(struct inode *inod, struct file *f)
 {	
-	struct video_device *loopdev=video_devdata(f);
-	priv_ptr ptr=(priv_ptr)loopdev->priv;
-	int nr=ptr->pipenr;
-	
+	struct video_device *loopdev = video_devdata(f);
+	priv_ptr ptr = (priv_ptr)loopdev->priv;
+	int nr = ptr->pipenr;
+
+    if (debug > LOG_NODEBUG)
+        info("Video loopback %d", nr);    
 
 	/* Only allow a output to be opened if there is someone feeding
 	 * the pipe.
 	 */
 	if (!ptr->in) {
-		if (loops[nr]->buffer==NULL) {
+		if (loops[nr]->buffer == NULL) 
 			return -EINVAL;
-		}
-		loops[nr]->framesread=0;
-		loops[nr]->ropen=1;
+		
+		loops[nr]->framesread = 0;
+		loops[nr]->ropen = 1;
 	} else {
 		if (loops[nr]->ropen || loops[nr]->wopen) 
 			return -EBUSY;
-		loops[nr]->framesdumped=0;
-		loops[nr]->frameswrite=0;
-		loops[nr]->wopen=1;
-		loops[nr]->zerocopy=0;
-		loops[nr]->ioctlnr=-1;
+
+		loops[nr]->framesdumped = 0;
+		loops[nr]->frameswrite = 0;
+		loops[nr]->wopen = 1;
+		loops[nr]->zerocopy = 0;
+		loops[nr]->ioctlnr = -1;
 		pipesused++;
 		if (nr_o_pipes-pipesused<spares) {
 			if (!create_pipe(nr_o_pipes)) {
@@ -359,47 +392,61 @@
 				nr_o_pipes++;
 			}
 		}
-		loops[nr]->pid=current->pid;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+        loops[nr]->pid = current->pid;
+#else
+        // TODO : Check in stable 2.6.27
+        loops[nr]->pid = task_pid(find_task_by_vpid(current->pid));
+        //loops[nr]->pid = task_pid(current);
+#endif        
+
+        if (debug > LOG_NODEBUG)
+            info("Current pid %d", current->pid);
 	}
 	return 0;
 }
 
 static int vloopback_release(struct inode * inod, struct file *f)
 {
-	struct video_device *loopdev=video_devdata(f);
-	priv_ptr ptr=(priv_ptr)loopdev->priv;
-	int nr=ptr->pipenr;
-	
+	struct video_device *loopdev = video_devdata(f);
+	priv_ptr ptr = (priv_ptr)loopdev->priv;
+	int nr = ptr->pipenr;
+
+    if (debug > LOG_NODEBUG)
+        info("Video loopback %d", nr);
+
 	if (ptr->in) {
 		down(&loops[nr]->lock);
 		if (loops[nr]->buffer && !loops[nr]->ropen) {
-			rvfree(loops[nr]->buffer,
-			    loops[nr]->buflength*N_BUFFS);
-			loops[nr]->buffer=NULL;
+			rvfree(loops[nr]->buffer, loops[nr]->buflength * N_BUFFS);
+			loops[nr]->buffer = NULL;
 		}
 		up(&loops[nr]->lock);
 		loops[nr]->frameswrite++;
 		if (waitqueue_active(&loops[nr]->wait))
 			wake_up(&loops[nr]->wait);
 
-		loops[nr]->width=0;
-		loops[nr]->height=0;
-		loops[nr]->palette=0;
-		loops[nr]->wopen=0;
+		loops[nr]->width = 0;
+		loops[nr]->height = 0;
+		loops[nr]->palette = 0;
+		loops[nr]->wopen = 0;
 		pipesused--;
 	} else {
 		down(&loops[nr]->lock);
 		if (loops[nr]->buffer && !loops[nr]->wopen) {
-			rvfree(loops[nr]->buffer,
-			    loops[nr]->buflength*N_BUFFS);
-			loops[nr]->buffer=NULL;
+			rvfree(loops[nr]->buffer, loops[nr]->buflength * N_BUFFS);
+			loops[nr]->buffer = NULL;
 		}
 		up(&loops[nr]->lock);
-		loops[nr]->ropen=0;
+		loops[nr]->ropen = 0;
 		if (loops[nr]->zerocopy && loops[nr]->buffer) {
-			loops[nr]->ioctlnr=0;
-			loops[nr]->ioctllength=0;
-			kill_proc(loops[nr]->pid, SIGIO, 1);
+			loops[nr]->ioctlnr = 0;
+			loops[nr]->ioctllength = 0;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+            kill_proc(loops[nr]->pid, SIGIO, 1);
+#else
+            kill_pid(loops[nr]->pid, SIGIO, 1);
+#endif            
 		}
 	}
 
@@ -407,22 +454,25 @@
 }
 
 static ssize_t vloopback_write(struct file *f, const char *buf,
-		size_t count, loff_t *offset)
+               size_t count, loff_t *offset)
 {
-	struct video_device *loopdev=video_devdata(f);
-	priv_ptr ptr=(priv_ptr)loopdev->priv;
-	int nr=ptr->pipenr;
-	unsigned long realcount=count;
-	
+	struct video_device *loopdev = video_devdata(f);
+	priv_ptr ptr = (priv_ptr)loopdev->priv;
+	int nr = ptr->pipenr;
+	unsigned long realcount = count;
+
+    if (debug > LOG_IOCTL)
+        info("Video loopback %d", nr);
+
 	if (!ptr->in)
 		return -EINVAL;
+
 	if (loops[nr]->zerocopy)
 		return -EINVAL;
 	
-	if (loops[nr]->buffer==NULL) {
+	if (loops[nr]->buffer == NULL) 
 		return -EINVAL;
-	}
-
+	
 	/* Anybody want some pictures??? */
 	if (!waitqueue_active(&loops[nr]->wait)) {
 		loops[nr]->framesdumped++;
@@ -434,17 +484,18 @@
 		up(&loops[nr]->lock);
 		return -EINVAL;
 	}
+
 	if (realcount > loops[nr]->buflength) {
 		realcount = loops[nr]->buflength;
-		info("Too much data! Only %ld bytes used.", realcount);
+		info("Too much data for Video loopback %d ! Only %ld bytes used.", 
+             nr, realcount);
 	}
 	
-	if (copy_from_user(
-	    loops[nr]->buffer+loops[nr]->frame*loops[nr]->buflength,
-	    buf, realcount
-	)) return -EFAULT;
+	if (copy_from_user(loops[nr]->buffer + loops[nr]->frame * loops[nr]->buflength, 
+                       buf, realcount)) 
+        return -EFAULT;
 
-	loops[nr]->frame=0;
+	loops[nr]->frame = 0;
 	up(&loops[nr]->lock);
 
 	loops[nr]->frameswrite++;
@@ -453,24 +504,32 @@
 	return realcount;
 }
 
-static ssize_t vloopback_read (struct file * f, char * buf, size_t count, loff_t *offset)
+static ssize_t vloopback_read(struct file * f, char * buf, size_t count, 
+               loff_t *offset)
 {
-	struct video_device *loopdev=video_devdata(f);
-	priv_ptr ptr=(priv_ptr)loopdev->priv;
-	int nr=ptr->pipenr;
-	unsigned long realcount=count;
+	struct video_device *loopdev = video_devdata(f);
+	priv_ptr ptr = (priv_ptr)loopdev->priv;
+	int nr = ptr->pipenr;
+	unsigned long realcount = count;
+
+    if (debug > LOG_IOCTL)
+        info("Video loopback %d", nr);
 
 	if (loops[nr]->zerocopy) {
 		if (ptr->in) {
-			if (realcount > loops[nr]->ioctllength+sizeof(unsigned long int))
-				realcount=loops[nr]->ioctllength+sizeof(unsigned long int);
+			if (realcount > loops[nr]->ioctllength + sizeof(unsigned long int))
+				realcount = loops[nr]->ioctllength + sizeof(unsigned long int);
+
 			if (copy_to_user(buf , &loops[nr]->ioctlnr, sizeof(unsigned long int)))
 				return -EFAULT;
-			if (copy_to_user(buf+sizeof(unsigned long int) , loops[nr]->ioctldata, 
-					realcount-sizeof(unsigned long int)))
+
+			if (copy_to_user(buf + sizeof(unsigned long int), loops[nr]->ioctldata, 
+				             realcount - sizeof(unsigned long int)))
 				return -EFAULT;	
-			if (loops[nr]->ioctlnr==0)
-				loops[nr]->ioctlnr=-1;
+
+			if (loops[nr]->ioctlnr == 0)
+				loops[nr]->ioctlnr = -1;
+
 			return realcount;
 		} else {
 			struct video_window vidwin;
@@ -480,30 +539,34 @@
 			fake_ioctl(nr, VIDIOCGWIN, &vidwin);
 			fake_ioctl(nr, VIDIOCGPICT, &vidpic);
 
-			vidmmap.height=vidwin.height;
-			vidmmap.width=vidwin.width;
-			vidmmap.format=vidpic.palette;
-			vidmmap.frame=0;
+			vidmmap.height = vidwin.height;
+			vidmmap.width = vidwin.width;
+			vidmmap.format = vidpic.palette;
+			vidmmap.frame = 0;
+
 			if (fake_ioctl(nr, VIDIOCMCAPTURE, &vidmmap))
 				return 0;
+
 			if (fake_ioctl(nr, VIDIOCSYNC, &vidmmap))
 				return 0;
-			realcount=vidwin.height*vidwin.width*vidpic.depth;
+
+			realcount = vidwin.height * vidwin.width * vidpic.depth;
 		}
 	}
+
 	if (ptr->in)
 		return -EINVAL;
 
 	if (realcount > loops[nr]->buflength) {
 		realcount = loops[nr]->buflength;
-		info("Not so much data in buffer!");
+		info("Not so much data in buffer! for Video loopback %d", nr);
 	}
 
 	if (!loops[nr]->zerocopy) {
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-		unsigned long fw=loops[nr]->frameswrite;
+		unsigned long fw = loops[nr]->frameswrite;
 		
-		wait_event_interruptible(loops[nr]->wait, fw!=loops[nr]->frameswrite);
+		wait_event_interruptible(loops[nr]->wait, fw != loops[nr]->frameswrite);
 #else
 		interruptible_sleep_on(&loops[nr]->wait);
 #endif
@@ -514,8 +577,10 @@
 		up(&loops[nr]->lock);
 		return 0;
 	}
+
 	if (copy_to_user(buf, loops[nr]->buffer, realcount))
 		return -EFAULT;
+
 	up(&loops[nr]->lock);
 
 	loops[nr]->framesread++;
@@ -524,95 +589,118 @@
 
 static int vloopback_mmap(struct file *f, struct vm_area_struct *vma)
 {
-	struct video_device *loopdev=video_devdata(f);
-	priv_ptr ptr=(priv_ptr)loopdev->priv;
-	int nr=ptr->pipenr;
+	struct video_device *loopdev = video_devdata(f);
+	priv_ptr ptr = (priv_ptr)loopdev->priv;
+	int nr = ptr->pipenr;
 	unsigned long start = (unsigned long)vma->vm_start;
 	long size = vma->vm_end - vma->vm_start;
 	unsigned long page, pos;
 
+    if (debug > LOG_NODEBUG)
+        info("Video loopback %d", nr);
+
 	down(&loops[nr]->lock);
+
 	if (ptr->in) {
-		loops[nr]->zerocopy=1;
+		loops[nr]->zerocopy = 1;
+
 		if (loops[nr]->ropen) {
-			info("Can't change size while opened for read");
-			up(&loops[nr]->lock);
-			return -EINVAL;
-		}
-		if (!size) {
+			info("Can't change size while opened for read in Video loopback %d",
+                 nr);
 			up(&loops[nr]->lock);
 			return -EINVAL;
 		}
+
+		if (!size) {
+			up(&loops[nr]->lock);
+            info("Invalid size Video loopback %d", nr);
+			return -EINVAL;
+		}
+
 		if (loops[nr]->buffer)
-			rvfree(loops[nr]->buffer, loops[nr]->buflength*N_BUFFS);
-		loops[nr]->buflength=size;
-		loops[nr]->buffer=rvmalloc(loops[nr]->buflength*N_BUFFS);
-	}
-        if (loops[nr]->buffer == NULL) {
-		up(&loops[nr]->lock);
-                return -EINVAL;
+			rvfree(loops[nr]->buffer, loops[nr]->buflength * N_BUFFS);
+
+		loops[nr]->buflength = size;
+		loops[nr]->buffer = rvmalloc(loops[nr]->buflength * N_BUFFS);
 	}
 
-        if (size > (((N_BUFFS * loops[nr]->buflength) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
+    if (loops[nr]->buffer == NULL) {
 		up(&loops[nr]->lock);
-                return -EINVAL;
+        return -EINVAL;
 	}
 
-        pos = (unsigned long)loops[nr]->buffer;
-        while (size > 0) {
+    if (size > (((N_BUFFS * loops[nr]->buflength) + PAGE_SIZE - 1) 
+        & ~(PAGE_SIZE - 1))) {
+		up(&loops[nr]->lock);
+        return -EINVAL;
+	}
+
+    pos = (unsigned long)loops[nr]->buffer;
+
+    while (size > 0) {
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9)
-                page = kvirt_to_pa(pos);
-                if (remap_page_range(vma,start, page, PAGE_SIZE, PAGE_SHARED)) {
+        page = kvirt_to_pa(pos);
+        if (remap_page_range(vma,start, page, PAGE_SIZE, PAGE_SHARED)) {
 #else
 		page = vmalloc_to_pfn((void *)pos);
-		if (remap_pfn_range(vma, start, page, PAGE_SIZE,
-				PAGE_SHARED)) {
+		if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
 #endif
-			up(&loops[nr]->lock);
-                        return -EAGAIN;
+		    up(&loops[nr]->lock);
+            return -EAGAIN;
 		}
-                start += PAGE_SIZE;
-                pos += PAGE_SIZE;
+        start += PAGE_SIZE;
+        pos += PAGE_SIZE;
 		size -= PAGE_SIZE;
-        }
+    }
+
 	up(&loops[nr]->lock);
 
 	return 0;
 }
 
-static int vloopback_ioctl(struct inode *inod, struct file *f, unsigned int cmd, unsigned long arg)
+static int vloopback_ioctl(struct inode *inod, struct file *f, unsigned int cmd, 
+           unsigned long arg)
 {
-	struct video_device *loopdev=video_devdata(f);
-	priv_ptr ptr=(priv_ptr)loopdev->priv;
-	int nr=ptr->pipenr;
+	struct video_device *loopdev = video_devdata(f);
+	priv_ptr ptr = (priv_ptr)loopdev->priv;
+	int nr = ptr->pipenr;
 	int i;
 
+    if (debug > LOG_NODEBUG)
+        info("Video loopback %d cmd %u", nr, cmd);
+
 	if (loops[nr]->zerocopy) {
 		if (!ptr->in) {
-			loops[nr]->ioctlnr=cmd;
-			loops[nr]->ioctllength=_IOC_SIZE(cmd);
+			loops[nr]->ioctlnr = cmd;
+			loops[nr]->ioctllength = _IOC_SIZE(cmd);
 			/* info("DEBUG: vl_ioctl: !loop->in"); */
 			/* info("DEBUG: vl_ioctl: cmd %lu", cmd); */
 			/* info("DEBUG: vl_ioctl: len %lu", loops[nr]->ioctllength); */
-			if(copy_from_user(loops[nr]->ioctldata, (void*)arg, _IOC_SIZE(cmd)))
+			if (copy_from_user(loops[nr]->ioctldata, (void*)arg, _IOC_SIZE(cmd)))
 				return -EFAULT;
-			kill_proc(loops[nr]->pid, SIGIO, 1);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+            kill_proc(loops[nr]->pid, SIGIO, 1);
+#else
+            kill_pid(loops[nr]->pid, SIGIO, 1);
+#endif            
+
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-			wait_event_interruptible(loops[nr]->wait, loops[nr]->ioctlnr==-1);
+			wait_event_interruptible(loops[nr]->wait, loops[nr]->ioctlnr == -1);
 #else
 			interruptible_sleep_on(&loops[nr]->wait);
 #endif			
 			
 			if (loops[nr]->invalid_ioctl) {
-				//info ("DEBUG: There was an invalid ioctl");
-				loops[nr]->invalid_ioctl = 0;
+				info ("There was an invalid ioctl in Video loopback %d", nr);
+                loops[nr]->invalid_ioctl = 0;
 				return -ENOTTY;
 			}
+
 			if (cmd & IOC_IN && !(cmd & IOC_OUT)) {
 				//info("DEBUG: vl_ioctl: cmd & IOC_IN 1"); 
-				if (memcmp(loops[nr]->ioctlretdata, loops[nr]->ioctldata, _IOC_SIZE(cmd))) {
+				if (memcmp(loops[nr]->ioctlretdata, loops[nr]->ioctldata, _IOC_SIZE(cmd))) 
 					return -EINVAL;
-				}
+				
 			 	//info("DEBUG: vl_ioctl: cmd & IOC_IN 2"); 
 				return 0;
 			} else {
@@ -622,309 +710,366 @@
 				return 0;
 			}
 		} else {
-			if ( (loops[nr]->ioctlnr!=cmd) && (cmd != (VIDIOCSINVALID))) {
+			if ((loops[nr]->ioctlnr != cmd) && (cmd != (VIDIOCSINVALID))) {
 				/* wrong ioctl */
-				info("DEBUG: vo_ioctl: Wrong IOCTL");
-				return 0;
+				info("Wrong IOCTL %u in Video loopback %d", cmd, nr);
+                return 0;
 			}
+
 			if (cmd == VIDIOCSINVALID) {
 				loops[nr]->invalid_ioctl = 1;
-			} else {
-				if (copy_from_user(loops[nr]->ioctlretdata, (void*)arg, loops[nr]->ioctllength))
-					return -EFAULT;
+			} else if (copy_from_user(loops[nr]->ioctlretdata, 
+                      (void*)arg, loops[nr]->ioctllength)) {
+				return -EFAULT;
 			}
-			loops[nr]->ioctlnr=-1;
+
+			loops[nr]->ioctlnr = -1;
+
 			if (waitqueue_active(&loops[nr]->wait))
 				wake_up(&loops[nr]->wait);
+
 			return 0;
 		}
 	}
+
 	switch(cmd)
 	{
-		/* Get capabilities */
-		case VIDIOCGCAP:
-		{
-			struct video_capability b;
-			if (ptr->in) {
-				sprintf(b.name, "Video loopback %d input",
-				    ptr->pipenr);
-				b.type = 0;
-			} else {
-				sprintf(b.name, "Video loopback %d output",
-				    ptr->pipenr);
-				b.type = VID_TYPE_CAPTURE;
-			}
-			b.channels=1;
-			b.audios=0;
-			b.maxwidth=loops[nr]->width;
-			b.maxheight=loops[nr]->height;
-			b.minwidth=20;
-			b.minheight=20;
-			if(copy_to_user((void*)arg, &b, sizeof(b)))
-				return -EFAULT;
-			return 0;
+	/* Get capabilities */
+	case VIDIOCGCAP:
+	{
+		struct video_capability b;
+		if (ptr->in) {
+			sprintf(b.name, "Video loopback %d input", nr);
+			b.type = 0;
+		} else {
+			sprintf(b.name, "Video loopback %d output", nr);
+			b.type = VID_TYPE_CAPTURE;
+		}
+
+		b.channels = 1;
+		b.audios = 0;
+		b.maxwidth = loops[nr]->width;
+		b.maxheight = loops[nr]->height;
+		b.minwidth = 20;
+		b.minheight = 20;
+
+		if (copy_to_user((void*)arg, &b, sizeof(b)))
+			return -EFAULT;
+
+		return 0;
+	}
+	/* Get channel info (sources) */
+	case VIDIOCGCHAN:
+	{
+		struct video_channel v;
+		if (copy_from_user(&v, (void*)arg, sizeof(v)))
+			return -EFAULT;
+
+		if (v.channel != 0) {
+			info("VIDIOCGCHAN: Invalid Channel, was %d", v.channel);
+			v.channel = 0;
+				//return -EINVAL;
 		}
-		/* Get channel info (sources) */
-		case VIDIOCGCHAN:
-		{
-			struct video_channel v;
-			if(copy_from_user(&v, (void*)arg, sizeof(v)))
-				return -EFAULT;
-			if(v.channel!=0) {
-				info("VIDIOCGCHAN: Invalid Channel, was %d", v.channel);
-				v.channel=0;
-				//return -EINVAL;
-			}
-			v.flags=0;
-			v.tuners=0;
-			v.norm=0;
-			v.type = VIDEO_TYPE_CAMERA;
-			/*strcpy(v.name, "Loopback"); -- tibit */
-			strcpy(v.name, "Composite1");
-			if(copy_to_user((void*)arg, &v, sizeof(v)))
-				return -EFAULT;
-			return 0;
+
+		v.flags = 0;
+		v.tuners = 0;
+		v.norm = 0;
+		v.type = VIDEO_TYPE_CAMERA;
+		/*strcpy(v.name, "Loopback"); -- tibit */
+		strcpy(v.name, "Composite1");
+
+		if (copy_to_user((void*)arg, &v, sizeof(v)))
+			return -EFAULT;
+
+		return 0;
+	}
+	/* Set channel 	*/
+	case VIDIOCSCHAN:
+	{
+		int v;
+
+		if (copy_from_user(&v, (void*)arg, sizeof(v)))
+			return -EFAULT;
+
+		if (v != 0) {
+			info("VIDIOCSCHAN: Invalid Channel, was %d", v);
+			return -EINVAL;
+		}
+
+		return 0;
+	}
+	/* Get tuner abilities */
+	case VIDIOCGTUNER:
+	{
+		struct video_tuner v;
+
+		if (copy_from_user(&v, (void*)arg, sizeof(v)) != 0)
+			return -EFAULT;
+
+		if (v.tuner) {
+			info("VIDIOCGTUNER: Invalid Tuner, was %d", v.tuner);
+			return -EINVAL;
 		}
-		/* Set channel 	*/
-		case VIDIOCSCHAN:
-		{
-			int v;
-			if(copy_from_user(&v, (void*)arg, sizeof(v)))
-				return -EFAULT;
-			if(v!=0) {
-				info("VIDIOCSCHAN: Invalid Channel, was %d", v);
-				return -EINVAL;
-			}
-			return 0;
-		}
-		/* Get tuner abilities */
-		case VIDIOCGTUNER:
-		{
-			struct video_tuner v;
-			if(copy_from_user(&v, (void*)arg, sizeof(v))!=0)
-				return -EFAULT;
-			if(v.tuner) {
-				info("VIDIOCGTUNER: Invalid Tuner, was %d", v.tuner);
+
+		strcpy(v.name, "Format");
+		v.rangelow = 0;
+		v.rangehigh = 0;
+		v.flags = 0;
+		v.mode = VIDEO_MODE_AUTO;
+
+		if (copy_to_user((void*)arg,&v, sizeof(v)) != 0)
+			return -EFAULT;
+
+		return 0;
+	}
+	/* Get picture properties */
+	case VIDIOCGPICT:
+	{
+		struct video_picture p;
+
+		p.colour = 0x8000;
+		p.hue = 0x8000;
+		p.brightness = 0x8000;
+		p.contrast = 0x8000;
+		p.whiteness = 0x8000;
+		p.depth = 0x8000;
+		p.palette = loops[nr]->palette;
+
+		if (copy_to_user((void*)arg, &p, sizeof(p)))
+			return -EFAULT;
+
+		return 0;
+	}
+	/* Set picture properties */
+	case VIDIOCSPICT:
+	{
+		struct video_picture p;
+
+		if (copy_from_user(&p, (void*)arg, sizeof(p)))
+			return -EFAULT;
+
+		if (!ptr->in) {
+			if (p.palette != loops[nr]->palette)
 				return -EINVAL;
-			}
-			strcpy(v.name, "Format");
-			v.rangelow=0;
-			v.rangehigh=0;
-			v.flags=0;
-			v.mode=VIDEO_MODE_AUTO;
-			if(copy_to_user((void*)arg,&v, sizeof(v))!=0)
-				return -EFAULT;
-			return 0;
-		}
-		/* Get picture properties */
-		case VIDIOCGPICT:
-		{
-			struct video_picture p;
-			p.colour=0x8000;
-			p.hue=0x8000;
-			p.brightness=0x8000;
-			p.contrast=0x8000;
-			p.whiteness=0x8000;
-			p.depth=0x8000;
-			p.palette=loops[nr]->palette;
-			if(copy_to_user((void*)arg, &p, sizeof(p)))
-				return -EFAULT;
+		} else {
+			loops[nr]->palette = p.palette;
+        }
+
+		return 0;
+	}
+	/* Get the video overlay window */
+	case VIDIOCGWIN:
+	{
+		struct video_window vw;
+
+		vw.x = 0;
+		vw.y = 0;
+		vw.width = loops[nr]->width;
+		vw.height = loops[nr]->height;
+		vw.chromakey = 0;
+		vw.flags = 0;
+		vw.clipcount = 0;
+
+		if (copy_to_user((void*)arg, &vw, sizeof(vw)))
+			return -EFAULT;
+
+		return 0;
+	}
+	/* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
+	case VIDIOCSWIN:
+	{
+		struct video_window vw;
+			
+		if (copy_from_user(&vw, (void*)arg, sizeof(vw)))
+			return -EFAULT;
+
+		if (vw.flags)
+			return -EINVAL;
+
+		if (vw.clipcount)
+			return -EINVAL;
+
+		if (loops[nr]->height == vw.height &&
+		    loops[nr]->width == vw.width)
 			return 0;
 
-		}
-		/* Set picture properties */
-		case VIDIOCSPICT:
-		{
-			struct video_picture p;
-			if(copy_from_user(&p, (void*)arg, sizeof(p)))
-				return -EFAULT;
-			if (!ptr->in) {
-				if (p.palette!=loops[nr]->palette)
-					return -EINVAL;
-			} else
-				loops[nr]->palette=p.palette;
-			return 0;
-		}
-		/* Get the video overlay window */
-		case VIDIOCGWIN:
-		{
-			struct video_window vw;
-			vw.x=0;
-			vw.y=0;
-			vw.width=loops[nr]->width;
-			vw.height=loops[nr]->height;
-			vw.chromakey=0;
-			vw.flags=0;
-			vw.clipcount=0;
-			if(copy_to_user((void*)arg, &vw, sizeof(vw)))
-				return -EFAULT;
-			return 0;
-		}
-		/* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
-		case VIDIOCSWIN:
-		{
-			struct video_window vw;
-			
-			if(copy_from_user(&vw, (void*)arg, sizeof(vw)))
-				return -EFAULT;
-			if(vw.flags)
-				return -EINVAL;
-			if(vw.clipcount)
-				return -EINVAL;
-			if (loops[nr]->height==vw.height &&
-			    loops[nr]->width==vw.width)
-				return 0;
-			if(!ptr->in) {
-				return -EINVAL;
-			} else {
-				loops[nr]->height=vw.height;
-				loops[nr]->width=vw.width;
-				/* Make sure nobody is using the buffer while we
-				   fool around with it.
-				   We are also not allowing changes while
-				   somebody using mmap has the output open.
-				 */
-				down(&loops[nr]->lock);
-				if (loops[nr]->ropen) {
-					info("Can't change size while opened for read");
-					up(&loops[nr]->lock);
-					return -EINVAL;
-				}
-				if (loops[nr]->buffer)
-					rvfree(loops[nr]->buffer, loops[nr]->buflength*N_BUFFS);
-				loops[nr]->buflength=vw.width*vw.height*4;
-				loops[nr]->buffer=rvmalloc(loops[nr]->buflength*N_BUFFS);
+		if (!ptr->in) {
+			return -EINVAL;
+		} else {
+			loops[nr]->height = vw.height;
+			loops[nr]->width = vw.width;
+			/* Make sure nobody is using the buffer while we
+			   fool around with it.
+			   We are also not allowing changes while
+			   somebody using mmap has the output open.
+			 */
+			down(&loops[nr]->lock);
+			if (loops[nr]->ropen) {
+				info("Can't change size while opened for read");
 				up(&loops[nr]->lock);
-			}
-			return 0;
-		}
-		/* Memory map buffer info */
-		case VIDIOCGMBUF:
-		{
-			struct video_mbuf vm;
-			
-			vm.size=loops[nr]->buflength*N_BUFFS;
-			vm.frames=N_BUFFS;
-			for (i=0; i<vm.frames; i++)
-				vm.offsets[i]=i*loops[nr]->buflength;
-			if(copy_to_user((void*)arg, &vm, sizeof(vm)))
-				return -EFAULT;
-			return 0;
-		}
-		/* Grab frames */
-		case VIDIOCMCAPTURE:
-		{
-			struct video_mmap vm;
-
-			if (ptr->in)
-				return -EINVAL;
-			if (!loops[nr]->buffer)
 				return -EINVAL;
-			if (copy_from_user(&vm, (void*)arg, sizeof(vm)))
-				return -EFAULT;
-			if (vm.format!=loops[nr]->palette)
-				return -EINVAL;
-			if (vm.frame > N_BUFFS)
-				return -EINVAL;
-			return 0;
-		}
-		/* Sync with mmap grabbing */
-		case VIDIOCSYNC:
-		{
-			int frame;
-			unsigned long fw;
+			}
+
+			if (loops[nr]->buffer)
+				rvfree(loops[nr]->buffer, loops[nr]->buflength * N_BUFFS);
 
-			if (copy_from_user((void *)&frame, (void*)arg, sizeof(int)))
-				return -EFAULT;
-			if (ptr->in)
-				return -EINVAL;
-			if (!loops[nr]->buffer)
-				return -EINVAL;
-			/* Ok, everything should be alright since the program
-			   should have called VIDIOMCAPTURE and we are ready to
-			   do the 'capturing' */
-			if (frame > 1)
-				return -EINVAL;
-			loops[nr]->frame=frame;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-			fw = loops[nr]->frameswrite;
-			wait_event_interruptible(loops[nr]->wait, fw!=loops[nr]->frameswrite);
-#else
-			interruptible_sleep_on(&loops[nr]->wait);
-#endif			
-			if (!loops[nr]->buffer)		/* possibly released during sleep */
-				return -EINVAL;
-			loops[nr]->framesread++;
-			return 0;
+			loops[nr]->buflength = vw.width * vw.height * 4;
+			loops[nr]->buffer = rvmalloc(loops[nr]->buflength * N_BUFFS);
+			up(&loops[nr]->lock);
 		}
-		/* Get attached units */
-		case VIDIOCGUNIT:
-		{
-			struct video_unit vu;
+		return 0;
+	}
+	/* Memory map buffer info */
+	case VIDIOCGMBUF:
+	{
+		struct video_mbuf vm;
 			
-			if (ptr->in)
-				vu.video=loops[nr]->vloopout->minor;
-			else
-				vu.video=loops[nr]->vloopin->minor;
-			vu.vbi=VIDEO_NO_UNIT;
-			vu.radio=VIDEO_NO_UNIT;
-			vu.audio=VIDEO_NO_UNIT;
-			vu.teletext=VIDEO_NO_UNIT;
-			if (copy_to_user((void*)arg, &vu, sizeof(vu)))
-				return -EFAULT;
-			return 0;
-		}
-		/* Get frame buffer */
-		case VIDIOCGFBUF:
-		{
-			struct video_buffer vb;
+		vm.size = loops[nr]->buflength * N_BUFFS;
+		vm.frames = N_BUFFS;
+		for (i = 0; i < vm.frames; i++)
+			vm.offsets[i] = i * loops[nr]->buflength;
+
+		if (copy_to_user((void*)arg, &vm, sizeof(vm)))
+			return -EFAULT;
+
+		return 0;
+	}
+	/* Grab frames */
+	case VIDIOCMCAPTURE:
+	{
+		struct video_mmap vm;
+
+		if (ptr->in)
+			return -EINVAL;
+
+		if (!loops[nr]->buffer)
+			return -EINVAL;
+
+		if (copy_from_user(&vm, (void*)arg, sizeof(vm)))
+			return -EFAULT;
+
+		if (vm.format != loops[nr]->palette)
+			return -EINVAL;
+
+		if (vm.frame > N_BUFFS)
+			return -EINVAL;
 
-			memset(&vb, 0, sizeof(vb));
-			vb.base=NULL;
+		return 0;
+	}
+	/* Sync with mmap grabbing */
+	case VIDIOCSYNC:
+	{
+		int frame;
+		unsigned long fw;
+
+		if (copy_from_user((void *)&frame, (void*)arg, sizeof(int)))
+			return -EFAULT;
+
+		if (ptr->in)
+			return -EINVAL;
 
-			if(copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
-				return -EFAULT;
+		if (!loops[nr]->buffer)
+			return -EINVAL;
+
+		/* Ok, everything should be alright since the program
+		   should have called VIDIOMCAPTURE and we are ready to
+		   do the 'capturing' */
+		if (frame > 1)
+            return -EINVAL;
+
+		loops[nr]->frame = frame;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+		fw = loops[nr]->frameswrite;
+		wait_event_interruptible(loops[nr]->wait, fw != loops[nr]->frameswrite);
+#else
+		interruptible_sleep_on(&loops[nr]->wait);
+#endif			
+		if (!loops[nr]->buffer)		/* possibly released during sleep */
+			return -EINVAL;
 
-			return 0;
-		}
-		/* Start, end capture */
-		case VIDIOCCAPTURE:
-		{
-			int start;
-			if (copy_from_user(&start, (void*)arg, sizeof(int)))
-				return -EFAULT;
-			if (start) info ("Capture started");
-			else info ("Capture stopped");
+		loops[nr]->framesread++;
+
+		return 0;
+	}
+	/* Get attached units */
+	case VIDIOCGUNIT:
+	{
+		struct video_unit vu;
+			
+		if (ptr->in)
+			vu.video = loops[nr]->vloopout->minor;
+		else
+			vu.video = loops[nr]->vloopin->minor;
+
+		vu.vbi = VIDEO_NO_UNIT;
+		vu.radio = VIDEO_NO_UNIT;
+		vu.audio = VIDEO_NO_UNIT;
+		vu.teletext = VIDEO_NO_UNIT;
+
+		if (copy_to_user((void*)arg, &vu, sizeof(vu)))
+			return -EFAULT;
+
+		return 0;
+	}
+	/* Get frame buffer */
+	case VIDIOCGFBUF:
+	{
+		struct video_buffer vb;
+
+		memset(&vb, 0, sizeof(vb));
+		vb.base = NULL;
 
-			return 0;
-		}
+		if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
+			return -EFAULT;
+
+		return 0;
+	}
+	/* Start, end capture */
+	case VIDIOCCAPTURE:
+	{
+		int start;
+
+		if (copy_from_user(&start, (void*)arg, sizeof(int)))
+			return -EFAULT;
 
-		case VIDIOCGFREQ:
-		case VIDIOCSFREQ:
-		case VIDIOCGAUDIO:
-		case VIDIOCSAUDIO:
-			return -EINVAL;
-		case VIDIOCKEY:
-			return 0;
-		default:
-			return -ENOTTY;
-			//return -ENOIOCTLCMD;
+		if (start) { 
+            info ("Video loopback %d Capture started", nr);
+        } else {
+            info ("Video loopback %d Capture stopped", nr);
+        }
+
+		return 0;
+	}
+	case VIDIOCGFREQ:
+	case VIDIOCSFREQ:
+	case VIDIOCGAUDIO:
+	case VIDIOCSAUDIO:
+		return -EINVAL;
+	case VIDIOCKEY:
+		return 0;
+	default:
+		return -ENOTTY;
+		//return -ENOIOCTLCMD;
 	}
 	return 0;
 }
 
 static unsigned int vloopback_poll(struct file *f, struct poll_table_struct *wait)
 {
-	struct video_device *loopdev=video_devdata(f);
-	priv_ptr ptr=(priv_ptr)loopdev->priv;
-	int nr=ptr->pipenr;
+	struct video_device *loopdev = video_devdata(f);
+	priv_ptr ptr = (priv_ptr)loopdev->priv;
+	int nr = ptr->pipenr;
 
-	if (loopdev==NULL)
+    if (debug > LOG_NODEBUG)
+        info("Video loopback %d", nr);
+
+	if (loopdev == NULL)
 		return -EFAULT;
+
 	if (!ptr->in)
 		return 0;
 
-	if (loops[nr]->ioctlnr!=-1) {
+	if (loops[nr]->ioctlnr != -1) {
 		if (loops[nr]->zerocopy) {
 			return (POLLIN | POLLPRI | POLLOUT | POLLRDNORM);
 		} else {
@@ -934,7 +1079,7 @@
 	return 0;
 }
 
-static struct file_operations fileops_template=
+static struct file_operations fileops_template =
 {
 	owner:		THIS_MODULE,
 	open:		vloopback_open,
@@ -946,11 +1091,14 @@
 	mmap:		vloopback_mmap,
 };
 
-static struct video_device vloopback_template=
+static struct video_device vloopback_template =
 {
-	owner:		THIS_MODULE,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)    
+    owner:      THIS_MODULE,
+    type:       VID_TYPE_CAPTURE,
+#endif
+    minor:      -1,    
 	name:		"Video Loopback",
-	type:		VID_TYPE_CAPTURE,
 	fops:		&fileops_template,
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
 	release:	video_device_release,
@@ -960,39 +1108,46 @@
 static int create_pipe(int nr)
 {
 	int minor_in, minor_out , ret;
-		
-	if (dev_offset == -1)
+
+    if (debug > LOG_NODEBUG)
+        info("Video loopback %d", nr);
+
+	if (dev_offset == -1) {
 		minor_in  = minor_out = -1; /* autoassign */
-	else {
-		minor_in  = 2*nr   + dev_offset;
-		minor_out = 2*nr+1 + dev_offset;
+    } else {
+		minor_in  = 2 * nr + dev_offset;
+		minor_out = 2 * nr + 1 + dev_offset;
 	}
 
 	/* allocate space for this pipe */
 	loops[nr]= kmalloc(sizeof(struct vloopback_pipe), GFP_KERNEL);
+
 	if (!loops[nr])
 		return -ENOMEM;
 	/* set up a new video device plus our private area */
-	loops[nr]->vloopin= video_device_alloc();
+	loops[nr]->vloopin = video_device_alloc();
+
 	if (loops[nr]->vloopin == NULL)
 		return -ENOMEM;
 	*loops[nr]->vloopin = vloopback_template;
-	loops[nr]->vloopin->priv= kmalloc(sizeof(struct vloopback_private),
-			GFP_KERNEL);
+	loops[nr]->vloopin->priv = kmalloc(sizeof(struct vloopback_private),
+			                           GFP_KERNEL);
 	if (loops[nr]->vloopin->priv == NULL) {
 		kfree(loops[nr]->vloopin);
 		return -ENOMEM;
 	}
 	/* repeat for the output device */
-	loops[nr]->vloopout= video_device_alloc();
+	loops[nr]->vloopout = video_device_alloc();
+
 	if (loops[nr]->vloopout == NULL) {
 		kfree(loops[nr]->vloopin->priv);
 		kfree(loops[nr]->vloopin);
 		return -ENOMEM;
 	}
 	*loops[nr]->vloopout = vloopback_template;
-	loops[nr]->vloopout->priv= kmalloc(sizeof(struct vloopback_private),
-			GFP_KERNEL);
+	loops[nr]->vloopout->priv = kmalloc(sizeof(struct vloopback_private),
+			                            GFP_KERNEL);
+
 	if (loops[nr]->vloopout->priv == NULL) {
 		kfree(loops[nr]->vloopin->priv);
 		kfree(loops[nr]->vloopin);
@@ -1000,43 +1155,49 @@
 		return -ENOMEM;
 	}
 
-	((priv_ptr)loops[nr]->vloopin->priv)->pipenr=nr;
-	((priv_ptr)loops[nr]->vloopout->priv)->pipenr=nr;
+	((priv_ptr)loops[nr]->vloopin->priv)->pipenr = nr;
+	((priv_ptr)loops[nr]->vloopout->priv)->pipenr = nr;
 	loops[nr]->invalid_ioctl = 0; /* tibit */
-	loops[nr]->buffer=NULL;
-	loops[nr]->width=0;
-	loops[nr]->height=0;
-	loops[nr]->palette=0;
-	loops[nr]->frameswrite=0;
-	loops[nr]->framesread=0;
-	loops[nr]->framesdumped=0;
-	loops[nr]->wopen=0;
-	loops[nr]->ropen=0;
-	loops[nr]->frame=0;
+	loops[nr]->buffer = NULL;
+	loops[nr]->width = 0;
+	loops[nr]->height = 0;
+	loops[nr]->palette = 0;
+	loops[nr]->frameswrite = 0;
+	loops[nr]->framesread = 0;
+	loops[nr]->framesdumped = 0;
+	loops[nr]->wopen = 0;
+	loops[nr]->ropen = 0;
+	loops[nr]->frame = 0;
 	
-	((priv_ptr)loops[nr]->vloopin->priv)->in=1;
-	((priv_ptr)loops[nr]->vloopout->priv)->in=0;
-	loops[nr]->vloopin->type=0;
-	sprintf(loops[nr]->vloopin->name, "Video loopback %d input", nr);
-	loops[nr]->vloopout->type=VID_TYPE_CAPTURE;
-	sprintf(loops[nr]->vloopout->name, "Video loopback %d output", nr);
+	((priv_ptr)loops[nr]->vloopin->priv)->in = 1;
+	((priv_ptr)loops[nr]->vloopout->priv)->in = 0;
+    sprintf(loops[nr]->vloopin->name, "Video loopback %d input", nr);
+    sprintf(loops[nr]->vloopout->name, "Video loopback %d output", nr);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+	loops[nr]->vloopin->type = 0;
+	loops[nr]->vloopout->type = VID_TYPE_CAPTURE;
+#endif
+    loops[nr]->vloopout->minor = minor_out;
+    loops[nr]->vloopin->minor = minor_in;
+
 	init_waitqueue_head(&loops[nr]->wait);
 	init_MUTEX(&loops[nr]->lock);
 	
-	ret = video_register_device(loops[nr]->vloopin, VFL_TYPE_GRABBER,minor_in);
+	ret = video_register_device(loops[nr]->vloopin, VFL_TYPE_GRABBER, minor_in);
 	
 	if ((ret == -1 ) || ( ret == -23 )) {
-		info("error registering device %s",loops[nr]->vloopin->name);
+		info("error registering device %s", loops[nr]->vloopin->name);
 		kfree(loops[nr]->vloopin->priv);
 		kfree(loops[nr]->vloopin);
 		kfree(loops[nr]->vloopout->priv);
 		kfree(loops[nr]->vloopout);
 		kfree(loops[nr]);
-		loops[nr]=NULL;
+		loops[nr] = NULL;
 		return ret;
 	}
 	
-	ret = video_register_device(loops[nr]->vloopout, VFL_TYPE_GRABBER,minor_out);
+	ret = video_register_device(loops[nr]->vloopout, VFL_TYPE_GRABBER, minor_out);
 	
 	if ((ret ==-1) || (ret == -23)) {
 		info("error registering device %s", loops[nr]->vloopout->name);
@@ -1045,12 +1206,12 @@
 		kfree(loops[nr]->vloopout->priv);
 		kfree(loops[nr]->vloopout);
 		kfree(loops[nr]);
-		loops[nr]=NULL;
+		loops[nr] = NULL;
 		return ret;
 	}
 	
-	loops[nr]->ioctldata=kmalloc(1024, GFP_KERNEL);
-	loops[nr]->ioctlretdata=kmalloc(1024, GFP_KERNEL);
+	loops[nr]->ioctldata = kmalloc(1024, GFP_KERNEL);
+	loops[nr]->ioctlretdata = kmalloc(1024, GFP_KERNEL);
 	return 0;
 }
 
@@ -1086,6 +1247,16 @@
 #endif
 
 MODULE_PARM_DESC(dev_offset, "Prefered offset for video device numbers");
+
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
+module_param(debug, int, 000);
+#else
+MODULE_PARM(debug_param, "i");
+#endif
+
+MODULE_PARM_DESC(debug, "Enable module debug level 0-3 (by default 0)");
+
 MODULE_LICENSE("GPL");
 MODULE_VERSION( VLOOPBACK_VERSION );
 
@@ -1093,25 +1264,27 @@
 {
 	int i,ret;
 
-	info("Video4linux loopback driver v"VLOOPBACK_VERSION);
+	info("video4linux loopback driver v"VLOOPBACK_VERSION);
 
-	if (pipes==-1) pipes=1;
+	if (pipes == -1) 
+        pipes = 1;
+
 	if (pipes > MAX_PIPES) {
-		pipes=MAX_PIPES;
+		pipes = MAX_PIPES;
 		info("Nr of pipes is limited to: %d", MAX_PIPES);
 	}
 
-	for (i=0; i<pipes; i++) {
+	for (i = 0; i < pipes; i++) {
 		
 		ret = create_pipe(i);
 
 		if (ret == 0) {
 			info("Loopback %d registered, input: video%d,"
-			     "output: video%d",
+			     " output: video%d",
 			     i, loops[i]->vloopin->minor,
 			     loops[i]->vloopout->minor);
-			nr_o_pipes=i+1;
-		}else{
+			nr_o_pipes = i + 1;
+		} else {
 			return ret;
 		}
 	}
@@ -1123,16 +1296,22 @@
 	int i;
 
 	info("Unregistering video4linux loopback devices");
-	for (i=0; i<nr_o_pipes; i++) if (loops[i]) {
-		kfree(loops[i]->vloopin->priv);
-		video_unregister_device(loops[i]->vloopin);
-		kfree(loops[i]->vloopout->priv);
-		video_unregister_device(loops[i]->vloopout);
-		if (loops[i]->buffer) rvfree(loops[i]->buffer, loops[i]->buflength*N_BUFFS);
-		kfree(loops[i]->ioctldata);
-		kfree(loops[i]->ioctlretdata);
-		kfree(loops[i]);
-	}
+
+    for (i = 0; i < nr_o_pipes; i++) {
+        if (loops[i]) {
+		    kfree(loops[i]->vloopin->priv);
+		    video_unregister_device(loops[i]->vloopin);
+		    kfree(loops[i]->vloopout->priv);
+		    video_unregister_device(loops[i]->vloopout);
+		    
+            if (loops[i]->buffer) 
+                rvfree(loops[i]->buffer, loops[i]->buflength * N_BUFFS);
+
+		    kfree(loops[i]->ioctldata);
+		    kfree(loops[i]->ioctlretdata);
+		    kfree(loops[i]);
+	    }
+    }        
 }
 
 module_init(vloopback_init);