3. 查询视频设备属性
任务目标
编写一个Linux用户空间程序,通过V4L2的VIDIOC_QUERYCAP ioctl查询指定视频设备的 capabilities,判断该设备是否为视频捕获设备(V4L2_CAP_VIDEO_CAPTURE),并输出设备名称(card)与驱动信息(driver)。
环境与依赖
- Linux系统(内核已启用V4L2框架)
- 开发头文件:
libv4l-dev(Debian/Ubuntu)或v4l-utils包中的头文件 - 编译工具:
gcc - 测试设备:
/dev/video0(若不存在,可使用v4l2loopback虚拟设备)
关键完整代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
int main(int argc, char *argv[]) {
const char *dev_path = (argc > 1) ? argv[1] : "/dev/video0";
int fd = open(dev_path, O_RDWR);
if (fd < 0) {
perror("open");
return 1;
}
struct v4l2_capability cap;
memset(&cap, 0, sizeof(cap));
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
perror("VIDIOC_QUERYCAP");
close(fd);
return 1;
}
printf("设备路径: %s\n", dev_path);
printf("驱动名称: %s\n", cap.driver);
printf("设备名称: %s\n", cap.card);
printf("总线信息: %s\n", cap.bus_info);
printf("驱动版本: %u.%u.%u\n",
(cap.version >> 16) & 0xFF,
(cap.version >> 8) & 0xFF,
cap.version & 0xFF);
printf("设备能力: 0x%08X\n", cap.capabilities);
if (cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
printf("判定结果: 是视频捕获设备\n");
} else {
printf("判定结果: 不是视频捕获设备\n");
}
close(fd);
return 0;
}
编译与运行
# 编译
gcc -o querycap querycap.c
# 运行(默认查询 /dev/video0)
./querycap
# 指定设备
./querycap /dev/video1
验证方法
运行程序后,观察输出:
- 若设备存在且支持V4L2,程序会打印驱动名称、设备名称、总线信息、驱动版本及设备能力值。
- 若设备是摄像头(如USB摄像头),
cap.capabilities应包含V4L2_CAP_VIDEO_CAPTURE(值为0x00000001),程序输出“是视频捕获设备”。 - 若查询的是非捕获设备(如VBI设备或仅输出设备),则输出“不是视频捕获设备”。
- 若设备路径不存在或无权限,程序会通过
perror打印错误原因并退出。
可通过 v4l2-ctl --list-devices 命令交叉验证设备名称与驱动信息是否一致。
常见问题
- 打开设备失败:确认设备节点存在且当前用户有读写权限(可尝试
sudo运行)。 - ioctl 返回错误:确认设备是V4L2设备而非其他类型(如DVB),可用
v4l2-ctl --info -d /dev/videoX检查。 - 无物理摄像头:安装
v4l2loopback内核模块创建虚拟设备:sudo modprobe v4l2loopback,然后重新运行程序。