fsociety_ 2024-06-29 17:16 采纳率: 28.6%
浏览 38
已结题

v4l2起来之后怎么修改分辨率

前提条件:v4l2已经开始以1280 x 720的分辨率开始捕获视频流
这种情况怎么修改分辨率为640 x 480。

已经尝试的操作: 使用VIDIOC_STREAMOFF命令去停止视频流,ioctrl返回为0,然后修改分辨率,最后再重新开始视频流。
但是ioctl(fd, VIDIOC_S_FMT, &fmt)修改分辨率的返回值为-1,log显示Device or resource busy。

void v4l2_change_pic_size(int new_width, int new_height)
{
    enum v4l2_buf_type type;
    struct v4l2_format fmt;
    struct v4l2_requestbuffers req;
    struct v4l2_buffer buf;
    int ret = 999;
    LOGD("new_width: %d, new_height: %d\n", new_width, new_height);
    // 停止数据流
    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
    LOGD("ioctl ret: %d\n", ret);
    if ( ret == -1) {
        LOGD("Failed to stop streaming");
        return;
    }
    // 确认视频流是否停止
    struct v4l2_capability cap;
    if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {
        LOGD("Failed to query device capabilities");
        close(fd);
        return;
    }

    if (cap.capabilities & V4L2_CAP_STREAMING) {
        LOGD("Device still supports streaming.\n");
    } else {
        LOGD("Device has stopped streaming.\n");
    }

    memset(&fmt, 0, sizeof(fmt));
    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
    fmt.fmt.pix.width = new_width;
    fmt.fmt.pix.height = new_height;
    fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
    fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
    LOGD("v4l2 fd: %d\n", fd);
    ret = ioctl(fd, VIDIOC_S_FMT, &fmt);
    if ( ret == -1)
    {
        LOGD("v4l2_change_pic_size failed, errorno: %s\n", strerror(errno));
    }

    // 恢复数据流
    if (ioctl(fd, VIDIOC_STREAMON, &type) == -1) {
        LOGD("Failed to start streaming");
    }
    return;
}

  • 写回答

3条回答 默认 最新

  • 蓝天居士 《人工智能从入门到进阶实战》作者 2024-06-30 10:32
    关注

    关闭设备,设置分辨率,重新打开

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 7月17日
  • 已采纳回答 7月13日
  • 创建了问题 6月29日