📄 spca_core.c
字号:
if (!spca50x->present) goto out; err = -EBUSY; if (spca50x->user) goto out; err = -ENOMEM; if (spca50x_alloc (spca50x)) goto out; /* initialize sensor and decoding */ err = spca50x_init_source (spca50x); if (err != 0){ PDEBUG (0, "DEALLOC error on spca50x_init_source\n"); up (&spca50x->lock); spca5xx_dealloc (spca50x); goto out2; } spca5xx_initDecoder(spca50x); /* open always start in rgb24 a bug in gqcam did not select the palette nor the size v4l spec need that the camera always start on the last setting*/ spca5xx_setFrameDecoder(spca50x); spca50x->user++;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) file->private_data = vdev;#endif err = spca50x_init_isoc (spca50x); if (err) { PDEBUG (0, " DEALLOC error on init_Isoc\n"); spca50x->user--; spca5xx_kill_isoc (spca50x); up (&spca50x->lock); spca5xx_dealloc (spca50x); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) file->private_data = NULL;#endif goto out2; } /* Now, let's get brightness from the camera */ spca50x->brightness = spca50x_get_brightness (spca50x) << 8;out: up (&spca50x->lock);out2:#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) if (err) MOD_DEC_USE_COUNT;#endif if (err) { PDEBUG (2, "Open failed"); } else { PDEBUG (2, "Open done"); } return err;}static void inlinespcaCameraShutDown (struct usb_spca50x *spca50x){ if (spca50x->dev) { if (spca50x->bridge == BRIDGE_ZC3XX) zc3xx_shutdown (spca50x); }}#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)static intspca5xx_close (struct inode *inode, struct file *file){ struct video_device *vdev = file->private_data;#elsestatic void spca5xx_close( struct video_device *vdev){#endif struct usb_spca50x *spca50x = video_get_drvdata (vdev); int i; PDEBUG (2, "spca50x_close"); down (&spca50x->lock); spca50x->user--; spca50x->curframe = -1; if (spca50x->present) { spca50x_stop_isoc (spca50x); spcaCameraShutDown (spca50x); for (i = 0; i < SPCA50X_NUMFRAMES; i++) { if (waitqueue_active (&spca50x->frame[i].wq)) wake_up_interruptible (&spca50x->frame[i].wq); } if (waitqueue_active (&spca50x->wq)) wake_up_interruptible (&spca50x->wq); } /* times to dealloc ressource */ up (&spca50x->lock); spca5xx_dealloc (spca50x); PDEBUG(2,"Release ressources done");#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) MOD_DEC_USE_COUNT;#endif#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) file->private_data = NULL; return 0;#endif}#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)static intspca5xx_do_ioctl (struct inode *inode, struct file *file, unsigned int cmd, void *arg){ struct video_device *vdev = file->private_data;#elsestatic int spca5xx_ioctl (struct video_device *vdev, unsigned int cmd, void *arg){#endif struct usb_spca50x *spca50x = video_get_drvdata (vdev); PDEBUG (2, "do_IOCtl: 0x%X", cmd); if (!spca50x->dev) return -EIO; switch (cmd) { case VIDIOCGCAP: {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) struct video_capability *b = arg;#else struct video_capability j ; struct video_capability *b = &j;#endif PDEBUG (2, "VIDIOCGCAP %p :", b); memset (b, 0, sizeof (struct video_capability)); snprintf (b->name, 32, "%s", clist[spca50x->desc].description); b->type = VID_TYPE_CAPTURE; b->channels = 1; b->audios = 0; b->maxwidth = spca50x->maxwidth; b->maxheight = spca50x->maxheight; b->minwidth = spca50x->minwidth; b->minheight = spca50x->minheight;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) if(copy_to_user(arg,b,sizeof(struct video_capability))) return -EFAULT;#endif return 0; } case VIDIOCGCHAN: {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) struct video_channel *v = arg;#else struct video_channel k ; struct video_channel *v = &k; if(copy_from_user(v,arg,sizeof(struct video_channel))) return -EFAULT;#endif switch (spca50x->bridge) { case BRIDGE_SPCA504: case BRIDGE_SPCA504B: case BRIDGE_SPCA504C: case BRIDGE_SPCA533: case BRIDGE_SPCA536: case BRIDGE_ZC3XX: case BRIDGE_SN9CXXX: { snprintf (v->name, 32, "%s", Blist[spca50x->bridge].name); break; } } v->flags = 0; v->tuners = 0; v->type = VIDEO_TYPE_CAMERA;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) if(copy_to_user(arg,v,sizeof(struct video_channel))) return -EFAULT;#endif return 0; } case VIDIOCSCHAN: { /* There seems to be some confusion as to whether this is a struct video_channel or an int. This should be safe as the first element of video_channel is an int channel number and we just ignore the rest */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) struct video_channel *v = arg;#else struct video_channel k ; struct video_channel *v = &k; if(copy_from_user(v,arg,sizeof(struct video_channel))) return -EFAULT;#endif /* make compiler happy i Hope */ v->flags = 0; v->tuners = 0; v->type = VIDEO_TYPE_CAMERA; return 0; } case VIDIOCGPICT: {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) struct video_picture *p = arg;#else struct video_picture p1 ; struct video_picture *p = &p1;#endif p->depth = spca50x->frame[0].depth; p->palette = spca50x->format; PDEBUG (4, "VIDIOCGPICT: depth=%d, palette=%d", p->depth, p->palette); switch (spca50x->bridge) { case BRIDGE_ZC3XX: spca50x->brightness =zc3xx_getbrightness (spca50x); p->brightness = spca50x->brightness; p->contrast = spca50x->contrast; p->colour = spca50x->colour; break; case BRIDGE_SN9CXXX: spca50x->brightness = sn9cxxx_getbrightness(spca50x); sn9cxxx_getcontrast(spca50x); //spca50x->colour = sn9cxxx_getcolors(spca50x); p->brightness = spca50x->brightness; p->contrast = spca50x->contrast; p->colour = spca50x->colour; break; case BRIDGE_SPCA536: case BRIDGE_SPCA533: case BRIDGE_SPCA504: case BRIDGE_SPCA504B: case BRIDGE_SPCA504C: { p->colour = sp5xxfw2_getcolors(spca50x); p->whiteness = 0; p->contrast = sp5xxfw2_getcontrast(spca50x); p->brightness = spca50x_get_brightness (spca50x); p->hue = 0; PDEBUG (0, "color: 0x%02x contrast: 0x%02x brightness: 0x%02x hue: 0x%02x", p->colour, p->contrast, p->brightness, p->hue); break; } default: { /* default to not allowing any settings to change */ p->colour = spca50x->colour; p->whiteness = spca50x->whiteness; p->contrast = spca50x->contrast; p->brightness = spca50x->brightness; p->hue = spca50x->hue; break; } } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) if(copy_to_user(arg,p,sizeof(struct video_picture))) return -EFAULT;#endif return 0; } case VIDIOCSPICT: { int i;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) struct video_picture *p = arg;#else struct video_picture p1 ; struct video_picture *p = &p1; if(copy_from_user(p,arg,sizeof(struct video_picture))) return -EFAULT;#endif PDEBUG (4, "VIDIOCSPICT"); if (!spca5xx_get_depth (spca50x, p->palette)) return -EINVAL;if(spca50x->format != p->palette){/* FIXME test if the palette is available */ PDEBUG (4, "Setting depth=%d, palette=%d", p->depth, p->palette); /* change the output palette the input stream is the same*/ /* no need to stop the camera streaming and restart */ for (i = 0; i < SPCA50X_NUMFRAMES; i++) { spca50x->frame[i].depth = p->depth; spca50x->frame[i].format = p->palette; } spca50x->format = p->palette;} switch (spca50x->bridge) { case BRIDGE_SN9CXXX: spca50x->contrast = p->contrast; spca50x->brightness = p->brightness; sn9cxxx_setbrightness(spca50x); sn9cxxx_setcontrast(spca50x); break; case BRIDGE_ZC3XX: spca50x->contrast = p->contrast; spca50x->brightness = p->brightness; zc3xx_setbrightness (spca50x); break; case BRIDGE_SPCA536: case BRIDGE_SPCA533: case BRIDGE_SPCA504: case BRIDGE_SPCA504B: case BRIDGE_SPCA504C: { spca50x_set_brightness (spca50x, ((p->brightness >> 8) + 128) % 255); spca50x->contrast = p->contrast; spca50x->colour = p->colour; sp5xxfw2_setcolors(spca50x); sp5xxfw2_setcontrast(spca50x); p->whiteness = 0; break; } default: { /* default to not allowing any settings to change ?? */ p->colour = spca50x->colour; p->whiteness = spca50x->whiteness; p->contrast = spca50x->contrast; p->brightness = spca50x->brightness; p->hue = spca50x->hue; break; } } spca50x->contrast = p->contrast; spca50x->brightness = p->brightness; spca50x->colour = p->colour; spca50x->hue = p->hue; spca50x->whiteness = p->whiteness;#ifdef SPCA50X_ENABLE_EXPERIMENTAL spca50x->nstable = 0; spca50x->nunstable = 0;#endif /* SPCA50X_ENABLE_EXPERIMENTAL */ return 0; } case VIDIOCGCAPTURE: { int *vf = arg; PDEBUG (4, "VIDIOCGCAPTURE"); *vf = 0; // no subcapture return -EINVAL; } case VIDIOCSCAPTURE: {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) struct video_capture *vc = arg;#else struct video_capture vc1 ; struct video_capture *vc = &vc1; if(copy_from_user(vc,arg,sizeof(struct video_capture))) return -EFAULT;#endif if (vc->flags) return -EINVAL; if (vc->decimation) return -EINVAL; return -EINVAL; } case VIDIOCSWIN: { int result;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) struct video_window *vw = arg;#else struct video_window vw1 ; struct video_window *vw = &vw1; if(copy_from_user(vw,arg,sizeof(struct video_window))) return -EFAULT;#endif PDEBUG (3, "VIDIOCSWIN: width=%d, height=%d, flags=%d", vw->width, vw->height, vw->flags); if (vw->x) return -EINVAL; if (vw->y) return -EINVAL; if (vw->width > (unsigned int) spca50x->maxwidth) return -EINVAL; if (vw->height > (unsigned int) spca50x->maxheight) return -EINVAL; if (vw->width < (unsigned int) spca50x->minwidth) return -EINVAL; if (vw->height < (unsigned int) spca50x->minheight) return -EINVAL; result = spca5xx_restartMode(spca50x,vw->width,vw->height,spca50x->frame[0].format); if (result == 0) { spca50x->frame[0].width = vw->width; spca50x->frame[0].height = vw->height; } return result; } case VIDIOCGWIN: {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) struct video_window *vw = arg;#else struct video_window vw1 ; struct video_window *vw = &vw1;#endif memset (vw, 0, sizeof (struct video_window)); vw->x = 0; vw->y = 0; vw->width = spca50x->frame[0].width; vw->height = spca50x->frame[0].height; vw->flags = 0; PDEBUG (4, "VIDIOCGWIN: %dx%d", vw->width, vw->height);#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) if(copy_to_user(arg,vw,sizeof(struct video_capture))) return -EFAULT;#endif return 0; } case VIDIOCGMBUF: {#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) struct video_mbuf *vm=arg;#else struct video_mbuf vm1; struct video_mbuf *vm = &vm1;#endif int i; PDEBUG (2, "VIDIOCGMBUF: %p ",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -