[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>
This commit is contained in:
parent
92884f80b7
commit
4c632e4e51
@ -79,6 +79,7 @@ enum e_ctrl {
|
|||||||
EXPOSURE,
|
EXPOSURE,
|
||||||
GAIN,
|
GAIN,
|
||||||
AUTOGAIN,
|
AUTOGAIN,
|
||||||
|
QUALITY,
|
||||||
NCTRLS /* number of controls */
|
NCTRLS /* number of controls */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -88,6 +89,8 @@ struct sd {
|
|||||||
|
|
||||||
struct gspca_ctrl ctrls[NCTRLS];
|
struct gspca_ctrl ctrls[NCTRLS];
|
||||||
|
|
||||||
|
u8 fmt; /* (used for JPEG QTAB update */
|
||||||
|
|
||||||
#define MIN_AVG_LUM 80
|
#define MIN_AVG_LUM 80
|
||||||
#define MAX_AVG_LUM 130
|
#define MAX_AVG_LUM 130
|
||||||
atomic_t avg_lum;
|
atomic_t avg_lum;
|
||||||
@ -101,7 +104,6 @@ struct sd {
|
|||||||
u8 vstart;
|
u8 vstart;
|
||||||
|
|
||||||
u8 jpeg_hdr[JPEG_HDR_SZ];
|
u8 jpeg_hdr[JPEG_HDR_SZ];
|
||||||
u8 quality;
|
|
||||||
|
|
||||||
u8 flags;
|
u8 flags;
|
||||||
};
|
};
|
||||||
@ -162,6 +164,7 @@ static void set_redblue(struct gspca_dev *gspca_dev);
|
|||||||
static void set_hvflip(struct gspca_dev *gspca_dev);
|
static void set_hvflip(struct gspca_dev *gspca_dev);
|
||||||
static void set_exposure(struct gspca_dev *gspca_dev);
|
static void set_exposure(struct gspca_dev *gspca_dev);
|
||||||
static void set_gain(struct gspca_dev *gspca_dev);
|
static void set_gain(struct gspca_dev *gspca_dev);
|
||||||
|
static void set_quality(struct gspca_dev *gspca_dev);
|
||||||
|
|
||||||
static const struct ctrl sd_ctrls[NCTRLS] = {
|
static const struct ctrl sd_ctrls[NCTRLS] = {
|
||||||
[BRIGHTNESS] = {
|
[BRIGHTNESS] = {
|
||||||
@ -307,6 +310,21 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
|
|||||||
.default_value = 1,
|
.default_value = 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
[QUALITY] = {
|
||||||
|
{
|
||||||
|
.id = V4L2_CID_JPEG_COMPRESSION_QUALITY,
|
||||||
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||||
|
.name = "Compression Quality",
|
||||||
|
#define QUALITY_MIN 50
|
||||||
|
#define QUALITY_MAX 90
|
||||||
|
#define QUALITY_DEF 80
|
||||||
|
.minimum = QUALITY_MIN,
|
||||||
|
.maximum = QUALITY_MAX,
|
||||||
|
.step = 1,
|
||||||
|
.default_value = QUALITY_DEF,
|
||||||
|
},
|
||||||
|
.set_control = set_quality
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct v4l2_pix_format vga_mode[] = {
|
static const struct v4l2_pix_format vga_mode[] = {
|
||||||
@ -1732,6 +1750,21 @@ static void set_gain(struct gspca_dev *gspca_dev)
|
|||||||
i2c_w(gspca_dev, gain);
|
i2c_w(gspca_dev, gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_quality(struct gspca_dev *gspca_dev)
|
||||||
|
{
|
||||||
|
struct sd *sd = (struct sd *) gspca_dev;
|
||||||
|
|
||||||
|
jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
|
||||||
|
reg_w1(gspca_dev, 0x1061, 0x01); /* stop transfer */
|
||||||
|
reg_w1(gspca_dev, 0x10e0, sd->fmt | 0x20); /* write QTAB */
|
||||||
|
reg_w(gspca_dev, 0x1100, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
|
||||||
|
reg_w(gspca_dev, 0x1140, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
|
||||||
|
reg_w1(gspca_dev, 0x1061, 0x03); /* restart transfer */
|
||||||
|
reg_w1(gspca_dev, 0x10e0, sd->fmt);
|
||||||
|
sd->fmt ^= 0x0c; /* invert QTAB use + write */
|
||||||
|
reg_w1(gspca_dev, 0x10e0, sd->fmt);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
#ifdef CONFIG_VIDEO_ADV_DEBUG
|
||||||
static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
|
static int sd_dbg_g_register(struct gspca_dev *gspca_dev,
|
||||||
struct v4l2_dbg_register *reg)
|
struct v4l2_dbg_register *reg)
|
||||||
@ -1846,7 +1879,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
|
|||||||
|
|
||||||
gspca_dev->cam.ctrls = sd->ctrls;
|
gspca_dev->cam.ctrls = sd->ctrls;
|
||||||
|
|
||||||
sd->quality = 95;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -2058,14 +2090,15 @@ static int sd_start(struct gspca_dev *gspca_dev)
|
|||||||
|
|
||||||
jpeg_define(sd->jpeg_hdr, height, width,
|
jpeg_define(sd->jpeg_hdr, height, width,
|
||||||
0x21);
|
0x21);
|
||||||
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
|
jpeg_set_qual(sd->jpeg_hdr, sd->ctrls[QUALITY].val);
|
||||||
|
|
||||||
if (mode & MODE_RAW)
|
if (mode & MODE_RAW)
|
||||||
fmt = 0x2d;
|
fmt = 0x2d;
|
||||||
else if (mode & MODE_JPEG)
|
else if (mode & MODE_JPEG)
|
||||||
fmt = 0x2c;
|
fmt = 0x24;
|
||||||
else
|
else
|
||||||
fmt = 0x2f; /* YUV 420 */
|
fmt = 0x2f; /* YUV 420 */
|
||||||
|
sd->fmt = fmt;
|
||||||
|
|
||||||
switch (mode & SCALE_MASK) {
|
switch (mode & SCALE_MASK) {
|
||||||
case SCALE_1280x1024:
|
case SCALE_1280x1024:
|
||||||
|
Loading…
Reference in New Issue
Block a user