diff options
author | Sylwester Nawrocki <s.nawrocki@samsung.com> | 2012-02-04 15:03:54 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-03-08 05:41:26 -0500 |
commit | f9331d115dadd4e63619ebb47960ec2b7d253700 (patch) | |
tree | 27733b4c1b07aee8abca70a905b171fed12f7b24 /drivers/media/video/s5p-fimc/fimc-capture.c | |
parent | 3b4c34aac7abea4754059084d0eef667a1993ac8 (diff) |
[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: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/s5p-fimc/fimc-capture.c')
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-capture.c | 104 |
1 files changed, 76 insertions, 28 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index b2fc0b55bc11..b06efd208328 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -1035,52 +1035,101 @@ static int fimc_cap_prepare_buf(struct file *file, void *priv, | |||
1035 | return vb2_prepare_buf(&fimc->vid_cap.vbq, b); | 1035 | return vb2_prepare_buf(&fimc->vid_cap.vbq, b); |
1036 | } | 1036 | } |
1037 | 1037 | ||
1038 | static int fimc_cap_cropcap(struct file *file, void *fh, | 1038 | static int fimc_cap_g_selection(struct file *file, void *fh, |
1039 | struct v4l2_cropcap *cr) | 1039 | struct v4l2_selection *s) |
1040 | { | 1040 | { |
1041 | struct fimc_dev *fimc = video_drvdata(file); | 1041 | struct fimc_dev *fimc = video_drvdata(file); |
1042 | struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; | 1042 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; |
1043 | struct fimc_frame *f = &ctx->s_frame; | ||
1043 | 1044 | ||
1044 | if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | 1045 | if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) |
1045 | return -EINVAL; | 1046 | return -EINVAL; |
1046 | 1047 | ||
1047 | cr->bounds.left = 0; | 1048 | switch (s->target) { |
1048 | cr->bounds.top = 0; | 1049 | case V4L2_SEL_TGT_COMPOSE_DEFAULT: |
1049 | cr->bounds.width = f->o_width; | 1050 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: |
1050 | cr->bounds.height = f->o_height; | 1051 | f = &ctx->d_frame; |
1051 | cr->defrect = cr->bounds; | 1052 | case V4L2_SEL_TGT_CROP_BOUNDS: |
1053 | case V4L2_SEL_TGT_CROP_DEFAULT: | ||
1054 | s->r.left = 0; | ||
1055 | s->r.top = 0; | ||
1056 | s->r.width = f->o_width; | ||
1057 | s->r.height = f->o_height; | ||
1058 | return 0; | ||
1052 | 1059 | ||
1053 | return 0; | 1060 | case V4L2_SEL_TGT_COMPOSE_ACTIVE: |
1061 | f = &ctx->d_frame; | ||
1062 | case V4L2_SEL_TGT_CROP_ACTIVE: | ||
1063 | s->r.left = f->offs_h; | ||
1064 | s->r.top = f->offs_v; | ||
1065 | s->r.width = f->width; | ||
1066 | s->r.height = f->height; | ||
1067 | return 0; | ||
1068 | } | ||
1069 | |||
1070 | return -EINVAL; | ||
1054 | } | 1071 | } |
1055 | 1072 | ||
1056 | static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) | 1073 | /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */ |
1074 | int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b) | ||
1057 | { | 1075 | { |
1058 | struct fimc_dev *fimc = video_drvdata(file); | 1076 | if (a->left < b->left || a->top < b->top) |
1059 | struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; | 1077 | return 0; |
1060 | 1078 | if (a->left + a->width > b->left + b->width) | |
1061 | cr->c.left = f->offs_h; | 1079 | return 0; |
1062 | cr->c.top = f->offs_v; | 1080 | if (a->top + a->height > b->top + b->height) |
1063 | cr->c.width = f->width; | 1081 | return 0; |
1064 | cr->c.height = f->height; | ||
1065 | 1082 | ||
1066 | return 0; | 1083 | return 1; |
1067 | } | 1084 | } |
1068 | 1085 | ||
1069 | static int fimc_cap_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) | 1086 | static int fimc_cap_s_selection(struct file *file, void *fh, |
1087 | struct v4l2_selection *s) | ||
1070 | { | 1088 | { |
1071 | struct fimc_dev *fimc = video_drvdata(file); | 1089 | struct fimc_dev *fimc = video_drvdata(file); |
1072 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; | 1090 | struct fimc_ctx *ctx = fimc->vid_cap.ctx; |
1073 | struct fimc_frame *ff; | 1091 | struct v4l2_rect rect = s->r; |
1092 | struct fimc_frame *f; | ||
1074 | unsigned long flags; | 1093 | unsigned long flags; |
1094 | unsigned int pad; | ||
1095 | |||
1096 | if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) | ||
1097 | return -EINVAL; | ||
1075 | 1098 | ||
1076 | fimc_capture_try_crop(ctx, &cr->c, FIMC_SD_PAD_SINK); | 1099 | switch (s->target) { |
1077 | ff = &ctx->s_frame; | 1100 | case V4L2_SEL_TGT_COMPOSE_DEFAULT: |
1101 | case V4L2_SEL_TGT_COMPOSE_BOUNDS: | ||
1102 | case V4L2_SEL_TGT_COMPOSE_ACTIVE: | ||
1103 | f = &ctx->d_frame; | ||
1104 | pad = FIMC_SD_PAD_SOURCE; | ||
1105 | break; | ||
1106 | case V4L2_SEL_TGT_CROP_BOUNDS: | ||
1107 | case V4L2_SEL_TGT_CROP_DEFAULT: | ||
1108 | case V4L2_SEL_TGT_CROP_ACTIVE: | ||
1109 | f = &ctx->s_frame; | ||
1110 | pad = FIMC_SD_PAD_SINK; | ||
1111 | break; | ||
1112 | default: | ||
1113 | return -EINVAL; | ||
1114 | } | ||
1078 | 1115 | ||
1116 | fimc_capture_try_crop(ctx, &rect, pad); | ||
1117 | |||
1118 | if (s->flags & V4L2_SEL_FLAG_LE && | ||
1119 | !enclosed_rectangle(&rect, &s->r)) | ||
1120 | return -ERANGE; | ||
1121 | |||
1122 | if (s->flags & V4L2_SEL_FLAG_GE && | ||
1123 | !enclosed_rectangle(&s->r, &rect)) | ||
1124 | return -ERANGE; | ||
1125 | |||
1126 | s->r = rect; | ||
1079 | spin_lock_irqsave(&fimc->slock, flags); | 1127 | spin_lock_irqsave(&fimc->slock, flags); |
1080 | set_frame_crop(ff, cr->c.left, cr->c.top, cr->c.width, cr->c.height); | 1128 | set_frame_crop(f, s->r.left, s->r.top, s->r.width, |
1081 | set_bit(ST_CAPT_APPLY_CFG, &fimc->state); | 1129 | s->r.height); |
1082 | spin_unlock_irqrestore(&fimc->slock, flags); | 1130 | spin_unlock_irqrestore(&fimc->slock, flags); |
1083 | 1131 | ||
1132 | set_bit(ST_CAPT_APPLY_CFG, &fimc->state); | ||
1084 | return 0; | 1133 | return 0; |
1085 | } | 1134 | } |
1086 | 1135 | ||
@@ -1104,9 +1153,8 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { | |||
1104 | .vidioc_streamon = fimc_cap_streamon, | 1153 | .vidioc_streamon = fimc_cap_streamon, |
1105 | .vidioc_streamoff = fimc_cap_streamoff, | 1154 | .vidioc_streamoff = fimc_cap_streamoff, |
1106 | 1155 | ||
1107 | .vidioc_g_crop = fimc_cap_g_crop, | 1156 | .vidioc_g_selection = fimc_cap_g_selection, |
1108 | .vidioc_s_crop = fimc_cap_s_crop, | 1157 | .vidioc_s_selection = fimc_cap_s_selection, |
1109 | .vidioc_cropcap = fimc_cap_cropcap, | ||
1110 | 1158 | ||
1111 | .vidioc_enum_input = fimc_cap_enum_input, | 1159 | .vidioc_enum_input = fimc_cap_enum_input, |
1112 | .vidioc_s_input = fimc_cap_s_input, | 1160 | .vidioc_s_input = fimc_cap_s_input, |