From patchwork Wed Dec 29 01:12:43 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hyunwoong Kim X-Patchwork-Id: 437681 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBT1YFiA006688 for ; Wed, 29 Dec 2010 01:34:15 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751259Ab0L2BeH (ORCPT ); Tue, 28 Dec 2010 20:34:07 -0500 Received: from ganesha.gnumonks.org ([213.95.27.120]:45390 "EHLO ganesha.gnumonks.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750986Ab0L2BeE (ORCPT ); Tue, 28 Dec 2010 20:34:04 -0500 Received: from uucp by ganesha.gnumonks.org with local-bsmtp (Exim 4.69) (envelope-from ) id 1PXkvS-0003YP-28; Wed, 29 Dec 2010 02:34:02 +0100 Received: from [12.23.102.184] (helo=localhost.localdomain) by jackpot.kr.gnumonks.org with esmtp (Exim 4.69) (envelope-from ) id 1PXjt2-0000t3-4V; Wed, 29 Dec 2010 09:27:28 +0900 From: Hyunwoong Kim To: linux-media@vger.kernel.org, linux-samsung-soc@vger.kernel.org Cc: s.nawrocki@samsung.com, Hyunwoong Kim Subject: [PATCH v2] [media] s5p-fimc: update checking scaling ratio range Date: Wed, 29 Dec 2010 10:12:43 +0900 Message-Id: <1293585163-23907-1-git-send-email-khw0178.kim@samsung.com> X-Mailer: git-send-email 1.6.2.5 Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 29 Dec 2010 01:34:15 +0000 (UTC) diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index b1cb937..e22a78c 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c @@ -761,7 +761,9 @@ static int fimc_cap_s_crop(struct file *file, void *fh, f = &ctx->s_frame; /* Check for the pixel scaling ratio when cropping input image. */ - ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); + ret = fimc_check_scaler_ratio(cr->c.width, cr->c.height, + ctx->d_frame.width, ctx->d_frame.height, + ctx->rotation); if (ret) { v4l2_err(&fimc->vid_cap.v4l2_dev, "Out of the scaler range"); return ret; diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 2b65961..e608fb8 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c @@ -198,24 +198,21 @@ static struct v4l2_queryctrl *get_ctrl(int id) return NULL; } -int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f) +int fimc_check_scaler_ratio(int sw, int sh, int dw, int dh, int rot) { - if (r->width > f->width) { - if (f->width > (r->width * SCALER_MAX_HRATIO)) - return -EINVAL; - } else { - if ((f->width * SCALER_MAX_HRATIO) < r->width) - return -EINVAL; - } + int tx, ty; - if (r->height > f->height) { - if (f->height > (r->height * SCALER_MAX_VRATIO)) - return -EINVAL; + if (rot == 90 || rot == 270) { + ty = dw; + tx = dh; } else { - if ((f->height * SCALER_MAX_VRATIO) < r->height) - return -EINVAL; + tx = dw; + ty = dh; } + if ((sw >= SCALER_MAX_HRATIO * tx) || (sh >= SCALER_MAX_VRATIO * ty)) + return -EINVAL; + return 0; } @@ -1063,6 +1060,7 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl) struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; struct fimc_dev *fimc = ctx->fimc_dev; unsigned long flags; + int ret = 0; if (ctx->rotation != 0 && (ctrl->id == V4L2_CID_HFLIP || ctrl->id == V4L2_CID_VFLIP)) { @@ -1089,6 +1087,20 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl) break; case V4L2_CID_ROTATE: + if (!(~ctx->state & (FIMC_DST_FMT | FIMC_SRC_FMT))) { + ret = fimc_check_scaler_ratio(ctx->s_frame.width, + ctx->s_frame.height, + ctx->d_frame.width, + ctx->d_frame.height, + ctrl->value); + if (ret) { + v4l2_err(&fimc->m2m.v4l2_dev, + "Out of scaler range"); + spin_unlock_irqrestore(&ctx->slock, flags); + return -EINVAL; + } + } + /* Check for the output rotator availability */ if ((ctrl->value == 90 || ctrl->value == 270) && (ctx->in_path == FIMC_DMA && !variant->has_out_rot)) { @@ -1237,18 +1249,27 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) &ctx->s_frame : &ctx->d_frame; spin_lock_irqsave(&ctx->slock, flags); - if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) { - /* Check to see if scaling ratio is within supported range */ - if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) - ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); - else - ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame); + /* Check to see if scaling ratio is within supported range */ + if (!(~ctx->state & (FIMC_DST_FMT | FIMC_SRC_FMT))) { + if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { + ret = fimc_check_scaler_ratio(cr->c.width, cr->c.height, + ctx->d_frame.width, + ctx->d_frame.height, + ctx->rotation); + } else { + ret = fimc_check_scaler_ratio(ctx->s_frame.width, + ctx->s_frame.height, + cr->c.width, cr->c.height, + ctx->rotation); + } + if (ret) { v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); spin_unlock_irqrestore(&ctx->slock, flags); return -EINVAL; } } + ctx->state |= FIMC_PARAMS; 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 d690398..b442fed 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h @@ -605,7 +605,7 @@ struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask); struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f, unsigned int mask); -int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f); +int fimc_check_scaler_ratio(int sw, int sh, int dw, int dh, int rot); int fimc_set_scaler_info(struct fimc_ctx *ctx); int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags); int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,