videodev.c
来自「omap3 linux 2.6 用nocc去除了冗余代码」· C语言 代码 · 共 2,112 行 · 第 1/4 页
C
2,112 行
break; } return cmd;}/* * Obsolete usercopy function - Should be removed soon */intvideo_usercopy(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg, int (*func)(struct inode *inode, struct file *file, unsigned int cmd, void *arg)){ char sbuf[128]; void *mbuf = NULL; void *parg = NULL; int err = -EINVAL; int is_ext_ctrl; size_t ctrls_size = 0; void __user *user_ptr = NULL; cmd = video_fix_command(cmd); is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS || cmd == VIDIOC_TRY_EXT_CTRLS); /* Copy arguments into temp kernel buffer */ switch (_IOC_DIR(cmd)) { case _IOC_NONE: parg = NULL; break; case _IOC_READ: case _IOC_WRITE: case (_IOC_WRITE | _IOC_READ): if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { parg = sbuf; } else { /* too big to allocate from stack */ mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL); if (NULL == mbuf) return -ENOMEM; parg = mbuf; } err = -EFAULT; if (_IOC_DIR(cmd) & _IOC_WRITE) if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) goto out; break; } if (is_ext_ctrl) { struct v4l2_ext_controls *p = parg; /* In case of an error, tell the caller that it wasn't a specific control that caused it. */ p->error_idx = p->count; user_ptr = (void __user *)p->controls; if (p->count) { ctrls_size = sizeof(struct v4l2_ext_control) * p->count; /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ mbuf = kmalloc(ctrls_size, GFP_KERNEL); err = -ENOMEM; if (NULL == mbuf) goto out_ext_ctrl; err = -EFAULT; if (copy_from_user(mbuf, user_ptr, ctrls_size)) goto out_ext_ctrl; p->controls = mbuf; } } /* call driver */ err = func(inode, file, cmd, parg); if (err == -ENOIOCTLCMD) err = -EINVAL; if (is_ext_ctrl) { struct v4l2_ext_controls *p = parg; p->controls = (void *)user_ptr; if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) err = -EFAULT; goto out_ext_ctrl; } if (err < 0) goto out;out_ext_ctrl: /* Copy results into user buffer */ switch (_IOC_DIR(cmd)) { case _IOC_READ: case (_IOC_WRITE | _IOC_READ): if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd))) err = -EFAULT; break; }out: kfree(mbuf); return err;}EXPORT_SYMBOL(video_usercopy);/* * open/release helper functions -- handle exclusive opens * Should be removed soon */int video_exclusive_open(struct inode *inode, struct file *file){ struct video_device *vfl = video_devdata(file); int retval = 0; mutex_lock(&vfl->lock); if (vfl->users) { retval = -EBUSY; } else { vfl->users++; } mutex_unlock(&vfl->lock); return retval;}EXPORT_SYMBOL(video_exclusive_open);int video_exclusive_release(struct inode *inode, struct file *file){ struct video_device *vfl = video_devdata(file); vfl->users--; return 0;}EXPORT_SYMBOL(video_exclusive_release);static void dbgbuf(unsigned int cmd, struct video_device *vfd, struct v4l2_buffer *p){ struct v4l2_timecode *tc=&p->timecode; dbgarg (cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, " "bytesused=%d, flags=0x%08d, " "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n", (p->timestamp.tv_sec/3600), (int)(p->timestamp.tv_sec/60)%60, (int)(p->timestamp.tv_sec%60), p->timestamp.tv_usec, p->index, prt_names(p->type, v4l2_type_names), p->bytesused, p->flags, p->field, p->sequence, prt_names(p->memory, v4l2_memory_names), p->m.userptr, p->length); dbgarg2 ("timecode= %02d:%02d:%02d type=%d, " "flags=0x%08d, frames=%d, userbits=0x%08x\n", tc->hours,tc->minutes,tc->seconds, tc->type, tc->flags, tc->frames, *(__u32 *) tc->userbits);}static inline void dbgrect(struct video_device *vfd, char *s, struct v4l2_rect *r){ dbgarg2 ("%sRect start at %dx%d, size= %dx%d\n", s, r->left, r->top, r->width, r->height);};static inline void v4l_print_pix_fmt (struct video_device *vfd, struct v4l2_pix_format *fmt){ dbgarg2 ("width=%d, height=%d, format=%c%c%c%c, field=%s, " "bytesperline=%d sizeimage=%d, colorspace=%d\n", fmt->width,fmt->height, (fmt->pixelformat & 0xff), (fmt->pixelformat >> 8) & 0xff, (fmt->pixelformat >> 16) & 0xff, (fmt->pixelformat >> 24) & 0xff, prt_names(fmt->field, v4l2_field_names), fmt->bytesperline, fmt->sizeimage, fmt->colorspace);};static int check_fmt (struct video_device *vfd, enum v4l2_buf_type type){ switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (vfd->vidioc_try_fmt_cap) return (0); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: if (vfd->vidioc_try_fmt_overlay) return (0); break; case V4L2_BUF_TYPE_VBI_CAPTURE: if (vfd->vidioc_try_fmt_vbi) return (0); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: if (vfd->vidioc_try_fmt_vbi_output) return (0); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: if (vfd->vidioc_try_fmt_vbi_capture) return (0); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (vfd->vidioc_try_fmt_video_output) return (0); break; case V4L2_BUF_TYPE_VBI_OUTPUT: if (vfd->vidioc_try_fmt_vbi_output) return (0); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: if (vfd->vidioc_try_fmt_output_overlay) return (0); break; case V4L2_BUF_TYPE_PRIVATE: if (vfd->vidioc_try_fmt_type_private) return (0); break; } return (-EINVAL);}static int __video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg){ struct video_device *vfd = video_devdata(file); void *fh = file->private_data; int ret = -EINVAL; if ( (vfd->debug & V4L2_DEBUG_IOCTL) && !(vfd->debug & V4L2_DEBUG_IOCTL_ARG)) { v4l_print_ioctl(vfd->name, cmd); } /*********************************************************** Handles calls to the obsoleted V4L1 API Due to the nature of VIDIOCGMBUF, each driver that supports V4L1 should implement its own handler for this ioctl. ***********************************************************/ /* --- streaming capture ------------------------------------- */ if (cmd == VIDIOCGMBUF) { struct video_mbuf *p=arg; memset(p, 0, sizeof(*p)); if (!vfd->vidiocgmbuf) return ret; ret=vfd->vidiocgmbuf(file, fh, p); if (!ret) dbgarg (cmd, "size=%d, frames=%d, offsets=0x%08lx\n", p->size, p->frames, (unsigned long)p->offsets); return ret; } /******************************************************** All other V4L1 calls are handled by v4l1_compat module. Those calls will be translated into V4L2 calls, and __video_do_ioctl will be called again, with one or more V4L2 ioctls. ********************************************************/ if (_IOC_TYPE(cmd)=='v') return v4l_compat_translate_ioctl(inode,file,cmd,arg, __video_do_ioctl); switch(cmd) { /* --- capabilities ------------------------------------------ */ case VIDIOC_QUERYCAP: { struct v4l2_capability *cap = (struct v4l2_capability*)arg; memset(cap, 0, sizeof(*cap)); if (!vfd->vidioc_querycap) break; ret=vfd->vidioc_querycap(file, fh, cap); if (!ret) dbgarg (cmd, "driver=%s, card=%s, bus=%s, " "version=0x%08x, " "capabilities=0x%08x\n", cap->driver,cap->card,cap->bus_info, cap->version, cap->capabilities); break; } /* --- priority ------------------------------------------ */ case VIDIOC_G_PRIORITY: { enum v4l2_priority *p=arg; if (!vfd->vidioc_g_priority) break; ret=vfd->vidioc_g_priority(file, fh, p); if (!ret) dbgarg(cmd, "priority is %d\n", *p); break; } case VIDIOC_S_PRIORITY: { enum v4l2_priority *p=arg; if (!vfd->vidioc_s_priority) break; dbgarg(cmd, "setting priority to %d\n", *p); ret=vfd->vidioc_s_priority(file, fh, *p); break; } /* --- capture ioctls ---------------------------------------- */ case VIDIOC_ENUM_FMT: { struct v4l2_fmtdesc *f = arg; enum v4l2_buf_type type; unsigned int index; index = f->index; type = f->type; memset(f,0,sizeof(*f)); f->index = index; f->type = type; switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (vfd->vidioc_enum_fmt_cap) ret=vfd->vidioc_enum_fmt_cap(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: if (vfd->vidioc_enum_fmt_overlay) ret=vfd->vidioc_enum_fmt_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: if (vfd->vidioc_enum_fmt_vbi) ret=vfd->vidioc_enum_fmt_vbi(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: if (vfd->vidioc_enum_fmt_vbi_output) ret=vfd->vidioc_enum_fmt_vbi_output(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: if (vfd->vidioc_enum_fmt_vbi_capture) ret=vfd->vidioc_enum_fmt_vbi_capture(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (vfd->vidioc_enum_fmt_video_output) ret=vfd->vidioc_enum_fmt_video_output(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: if (vfd->vidioc_enum_fmt_vbi_output) ret=vfd->vidioc_enum_fmt_vbi_output(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: if (vfd->vidioc_enum_fmt_output_overlay) ret=vfd->vidioc_enum_fmt_output_overlay(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: if (vfd->vidioc_enum_fmt_type_private) ret=vfd->vidioc_enum_fmt_type_private(file, fh, f); break; } if (!ret) dbgarg (cmd, "index=%d, type=%d, flags=%d, " "pixelformat=%c%c%c%c, description='%s'\n", f->index, f->type, f->flags, (f->pixelformat & 0xff), (f->pixelformat >> 8) & 0xff, (f->pixelformat >> 16) & 0xff, (f->pixelformat >> 24) & 0xff, f->description); break; } case VIDIOC_G_FMT: { struct v4l2_format *f = (struct v4l2_format *)arg; enum v4l2_buf_type type=f->type; memset(&f->fmt.pix,0,sizeof(f->fmt.pix)); f->type=type; /* FIXME: Should be one dump per type */ dbgarg (cmd, "type=%s\n", prt_names(type, v4l2_type_names)); switch (type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (vfd->vidioc_g_fmt_cap) ret=vfd->vidioc_g_fmt_cap(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd,&f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: if (vfd->vidioc_g_fmt_overlay) ret=vfd->vidioc_g_fmt_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: if (vfd->vidioc_g_fmt_vbi) ret=vfd->vidioc_g_fmt_vbi(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: if (vfd->vidioc_g_fmt_vbi_output) ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: if (vfd->vidioc_g_fmt_vbi_capture) ret=vfd->vidioc_g_fmt_vbi_capture(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (vfd->vidioc_g_fmt_video_output) ret=vfd->vidioc_g_fmt_video_output(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: if (vfd->vidioc_g_fmt_output_overlay) ret=vfd->vidioc_g_fmt_output_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: if (vfd->vidioc_g_fmt_vbi_output) ret=vfd->vidioc_g_fmt_vbi_output(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: if (vfd->vidioc_g_fmt_type_private) ret=vfd->vidioc_g_fmt_type_private(file, fh, f); break; } break; } case VIDIOC_S_FMT: { struct v4l2_format *f = (struct v4l2_format *)arg; /* FIXME: Should be one dump per type */ dbgarg (cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: v4l_print_pix_fmt(vfd,&f->fmt.pix); if (vfd->vidioc_s_fmt_cap) ret=vfd->vidioc_s_fmt_cap(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: if (vfd->vidioc_s_fmt_overlay) ret=vfd->vidioc_s_fmt_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: if (vfd->vidioc_s_fmt_vbi) ret=vfd->vidioc_s_fmt_vbi(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: if (vfd->vidioc_s_fmt_vbi_output) ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: if (vfd->vidioc_s_fmt_vbi_capture) ret=vfd->vidioc_s_fmt_vbi_capture(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (vfd->vidioc_s_fmt_video_output) ret=vfd->vidioc_s_fmt_video_output(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: if (vfd->vidioc_s_fmt_output_overlay) ret=vfd->vidioc_s_fmt_output_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: if (vfd->vidioc_s_fmt_vbi_output) ret=vfd->vidioc_s_fmt_vbi_output(file, fh, f); break; case V4L2_BUF_TYPE_PRIVATE: if (vfd->vidioc_s_fmt_type_private) ret=vfd->vidioc_s_fmt_type_private(file, fh, f); break; } break; } case VIDIOC_TRY_FMT: { struct v4l2_format *f = (struct v4l2_format *)arg; /* FIXME: Should be one dump per type */ dbgarg (cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); switch (f->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: if (vfd->vidioc_try_fmt_cap) ret=vfd->vidioc_try_fmt_cap(file, fh, f); if (!ret) v4l_print_pix_fmt(vfd,&f->fmt.pix); break; case V4L2_BUF_TYPE_VIDEO_OVERLAY: if (vfd->vidioc_try_fmt_overlay) ret=vfd->vidioc_try_fmt_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_CAPTURE: if (vfd->vidioc_try_fmt_vbi) ret=vfd->vidioc_try_fmt_vbi(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT: if (vfd->vidioc_try_fmt_vbi_output) ret=vfd->vidioc_try_fmt_vbi_output(file, fh, f); break; case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: if (vfd->vidioc_try_fmt_vbi_capture) ret=vfd->vidioc_try_fmt_vbi_capture(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: if (vfd->vidioc_try_fmt_video_output) ret=vfd->vidioc_try_fmt_video_output(file, fh, f); break; case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: if (vfd->vidioc_try_fmt_output_overlay) ret=vfd->vidioc_try_fmt_output_overlay(file, fh, f); break; case V4L2_BUF_TYPE_VBI_OUTPUT: if (vfd->vidioc_try_fmt_vbi_output)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?