⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sqcam.c

📁 一种linux下的看摄像头的画面的软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	DBG("open\n");	if (!cam) {		printk(KERN_ERR		       "sqcam video_device improperly initialized");	}	intr = down_interruptible(&cam->busy_lock);	if (intr)		return -EINTR;	if (cam->is_opened) {		printk(KERN_INFO		       "sqcam_open called on already opened camera");		up(&cam->busy_lock);		return -EBUSY;	}	if (!cam->raw_image) {		cam->raw_image = kmalloc(SQCAM_MAX_RAW_SIZE, GFP_KERNEL);		if (!cam->raw_image) {			up(&cam->busy_lock);			return -ENOMEM;		}	}	if (!cam->framebuf) {		cam->framebuf =		    usbvideo_rvmalloc(SQCAM_MAX_FRAME_SIZE * SQCAM_FRAMES);		if (!cam->framebuf) {			kfree(cam->raw_image);			up(&cam->busy_lock);			return -ENOMEM;		}	}	if (!cam->is_initialized) {		initialize_camera(cam);		cam->is_initialized = 1;	}	n = send_control_msg(1, cam->udev, 0x0c, 0xc0, 0, NULL, 0);	siz = 0x61; // 0x60 -> 160x120, 0x61 -> 320x240	if (n >= 0) n = send_control_msg(1, cam->udev, 0x0c, 0x06, siz, NULL, 0);	if (n >= 0) n = send_control_msg(0, cam->udev, 0x0c, 0x07, 0, NULL, 0);	cam->is_opened = 1;	up(&cam->busy_lock);	return 0;}static voidsqcam_close(struct video_device *dev){	struct sqcam_camera *cam = (struct sqcam_camera *) dev->priv;	DBG("close\n");	if (cam->is_removed) {		sqcam_purge(cam);	} else {		reset_camera(cam);		cam->is_opened = 0;	}}#define DATA_HEADER_SIZE 64void sqcam_decode_bayer(char *data, char *rgb){	int j;	unsigned char b;	unsigned char *src;	unsigned char *dst;	src = data + DATA_HEADER_SIZE;	dst = rgb;        /* Reverse the data, else the pic is upside down. */        for (j = 0; j < 320*240 / 2; j++) {	      b = src[j];	      src[j] = src[320*240 - 1 - j];	      src[320*240 - 1 - j] = b;        } 	gp_bayer_decode(src, 320, 240, dst, 3);}static voidread_frame(struct sqcam_camera *cam, int framenum){	unsigned char siz;	int n, read;	int actual_length;	read = 320 * 240 + 64;	// read 'read' bytes in SQCAM_MAX_READ_SIZE chunks	do {		siz = 0x50;		n = send_control_msg(1, cam->udev, 0x0c, 0x03, 				(read > SQCAM_MAX_READ_SIZE) ? SQCAM_MAX_READ_SIZE : read, 				&siz, 1);		if (n < 0) {			printk(KERN_ERR		       		" Problem sending frame capture control message");			return;		}		n = usb_bulk_msg(cam->udev,			 usb_rcvbulkpipe(cam->udev, cam->bulkEndpoint),			 cam->raw_image + (320*240+64 - read),			 (read > SQCAM_MAX_READ_SIZE) ? SQCAM_MAX_READ_SIZE : read,			 &actual_length, 500);		read -= actual_length;		DBG("blk msg:: size: %d\n", actual_length);		if (n < 0) {			printk(KERN_ERR "Problem during bulk read of frame data: %d\n", n);			read = 0;		}	} while (read);			sqcam_decode_bayer(cam->raw_image,			 cam->framebuf +			 framenum * SQCAM_MAX_FRAME_SIZE );	cam->framebuf_size =	    320 * 240 * SQCAM_BYTES_PER_PIXEL;	cam->framebuf_read_start = 0;	return;}static longsqcam_read(struct video_device *dev, char *buf,		 unsigned long count, int noblock){	struct sqcam_camera *cam = dev->priv;	int intr;	DBG("read %d bytes.\n", (int) count);	if (!buf)		return -EINVAL;	if (!count)		return -EINVAL;	// This is some code that will hopefully allow us to do shell copies	// from the /dev/videoX to a file and have it actually work.	if (cam->framebuf_size != 0) {		if (cam->framebuf_read_start == cam->framebuf_size) {			cam->framebuf_size = cam->framebuf_read_start = 0;			return 0;		} else {			if (cam->framebuf_read_start + count <=			    cam->framebuf_size) {				// count does not exceed available bytes				copy_to_user(buf,					     (cam->framebuf) +					     cam->framebuf_read_start, count);				cam->framebuf_read_start += count;				return count;			} else {				count =				    cam->framebuf_size -				    cam->framebuf_read_start;				copy_to_user(buf,					     (cam->framebuf) +					     cam->framebuf_read_start, count);				cam->framebuf_read_start = cam->framebuf_size;				return count;			}		}	}	intr = down_interruptible(&cam->busy_lock);	if (intr)		return -EINTR;	read_frame(cam, 0);	if (count > cam->framebuf_size)		count = cam->framebuf_size;	copy_to_user(buf, cam->framebuf, count);	if (count != cam->framebuf_size)		cam->framebuf_read_start = count;	else		cam->framebuf_size = 0;	up(&cam->busy_lock);	return count;}static intsqcam_mmap(struct video_device *dev, const char *adr, unsigned long size){	// TODO: allocate the raw frame buffer if necessary	unsigned long start = (unsigned long) adr;	unsigned long page, pos;	struct sqcam_camera *cam = dev->priv;	if (!cam)		return -ENODEV;	DBG("sqcam_mmap: %ld\n", size);	/* We let mmap allocate as much as it wants because Linux was adding 2048 bytes	 * to the size the application requested for mmap and it was screwing apps up.	 if (size > SQCAM_FRAMES*SQCAM_MAX_FRAME_SIZE)	 return -EINVAL;	 */	/* make this _really_ smp-safe */	if (down_interruptible(&cam->busy_lock))		return -EINTR;	if (!cam->framebuf) {	/* we do lazy allocation */		cam->framebuf =		    usbvideo_rvmalloc(SQCAM_MAX_FRAME_SIZE * SQCAM_FRAMES);		if (!cam->framebuf) {			up(&cam->busy_lock);			return -ENOMEM;		}	}	pos = (unsigned long) (cam->framebuf);	while (size > 0) {		page = usbvideo_kvirt_to_pa(pos);		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {			up(&cam->busy_lock);			return -EAGAIN;		}		start += PAGE_SIZE;		pos += PAGE_SIZE;		if (size > PAGE_SIZE)			size -= PAGE_SIZE;		else			size = 0;	}	up(&cam->busy_lock);	return 0;}intsqcam_video_init(struct video_device *vdev){	return 0;}static longsqcam_write(struct video_device *v, const char *buf, unsigned long count,		  int nonblock){	return -EINVAL;}static struct video_device sqcam_template = {	owner:THIS_MODULE,	name:"SQcam-based USB Camera",	type:VID_TYPE_CAPTURE,	hardware:VID_HARDWARE_SE401, /* need an own value */	open:sqcam_open,	close:sqcam_close,	read:sqcam_read,	write:sqcam_write,	ioctl:sqcam_ioctl,	mmap:sqcam_mmap,	initialize:sqcam_video_init,	minor:-1,};/* table of devices that work with this driver */static struct usb_device_id sqcam_table[] = {	{USB_DEVICE(USB_SQCAM_VENDOR_ID, USB_SQCAM_PRODUCT_ID)},	{}			/* Terminating entry */};MODULE_DEVICE_TABLE(usb, sqcam_table);static struct usb_driver sqcam_driver = {	name:"sqcam",	probe:sqcam_probe,	disconnect:sqcam_disconnect,	id_table:sqcam_table};/** *	sqcam_probe * *	Called by the usb core when a new device is connected that it thinks *	this driver might be interested in. */static void *sqcam_probe(struct usb_device *dev, unsigned int ifnum,		  const struct usb_device_id *id){	int nas, bulkEndpoint = 0;	const struct usb_interface_descriptor *interface;	const struct usb_endpoint_descriptor *endpoint;	struct sqcam_camera *cam;	/* See if the device offered us matches what we can accept */	if ((dev->descriptor.idVendor != USB_SQCAM_VENDOR_ID) ||	    (dev->descriptor.idProduct != USB_SQCAM_PRODUCT_ID)) {		return NULL;	}	printk(KERN_INFO "SQcam based webcam connected\n");	nas = dev->actconfig->interface[ifnum].num_altsetting;	if (nas != 1) {		printk(KERN_WARNING		       "Expected only one alternate setting for this camera!\n");		return NULL;	}	interface = &dev->actconfig->interface[ifnum].altsetting[0];	DBG(KERN_DEBUG "Interface %d. has %u. endpoints!\n",	       ifnum, (unsigned) (interface->bNumEndpoints));	endpoint = &interface->endpoint[0];	if ((endpoint->bEndpointAddress & 0x80) &&	    ((endpoint->bmAttributes & 3) == 0x02)) {		/* we found a bulk in endpoint */		bulkEndpoint = endpoint->bEndpointAddress;	} else {		printk(KERN_ERR		       "No bulk in endpoint was found ?! (this is bad)\n");	}	if ((cam =	     kmalloc(sizeof (struct sqcam_camera), GFP_KERNEL)) == NULL) {		printk(KERN_WARNING		       "could not allocate kernel memory for sqcam_camera struct\n");		return NULL;	}	memset(cam, 0, sizeof (struct sqcam_camera));	init_MUTEX(&cam->busy_lock);	memcpy(&cam->vdev, &sqcam_template,	       sizeof (sqcam_template));	cam->vdev.priv = cam;	// sort of a reverse mapping for those functions that get vdev only	cam->udev = dev;	cam->bulkEndpoint = bulkEndpoint;	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) == -1) {		kfree(cam);		printk(KERN_WARNING "video_register_device failed\n");		return NULL;	}	printk(KERN_INFO "SQcam webcam driver now controlling video device %d\n",cam->vdev.minor);	return cam;}static voidsqcam_purge(struct sqcam_camera *cam){	video_unregister_device(&cam->vdev);	if (cam->raw_image)		kfree(cam->raw_image);	if (cam->framebuf)		usbvideo_rvfree(cam->framebuf,		       SQCAM_MAX_FRAME_SIZE * SQCAM_FRAMES);	kfree(cam);	printk(KERN_DEBUG "SQcam-based WebCam disconnected\n");}static voidsqcam_disconnect(struct usb_device *dev, void *ptr){	struct sqcam_camera *cam = ptr;	if (cam->is_opened) {		cam->is_removed = 1;	} else {		sqcam_purge(cam);	}}/* */static int __initusb_sqcam_init(void){	DBG(KERN_INFO "SQcam-based WebCam driver startup\n");	if (usb_register(&sqcam_driver) != 0)		printk(KERN_WARNING "usb_register failed!\n");	return 0;}static void __exitusb_sqcam_exit(void){	DBG(KERN_INFO	       "SQcam-based WebCam driver shutdown\n");	usb_deregister(&sqcam_driver);}module_init(usb_sqcam_init);module_exit(usb_sqcam_exit);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");/* bayer.c * * Copyright 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -