SN9C20x/GSPCA JPEG improvements

This increases the JPEG buffersize and adds JPEG quality set/get methods.
The largest framesize I've encountered was 230KB resulting from quality=95
(and a complex/blury image).  This also fixes a bug in the mode selection.

Signed-off-by: Tim Harvey <[email protected]>

 target/linux/generic/patches-3.3/065-gspca_bufsize.patch |  144 +++++++++++++++
 1 file changed, 144 insertions(+)

Index: trunk/target/linux/generic/patches-3.3/065-gspca_bufsize.patch
===================================================================
--- trunk/target/linux/generic/patches-3.3/065-gspca_bufsize.patch      
(revision 0)
+++ trunk/target/linux/generic/patches-3.3/065-gspca_bufsize.patch      
(working copy)
@@ -0,0 +1,144 @@
+--- a/drivers/media/video/gspca/gspca.c
++++ b/drivers/media/video/gspca/gspca.c
+@@ -1044,11 +1044,13 @@ static int gspca_get_mode(struct gspca_d
+                                                               == pixfmt)
+                               return modeD;
+               }
++/*
+               if (++modeU < gspca_dev->cam.nmodes) {
+                       if (gspca_dev->cam.cam_mode[modeU].pixelformat
+                                                               == pixfmt)
+                               return modeU;
+               }
++*/
+       }
+       return -EINVAL;
+ }
+--- a/drivers/media/video/gspca/sn9c20x.c
++++ b/drivers/media/video/gspca/sn9c20x.c
+@@ -35,6 +35,14 @@ MODULE_LICENSE("GPL");
+ 
+ #define MODULE_NAME "sn9c20x"
+ 
++#define QUALITY_MIN 20
++#define QUALITY_DEF 85
++#define QUALITY_MAX 95
++
++static int jpeg_quality = QUALITY_DEF;
++module_param(jpeg_quality, int, 0644);
++MODULE_PARM_DESC(jpeg_quality, "JPEG Quality");
++
+ /*
+  * Pixel format private data
+  */
+@@ -363,7 +371,7 @@ static const struct ctrl sd_ctrls[] = {
+ static const struct v4l2_pix_format vga_mode[] = {
+       {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+               .bytesperline = 160,
+-              .sizeimage = 160 * 120 * 4 / 8 + 590,
++              .sizeimage = 160 * 120 * 7 / 8 + 590,
+               .colorspace = V4L2_COLORSPACE_JPEG,
+               .priv = SCALE_160x120 | MODE_JPEG},
+       {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+@@ -378,7 +386,7 @@ static const struct v4l2_pix_format vga_
+               .priv = SCALE_160x120},
+       {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+               .bytesperline = 320,
+-              .sizeimage = 320 * 240 * 4 / 8 + 590,
++              .sizeimage = 320 * 240 * 7 / 8 + 590,
+               .colorspace = V4L2_COLORSPACE_JPEG,
+               .priv = SCALE_320x240 | MODE_JPEG},
+       {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+@@ -393,7 +401,7 @@ static const struct v4l2_pix_format vga_
+               .priv = SCALE_320x240},
+       {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+               .bytesperline = 640,
+-              .sizeimage = 640 * 480 * 4 / 8 + 590,
++              .sizeimage = 640 * 480 * 7 / 8 + 590,
+               .colorspace = V4L2_COLORSPACE_JPEG,
+               .priv = SCALE_640x480 | MODE_JPEG},
+       {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+@@ -411,7 +419,7 @@ static const struct v4l2_pix_format vga_
+ static const struct v4l2_pix_format sxga_mode[] = {
+       {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+               .bytesperline = 160,
+-              .sizeimage = 160 * 120 * 4 / 8 + 590,
++              .sizeimage = 160 * 120 * 7 / 8 + 590,
+               .colorspace = V4L2_COLORSPACE_JPEG,
+               .priv = SCALE_160x120 | MODE_JPEG},
+       {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+@@ -426,7 +434,7 @@ static const struct v4l2_pix_format sxga
+               .priv = SCALE_160x120},
+       {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+               .bytesperline = 320,
+-              .sizeimage = 320 * 240 * 4 / 8 + 590,
++              .sizeimage = 320 * 240 * 7 / 8 + 590,
+               .colorspace = V4L2_COLORSPACE_JPEG,
+               .priv = SCALE_320x240 | MODE_JPEG},
+       {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+@@ -441,7 +449,7 @@ static const struct v4l2_pix_format sxga
+               .priv = SCALE_320x240},
+       {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+               .bytesperline = 640,
+-              .sizeimage = 640 * 480 * 4 / 8 + 590,
++              .sizeimage = 640 * 480 * 7 / 8 + 590,
+               .colorspace = V4L2_COLORSPACE_JPEG,
+               .priv = SCALE_640x480 | MODE_JPEG},
+       {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+@@ -2090,7 +2098,7 @@ static int sd_config(struct gspca_dev *g
+       sd->gain = GAIN_DEFAULT;
+       sd->auto_exposure = AUTO_EXPOSURE_DEFAULT;
+ 
+-      sd->quality = 95;
++      sd->quality = jpeg_quality;
+ 
+       return 0;
+ }
+@@ -2503,6 +2511,38 @@ static void sd_pkt_scan(struct gspca_dev
+       }
+ }
+ 
++static int sd_set_jcomp(struct gspca_dev *gspca_dev,
++                      struct v4l2_jpegcompression *jcomp)
++{
++      struct sd *sd = (struct sd *) gspca_dev;
++
++      if (jcomp->quality < QUALITY_MIN)
++              sd->quality = QUALITY_MIN;
++      else if (jcomp->quality > QUALITY_MAX)
++              sd->quality = QUALITY_MAX;
++      else
++              sd->quality = jcomp->quality;
++      if (gspca_dev->streaming)
++      {
++              jpeg_set_qual(sd->jpeg_hdr, sd->quality);
++              reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
++              reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
++      }
++      return gspca_dev->usb_err;
++}
++
++static int sd_get_jcomp(struct gspca_dev *gspca_dev,
++                      struct v4l2_jpegcompression *jcomp)
++{
++      struct sd *sd = (struct sd *) gspca_dev;
++
++      memset(jcomp, 0, sizeof *jcomp);
++      jcomp->quality = sd->quality;
++      jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
++                      | V4L2_JPEG_MARKER_DQT;
++      return 0;
++}
++
+ /* sub-driver description */
+ static const struct sd_desc sd_desc = {
+       .name = MODULE_NAME,
+@@ -2523,6 +2563,8 @@ static const struct sd_desc sd_desc = {
+       .get_register = sd_dbg_g_register,
+ #endif
+       .get_chip_ident = sd_chip_ident,
++      .set_jcomp = sd_set_jcomp,
++      .get_jcomp = sd_get_jcomp,
+ };
+ 
+ #define SN9C20X(sensor, i2c_addr, flags) \
_______________________________________________
openwrt-devel mailing list
[email protected]
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to