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

📄 pwc-v4l.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
				case V4L2_CID_PRIVATE_RESTORE_FACTORY:					return -EINVAL;			}			return -EINVAL;		}		case VIDIOC_S_CTRL:		{			struct v4l2_control *c = arg;			int ret;			switch (c->id)			{				case V4L2_CID_BRIGHTNESS:					c->value <<= 9;					ret = pwc_set_brightness(pdev, c->value);					if (ret<0)						return -EINVAL;					return 0;				case V4L2_CID_CONTRAST:					c->value <<= 10;					ret = pwc_set_contrast(pdev, c->value);					if (ret<0)						return -EINVAL;					return 0;				case V4L2_CID_SATURATION:					ret = pwc_set_saturation(pdev, c->value);					if (ret<0)					  return -EINVAL;					return 0;				case V4L2_CID_GAMMA:					c->value <<= 11;					ret = pwc_set_gamma(pdev, c->value);					if (ret<0)						return -EINVAL;					return 0;				case V4L2_CID_RED_BALANCE:					c->value <<= 8;					ret = pwc_set_red_gain(pdev, c->value);					if (ret<0)						return -EINVAL;					return 0;				case V4L2_CID_BLUE_BALANCE:					c->value <<= 8;					ret = pwc_set_blue_gain(pdev, c->value);					if (ret<0)						return -EINVAL;					return 0;				case V4L2_CID_AUTO_WHITE_BALANCE:					c->value = (c->value == 0)?PWC_WB_MANUAL:PWC_WB_AUTO;					ret = pwc_set_awb(pdev, c->value);					if (ret<0)						return -EINVAL;					return 0;				case V4L2_CID_EXPOSURE:					c->value <<= 8;					ret = pwc_set_shutter_speed(pdev, c->value?0:1, c->value);					if (ret<0)						return -EINVAL;					return 0;				case V4L2_CID_AUTOGAIN:					/* autogain off means nothing without a gain */					if (c->value == 0)						return 0;					ret = pwc_set_agc(pdev, c->value, 0);					if (ret<0)						return -EINVAL;					return 0;				case V4L2_CID_GAIN:					c->value <<= 8;					ret = pwc_set_agc(pdev, 0, c->value);					if (ret<0)						return -EINVAL;					return 0;				case V4L2_CID_PRIVATE_SAVE_USER:					if (pwc_save_user(pdev))						return -EINVAL;					return 0;				case V4L2_CID_PRIVATE_RESTORE_USER:					if (pwc_restore_user(pdev))						return -EINVAL;					return 0;				case V4L2_CID_PRIVATE_RESTORE_FACTORY:					if (pwc_restore_factory(pdev))						return -EINVAL;					return 0;				case V4L2_CID_PRIVATE_COLOUR_MODE:					ret = pwc_set_colour_mode(pdev, c->value);					if (ret < 0)					  return -EINVAL;					return 0;				case V4L2_CID_PRIVATE_AUTOCONTOUR:				  c->value=(c->value == 1)?-1:0;				  ret = pwc_set_contour(pdev, c->value);				  if (ret < 0)				    return -EINVAL;				  return 0;				case V4L2_CID_PRIVATE_CONTOUR:				  c->value <<= 10;				  ret = pwc_set_contour(pdev, c->value);				  if (ret < 0)				    return -EINVAL;				  return 0;				case V4L2_CID_PRIVATE_BACKLIGHT:				  ret = pwc_set_backlight(pdev, c->value);				  if (ret < 0)				    return -EINVAL;				  return 0;				case V4L2_CID_PRIVATE_FLICKERLESS:				  ret = pwc_set_flicker(pdev, c->value);				  if (ret < 0)				    return -EINVAL;				case V4L2_CID_PRIVATE_NOISE_REDUCTION:				  ret = pwc_set_dynamic_noise(pdev, c->value);				  if (ret < 0)				    return -EINVAL;				  return 0;			}			return -EINVAL;		}		case VIDIOC_ENUM_FMT:		{			struct v4l2_fmtdesc *f = arg;			int index;			if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)			      return -EINVAL;			/* We only support two format: the raw format, and YUV */			index = f->index;			memset(f,0,sizeof(struct v4l2_fmtdesc));			f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;			f->index = index;			switch(index)			{				case 0:					/* RAW format */					f->pixelformat = pdev->type<=646?V4L2_PIX_FMT_PWC1:V4L2_PIX_FMT_PWC2;					f->flags = V4L2_FMT_FLAG_COMPRESSED;					strlcpy(f->description,"Raw Philips Webcam",sizeof(f->description));					break;				case 1:					f->pixelformat = V4L2_PIX_FMT_YUV420;					strlcpy(f->description,"4:2:0, planar, Y-Cb-Cr",sizeof(f->description));					break;				default:					return -EINVAL;			}			return 0;		}		case VIDIOC_G_FMT:		{			struct v4l2_format *f = arg;			PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",pdev->image.x,pdev->image.y);			if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)			      return -EINVAL;			pwc_vidioc_fill_fmt(pdev, f);			return 0;		}		case VIDIOC_TRY_FMT:			return pwc_vidioc_try_fmt(pdev, arg);		case VIDIOC_S_FMT:			return pwc_vidioc_set_fmt(pdev, arg);		case VIDIOC_G_STD:		{			v4l2_std_id *std = arg;			*std = V4L2_STD_UNKNOWN;			return 0;		}		case VIDIOC_S_STD:		{			v4l2_std_id *std = arg;			if (*std != V4L2_STD_UNKNOWN)				return -EINVAL;			return 0;		}		case VIDIOC_ENUMSTD:		{			struct v4l2_standard *std = arg;			if (std->index != 0)				return -EINVAL;			std->id = V4L2_STD_UNKNOWN;			strncpy(std->name, "webcam", sizeof(std->name));			return 0;		}		case VIDIOC_REQBUFS:		{			struct v4l2_requestbuffers *rb = arg;			int nbuffers;			PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n",rb->count);			if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)				return -EINVAL;			if (rb->memory != V4L2_MEMORY_MMAP)				return -EINVAL;			nbuffers = rb->count;			if (nbuffers < 2)				nbuffers = 2;			else if (nbuffers > pwc_mbufs)				nbuffers = pwc_mbufs;			/* Force to use our # of buffers */			rb->count = pwc_mbufs;			return 0;		}		case VIDIOC_QUERYBUF:		{			struct v4l2_buffer *buf = arg;			int index;			PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n",buf->index);			if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {				PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n");				return -EINVAL;			}			if (buf->memory != V4L2_MEMORY_MMAP) {				PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad memory type\n");				return -EINVAL;			}			index = buf->index;			if (index < 0 || index >= pwc_mbufs) {				PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index);				return -EINVAL;			}			memset(buf, 0, sizeof(struct v4l2_buffer));			buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;			buf->index = index;			buf->m.offset = index * pdev->len_per_image;			if (pdev->vpalette == VIDEO_PALETTE_RAW)				buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);			else				buf->bytesused = pdev->view.size;			buf->field = V4L2_FIELD_NONE;			buf->memory = V4L2_MEMORY_MMAP;			//buf->flags = V4L2_BUF_FLAG_MAPPED;			buf->length = pdev->len_per_image;			PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n",buf->index);			PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n",buf->m.offset);			PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n",buf->bytesused);			return 0;		}		case VIDIOC_QBUF:		{			struct v4l2_buffer *buf = arg;			PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n",buf->index);			if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)				return -EINVAL;			if (buf->memory != V4L2_MEMORY_MMAP)				return -EINVAL;			if (buf->index < 0 || buf->index >= pwc_mbufs)				return -EINVAL;			buf->flags |= V4L2_BUF_FLAG_QUEUED;			buf->flags &= ~V4L2_BUF_FLAG_DONE;			return 0;		}		case VIDIOC_DQBUF:		{			struct v4l2_buffer *buf = arg;			int ret;			PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n");			if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)				return -EINVAL;			/* Add ourselves to the frame wait-queue.			   FIXME: needs auditing for safety.			   QUESTION: In what respect? I think that using the				     frameq is safe now.			 */			add_wait_queue(&pdev->frameq, &wait);			while (pdev->full_frames == NULL) {				if (pdev->error_status) {					remove_wait_queue(&pdev->frameq, &wait);					set_current_state(TASK_RUNNING);					return -pdev->error_status;				}				if (signal_pending(current)) {					remove_wait_queue(&pdev->frameq, &wait);					set_current_state(TASK_RUNNING);					return -ERESTARTSYS;				}				schedule();				set_current_state(TASK_INTERRUPTIBLE);			}			remove_wait_queue(&pdev->frameq, &wait);			set_current_state(TASK_RUNNING);			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n");			/* Decompress data in pdev->images[pdev->fill_image] */			ret = pwc_handle_frame(pdev);			if (ret)				return -EFAULT;			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n");			buf->index = pdev->fill_image;			if (pdev->vpalette == VIDEO_PALETTE_RAW)				buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);			else				buf->bytesused = pdev->view.size;			buf->flags = V4L2_BUF_FLAG_MAPPED;			buf->field = V4L2_FIELD_NONE;			do_gettimeofday(&buf->timestamp);			buf->sequence = 0;			buf->memory = V4L2_MEMORY_MMAP;			buf->m.offset = pdev->fill_image * pdev->len_per_image;			buf->length = pdev->len_per_image;			pwc_next_image(pdev);			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index);			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n",buf->length);			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n",buf->m.offset);			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n",buf->bytesused);			PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n");			return 0;		}		case VIDIOC_STREAMON:		{			/* WARNING: pwc_try_video_mode() called pwc_isoc_init */			pwc_isoc_init(pdev);			return 0;		}		case VIDIOC_STREAMOFF:		{			pwc_isoc_cleanup(pdev);			return 0;		}		case VIDIOC_ENUM_FRAMESIZES:		{			struct v4l2_frmsizeenum *fsize = arg;			unsigned int i = 0, index = fsize->index;			if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {				for (i = 0; i < PSZ_MAX; i++) {					if (pdev->image_mask & (1UL << i)) {						if (!index--) {							fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;							fsize->discrete.width = pwc_image_sizes[i].x;							fsize->discrete.height = pwc_image_sizes[i].y;							return 0;						}					}				}			} else if (fsize->index == 0 &&				   ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||				    (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {				fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;				fsize->discrete.width = pdev->abs_max.x;				fsize->discrete.height = pdev->abs_max.y;				return 0;			}			return -EINVAL;		}		case VIDIOC_ENUM_FRAMEINTERVALS:		{			struct v4l2_frmivalenum *fival = arg;			int size = -1;			unsigned int i;			for (i = 0; i < PSZ_MAX; i++) {				if (pwc_image_sizes[i].x == fival->width &&				    pwc_image_sizes[i].y == fival->height) {					size = i;					break;				}			}			/* TODO: Support raw format */			if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) {				return -EINVAL;			}			i = pwc_get_fps(pdev, fival->index, size);			if (!i)				return -EINVAL;			fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;			fival->discrete.numerator = 1;			fival->discrete.denominator = i;			return 0;		}		default:			return pwc_ioctl(pdev, cmd, arg);	} /* ..switch */	return 0;}/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */

⌨️ 快捷键说明

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