[media] soc-camera: Honor user-requested bytesperline and sizeimage
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Wed, 21 Mar 2012 11:03:26 +0000 (08:03 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 15 May 2012 19:11:07 +0000 (16:11 -0300)
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@ideasonboard.com>
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/mx3_camera.c
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/soc_camera.c

index 2bdda6ca13c05d669a56a4aeb1af996130db93a0..02d54a057b601f761ea5354a3dc4de29f699f67d 100644 (file)
@@ -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(xlate->host_fmt, bytes_per_line,
+                                         fmt->fmt.pix.height);
+               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;
index 87b07bcab323d6bfa764fd48a2001c055bc71f4e..79bec15cc4a36eb9ad39a1228a7e16a808458797 100644 (file)
@@ -214,17 +214,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(xlate->host_fmt, bytes_per_line,
+                                         fmt->fmt.pix.height);
+               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;
index d86b150846289cbf1184235eeab4bd4b2f898596..5e3274e557564194d07d6fbc6600aeaf21b138bf 100644 (file)
@@ -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(xlate->host_fmt, pix->bytesperline,
+                                 pix->height);
+       if (ret < 0)
+               return ret;
+
+       pix->sizeimage = max_t(u32, pix->sizeimage, ret);
 
        return 0;
 }