diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-03-16 15:48:30 +0100 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-05-01 12:13:56 +0200 |
commit | f030d07589524d07d5eaf7c2dfff607656889b8b (patch) | |
tree | be57ed8735b8ffbc6fb9cd7ca461f037c1e61978 /iq.c | |
parent | b0e966a8488e19fcc1c7eb86a217c5f7675a4da0 (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.c | 134 |
1 files changed, 100 insertions, 34 deletions
@@ -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 = ¶ms->exposure; + else if (strncmp(arg, "exposure-min", size) == 0) + val_uint = ¶ms->exposure_min; + else if (strncmp(arg, "exposure-max", size) == 0) + val_uint = ¶ms->exposure_max; + else if (strncmp(arg, "gain-def", size) == 0) + val_uint = ¶ms->gain; + else if (strncmp(arg, "gain-min", size) == 0) + val_uint = ¶ms->gain_min; + else if (strncmp(arg, "gain-max", size) == 0) + val_uint = ¶ms->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; |