aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJean-François Moine <moinejf@free.fr>2012-03-19 03:35:34 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-19 21:30:20 -0400
commit4c632e4e51e5d89af75ecf3e958988658c01294f (patch)
tree47d8cd9aeb262e3038c517ebe816353f7a847b9a /drivers/media
parent92884f80b7e5f8d0ffd725a251c81dd45e9e6eb0 (diff)
[media] gspca - sn9c20x: Add the JPEG compression quality control
The JPEG compression quality was hardcoded to 95%. This value was too big, raising often buffer overflows. This quality is now 80% by default and is settable. Signed-off-by: Jean-François Moine <moinejf@free.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/gspca/sn9c20x.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index 97c653f9f983..0894a3d2c336 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -79,6 +79,7 @@ enum e_ctrl {
79 EXPOSURE, 79 EXPOSURE,
80 GAIN, 80 GAIN,
81 AUTOGAIN, 81 AUTOGAIN,
82 QUALITY,
82 NCTRLS /* number of controls */ 83 NCTRLS /* number of controls */
83}; 84};
84 85
@@ -88,6 +89,8 @@ struct sd {
88 89
89 struct gspca_ctrl ctrls[NCTRLS]; 90 struct gspca_ctrl ctrls[NCTRLS];
90 91
92 u8 fmt; /* (used for JPEG QTAB update */
93
91#define MIN_AVG_LUM 80 94#define MIN_AVG_LUM 80
92#define MAX_AVG_LUM 130 95#define MAX_AVG_LUM 130
93 atomic_t avg_lum; 96 atomic_t avg_lum;
@@ -101,7 +104,6 @@ struct sd {
101 u8 vstart; 104 u8 vstart;
102 105
103 u8 jpeg_hdr[JPEG_HDR_SZ]; 106 u8 jpeg_hdr[JPEG_HDR_SZ];
104 u8 quality;
105 107
106 u8 flags; 108 u8 flags;
107}; 109};
@@ -162,6 +164,7 @@ static void set_redblue(struct gspca_dev *gspca_dev);
162static void set_hvflip(struct gspca_dev *gspca_dev); 164static void set_hvflip(struct gspca_dev *gspca_dev);
163static void set_exposure(struct gspca_dev *gspca_dev); 165static void set_exposure(struct gspca_dev *gspca_dev);
164static void set_gain(struct gspca_dev *gspca_dev); 166static void set_gain(struct gspca_dev *gspca_dev);
167static void set_quality(struct gspca_dev *gspca_dev);
165 168
166static const struct ctrl sd_ctrls[NCTRLS] = { 169static const struct ctrl sd_ctrls[NCTRLS] = {
167[BRIGHTNESS] = { 170[BRIGHTNESS] = {
@@ -307,6 +310,21 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
307 .default_value = 1, 310 .default_value = 1,
308 }, 311 },
309 }, 312 },
313[QUALITY] = {
314 {
315 .id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
316 .type = V4L2_CTRL_TYPE_INTEGER,
317 .name = "Compression Quality",
318#define QUALITY_MIN 50
319#define QUALITY_MAX 90
320#define QUALITY_DEF 80
321 .minimum = QUALITY_MIN,
322 .maximum = QUALITY_MAX,
323 .step = 1,
324 .default_value = QUALITY_DEF,
325 },
326 .set_control = set_quality
327 },
310}; 328};
311 329
312static const struct v4l2_pix_format vga_mode[] = { 330static const struct v4l2_pix_format vga_mode[] = {
@@ -1732,6 +1750,21 @@ static void set_gain(struct gspca_dev *gspca_dev)
1732 i2c_w(gspca_dev, gain); 1750 i2c_w(gspca_dev, gain);
1733} 1751}
1734 1752
1753static void set_quality(struct gspca_dev *gspca_dev)
1754{
1755 struct sd *sd = (struct sd *) gspca_dev;
1756
1757 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
1758 reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */
1759 reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
1760 reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
1761 reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
1762 reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */
1763 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1764 sd->fmt ^= 0x0c; /* invert QTAB use + write */
1765 reg_w1(gspca_dev, 0x10e0, sd->fmt);
1766}
1767
1735#ifdef CONFIG_VIDEO_ADV_DEBUG 1768#ifdef CONFIG_VIDEO_ADV_DEBUG
1736static int sd_dbg_g_register(struct gspca_dev *gspca_dev, 1769static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
1737 struct v4l2_dbg_register *reg) 1770 struct v4l2_dbg_register *reg)
@@ -1846,7 +1879,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
1846 1879
1847 gspca_dev->cam.ctrls = sd->ctrls; 1880 gspca_dev->cam.ctrls = sd->ctrls;
1848 1881
1849 sd->quality = 95;
1850 1882
1851 return 0; 1883 return 0;
1852} 1884}
@@ -2058,14 +2090,15 @@ static int sd_start(struct gspca_dev *gspca_dev)
2058 2090
2059 jpeg_define(sd->jpeg_hdr, height, width, 2091 jpeg_define(sd->jpeg_hdr, height, width,
2060 0x21); 2092 0x21);
2061 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 2093 jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
2062 2094
2063 if (mode & MODE_RAW) 2095 if (mode & MODE_RAW)
2064 fmt = 0x2d; 2096 fmt = 0x2d;
2065 else if (mode & MODE_JPEG) 2097 else if (mode & MODE_JPEG)
2066 fmt = 0x2c; 2098 fmt = 0x24;
2067 else 2099 else
2068 fmt = 0x2f; /* YUV 420 */ 2100 fmt = 0x2f; /* YUV 420 */
2101 sd->fmt = fmt;
2069 2102
2070 switch (mode & SCALE_MASK) { 2103 switch (mode & SCALE_MASK) {
2071 case SCALE_1280x1024: 2104 case SCALE_1280x1024: