@@ -164,6 +164,67 @@ int v4l2_subdev_set_format(struct media_entity *entity,
return 0;
}
+int v4l2_subdev_apply_pipeline_fmt(struct media_device *media,
+ struct v4l2_format *fmt)
+{
+ struct v4l2_mbus_framefmt mbus_fmt = { 0 };
+ struct media_entity *entity = media->pipeline;
+ struct media_pad *pad;
+ int ret;
+
+ while (entity) {
+ /*
+ * Source entity is linked only through a source pad
+ * and this pad should be used for setting the format.
+ * For other entities set the format on a sink pad.
+ */
+ pad = entity->pipe_sink_pad ? entity->pipe_sink_pad :
+ entity->pipe_src_pad;
+ if (pad == NULL)
+ return -EINVAL;
+
+ ret = v4l2_subdev_get_format(entity, &mbus_fmt, pad->index,
+ V4L2_SUBDEV_FORMAT_TRY);
+
+ if (ret < 0)
+ return ret;
+
+ media_dbg(media, "VIDIOC_SUBDEV_G_FMT %s:%d: mbus_code: %s, width: %d, height: %d\n",
+ media_entity_get_name(entity), pad->index,
+ v4l2_subdev_pixelcode_to_string(mbus_fmt.code),
+ mbus_fmt.width, mbus_fmt.height);
+
+ ret = v4l2_subdev_set_format(entity, &mbus_fmt, pad->index,
+ V4L2_SUBDEV_FORMAT_ACTIVE);
+ if (ret < 0)
+ return ret;
+
+ media_dbg(media, "VIDIOC_SUBDEV_S_FMT %s:%d: mbus_code: %s, width: %d, height: %d\n",
+ media_entity_get_name(entity), pad->index,
+ v4l2_subdev_pixelcode_to_string(mbus_fmt.code),
+ mbus_fmt.width, mbus_fmt.height);
+
+ entity = entity->next;
+
+ /* Last entity in the pipeline is not a sub-device */
+ if (entity->next == NULL)
+ break;
+ }
+
+ /*
+ * Sink entity represents a video device node and is not
+ * a sub-device. Nonetheless because it has associated
+ * file descriptor and can expose v4l2-controls the
+ * v4l2-subdev structure is used for caching the
+ * related data.
+ */
+ ret = ioctl(entity->sd->fd, VIDIOC_S_FMT, fmt);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
int v4l2_subdev_get_selection(struct media_entity *entity,
struct v4l2_rect *rect, unsigned int pad, unsigned int target,
enum v4l2_subdev_format_whence which)
@@ -131,6 +131,21 @@ int v4l2_subdev_set_format(struct media_entity *entity,
enum v4l2_subdev_format_whence which);
/**
+ * @brief Set media device pipeline format
+ * @param media - media device.
+ * @param fmt - negotiated format.
+ *
+ * Set the active format on all the media device pipeline entities.
+ * The format has to be at first negotiated with VIDIOC_SUBDEV_S_FMT
+ * by struct v4l2_subdev_format's 'whence' property set to
+ * V4L2_SUBDEV_FORMAT_TRY.
+ *
+ * @return 0 on success, or a negative error code on failure.
+ */
+int v4l2_subdev_apply_pipeline_fmt(struct media_device *media,
+ struct v4l2_format *fmt);
+
+/**
* @brief Retrieve a selection rectangle on a pad.
* @param entity - subdev-device media entity.
* @param r - rectangle to be filled.