UVC设备也是一个usb设备,在uvc_driver.c中的init函数会调用usb_register注册,根据id_table发送可支持的设备后调用probe函数,其会去uvc_register_chains注册所有uvc_device,前面说的根据id_table匹配的过程是usb_bus总线,uvc是另一个东西了

vivi.c是一个摄像头驱动模板或者实例,安装vivi模块后会产生一个虚拟的摄像头,使用应用程序可以获得其提供的虚拟数据并显示。

vivi_init
  vivi_create_instance
    v4l2_device_register // 不是主要, 只是用于初始化一些东西,比如自旋锁、引用计数

    hdl = &dev->ctrl_handler;//hdl 是用于保存子设备控制方法集的结构体,对于视频设备这些ctrls包括设置亮度、饱和度、对比度和 清晰度                                                                                      等,用链表的方式来保存ctrls,可以通过v4l2_ctrl_new_std函数向链表添加ctrls。在下面的代码中用到了这个函数。
    video_device_alloc 
    // 设置
      1. vfd:
        .fops = &vivi_fops,
        .ioctl_ops = &vivi_ioctl_ops,
        .release = video_device_release,
      2.
        vfd->v4l2_dev = &dev->v4l2_dev;
      3. 设置"ctrl属性",并挂接到hdl的链表上(用于应用的ioctl)://后续会根据这里设置的属性调用真正的ioctl,用户空间可以通过ioctl的VIDIOC_S_CTRL指令调用到hdl(v4l2_ctrl_handler结构体)
        v4l2_ctrl_handler_init(hdl, 11);
        dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
          V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
        dev->brightness = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
          V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
        dev->contrast = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
          V4L2_CID_CONTRAST, 0, 255, 1, 16);

    video_register_device(video_device, type:VFL_TYPE_GRABBER, nr)
      __video_register_device
        vdev->cdev = cdev_alloc();
        vdev->cdev->ops = &v4l2_fops;//真正的fops是vivi_fops
        cdev_add

        video_device[vdev->minor] = vdev;//把包含真正fops结构体的变量放入video_device数组,以次设备号为下标

          if (vdev->ctrl_handler == NULL)
            vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;

分析vivi.c的open,read,write,ioctl过程
1. open
app: open("/dev/video0",....)
---------------------------------------------------
drv: v4l2_fops.v4l2_open
    vdev = video_devdata(filp); // 根据次设备号从数组中得到video_device
    ret = vdev->fops->open(filp);
      vivi_ioctl_ops.open
        v4l2_fh_open

2. read
app: read ....
---------------------------------------------------
drv: v4l2_fops.v4l2_read
    struct video_device *vdev = video_devdata(filp);
    ret = vdev->fops->read(filp, buf, sz, off);

3. ioctl
app: ioctl
----------------------------------------------------
drv: v4l2_fops.unlocked_ioctl
  v4l2_ioctl
    struct video_device *vdev = video_devdata(filp);
    ret = vdev->fops->unlocked_ioctl(filp, cmd, arg);
      video_ioctl2
        video_usercopy(file, cmd, arg, __video_do_ioctl);
          __video_do_ioctl
            struct video_device *vfd = video_devdata(file);
            根据应用传入的cmd来获得、设置"某些属性"

v4l2_ctrl_handler的使用过程:(v4l2_ctrl_handler是属性链表,在video_device_alloc被设置)
  __video_do_ioctl//往上面数5行,video_usercopy里面调用__video_do_ioctl这个函数,最终ioctrl会表用vivi_ioctl_ops结构体里面的ioctrl函数
    struct video_device *vfd = video_devdata(file);

    case VIDIOC_QUERYCTRL:
    {
      struct v4l2_queryctrl *p = arg;

      if (vfh && vfh->ctrl_handler)
        ret = v4l2_queryctrl(vfh->ctrl_handler, p);
      else if (vfd->ctrl_handler) // 在哪设置?在video_register_device中vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler,vdev->v4l2_dev在video_register_device前通过vfd->v4l2_dev = &dev->v4l2_dev复制,这里的dev是vivi_device,dev->v4l2_dev.ctrl_handler = hdl,这里的hdl就是vivi_init过程中在v4l2_ctrl_new_std里面被设置,vfd就是video_device结构体类型;ctrl_handler是v4l2_ctrl_handler

        ret = v4l2_queryctrl(vfd->ctrl_handler, p);
          // 根据ID在ctrl_handler里找到v4l2_ctrl,返回它的值,ID在v4l2_ctrl_new_std里面被设置

怎么写V4L2驱动?

1、分配、设置、注册V4L2_device  (v4l2_device_register,v4l2_device)(仅初始化,并提供一些属性参数供ioctl设置,辅助作用,属性在这个v4l2_ctrl_handler里面被管理,v4l2_ctrl来表示属性,v4l2_ctrl_new_std来创建v4l2_ctrl,放入v4l2_ctrl_handler链表)

2、分配video_device(video_device_alloc)

3、设置 video_device()

  vfd->v4l2_dev = &dev->v4l2_dev;//把video_device和第一部里面设置的属性关联起来,后面会用来ioctl设置属性,比如亮度、饱和度等参数

  fops=真真的v4l2_file_operations,v4l2_fops中的read等会指向这里设置的fops;

  ioctl_ops=真真的ioctl函数,v4l2_fops->unlocked_ioctl调用v4l2_file_operations->unlocked_ioctl,调用ioctl_ops

13、虚拟驱动vivi.c注册过程分析及怎么写V4L2驱动及启动过程的更多相关文章

  1. 2.1 摄像头V4L2驱动框架分析

    学习目标:学习V4L2(V4L2:vidio for linux version 2)摄像头驱动框架,分析vivi.c(虚拟视频硬件相关)驱动源码程序,总结V4L2硬件相关的驱动的步骤:  一.V4L ...

  2. v4l2驱动编写篇【转】

    转自:http://blog.csdn.net/michaelcao1980/article/details/53008418 大部分所需的信息都在这里.作为一个驱动作者,当挖掘头文件的时候,你可能也 ...

  3. 通过虚拟驱动vivi分析摄像头驱动

    Linux摄像头驱动学习之:(二)通过虚拟驱动vivi分析摄像头驱动 一.通过指令 "strace -o xawtv.log xawtv" 得到以下调用信息: // 1~7都是在v ...

  4. 彻底分析虚拟视频驱动vivi(三)

    在Ubuntu系统中接上usb摄像头设备时,系统会自动安装对应的usb设备驱动程序.我们现在要使用自己编译的vivi驱动,该怎么办呢? 1.先安装系统自带的vivi驱动和它所依赖的所有驱动:sudo ...

  5. V4L2(二)虚拟摄像头驱动vivi深入分析【转】

    转自:http://www.cnblogs.com/tureno/articles/6694463.html 转载于: http://blog.csdn.net/lizuobin2/article/d ...

  6. 初始v4l2(六)-------根据虚拟驱动vivi的使用彻底分析摄像头驱动

    前面的几篇文章已经分析了v4l2的框架,对框架的分析是比较粗浅的,能基本清楚函数之间的调用过程.但是很多内容并没有分析,比如说里面有很多ioctl,并没有分析哪些ioctl是必须的,也没有分析如何从应 ...

  7. 20、在PC上测试虚拟驱动vivi

    在Ubuntu上测试 准备工作:安装xawtv(是一个应用程序,用来在Ubuntu上捕获摄像头数据并显示)sudo apt-get install xawtv 源码xawtv-3.95.tar.gz: ...

  8. (四) 虚拟摄像头vivi体验

    目录 虚拟摄像头vivi体验 源码下载 修改Makefile 安装xawtv 测试体验 title: 虚拟摄像头vivi体验 date: 2019/4/23 19:20:00 toc: true -- ...

  9. 虚拟摄像头vivi的测试(二)

    (前一部分的基础操作来源于作者:LingXiaokai 的 Ubuntu 9.10 下如何使用笔记本摄像头以及虚拟摄像头vivi的测试) 自己仅对实际操作中需要注意的点进行阐述 一.先在Ubuntu ...

随机推荐

  1. Kinect 开发 —— Kinect for windows SDK

    开发 —— 基本的SDK和Windows 编程技巧(彩色图像视频流,深度图像视频流的采集,骨骼跟踪,音频处理,语音识别API) 深度数据,就是Kinect的精髓和灵魂,很多问题都转换为深度图像的模式识 ...

  2. 今日SGU 5.8

    SGU 109 题意:一个n*n的矩形,起点在1,1然后每次给你一个操作,走ki步,然后你可以删除任意一个点这次步走不到的,删了就不能再走了,然后问构造这种操作,使得最后删除n*n-1个点 剩下一个点 ...

  3. 构建自己的AngularJS - 作用域和Digest(一)

    作用域 第一章 作用域和Digest(一) Angular作用域是简单javascript对象,因此你能够像对其它对象一样加入属性.然而,他们也有一些额外的功能:用于观測数据结构的变化.这样的观察能力 ...

  4. Android 关于expandableListView childrenView 点击改变颜色

    1.点击后改变颜色并保持颜色改变状态: <?xml version="1.0" encoding="utf-8"?> <selector xm ...

  5. 关于编译com工程的一些体会

    作者:朱金灿 来源:http://blog.csdn.net/clever101 今天发现com的编译的一个重要一步是微软提供的midl工具将其中的idl文件生成一个头文件.c文件(即IID文件)和代 ...

  6. Activity启动模式的深入分析

    网上关于Activity启动模式的文章许多.可是看起来都千篇一律,看完之后我们都能理解这4种启动模式.只是官方api对singleTask这个启动模式解释有些争议,导致我事实上并没有真正理解这几种模式 ...

  7. 89.hash算法实现CSDN密码处理

    初始化,数据的行数,hash链表结构体,存储头结点 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdl ...

  8. HDU 4508 湫湫系列故事——减肥记I (2013腾讯编程马拉松初赛第一场)

    http://acm.hdu.edu.cn/showproblem.php?pid=4508 题目大意: 给定一些数据. 每组数据以一个整数n开始,表示每天的食物清单有n种食物.  接下来n行,每行两 ...

  9. 洛谷 P2790 ccj与zrz之积木问题

    P2790 ccj与zrz之积木问题 题目背景 ccj和zrz无聊到了玩起了搭积木...(本题选自uva101,翻译来自<算法竞赛入门经典2>) 题目描述 从左到右有n个木块,编号从0到n ...

  10. a-star算法

    http://blog.csdn.net/shanshanpt/article/details/8977512 这篇文章讲得不错. 所谓的启发函数,所谓权值之类(此处所谓的权值就是路劲的长度).YES ...