2. 摄像头设备打开与关闭
任务目标
本案例实现通过V4L2接口打开指定摄像头设备(/dev/video0),检查设备打开状态,并在使用完毕后正确关闭设备。核心是掌握open()/close()系统调用在V4L2设备上的标准用法及错误处理流程。
核心实现
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#define DEVICE_PATH "/dev/video0"
int main(void)
{
int fd = -1;
struct v4l2_capability cap;
/* 1. 打开设备 */
fd = open(DEVICE_PATH, O_RDWR);
if (fd < 0) {
fprintf(stderr, "打开 %s 失败: %s\n", DEVICE_PATH, strerror(errno));
return EXIT_FAILURE;
}
/* 2. 检查设备是否为有效的V4L2设备 */
memset(&cap, 0, sizeof(cap));
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) < 0) {
fprintf(stderr, "设备不支持V4L2: %s\n", strerror(errno));
close(fd);
return EXIT_FAILURE;
}
printf("设备打开成功\n");
printf("驱动名称: %s\n", cap.driver);
printf("设备名称: %s\n", cap.card);
printf("总线信息: %s\n", cap.bus_info);
/* 3. 检查是否支持视频采集 */
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
fprintf(stderr, "设备不支持视频采集\n");
close(fd);
return EXIT_FAILURE;
}
/* 4. 正常关闭设备 */
if (close(fd) < 0) {
fprintf(stderr, "关闭设备失败: %s\n", strerror(errno));
return EXIT_FAILURE;
}
printf("设备已正确关闭\n");
return EXIT_SUCCESS;
}
编译与运行
# 编译
gcc -o v4l2_open_close v4l2_open_close.c
# 运行(需要root权限或video组权限)
./v4l2_open_close
验证方法
满足以下条件即判定通过:
- 程序退出码为0,且依次输出“设备打开成功”“设备已正确关闭”
- 输出的驱动名称、设备名称与
v4l2-ctl --list-devices查询结果一致 - 若设备不存在或权限不足,程序输出对应
strerror错误信息并以非零码退出
关键说明
open()使用O_RDWR标志,确保后续可进行读写操作;若仅查询能力可用O_RDONLYVIDIOC_QUERYCAP是验证设备是否为V4L2设备的标准方法,避免对非摄像头设备误操作- 关闭设备后应将
fd置为-1,防止悬空指针误用(本示例直接退出,实际工程中需注意) - 错误处理覆盖了打开失败、非V4L2设备、不支持采集、关闭失败四种典型场景