All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pratyush Yadav <p.yadav@ti.com>
To: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
Cc: <linux-media@vger.kernel.org>, <sakari.ailus@linux.intel.com>,
	Jacopo Mondi <jacopo+renesas@jmondi.org>,
	Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
	<niklas.soderlund+renesas@ragnatech.se>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	Hans Verkuil <hverkuil-cisco@xs4all.nl>
Subject: Re: [PATCH v1 3/4] media-ctl: add support for routes and streams
Date: Mon, 21 Mar 2022 16:07:34 +0530	[thread overview]
Message-ID: <20220321103734.yl6xdidu2c5rc26x@ti.com> (raw)
In-Reply-To: <20211130141815.892354-4-tomi.valkeinen@ideasonboard.com>

Hi Tomi,

On 30/11/21 04:18PM, Tomi Valkeinen wrote:
> Add support to get and set subdev routes and to get and set
> configurations per stream.
> 
> Based on work from Sakari Ailus <sakari.ailus@linux.intel.com>.
> 
> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>

I tried this on TI's downstream fork with your routing patches. It works 
fine for setting and viewing formats and routes.

Tested-by: Pratyush Yadav <p.yadav@ti.com>

I have not gone through the code too thoroughly. A few small things I 
noticed below.

> ---
>  utils/media-ctl/libmediactl.c   |  41 +++++
>  utils/media-ctl/libv4l2subdev.c | 256 ++++++++++++++++++++++++++++----
>  utils/media-ctl/media-ctl.c     | 113 +++++++++++---
>  utils/media-ctl/mediactl.h      |  16 ++
>  utils/media-ctl/options.c       |  15 +-
>  utils/media-ctl/options.h       |   1 +
>  utils/media-ctl/v4l2subdev.h    |  58 +++++++-
>  7 files changed, 444 insertions(+), 56 deletions(-)
> 
[...]
> +int v4l2_subdev_get_routing(struct media_entity *entity,
> +			    struct v4l2_subdev_route **routes,
> +			    unsigned int *num_routes)
> +{
> +	struct v4l2_subdev_routing routing = { 0 };
> +	struct v4l2_subdev_route *r;
> +	int ret;
> +
> +	ret = v4l2_subdev_open(entity);
> +	if (ret < 0)
> +		return ret;
> +
> +	routing.which = V4L2_SUBDEV_FORMAT_ACTIVE;
> +
> +	ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_ROUTING, &routing);
> +	if (ret == -1 && errno != ENOSPC)
> +		return -errno;
> +
> +	r = calloc(routing.num_routes, sizeof(*r));
> +	if (!r)

calloc man page says:

  If nmemb or size is 0, then calloc() returns either NULL, or a unique 
  pointer value that can later be successfully passed to free().

So if a subdev reports 0 routes then you could end up with a non-NULL 
pointer that you should not use, other than to pass to free(). I don't 
know if any implementation out there does actually return anything other 
than NULL though. I suggest explicitly checking for num_routes == 0 to 
avoid all this.

> +		return -ENOMEM;
> +
> +	routing.routes = (uintptr_t)r;
> +	ret = ioctl(entity->fd, VIDIOC_SUBDEV_G_ROUTING, &routing);
> +	if (ret) {
> +		free(r);
> +		return ret;
> +	}
> +
> +	*num_routes = routing.num_routes;
> +	*routes = r;
> +
> +	return 0;
> +}
> +
>  int v4l2_subdev_get_dv_timings_caps(struct media_entity *entity,
>  	struct v4l2_dv_timings_cap *caps)
>  {
[...]
> @@ -306,6 +370,135 @@ int v4l2_subdev_set_frame_interval(struct media_entity *entity,
>  	return 0;
>  }
>  
> +int v4l2_subdev_parse_setup_routes(struct media_device *media, const char *p)
> +{
> +	struct media_entity *entity;
> +	struct v4l2_subdev_route *routes;
> +	unsigned int num_routes;
> +	char *end;
> +	int ret;
> +	int i;
> +
> +	entity = media_parse_entity(media, p, &end);
> +	if (!entity)
> +		return -EINVAL;
> +
> +	p = end;
> +
> +	if (*p != '[') {
> +		media_dbg(media, "Expected '['\n");
> +		return -EINVAL;
> +	}
> +
> +	p++;
> +
> +	routes = calloc(256, sizeof(routes[0]));

You are not checking for NULL here.

> +	num_routes = 0;
> +
> +	while (*p != 0) {
> +		struct v4l2_subdev_route *r = &routes[num_routes];
> +
> +		/* sink pad/stream */
> +
> +		r->sink_pad = strtoul(p, &end, 10);
> +
> +		if (*end != '/') {
> +			media_dbg(media, "Expected '/'\n");
> +			return -EINVAL;
> +		}
> +
> +		p = end + 1;
> +
> +		r->sink_stream = strtoul(p, &end, 10);
> +
> +		for (; isspace(*end); ++end);
> +
> +		if (end[0] != '-' || end[1] != '>') {
> +			media_dbg(media, "Expected '->'\n");
> +			return -EINVAL;
> +		}
> +		p = end + 2;
> +
> +		/* source pad/stream */
> +
> +		r->source_pad = strtoul(p, &end, 10);
> +
> +		if (*end != '/') {
> +			media_dbg(media, "Expected '/'\n");
> +			return -EINVAL;
> +		}
> +
> +		p = end + 1;
> +
> +		r->source_stream = strtoul(p, &end, 10);
> +
> +		/* flags */
> +
> +		for (; isspace(*end); ++end);
> +
> +		if (*end != '[') {
> +			media_dbg(media, "Expected '['\n");
> +			return -EINVAL;
> +		}
> +
> +		for (end++; isspace(*end); ++end);
> +
> +		p = end;
> +
> +		r->flags = strtoul(p, &end, 0);
> +
> +		if (r->flags & ~(V4L2_SUBDEV_ROUTE_FL_ACTIVE |
> +				 V4L2_SUBDEV_ROUTE_FL_IMMUTABLE |
> +				 V4L2_SUBDEV_ROUTE_FL_SOURCE)) {
> +			media_dbg(media, "Bad route flags %#x\n", r->flags);
> +			return -EINVAL;
> +		}
> +
> +		for (; isspace(*end); ++end);
> +
> +		if (*end != ']') {
> +			media_dbg(media, "Expected ']'\n");
> +			return -EINVAL;
> +		}
> +		end++;
> +
> +		p = end;
> +
> +		num_routes++;
> +
> +		if (*p == ',') {
> +			p++;
> +			continue;
> +		}
> +
> +		break;
> +	}
> +
> +	if (*p != ']') {
> +		media_dbg(media, "Expected ']'\n");
> +		return -EINVAL;
> +	}
> +
> +	for (i = 0; i < num_routes; ++i) {
> +		struct v4l2_subdev_route *r = &routes[i];
> +
> +		media_dbg(entity->media,
> +			  "Setting up route %s : %u/%u -> %u/%u, flags 0x%8.8x\n",
> +			  entity->info.name,
> +			  r->sink_pad, r->sink_stream,
> +			  r->source_pad, r->source_stream,
> +			  r->flags);
> +	}
> +
> +	ret = v4l2_subdev_set_routing(entity, routes, num_routes);
> +	if (ret) {
> +		printf("VIDIOC_SUBDEV_S_ROUTING failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
>  static int v4l2_subdev_parse_format(struct media_device *media,
>  				    struct v4l2_mbus_framefmt *format,
>  				    const char *p, char **endp)
[...]

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

  reply	other threads:[~2022-03-21 10:37 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-30 14:18 [PATCH v1 0/4] v4l-utils: support multiplexed streams Tomi Valkeinen
2021-11-30 14:18 ` [PATCH v1 1/4] v4l2-utils: update Linux headers for " Tomi Valkeinen
2021-12-01 17:50   ` Laurent Pinchart
2021-12-01 18:53     ` Tomi Valkeinen
2021-11-30 14:18 ` [PATCH v1 2/4] v4l2-ctl: Add routing and streams support Tomi Valkeinen
2021-11-30 14:18 ` [PATCH v1 3/4] media-ctl: add support for routes and streams Tomi Valkeinen
2022-03-21 10:37   ` Pratyush Yadav [this message]
2022-03-21 10:45   ` Laurent Pinchart
2022-07-14 12:04     ` Tomi Valkeinen
2021-11-30 14:18 ` [PATCH v1 4/4] v4l2-ctl/compliance: add routing and streams multiplexed streams Tomi Valkeinen
2021-12-01  3:46 ` [PATCH v1 0/4] v4l-utils: support " Laurent Pinchart
2021-12-01  6:28   ` Tomi Valkeinen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220321103734.yl6xdidu2c5rc26x@ti.com \
    --to=p.yadav@ti.com \
    --cc=hverkuil-cisco@xs4all.nl \
    --cc=jacopo+renesas@jmondi.org \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=niklas.soderlund+renesas@ragnatech.se \
    --cc=sakari.ailus@linux.intel.com \
    --cc=tomi.valkeinen@ideasonboard.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.