diff example/dummy.c @ 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 5f21a4dddc0c
children 5971a90f2459
line wrap: on
line diff
--- 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);
 }