diff options
author | Hyunwoong Kim <khw0178.kim@samsung.com> | 2010-12-28 20:12:43 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-03-21 19:31:40 -0400 |
commit | 1b09f292eb99fd6a3601e8421c463905dbb0a866 (patch) | |
tree | b4b2f033ed5846e98c1cd4d3392a522cc504aff9 /drivers/media | |
parent | 70f66ea2aafbd9022a5dcdfd823538e540873585 (diff) |
[media] s5p-fimc: update checking scaling ratio range
Horizontal and vertical scaling range are according to the following equations.
If (SRC_Width >= 64 x DST_Width) { Exit(-1); /* Out of Horizontal scale range}
If (SRC_Height >= 64 x DST_Height) { Exit(-1); /* Out of Vertical scale range}
fimc_check_scaler_ratio() is used to check if horizontal and vertical
scale range are valid or not. To use fimc_check_scaler_ratio,
source and destination format should be set by VIDIOC_S_FMT.
And in case of scaling up, it doesn't have to check the scale range.
Reviewed-by: Jonghun Han <jonghun.han@samsung.com>
Signed-off-by: Hyunwoong Kim <khw0178.kim@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-capture.c | 4 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.c | 59 | ||||
-rw-r--r-- | drivers/media/video/s5p-fimc/fimc-core.h | 2 |
3 files changed, 44 insertions, 21 deletions
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 2b03c956d0f6..c326f6bbf290 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -787,7 +787,9 @@ static int fimc_cap_s_crop(struct file *file, void *fh, | |||
787 | 787 | ||
788 | f = &ctx->s_frame; | 788 | f = &ctx->s_frame; |
789 | /* Check for the pixel scaling ratio when cropping input image. */ | 789 | /* Check for the pixel scaling ratio when cropping input image. */ |
790 | ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); | 790 | ret = fimc_check_scaler_ratio(cr->c.width, cr->c.height, |
791 | ctx->d_frame.width, ctx->d_frame.height, | ||
792 | ctx->rotation); | ||
791 | if (ret) { | 793 | if (ret) { |
792 | v4l2_err(&fimc->vid_cap.v4l2_dev, "Out of the scaler range"); | 794 | v4l2_err(&fimc->vid_cap.v4l2_dev, "Out of the scaler range"); |
793 | return ret; | 795 | return ret; |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 09bfac45ea32..560cd21dae28 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -200,24 +200,21 @@ static struct v4l2_queryctrl *get_ctrl(int id) | |||
200 | return NULL; | 200 | return NULL; |
201 | } | 201 | } |
202 | 202 | ||
203 | int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f) | 203 | int fimc_check_scaler_ratio(int sw, int sh, int dw, int dh, int rot) |
204 | { | 204 | { |
205 | if (r->width > f->width) { | 205 | int tx, ty; |
206 | if (f->width > (r->width * SCALER_MAX_HRATIO)) | ||
207 | return -EINVAL; | ||
208 | } else { | ||
209 | if ((f->width * SCALER_MAX_HRATIO) < r->width) | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | 206 | ||
213 | if (r->height > f->height) { | 207 | if (rot == 90 || rot == 270) { |
214 | if (f->height > (r->height * SCALER_MAX_VRATIO)) | 208 | ty = dw; |
215 | return -EINVAL; | 209 | tx = dh; |
216 | } else { | 210 | } else { |
217 | if ((f->height * SCALER_MAX_VRATIO) < r->height) | 211 | tx = dw; |
218 | return -EINVAL; | 212 | ty = dh; |
219 | } | 213 | } |
220 | 214 | ||
215 | if ((sw >= SCALER_MAX_HRATIO * tx) || (sh >= SCALER_MAX_VRATIO * ty)) | ||
216 | return -EINVAL; | ||
217 | |||
221 | return 0; | 218 | return 0; |
222 | } | 219 | } |
223 | 220 | ||
@@ -1065,6 +1062,7 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl) | |||
1065 | struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; | 1062 | struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; |
1066 | struct fimc_dev *fimc = ctx->fimc_dev; | 1063 | struct fimc_dev *fimc = ctx->fimc_dev; |
1067 | unsigned long flags; | 1064 | unsigned long flags; |
1065 | int ret = 0; | ||
1068 | 1066 | ||
1069 | spin_lock_irqsave(&ctx->slock, flags); | 1067 | spin_lock_irqsave(&ctx->slock, flags); |
1070 | 1068 | ||
@@ -1084,6 +1082,20 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl) | |||
1084 | break; | 1082 | break; |
1085 | 1083 | ||
1086 | case V4L2_CID_ROTATE: | 1084 | case V4L2_CID_ROTATE: |
1085 | if (!(~ctx->state & (FIMC_DST_FMT | FIMC_SRC_FMT))) { | ||
1086 | ret = fimc_check_scaler_ratio(ctx->s_frame.width, | ||
1087 | ctx->s_frame.height, | ||
1088 | ctx->d_frame.width, | ||
1089 | ctx->d_frame.height, | ||
1090 | ctrl->value); | ||
1091 | if (ret) { | ||
1092 | v4l2_err(&fimc->m2m.v4l2_dev, | ||
1093 | "Out of scaler range"); | ||
1094 | spin_unlock_irqrestore(&ctx->slock, flags); | ||
1095 | return -EINVAL; | ||
1096 | } | ||
1097 | } | ||
1098 | |||
1087 | /* Check for the output rotator availability */ | 1099 | /* Check for the output rotator availability */ |
1088 | if ((ctrl->value == 90 || ctrl->value == 270) && | 1100 | if ((ctrl->value == 90 || ctrl->value == 270) && |
1089 | (ctx->in_path == FIMC_DMA && !variant->has_out_rot)) { | 1101 | (ctx->in_path == FIMC_DMA && !variant->has_out_rot)) { |
@@ -1232,18 +1244,27 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) | |||
1232 | &ctx->s_frame : &ctx->d_frame; | 1244 | &ctx->s_frame : &ctx->d_frame; |
1233 | 1245 | ||
1234 | spin_lock_irqsave(&ctx->slock, flags); | 1246 | spin_lock_irqsave(&ctx->slock, flags); |
1235 | if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) { | 1247 | /* Check to see if scaling ratio is within supported range */ |
1236 | /* Check to see if scaling ratio is within supported range */ | 1248 | if (!(~ctx->state & (FIMC_DST_FMT | FIMC_SRC_FMT))) { |
1237 | if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) | 1249 | if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { |
1238 | ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); | 1250 | ret = fimc_check_scaler_ratio(cr->c.width, cr->c.height, |
1239 | else | 1251 | ctx->d_frame.width, |
1240 | ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame); | 1252 | ctx->d_frame.height, |
1253 | ctx->rotation); | ||
1254 | } else { | ||
1255 | ret = fimc_check_scaler_ratio(ctx->s_frame.width, | ||
1256 | ctx->s_frame.height, | ||
1257 | cr->c.width, cr->c.height, | ||
1258 | ctx->rotation); | ||
1259 | } | ||
1260 | |||
1241 | if (ret) { | 1261 | if (ret) { |
1242 | v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); | 1262 | v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); |
1243 | spin_unlock_irqrestore(&ctx->slock, flags); | 1263 | spin_unlock_irqrestore(&ctx->slock, flags); |
1244 | return -EINVAL; | 1264 | return -EINVAL; |
1245 | } | 1265 | } |
1246 | } | 1266 | } |
1267 | |||
1247 | ctx->state |= FIMC_PARAMS; | 1268 | ctx->state |= FIMC_PARAMS; |
1248 | 1269 | ||
1249 | f->offs_h = cr->c.left; | 1270 | f->offs_h = cr->c.left; |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 1c15358b43b6..57bff0d21962 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h | |||
@@ -611,7 +611,7 @@ struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask); | |||
611 | struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f, | 611 | struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f, |
612 | unsigned int mask); | 612 | unsigned int mask); |
613 | 613 | ||
614 | int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f); | 614 | int fimc_check_scaler_ratio(int sw, int sh, int dw, int dh, int rot); |
615 | int fimc_set_scaler_info(struct fimc_ctx *ctx); | 615 | int fimc_set_scaler_info(struct fimc_ctx *ctx); |
616 | int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags); | 616 | int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags); |
617 | int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb, | 617 | int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb, |