summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJanusz Krzysztofik <jmkrzyszt@gmail.com>2020-05-04 00:06:18 +0200
committerMauro Carvalho Chehab <mchehab@kernel.org>2022-01-28 19:32:48 +0100
commit985d2d7a482e9b64ef9643702b066da9cbd6ae8e (patch)
tree49b8d22bcd2ade157c8b008dc130f01f72cb96dd
parentc74052646496ffe0bc606152e6b9653137020cbf (diff)
downloadlinux-985d2d7a482e9b64ef9643702b066da9cbd6ae8e.tar.bz2
media: ov6650: Fix crop rectangle affected by set format
According to subdevice interface specification found in V4L2 API documentation, set format pad operations should not affect image geometry set in preceding image processing steps. Unfortunately, that requirement is not respected by the driver implementation of set format as it was not the case when that code was still implementing a pair of now obsolete .s_mbus_fmt() / .try_mbus_fmt() video operations before they have been merged and reused as an implementation of .set_fmt() pad operation by commit 717fd5b4907a ("[media] v4l2: replace try_mbus_fmt by set_fmt"). Exclude non-compliant crop rectangle adjustments from set format try, as well as a call to .set_selection() from set format active processing path, so only frame scaling is applied as needed and crop rectangle is no longer modified. [Sakari Ailus: Rebase on subdev state patches] Fixes: 717fd5b4907a ("[media] v4l2: replace try_mbus_fmt by set_fmt") Signed-off-by: Janusz Krzysztofik <jmkrzyszt@gmail.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
-rw-r--r--drivers/media/i2c/ov6650.c28
1 files changed, 4 insertions, 24 deletions
diff --git a/drivers/media/i2c/ov6650.c b/drivers/media/i2c/ov6650.c
index 3672169d5386..9887f486ca5f 100644
--- a/drivers/media/i2c/ov6650.c
+++ b/drivers/media/i2c/ov6650.c
@@ -693,11 +693,7 @@ static int ov6650_set_fmt(struct v4l2_subdev *sd,
struct v4l2_mbus_framefmt *mf = &format->format;
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct ov6650 *priv = to_ov6650(client);
- struct v4l2_subdev_selection sel = {
- .which = V4L2_SUBDEV_FORMAT_ACTIVE,
- .target = V4L2_SEL_TGT_CROP,
- };
- struct v4l2_rect *crop = &sel.r;
+ struct v4l2_rect *crop;
bool half_scale;
if (format->pad)
@@ -721,24 +717,13 @@ static int ov6650_set_fmt(struct v4l2_subdev *sd,
}
if (format->which == V4L2_SUBDEV_FORMAT_TRY)
- *crop = sd_state->pads->try_crop;
+ crop = &sd_state->pads->try_crop;
else
- *crop = priv->rect;
+ crop = &priv->rect;
half_scale = !is_unscaled_ok(mf->width, mf->height, crop);
- /* adjust new crop rectangle position against its current center */
- crop->left += (crop->width - (mf->width << half_scale)) / 2;
- crop->top += (crop->height - (mf->height << half_scale)) / 2;
- /* adjust new crop rectangle size */
- crop->width = mf->width << half_scale;
- crop->height = mf->height << half_scale;
-
if (format->which == V4L2_SUBDEV_FORMAT_TRY) {
- /* store new crop rectangle, hadware bound, in pad config */
- ov6650_bind_align_crop_rectangle(crop);
- sd_state->pads->try_crop = *crop;
-
/* store new mbus frame format code and size in pad config */
sd_state->pads->try_fmt.width = crop->width >> half_scale;
sd_state->pads->try_fmt.height = crop->height >> half_scale;
@@ -751,12 +736,7 @@ static int ov6650_set_fmt(struct v4l2_subdev *sd,
mf->code = sd_state->pads->try_fmt.code;
} else {
- int ret;
-
- /* apply new crop rectangle */
- ret = ov6650_set_selection(sd, NULL, &sel);
- if (ret)
- return ret;
+ int ret = 0;
/* apply new media bus frame format and scaling if changed */
if (mf->code != priv->code || half_scale != priv->half_scale)