Compute the bytesperline and sizeimage values when trying/setting formats or when allocating buffers by taking the user-requested values into account. Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> --- drivers/media/video/mx3_camera.c | 20 +++++++++++++----- drivers/media/video/sh_mobile_ceu_camera.c | 20 +++++++++++++----- drivers/media/video/soc_camera.c | 29 ++++++++++++++------------- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index 813323c..4fd62d1 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c @@ -206,17 +206,25 @@ static int mx3_videobuf_setup(struct vb2_queue *vq, if (fmt) { const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd, fmt->fmt.pix.pixelformat); - int bytes_per_line; + unsigned int bytes_per_line; + int ret; if (!xlate) return -EINVAL; - bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width, - xlate->host_fmt); - if (bytes_per_line < 0) - return bytes_per_line; + ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width, + xlate->host_fmt); + if (ret < 0) + return ret; + + bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret); + + ret = soc_mbus_image_size(bytes_per_line, fmt->fmt.pix.height, + xlate->host_fmt); + if (ret < 0) + return ret; - sizes[0] = bytes_per_line * fmt->fmt.pix.height; + sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret); } else { /* Called from VIDIOC_REQBUFS or in compatibility mode */ sizes[0] = icd->sizeimage; diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index bd6ae79..47b336b 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -210,17 +210,25 @@ static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq, if (fmt) { const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd, fmt->fmt.pix.pixelformat); - int bytes_per_line; + unsigned int bytes_per_line; + int ret; if (!xlate) return -EINVAL; - bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width, - xlate->host_fmt); - if (bytes_per_line < 0) - return bytes_per_line; + ret = soc_mbus_bytes_per_line(fmt->fmt.pix.width, + xlate->host_fmt); + if (ret < 0) + return ret; + + bytes_per_line = max_t(u32, fmt->fmt.pix.bytesperline, ret); + + ret = soc_mbus_image_size(bytes_per_line, fmt->fmt.pix.height, + xlate->host_fmt); + if (ret < 0) + return ret; - sizes[0] = bytes_per_line * fmt->fmt.pix.height; + sizes[0] = max_t(u32, fmt->fmt.pix.sizeimage, ret); } else { /* Called from VIDIOC_REQBUFS or in compatibility mode */ sizes[0] = icd->sizeimage; diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 62e4312..b49ad27 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -164,6 +164,7 @@ static int soc_camera_try_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { struct soc_camera_host *ici = to_soc_camera_host(icd->parent); + const struct soc_camera_format_xlate *xlate; struct v4l2_pix_format *pix = &f->fmt.pix; int ret; @@ -177,22 +178,22 @@ static int soc_camera_try_fmt(struct soc_camera_device *icd, if (ret < 0) return ret; - if (!pix->sizeimage) { - if (!pix->bytesperline) { - const struct soc_camera_format_xlate *xlate; + xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); + if (!xlate) + return -EINVAL; - xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); - if (!xlate) - return -EINVAL; + ret = soc_mbus_bytes_per_line(pix->width, xlate->host_fmt); + if (ret < 0) + return ret; - ret = soc_mbus_bytes_per_line(pix->width, - xlate->host_fmt); - if (ret > 0) - pix->bytesperline = ret; - } - if (pix->bytesperline) - pix->sizeimage = pix->bytesperline * pix->height; - } + pix->bytesperline = max_t(u32, pix->bytesperline, ret); + + ret = soc_mbus_image_size(pix->bytesperline, pix->height, + xlate->host_fmt); + if (ret < 0) + return ret; + + pix->sizeimage = max_t(u32, pix->sizeimage, ret); return 0; } -- 1.7.3.4 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html