summaryrefslogtreecommitdiff
path: root/iq.c
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-03-16 15:48:30 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2012-05-01 12:13:56 +0200
commitf030d07589524d07d5eaf7c2dfff607656889b8b (patch)
treebe57ed8735b8ffbc6fb9cd7ca461f037c1e61978 /iq.c
parentb0e966a8488e19fcc1c7eb86a217c5f7675a4da0 (diff)
iq: Make the IQ parameters configurable
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'iq.c')
-rw-r--r--iq.c134
1 files changed, 100 insertions, 34 deletions
diff --git a/iq.c b/iq.c
index b02c297..c407b6e 100644
--- a/iq.c
+++ b/iq.c
@@ -37,22 +37,14 @@ struct iq_tuning {
unsigned int frame_count;
unsigned int pix_max;
- float mean_level;
- unsigned int exposure;
- unsigned int exposure_min;
- unsigned int exposure_max;
-
- unsigned int gain;
- unsigned int gain_min;
- unsigned int gain_max;
-
- unsigned int black_level;
+ struct iq_params params;
};
void iq_aewb_process(struct iq_tuning *iq,
const struct omap3_isp_aewb_stats *stats)
{
+ struct iq_params *iqp = &iq->params;
unsigned int i;
float gains[4];
double factor;
@@ -77,24 +69,104 @@ void iq_aewb_process(struct iq_tuning *iq,
+ stats->accum[2] + stats->accum[3];
mean /= 4 * stats->npix;
- factor = (iq->pix_max * iq->mean_level) / mean;
+ factor = (iq->pix_max * iqp->mean_level) / mean;
- gain = factor * iq->exposure * iq->gain / iq->gain_min;
- iq->exposure = clamp((unsigned int)gain,
- iq->exposure_min, iq->exposure_max);
+ gain = factor * iqp->exposure * iqp->gain / iqp->gain_min;
+ iqp->exposure = clamp((unsigned int)gain,
+ iqp->exposure_min, iqp->exposure_max);
- gain = gain / iq->exposure * iq->gain_min;
- iq->gain = clamp((unsigned int)gain,
- iq->gain_min, iq->gain_max);
+ gain = gain / iqp->exposure * iqp->gain_min;
+ iqp->gain = clamp((unsigned int)gain, iqp->gain_min, iqp->gain_max);
printf("AE: factor %.4f exposure %u sensor gain %u\n",
- factor, iq->exposure, iq->gain);
+ factor, iqp->exposure, iqp->gain);
- omap3_isp_sensor_set_exposure(iq->isp, iq->exposure);
- omap3_isp_sensor_set_gain(iq->isp, iq->gain);
+ omap3_isp_sensor_set_exposure(iq->isp, iqp->exposure);
+ omap3_isp_sensor_set_gain(iq->isp, iqp->gain);
}
-struct iq_tuning *iq_init(struct omap3_isp_device *isp)
+/**
+ * iq_params_init - Initialize IQ parameters
+ * @params: IQ parameters
+ *
+ * Fill the passed params structure with the default IQ parameters.
+ */
+void iq_params_init(struct iq_params *params)
+{
+ params->mean_level = 0.15;
+ params->exposure = 1000;
+ params->exposure_min = 10;
+ params->exposure_max = 2000;
+ params->gain = 8;
+ params->gain_min = 8;
+ params->gain_max = 1024;
+ params->black_level = 64;
+}
+
+/**
+ * iq_params_parse - Parse an IQ parameter string
+ * @params: IQ parameters
+ * @arg: Parameter string
+ *
+ * Parse the given parameter string and store the parameter value in the params
+ * structure. The parameter string must have the form
+ *
+ * name=value
+ *
+ * Return 0 on success or a negative error code otherwise:
+ *
+ * -EINVAL: The string format or the parameter name is invalid
+ * -ERANGE: The parameter value is out of range for the given parameter
+ */
+int iq_params_parse(struct iq_params *params, const char *arg)
+{
+ unsigned int *val_uint;
+ const char *value;
+ unsigned int size;
+ char *endp;
+
+ value = strchr(arg, '=');
+ if (value == NULL)
+ return -EINVAL;
+
+ size = value - arg;
+ value++;
+
+ if (strncmp(arg, "mean-level", size) == 0) {
+ params->mean_level = strtof(value, &endp);
+ if (*endp != '\0')
+ return -EINVAL;
+
+ if (params->mean_level <= 0 || params-> mean_level >= 1)
+ return -ERANGE;
+
+ return 0;
+ }
+
+ if (strncmp(arg, "exposure-def", size) == 0)
+ val_uint = &params->exposure;
+ else if (strncmp(arg, "exposure-min", size) == 0)
+ val_uint = &params->exposure_min;
+ else if (strncmp(arg, "exposure-max", size) == 0)
+ val_uint = &params->exposure_max;
+ else if (strncmp(arg, "gain-def", size) == 0)
+ val_uint = &params->gain;
+ else if (strncmp(arg, "gain-min", size) == 0)
+ val_uint = &params->gain_min;
+ else if (strncmp(arg, "gain-max", size) == 0)
+ val_uint = &params->gain_max;
+ else
+ return -EINVAL;
+
+ *val_uint = strtoul(value, &endp, 10);
+ if (*endp != '\0')
+ return -EINVAL;
+
+ return 0;
+}
+
+struct iq_tuning *iq_init(struct omap3_isp_device *isp,
+ const struct iq_params *params)
{
struct v4l2_mbus_framefmt format;
struct v4l2_rect window;
@@ -107,18 +179,12 @@ struct iq_tuning *iq_init(struct omap3_isp_device *isp)
iq->isp = isp;
iq->frame_count = 0;
iq->pix_max = (1 << 10) - 1;
- iq->mean_level = 0.15;
- iq->exposure = 1000;
- iq->exposure_min = 10;
- iq->exposure_max = 2000;
- iq->gain = 8;
- iq->gain_min = 8;
- iq->gain_max = 1024;
- iq->black_level = 64;
-
- omap3_isp_sensor_set_gain(isp, iq->gain);
- omap3_isp_sensor_set_exposure(isp, iq->exposure);
- omap3_isp_ccdc_set_black_level(isp, iq->black_level);
+
+ iq->params = *params;
+
+ omap3_isp_sensor_set_gain(isp, iq->params.gain);
+ omap3_isp_sensor_set_exposure(isp, iq->params.exposure);
+ omap3_isp_ccdc_set_black_level(isp, iq->params.black_level);
omap3_isp_stats_get_format(isp, &format);
window.left = 0;
@@ -126,7 +192,7 @@ struct iq_tuning *iq_init(struct omap3_isp_device *isp)
window.width = format.width;
window.height = format.height;
- omap3_isp_aewb_configure(isp, &window, iq->pix_max - iq->black_level - 1);
+ omap3_isp_aewb_configure(isp, &window, iq->pix_max - iq->params.black_level - 1);
omap3_isp_stats_enable(isp, true);
return iq;