Commit f9331d11 authored by Sylwester Nawrocki's avatar Sylwester Nawrocki Committed by Mauro Carvalho Chehab

[media] s5p-fimc: Replace the crop ioctls with VIDIOC_S/G_SELECTION

Add support for cropping and composition setup on the video capture
node through VIDIOC_S/G_SELECTION ioctls. S/G_CROP, CROPCAP ioctls
are still  supported for applications since the core will translate
them to *_selection handler calls.
Signed-off-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 3b4c34aa
...@@ -1035,52 +1035,101 @@ static int fimc_cap_prepare_buf(struct file *file, void *priv, ...@@ -1035,52 +1035,101 @@ static int fimc_cap_prepare_buf(struct file *file, void *priv,
return vb2_prepare_buf(&fimc->vid_cap.vbq, b); return vb2_prepare_buf(&fimc->vid_cap.vbq, b);
} }
static int fimc_cap_cropcap(struct file *file, void *fh, static int fimc_cap_g_selection(struct file *file, void *fh,
struct v4l2_cropcap *cr) struct v4l2_selection *s)
{ {
struct fimc_dev *fimc = video_drvdata(file); struct fimc_dev *fimc = video_drvdata(file);
struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; struct fimc_ctx *ctx = fimc->vid_cap.ctx;
struct fimc_frame *f = &ctx->s_frame;
if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
return -EINVAL; return -EINVAL;
cr->bounds.left = 0; switch (s->target) {
cr->bounds.top = 0; case V4L2_SEL_TGT_COMPOSE_DEFAULT:
cr->bounds.width = f->o_width; case V4L2_SEL_TGT_COMPOSE_BOUNDS:
cr->bounds.height = f->o_height; f = &ctx->d_frame;
cr->defrect = cr->bounds; case V4L2_SEL_TGT_CROP_BOUNDS:
case V4L2_SEL_TGT_CROP_DEFAULT:
s->r.left = 0;
s->r.top = 0;
s->r.width = f->o_width;
s->r.height = f->o_height;
return 0;
case V4L2_SEL_TGT_COMPOSE_ACTIVE:
f = &ctx->d_frame;
case V4L2_SEL_TGT_CROP_ACTIVE:
s->r.left = f->offs_h;
s->r.top = f->offs_v;
s->r.width = f->width;
s->r.height = f->height;
return 0; return 0;
}
return -EINVAL;
} }
static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
{ {
struct fimc_dev *fimc = video_drvdata(file); if (a->left < b->left || a->top < b->top)
struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; return 0;
if (a->left + a->width > b->left + b->width)
cr->c.left = f->offs_h;
cr->c.top = f->offs_v;
cr->c.width = f->width;
cr->c.height = f->height;
return 0; return 0;
if (a->top + a->height > b->top + b->height)
return 0;
return 1;
} }
static int fimc_cap_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) static int fimc_cap_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{ {
struct fimc_dev *fimc = video_drvdata(file); struct fimc_dev *fimc = video_drvdata(file);
struct fimc_ctx *ctx = fimc->vid_cap.ctx; struct fimc_ctx *ctx = fimc->vid_cap.ctx;
struct fimc_frame *ff; struct v4l2_rect rect = s->r;
struct fimc_frame *f;
unsigned long flags; unsigned long flags;
unsigned int pad;
fimc_capture_try_crop(ctx, &cr->c, FIMC_SD_PAD_SINK); if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
ff = &ctx->s_frame; return -EINVAL;
switch (s->target) {
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
case V4L2_SEL_TGT_COMPOSE_ACTIVE:
f = &ctx->d_frame;
pad = FIMC_SD_PAD_SOURCE;
break;
case V4L2_SEL_TGT_CROP_BOUNDS:
case V4L2_SEL_TGT_CROP_DEFAULT:
case V4L2_SEL_TGT_CROP_ACTIVE:
f = &ctx->s_frame;
pad = FIMC_SD_PAD_SINK;
break;
default:
return -EINVAL;
}
fimc_capture_try_crop(ctx, &rect, pad);
if (s->flags & V4L2_SEL_FLAG_LE &&
!enclosed_rectangle(&rect, &s->r))
return -ERANGE;
if (s->flags & V4L2_SEL_FLAG_GE &&
!enclosed_rectangle(&s->r, &rect))
return -ERANGE;
s->r = rect;
spin_lock_irqsave(&fimc->slock, flags); spin_lock_irqsave(&fimc->slock, flags);
set_frame_crop(ff, cr->c.left, cr->c.top, cr->c.width, cr->c.height); set_frame_crop(f, s->r.left, s->r.top, s->r.width,
set_bit(ST_CAPT_APPLY_CFG, &fimc->state); s->r.height);
spin_unlock_irqrestore(&fimc->slock, flags); spin_unlock_irqrestore(&fimc->slock, flags);
set_bit(ST_CAPT_APPLY_CFG, &fimc->state);
return 0; return 0;
} }
...@@ -1104,9 +1153,8 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { ...@@ -1104,9 +1153,8 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
.vidioc_streamon = fimc_cap_streamon, .vidioc_streamon = fimc_cap_streamon,
.vidioc_streamoff = fimc_cap_streamoff, .vidioc_streamoff = fimc_cap_streamoff,
.vidioc_g_crop = fimc_cap_g_crop, .vidioc_g_selection = fimc_cap_g_selection,
.vidioc_s_crop = fimc_cap_s_crop, .vidioc_s_selection = fimc_cap_s_selection,
.vidioc_cropcap = fimc_cap_cropcap,
.vidioc_enum_input = fimc_cap_enum_input, .vidioc_enum_input = fimc_cap_enum_input,
.vidioc_s_input = fimc_cap_s_input, .vidioc_s_input = fimc_cap_s_input,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment