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

📄 vicam.c

📁 h内核
💻 C
📖 第 1 页 / 共 3 页
字号:
}static intinitialize_camera(struct vicam_camera *cam){	const struct {		u8 *data;		u32 size;	} firmware[] = {		{ .data = setup1, .size = sizeof(setup1) },		{ .data = setup2, .size = sizeof(setup2) },		{ .data = setup3, .size = sizeof(setup3) },		{ .data = setup4, .size = sizeof(setup4) },		{ .data = setup5, .size = sizeof(setup5) },		{ .data = setup3, .size = sizeof(setup3) },		{ .data = NULL, .size = 0 }	};	int err, i;	for (i = 0, err = 0; firmware[i].data && !err; i++) {		memcpy(cam->cntrlbuf, firmware[i].data, firmware[i].size);		err = send_control_msg(cam, 0xff, 0, 0,				       cam->cntrlbuf, firmware[i].size);	}	return err;}static intset_camera_power(struct vicam_camera *cam, int state){	int status;	if ((status = send_control_msg(cam, 0x50, state, 0, NULL, 0)) < 0)		return status;	if (state) {		send_control_msg(cam, 0x55, 1, 0, NULL, 0);	}	return 0;}static intvicam_ioctl(struct inode *inode, struct file *file, unsigned int ioctlnr, unsigned long arg){	void __user *user_arg = (void __user *)arg;	struct vicam_camera *cam = file->private_data;	int retval = 0;	if (!cam)		return -ENODEV;	switch (ioctlnr) {		/* query capabilities */	case VIDIOCGCAP:		{			struct video_capability b;			DBG("VIDIOCGCAP\n");			memset(&b, 0, sizeof(b));			strcpy(b.name, "ViCam-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_48_48 */			b.minheight = 240;			if (copy_to_user(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, user_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(user_arg, &v, sizeof(v)))				retval = -EFAULT;			break;		}	case VIDIOCSCHAN:		{			int v;			if (copy_from_user(&v, user_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.brightness = cam->gain << 8;			vp.depth = 24;			vp.palette = VIDEO_PALETTE_RGB24;			if (copy_to_user(user_arg, &vp, sizeof (struct video_picture)))				retval = -EFAULT;			break;		}	case VIDIOCSPICT:		{			struct video_picture vp;						if (copy_from_user(&vp, user_arg, sizeof(vp))) {				retval = -EFAULT;				break;			}						DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth,			    vp.palette);			cam->gain = vp.brightness >> 8;			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(user_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;			if (copy_from_user(&vw, user_arg, sizeof(vw))) {				retval = -EFAULT;				break;			}			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 =			    VICAM_MAX_FRAME_SIZE * VICAM_FRAMES;			vm.frames = VICAM_FRAMES;			for (i = 0; i < VICAM_FRAMES; i++)				vm.offsets[i] = VICAM_MAX_FRAME_SIZE * i;			if (copy_to_user(user_arg, (void *)&vm, sizeof(vm)))				retval = -EFAULT;			break;		}	case VIDIOCMCAPTURE:		{			struct video_mmap vm;			// int video_size;			if (copy_from_user((void *)&vm, user_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 >= VICAM_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, user_arg, sizeof(int))) {				retval = -EFAULT;				break;			}			DBG("VIDIOCSYNC: %d\n", frame);			read_frame(cam, frame);			vicam_decode_color(cam->raw_image,					   cam->framebuf +					   frame * VICAM_MAX_FRAME_SIZE );			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;	}	return retval;}static intvicam_open(struct inode *inode, struct file *file){	struct video_device *dev = video_devdata(file);	struct vicam_camera *cam =	    (struct vicam_camera *) dev->priv;	DBG("open\n");	if (!cam) {		printk(KERN_ERR		       "vicam video_device improperly initialized");	}	/* the videodev_lock held above us protects us from	 * simultaneous opens...for now. we probably shouldn't	 * rely on this fact forever.	 */	if (cam->open_count > 0) {		printk(KERN_INFO		       "vicam_open called on already opened camera");		return -EBUSY;	}	cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);	if (!cam->raw_image) {		return -ENOMEM;	}	cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);	if (!cam->framebuf) {		kfree(cam->raw_image);		return -ENOMEM;	}	cam->cntrlbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);	if (!cam->cntrlbuf) {		kfree(cam->raw_image);		rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);		return -ENOMEM;	}	// First upload firmware, then turn the camera on	if (!cam->is_initialized) {		initialize_camera(cam);		cam->is_initialized = 1;	}	set_camera_power(cam, 1);	cam->needsDummyRead = 1;	cam->open_count++;	file->private_data = cam;			return 0;}static int vicam_close(struct inode *inode, struct file *file){	struct vicam_camera *cam = file->private_data;	int open_count;	struct usb_device *udev;	DBG("close\n");	/* it's not the end of the world if	 * we fail to turn the camera off.	 */	set_camera_power(cam, 0);	kfree(cam->raw_image);	rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);	kfree(cam->cntrlbuf);	down(&cam->cam_lock);	cam->open_count--;	open_count = cam->open_count;	udev = cam->udev;	up(&cam->cam_lock);	if (!open_count && !udev) {		kfree(cam);	}	return 0;}static void vicam_decode_color(const u8 *data, u8 *rgb){	/* vicam_decode_color - Convert from Vicam Y-Cr-Cb to RGB	 * Copyright (C) 2002 Monroe Williams (monroe@pobox.com)	 */	int i, prevY, nextY;	prevY = 512;	nextY = 512;	data += VICAM_HEADER_SIZE;	for( i = 0; i < 240; i++, data += 512 ) {		const int y = ( i * 242 ) / 240;		int j, prevX, nextX;		int Y, Cr, Cb;		if ( y == 242 - 1 ) {			nextY = -512;		}		prevX = 1;		nextX = 1;		for ( j = 0; j < 320; j++, rgb += 3 ) {			const int x = ( j * 512 ) / 320;			const u8 * const src = &data[x];			if ( x == 512 - 1 ) {				nextX = -1;			}			Cr = ( src[prevX] - src[0] ) +				( src[nextX] - src[0] );			Cr /= 2;			Cb = ( src[prevY] - src[prevX + prevY] ) +				( src[prevY] - src[nextX + prevY] ) +				( src[nextY] - src[prevX + nextY] ) +				( src[nextY] - src[nextX + nextY] );			Cb /= 4;			Y = 1160 * ( src[0] + ( Cr / 2 ) - 16 );			if ( i & 1 ) {				int Ct = Cr;				Cr = Cb;				Cb = Ct;			}			if ( ( x ^ i ) & 1 ) {				Cr = -Cr;				Cb = -Cb;			}			rgb[0] = clamp( ( ( Y + ( 2017 * Cb ) ) +					500 ) / 900, 0, 255 );			rgb[1] = clamp( ( ( Y - ( 392 * Cb ) -					  ( 813 * Cr ) ) +					  500 ) / 1000, 0, 255 );			rgb[2] = clamp( ( ( Y + ( 1594 * Cr ) ) +					500 ) / 1300, 0, 255 );			prevX = -1;		}		prevY = -512;	}}static voidread_frame(struct vicam_camera *cam, int framenum){	unsigned char *request = cam->cntrlbuf;	int realShutter;	int n;	int actual_length;	if (cam->needsDummyRead) {		cam->needsDummyRead = 0;		read_frame(cam, framenum);	}	memset(request, 0, 16);	request[0] = cam->gain;	// 0 = 0% gain, FF = 100% gain	request[1] = 0;	// 512x242 capture	request[2] = 0x90;	// the function of these two bytes	request[3] = 0x07;	// is not yet understood

⌨️ 快捷键说明

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