You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

读取/dev/video0设备信息时出现Video4Linux ioctl错误(#25)

问题分析与解决办法

你遇到的"Inappropriate ioctl for device"错误,核心原因是你用错了设备节点和对应的ioctl命令:

  • /dev/video0是V4L2(Video for Linux 2)标准的视频捕获设备节点,它不支持MEDIA_IOC_DEVICE_INFO这个ioctl——这个命令是给媒体控制器设备(路径通常是/dev/media0、/dev/media1这类)用的,专门用来查询整个媒体拓扑的设备信息。

下面分两种场景给出修正方案:

场景1:获取媒体控制器设备信息

如果你确实想获取媒体控制器层面的设备信息,需要打开/dev/mediaX节点(先通过ls /dev/media*查看系统中存在的媒体控制器设备),代码修改如下:

#include <fcntl.h>
#include <unistd.h>
#include <linux/media.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv) {
    // 打开媒体控制器设备,替换成你系统中存在的/mediaX路径
    int fd = open("/dev/media0", O_RDONLY, 0);
    if (fd > 0) {
        struct media_device_info *device_data = malloc(sizeof(struct media_device_info));
        if (ioctl(fd, MEDIA_IOC_DEVICE_INFO, device_data) == 0) {
            printf("Media Version: %u\nDriver: %s\nVersion: %u\nSerial: %s\n",
                   (unsigned int)device_data->media_version,
                   device_data->driver,
                   (unsigned int)device_data->driver_version,
                   device_data->serial);
        } else {
            fprintf(stderr, "Couldn't get device info: %d: %s\n", errno, strerror(errno));
        }
        close(fd);
        free(device_data);
    } else {
        fprintf(stderr, "Failed to open device: %d: %s\n", errno, strerror(errno));
    }
    return 0;
}

场景2:获取/dev/video0的视频设备信息

如果你的目标是查询/dev/video0这个视频捕获设备的信息,应该使用V4L2标准的VIDIOC_QUERYCAP命令,代码示例如下:

#include <fcntl.h>
#include <unistd.h>
#include <linux/videodev2.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv) {
    // V4L2设备建议用RDWR模式打开,部分操作需要写入权限
    int fd = open("/dev/video0", O_RDWR | O_NONBLOCK, 0);
    if (fd > 0) {
        struct v4l2_capability cap;
        if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == 0) {
            printf("Driver Name: %s\nCard Name: %s\nBus Info: %s\nDriver Version: %u.%u.%u\n",
                   cap.driver,
                   cap.card,
                   cap.bus_info,
                   (cap.version >> 16) & 0xFF,
                   (cap.version >> 8) & 0xFF,
                   cap.version & 0xFF);
        } else {
            fprintf(stderr, "Couldn't get video device info: %d: %s\n", errno, strerror(errno));
        }
        close(fd);
    } else {
        fprintf(stderr, "Failed to open video device: %d: %s\n", errno, strerror(errno));
    }
    return 0;
}

额外提示

  • 打开这些设备通常需要权限,你可以通过sudo usermod -aG video your_username将自己加入video用户组,然后重新登录,避免每次用root权限运行程序。
  • 编译时直接用gcc your_code.c -o your_program即可,这些内核头文件不需要额外链接库。

内容的提问来源于stack exchange,提问作者tiredone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:03:36