Skip to content

Commit

Permalink
[media] gspca - zc3xx: Adjust the JPEG decompression tables
Browse files Browse the repository at this point in the history
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: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Jean-François Moine authored and Mauro Carvalho Chehab committed Mar 8, 2012
1 parent a7705c0 commit 30c73d4
Showing 1 changed file with 50 additions and 47 deletions.
97 changes: 50 additions & 47 deletions drivers/media/video/gspca/zc3xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ MODULE_LICENSE("GPL");

static int force_sensor = -1;

#define QUANT_VAL 1 /* quantization table */
#define REG08_DEF 3 /* default JPEG compression (70%) */
#include "zc3xx-reg.h"

/* controls */
Expand All @@ -57,10 +57,7 @@ struct sd {

struct gspca_ctrl ctrls[NCTRLS];

u8 quality; /* image quality */
#define QUALITY_MIN 50
#define QUALITY_MAX 80
#define QUALITY_DEF 70
u8 reg08; /* webcam compression quality */

u8 bridge;
u8 sensor; /* Type of image sensor chip */
Expand Down Expand Up @@ -229,6 +226,9 @@ static const struct v4l2_pix_format sif_mode[] = {
.priv = 0},
};

/* bridge reg08 -> JPEG quality conversion table */
static u8 jpeg_qual[] = {40, 50, 60, 70, /*80*/};

/* usb exchanges */
struct usb_action {
u8 req;
Expand Down Expand Up @@ -5925,32 +5925,17 @@ static void setexposure(struct gspca_dev *gspca_dev)
static void setquality(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
u8 frxt;
s8 reg07;

reg07 = 0;
switch (sd->sensor) {
case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_HV7131B:
case SENSOR_HV7131R:
case SENSOR_OV7620:
case SENSOR_PAS202B:
case SENSOR_PO2030:
return;
reg07 = 0x30;
break;
}
/*fixme: is it really 0008 0007 0018 for all other sensors? */
reg_w(gspca_dev, QUANT_VAL, 0x0008);
frxt = 0x30;
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);
reg_w(gspca_dev, sd->reg08, ZC3XX_R008_CLOCKSETTING);
if (reg07 != 0)
reg_w(gspca_dev, reg07, 0x0007);
}

/* Matches the sensor's internal frame rate to the lighting frequency.
Expand Down Expand Up @@ -6411,7 +6396,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info;

gspca_dev->cam.ctrls = sd->ctrls;
sd->quality = QUALITY_DEF;
sd->reg08 = REG08_DEF;

return 0;
}
Expand Down Expand Up @@ -6464,6 +6449,27 @@ static int sd_init(struct gspca_dev *gspca_dev)
[SENSOR_PO2030] = 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);
if (sensor >= 0)
Expand Down Expand Up @@ -6616,6 +6622,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
}

sd->ctrls[GAMMA].def = gamma[sd->sensor];
sd->reg08 = reg08_tb[sd->sensor];

switch (sd->sensor) {
case SENSOR_HV7131R:
Expand Down Expand Up @@ -6685,7 +6692,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* create the JPEG header */
jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
0x21); /* JPEG 422 */
jpeg_set_qual(sd->jpeg_hdr, sd->quality);

mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
switch (sd->sensor) {
Expand Down Expand Up @@ -6761,10 +6767,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_r(gspca_dev, 0x0180); /* from win */
reg_w(gspca_dev, 0x00, 0x0180);
break;
default:
setquality(gspca_dev);
break;
}
setquality(gspca_dev);
jpeg_set_qual(sd->jpeg_hdr, jpeg_qual[sd->reg08]);
setlightfreq(gspca_dev);

switch (sd->sensor) {
Expand Down Expand Up @@ -6802,13 +6807,6 @@ static int sd_start(struct gspca_dev *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;
}

Expand Down Expand Up @@ -6897,15 +6895,20 @@ static int sd_set_jcomp(struct gspca_dev *gspca_dev,
struct v4l2_jpegcompression *jcomp)
{
struct sd *sd = (struct sd *) gspca_dev;
int i;

if (jcomp->quality < QUALITY_MIN)
sd->quality = QUALITY_MIN;
else if (jcomp->quality > QUALITY_MAX)
sd->quality = QUALITY_MAX;
else
sd->quality = jcomp->quality;
for (i = 0; i < ARRAY_SIZE(jpeg_qual) - 1; i++) {
if (jcomp->quality <= jpeg_qual[i])
break;
}
if (i > 0
&& i == sd->reg08
&& jcomp->quality < jpeg_qual[sd->reg08])
i--;
sd->reg08 = i;
jcomp->quality = jpeg_qual[i];
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;
}

Expand All @@ -6915,7 +6918,7 @@ static int sd_get_jcomp(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;

memset(jcomp, 0, sizeof *jcomp);
jcomp->quality = sd->quality;
jcomp->quality = jpeg_qual[sd->reg08];
jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
| V4L2_JPEG_MARKER_DQT;
return 0;
Expand Down

0 comments on commit 30c73d4

Please sign in to comment.