?? pwc-v4l.c
字號:
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 + -