media: rcar-vin: Do not cache remote rectangle

Prepare for scaling support in the media controller part of the driver
by not caching the remote rectangle. Mimic the omap3isp and look it up
each time it's needed.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
Niklas Söderlund 2022-10-09 19:35:49 +01:00 committed by Mauro Carvalho Chehab
parent 0ed554fd76
commit f42a323252
2 changed files with 65 additions and 21 deletions

View File

@ -226,10 +226,10 @@ static int rvin_reset_format(struct rvin_dev *vin)
v4l2_fill_pix_format(&vin->format, &fmt.format);
vin->src_rect.top = 0;
vin->src_rect.left = 0;
vin->src_rect.width = vin->format.width;
vin->src_rect.height = vin->format.height;
vin->crop.top = 0;
vin->crop.left = 0;
vin->crop.width = vin->format.width;
vin->crop.height = vin->format.height;
/* Make use of the hardware interlacer by default. */
if (vin->format.field == V4L2_FIELD_ALTERNATE) {
@ -239,8 +239,6 @@ static int rvin_reset_format(struct rvin_dev *vin)
rvin_format_align(vin, &vin->format);
vin->crop = vin->src_rect;
vin->compose.top = 0;
vin->compose.left = 0;
vin->compose.width = vin->format.width;
@ -349,7 +347,6 @@ static int rvin_s_fmt_vid_cap(struct file *file, void *priv,
v4l2_rect_map_inside(&vin->crop, &src_rect);
v4l2_rect_map_inside(&vin->compose, &fmt_rect);
vin->src_rect = src_rect;
return 0;
}
@ -428,10 +425,57 @@ static int rvin_enum_fmt_vid_cap(struct file *file, void *priv,
return -EINVAL;
}
static int rvin_remote_rectangle(struct rvin_dev *vin, struct v4l2_rect *rect)
{
struct v4l2_subdev_format fmt = {
.which = V4L2_SUBDEV_FORMAT_ACTIVE,
};
struct v4l2_subdev *sd;
unsigned int index;
int ret;
if (vin->info->use_mc) {
struct media_pad *pad = media_pad_remote_pad_first(&vin->pad);
if (!pad)
return -EINVAL;
sd = media_entity_to_v4l2_subdev(pad->entity);
index = pad->index;
} else {
sd = vin_to_source(vin);
index = vin->parallel.source_pad;
}
fmt.pad = index;
ret = v4l2_subdev_call(sd, pad, get_fmt, NULL, &fmt);
if (ret)
return ret;
rect->left = rect->top = 0;
rect->width = fmt.format.width;
rect->height = fmt.format.height;
if (fmt.format.field == V4L2_FIELD_ALTERNATE) {
switch (vin->format.field) {
case V4L2_FIELD_INTERLACED_TB:
case V4L2_FIELD_INTERLACED_BT:
case V4L2_FIELD_INTERLACED:
case V4L2_FIELD_SEQ_TB:
case V4L2_FIELD_SEQ_BT:
rect->height *= 2;
break;
}
}
return 0;
}
static int rvin_g_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{
struct rvin_dev *vin = video_drvdata(file);
int ret;
if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@ -439,9 +483,10 @@ 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:
s->r.left = s->r.top = 0;
s->r.width = vin->src_rect.width;
s->r.height = vin->src_rect.height;
ret = rvin_remote_rectangle(vin, &s->r);
if (ret)
return ret;
break;
case V4L2_SEL_TGT_CROP:
s->r = vin->crop;
@ -473,6 +518,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;
@ -482,23 +528,23 @@ 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 */
max_rect.top = max_rect.left = 0;
max_rect.width = vin->src_rect.width;
max_rect.height = vin->src_rect.height;
ret = rvin_remote_rectangle(vin, &max_rect);
if (ret)
return ret;
v4l2_rect_map_inside(&r, &max_rect);
v4l_bound_align_image(&r.width, 6, vin->src_rect.width, 0,
&r.height, 2, vin->src_rect.height, 0, 0);
v4l_bound_align_image(&r.width, 6, max_rect.width, 0,
&r.height, 2, max_rect.height, 0, 0);
r.top = clamp_t(s32, r.top, 0,
vin->src_rect.height - r.height);
r.left = clamp_t(s32, r.left, 0, vin->src_rect.width - r.width);
r.top = clamp_t(s32, r.top, 0, max_rect.height - r.height);
r.left = clamp_t(s32, r.left, 0, max_rect.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->src_rect.width, vin->src_rect.height);
max_rect.width, max_rect.height);
break;
case V4L2_SEL_TGT_COMPOSE:
/* Make sure compose rect fits inside output format */

View File

@ -203,7 +203,6 @@ struct rvin_info {
*
* @crop: active cropping
* @compose: active composing
* @src_rect: active size of the video source
* @std: active video standard of the video source
*
* @alpha: Alpha component to fill in for supported pixel formats
@ -247,7 +246,6 @@ struct rvin_dev {
struct v4l2_rect crop;
struct v4l2_rect compose;
struct v4l2_rect src_rect;
v4l2_std_id std;
unsigned int alpha;