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

📄 vicam.c

📁 ep9315平台下USB驱动的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
{	struct vicam_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, "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(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.brightness = cam->gain << 8;			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);				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			    ((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 =			    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			    ((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 >= 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, 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 intvicam_open(struct video_device *dev, int flags){	struct vicam_camera *cam =	    (struct vicam_camera *) dev->priv;	DBG("open\n");	if (!cam) {		printk(KERN_ERR		       "vicam video_device improperly initialized");	}	down_interruptible(&cam->busy_lock);	if (cam->open_count > 0) {		printk(KERN_INFO		       "vicam_open called on already opened camera");		up(&cam->busy_lock);		return -EBUSY;	}	if (!cam->raw_image) {		cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);		if (!cam->raw_image) {			up(&cam->busy_lock);			return -ENOMEM;		}	}	if (!cam->framebuf) {		cam->framebuf =		    usbvideo_rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);		if (!cam->framebuf) {			kfree(cam->raw_image);			up(&cam->busy_lock);			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++;	up(&cam->busy_lock);	return 0;}static voidvicam_close(struct video_device *dev){	DBG("close\n");	set_camera_power((struct vicam_camera *) dev->priv, 0);	((struct vicam_camera *) dev->priv)->open_count--;}inline int pin(int x){	return((x > 255) ? 255 : ((x < 0) ? 0 : x));}inline void writepixel(char *rgb, int Y, int Cr, int Cb){	Y = 1160 * (Y - 16);		rgb[2] = pin( ( ( Y + ( 1594 * Cr ) ) + 500 ) / 1300 );	rgb[1] = pin( ( ( Y - (  392 * Cb ) - ( 813 * Cr ) ) + 500 ) / 1000 );	rgb[0] = pin( ( ( Y + ( 2017 * Cb ) ) + 500 ) / 900 );}#define DATA_HEADER_SIZE 64// --------------------------------------------------------------------------------//	vicam_decode_color - Convert from Vicam Y-Cr-Cb to RGB////   Copyright (C) 2002 Monroe Williams (monroe@pobox.com)// --------------------------------------------------------------------------------void vicam_decode_color( char *data, char *rgb){	int x,y;	int Cr, Cb;	int sign;	int prevX, nextX, prevY, nextY;	int skip;	unsigned char *src;	unsigned char *dst;	prevY = 512;	nextY = 512;	src = data + DATA_HEADER_SIZE;	dst = rgb;	for(y = 1; y < 241; y += 2)	{		// even line		sign = 1;		prevX = 1;		nextX = 1;		skip = 0;		dst = rgb + (y-1)*320*3;				for(x = 0; x < 512; x++)		{			if(x == 512-1)				nextX = -1;			Cr = sign * ((src[prevX] - src[0]) + (src[nextX] - src[0])) >> 1;			Cb = sign * ((src[prevY] - src[prevX + prevY]) + (src[prevY] - src[nextX + prevY]) + (src[nextY] - src[prevX + nextY]) + (src[nextY] - src[nextX + nextY])) >> 2;			writepixel(					dst + ((x*5)>>3)*3,					src[0] + (sign * (Cr >> 1)),					Cr,					Cb);			src++;			sign *= -1;			prevX = -1;		}		prevY = -512;		if(y == (242 - 2))			nextY = -512;		// odd line		sign = 1;		prevX = 1;		nextX = 1;		skip = 0;		dst = rgb + (y)*320*3;				for(x = 0; x < 512; x++)		{			if(x == 512-1)				nextX = -1;						Cr = sign * ((src[prevX + prevY] - src[prevY]) + (src[nextX + prevY] - src[prevY]) + (src[prevX + nextY] - src[nextY]) + (src[nextX + nextY] - src[nextY])) >> 2;			Cb = sign * ((src[0] - src[prevX]) + (src[0] - src[nextX])) >> 1;			writepixel(					dst + ((x * 5)>>3)*3,					src[0] - (sign * (Cb >> 1)),					Cr,					Cb);			src++;			sign *= -1;			prevX = -1;		}	}}static voidread_frame(struct vicam_camera *cam, int framenum){	unsigned char request[16];	int realShutter;	int n;	int actual_length;	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	if (cam->shutter_speed > 60) {		// Short exposure		realShutter =		    ((-15631900 / cam->shutter_speed) + 260533) / 1000;		request[4] = realShutter & 0xFF;		request[5] = (realShutter >> 8) & 0xFF;		request[6] = 0x03;		request[7] = 0x01;	} else {		// Long exposure		realShutter = 15600 / cam->shutter_speed - 1;		request[4] = 0;		request[5] = 0;		request[6] = realShutter & 0xFF;		request[7] = realShutter >> 8;	}	// Per John Markus Bj鴕ndalen, byte at index 8 causes problems if it isn't 0	request[8] = 0;	// bytes 9-15 do not seem to affect exposure or image quality	n = send_control_msg(cam->udev, 0x51, 0x80, 0, request, 16);	if (n < 0) {		printk(KERN_ERR		       " Problem sending frame capture control message");		return;	}

⌨️ 快捷键说明

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