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

📄 sqcam.c

📁 一种linux下的看摄像头的画面的软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * USB SQcam WebCam driver based on the ViCam driver written by Joe Burks,  * Christopher L Cheney, Pavel Machek, John Tyner, Monroe Williams. * * Thanks to Theodore Kilgore for his help. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * This source code is based heavily on the CPiA webcam driver which was * written by Peter Pregler, Scott J. Bertin and Johannes Erdfelt * * Portions of this code were also copied from usbvideo.c * * The bayer decoding functions are copied from libgphoto2 * */#include <linux/kernel.h>#include <linux/wrapper.h>#include <linux/module.h>#include <linux/init.h>#include <linux/videodev.h>#include <linux/usb.h>#include <linux/vmalloc.h>#include <linux/slab.h>#include "usbvideo.h"//#define SQCAM_DEBUG#ifndef MODULE_LICENSE#define MODULE_LICENSE(a)#endif#ifndef bool#define bool int#endif#ifdef SQCAM_DEBUG#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, __FUNCTION__, lineno, ##args)#define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt,##args)#else#define DBG(fmn,args...) do {} while(0)#endif/* Version Information */#define DRIVER_VERSION "v1.0"#define DRIVER_AUTHOR "Marcell Lengyel, miketkf@mailbox.hu"#define DRIVER_DESC "SQcam WebCam Driver"/* Define these values to match your device */#define USB_SQCAM_VENDOR_ID	0x2770#define USB_SQCAM_PRODUCT_ID	0x9120#define SQCAM_BYTES_PER_PIXEL 3#define SQCAM_MAX_READ_SIZE 0x8000#define SQCAM_MAX_RAW_SIZE 320*240+64#define SQCAM_MAX_FRAME_SIZE (SQCAM_BYTES_PER_PIXEL*320*240)#define SQCAM_FRAMES 2struct sqcam_camera {	u8 *raw_image;		// raw data captured from the camera	u8 *framebuf;		// processed data in RGB24 format	struct video_device vdev;	// v4l video device	struct usb_device *udev;	// usb device	struct semaphore busy_lock;	// guard against SMP multithreading	bool is_initialized;	bool is_removed;	bool is_opened;	u8 bulkEndpoint;	u32 framebuf_size;	// # of valid bytes in framebuf	u32 framebuf_read_start;	// position in frame buf that a read is happening at.};static void *sqcam_probe(struct usb_device *dev, unsigned int ifnum,			       const struct usb_device_id *id);static void sqcam_disconnect(struct usb_device *dev, void *ptr);static void read_frame(struct sqcam_camera *cam, int framenum);static void sqcam_purge(struct sqcam_camera *cam);static int gp_bayer_decode (unsigned char *input, int w, int h,			     unsigned char *output, int tile);static intsend_control_msg(int set, struct usb_device *udev, u8 request, u16 value,		 u16 index, unsigned char *cp, u16 size){	int status;	// for reasons not yet known to me, you can't send USB control messages	// with data in the module (if you are compiled as a module).  Whatever	// the reason, copying it to memory allocated as kernel memory then	// doing the usb control message fixes the problem.	unsigned char *transfer_buffer = kmalloc(size, GFP_KERNEL);	memcpy(transfer_buffer, cp, size);	status = usb_control_msg(udev,				 set ? usb_sndctrlpipe(udev, 0) : usb_rcvctrlpipe(udev, 0),				 request,				 (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR |				 USB_RECIP_DEVICE, value, index,				 transfer_buffer, size, HZ);	kfree(transfer_buffer);	DBG("ctrl msg:: value: %0x, index: %0x\n", value, index);	if (status < 0) {		printk(KERN_INFO "Failed sending control message, error %d.\n",		       status);	}	return status;}static intinitialize_camera(struct sqcam_camera *cam){	struct usb_device *udev = cam->udev;	int status;	unsigned char ch[5];	if ((status =	     send_control_msg(1, udev, 0x0c, 0x06, 0xf0, NULL, 0)) < 0)		return status;	if ((status =	     send_control_msg(0, udev, 0x0c, 0x07, 0, &ch[0], 1)) < 0)		return status;	if ((status =	     send_control_msg(0, udev, 0x0c, 0x07, 0, &ch[0], 4)) < 0)		return status;	ch[0] = 0x50;	if ((status =	     send_control_msg(1, udev, 0x0c, 0x06, 0xa0, &ch[0], 1)) < 0)		return status;	if ((status =	     send_control_msg(0, udev, 0x0c, 0x07, 0, &ch[0], 1)) < 0)		return status;	return 0;}static intreset_camera(struct sqcam_camera *cam){	struct usb_device *udev = cam->udev;	int status;	unsigned char ch;	ch = 0xff;	if ((status =	     send_control_msg(1, udev, 0x0c, 0xc0, 0x00, &ch, 1)) < 0)		return status;	if ((status =	     send_control_msg(1, udev, 0x0c, 0x06, 0xa0, NULL, 0)) < 0)		return status;	if ((status =	     send_control_msg(0, udev, 0x0c, 0x07, 0, &ch, 1)) < 0)		return status;	return 0;}static intsqcam_ioctl(struct video_device *dev, unsigned int ioctlnr, void *arg){	struct sqcam_camera *cam = dev->priv;	int retval = 0;	if (!cam)		return -ENODEV;	/* make this _really_ smp-safe */	if (down_interruptible(&cam->busy_lock))		return -EINTR;	switch (ioctlnr) {		/* query capabilites */	case VIDIOCGCAP:		{			struct video_capability b;			DBG("VIDIOCGCAP\n");			strcpy(b.name, "SQcam-based Camera");			b.type = VID_TYPE_CAPTURE;			b.channels = 1;			b.audios = 0;			b.maxwidth = 320;	/* VIDEOSIZE_CIF */			b.maxheight = 240;			b.minwidth = 320;	/* VIDEOSIZE_160_120 */			b.minheight = 240;			if (copy_to_user(arg, &b, sizeof (b)))				retval = -EFAULT;			break;		}		/* get/set video source - we are a camera and nothing else */	case VIDIOCGCHAN:		{			struct video_channel v;			DBG("VIDIOCGCHAN\n");			if (copy_from_user(&v, arg, sizeof (v))) {				retval = -EFAULT;				break;			}			if (v.channel != 0) {				retval = -EINVAL;				break;			}			v.channel = 0;			strcpy(v.name, "Camera");			v.tuners = 0;			v.flags = 0;			v.type = VIDEO_TYPE_CAMERA;			v.norm = 0;			if (copy_to_user(arg, &v, sizeof (v)))				retval = -EFAULT;			break;		}	case VIDIOCSCHAN:		{			int v;			if (copy_from_user(&v, arg, sizeof (v)))				retval = -EFAULT;			DBG("VIDIOCSCHAN %d\n", v);			if (retval == 0 && v != 0)				retval = -EINVAL;			break;		}		/* image properties */	case VIDIOCGPICT:		{			struct video_picture vp;			DBG("VIDIOCGPICT\n");			memset(&vp, 0, sizeof (struct video_picture));			vp.depth = 24;			vp.palette = VIDEO_PALETTE_RGB24;			if (copy_to_user			    (arg, &vp, sizeof (struct video_picture)))				retval = -EFAULT;			break;		}	case VIDIOCSPICT:		{			struct video_picture vp;						if(copy_from_user(&vp, (struct video_picture *) arg,				sizeof(struct video_picture)))				retval = -EFAULT;			else			{				DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth,				    vp.palette);				if (vp.depth != 24				    || vp.palette != VIDEO_PALETTE_RGB24)					retval = -EINVAL;			}			break;		}		/* get/set capture window */	case VIDIOCGWIN:		{			struct video_window vw;			vw.x = 0;			vw.y = 0;			vw.width = 320;			vw.height = 240;			vw.chromakey = 0;			vw.flags = 0;			vw.clips = NULL;			vw.clipcount = 0;			DBG("VIDIOCGWIN\n");			if (copy_to_user			    ((void *) arg, (void *) &vw, sizeof (vw)))				retval = -EFAULT;			// I'm not sure what the deal with a capture window is, it is very poorly described			// in the doc.  So I won't support it now.			break;		}	case VIDIOCSWIN:		{			struct video_window *vw = (struct video_window *) arg;			DBG("VIDIOCSWIN %d x %d\n", vw->width, vw->height);			if ( vw->width != 320 || vw->height != 240 )				retval = -EFAULT;						break;		}		/* mmap interface */	case VIDIOCGMBUF:		{			struct video_mbuf vm;			int i;			DBG("VIDIOCGMBUF\n");			memset(&vm, 0, sizeof (vm));			vm.size =			    SQCAM_MAX_FRAME_SIZE * SQCAM_FRAMES;			vm.frames = SQCAM_FRAMES;			for (i = 0; i < SQCAM_FRAMES; i++)				vm.offsets[i] = SQCAM_MAX_FRAME_SIZE * i;			if (copy_to_user			    ((void *) arg, (void *) &vm, sizeof (vm)))				retval = -EFAULT;			break;		}	case VIDIOCMCAPTURE:		{			struct video_mmap vm;			// int video_size;			if (copy_from_user			    ((void *) &vm, (void *) arg, sizeof (vm))) {				retval = -EFAULT;				break;			}			DBG("VIDIOCMCAPTURE frame=%d, height=%d, width=%d, format=%d.\n",vm.frame,vm.width,vm.height,vm.format);			if ( vm.frame >= SQCAM_FRAMES || vm.format != VIDEO_PALETTE_RGB24 )				retval = -EINVAL;			// in theory right here we'd start the image capturing			// (fill in a bulk urb and submit it asynchronously)			//			// Instead we're going to do a total hack job for now and			// retrieve the frame in VIDIOCSYNC			break;		}	case VIDIOCSYNC:		{			int frame;			if (copy_from_user((void *) &frame, arg, sizeof (int))) {				retval = -EFAULT;				break;			}			DBG("VIDIOCSYNC: %d\n", frame);			read_frame(cam, frame);			break;		}		/* pointless to implement overlay with this camera */	case VIDIOCCAPTURE:	case VIDIOCGFBUF:	case VIDIOCSFBUF:	case VIDIOCKEY:		retval = -EINVAL;		break;		/* tuner interface - we have none */	case VIDIOCGTUNER:	case VIDIOCSTUNER:	case VIDIOCGFREQ:	case VIDIOCSFREQ:		retval = -EINVAL;		break;		/* audio interface - we have none */	case VIDIOCGAUDIO:	case VIDIOCSAUDIO:		retval = -EINVAL;		break;	default:		retval = -ENOIOCTLCMD;		break;	}	up(&cam->busy_lock);	return retval;}static intsqcam_open(struct video_device *dev, int flags){	struct sqcam_camera *cam =	    (struct sqcam_camera *) dev->priv;	int intr;	unsigned char siz;	int n;

⌨️ 快捷键说明

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