hcf123cx 2015-10-28 06:01 采纳率: 0%
浏览 3871

v4l2 VIDIOC_STREAMON 出错

运行到 ioctl(Dev, VIDIOC_STREAMON, &Type);
输出main() VIDIOC_STREAMON V4L2_BUF_TYPE_VIDEO_OUTPUT failed errno(22) Invalid argument
可能是什么原因导致的呢

  • 写回答

1条回答 默认 最新

  • 幸福快乐fyf 2023-07-01 17:07
    关注

    在运行到 ioctl(Dev, VIDIOC_STREAMON, &Type) 时,输出 VIDIOC_STREAMON V4L2_BUF_TYPE_VIDEO_OUTPUT failed errno(22) Invalid argument,这可能是由于设备不支持视频输出或者输入格式设置有误导致的。

    请检查以下几点:

    1. 确认设备是否支持视频输出功能。如果设备不支持输出,则应该使用 V4L2_BUF_TYPE_VIDEO_CAPTURE 类型。
    2. 确保格式设置正确。将 struct v4l2_format 中的 type 成员设置为 V4L2_BUF_TYPE_VIDEO_CAPTURE 或 V4L2_BUF_TYPE_VIDEO_OUTPUT,并根据设备要求设置 fmt 成员中的参数。
      下面是一份修改后的代码示例,仅供参考:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <linux/videodev2.h>
    
    #define WIDTH 640
    #define HEIGHT 480
    #define FPS 30
    
    int main() {
        int fd = open("/dev/video0", O_RDWR);
        if (fd == -1) {
            printf("Error: Cannot open device video0\n");
            return -1;
        }
    
        struct v4l2_capability cap;
        if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
            printf("Error: Cannot query device capabilities\n");
            close(fd);
            return -1;
        }
    
        struct v4l2_format fmt;
        memset(&fmt, 0, sizeof(fmt));
        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        fmt.fmt.pix.width = WIDTH;
        fmt.fmt.pix.height = HEIGHT;
        fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
        fmt.fmt.pix.field = V4L2_FIELD_NONE;
        if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {
            printf("Error: Cannot set format\n");
            close(fd);
            return -1;
        }
    
        struct v4l2_requestbuffers reqbuf;
        memset(&reqbuf, 0, sizeof(reqbuf));
        reqbuf.count = 4;
        reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        reqbuf.memory = V4L2_MEMORY_MMAP;
        if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) == -1) {
            printf("Error: Cannot request buffers\n");
            close(fd);
            return -1;
        }
    
        struct v4l2_buffer buffer[4];
        void* start[4];
        for (int i = 0; i < reqbuf.count; i++) {
            memset(&buffer[i], 0, sizeof(buffer[i]));
            buffer[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
            buffer[i].memory = V4L2_MEMORY_MMAP;
            buffer[i].index = i;
            if (ioctl(fd, VIDIOC_QUERYBUF, &buffer[i]) == -1) {
                printf("Error: Cannot query buffer\n");
                close(fd);
                return -1;
            }
            start[i] = mmap(NULL, buffer[i].length, PROT_READ | PROT_WRITE,
                             MAP_SHARED, fd, buffer[i].m.offset);
            if (start[i] == MAP_FAILED) {
                printf("Error: Cannot mmap buffer\n");
                close(fd);
                return -1;
            }
        }
    
        for (int i = 0; i < reqbuf.count; i++) {
            if (ioctl(fd, VIDIOC_QBUF, &buffer[i]) == -1) {
                printf("Error: Cannot queue buffer\n");
                close(fd);
                return -1;
            }
        }
    
        enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        if (ioctl(fd, VIDIOC_STREAMON, &type) == -1) {
            printf("Error: Cannot start streaming\n");
            close(fd);
            return -1;
        }
    
        int frame_count = 100;
        while (frame_count-- > 0) {
            fd_set fds;
            FD_ZERO(&fds);
            FD_SET(fd, &fds);
    
            struct timeval timeout;
            timeout.tv_sec = 2;
            timeout.tv_usec = 0;
    
            int ret = select(fd + 1, &fds, NULL, NULL, &timeout);
            if (ret == -1) {
                printf("Error: Cannot waiting for data\n");
                close(fd);
                return -1
            }
    }
    
    评论

报告相同问题?