UVC工作原理:
关于UVC的实现方式,UVC驱动分为设备端和主机端,根据 linux 内核的实现,貌似设备端的实现源码头部的版本信息描述为“USB Video Class Gadget driver”,而主机端的实现则是“USB Video Class driver”。并且主机端和设备都都和和v4l2框架挂接,根据下图可以看到这一点。
UVC设备驱动初始化入口为uvcg_video_init
而主机端驱动初始化入口为,至于为什么这么确定他是主机端驱动,是因为linux/drivers/meida/usb/uvc/目录的编译是依赖CONFIG_USB_VIDEO_CLASS宏配置的,而这个宏配置是主机端驱动的配置项.
注册用于发送的/dev/video设备节点:
而主机中也有一个一模一样的接口:
注册了主机的端的IOCTL
和主机端恰恰相反,这里的videoc_qbuf是向USB接口发送编码帧,而且dqbuf是获取空帧。
buffer_done也会被调用,它是在USB传输完成后,生成空帧的。
在传输结束后,USB协议栈调用complete接口
通过uvcg_queue_cancel接口,调用vb2_buffer_done,将空帧还给V4L2
所以看起来,作为设备端的UVCgadget驱动和作为主机端的UVC驱动buffer的语义相同,但数据流是相反的,dqbuf在主机端是有用像素数据,qbuf是空帧,buffer_done是帧数据,而在设备端,qbuf是有效编码数据,要通过usb发送出去的,而且dqbuf是空帧,buffer_done表示USB传输完了,这个buffer可以被重新填充了,是无效数据,所以恰好是相反的两个过程。
也就是说/dev/videoX节点,既可以做输入源,也可以做输出sink,用户层面可以将数据通过/dev/videoX发送出去,而buffer 的使用以及vb2_buffer_done在这两种情况下的作用恰好是对偶的。
关于UVC驱动分为主机端和设备端的另一个铁证是VIDIOC_QUERYCAP调用说明的,在使用V4L2设备之前,应用一般会调用VIDIOC_QUERYCAP去探测video设备的capability,返回的主要功能有两类,一类是
V4L2_CAP_STREAMING/V4L2_CAP_VIDEO_CAPTURE,代表UVC主机驱动端,抓取数据流的能力,比如接UVC摄像头的PC主机端UVC驱动。
当然还有另外一个,V4L2_CAP_VIDEO_OUTPUT,这个代表的是video output device, 设备节点可以输出视频帧,对应的是UVC设备端驱动,比如UVC摄像头端驱动。
关于其它UVC摄像头的capability信息可以参考博客
配置:
如若支持UVC设备端的功能,需要打开以下配置项:
使用流程:
对于UVC设备端的应用来说,系统中同时存在着两类UVC设备,一类是CAPTURE类型的,负责连接摄像头抓取图像,另一边则是OUTPUT类型的V4L2设备,它是将压缩格式的图像通过USB发送出去。中间通过用户层软件连接,用户软件的作用则主要是进行编码操作。
对一个模块建立宏观印象最好的一个方式是看应用如何使用它,来看一个UVC设备端的具体应用实现:
总结:
在运行Linux-4.15之后内核的主机上,插入一个 usb 摄像头,会出现两个 /dev/video*,这不是 bug,而是V4L2的特性,更多的讨论见此文章:
阅读UVC实现框架代码的时候,可以主机端和设备端驱动对照着看,这样更能加深理解整个通路。
UVC gadget驱动的实现框架如下图所示:
结束!
标签:USB,主机,原理,驱动,UVC,V4L2,设备 From: https://blog.51cto.com/u_15899439/5911838