举例说明如何在linux下检测摄像头设备具备的功能

假设摄像头设备文件为/dev/video1 ,下面是一个专门用于检测 /dev/video1 设备能力的简化程序。这个程序将打印出设备的所有能力、格式和其他相关信息,以帮助你了解设备支持的功能。

检测 /dev/video1 设备能力的程序

复制代码
#include <fcntl.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <android/log.h>

#define LOG_TAG "DeviceCapabilityCheck"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)

// 定义一个宏来检查特定的能力是否被设置
#define CHECK_CAPABILITY(capability) \
    if (cap.capabilities & capability) { \
        LOGD(" - " #capability); \
    }

int xioctl(int fh, int request, void *arg) {
    int r;
    do {
        r = ioctl(fh, request, arg);
    } while (r == -1 && ((errno == EINTR) || (errno == EAGAIN)));
    if (r == -1) {
        perror("ioctl failed");
        exit(EXIT_FAILURE);
    }
    return r;
}

void print_supported_pixel_formats(int fd) {
    struct v4l2_fmtdesc fmtdesc;
    memset(&fmtdesc, 0, sizeof(fmtdesc));
    fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; // 使用多平面类型

    LOGD("Supported pixel formats:");
    int index = 0;
    while (true) {
        fmtdesc.index = index++;
        if (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == -1) {
            if (errno == EINVAL) break; // 没有更多的格式了
            perror("VIDIOC_ENUM_FMT failed");
            return;
        }
        LOGD(" - %s (0x%08x)", fmtdesc.description, fmtdesc.pixelformat);
    }
}

int main() {
    const char *dev_name = "/dev/video1";
    LOGD("Checking capabilities for device %s", dev_name);

    int fd = open(dev_name, O_RDWR);
    if (fd == -1) {
        perror("Cannot open device");
        return EXIT_FAILURE;
    }

    // 查询设备能力
    struct v4l2_capability cap;
    if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
        perror("Querying capabilities failed");
        close(fd);
        return EXIT_FAILURE;
    }

    LOGD("Device capabilities: 0x%08x", cap.capabilities);
    LOGD("Device bus info: %s", cap.bus_info);
    LOGD("Device driver: %s", cap.driver);
    LOGD("Device card: %s", cap.card);

    LOGD("Device capabilities detailed:");
    CHECK_CAPABILITY(V4L2_CAP_VIDEO_CAPTURE);
    CHECK_CAPABILITY(V4L2_CAP_VIDEO_CAPTURE_MPLANE); // 添加对多平面的支持检查
    CHECK_CAPABILITY(V4L2_CAP_VIDEO_OUTPUT);
    CHECK_CAPABILITY(V4L2_CAP_VIDEO_OVERLAY);
    CHECK_CAPABILITY(V4L2_CAP_VBI_CAPTURE);
    CHECK_CAPABILITY(V4L2_CAP_VBI_OUTPUT);
    CHECK_CAPABILITY(V4L2_CAP_SLICED_VBI_CAPTURE);
    CHECK_CAPABILITY(V4L2_CAP_SLICED_VBI_OUTPUT);
    CHECK_CAPABILITY(V4L2_CAP_RDS_CAPTURE);
    CHECK_CAPABILITY(V4L2_CAP_VIDEO_OUTPUT_OVERLAY);
    CHECK_CAPABILITY(V4L2_CAP_HW_FREQ_SEEK);
    CHECK_CAPABILITY(V4L2_CAP_RDS_OUTPUT);
    CHECK_CAPABILITY(V4L2_CAP_READWRITE);
    CHECK_CAPABILITY(V4L2_CAP_ASYNCIO);
    CHECK_CAPABILITY(V4L2_CAP_STREAMING);

    // 打印支持的像素格式
    print_supported_pixel_formats(fd);

    close(fd);
    return 0;
}

关键更改点

  1. 多平面类型:

    • 在 print_supported_pixel_formats 函数中,我们将 fmtdesc.type 设置为 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE 以匹配设备的能力。
  2. 错误处理:

    • 在枚举格式时添加了更详细的错误处理,以便在遇到无效索引时停止枚举。
  3. 能力检查:

    • 添加了对 V4L2_CAP_VIDEO_CAPTURE_MPLANE 的检查,以确认设备支持多平面视频捕获。
相关推荐
GeW35 分钟前
国产化替代进入深水区之后Linux 与数据库为什么必须走向重建
linux
女神下凡4 小时前
芯参谋(85):Linux_PPI_NAND_驱动开发指南
linux·运维·arm开发·驱动开发·单片机·嵌入式硬件·设计规范
12.=0.4 小时前
【持续更新】shell脚本 + Linux命令
linux·运维·服务器
Escalating_xu5 小时前
【Linux 网络编程】五种 I/O 模型与非阻塞 I/O:从“等数据”到正确处理 EAGAIN
java·linux·网络
无言听风雨丶5 小时前
Linux 容器本质探秘:Cgroup 与 Namespace 深度解析与实战
linux·运维·服务器·kubernetes
万联WANFLOW5 小时前
CVE-2026-98432 等漏洞自查:AI 查出的 Linux、Windows 漏洞,运维怎么确认受不受影响
linux·运维·windows·网络安全
OPEN-F5 小时前
Ubuntu 自动登录后 GNOME 远程桌面连不上?一次登录钥匙环锁定的排查与永久修复
linux·运维·ubuntu
硅基手札5 小时前
【Linux 内核专栏 19】20 · 嵌入式子系统 — GPIO·pinctrl·clock·regulator
linux·运维·单片机·linux内核·嵌入式开发·调试定位
默|笙6 小时前
【Linux网络】传输层协议TCP(3)滑动窗口、流量控制
linux·网络·tcp/ip
Linux界最忧郁之人7 小时前
华为云ECS&IMS&AS实战|弹性云服务器、私有镜像、弹性伸缩完整实验
linux·运维·服务器·centos·华为云·openstack