Commit 30c73d46 authored by Jean-François Moine's avatar Jean-François Moine Committed by Mauro Carvalho Chehab

[media] gspca - zc3xx: Adjust the JPEG decompression tables

As the bridge register 08 defines the JPEG compression quality,
it must be changed on JPEG quality change and also, the decompression
tables must be adjusted when the register varies.

[mchehab@redhat.com: replace a // comment by a /* */ one]
Signed-off-by: default avatarJean-François Moine <moinejf@free.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent a7705c09
...@@ -34,7 +34,7 @@ MODULE_LICENSE("GPL"); ...@@ -34,7 +34,7 @@ MODULE_LICENSE("GPL");
static int force_sensor = -1; static int force_sensor = -1;
#define QUANT_VAL 1 /* quantization table */ #define REG08_DEF 3 /* default JPEG compression (70%) */
#include "zc3xx-reg.h" #include "zc3xx-reg.h"
/* controls */ /* controls */
...@@ -57,10 +57,7 @@ struct sd { ...@@ -57,10 +57,7 @@ struct sd {
struct gspca_ctrl ctrls[NCTRLS]; struct gspca_ctrl ctrls[NCTRLS];
u8 quality; /* image quality */ u8 reg08; /* webcam compression quality */
#define QUALITY_MIN 50
#define QUALITY_MAX 80
#define QUALITY_DEF 70
u8 bridge; u8 bridge;
u8 sensor; /* Type of image sensor chip */ u8 sensor; /* Type of image sensor chip */
...@@ -229,6 +226,9 @@ static const struct v4l2_pix_format sif_mode[] = { ...@@ -229,6 +226,9 @@ static const struct v4l2_pix_format sif_mode[] = {
.priv = 0}, .priv = 0},
}; };
/* bridge reg08 -> JPEG quality conversion table */
static u8 jpeg_qual[] = {40, 50, 60, 70, /*80*/};
/* usb exchanges */ /* usb exchanges */
struct usb_action { struct usb_action {
u8 req; u8 req;
...@@ -5925,32 +5925,17 @@ static void setexposure(struct gspca_dev *gspca_dev) ...@@ -5925,32 +5925,17 @@ static void setexposure(struct gspca_dev *gspca_dev)
static void setquality(struct gspca_dev *gspca_dev) static void setquality(struct gspca_dev *gspca_dev)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
u8 frxt; s8 reg07;
reg07 = 0;
switch (sd->sensor) { switch (sd->sensor) {
case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_HV7131B:
case SENSOR_HV7131R:
case SENSOR_OV7620: case SENSOR_OV7620:
case SENSOR_PAS202B: reg07 = 0x30;
case SENSOR_PO2030: break;
return;
} }
/*fixme: is it really 0008 0007 0018 for all other sensors? */ reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
reg_w(gspca_dev, QUANT_VAL, 0x0008); if (reg07 != 0)
frxt = 0x30; reg_w(gspca_dev, reg07, 0x0007);
reg_w(gspca_dev, frxt, 0x0007);
#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2
frxt = 0xff;
#elif QUANT_VAL == 3
frxt = 0xf0;
#elif QUANT_VAL == 4
frxt = 0xe0;
#else
frxt = 0x20;
#endif
reg_w(gspca_dev, frxt, 0x0018);
} }
/* Matches the sensor's internal frame rate to the lighting frequency. /* Matches the sensor's internal frame rate to the lighting frequency.
...@@ -6411,7 +6396,7 @@ static int sd_config(struct gspca_dev *gspca_dev, ...@@ -6411,7 +6396,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info; sd->sensor = id->driver_info;
gspca_dev->cam.ctrls = sd->ctrls; gspca_dev->cam.ctrls = sd->ctrls;
sd->quality = QUALITY_DEF; sd->reg08 = REG08_DEF;
return 0; return 0;
} }
...@@ -6464,6 +6449,27 @@ static int sd_init(struct gspca_dev *gspca_dev) ...@@ -6464,6 +6449,27 @@ static int sd_init(struct gspca_dev *gspca_dev)
[SENSOR_PO2030] = 1, [SENSOR_PO2030] = 1,
[SENSOR_TAS5130C] = 1, [SENSOR_TAS5130C] = 1,
}; };
static const u8 reg08_tb[SENSOR_MAX] = {
[SENSOR_ADCM2700] = 1,
[SENSOR_CS2102] = 3,
/* [SENSOR_CS2102K] = 3, */
[SENSOR_GC0303] = 2,
[SENSOR_GC0305] = 3,
[SENSOR_HDCS2020] = 1,
[SENSOR_HV7131B] = 3,
[SENSOR_HV7131R] = 3,
[SENSOR_ICM105A] = 3,
[SENSOR_MC501CB] = 3,
[SENSOR_MT9V111_1] = 3,
[SENSOR_MT9V111_3] = 3,
[SENSOR_OV7620] = 1,
[SENSOR_OV7630C] = 3,
[SENSOR_PAS106] = 3,
[SENSOR_PAS202B] = 3,
[SENSOR_PB0330] = 3,
[SENSOR_PO2030] = 2,
[SENSOR_TAS5130C] = 3,
};
sensor = zcxx_probeSensor(gspca_dev); sensor = zcxx_probeSensor(gspca_dev);
if (sensor >= 0) if (sensor >= 0)
...@@ -6616,6 +6622,7 @@ static int sd_init(struct gspca_dev *gspca_dev) ...@@ -6616,6 +6622,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
} }
sd->ctrls[GAMMA].def = gamma[sd->sensor]; sd->ctrls[GAMMA].def = gamma[sd->sensor];
sd->reg08 = reg08_tb[sd->sensor];
switch (sd->sensor) { switch (sd->sensor) {
case SENSOR_HV7131R: case SENSOR_HV7131R:
...@@ -6685,7 +6692,6 @@ static int sd_start(struct gspca_dev *gspca_dev) ...@@ -6685,7 +6692,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* create the JPEG header */ /* create the JPEG header */
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
0x21); /* JPEG 422 */ 0x21); /* JPEG 422 */
jpeg_set_qual(sd->jpeg_hdr, sd->quality);
mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
switch (sd->sensor) { switch (sd->sensor) {
...@@ -6761,10 +6767,9 @@ static int sd_start(struct gspca_dev *gspca_dev) ...@@ -6761,10 +6767,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_r(gspca_dev, 0x0180); /* from win */ reg_r(gspca_dev, 0x0180); /* from win */
reg_w(gspca_dev, 0x00, 0x0180); reg_w(gspca_dev, 0x00, 0x0180);
break; break;
default:
setquality(gspca_dev);
break;
} }
setquality(gspca_dev);
jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08]);
setlightfreq(gspca_dev); setlightfreq(gspca_dev);
switch (sd->sensor) { switch (sd->sensor) {
...@@ -6802,13 +6807,6 @@ static int sd_start(struct gspca_dev *gspca_dev) ...@@ -6802,13 +6807,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
} }
setautogain(gspca_dev); setautogain(gspca_dev);
switch (sd->sensor) {
case SENSOR_PO2030:
msleep(50);
reg_w(gspca_dev, 0x00, 0x0007); /* (from win traces) */
reg_w(gspca_dev, 0x02, ZC3XX_R008_CLOCKSETTING);
break;
}
return gspca_dev->usb_err; return gspca_dev->usb_err;
} }
...@@ -6897,15 +6895,20 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev, ...@@ -6897,15 +6895,20 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev,
struct v4l2_jpegcompression *jcomp) struct v4l2_jpegcompression *jcomp)
{ {
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
int i;
if (jcomp->quality < QUALITY_MIN) for (i = 0; i < ARRAY_SIZE(jpeg_qual) - 1; i++) {
sd->quality = QUALITY_MIN; if (jcomp->quality <= jpeg_qual[i])
else if (jcomp->quality > QUALITY_MAX) break;
sd->quality = QUALITY_MAX; }
else if (i > 0
sd->quality = jcomp->quality; && i == sd->reg08
&& jcomp->quality < jpeg_qual[sd->reg08])
i--;
sd->reg08 = i;
jcomp->quality = jpeg_qual[i];
if (gspca_dev->streaming) if (gspca_dev->streaming)
jpeg_set_qual(sd->jpeg_hdr, sd->quality); jpeg_set_qual(sd->jpeg_hdr, jcomp->quality);
return gspca_dev->usb_err; return gspca_dev->usb_err;
} }
...@@ -6915,7 +6918,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev, ...@@ -6915,7 +6918,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev; struct sd *sd = (struct sd *) gspca_dev;
memset(jcomp, 0, sizeof *jcomp); memset(jcomp, 0, sizeof *jcomp);
jcomp->quality = sd->quality; jcomp->quality = jpeg_qual[sd->reg08];
jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
| V4L2_JPEG_MARKER_DQT; | V4L2_JPEG_MARKER_DQT;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment