首页 > 代码库 > 远程视频监控之驱动篇(摄像头)

远程视频监控之驱动篇(摄像头)

        转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/38515279


一.linux摄像头驱动框架


二.UVC介绍

       UVC是USB video class的简称,图像产品在不需要安装任何的驱动程序下即插即用。我们通常所说的免驱摄像头。

免驱并不是说没有,而是大家硬件上都支持UVC这个规范,所以linux中有了一个通用的驱动。所以你再插上你的摄像头就不用下载驱动了,自动加载。


三.驱动分析

     1.驱动的注册:

             驱动在\drivers\media\video\uvc\uvc_driver.c 大家对照着看。

入口函数:uvc_init(void)

                     分配和设置: struct uvc_driver uvc_driver

                                    注册: usb_register(&uvc_driver.driver);


我们下面将主要把经历放在分配和设置中

struct uvc_driver uvc_driver = {
	.driver = {
		.name		= "uvcvideo",
		.probe		= uvc_probe,
		.disconnect	= uvc_disconnect,
		.suspend	= uvc_suspend,
		.resume		= uvc_resume,
		.reset_resume	= uvc_reset_resume,
		.id_table	= uvc_ids,
		.supports_autosuspend = 1,
	},
};


    我们先从简单的开始支持的id列表:.id_table    = uvc_ids,

    /* Generic USB Video Class */
    { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },  //通用USB类,控制接口


    如果有摄像头插入并且在支持(符合UVC规范),自动调用  .probe        = uvc_probe,

         v4l2_device_register(&intf->dev, &dev->vdev)   //相当于初始化的作用

         uvc_register_chains(dev)

                uvc_register_terms(dev, chain)

                      uvc_register_video(dev, stream);

                               video_device_alloc();                                                                //分配

                               vdev->v4l2_dev = &dev->vdev;                                                //设置
                               vdev->fops = &uvc_fops;
                               vdev->release = uvc_release;
                               strlcpy(vdev->name, dev->name, sizeof vdev->name);               

                               video_register_device(vdev, VFL_TYPE_GRABBER, -1);       //注册device向V4L2

                                      __video_register_device(vdev, type, nr, 1, vdev->fops->owner)

                                               vdev->cdev = cdev_alloc();                                                                      //分配

                                               vdev->cdev->ops = &v4l2_fops;                                                               //设置

                                               cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1)     //注册字符设备

         这就是从摄像头插入的一系列注册过程


     2.应用程序的调用

           上面我们是从底层驱动逆推到了注册字符驱动,下面我们将从应用层起来看整个调用过程

a.   open
app:     open("/dev/video0",....)
---------------------------------------------------
drv:     v4l2_fops.v4l2_open
            vdev = video_devdata(filp);  // 根据次设备号从数组中得到video_device
            vdev->fops->open               //即调用uvc_fops的open

                   uvc_v4l2_open

b.    read
app:    read ....
---------------------------------------------------
drv:    v4l2_fops.v4l2_read
            struct video_device *vdev = video_devdata(filp);
             vdev->fops->read(filp, buf, sz, off);           //即调用uvc_fops的read

                   uvc_v4l2_read

c.    ioctl
app:   ioctl
----------------------------------------------------
drv:   v4l2_fops.unlocked_ioctl
            v4l2_ioctl
                struct video_device *vdev = video_devdata(filp);
                vdev->fops->unlocked_ioctl(filp, cmd, arg);                //即调用uvc_fops的unlocked_ioctl
                     uvc_v4l2_ioctl

                             video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl);    

                                         uvc_v4l2_do_ioctl                            

                                              struct video_device *vdev = video_devdata(file)

                                                      根据APP传过来的命令标识符进行相应的操作具体操作有很多,我就不详细的讲了

附上常用命令标识符供大家看代码时候参考:

  1. VIDIOC_REQBUFS:分配内存
  2. VIDIOC_QUERYBUF:把VIDIOC_REQBUFS中分配的数据缓存转换成物理地址
  3. VIDIOC_QUERYCAP:查询驱动功能
  4. VIDIOC_ENUM_FMT:获取当前驱动支持的视频格式
  5. VIDIOC_S_FMT:设置当前驱动的频捕获格式
  6. VIDIOC_G_FMT:读取当前驱动的频捕获格式
  7. VIDIOC_TRY_FMT:验证当前驱动的显示格式
  8. VIDIOC_CROPCAP:查询驱动的修剪能力
  9. VIDIOC_S_CROP:设置视频信号的边框
  10. VIDIOC_G_CROP:读取视频信号的边框
  11. VIDIOC_QBUF:把数据从缓存中读取出来
  12. VIDIOC_DQBUF:把数据放回缓存队列
  13. VIDIOC_STREAMON:开始视频显示函数
  14. VIDIOC_STREAMOFF:结束视频显示函数
  15. VIDIOC_QUERYSTD:检查当前视频设备支持的标准,例如PAL或NTSC。
   

参考:韦东山视频第三期