diff options
author | Liu Ying <Ying.Liu@freescale.com> | 2013-11-25 18:34:40 +0800 |
---|---|---|
committer | Peng Fushi <fushi.peng@freescale.com> | 2014-08-28 16:53:11 +0800 |
commit | b5a599abb9ed1d1d6718a953986ebafcf8db868b (patch) | |
tree | d7b7aa7dcdab154f336411601b72c5f9713e0439 | |
parent | 376e8d987142463f68f03e0074b85465ef7ff0e3 (diff) |
ENGR00289553 IPU dev:correct downsize overflow check in rot case
In rotation cases, the width and height of IPUv3 IC scaling block's
output should align with the width and height of IPUv3 IC rotation
block. And, users only tell the IPUv3 device driver about the parameters
of scaling block's input and rotation block's output. So, we need to
swap the width and height of rotation block in cache before we do
downsize(a functionality of the scaling block) overflow check.
This patch fixes the issue which can be reproduced by this unit test case:
/unit_tests/mxc_v4l2_output.out -iw 128 -ih 128 -ow 176 -oh 10 -r 90
Signed-off-by: Liu Ying <Ying.Liu@freescale.com>
-rw-r--r-- | drivers/mxc/ipu3/ipu_device.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/mxc/ipu3/ipu_device.c b/drivers/mxc/ipu3/ipu_device.c index c763271152b1..0bb4669ce8c7 100644 --- a/drivers/mxc/ipu3/ipu_device.c +++ b/drivers/mxc/ipu3/ipu_device.c @@ -942,6 +942,7 @@ static int check_task(struct ipu_task_entry *t) int ret = IPU_CHECK_OK; int timeout; bool vdi_split = false; + int ocw, och; if ((IPU_PIX_FMT_TILED_NV12 == t->overlay.format) || (IPU_PIX_FMT_TILED_NV12F == t->overlay.format) || @@ -978,12 +979,25 @@ static int check_task(struct ipu_task_entry *t) &t->set.o_off, &t->set.o_uoff, &t->set.o_voff, &t->set.ostride); - if (t->output.crop.w * 8 <= t->input.crop.w) { + if (t->output.rotate >= IPU_ROTATE_90_RIGHT) { + /* + * Cache output width and height and + * swap them so that we may check + * downsize overflow correctly. + */ + ocw = t->output.crop.h; + och = t->output.crop.w; + } else { + ocw = t->output.crop.w; + och = t->output.crop.h; + } + + if (ocw * 8 <= t->input.crop.w) { ret = IPU_CHECK_ERR_W_DOWNSIZE_OVER; goto done; } - if (t->output.crop.h * 8 <= t->input.crop.h) { + if (och * 8 <= t->input.crop.h) { ret = IPU_CHECK_ERR_H_DOWNSIZE_OVER; goto done; } @@ -1018,14 +1032,15 @@ static int check_task(struct ipu_task_entry *t) ret = IPU_CHECK_ERR_OVERLAY_CROP; goto done; } else { - int ow = t->output.crop.w; - int oh = t->output.crop.h; + ocw = t->output.crop.w; + och = t->output.crop.h; if (t->output.rotate >= IPU_ROTATE_90_RIGHT) { - ow = t->output.crop.h; - oh = t->output.crop.w; + ocw = t->output.crop.h; + och = t->output.crop.w; } - if ((t->overlay.crop.w != ow) || (t->overlay.crop.h != oh)) { + if ((t->overlay.crop.w != ocw) || + (t->overlay.crop.h != och)) { ret = IPU_CHECK_ERR_OV_OUT_NO_FIT; goto done; } |