📄 qcamvc.c
字号:
/* Video channel ioctl */ case VIDIOCGCHAN: { if (copy_to_user(arg, &qcamvc->vchan, sizeof(struct video_channel))) { up(&qcamvc->busy); return -EFAULT; } up(&qcamvc->busy); return 0; } case VIDIOCSCHAN: { int v; if(copy_from_user(&v, arg,sizeof(int))) { up(&qcamvc->busy); return -EFAULT; } if(v!=0) { up(&qcamvc->busy); return -EINVAL; } up(&qcamvc->busy); return 0; } /* Video picture ioctl */ case VIDIOCGPICT: { if (copy_to_user(arg, &qcamvc->vpic, sizeof(struct video_picture))) { up(&qcamvc->busy); return -EFAULT; } up(&qcamvc->busy); return 0; } case VIDIOCSPICT: { struct video_picture p; if(copy_from_user(&p, arg, sizeof(struct video_picture))) { up(&qcamvc->busy); return -EFAULT; } if (p.depth != 24 || p.palette != VIDEO_PALETTE_RGB24) { up(&qcamvc->busy); return -EINVAL; } if (p.brightness >> 8 != qcamvc->brightness) { qcamvc->brightness = p.brightness >> 8; qcamvc_set_brightness(qcamvc,qcamvc->brightness); } if (p.whiteness >> 8 != qcamvc->exposure) { qcamvc->exposure = p.whiteness >> 8; qcamvc_set_exposure(qcamvc,qcamvc->exposure); } if (p.contrast != qcamvc->vpic.contrast) { qcamvc->blue_hue = p.contrast >> 8; qcamvc->hue_calc=0; } if (p.hue != qcamvc->vpic.hue) { qcamvc->red_hue = p.hue >> 8; qcamvc->hue_calc=0; } if (p.colour != qcamvc->vpic.colour) { qcamvc->santrast = p.colour >> 8; qcamvc->hue_calc=0; } qcamvc->vpic = p; up(&qcamvc->busy); return 0; } /* Capture window ioctl */ case VIDIOCSWIN: { struct video_window vw; int res = qcamvc->res; if(copy_from_user(&vw, arg,sizeof(struct video_window))) { up(&qcamvc->busy); return -EFAULT; } if(vw.flags) { printk("1\n"); up(&qcamvc->busy); return -EINVAL; } if(vw.clipcount) { printk("2\n"); up(&qcamvc->busy); return -EINVAL; } if(vw.height<MIN_HEIGHT || vw.height>MAX_HEIGHT) { printk("Want to set %dx%d 3\n",vw.width, vw.height); up(&qcamvc->busy); return -EINVAL; } if(vw.width<MIN_WIDTH || vw.width>MAX_WIDTH) { printk("Want to set %dx%d 4\n",vw.width, vw.height); up(&qcamvc->busy); return -EINVAL; } if(vw.width>=160 && vw.height>=120) { res=R160x120; } if(vw.width>=176 && vw.height>=144) { res=R176x144; } if(vw.width>=320 && vw.height>=240) { res=R320x240; } if(vw.width>=352 && vw.height>=288) { res=R352x288; } qcamvc_set_res(qcamvc, res); up(&qcamvc->busy); return 0; } case VIDIOCGWIN: { struct video_window vw; memset(&vw, 0, sizeof(struct video_window)); vw.width = qcamvc->width; vw.height = qcamvc->height; vw.flags = 0; if(copy_to_user(arg, &vw, sizeof(struct video_window))) { up(&qcamvc->busy); return -EFAULT; } up(&qcamvc->busy); return 0; }#ifdef USE_MMAP /* mmap interface */ case VIDIOCGMBUF: { struct video_mbuf vm; int i; memset(&vm, 0, sizeof(struct video_mbuf)); vm.size = qcamvc->width * qcamvc->height * 3 * QUICKCAM_NUMFRAMES; vm.frames = QUICKCAM_NUMFRAMES; for (i = 0; i < QUICKCAM_NUMFRAMES ; i++) vm.offsets[i] = qcamvc->width * qcamvc->height * 3 * i; if (copy_to_user((void *)arg, (void *)&vm, sizeof(struct video_mbuf))) { up(&qcamvc->busy); return -EFAULT; } up(&qcamvc->busy); return 0; } case VIDIOCSYNC: { int frame; if (copy_from_user((void *)&frame, arg, sizeof(int))) { up(&qcamvc->busy); return -EFAULT; } if (frame<0 || frame >= QUICKCAM_NUMFRAMES ) { up(&qcamvc->busy); return -EINVAL; } switch (qcamvc->frame[frame].state) { case FRAME_UNUSED: case FRAME_READY: case FRAME_GRABBING: { printk("sync to unused frame %d\n", frame); up(&qcamvc->busy); return -EINVAL; } case FRAME_DONE: qcamvc->frame[frame].state = FRAME_UNUSED; } up(&qcamvc->busy); return 0; } case VIDIOCMCAPTURE: { struct video_mmap vm; if (copy_from_user((void *)&vm, (void *)arg, sizeof(struct video_mmap))) { up(&qcamvc->busy); return -EFAULT; } if (vm.frame<0||vm.frame>QUICKCAM_NUMFRAMES) { up(&qcamvc->busy); return -EINVAL; } if (vm.format != VIDEO_PALETTE_YUV422) { up(&qcamvc->busy); return -EINVAL; } if (qcamvc->frame[vm.frame].state == FRAME_UNUSED) { up(&qcamvc->busy); return capture_frame(qcamvc, &vm); } }#else /* USE_MMAP */ case VIDIOCGMBUF: case VIDIOCSYNC: case VIDIOCMCAPTURE: { up(&qcamvc->busy); return -EINVAL; }#endif/* USE_MMAP */ /* No overlay support */ case VIDIOCCAPTURE: { up(&qcamvc->busy); return -EINVAL; } case VIDIOCSFBUF: { up(&qcamvc->busy); return -EINVAL; } case VIDIOCGFBUF: { up(&qcamvc->busy); return -EINVAL; } case VIDIOCKEY: { up(&qcamvc->busy); return -EINVAL; } /* No tuner interface */ case VIDIOCGTUNER: { up(&qcamvc->busy); return -EINVAL; } case VIDIOCSTUNER: { up(&qcamvc->busy); return -EINVAL; } case VIDIOCGFREQ: { up(&qcamvc->busy); return -EINVAL; } case VIDIOCSFREQ: { up(&qcamvc->busy); return -EINVAL; } /* No audio interface */ case VIDIOCGAUDIO: { up(&qcamvc->busy); return -EINVAL; } case VIDIOCSAUDIO: { up(&qcamvc->busy); return -EINVAL; } default: { up(&qcamvc->busy); return -ENOIOCTLCMD; } } up(&qcamvc->busy); return 0;}static int qcamvc_vopen(struct video_device *dev, int flags){ struct qcamvc *qcamvc = dev->priv;#ifdef DBG_CAM printk("USB QuickCam Open:\n");#endif#ifdef USE_MMAP /* Set the frames */ qcamvc->current_frame = 0; for (i = 0; i < QUICKCAM_NUMFRAMES; i++) { qcamvc->frame[i].state = FRAME_UNUSED; qcamvc->frame[i].data = NULL; }#endif qcamvc->ops->qcamvc_open(qcamvc->lowlevel_data); qcamvc->open_count++; return 0;}static void qcamvc_vclose(struct video_device *dev){ struct qcamvc *qcamvc = dev->priv;#ifdef USE_MMAP free_frame_buf(qcamvc);#endif qcamvc->ops->qcamvc_close(qcamvc->lowlevel_data); qcamvc->open_count--; }/*****************************************************************************//* *//* QuickCam Video Camera layer *//* This layer want be indipendent from the camera structure (PP/USB) *//* *//*****************************************************************************/static void qcamvc_video_init(struct qcamvc *qcamvc){ if (qcamvc == NULL) return; /* Set the video capability */ memset(&qcamvc->vcap, 0, sizeof(struct video_capability)); strcpy(qcamvc->vcap.name, qcamvc->camtype); qcamvc->vcap.type = VID_TYPE_CAPTURE; qcamvc->vcap.channels = 1; qcamvc->vcap.audios = 0; qcamvc->vcap.maxwidth = MAX_WIDTH; qcamvc->vcap.maxheight = MAX_HEIGHT; qcamvc->vcap.minwidth = MIN_WIDTH; qcamvc->vcap.minheight = MIN_HEIGHT; qcamvc->res = R352x288; /* Set the video channel structure */ memset(&qcamvc->vchan, 0, sizeof(struct video_channel)); qcamvc->vchan.flags = 0; qcamvc->vchan.tuners = 0; qcamvc->vchan.channel = 0; qcamvc->vchan.type = VIDEO_TYPE_CAMERA; strcpy(qcamvc->vchan.name, "Camera"); /* Set the video picture structure */ memset(&qcamvc->vpic, 0, sizeof(struct video_picture)); qcamvc->bpc=bpc6; qcamvc->brightness = 175; qcamvc->exposure = 150; qcamvc->hue_calc = 0; qcamvc->blue_hue = 132; qcamvc->red_hue = 52; qcamvc->santrast = 50; qcamvc->vpic.colour = qcamvc->santrast * 0xff; qcamvc->vpic.hue = qcamvc->red_hue * 0xff; qcamvc->vpic.brightness = qcamvc->brightness * 0xff; qcamvc->vpic.contrast = qcamvc->blue_hue * 0xff; qcamvc->vpic.whiteness = qcamvc->exposure * 0xff; qcamvc->vpic.depth = 24; qcamvc->vpic.palette = VIDEO_PALETTE_RGB24; init_MUTEX(&qcamvc->busy); memcpy(&qcamvc->vdev, &qcamvc_template, sizeof(qcamvc_template)); qcamvc->vdev.priv = qcamvc;#if LINUX_VERSION_CODE >= 0x020405 if (video_register_device(&qcamvc->vdev, VFL_TYPE_GRABBER, -1) == -1) {#else if (video_register_device(&qcamvc->vdev, VFL_TYPE_GRABBER) == -1) {#endif printk("Quickcam VC: video_register_device failed.\n"); memset (qcamvc, 0, sizeof(struct qcamvc)); } qcamvc_camera_init(qcamvc);}struct qcamvc *qcamvc_register_camera(struct qcamvc_camera_ops *ops, void *lowlevel, char *camtype){ struct qcamvc *qcamvc; if ((qcamvc = kmalloc(sizeof(struct qcamvc), GFP_KERNEL)) == NULL) { printk("QuickCam VC:Error allocating memory in qcamvc_register_camera\n"); return NULL; } qcamvc->lowlevel_data = lowlevel; qcamvc->ops = ops; qcamvc->open_count = 0; qcamvc->camtype=kmalloc(strlen(camtype), GFP_KERNEL); strcpy(qcamvc->camtype, camtype); qcamvc_video_init(qcamvc); MOD_INC_USE_COUNT; printk("Camera sucessfull registered\n"); return qcamvc;}void qcamvc_unregister_camera(struct qcamvc *qcamvc){ if (!qcamvc->open_count){ #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) destroy_proc_qcamvc (qcamvc); #endif printk("QuickCam VC: unregistering video\n"); video_unregister_device(&qcamvc->vdev); kfree(qcamvc->camtype); qcamvc->camtype=NULL; } else { qcamvc->ops=NULL; } if(!qcamvc->open_count){ kfree(qcamvc); } MOD_DEC_USE_COUNT;}/*****************************************************************************//* *//* QuickCam Video Camera layer *//* Module subs *//* *//*****************************************************************************/static int __init qcamvc_driver_init(void){ printk("QuickCam VC: (C) 2001 by Daniele De Marchi, <demarchidaniele@libero.it>\n"); printk("QuickCam VC: (C) 2004 (int version) Renzo Davoli <renzo@cs.unibo.it>\n"); printk("QuickCam VC: v4l level driver version %s registered.\n",QCAMVCVERSION);#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) proc_qcamvc_create();#endif#ifdef CONFIG_KMOD#ifdef CONFIG_VIDEO_QCAMVC_USB_MODULE request_module("qcamvc_usb");#endif#ifdef CONFIG_VIDEO_QCAMVC_PP_MODULE request_module("qcamvc_pp");#endif#endif#ifdef CONFIG_VIDEO_QCAMVC_PP qcamvc_pp_init();#endif#ifdef CONFIG_VIDEO_QCAMVC_USB qcamvc_usb_init();#endifreturn 0;}static void __exit qcamvc_driver_exit(void){#if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS) proc_quickcam_destroy();#endif printk("QuickCam VC: v4l driver unregistered\n");}module_init(qcamvc_driver_init);module_exit(qcamvc_driver_exit);/* Exported symbols for modules. */EXPORT_SYMBOL(qcamvc_register_camera);EXPORT_SYMBOL(qcamvc_unregister_camera);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -