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:
parent
0ed554fd76
commit
f42a323252
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue