aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorHyunwoong Kim <khw0178.kim@samsung.com>2010-12-28 20:12:43 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-03-21 19:31:40 -0400
commit1b09f292eb99fd6a3601e8421c463905dbb0a866 (patch)
treeb4b2f033ed5846e98c1cd4d3392a522cc504aff9 /drivers/media
parent70f66ea2aafbd9022a5dcdfd823538e540873585 (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.c4
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c59
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h2
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
203int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f) 203int 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);
611struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f, 611struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f,
612 unsigned int mask); 612 unsigned int mask);
613 613
614int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f); 614int fimc_check_scaler_ratio(int sw, int sh, int dw, int dh, int rot);
615int fimc_set_scaler_info(struct fimc_ctx *ctx); 615int fimc_set_scaler_info(struct fimc_ctx *ctx);
616int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags); 616int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags);
617int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb, 617int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,