OSDN Git Service

media: rcar-vin: Do not cache remote rectangle
authorNiklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Sun, 9 Oct 2022 18:35:49 +0000 (19:35 +0100)
committerMauro Carvalho Chehab <mchehab@kernel.org>
Fri, 25 Nov 2022 10:59:32 +0000 (10:59 +0000)
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>
drivers/media/platform/renesas/rcar-vin/rcar-v4l2.c
drivers/media/platform/renesas/rcar-vin/rcar-vin.h

index 576059f..a0b398a 100644 (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 */
index 1f94589..469c4aa 100644 (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;