前提条件: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;
}