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

📄 pwc-v4l.c

📁 webcam device driver
💻 C
📖 第 1 页 / 共 3 页
字号:
						return -EINVAL;					c->value >>= 8;					return 0;				case V4L2_CID_AUTOGAIN:					ret = pwc_get_agc(pdev, &c->value);					if (ret<0)						return -EINVAL;					c->value = (c->value < 0)?1:0;					return 0;				case V4L2_CID_EXPOSURE:					ret = pwc_get_shutter_speed(pdev, &c->value);					if (ret<0)						return -EINVAL;					return 0;			        case V4L2_CID_PRIVATE_COLOUR_MODE:					ret = pwc_get_colour_mode(pdev, &c->value);					if (ret < 0)						return -EINVAL;					return 0;			        case V4L2_CID_PRIVATE_AUTOCONTOUR:					ret = pwc_get_contour(pdev, &c->value);					if (ret < 0)						return -EINVAL;					c->value=(c->value == -1?1:0);					return 0;				case V4L2_CID_PRIVATE_CONTOUR:					ret = pwc_get_contour(pdev, &c->value);					if (ret < 0)						return -EINVAL;					c->value >>= 10;					return 0;				case V4L2_CID_PRIVATE_BACKLIGHT:					ret = pwc_get_backlight(pdev, &c->value);					if (ret < 0)						return -EINVAL;					return 0;				case V4L2_CID_PRIVATE_FLICKERLESS:					ret = pwc_get_flicker(pdev, &c->value);					if (ret < 0)						return -EINVAL;					c->value=(c->value?1:0);					return 0;				case V4L2_CID_PRIVATE_NOISE_REDUCTION:					ret = pwc_get_dynamic_noise(pdev, &c->value);					if (ret < 0)						return -EINVAL;					return 0;				case V4L2_CID_PRIVATE_SAVE_USER:				case V4L2_CID_PRIVATE_RESTORE_USER:				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 = buf->bytesused;			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;		}			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 + -