From patchwork Mon Jun 10 01:22:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 13691433 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F6211869 for ; Mon, 10 Jun 2024 01:23:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717982583; cv=none; b=An9XepFAhgWut3R5wYkI+URil04yBZwv3LK9DxyL6ZaAt/z2uhfOyqm5vfwPFzJfpBl+9Tfl9hIxJGU8d8VEw1JdSaXWjTfQTcb14gjb4URWmA/W3rdVtt2SH1guhdqIXmeqQ0R2XIiODejJ1gm7RXwpeVjoYIFTr6azf8ovu4k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717982583; c=relaxed/simple; bh=SJwZgOt7BnIsBNckuu93V9HPz7inVBiMNALfIFocaGk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YrbHvgDDVZbTt6ing88Mw0wrx48r/fezEDuguXKrfI/JJ2/uXmfLuaQhNdkg/8Fp5Ugz6v4WpwxsQxXARifh9iWx4LRKi3ElC/jxQS+U+cxMObrElIKswbCFgnMzcRfADuaUx7Xib6yJqGRe7HQk75ovyHlVBkDWHdFB0V4hdxQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=RdB+xres; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="RdB+xres" Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 3118AD77; Mon, 10 Jun 2024 03:22:48 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1717982568; bh=SJwZgOt7BnIsBNckuu93V9HPz7inVBiMNALfIFocaGk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RdB+xres4RHKEiyP2v83/g3LqCAVQf391e2cFk+AUhJzNhQTFMuQUpRm8IiFMdQz9 VSYD5W+43MFhxiqRDocP5u9A3GVP+NOaNUVHgohyy29CgZ1fXqDJYIn1DleOjD3brD LpOlMglE8Ae3zrD+tPh8ba1Z6duro+g4I1fzE5/0= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Tomi Valkeinen , Hans Verkuil Subject: [v4l-utils] [PATCH v1 1/3] libv4l2subdev: Extend API with 'which' argument where missing Date: Mon, 10 Jun 2024 04:22:36 +0300 Message-ID: <20240610012238.30462-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20240610012238.30462-1-laurent.pinchart@ideasonboard.com> References: <20240610012238.30462-1-laurent.pinchart@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 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 Reviewed-by: Tomi Valkeinen --- 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. From patchwork Mon Jun 10 01:22:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 13691434 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7F8121860 for ; Mon, 10 Jun 2024 01:23:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717982585; cv=none; b=sypnehLNDsSLeoWBA6bcvsAwsfc0BL/aAFasqvHfqIJ5sOVWZF2T9r36HKqRUkalAHc8IOYPMtDNRYJjeybPfRyNcbqBWtLpYevM9ZxIiqRsQ1J7SiAAu2YvGfuVImqE3XYMlnOMJnDAkTuoxzFaTekS5r6pHemF72X07QWYjd4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717982585; c=relaxed/simple; bh=4bNdxjaTn5udbdsVbJRqSRfhGJen2fgLYLzZwMfsHqY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YWHBRW+f3k1N2ZZKUta7pcmyjvL7gEzmdL/mekxllAeeCWr4zB6ljeai04icoj/pns3JsXN+eSuwf/Om+7dLnqvmi3qi2mT74mGnBp0/zbEWLviDnllkfdOCaXMskWNpVwKBoYqiwnXiHizUk6Zho01Ktrc5l+htMj8KN0Y/UrE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=T8FE8Ua5; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="T8FE8Ua5" Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 7F8BF14B0; Mon, 10 Jun 2024 03:22:49 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1717982569; bh=4bNdxjaTn5udbdsVbJRqSRfhGJen2fgLYLzZwMfsHqY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=T8FE8Ua5VadOepvYEcFOP2bPa4zyA1Xskj73+VLiEHee9KeRd/vWGFnR6/e319wcH zEcDI9k0AXUqZnfKVlTl0fmd15rtHE0+Pdh/xbklscrsQLq8vuvtO75aYwnPtr0bfE 70x7vbwvEsoYeScYtn86zq9IzeNoJuMhvBpiHctE= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Tomi Valkeinen , Hans Verkuil Subject: [v4l-utils] [PATCH v1 2/3] utils: media-ctl: Prepare for TRY state support Date: Mon, 10 Jun 2024 04:22:37 +0300 Message-ID: <20240610012238.30462-3-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20240610012238.30462-1-laurent.pinchart@ideasonboard.com> References: <20240610012238.30462-1-laurent.pinchart@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Pass a 'which' argument to all functions to select which state to access. Hardcode the value to V4L2_SUBDEV_FORMAT_ACTIVE in a single location in main(), to preserve the existing behaviour. This prepares media-ctl for support of the TRY state. Signed-off-by: Laurent Pinchart Reviewed-by: Tomi Valkeinen --- utils/media-ctl/media-ctl.c | 39 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/utils/media-ctl/media-ctl.c b/utils/media-ctl/media-ctl.c index 44256df953db..42b1bd9aaa6e 100644 --- a/utils/media-ctl/media-ctl.c +++ b/utils/media-ctl/media-ctl.c @@ -109,7 +109,7 @@ static void v4l2_subdev_print_format(struct media_entity *entity, return; ret = v4l2_subdev_get_frame_interval(entity, &interval, pad, stream, - V4L2_SUBDEV_FORMAT_ACTIVE); + which); if (ret != 0 && ret != -ENOTTY && ret != -EINVAL) return; @@ -459,7 +459,8 @@ static void media_print_topology_dot(struct media_device *media) static void media_print_pad_text(struct media_entity *entity, const struct media_pad *pad, struct v4l2_subdev_route *routes, - unsigned int num_routes) + unsigned int num_routes, + enum v4l2_subdev_format_whence which) { uint64_t printed_streams_mask = 0; unsigned int i; @@ -468,8 +469,7 @@ static void media_print_pad_text(struct media_entity *entity, return; if (!routes) { - v4l2_subdev_print_format(entity, pad->index, 0, - V4L2_SUBDEV_FORMAT_ACTIVE); + v4l2_subdev_print_format(entity, pad->index, 0, which); } else { for (i = 0; i < num_routes; ++i) { const struct v4l2_subdev_route *route = &routes[i]; @@ -494,20 +494,21 @@ static void media_print_pad_text(struct media_entity *entity, continue; v4l2_subdev_print_format(entity, pad->index, stream, - V4L2_SUBDEV_FORMAT_ACTIVE); + which); printed_streams_mask |= (1ULL << stream); } } - v4l2_subdev_print_pad_dv(entity, pad->index, V4L2_SUBDEV_FORMAT_ACTIVE); + v4l2_subdev_print_pad_dv(entity, pad->index, which); if (pad->flags & MEDIA_PAD_FL_SOURCE) v4l2_subdev_print_subdev_dv(entity); } static void media_print_topology_text_entity(struct media_device *media, - struct media_entity *entity) + struct media_entity *entity, + enum v4l2_subdev_format_whence which) { static const struct flag_name link_flags[] = { { MEDIA_LNK_FL_ENABLED, "ENABLED" }, @@ -528,8 +529,7 @@ 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_FORMAT_ACTIVE); + v4l2_subdev_get_routing(entity, &routes, &num_routes, which); padding = printf("- entity %u: ", info->id); printf("%s (%u pad%s, %u link%s", info->name, @@ -557,7 +557,7 @@ static void media_print_topology_text_entity(struct media_device *media, printf("\tpad%u: ", j); print_flags(pad_flags, ARRAY_SIZE(pad_flags), pad->flags); printf("\n"); - media_print_pad_text(entity, pad, routes, num_routes); + media_print_pad_text(entity, pad, routes, num_routes, which); for (k = 0; k < num_links; k++) { const struct media_link *link = media_entity_get_link(entity, k); @@ -585,7 +585,8 @@ static void media_print_topology_text_entity(struct media_device *media, free(routes); } -static void media_print_topology_text(struct media_device *media) +static void media_print_topology_text(struct media_device *media, + enum v4l2_subdev_format_whence which) { unsigned int nents = media_get_entities_count(media); unsigned int i; @@ -594,11 +595,12 @@ static void media_print_topology_text(struct media_device *media) for (i = 0; i < nents; ++i) media_print_topology_text_entity( - media, media_get_entity(media, i)); + media, media_get_entity(media, i), which); } int main(int argc, char **argv) { + const enum v4l2_subdev_format_whence which = V4L2_SUBDEV_FORMAT_ACTIVE; struct media_device *media; struct media_entity *entity = NULL; int ret = -1; @@ -665,8 +667,7 @@ int main(int argc, char **argv) goto out; } - v4l2_subdev_print_format(pad->entity, pad->index, stream, - V4L2_SUBDEV_FORMAT_ACTIVE); + v4l2_subdev_print_format(pad->entity, pad->index, stream, which); } if (media_opts.get_dv_pad) { @@ -708,9 +709,9 @@ int main(int argc, char **argv) media_print_topology_dot(media); } else if (media_opts.print) { if (entity) - media_print_topology_text_entity(media, entity); + media_print_topology_text_entity(media, entity, which); else - media_print_topology_text(media); + media_print_topology_text(media, which); } else if (entity) { const char *devname; @@ -740,8 +741,7 @@ int main(int argc, char **argv) } if (media_opts.routes) { - ret = v4l2_subdev_parse_setup_routes(media, - V4L2_SUBDEV_FORMAT_ACTIVE, + ret = v4l2_subdev_parse_setup_routes(media, which, media_opts.routes); if (ret) { printf("Unable to setup routes: %s (%d)\n", @@ -751,8 +751,7 @@ int main(int argc, char **argv) } if (media_opts.formats) { - ret = v4l2_subdev_parse_setup_formats(media, - V4L2_SUBDEV_FORMAT_ACTIVE, + ret = v4l2_subdev_parse_setup_formats(media, which, media_opts.formats); if (ret) { printf("Unable to setup formats: %s (%d)\n", From patchwork Mon Jun 10 01:22:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 13691435 Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 04C59566A for ; Mon, 10 Jun 2024 01:23:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=213.167.242.64 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717982587; cv=none; b=LQt7c4bCcKfkrD9/9rZESqZd5q+xk9zm7aCqD4dpWrIPRZgr0uxK4ZbhJAUv+hbUN5c7cNazkameV/G9vMj/HemQdmICZkl4ibKM466dvILFiuWqJRwLKUbcL9y0vZTF9OhjI2tLMkK5agY3+nrOUQB4Tz4dlvQj7sALleCMfaw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717982587; c=relaxed/simple; bh=eIXt7AudWEj+K4Mmcw3wbWGAf/H0VZOZ4hXbbO/DBJA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=cR9ob3RvmjXJRHv62zoAiG6DO9RZB2o3APSXoMkLHUgMc+AfHmDU/NIIShwSoHv6Bj7/GxqC+pSLyYHSZ/hsBomYEviODXu7iSHSba1LQe9yvhnsFuna/xwqLrtsFuru3kASCkEk9MYrd3UWVEKVpphBGvgG8oTvTxq9/bDXomk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com; spf=pass smtp.mailfrom=ideasonboard.com; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b=CD9lwdS/; arc=none smtp.client-ip=213.167.242.64 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ideasonboard.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="CD9lwdS/" Received: from pendragon.ideasonboard.com (81-175-209-231.bb.dnainternet.fi [81.175.209.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id CD81D15C5; Mon, 10 Jun 2024 03:22:50 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1717982571; bh=eIXt7AudWEj+K4Mmcw3wbWGAf/H0VZOZ4hXbbO/DBJA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CD9lwdS/Hc++O8KvC6XzOObrbjWruDUA6zDMBNioCQxm/0m3bCZnLee0d+oM1nsqc DrV8CE4STThm/gNQr1f+FOfokSTEBw1IYQUayPZN8RFDOmwAZcSUhL5Zt2HvQ2ZAS2 jaQkG0V6en3phof548a0GAqGX0y7nhUjryBA9fVQ= From: Laurent Pinchart To: linux-media@vger.kernel.org Cc: Sakari Ailus , Tomi Valkeinen , Hans Verkuil Subject: [v4l-utils] [PATCH v1 3/3] utils: media-ctl: Support accessing the subdev TRY state Date: Mon, 10 Jun 2024 04:22:38 +0300 Message-ID: <20240610012238.30462-4-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.44.2 In-Reply-To: <20240610012238.30462-1-laurent.pinchart@ideasonboard.com> References: <20240610012238.30462-1-laurent.pinchart@ideasonboard.com> Precedence: bulk X-Mailing-List: linux-media@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add a -W/--which argument to media-ctl to select which state to operate on. Default to the ACTIVE state to preserve the current behaviour. Despite the fact that all values set on the TRY state are lost when media-ctl terminates, support for the TRY state is useful in order to retrieve the default configuration of subdevs, or to try configurations. Signed-off-by: Laurent Pinchart Reviewed-by: Tomi Valkeinen --- utils/media-ctl/media-ctl.c | 13 +++++++------ utils/media-ctl/options.c | 18 +++++++++++++++++- utils/media-ctl/options.h | 1 + 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/utils/media-ctl/media-ctl.c b/utils/media-ctl/media-ctl.c index 42b1bd9aaa6e..33df0880fd9b 100644 --- a/utils/media-ctl/media-ctl.c +++ b/utils/media-ctl/media-ctl.c @@ -600,7 +600,6 @@ static void media_print_topology_text(struct media_device *media, int main(int argc, char **argv) { - const enum v4l2_subdev_format_whence which = V4L2_SUBDEV_FORMAT_ACTIVE; struct media_device *media; struct media_entity *entity = NULL; int ret = -1; @@ -667,7 +666,8 @@ int main(int argc, char **argv) goto out; } - v4l2_subdev_print_format(pad->entity, pad->index, stream, which); + v4l2_subdev_print_format(pad->entity, pad->index, stream, + media_opts.which); } if (media_opts.get_dv_pad) { @@ -709,9 +709,10 @@ int main(int argc, char **argv) media_print_topology_dot(media); } else if (media_opts.print) { if (entity) - media_print_topology_text_entity(media, entity, which); + media_print_topology_text_entity(media, entity, + media_opts.which); else - media_print_topology_text(media, which); + media_print_topology_text(media, media_opts.which); } else if (entity) { const char *devname; @@ -741,7 +742,7 @@ int main(int argc, char **argv) } if (media_opts.routes) { - ret = v4l2_subdev_parse_setup_routes(media, which, + ret = v4l2_subdev_parse_setup_routes(media, media_opts.which, media_opts.routes); if (ret) { printf("Unable to setup routes: %s (%d)\n", @@ -751,7 +752,7 @@ int main(int argc, char **argv) } if (media_opts.formats) { - ret = v4l2_subdev_parse_setup_formats(media, which, + ret = v4l2_subdev_parse_setup_formats(media, media_opts.which, media_opts.formats); if (ret) { printf("Unable to setup formats: %s (%d)\n", diff --git a/utils/media-ctl/options.c b/utils/media-ctl/options.c index 3c408a1b9b06..3606525c33da 100644 --- a/utils/media-ctl/options.c +++ b/utils/media-ctl/options.c @@ -40,6 +40,7 @@ struct media_options media_opts = { .devname = MEDIA_DEVNAME_DEFAULT, + .which = V4L2_SUBDEV_FORMAT_ACTIVE, }; static void print_version() @@ -75,6 +76,7 @@ static void usage(const char *argv0) printf("-r, --reset Reset all links to inactive\n"); printf("-v, --verbose Be verbose\n"); printf(" --version Show version information\n"); + printf("-W, --which which Select the subdev state to operate on\n"); printf("\n"); printf("Links and formats are defined as\n"); printf("\tlinks = link { ',' link } ;\n"); @@ -140,6 +142,8 @@ static void usage(const char *argv0) for (i = V4L2_YCBCR_ENC_DEFAULT; i <= V4L2_YCBCR_ENC_SMPTE240M; i++) printf("\t %s\n", v4l2_subdev_ycbcr_encoding_to_string(i)); + + printf("\twhich Subdev state ('ACTIVE' or 'TRY')\n"); } #define OPT_PRINT_DOT 256 @@ -168,6 +172,7 @@ static struct option opts[] = { {"reset", 0, 0, 'r'}, {"verbose", 0, 0, 'v'}, {"version", 0, 0, OPT_VERSION}, + {"which", 1, 0, 'W'}, { }, }; @@ -244,7 +249,7 @@ int parse_cmdline(int argc, char **argv) } /* parse options */ - while ((opt = getopt_long(argc, argv, "d:e:f:hil:prvV:R:", + while ((opt = getopt_long(argc, argv, "d:e:f:hil:prvV:R:W:", opts, NULL)) != -1) { switch (opt) { case 'd': @@ -294,6 +299,17 @@ int parse_cmdline(int argc, char **argv) media_opts.routes = optarg; break; + case 'W': + if (!strcmp(optarg, "ACTIVE")) + media_opts.which = V4L2_SUBDEV_FORMAT_ACTIVE; + else if (!strcmp(optarg, "TRY")) + media_opts.which = V4L2_SUBDEV_FORMAT_TRY; + else { + printf("Invalid 'which' value '%s'\n", optarg); + return 1; + } + break; + case OPT_PRINT_DOT: media_opts.print_dot = 1; break; diff --git a/utils/media-ctl/options.h b/utils/media-ctl/options.h index 753d09347585..095729b98014 100644 --- a/utils/media-ctl/options.h +++ b/utils/media-ctl/options.h @@ -37,6 +37,7 @@ struct media_options const char *get_dv_pad; const char *dv_pad; const char *routes; + enum v4l2_subdev_format_whence which; }; extern struct media_options media_opts;