摄像头应用编程(一):使用v4l2-ctl、media-ctl采集摄像头数据

1、前言

本文将介绍如何使用v4l2-ctl、media-ctl工具采集UCV摄像头数据和MIPI摄像头数据。

2、v4l2-utils

v4l2-utils是一个用于 Linux 系统的工具包,包含一系列与 Video4Linux2 (V4L2) 框架相关的实用程序和库。它旨在帮助开发者、系统管理员和用户进行 V4L2 设备的管理、测试、配置和诊断。

2.1、主要组成部分

v4l2-ctl:

  • 用于操作和管理 V4L2 设备节点(如 /dev/videoX)。
  • 支持设置设备的格式(分辨率、像素格式等)、请求和管理缓冲区、控制视频流的启动和停止。

media-ctl:

  • 专注于管理媒体设备的拓扑结构,操作实体(entity)、接口(pad)和链接(link)。
  • 可以设置或查询设备之间的链接状态,定义数据流的路径。

开发库:

  • 包括 libv4l2 等库,提供对 V4L2 设备的编程支持。

3、采集UCV摄像头数据

UVC(USB Video Class)摄像头是一种遵循USB视频类标准的摄像头设备,广泛应用于多种场景,具有即插即用、高兼容性和无需额外驱动程序的特点。

对于USB摄像头来说,可以直接使用v4l2-ctl工具来采集数据。

3.1、查看USB摄像头节点

v4l2-ctl --list-devices

  • /dev/video*:视频捕获设备节点
  • /dev/media1:media子系统设备节点

3.2、查看摄像头支持的图像格式和分辨率

v4l2-ctl -d /dev/video10 --list-formats-ext

  • 支持MJPG和YUYV两种图像格式。

3.3、设置图像格式和分辨率

v4l2-ctl -d /dev/video0 --set-fmt-video=width=640,height=480,pixelformat=MJPG
v4l2-ctl -d /dev/video0 --set-parm=30
  • width, height:分辨率
  • pixelformat:图像格式

3.4、确认图像格式和分辨率

v4l2-ctl -d /dev/video10 --get-fmt-video

3.5、采集一帧图像

# 采集一帧图像
v4l2-ctl --verbose -d /dev/video10 --stream-mmap=4 --stream-skip=3 --stream-count=1 --stream-to=./01.jpg --stream-poll

# 采集一帧图像,同时指定图像格式和分辨率
v4l2-ctl --verbose -d /dev/video10 --set-fmt-video=width=640,height=480,pixelformat=MJPG --stream-mmap=4 --stream-skip=3 --stream-count=1 --stream-to=./01.jpg --stream-poll

4、采集MIPI摄像头数据

在Linux中,MIPI摄像头的通路相对复杂,因为MIPI摄像头涉及到传感器Sensor、硬件接口、ISP等多个模块。

对于内核中的MIPI摄像头驱动框架来说,引入了media子系统来管理各个entity。在应用层,可以使用media-ctl工具来操作和查询媒体控制器的拓扑结构,包括实体(entities)、接口(pads)和链接(links)。

下面以RK3566和MIPI OV8858摄像头举例。

4.1、查看MIPI摄像头的media节点

v4l2-ctl --list-devices

4.2、查看媒体控制器的拓扑结构

4.2.1、命令行查看拓扑结构

media-ctl -p -d /dev/media0
  • -p:打印媒体控制器的拓扑结构,包括实体、接口和链接。
  • -d /dev/media0:指定媒体控制器的设备节点为 /dev/media0
Media controller API version 5.10.198

Media device information
------------------------
driver          rkisp-vir0
model           rkisp0
serial
bus info
hw revision     0x0
driver version  5.10.198

Device topology
- entity 1: rkisp-isp-subdev (4 pads, 8 links)
            type V4L2 subdev subtype Unknown flags 0
            device node name /dev/v4l-subdev0
        pad0: Sink
                [fmt:SBGGR10_1X10/3264x2448 field:none
                 crop.bounds:(0,0)/3264x2448
                 crop:(0,0)/3264x2448]
                <- "rkisp-csi-subdev":1 [ENABLED]
                <- "rkisp_rawrd0_m":0 []
                <- "rkisp_rawrd2_s":0 []
        pad1: Sink
                <- "rkisp-input-params":0 [ENABLED]
        pad2: Source
                [fmt:YUYV8_2X8/3264x2448 field:none colorspace:smpte170m quantization:full-range
                 crop.bounds:(0,0)/3264x2448
                 crop:(0,0)/3264x2448]
                -> "rkisp_mainpath":0 [ENABLED]
                -> "rkisp_selfpath":0 [ENABLED]
                -> "rkisp_iqtool":0 [ENABLED]
        pad3: Source
                -> "rkisp-statistics":0 [ENABLED]

- entity 6: rkisp-csi-subdev (6 pads, 5 links)
            type V4L2 subdev subtype Unknown flags 0
            device node name /dev/v4l-subdev1
        pad0: Sink
                [fmt:SBGGR10_1X10/3264x2448 field:none]
                <- "rockchip-csi2-dphy1":1 [ENABLED]
        pad1: Source
                [fmt:SBGGR10_1X10/3264x2448 field:none]
                -> "rkisp-isp-subdev":0 [ENABLED]
        pad2: Source
                -> "rkisp_rawwr0":0 [ENABLED]
        pad3: Source
        pad4: Source
                -> "rkisp_rawwr2":0 [ENABLED]
        pad5: Source
                -> "rkisp_rawwr3":0 [ENABLED]

- entity 13: rkisp_mainpath (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video0
        pad0: Sink
                <- "rkisp-isp-subdev":2 [ENABLED]

- entity 19: rkisp_selfpath (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video1
        pad0: Sink
                <- "rkisp-isp-subdev":2 [ENABLED]

- entity 25: rkisp_rawwr0 (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video2
        pad0: Sink
                <- "rkisp-csi-subdev":2 [ENABLED]

- entity 31: rkisp_rawwr2 (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video3
        pad0: Sink
                <- "rkisp-csi-subdev":4 [ENABLED]

- entity 37: rkisp_rawwr3 (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video4
        pad0: Sink
                <- "rkisp-csi-subdev":5 [ENABLED]

- entity 43: rkisp_iqtool (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video5
        pad0: Sink
                <- "rkisp-isp-subdev":2 [ENABLED]

- entity 49: rkisp_rawrd0_m (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video6
        pad0: Source
                -> "rkisp-isp-subdev":0 []

- entity 55: rkisp_rawrd2_s (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video7
        pad0: Source
                -> "rkisp-isp-subdev":0 []

- entity 61: rkisp-statistics (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video8
        pad0: Sink
                <- "rkisp-isp-subdev":3 [ENABLED]

- entity 67: rkisp-input-params (1 pad, 1 link)
             type Node subtype V4L flags 0
             device node name /dev/video9
        pad0: Source
                -> "rkisp-isp-subdev":1 [ENABLED]

- entity 73: rockchip-csi2-dphy1 (2 pads, 2 links)
             type V4L2 subdev subtype Unknown flags 0
             device node name /dev/v4l-subdev2
        pad0: Sink
                [fmt:SBGGR10_1X10/3264x2448@10000/230000 field:none]
                <- "m00_b_ov8858 1-0036":0 [ENABLED]
        pad1: Source
                -> "rkisp-csi-subdev":0 [ENABLED]

- entity 76: m00_b_ov8858 1-0036 (1 pad, 1 link)
             type V4L2 subdev subtype Sensor flags 0
             device node name /dev/v4l-subdev3
        pad0: Source
                [fmt:SBGGR10_1X10/3264x2448@10000/230000 field:none]
                -> "rockchip-csi2-dphy1":0 [ENABLED]

以entity 76为例:

- entity 76: m00_b_ov8858 1-0036 (1 pad, 1 link)
             type V4L2 subdev subtype Sensor flags 0
             device node name /dev/v4l-subdev3
        pad0: Source
                [fmt:SBGGR10_1X10/3264x2448@10000/230000 field:none]
                -> "rockchip-csi2-dphy1":0 [ENABLED]
  • entity 76:代表一个实体,实体名为:m00_b_ov8858 1-0036。该实体有1个pad,1个link。
  • pad0: Source:pad代表端口,Source表明该端口为输出端口,如果是Sink则表明为输入端口。
  • -> "rockchip-csi2-dphy1":0:该端口连接至实体“rockchip-csi2-dphy1”的pad0。

4.2.2、生成拓扑图

将拓扑结构以Graphviz的.dot格式输出到文件media0.dot

media-ctl -d /dev/media0 --print-dot > media0.dot

安装Graphviz工具:

sudo apt install graphviz

使用Graphviz将.dot文件转换为PNG图片:

dot -Tpng media0.dot -o media0.png

4.3、配置链路

4.3.1、使能或关闭Sensor连接

关闭摄像头连接:

media-ctl -l '"m00_b_ov8858 1-0036":0 -> "rockchip-csi2-dphy1":0 [0]'
  • -l:启用或禁用链接。
  • [0]:0关闭,1使能。

使能摄像头连接:

media-ctl -l '"m00_b_ov8858 1-0036":0 -> "rockchip-csi2-dphy1":0 [1]'

4.3.2、设置路由

命令格式如下,这里暂不需要所以不演示:

media-ctl -r '"<source_entity>":<source_pad> -> "<sink_entity>":<sink_pad> [enable]'

4.4、video节点确认

MIPI摄像头对应的video节点为:video0、video1。

知道video节点后,剩下的操作都和操作UVC摄像头一样。

4.5、查看摄像头支持的图像格式和分辨率

v4l2-ctl -d /dev/video0 --list-formats-ext

4.6、采集一帧图像

v4l2-ctl --verbose -d /dev/video0 --set-fmt-video=width=640,height=480,pixelformat=NV21 --stream-mmap=4 --stream-skip=3 --stream-count=1 --stream-to=./video0.yuv --stream-poll

windows下使用yuv player.exe软件查看图像:

5、总结

参考文章:

ArmSoM-W3开发板 (RK3588) 之 USB摄像头图像预览_rk3588 usb摄像头-优快云博客

RK3576——MIPI CSI之v4l2-ctl、media-ctl命令分析-优快云博客

### 回答1: v4l2-ctl个命令行工具,用于对Video4Linux2 (V4L2)设备进行控制和调试。该工具的源代码可以在Linux内核源代码树中的/usr/src/linux-headers-<kernel-version>/tools/media/v4l2-utils/v4l2-ctl目录下找到。 v4l2-ctl的源代码主要包含了关于V4L2设备的控制和配置的功能实现。其中包括设备的打开和关闭、格式的设置、视频参数的设置以及缓冲区配置等。 在源代码中,核心的功能主要由v4l2-ctl.c文件实现。其中包含了命令行参数的解析和设备控制的实现代码。v4l2-ctl-util.c文件主要为工具提供了些常见的实用函数,如日志输出、时间戳计算和缓冲区地址转换等。 此外,在源代码中,还涉及了些相关的头文件和宏定义。例如,v4l2-ctl.h文件中包含了些用于V4L2控制的结构体、枚举和函数原型的定义;v4l2-ioctl.h则包含了些与ioctl系统调用相关的宏定义和结构体定义。 总之,v4l2-ctl的源代码提供了个基本的框架,可以方便地扩展和修改其功能,从而满足不同应用场景的需求。它也可以作为学习V4L2设备控制和驱动开发的案例参考。 ### 回答2: v4l2-ctl个基于 V4L2 接口的命令行工具,用于控制视频设备。其代码位于 Linux 内核源码的 drivers/media/v4l2-core/v4l2-ctl.c 文件中。 v4l2-ctl 主要功能包括列出和设置视频设备的属性(如亮度、对比度、饱和度等),获取并输出视频设备的参数以及测试视频设备的性能等。该工具实现了向设备发送 IOCTL 命令并读取响应数据的逻辑,因此可以将其视为 V4L2 接口的命令行接口。 在源码中,v4l2-ctl 主要由 main() 函数和系列辅助函数构成。其中,main() 函数主要负责解析用户输入的命令行参数,并调用相应的函数实现对视频设备的操作。辅助函数包括获取设备信息、列出和修改设备属性等,大部分代码都是基于 V4L2 的 IOCTL 接口实现的。 总之,v4l2-ctl 的源码并不复杂,但实现了对视频设备的基本控制和调试功能,为后续开发者提供了不少便利。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值