Re: [v4l-utils] [PATCH v1 1/3] libv4l2subdev: Extend API with 'which' argument where missing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 10/06/2024 04:22, Laurent Pinchart wrote:
Many functions exposed by libv4l2subdev have been added over time
hardcoding usage of the V4L2_SUBDEV_FORMAT_ACTIVE state. Extend them
with a 'which' argument to allow callers to access the TRY state as
well. Update existing callers to pass V4L2_SUBDEV_FORMAT_ACTIVE
unconditionally, preserving the existing behaviour.

To support accessing the TRY state when getting or setting frame
intervals, set the V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH client
capability.

I would have split this one to a separate patch, but not a biggie.

Reviewed-by: Tomi Valkeinen <tomi.valkeinen@xxxxxxxxxxxxxxxx>

 Tomi


Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
---
  utils/media-ctl/libv4l2subdev.c | 65 +++++++++++++++++++++------------
  utils/media-ctl/media-ctl.c     | 11 ++++--
  utils/media-ctl/v4l2subdev.h    | 49 ++++++++++++++++++++++---
  3 files changed, 92 insertions(+), 33 deletions(-)

diff --git a/utils/media-ctl/libv4l2subdev.c b/utils/media-ctl/libv4l2subdev.c
index e0df686e01c7..163fd610dce7 100644
--- a/utils/media-ctl/libv4l2subdev.c
+++ b/utils/media-ctl/libv4l2subdev.c
@@ -69,7 +69,8 @@ int v4l2_subdev_open(struct media_entity *entity)
  	ret = ioctl(entity->fd, VIDIOC_SUBDEV_QUERYCAP, &subdevcap);
  	subdev_streams = !ret && (subdevcap.capabilities & V4L2_SUBDEV_CAP_STREAMS);
- clientcap.capabilities = V4L2_SUBDEV_CLIENT_CAP_STREAMS;
+	clientcap.capabilities = V4L2_SUBDEV_CLIENT_CAP_STREAMS
+			       | V4L2_SUBDEV_CLIENT_CAP_INTERVAL_USES_WHICH;
ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_CLIENT_CAP, &clientcap);
  	client_streams = !ret && (clientcap.capabilities & V4L2_SUBDEV_CLIENT_CAP_STREAMS);
@@ -240,10 +241,11 @@ int v4l2_subdev_set_selection(struct media_entity *entity,
int v4l2_subdev_get_routing(struct media_entity *entity,
  			    struct v4l2_subdev_route **routes,
-			    unsigned int *num_routes)
+			    unsigned int *num_routes,
+			    enum v4l2_subdev_format_whence which)
  {
  	struct v4l2_subdev_routing routing = {
-		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		.which = which,
  	};
  	struct v4l2_subdev_route *r;
  	int ret;
@@ -287,10 +289,11 @@ int v4l2_subdev_get_routing(struct media_entity *entity,
int v4l2_subdev_set_routing(struct media_entity *entity,
  			    struct v4l2_subdev_route *routes,
-			    unsigned int num_routes)
+			    unsigned int num_routes,
+			    enum v4l2_subdev_format_whence which)
  {
  	struct v4l2_subdev_routing routing = {
-		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		.which = which,
  		.routes = (uintptr_t)routes,
  		.num_routes = num_routes,
  		.len_routes = num_routes,
@@ -387,7 +390,8 @@ int v4l2_subdev_set_dv_timings(struct media_entity *entity,
int v4l2_subdev_get_frame_interval(struct media_entity *entity,
  				   struct v4l2_fract *interval,
-				   unsigned int pad, unsigned int stream)
+				   unsigned int pad, unsigned int stream,
+				   enum v4l2_subdev_format_whence which)
  {
  	struct v4l2_subdev_frame_interval ival;
  	int ret;
@@ -404,6 +408,7 @@ int v4l2_subdev_get_frame_interval(struct media_entity *entity,
  	memset(&ival, 0, sizeof(ival));
  	ival.pad = pad;
  	ival.stream = stream;
+	ival.which = which;
ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_FRAME_INTERVAL, &ival);
  	if (ret < 0)
@@ -415,7 +420,8 @@ int v4l2_subdev_get_frame_interval(struct media_entity *entity,
int v4l2_subdev_set_frame_interval(struct media_entity *entity,
  				   struct v4l2_fract *interval,
-				   unsigned int pad, unsigned int stream)
+				   unsigned int pad, unsigned int stream,
+				   enum v4l2_subdev_format_whence which)
  {
  	struct v4l2_subdev_frame_interval ival;
  	int ret;
@@ -433,6 +439,7 @@ int v4l2_subdev_set_frame_interval(struct media_entity *entity,
  	ival.pad = pad;
  	ival.stream = stream;
  	ival.interval = *interval;
+	ival.which = which;
ret = ioctl(entity->fd, VIDIOC_SUBDEV_S_FRAME_INTERVAL, &ival);
  	if (ret < 0)
@@ -514,7 +521,9 @@ static int v4l2_subdev_parse_setup_route(struct media_device *media,
  	return 0;
  }
-int v4l2_subdev_parse_setup_routes(struct media_device *media, const char *p)
+int v4l2_subdev_parse_setup_routes(struct media_device *media,
+				   enum v4l2_subdev_format_whence which,
+				   const char *p)
  {
  	struct media_entity *entity;
  	struct v4l2_subdev_route *routes;
@@ -578,7 +587,7 @@ int v4l2_subdev_parse_setup_routes(struct media_device *media, const char *p)
  			  r->flags);
  	}
- ret = v4l2_subdev_set_routing(entity, routes, num_routes);
+	ret = v4l2_subdev_set_routing(entity, routes, num_routes, which);
  	if (ret) {
  		media_dbg(entity->media, "VIDIOC_SUBDEV_S_ROUTING failed: %d\n",
  			  ret);
@@ -961,7 +970,8 @@ static struct media_pad *v4l2_subdev_parse_pad_format(
static int set_format(struct media_pad *pad,
  		      unsigned int stream,
-		      struct v4l2_mbus_framefmt *format)
+		      struct v4l2_mbus_framefmt *format,
+		      enum v4l2_subdev_format_whence which)
  {
  	int ret;
@@ -975,7 +985,7 @@ static int set_format(struct media_pad *pad,
  		  pad->entity->info.name, pad->index, stream);
ret = v4l2_subdev_set_format(pad->entity, format, pad->index, stream,
-				     V4L2_SUBDEV_FORMAT_ACTIVE);
+				     which);
  	if (ret < 0) {
  		media_dbg(pad->entity->media,
  			  "Unable to set format: %s (%d)\n",
@@ -992,7 +1002,8 @@ static int set_format(struct media_pad *pad,
  }
static int set_selection(struct media_pad *pad, unsigned int stream,
-			 unsigned int target, struct v4l2_rect *rect)
+			 unsigned int target, struct v4l2_rect *rect,
+			 enum v4l2_subdev_format_whence which)
  {
  	int ret;
@@ -1005,7 +1016,7 @@ static int set_selection(struct media_pad *pad, unsigned int stream,
  		  pad->entity->info.name, pad->index, stream);
ret = v4l2_subdev_set_selection(pad->entity, rect, pad->index, stream,
-					target, V4L2_SUBDEV_FORMAT_ACTIVE);
+					target, which);
  	if (ret < 0) {
  		media_dbg(pad->entity->media,
  			  "Unable to set selection rectangle: %s (%d)\n",
@@ -1021,7 +1032,8 @@ static int set_selection(struct media_pad *pad, unsigned int stream,
  }
static int set_frame_interval(struct media_pad *pad, unsigned int stream,
-			      struct v4l2_fract *interval)
+			      struct v4l2_fract *interval,
+			      enum v4l2_subdev_format_whence which)
  {
  	int ret;
@@ -1034,7 +1046,7 @@ static int set_frame_interval(struct media_pad *pad, unsigned int stream,
  		  pad->entity->info.name, pad->index, stream);
ret = v4l2_subdev_set_frame_interval(pad->entity, interval, pad->index,
-					     stream);
+					     stream, which);
  	if (ret < 0) {
  		media_dbg(pad->entity->media,
  			  "Unable to set frame interval: %s (%d)",
@@ -1050,6 +1062,7 @@ static int set_frame_interval(struct media_pad *pad, unsigned int stream,
static int v4l2_subdev_parse_setup_format(struct media_device *media,
+					  enum v4l2_subdev_format_whence which,
  					  const char *p, char **endp)
  {
  	struct v4l2_mbus_framefmt format = { 0, 0, 0 };
@@ -1072,26 +1085,26 @@ static int v4l2_subdev_parse_setup_format(struct media_device *media,
  	}
if (pad->flags & MEDIA_PAD_FL_SINK) {
-		ret = set_format(pad, stream, &format);
+		ret = set_format(pad, stream, &format, which);
  		if (ret < 0)
  			return ret;
  	}
- ret = set_selection(pad, stream, V4L2_SEL_TGT_CROP, &crop);
+	ret = set_selection(pad, stream, V4L2_SEL_TGT_CROP, &crop, which);
  	if (ret < 0)
  		return ret;
- ret = set_selection(pad, stream, V4L2_SEL_TGT_COMPOSE, &compose);
+	ret = set_selection(pad, stream, V4L2_SEL_TGT_COMPOSE, &compose, which);
  	if (ret < 0)
  		return ret;
if (pad->flags & MEDIA_PAD_FL_SOURCE) {
-		ret = set_format(pad, stream, &format);
+		ret = set_format(pad, stream, &format, which);
  		if (ret < 0)
  			return ret;
  	}
- ret = set_frame_interval(pad, stream, &interval);
+	ret = set_frame_interval(pad, stream, &interval, which);
  	if (ret < 0)
  		return ret;
@@ -1109,9 +1122,11 @@ static int v4l2_subdev_parse_setup_format(struct media_device *media,
  			if (link->source == pad &&
  			    link->sink->entity->info.type == MEDIA_ENT_T_V4L2_SUBDEV) {
  				remote_format = format;
-				set_format(link->sink, stream, &remote_format);
+				set_format(link->sink, stream, &remote_format,
+					   which);
- ret = set_frame_interval(link->sink, stream, &interval);
+				ret = set_frame_interval(link->sink, stream,
+							 &interval, which);
  				if (ret < 0 && ret != -EINVAL && ret != -ENOTTY)
  					return ret;
  			}
@@ -1122,13 +1137,15 @@ static int v4l2_subdev_parse_setup_format(struct media_device *media,
  	return 0;
  }
-int v4l2_subdev_parse_setup_formats(struct media_device *media, const char *p)
+int v4l2_subdev_parse_setup_formats(struct media_device *media,
+				    enum v4l2_subdev_format_whence which,
+				    const char *p)
  {
  	char *end;
  	int ret;
do {
-		ret = v4l2_subdev_parse_setup_format(media, p, &end);
+		ret = v4l2_subdev_parse_setup_format(media, which, p, &end);
  		if (ret < 0)
  			return ret;
diff --git a/utils/media-ctl/media-ctl.c b/utils/media-ctl/media-ctl.c
index 1a9e393ac1f3..44256df953db 100644
--- a/utils/media-ctl/media-ctl.c
+++ b/utils/media-ctl/media-ctl.c
@@ -108,7 +108,8 @@ static void v4l2_subdev_print_format(struct media_entity *entity,
  	if (ret != 0)
  		return;
- ret = v4l2_subdev_get_frame_interval(entity, &interval, pad, stream);
+	ret = v4l2_subdev_get_frame_interval(entity, &interval, pad, stream,
+					     V4L2_SUBDEV_FORMAT_ACTIVE);
  	if (ret != 0 && ret != -ENOTTY && ret != -EINVAL)
  		return;
@@ -527,7 +528,8 @@ static void media_print_topology_text_entity(struct media_device *media,
  	unsigned int padding;
if (media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV)
-		v4l2_subdev_get_routing(entity, &routes, &num_routes);
+		v4l2_subdev_get_routing(entity, &routes, &num_routes,
+					V4L2_SUBDEV_FORMAT_ACTIVE);
padding = printf("- entity %u: ", info->id);
  	printf("%s (%u pad%s, %u link%s", info->name,
@@ -738,7 +740,9 @@ int main(int argc, char **argv)
  	}
if (media_opts.routes) {
-		ret = v4l2_subdev_parse_setup_routes(media, media_opts.routes);
+		ret = v4l2_subdev_parse_setup_routes(media,
+						     V4L2_SUBDEV_FORMAT_ACTIVE,
+						     media_opts.routes);
  		if (ret) {
  			printf("Unable to setup routes: %s (%d)\n",
  			       strerror(-ret), -ret);
@@ -748,6 +752,7 @@ int main(int argc, char **argv)
if (media_opts.formats) {
  		ret = v4l2_subdev_parse_setup_formats(media,
+						      V4L2_SUBDEV_FORMAT_ACTIVE,
  						      media_opts.formats);
  		if (ret) {
  			printf("Unable to setup formats: %s (%d)\n",
diff --git a/utils/media-ctl/v4l2subdev.h b/utils/media-ctl/v4l2subdev.h
index 1277040bfeae..0c1feae28e88 100644
--- a/utils/media-ctl/v4l2subdev.h
+++ b/utils/media-ctl/v4l2subdev.h
@@ -142,32 +142,44 @@ int v4l2_subdev_set_selection(struct media_entity *entity,
   * @param entity - subdev-device media entity.
   * @param routes - routes of the subdev.
   * @param num_routes - number of routes.
+ * @param which - identifier of the routes to get.
   *
   * Get the routes of @a entity and return them in an allocated array in @a routes
   * and the number of routes in @a num_routes.
   *
   * The caller is responsible for freeing the routes array after use.
   *
+ * @a which is set to V4L2_SUBDEV_FORMAT_TRY to get the routing table stored in
+ * the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to get the device's active
+ * routing table.
+ *
   * @return 0 on success, or a negative error code on failure.
   */
  int v4l2_subdev_get_routing(struct media_entity *entity,
  			    struct v4l2_subdev_route **routes,
-			    unsigned int *num_routes);
+			    unsigned int *num_routes,
+			    enum v4l2_subdev_format_whence which);
/**
   * @brief Set the routing table of a subdev media entity.
   * @param entity - subdev-device media entity.
   * @param routes - routes of the subdev.
   * @param num_routes - number of routes.
+ * @param which - identifier of the routes to set.
   *
   * Set the routes of @a entity. The routes are given in @a routes with the
   * length of @a num_routes.
   *
+ * @a which is set to V4L2_SUBDEV_FORMAT_TRY to set the routing table stored in
+ * the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to set the device's active
+ * routing table.
+ *
   * @return 0 on success, or a negative error code on failure.
   */
  int v4l2_subdev_set_routing(struct media_entity *entity,
  			    struct v4l2_subdev_route *route,
-			    unsigned int num_routes);
+			    unsigned int num_routes,
+			    enum v4l2_subdev_format_whence which);
/**
   * @brief Query the digital video capabilities of a pad.
@@ -228,6 +240,7 @@ int v4l2_subdev_set_dv_timings(struct media_entity *entity,
   * @param interval - frame interval to be filled.
   * @param pad - pad number.
   * @param stream - stream number.
+ * @param which - identifier of the interval to get.
   *
   * Retrieve the current frame interval on subdev @a entity and store it in the
   * @a interval structure.
@@ -235,11 +248,16 @@ int v4l2_subdev_set_dv_timings(struct media_entity *entity,
   * Frame interval retrieving is usually supported only on devices at the
   * beginning of video pipelines, such as sensors.
   *
+ * @a which is set to V4L2_SUBDEV_FORMAT_TRY to get the frame interval stored
+ * in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to get the device's active
+ * frame interval.
+ *
   * @return 0 on success, or a negative error code on failure.
   */
int v4l2_subdev_get_frame_interval(struct media_entity *entity,
-	struct v4l2_fract *interval, unsigned int pad, unsigned int stream);
+	struct v4l2_fract *interval, unsigned int pad, unsigned int stream,
+	enum v4l2_subdev_format_whence which);
/**
   * @brief Set the frame interval on a sub-device.
@@ -247,6 +265,7 @@ int v4l2_subdev_get_frame_interval(struct media_entity *entity,
   * @param interval - frame interval.
   * @param pad - pad number.
   * @param stream - stream number.
+ * @param which - identifier of the interval to set.
   *
   * Set the frame interval on subdev @a entity to @a interval. The driver is
   * allowed to modify the requested frame interval, in which case @a interval is
@@ -255,14 +274,20 @@ int v4l2_subdev_get_frame_interval(struct media_entity *entity,
   * Frame interval setting is usually supported only on devices at the beginning
   * of video pipelines, such as sensors.
   *
+ * @a which is set to V4L2_SUBDEV_FORMAT_TRY to set the frame interval stored
+ * in the file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to set the device's active
+ * frame interval.
+ *
   * @return 0 on success, or a negative error code on failure.
   */
  int v4l2_subdev_set_frame_interval(struct media_entity *entity,
-	struct v4l2_fract *interval, unsigned int pad, unsigned int stream);
+	struct v4l2_fract *interval, unsigned int pad, unsigned int stream,
+	enum v4l2_subdev_format_whence which);
/**
   * @brief Parse a string and apply format, crop and frame interval settings.
   * @param media - media device.
+ * @param which - identifier of the parameters to set.
   * @param p - input string
   * @param endp - pointer to string p where parsing ended (return)
   *
@@ -272,20 +297,32 @@ int v4l2_subdev_set_frame_interval(struct media_entity *entity,
   *
   * Format strings are separeted by commas (,).
   *
+ * @a which is set to V4L2_SUBDEV_FORMAT_TRY to set the parameters stored in the
+ * file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to set the device's active
+ * parameters.
+ *
   * @return 0 on success, or a negative error code on failure.
   */
-int v4l2_subdev_parse_setup_formats(struct media_device *media, const char *p);
+int v4l2_subdev_parse_setup_formats(struct media_device *media,
+				    enum v4l2_subdev_format_whence which,
+				    const char *p);
/**
   * @brief Parse a string and apply route settings.
   * @param media - media device.
+ * @param which - identifier of the routes to set.
   * @param p - input string
   *
   * Parse string @a p and apply route settings to a subdev.
   *
+ * @a which is set to V4L2_SUBDEV_FORMAT_TRY to set the routes stored in the
+ * file handle, of V4L2_SUBDEV_FORMAT_ACTIVE to set the device's active routes.
+ *
   * @return 0 on success, or a negative error code on failure.
   */
-int v4l2_subdev_parse_setup_routes(struct media_device *media, const char *p);
+int v4l2_subdev_parse_setup_routes(struct media_device *media,
+				   enum v4l2_subdev_format_whence which,
+				   const char *p);
/**
   * @brief Convert media bus pixel code to string.





[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux