• Linux摄像头驱动学习之:(一)V4L2_框架分析


    这段时间开始搞安卓camera底层驱动了,把以前的的Linux视频驱动回顾一下,本篇主要概述一下vfl2(video for linux 2).

    一. V4L2框架: video for linux version 2
    虚拟视频驱动vivi.c分析:
    1.分配video_device
    2.设置
    3.注册:video_register_device

    vivi_init
        vivi_create_instance
            v4l2_device_register   // 不是主要, 只是用于初始化一些东西,比如自旋锁、引用计数
            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属性"(用于APP的ioctl):
                 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;
                    cdev_add
                   
                    video_device[vdev->minor] = vdev;

              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);
                                            根据APP传入的cmd来获得、设置"某些属性"v4l2_ctrl_handler的使用过程:
        __video_do_ioctl
            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
           ret = v4l2_queryctrl(vfd->ctrl_handler, p);
                       // 根据ID在ctrl_handler里找到v4l2_ctrl,返回它的值...}
                                                    
                                                      

    [18721.327983] usb 2-1: USB disconnect, address 4
    [18724.929301] usb 2-1: new full speed USB device using uhci_hcd and address 5
    [18725.196200] usb 2-1: configuration #1 chosen from 1 choice
    [18725.204999] uvcvideo: Found UVC 1.00 device <unnamed> (1b3b:2977)
    [18725.222065] input: UVC Camera (1b3b:2977) as /devices/pci0000:00/0000:00:07.2/usb2/2-1/2-1:1.0/input/input7
    [25252.578719] usb 2-1: USB disconnect, address 5

    由以上usb摄像头插入的dmesg打印信息,搜索UVC关键字得到相关代码:uvc.driver.c ->uvc_driver结构体->video_register_device方法。

    二、如何写v4l2驱动:

     ①构造、设置、注册: v4l2_device : v4l2_device_register, v4l2_device

     ②分配:video_device, video_device_alloc

     ③设置: a. vfd->v4l2_dev

         b. vfd: .fops = ***.open/read/write  <-上层app调用

              .ioctl_ops  <-驱动程序 v4l2_fops {open,read,write,"ioctl"}

           c.APP通过ioctl来设置,获得亮度 等信息。

        驱动程序: v4l2_ctrl : 属性。

           v4l2_ctrl_handler : 管理 ===>(1)初始化:v4l2_ctrl_handler_init

                            (2)设置:v4l2_ctrl_new_std , v4l2_ctrl_new_custom ,设置创建v4l2_ctrl并加入链表。

                              (3)跟vdev关联: v4l2_dev.ctrl_handler = hdl  

                              video_dev -> v4l2_dev.

         

    具体驱动代码的编写将在下篇继续....

  • 相关阅读:
    PL/SQL database character set(AL32UTF8) and Client character set(ZHS16GBK) are different
    pl sql 无法解析指定的连接标识符
    【转】几个常用的Oracle存储过程
    .NET 条件查询实现--类似网上商城宝贝搜索
    SQL Server 中大小写区分的处理
    .NET DataGrid 导出Excel 无分页
    C# 读书笔记之访问虚方法、重写方法和隐藏方法
    人工智能技术在中小学课堂中的应用
    dzzoffice协同办公平台与onlyoffice在线协作平台安装与部署
    一本通 确定进制
  • 原文地址:https://www.cnblogs.com/blogs-of-lxl/p/4946113.html
Copyright © 2020-2023  润新知