All of lore.kernel.org
 help / color / mirror / Atom feed
* PATCH: gspca-general-autogain_n_exposure-knee-algp.patch
@ 2008-07-09 13:29 Hans de Goede
  0 siblings, 0 replies; only message in thread
From: Hans de Goede @ 2008-07-09 13:29 UTC (permalink / raw)
  To: video4linux-list

[-- Attachment #1: Type: text/plain, Size: 427 bytes --]

Hi,

Make the knee auto gain and exposure algorithm, described here:
http://ytse.tricolour.net/docs/LowLightOptimization.html

And currently used in the pac207 generic (iow not pac207 specific) and move it
to gspca.c . This is a preperation patch for adding exposure setting and auto
gain and exposure to the sn9c10x driver (for selective sensors for now).

Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl>

Regards,

Hans


[-- Attachment #2: gspca-general-autogain_n_exposure-knee-algp.patch --]
[-- Type: text/plain, Size: 6978 bytes --]

Make the knee auto gain and exposure algorithm, described here:
http://ytse.tricolour.net/docs/LowLightOptimization.html

And currently used in the pac207 generic (iow not pac207 specific) and move it
to gspca.c . This is a preperation patch for adding exposure setting and auto
gain and exposure to the sn9c10x driver (for selective sensors for now).

Signed-off-by: Hans de Goede <j.w.r.degoede@hhs.nl>

diff -r 5065159a99d4 linux/drivers/media/video/gspca/gspca.c
--- a/linux/drivers/media/video/gspca/gspca.c	Sun Jul 06 09:27:19 2008 +0200
+++ b/linux/drivers/media/video/gspca/gspca.c	Mon Jul 07 09:15:54 2008 +0200
@@ -1894,6 +1894,91 @@
 }
 EXPORT_SYMBOL(gspca_disconnect);
 
+/* -- cam driver utility functions -- */
+
+/* auto gain and exposure algorithm based on the knee algorithm described here:
+   http://ytse.tricolour.net/docs/LowLightOptimization.html
+
+   Returns 0 if no changes were made, 1 if the gain and or exposure settings
+   where changed. */
+int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
+	int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee)
+{
+	int i, steps, gain, orig_gain, exposure, orig_exposure, autogain;
+	const struct ctrl *gain_ctrl = NULL;
+	const struct ctrl *exposure_ctrl = NULL;
+	const struct ctrl *autogain_ctrl = NULL;
+	int retval = 0;
+
+	for (i = 0; i < gspca_dev->sd_desc->nctrls; i++) {
+		if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_GAIN)
+			gain_ctrl = &gspca_dev->sd_desc->ctrls[i];
+		if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_EXPOSURE)
+			exposure_ctrl = &gspca_dev->sd_desc->ctrls[i];
+		if (gspca_dev->sd_desc->ctrls[i].qctrl.id == V4L2_CID_AUTOGAIN)
+			autogain_ctrl = &gspca_dev->sd_desc->ctrls[i];
+	}
+	if (!gain_ctrl || !exposure_ctrl || !autogain_ctrl) {
+		PDEBUG(D_ERR, "Error: gspca_auto_gain_n_exposure called "
+			"on cam without (auto)gain/exposure");
+		return 0;
+	}
+
+	if (gain_ctrl->get(gspca_dev, &gain) ||
+			exposure_ctrl->get(gspca_dev, &exposure) ||
+			autogain_ctrl->get(gspca_dev, &autogain) || !autogain)
+		return 0;
+
+	orig_gain = gain;
+	orig_exposure = exposure;
+
+	/* If we are of a multiple of deadzone, do multiple steps to reach the
+	   desired lumination fast (with the risc of a slight overshoot) */
+	steps = abs(desired_avg_lum - avg_lum) / deadzone;
+
+	for (i = 0; i < steps; i++) {
+		if (avg_lum > desired_avg_lum) {
+			if (gain > gain_knee)
+				gain--;
+			else if (exposure > exposure_knee)
+				exposure--;
+			else if (gain > gain_ctrl->qctrl.default_value)
+				gain--;
+			else if (exposure > exposure_ctrl->qctrl.minimum)
+				exposure--;
+			else if (gain > gain_ctrl->qctrl.minimum)
+				gain--;
+			else
+				break;
+		} else {
+			if (gain < gain_ctrl->qctrl.default_value)
+				gain++;
+			else if (exposure < exposure_knee)
+				exposure++;
+			else if (gain < gain_knee)
+				gain++;
+			else if (exposure < exposure_ctrl->qctrl.maximum)
+				exposure++;
+			else if (gain < gain_ctrl->qctrl.maximum)
+				gain++;
+			else
+				break;
+		}
+	}
+
+	if (gain != orig_gain) {
+		gain_ctrl->set(gspca_dev, gain);
+		retval = 1;
+	}
+	if (exposure != orig_exposure) {
+		exposure_ctrl->set(gspca_dev, exposure);
+		retval = 1;
+	}
+
+	return retval;
+}
+EXPORT_SYMBOL(gspca_auto_gain_n_exposure);
+
 /* -- module insert / remove -- */
 static int __init gspca_init(void)
 {
diff -r 5065159a99d4 linux/drivers/media/video/gspca/gspca.h
--- a/linux/drivers/media/video/gspca/gspca.h	Sun Jul 06 09:27:19 2008 +0200
+++ b/linux/drivers/media/video/gspca/gspca.h	Mon Jul 07 09:15:54 2008 +0200
@@ -172,4 +172,6 @@
 				    struct gspca_frame *frame,
 				    const __u8 *data,
 				    int len);
+int gspca_auto_gain_n_exposure(struct gspca_dev *gspca_dev, int avg_lum,
+	int desired_avg_lum, int deadzone, int gain_knee, int exposure_knee);
 #endif /* GSPCAV2_H */
diff -r 5065159a99d4 linux/drivers/media/video/gspca/pac207.c
--- a/linux/drivers/media/video/gspca/pac207.c	Sun Jul 06 09:27:19 2008 +0200
+++ b/linux/drivers/media/video/gspca/pac207.c	Mon Jul 07 09:15:54 2008 +0200
@@ -357,70 +357,20 @@
 {
 }
 
-/* auto gain and exposure algorithm based on the knee algorithm described here:
- * <http://ytse.tricolour.net/docs/LowLightOptimization.html> */
 static void pac207_do_auto_gain(struct gspca_dev *gspca_dev)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-	int i, steps, desired_avg_lum;
-	int orig_gain = sd->gain;
-	int orig_exposure = sd->exposure;
 	int avg_lum = atomic_read(&sd->avg_lum);
 
-	if (!sd->autogain || avg_lum == -1)
+	if (avg_lum == -1)
 		return;
 
-	if (sd->autogain_ignore_frames > 0) {
+	if (sd->autogain_ignore_frames > 0)
 		sd->autogain_ignore_frames--;
-		return;
-	}
-
-	/* correct desired lumination for the configured brightness */
-	desired_avg_lum = 100 + sd->brightness / 2;
-
-	/* If we are of a multiple of deadzone, do multiple step to reach the
-	   desired lumination fast (with the risc of a slight overshoot) */
-	steps = abs(desired_avg_lum - avg_lum) / PAC207_AUTOGAIN_DEADZONE;
-
-	for (i = 0; i < steps; i++) {
-		if (avg_lum > desired_avg_lum) {
-			if (sd->gain > PAC207_GAIN_KNEE)
-				sd->gain--;
-			else if (sd->exposure > PAC207_EXPOSURE_KNEE)
-				sd->exposure--;
-			else if (sd->gain > PAC207_GAIN_DEFAULT)
-				sd->gain--;
-			else if (sd->exposure > PAC207_EXPOSURE_MIN)
-				sd->exposure--;
-			else if (sd->gain > PAC207_GAIN_MIN)
-				sd->gain--;
-			else
-				break;
-		} else {
-			if (sd->gain < PAC207_GAIN_DEFAULT)
-				sd->gain++;
-			else if (sd->exposure < PAC207_EXPOSURE_KNEE)
-				sd->exposure++;
-			else if (sd->gain < PAC207_GAIN_KNEE)
-				sd->gain++;
-			else if (sd->exposure < PAC207_EXPOSURE_MAX)
-				sd->exposure++;
-			else if (sd->gain < PAC207_GAIN_MAX)
-				sd->gain++;
-			else
-				break;
-		}
-	}
-
-	if (sd->exposure != orig_exposure || sd->gain != orig_gain) {
-		if (sd->exposure != orig_exposure)
-			pac207_write_reg(gspca_dev, 0x0002, sd->exposure);
-		if (sd->gain != orig_gain)
-			pac207_write_reg(gspca_dev, 0x000e, sd->gain);
-		pac207_write_reg(gspca_dev, 0x13, 0x01); /* load reg to sen */
-		pac207_write_reg(gspca_dev, 0x1c, 0x01); /* not documented */
+	else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
+			100 + sd->brightness / 2, PAC207_AUTOGAIN_DEADZONE,
+			PAC207_GAIN_KNEE, PAC207_EXPOSURE_KNEE))
 		sd->autogain_ignore_frames = PAC207_AUTOGAIN_IGNORE_FRAMES;
-	}
 }
 
 static unsigned char *pac207_find_sof(struct gspca_dev *gspca_dev,
@@ -546,10 +496,6 @@
 {
 	struct sd *sd = (struct sd *) gspca_dev;
 
-	/* don't allow mucking with exposure when using autogain */
-	if (sd->autogain)
-		return -EINVAL;
-
 	sd->exposure = val;
 	if (gspca_dev->streaming)
 		setexposure(gspca_dev);
@@ -567,10 +513,6 @@
 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
 {
 	struct sd *sd = (struct sd *) gspca_dev;
-
-	/* don't allow mucking with gain when using autogain */
-	if (sd->autogain)
-		return -EINVAL;
 
 	sd->gain = val;
 	if (gspca_dev->streaming)


[-- Attachment #3: Type: text/plain, Size: 164 bytes --]

--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@redhat.com?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-07-09 13:30 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-09 13:29 PATCH: gspca-general-autogain_n_exposure-knee-algp.patch Hans de Goede

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.