linux-media.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Niklas Söderlund" <niklas.soderlund+renesas@ragnatech.se>
To: Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
	Hans Verkuil <hverkuil@xs4all.nl>,
	linux-media@vger.kernel.org
Cc: linux-renesas-soc@vger.kernel.org,
	tomoharu.fukawa.eb@renesas.com,
	"Kieran Bingham" <kieran.bingham@ideasonboard.com>,
	"Niklas Söderlund" <niklas.soderlund+renesas@ragnatech.se>
Subject: [PATCH v11 16/32] rcar-vin: read subdevice format for crop only when needed
Date: Fri,  2 Mar 2018 02:57:35 +0100	[thread overview]
Message-ID: <20180302015751.25596-17-niklas.soderlund+renesas@ragnatech.se> (raw)
In-Reply-To: <20180302015751.25596-1-niklas.soderlund+renesas@ragnatech.se>

Instead of caching the subdevice format each time the video device
format is set read it directly when it's needed. As it turns out the
format is only needed when figuring out the max rectangle for cropping.

This simplifies the code and makes it clearer what the source format is
used for.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
---
 drivers/media/platform/rcar-vin/rcar-v4l2.c | 158 ++++++++++++++--------------
 drivers/media/platform/rcar-vin/rcar-vin.h  |  12 ---
 2 files changed, 80 insertions(+), 90 deletions(-)

diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c
index 3290e603b44cdf3a..55640c6b2a1200ca 100644
--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c
+++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c
@@ -144,67 +144,62 @@ static int rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix)
  * V4L2
  */
 
-static void rvin_reset_crop_compose(struct rvin_dev *vin)
+static int rvin_get_vin_format_from_source(struct rvin_dev *vin,
+					   struct v4l2_pix_format *pix)
 {
+	struct v4l2_subdev_format fmt = {
+		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
+		.pad = vin->digital->source_pad,
+	};
+	int ret;
+
+	ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);
+	if (ret)
+		return ret;
+
+	v4l2_fill_pix_format(pix, &fmt.format);
+
+	return rvin_format_align(vin, pix);
+}
+
+static int rvin_reset_format(struct rvin_dev *vin)
+{
+	int ret;
+
+	ret = rvin_get_vin_format_from_source(vin, &vin->format);
+	if (ret)
+		return ret;
+
 	vin->crop.top = vin->crop.left = 0;
-	vin->crop.width = vin->source.width;
-	vin->crop.height = vin->source.height;
+	vin->crop.width = vin->format.width;
+	vin->crop.height = vin->format.height;
 
 	vin->compose.top = vin->compose.left = 0;
 	vin->compose.width = vin->format.width;
 	vin->compose.height = vin->format.height;
-}
-
-static int rvin_reset_format(struct rvin_dev *vin)
-{
-	struct v4l2_subdev_format fmt = {
-		.which = V4L2_SUBDEV_FORMAT_ACTIVE,
-	};
-	struct v4l2_mbus_framefmt *mf = &fmt.format;
-	int ret;
-
-	fmt.pad = vin->digital->source_pad;
-
-	ret = v4l2_subdev_call(vin_to_source(vin), pad, get_fmt, NULL, &fmt);
-	if (ret)
-		return ret;
-
-	vin->format.width	= mf->width;
-	vin->format.height	= mf->height;
-	vin->format.colorspace	= mf->colorspace;
-	vin->format.field	= mf->field;
-
-	rvin_reset_crop_compose(vin);
-
-	vin->format.bytesperline = rvin_format_bytesperline(&vin->format);
-	vin->format.sizeimage = rvin_format_sizeimage(&vin->format);
 
 	return 0;
 }
 
-static int __rvin_try_format_source(struct rvin_dev *vin,
-				    u32 which,
-				    struct v4l2_pix_format *pix,
-				    struct rvin_source_fmt *source)
+static int rvin_try_format(struct rvin_dev *vin, u32 which,
+			   struct v4l2_pix_format *pix,
+			   struct v4l2_rect *crop, struct v4l2_rect *compose)
 {
-	struct v4l2_subdev *sd;
+	struct v4l2_subdev *sd = vin_to_source(vin);
 	struct v4l2_subdev_pad_config *pad_cfg;
 	struct v4l2_subdev_format format = {
 		.which = which,
+		.pad = vin->digital->source_pad,
 	};
 	enum v4l2_field field;
 	u32 width, height;
 	int ret;
 
-	sd = vin_to_source(vin);
-
-	v4l2_fill_mbus_format(&format.format, pix, vin->digital->code);
-
 	pad_cfg = v4l2_subdev_alloc_pad_config(sd);
 	if (pad_cfg == NULL)
 		return -ENOMEM;
 
-	format.pad = vin->digital->source_pad;
+	v4l2_fill_mbus_format(&format.format, pix, vin->digital->code);
 
 	/* Allow the video device to override field and to scale */
 	field = pix->field;
@@ -217,34 +212,34 @@ static int __rvin_try_format_source(struct rvin_dev *vin,
 
 	v4l2_fill_pix_format(pix, &format.format);
 
-	source->width = pix->width;
-	source->height = pix->height;
+	crop->top = crop->left = 0;
+	crop->width = pix->width;
+	crop->height = pix->height;
+
+	/*
+	 * If source is ALTERNATE the driver will use the VIN hardware
+	 * to INTERLACE it. The crop height then needs to be doubled.
+	 */
+	if (pix->field == V4L2_FIELD_ALTERNATE)
+		crop->height *= 2;
+
+	if (field != V4L2_FIELD_ANY)
+		pix->field = field;
 
-	pix->field = field;
 	pix->width = width;
 	pix->height = height;
 
-	vin_dbg(vin, "Source resolution: %ux%u\n", source->width,
-		source->height);
+	ret = rvin_format_align(vin, pix);
+	if (ret)
+		return ret;
 
+	compose->top = compose->left = 0;
+	compose->width = pix->width;
+	compose->height = pix->height;
 done:
 	v4l2_subdev_free_pad_config(pad_cfg);
-	return ret;
-}
 
-static int __rvin_try_format(struct rvin_dev *vin,
-			     u32 which,
-			     struct v4l2_pix_format *pix,
-			     struct rvin_source_fmt *source)
-{
-	int ret;
-
-	/* Limit to source capabilities */
-	ret = __rvin_try_format_source(vin, which, pix, source);
-	if (ret)
-		return ret;
-
-	return rvin_format_align(vin, pix);
+	return 0;
 }
 
 static int rvin_querycap(struct file *file, void *priv,
@@ -263,33 +258,30 @@ static int rvin_try_fmt_vid_cap(struct file *file, void *priv,
 				struct v4l2_format *f)
 {
 	struct rvin_dev *vin = video_drvdata(file);
-	struct rvin_source_fmt source;
+	struct v4l2_rect crop, compose;
 
-	return __rvin_try_format(vin, V4L2_SUBDEV_FORMAT_TRY, &f->fmt.pix,
-				 &source);
+	return rvin_try_format(vin, V4L2_SUBDEV_FORMAT_TRY, &f->fmt.pix, &crop,
+			       &compose);
 }
 
 static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
 			      struct v4l2_format *f)
 {
 	struct rvin_dev *vin = video_drvdata(file);
-	struct rvin_source_fmt source;
+	struct v4l2_rect crop, compose;
 	int ret;
 
 	if (vb2_is_busy(&vin->queue))
 		return -EBUSY;
 
-	ret = __rvin_try_format(vin, V4L2_SUBDEV_FORMAT_ACTIVE, &f->fmt.pix,
-				&source);
+	ret = rvin_try_format(vin, V4L2_SUBDEV_FORMAT_ACTIVE, &f->fmt.pix,
+			      &crop, &compose);
 	if (ret)
 		return ret;
 
-	vin->source.width = source.width;
-	vin->source.height = source.height;
-
 	vin->format = f->fmt.pix;
-
-	rvin_reset_crop_compose(vin);
+	vin->crop = crop;
+	vin->compose = compose;
 
 	return 0;
 }
@@ -319,6 +311,8 @@ static int rvin_g_selection(struct file *file, void *fh,
 			    struct v4l2_selection *s)
 {
 	struct rvin_dev *vin = video_drvdata(file);
+	struct v4l2_pix_format pix;
+	int ret;
 
 	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -326,9 +320,12 @@ static int rvin_g_selection(struct file *file, void *fh,
 	switch (s->target) {
 	case V4L2_SEL_TGT_CROP_BOUNDS:
 	case V4L2_SEL_TGT_CROP_DEFAULT:
+		ret = rvin_get_vin_format_from_source(vin, &pix);
+		if (ret)
+			return ret;
 		s->r.left = s->r.top = 0;
-		s->r.width = vin->source.width;
-		s->r.height = vin->source.height;
+		s->r.width = pix.width;
+		s->r.height = pix.height;
 		break;
 	case V4L2_SEL_TGT_CROP:
 		s->r = vin->crop;
@@ -353,6 +350,7 @@ static int rvin_s_selection(struct file *file, void *fh,
 			    struct v4l2_selection *s)
 {
 	struct rvin_dev *vin = video_drvdata(file);
+	struct v4l2_pix_format pix;
 	const struct rvin_video_format *fmt;
 	struct v4l2_rect r = s->r;
 	struct v4l2_rect max_rect;
@@ -360,6 +358,7 @@ static int rvin_s_selection(struct file *file, void *fh,
 		.width = 6,
 		.height = 2,
 	};
+	int ret;
 
 	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 		return -EINVAL;
@@ -369,22 +368,25 @@ static int rvin_s_selection(struct file *file, void *fh,
 	switch (s->target) {
 	case V4L2_SEL_TGT_CROP:
 		/* Can't crop outside of source input */
+		ret = rvin_get_vin_format_from_source(vin, &pix);
+		if (ret)
+			return ret;
 		max_rect.top = max_rect.left = 0;
-		max_rect.width = vin->source.width;
-		max_rect.height = vin->source.height;
+		max_rect.width = pix.width;
+		max_rect.height = pix.height;
 		v4l2_rect_map_inside(&r, &max_rect);
 
-		v4l_bound_align_image(&r.width, 2, vin->source.width, 1,
-				      &r.height, 4, vin->source.height, 2, 0);
+		v4l_bound_align_image(&r.width, 2, pix.width, 1,
+				      &r.height, 4, pix.height, 2, 0);
 
-		r.top  = clamp_t(s32, r.top, 0, vin->source.height - r.height);
-		r.left = clamp_t(s32, r.left, 0, vin->source.width - r.width);
+		r.top  = clamp_t(s32, r.top, 0, pix.height - r.height);
+		r.left = clamp_t(s32, r.left, 0, pix.width - r.width);
 
 		vin->crop = s->r = r;
 
 		vin_dbg(vin, "Cropped %dx%d@%d:%d of %dx%d\n",
 			r.width, r.height, r.left, r.top,
-			vin->source.width, vin->source.height);
+			pix.width, pix.height);
 		break;
 	case V4L2_SEL_TGT_COMPOSE:
 		/* Make sure compose rect fits inside output format */
diff --git a/drivers/media/platform/rcar-vin/rcar-vin.h b/drivers/media/platform/rcar-vin/rcar-vin.h
index 8daba9db0e927a49..39051da31650bd79 100644
--- a/drivers/media/platform/rcar-vin/rcar-vin.h
+++ b/drivers/media/platform/rcar-vin/rcar-vin.h
@@ -48,16 +48,6 @@ enum rvin_dma_state {
 	STOPPING,
 };
 
-/**
- * struct rvin_source_fmt - Source information
- * @width:	Width from source
- * @height:	Height from source
- */
-struct rvin_source_fmt {
-	u32 width;
-	u32 height;
-};
-
 /**
  * struct rvin_video_format - Data format stored in memory
  * @fourcc:	Pixelformat
@@ -124,7 +114,6 @@ struct rvin_info {
  * @sequence:		V4L2 buffers sequence number
  * @state:		keeps track of operation state
  *
- * @source:		active format from the video source
  * @format:		active V4L2 pixel format
  *
  * @crop:		active cropping
@@ -151,7 +140,6 @@ struct rvin_dev {
 	unsigned int sequence;
 	enum rvin_dma_state state;
 
-	struct rvin_source_fmt source;
 	struct v4l2_pix_format format;
 
 	struct v4l2_rect crop;
-- 
2.16.2

  parent reply	other threads:[~2018-03-02  1:59 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-02  1:57 [PATCH v11 00/32] rcar-vin: Add Gen3 with media controller Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 01/32] dt-bindings: media: rcar_vin: Reverse SoC part number list Niklas Söderlund
2018-03-02  9:27   ` Laurent Pinchart
2018-03-02  1:57 ` [PATCH v11 02/32] dt-bindings: media: rcar_vin: add device tree support for r8a774[35] Niklas Söderlund
2018-03-02  9:27   ` Laurent Pinchart
2018-03-02  1:57 ` [PATCH v11 03/32] rcar-vin: add Gen3 devicetree bindings documentation Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 04/32] rcar-vin: rename poorly named initialize and cleanup functions Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 05/32] rcar-vin: unregister video device on driver removal Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 06/32] rcar-vin: move subdevice handling to async callbacks Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 07/32] rcar-vin: move model information to own struct Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 08/32] rcar-vin: move max width and height information to chip information Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 09/32] rcar-vin: move functions regarding scaling Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 10/32] rcar-vin: all Gen2 boards can scale simplify logic Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 11/32] rcar-vin: set a default field to fallback on Niklas Söderlund
2018-03-02  9:29   ` Laurent Pinchart
2018-03-02  1:57 ` [PATCH v11 12/32] rcar-vin: fix handling of single field frames (top, bottom and alternate fields) Niklas Söderlund
2018-03-02 10:48   ` Laurent Pinchart
2018-03-03 16:23     ` Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 13/32] rcar-vin: update bytesperline and sizeimage calculation Niklas Söderlund
2018-03-02  9:44   ` Laurent Pinchart
2018-03-02  1:57 ` [PATCH v11 14/32] rcar-vin: align pixelformat check Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 15/32] rcar-vin: break out format alignment and checking Niklas Söderlund
2018-03-02  9:53   ` Laurent Pinchart
2018-03-03 16:11     ` Niklas Söderlund
2018-03-02  1:57 ` Niklas Söderlund [this message]
2018-03-02 11:06   ` [PATCH v11 16/32] rcar-vin: read subdevice format for crop only when needed Laurent Pinchart
2018-03-03 17:04     ` Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 17/32] rcar-vin: move media bus configuration to struct rvin_info Niklas Söderlund
2018-03-02 11:26   ` Laurent Pinchart
2018-03-03 13:57     ` Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 18/32] rcar-vin: enable Gen3 hardware configuration Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 19/32] rcar-vin: add function to manipulate Gen3 chsel value Niklas Söderlund
2018-03-02 11:31   ` Laurent Pinchart
2018-03-03 14:03     ` Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 20/32] rcar-vin: add flag to switch to media controller mode Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 21/32] rcar-vin: use different v4l2 operations in " Niklas Söderlund
2018-03-02 11:39   ` Laurent Pinchart
2018-03-02  1:57 ` [PATCH v11 22/32] rcar-vin: force default colorspace for media centric mode Niklas Söderlund
2018-03-02  9:59   ` Laurent Pinchart
2018-03-03 15:19     ` Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 23/32] rcar-vin: prepare for media controller mode initialization Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 24/32] rcar-vin: add group allocator functions Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 25/32] rcar-vin: change name of video device Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 26/32] rcar-vin: add chsel information to rvin_info Niklas Söderlund
2018-03-02 11:43   ` Laurent Pinchart
2018-03-02  1:57 ` [PATCH v11 27/32] rcar-vin: parse Gen3 OF and setup media graph Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 28/32] rcar-vin: add link notify for Gen3 Niklas Söderlund
2018-03-02 12:00   ` Laurent Pinchart
2018-03-03 15:49     ` Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 29/32] rcar-vin: extend {start,stop}_streaming to work with media controller Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 30/32] rcar-vin: enable support for r8a7795 Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 31/32] rcar-vin: enable support for r8a7796 Niklas Söderlund
2018-03-02  1:57 ` [PATCH v11 32/32] rcar-vin: enable support for r8a77970 Niklas Söderlund

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=20180302015751.25596-17-niklas.soderlund+renesas@ragnatech.se \
    --to=niklas.soderlund+renesas@ragnatech.se \
    --cc=hverkuil@xs4all.nl \
    --cc=kieran.bingham@ideasonboard.com \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-renesas-soc@vger.kernel.org \
    --cc=tomoharu.fukawa.eb@renesas.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).