|
@@ -227,12 +227,6 @@ libmegapixels_select_mode(libmegapixels_camera *camera, libmegapixels_mode *mode
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case LIBMEGAPIXELS_CMD_MODE:
|
|
case LIBMEGAPIXELS_CMD_MODE:
|
|
- subdev_fmt.pad = cmd->pad_from;
|
|
|
|
- subdev_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
|
|
|
- subdev_fmt.format.width = cmd->width;
|
|
|
|
- subdev_fmt.format.height = cmd->height;
|
|
|
|
- subdev_fmt.format.code = libmegapixels_format_to_media_busfmt(cmd->format);
|
|
|
|
- subdev_fmt.format.field = V4L2_FIELD_ANY;
|
|
|
|
log_debug(" Mode %s:%d [%dx%d %s]\n", cmd->entity_from, cmd->pad_from, cmd->width, cmd->height,
|
|
log_debug(" Mode %s:%d [%dx%d %s]\n", cmd->entity_from, cmd->pad_from, cmd->width, cmd->height,
|
|
libmegapixels_format_name(cmd->format));
|
|
libmegapixels_format_name(cmd->format));
|
|
|
|
|
|
@@ -256,9 +250,43 @@ libmegapixels_select_mode(libmegapixels_camera *camera, libmegapixels_mode *mode
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ subdev_fmt.pad = cmd->pad_from;
|
|
|
|
+ subdev_fmt.which = V4L2_SUBDEV_FORMAT_TRY;
|
|
|
|
+ subdev_fmt.format.width = cmd->width;
|
|
|
|
+ subdev_fmt.format.height = cmd->height;
|
|
|
|
+ subdev_fmt.format.code = libmegapixels_format_to_media_busfmt(cmd->format);
|
|
|
|
+ subdev_fmt.format.field = V4L2_FIELD_ANY;
|
|
|
|
+
|
|
|
|
+ if (xioctl(sd->fd, VIDIOC_SUBDEV_S_FMT, &subdev_fmt) == -1) {
|
|
|
|
+ log_error("Could not try mode on %s:%d: %s\n", cmd->entity_from, cmd->pad_from, strerror(errno));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (subdev_fmt.format.width != cmd->width || subdev_fmt.format.height != cmd->height) {
|
|
|
|
+ log_error("Driver rejected resolution %dx%d, changed to %dx%d\n", cmd->width, cmd->height,
|
|
|
|
+ subdev_fmt.format.width, subdev_fmt.format.height);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (subdev_fmt.format.code != libmegapixels_format_to_media_busfmt(cmd->format)) {
|
|
|
|
+ log_error("Driver rejected pixfmt try: %d\n", subdev_fmt.format.code);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ subdev_fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
|
if (xioctl(sd->fd, VIDIOC_SUBDEV_S_FMT, &subdev_fmt) == -1) {
|
|
if (xioctl(sd->fd, VIDIOC_SUBDEV_S_FMT, &subdev_fmt) == -1) {
|
|
log_error("Could not set mode on %s:%d: %s\n", cmd->entity_from, cmd->pad_from, strerror(errno));
|
|
log_error("Could not set mode on %s:%d: %s\n", cmd->entity_from, cmd->pad_from, strerror(errno));
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ // There seem to be drivers that don't reject resolutions in V4L2_SUBDEV_FORMAT_TRY mode but
|
|
|
|
+ // do silently change the resolution when doing the V4L2_SUBDEV_FORMAT_ACTIVE bit. So check
|
|
|
|
+ // again since V4L2 is the wild west.
|
|
|
|
+ if (subdev_fmt.format.width != cmd->width || subdev_fmt.format.height != cmd->height) {
|
|
|
|
+ log_error("Driver rejected resolution %dx%d, changed to %dx%d\n", cmd->width, cmd->height,
|
|
|
|
+ subdev_fmt.format.width, subdev_fmt.format.height);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ if (subdev_fmt.format.code != libmegapixels_format_to_media_busfmt(cmd->format)) {
|
|
|
|
+ log_error("Driver rejected pixfmt: %d\n", subdev_fmt.format.code);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
break;
|
|
break;
|
|
case LIBMEGAPIXELS_CMD_INTERVAL:
|
|
case LIBMEGAPIXELS_CMD_INTERVAL:
|
|
subdev_ival.pad = cmd->pad_from;
|
|
subdev_ival.pad = cmd->pad_from;
|