V4L2应用程序开发-- 控制流程
使用摄像头时,我们可以调整很多参数,比如:
-
对于视频流本身:
-
设置格式:比如V4L2_PIX_FMT_YUYV、V4L2_PIX_FMT_MJPEG、V4L2_PIX_FMT_RGB565
-
设置分辨率:1024*768等
-
-
对于控制部分:
-
调节亮度
-
调节对比度
-
调节色度
-
2.1 APP接口
就APP而言,对于这些参数有3套接口:查询或枚举(Query/Enum)、获得(Get)、设置(Set)。
2.1.1 数据格式
以设置数据格式为例,可以先枚举:
还可以获得当前的格式:
也可以设置当前的格式:
2.1.3 其他参数
如果每一参数都提供一系列的ioctl cmd,那使用起来很不方便。
对于这些参数,APP使用对应ID来选中它,然后使用VIDIOC_QUERYCTRL、VIDIOC_G_CTRL、VIDIOC_S_CTRL来操作它。
不同参数的ID值不同。
以亮度Brightness为例,有如下调用方法:
-
查询:
获得当前值 :
2.2 理解接口
2.2.1 概念
以USB摄像头为例,它的内部结构如下:
一个USB摄像头必定有一个VideoControl接口,用于控制。有0个或多个VideoStreaming接口,用于传输视频。
在VideoControl内部,有多个Unit或Terminal,上一个Unit或Terminal的数据,流向下一个Unit或Terminal,多个Unit或Terminal组成一个完整的UVC功能设备。
2.2.2 操作方法
我们使用ioctl操作设备节点"/dev/video0"时,不同的ioctl操作的可能是VideoControl接口,或者VideoStreaming接口。
跟视频流相关的操作,比如:VIDIOC_ENUM_FMT、VIDIOC_G_FMT、VIDIOC_S_FMT、VIDIOC_STREAMON、VIDIOC_STREAMOFF,是操作VideoStreaming接口。
其他ioctl,大多都是操作VideoControl接口。
从底层驱动和硬件角度看,要操作VideoControl接口,需要指明:
-
entity:你要操作哪个Terminal或Unit,比如PU
-
Control Selector:你要操作entity里面的哪个控制项?比如亮度PU_BRIGHTNESS_CONTROL
-
控制项里哪些位:比如CT(Camera Terminal)里的CT_PANTILT_RELATIVE_CONTROL控制项对应32位的数据,其中前16位对应PAN控制(左右转动),后16位对应TILE控制(上下转动)
但是APP不关注这些细节,使用一个ID来指定entity、Control Selector、哪些位:
但是有了上述知识后,我们才能看懂mjpg-streamer的如下代码:
-
XU:使用比较老的UVC驱动时,需要APP传入厂家的XU信息;新驱动里可以解析出XU信息,无需APP传入