The patch number 14245 was added via h...@rhel5-devel.localdomain
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        Linux Media Mailing List <linux-me...@vger.kernel.org>

------

From: Hans de Goede  <hdego...@redhat.com>
libv4l: avoid overshooting when doing autogain


If we were decreasing gain/expo and change to increasing, or vica versa,
half the number of steps to avoid overshooting and oscilating.

Priority: normal

Signed-off-by: Hans de Goede <hdego...@redhat.com>


---

 v4l2-apps/libv4l/libv4lconvert/processing/autogain.c              |   25 
++++++++--
 v4l2-apps/libv4l/libv4lconvert/processing/libv4lprocessing-priv.h |    2 
 2 files changed, 23 insertions(+), 4 deletions(-)

diff -r 8da940f5312d -r 5d1f996fc3a0 
v4l2-apps/libv4l/libv4lconvert/processing/autogain.c
--- a/v4l2-apps/libv4l/libv4lconvert/processing/autogain.c      Thu Oct 01 
08:29:58 2009 +0200
+++ b/v4l2-apps/libv4l/libv4lconvert/processing/autogain.c      Thu Oct 01 
12:04:14 2009 +0200
@@ -28,7 +28,15 @@
 #include "../libv4lsyscall-priv.h"
 
 static int autogain_active(struct v4lprocessing_data *data) {
-  return v4lcontrol_get_ctrl(data->control, V4LCONTROL_AUTOGAIN);
+  int autogain;
+
+  autogain = v4lcontrol_get_ctrl(data->control, V4LCONTROL_AUTOGAIN);
+  if (!autogain) {
+    /* Reset last_correction val */
+    data->last_gain_correction = 0;
+  }
+
+  return autogain;
 }
 
 /* auto gain and exposure algorithm based on the knee algorithm described here:
@@ -41,7 +49,7 @@
   int gain, exposure, orig_gain, orig_exposure;
   struct v4l2_control ctrl;
   struct v4l2_queryctrl gainctrl, expoctrl;
-  const int deadzone = 8;
+  const int deadzone = 6;
 
   ctrl.id = V4L2_CID_EXPOSURE;
   expoctrl.id = V4L2_CID_EXPOSURE;
@@ -94,9 +102,15 @@
   /* If we are off a multiple of deadzone, do multiple steps to reach the
      desired lumination fast (with the risc of a slight overshoot) */
   target = v4lcontrol_get_ctrl(data->control, V4LCONTROL_AUTOGAIN_TARGET);
-  steps = abs(target - avg_lum) / deadzone;
+  steps = (target - avg_lum) / deadzone;
 
-  for (x = 0; x < steps; x++) {
+  /* If we were decreasing and are now increasing, or vica versa, half the
+     number of steps to avoid overshooting and oscilating */
+  if ((steps > 0 && data->last_gain_correction < 0) ||
+      (steps < 0 && data->last_gain_correction > 0))
+    steps /= 2;
+
+  for (x = 0; x < abs(steps); x++) {
     if (avg_lum > target) {
       if (exposure > expoctrl.default_value)
        exposure--;
@@ -122,6 +136,9 @@
     }
   }
 
+  if (steps)
+    data->last_gain_correction = steps;
+
   if (gain != orig_gain) {
     ctrl.id = V4L2_CID_GAIN;
     ctrl.value = gain;
diff -r 8da940f5312d -r 5d1f996fc3a0 
v4l2-apps/libv4l/libv4lconvert/processing/libv4lprocessing-priv.h
--- a/v4l2-apps/libv4l/libv4lconvert/processing/libv4lprocessing-priv.h Thu Oct 
01 08:29:58 2009 +0200
+++ b/v4l2-apps/libv4l/libv4lconvert/processing/libv4lprocessing-priv.h Thu Oct 
01 12:04:14 2009 +0200
@@ -49,6 +49,8 @@
   /* gamma.c data */
   int last_gamma;
   unsigned char gamma_table[256];
+  /* autogain.c data */
+  int last_gain_correction;
 };
 
 struct v4lprocessing_filter {


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/5d1f996fc3a03fca19dbb95e0e5112ff02964546

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to