Commit 158efdee authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

media: exynos4-is: convert g/s_crop to g/s_selection

Replace g/s_crop by g/s_selection and set the V4L2_FL_QUIRK_INVERTED_CROP
flag since this is one of the old drivers that predates the selection
API. Those old drivers allowed g_crop when it really shouldn't have since
g_crop returns a compose rectangle instead of a crop rectangle for the
CAPTURE stream, and vice versa for the OUTPUT stream.

Also drop the now unused vidioc_cropcap.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Reviewed-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Tested-by: default avatarSylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
parent 8edf27c2
...@@ -596,12 +596,14 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx, ...@@ -596,12 +596,14 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
{ {
struct fimc_frame *frame; struct fimc_frame *frame;
if (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE == type) { if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE ||
type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
if (fimc_ctx_state_is_set(FIMC_CTX_M2M, ctx)) if (fimc_ctx_state_is_set(FIMC_CTX_M2M, ctx))
frame = &ctx->s_frame; frame = &ctx->s_frame;
else else
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} else if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == type) { } else if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE ||
type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
frame = &ctx->d_frame; frame = &ctx->d_frame;
} else { } else {
v4l2_err(ctx->fimc_dev->v4l2_dev, v4l2_err(ctx->fimc_dev->v4l2_dev,
......
...@@ -383,60 +383,80 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh, ...@@ -383,60 +383,80 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *fh,
return 0; return 0;
} }
static int fimc_m2m_cropcap(struct file *file, void *fh, static int fimc_m2m_g_selection(struct file *file, void *fh,
struct v4l2_cropcap *cr) struct v4l2_selection *s)
{ {
struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_ctx *ctx = fh_to_ctx(fh);
struct fimc_frame *frame; struct fimc_frame *frame;
frame = ctx_get_frame(ctx, cr->type); frame = ctx_get_frame(ctx, s->type);
if (IS_ERR(frame)) if (IS_ERR(frame))
return PTR_ERR(frame); return PTR_ERR(frame);
cr->bounds.left = 0; switch (s->target) {
cr->bounds.top = 0; case V4L2_SEL_TGT_CROP:
cr->bounds.width = frame->o_width; case V4L2_SEL_TGT_CROP_DEFAULT:
cr->bounds.height = frame->o_height; case V4L2_SEL_TGT_CROP_BOUNDS:
cr->defrect = cr->bounds; if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
return -EINVAL;
return 0; break;
} case V4L2_SEL_TGT_COMPOSE:
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) case V4L2_SEL_TGT_COMPOSE_BOUNDS:
{ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
struct fimc_ctx *ctx = fh_to_ctx(fh); return -EINVAL;
struct fimc_frame *frame; break;
default:
frame = ctx_get_frame(ctx, cr->type); return -EINVAL;
if (IS_ERR(frame)) }
return PTR_ERR(frame);
cr->c.left = frame->offs_h;
cr->c.top = frame->offs_v;
cr->c.width = frame->width;
cr->c.height = frame->height;
switch (s->target) {
case V4L2_SEL_TGT_CROP:
case V4L2_SEL_TGT_COMPOSE:
s->r.left = frame->offs_h;
s->r.top = frame->offs_v;
s->r.width = frame->width;
s->r.height = frame->height;
break;
case V4L2_SEL_TGT_CROP_DEFAULT:
case V4L2_SEL_TGT_CROP_BOUNDS:
case V4L2_SEL_TGT_COMPOSE_DEFAULT:
case V4L2_SEL_TGT_COMPOSE_BOUNDS:
s->r.left = 0;
s->r.top = 0;
s->r.width = frame->o_width;
s->r.height = frame->o_height;
break;
default:
return -EINVAL;
}
return 0; return 0;
} }
static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr) static int fimc_m2m_try_selection(struct fimc_ctx *ctx,
struct v4l2_selection *s)
{ {
struct fimc_dev *fimc = ctx->fimc_dev; struct fimc_dev *fimc = ctx->fimc_dev;
struct fimc_frame *f; struct fimc_frame *f;
u32 min_size, halign, depth = 0; u32 min_size, halign, depth = 0;
int i; int i;
if (cr->c.top < 0 || cr->c.left < 0) { if (s->r.top < 0 || s->r.left < 0) {
v4l2_err(&fimc->m2m.vfd, v4l2_err(&fimc->m2m.vfd,
"doesn't support negative values for top & left\n"); "doesn't support negative values for top & left\n");
return -EINVAL; return -EINVAL;
} }
if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
f = &ctx->d_frame; f = &ctx->d_frame;
else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) if (s->target != V4L2_SEL_TGT_COMPOSE)
return -EINVAL;
} else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
f = &ctx->s_frame; f = &ctx->s_frame;
else if (s->target != V4L2_SEL_TGT_CROP)
return -EINVAL;
} else {
return -EINVAL; return -EINVAL;
}
min_size = (f == &ctx->s_frame) ? min_size = (f == &ctx->s_frame) ?
fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize; fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
...@@ -450,61 +470,61 @@ static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr) ...@@ -450,61 +470,61 @@ static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
for (i = 0; i < f->fmt->memplanes; i++) for (i = 0; i < f->fmt->memplanes; i++)
depth += f->fmt->depth[i]; depth += f->fmt->depth[i];
v4l_bound_align_image(&cr->c.width, min_size, f->o_width, v4l_bound_align_image(&s->r.width, min_size, f->o_width,
ffs(min_size) - 1, ffs(min_size) - 1,
&cr->c.height, min_size, f->o_height, &s->r.height, min_size, f->o_height,
halign, 64/(ALIGN(depth, 8))); halign, 64/(ALIGN(depth, 8)));
/* adjust left/top if cropping rectangle is out of bounds */ /* adjust left/top if cropping rectangle is out of bounds */
if (cr->c.left + cr->c.width > f->o_width) if (s->r.left + s->r.width > f->o_width)
cr->c.left = f->o_width - cr->c.width; s->r.left = f->o_width - s->r.width;
if (cr->c.top + cr->c.height > f->o_height) if (s->r.top + s->r.height > f->o_height)
cr->c.top = f->o_height - cr->c.height; s->r.top = f->o_height - s->r.height;
cr->c.left = round_down(cr->c.left, min_size); s->r.left = round_down(s->r.left, min_size);
cr->c.top = round_down(cr->c.top, fimc->variant->hor_offs_align); s->r.top = round_down(s->r.top, fimc->variant->hor_offs_align);
dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d", dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
cr->c.left, cr->c.top, cr->c.width, cr->c.height, s->r.left, s->r.top, s->r.width, s->r.height,
f->f_width, f->f_height); f->f_width, f->f_height);
return 0; return 0;
} }
static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop) static int fimc_m2m_s_selection(struct file *file, void *fh,
struct v4l2_selection *s)
{ {
struct fimc_ctx *ctx = fh_to_ctx(fh); struct fimc_ctx *ctx = fh_to_ctx(fh);
struct fimc_dev *fimc = ctx->fimc_dev; struct fimc_dev *fimc = ctx->fimc_dev;
struct v4l2_crop cr = *crop;
struct fimc_frame *f; struct fimc_frame *f;
int ret; int ret;
ret = fimc_m2m_try_crop(ctx, &cr); ret = fimc_m2m_try_selection(ctx, s);
if (ret) if (ret)
return ret; return ret;
f = (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ? f = (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
&ctx->s_frame : &ctx->d_frame; &ctx->s_frame : &ctx->d_frame;
/* Check to see if scaling ratio is within supported range */ /* Check to see if scaling ratio is within supported range */
if (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
ret = fimc_check_scaler_ratio(ctx, cr.c.width, ret = fimc_check_scaler_ratio(ctx, s->r.width,
cr.c.height, ctx->d_frame.width, s->r.height, ctx->d_frame.width,
ctx->d_frame.height, ctx->rotation); ctx->d_frame.height, ctx->rotation);
} else { } else {
ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width, ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
ctx->s_frame.height, cr.c.width, ctx->s_frame.height, s->r.width,
cr.c.height, ctx->rotation); s->r.height, ctx->rotation);
} }
if (ret) { if (ret) {
v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n"); v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n");
return -EINVAL; return -EINVAL;
} }
f->offs_h = cr.c.left; f->offs_h = s->r.left;
f->offs_v = cr.c.top; f->offs_v = s->r.top;
f->width = cr.c.width; f->width = s->r.width;
f->height = cr.c.height; f->height = s->r.height;
fimc_ctx_state_set(FIMC_PARAMS, ctx); fimc_ctx_state_set(FIMC_PARAMS, ctx);
...@@ -528,9 +548,8 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { ...@@ -528,9 +548,8 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
.vidioc_expbuf = v4l2_m2m_ioctl_expbuf, .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
.vidioc_streamon = v4l2_m2m_ioctl_streamon, .vidioc_streamon = v4l2_m2m_ioctl_streamon,
.vidioc_streamoff = v4l2_m2m_ioctl_streamoff, .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
.vidioc_g_crop = fimc_m2m_g_crop, .vidioc_g_selection = fimc_m2m_g_selection,
.vidioc_s_crop = fimc_m2m_s_crop, .vidioc_s_selection = fimc_m2m_s_selection,
.vidioc_cropcap = fimc_m2m_cropcap
}; };
...@@ -717,6 +736,7 @@ int fimc_register_m2m_device(struct fimc_dev *fimc, ...@@ -717,6 +736,7 @@ int fimc_register_m2m_device(struct fimc_dev *fimc,
vfd->release = video_device_release_empty; vfd->release = video_device_release_empty;
vfd->lock = &fimc->lock; vfd->lock = &fimc->lock;
vfd->vfl_dir = VFL_DIR_M2M; vfd->vfl_dir = VFL_DIR_M2M;
set_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags);
snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id); snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id);
video_set_drvdata(vfd, fimc); video_set_drvdata(vfd, fimc);
......
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