This is an automatic generated email to let you know that the following patch 
were queued at the 
http://git.linuxtv.org/cgit.cgi/v4l-utils.git tree:

Subject: libv4l2subdev: Extend API with 'which' argument where missing
Author:  Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Date:    Mon Jun 10 03:46:24 2024 +0300

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.

Signed-off-by: Laurent Pinchart <laurent.pinch...@ideasonboard.com>
Reviewed-by: Tomi Valkeinen <tomi.valkei...@ideasonboard.com>
Acked-by: Sakari Ailus <sakari.ai...@linux.intel.com>

 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(-)

---

http://git.linuxtv.org/cgit.cgi/v4l-utils.git/commit/?id=9e51a78389be1ab2d288be4aa2921e09f3ebabe1
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.

Reply via email to