|
@@ -212,6 +212,7 @@ libmegapixels_select_mode(libmegapixels_camera *camera, libmegapixels_mode *mode
|
|
|
libmegapixels_cmd *cmd = mode->cmds[i];
|
|
|
struct v4l2_subdev_format subdev_fmt = {};
|
|
|
struct v4l2_subdev_crop subdev_crop = {};
|
|
|
+ struct v4l2_subdev_frame_interval subdev_ival = {};
|
|
|
int found = 0;
|
|
|
libmegapixels_subdev *sd;
|
|
|
|
|
@@ -258,6 +259,38 @@ libmegapixels_select_mode(libmegapixels_camera *camera, libmegapixels_mode *mode
|
|
|
log_error("Could not set mode on %s:%d: %s\n", cmd->entity_from, cmd->pad_from, strerror(errno));
|
|
|
}
|
|
|
break;
|
|
|
+ case LIBMEGAPIXELS_CMD_INTERVAL:
|
|
|
+ subdev_ival.pad = cmd->pad_from;
|
|
|
+ struct v4l2_fract ival;
|
|
|
+ ival.numerator = 1;
|
|
|
+ ival.denominator = cmd->rate;
|
|
|
+ subdev_ival.interval = ival;
|
|
|
+ log_debug(" Rate %s:%d [%d]\n", cmd->entity_from, cmd->pad_from, cmd->rate);
|
|
|
+
|
|
|
+ found = 0;
|
|
|
+ for (int h = 0; h < camera->num_handles; h++) {
|
|
|
+ if (camera->handles[h]->entity_id == cmd->entity_from_id) {
|
|
|
+ sd = camera->handles[h];
|
|
|
+ found++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (found != 1) {
|
|
|
+ log_error("Could not find handle for entity\n");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (sd->fd == 0) {
|
|
|
+ sd->fd = open(sd->path, O_RDWR);
|
|
|
+ if (sd->fd < 0) {
|
|
|
+ log_error("Could not open %s\n", sd->path);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (xioctl(sd->fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &subdev_ival) == -1) {
|
|
|
+ log_error("Could not set rate on %s:%d: %s\n", cmd->entity_from, cmd->pad_from, strerror(errno));
|
|
|
+ }
|
|
|
+ break;
|
|
|
case LIBMEGAPIXELS_CMD_CROP:
|
|
|
subdev_crop.pad = cmd->pad_from;
|
|
|
subdev_crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|