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

📄 ovfx2.c

📁 支持linux2.6和linux2.4的ov511摄像头驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* This code breaks a few apps (Gnomemeeting, possibly  others). Disable it until a solution can be found */#if 0		if (vw->flags || vw->clipcount)			return -EINVAL;#endif		rc = ov51x_wait_frames_inactive(ov);		if (rc)			return rc;		rc = mode_init_regs(ov, vw->width, vw->height,			ov->frame[0].format, ov->sub_flag);		if (rc < 0)			return rc;		for (i = 0; i < OVFX2_NUMFRAMES; i++) {			ov->frame[i].width = vw->width;			ov->frame[i].height = vw->height;		}		return 0;	}	case VIDIOCGWIN:	{		struct video_window *vw = arg;		memset(vw, 0, sizeof(struct video_window));		vw->x = 0;		/* FIXME */		vw->y = 0;		vw->width = ov->frame[0].width;		vw->height = ov->frame[0].height;		PDEBUG(4, "Get window: %dx%d", vw->width, vw->height);		return 0;	}	case VIDIOCGMBUF:	{		struct video_mbuf *vm = arg;		int i;		memset(vm, 0, sizeof(struct video_mbuf));		vm->size = OVFX2_NUMFRAMES			   * MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);		vm->frames = OVFX2_NUMFRAMES;		vm->offsets[0] = 0;		for (i = 1; i < OVFX2_NUMFRAMES; i++) {			vm->offsets[i] = vm->offsets[i-1]			   + MAX_DATA_SIZE(ov->maxwidth, ov->maxheight);		}		return 0;	}	case VIDIOCMCAPTURE:	{		struct video_mmap *vm = arg;		int rc, depth;		unsigned int f = vm->frame;		PDEBUG(4, "MCAPTURE: frame: %d, %dx%d, %s", f, vm->width,			vm->height, symbolic(v4l1_plist, vm->format));		depth = get_depth(vm->format);		if (!depth) {			PDEBUG(2, "MCAPTURE: invalid format (%s)",			       symbolic(v4l1_plist, vm->format));			return -EINVAL;		}		if (f >= OVFX2_NUMFRAMES) {			err("MCAPTURE: invalid frame (%d)", f);			return -EINVAL;		}		if (vm->width > ov->maxwidth		    || vm->height > ov->maxheight) {			err("MCAPTURE: requested dimensions too big");			return -EINVAL;		}		if (ov->frame[f].grabstate == FRAME_GRABBING) {			PDEBUG(4, "MCAPTURE: already grabbing");			return -EBUSY;		}		if (force_palette && (vm->format != force_palette)) {			PDEBUG(2, "MCAPTURE: palette rejected (%s)",			       symbolic(v4l1_plist, vm->format));			return -EINVAL;		}		if ((ov->frame[f].width != vm->width) ||		    (ov->frame[f].height != vm->height) ||		    (ov->frame[f].format != vm->format) ||		    (ov->frame[f].sub_flag != ov->sub_flag) ||		    (ov->frame[f].depth != depth)) {			PDEBUG(4, "MCAPTURE: change in image parameters");			rc = ov51x_wait_frames_inactive(ov);			if (rc)				return rc;			rc = mode_init_regs(ov, vm->width, vm->height,				vm->format, ov->sub_flag);#if 0			if (rc < 0) {				PDEBUG(1, "Got error while initializing regs ");				return rc;			}#endif			ov->frame[f].width = vm->width;			ov->frame[f].height = vm->height;			ov->frame[f].format = vm->format;			ov->frame[f].sub_flag = ov->sub_flag;			ov->frame[f].depth = depth;		}		/* Mark it as ready */		ov->frame[f].grabstate = FRAME_READY;		return ovfx2_new_frame(ov, f);	}	case VIDIOCSYNC:	{		unsigned int fnum = *((unsigned int *) arg);		struct ovfx2_frame *frame;		int rc;		if (fnum >= OVFX2_NUMFRAMES) {			err("SYNC: invalid frame (%d)", fnum);			return -EINVAL;		}		frame = &ov->frame[fnum];		PDEBUG(4, "syncing to frame %d, grabstate = %d", fnum,		       frame->grabstate);		switch (frame->grabstate) {		case FRAME_UNUSED:			return -EINVAL;		case FRAME_READY:		case FRAME_GRABBING:		case FRAME_ERROR:redo:			rc = wait_event_interruptible(frame->wq,			    (frame->grabstate == FRAME_DONE)			    || (frame->grabstate == FRAME_ERROR)			    || !ov->present);			if (rc)				return rc;			if (!ov->present)				return -ENODEV;			if (frame->grabstate == FRAME_ERROR) {				if ((rc = ovfx2_new_frame(ov, fnum)) < 0)					return rc;				goto redo;			}			/* Fall through */		case FRAME_DONE:			PDEBUG(4, "SYNC: frame %d is DONE", fnum);			frame->grabstate = FRAME_UNUSED;			/* Decompression, format conversion, etc... */			ovfx2_postprocess(ov, frame);			break;		} /* end switch */		return 0;	}	case VIDIOCGFBUF:	{		struct video_buffer *vb = arg;		memset(vb, 0, sizeof(struct video_buffer));		return 0;	}	case VIDIOCGUNIT:	{		struct video_unit *vu = arg;		memset(vu, 0, sizeof(struct video_unit));		vu->video = ov->vdev->minor;		vu->vbi = VIDEO_NO_UNIT;		vu->radio = VIDEO_NO_UNIT;		vu->audio = VIDEO_NO_UNIT;		vu->teletext = VIDEO_NO_UNIT;		return 0;	}#if defined(HAVE_V4L2)	case VIDIOC_QUERYCAP:	{		struct v4l2_capability *c = arg;		if (!v4l2)			return -EINVAL;		memset(c, 0, sizeof(*c));		strcpy(c->driver, "ovfx2");		// FIXME: Use a better description (e.g. from device table)		snprintf(c->card, sizeof(c->card), "FX2/%s",			symbolic(senlist, ov->sensor));		strncpy(c->bus_info, ov->usb_path, sizeof(c->bus_info));		c->version = DRIVER_VERSION_CODE;		c->capabilities =			V4L2_CAP_VIDEO_CAPTURE |			V4L2_CAP_READWRITE;// FIXME: Implement this later//		c->capabilities |= V4L2_CAP_STREAMING;		return 0;	}	case VIDIOC_CROPCAP:	{		struct v4l2_cropcap *c = arg;		if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)			return -EINVAL;		c->bounds.left = 0;		c->bounds.top = 0;		c->bounds.width = ov->maxwidth;		c->bounds.height = ov->maxheight;		c->defrect.left = 0;		c->defrect.top = 0;		c->defrect.width = ov->maxwidth;		c->defrect.height = ov->maxheight;		return 0;	}	case VIDIOC_ENUM_FMT:	{		struct v4l2_fmtdesc *f = arg;		const struct v4l2_fmtdesc *ptr = NULL;		int index = f->index;		if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)			return -EINVAL;		if (force_palette) {			if (index)				return -EINVAL;			switch (force_palette) {//			case VIDEO_PALETTE_GREY://				ptr = &ovfx2_fmt_grey;//				break;			case VIDEO_PALETTE_RGB24:				ptr = &ovfx2_fmt_bgr24;				break;			}		} else {			switch (index) {//			case 0://				ptr = &ovfx2_fmt_grey;//				break;			case 1:				ptr = &ovfx2_fmt_bgr24;				break;			}		}		if (ptr)			memcpy(f, ptr, sizeof(*f));		else			return -EINVAL;		f->index = index;		f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;		return 0;	}	case VIDIOC_G_FMT:	{		struct v4l2_format *f = arg;		if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)			return -EINVAL;		memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));		f->fmt.pix.width = ov->frame[0].width;		f->fmt.pix.height = ov->frame[0].height;		switch (ov->frame[0].format) {//		case VIDEO_PALETTE_GREY://			f->fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;//			f->fmt.pix.bytesperline = f->fmt.pix.width;//			f->fmt.pix.sizeimage =//				f->fmt.pix.bytesperline * f->fmt.pix.height;//			break;		case VIDEO_PALETTE_RGB24:			f->fmt.pix.pixelformat = V4L2_PIX_FMT_BGR24;			f->fmt.pix.bytesperline = f->fmt.pix.width * 3;			f->fmt.pix.sizeimage =				f->fmt.pix.bytesperline * f->fmt.pix.height;			break;		default:			err("Bad pixel format");			return -ENODATA;		}		f->fmt.pix.field = V4L2_FIELD_NONE;		// FIXME: This might not be right		f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;		return 0;	}	case VIDIOC_S_FMT:	{		struct v4l2_format *f = arg;		int format, i;		if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)			return -EINVAL;		switch (f->fmt.pix.pixelformat) {//		case V4L2_PIX_FMT_GREY://			format = VIDEO_PALETTE_GREY;//			f->fmt.pix.bytesperline = f->fmt.pix.width;//			f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *//			    f->fmt.pix.height;//			break;		case V4L2_PIX_FMT_BGR24:			format = VIDEO_PALETTE_RGB24;			f->fmt.pix.bytesperline = f->fmt.pix.width * 3;			f->fmt.pix.sizeimage =				f->fmt.pix.bytesperline * f->fmt.pix.height;			break;		default:			PDEBUG(2, "App requested unsupported pix format: 0x%x",				f->fmt.pix.pixelformat);			/* According to V4L2 spec, we're allowed to return			 * -EINVAL iff v4l2_format is ambiguous */ 			return -EINVAL;		}		if (force_palette && (format != force_palette)) {			PDEBUG(2, "palette rejected (%s)",				symbolic(v4l1_plist, format));			return -EINVAL;		}		f->fmt.pix.field = V4L2_FIELD_NONE;		// FIXME: This might not be right		f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;		// FIXME: This sucks. mode_init_regs() should handle this		for (i = 0; i < OVFX2_NUMFRAMES; i++) {			ov->frame[i].width = f->fmt.pix.width;			ov->frame[i].height = f->fmt.pix.height;			ov->frame[i].sub_flag = 0;			ov->frame[i].depth = get_depth(format);			ov->frame[i].format = format;		}		// FIXME: This function gives up rather than forcing the		// closest supported size.		return mode_init_regs(ov, f->fmt.pix.width, f->fmt.pix.height,			format, 0);	}	case VIDIOC_ENUMINPUT:	{		struct v4l2_input *i = arg;		__u32 n;		n = i->index;		if (n)			return -EINVAL;		memset(i, 0, sizeof(*i));		i->index = n;		sprintf(i->name, "%s", "Camera");		i->type = V4L2_INPUT_TYPE_CAMERA;		i->std = V4L2_STD_UNKNOWN;		return 0;	}	case VIDIOC_G_INPUT:	{		*((int *)arg) = 0;		return 0;	}	case VIDIOC_S_INPUT:	{		if (*((int *)arg))			return -EINVAL;		else			return 0;	}	case VIDIOC_QUERYCTRL:	case VIDIOC_S_CTRL:	case VIDIOC_G_CTRL:	{		struct v4l2_queryctrl *c = arg;		int rc;		/* Since controls are implemented at multiple driver layers,		 * we need translate the IDs in some cases and route them		 * accordingly. Apps should find private controls by name		 * rather than by ID */		if (c->id >= V4L2_CID_BASE || c->id < V4L2_CID_LASTP1) {			rc = ovfx2_control_op(ov, cmd, c);			// FIXME: -EINVAL could mean multiple things here			if (rc == -EINVAL)				rc = sensor_cmd(ov, cmd, c);		} else if ((c->id >= V4L2_CID_PRIVATE_BASE) &&		           (c->id < OVFX2_CID_LASTP1)) {			rc = ovfx2_control_op(ov, cmd, c);		} else if (c->id < (SENSOR_CID_OFFSET +		                    OVCAMCHIP_V4L2_CID_LASTP1)) {			c->id += SENSOR_CID_OFFSET;			rc = sensor_cmd(ov, cmd, c);			c->id -= SENSOR_CID_OFFSET;		} else {			rc = -EINVAL;		}		return rc;	}// mmap() capture disabled until select() and rest of ioctls are implemented#if 0	case VIDIOC_REQBUFS:	{		struct v4l2_requestbuffers *rb = arg;		if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||		    rb->memory != V4L2_MEMORY_MMAP)			return -EINVAL;		// FIXME: This shouldn't be hardcoded		rb->count = OV511_NUMFRAMES;//		memset(rb->reserved, 0, sizeof(*(rb->reserved)));		// FIXME: Driver should check that this ioctl was called		// before allowing buffers to be queued or queried		return 0;	}	case VIDIOC_STREAMON:	{		int type = *((int *)arg);		int i;		if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)			return -EINVAL;				// FIXME: ISO streaming shouldn't be started until this ioctl		for (i = 1; i < OV511_NUMFRAMES; i++)			if (ov->frame[i].grabstate == FRAME_UNUSED)				ov->frame[i].grabstate = FRAME_READY; // Racy!!		return 0;	}	case VIDIOC_STREAMOFF:	{		int type = *((int *)arg);		int i;		if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)			return -EINVAL;		// FIXME: ISO streaming should be stopped by this ioctl		for (i = 1; i < OV511_NUMFRAMES; i++)			ov->frame[i].grabstate = FRAME_UNUSED;		return 0;	}#endif// Incomplete code#if 0	case: VIDIOC_QBUF:	{		struct v4l2_buffer *buf = arg;		struct ov511_frame *frame;		int rc;		if (buf->index >= OV511_NUMFRAMES) {			PDEBUG(2, "VIDIOC_QBUF: invalid index: %d", buf->index);			return -EINVAL;		}		frame = &ov->frame[buf->index];		if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)			return -EINVAL;		switch (frame->grabstate) {		case FRAME_READY:		case FRAME_GRABBING:			buf->flags |= V4L2_BUF_FLAG_MAPPED;			buf->flags |= V4L2_BUF_FLAG_QUEUED;			buf->flags = buf->flags &~ V4L2_BUF_FLAG_DONE;		}		return 0;	}	case: VIDIOC_DQBUF:	{		struct v4l2_buffer *buf = arg;		if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)			return -EINVAL;		return 0;	}#endif#endif /* HAVE_V4L2 */	default:		PDEBUG(3, "Unsupported IOCtl: 0x%X", cmd);		return -ENOIOCTLCMD;	/* V4L layer handles this */	} /* end switch */	return 0;}static intovfx2_ioctl(struct inode *inode, struct file *file,		 unsigned int cmd, unsigned long arg){	struct video_device *vdev = file->private_data;	struct usb_ovfx2 *ov = video_get_drvdata(vdev);	int rc;	if (down_interruptible(&ov->lock))		return -EINTR;	rc = video_usercopy(inode, file, cmd, arg, ovfx2_do_ioctl);	up(&ov->lock);	return rc;}static ssize_t#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 8)ovfx2_read(struct file *file, char __user *buf, size_t cnt, loff_t *p

⌨️ 快捷键说明

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