@@ -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;
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> --- .../platform/renesas/rcar-vin/rcar-v4l2.c | 84 ++++++++++++++----- .../platform/renesas/rcar-vin/rcar-vin.h | 2 - 2 files changed, 65 insertions(+), 21 deletions(-)