1 /*
2 * aiq_handler.cpp - AIQ handler
3 *
4 * Copyright (c) 2012-2015 Intel Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Wind Yuan <feng.yuan@intel.com>
19 * Author: Yan Zhang <yan.y.zhang@intel.com>
20 */
21
22 #include "aiq_handler.h"
23 #include "x3a_isp_config.h"
24
25 #include <string.h>
26 #include <math.h>
27
28 #include "ia_isp_2_2.h"
29
30 #define MAX_STATISTICS_WIDTH 150
31 #define MAX_STATISTICS_HEIGHT 150
32
33 //#define USE_RGBS_GRID_WEIGHTING
34 #define USE_HIST_GRID_WEIGHTING
35
36 namespace XCam {
37
38 struct IspInputParameters {
39 ia_aiq_frame_use frame_use;
40 ia_aiq_frame_params *sensor_frame_params;
41 ia_aiq_exposure_parameters *exposure_results;
42 ia_aiq_awb_results *awb_results;
43 ia_aiq_gbce_results *gbce_results;
44 ia_aiq_pa_results *pa_results;
45 #ifdef HAVE_AIQ_2_7
46 ia_aiq_sa_results *sa_results;
47 #endif
48 int8_t manual_brightness;
49 int8_t manual_contrast;
50 int8_t manual_hue;
51 int8_t manual_saturation;
52 int8_t manual_sharpness;
53 int8_t manual_nr_level;
54 ia_isp_effect effects;
55
IspInputParametersXCam::IspInputParameters56 IspInputParameters ()
57 : frame_use (ia_aiq_frame_use_preview)
58 , sensor_frame_params (NULL)
59 , exposure_results (NULL)
60 , awb_results (NULL)
61 , gbce_results (NULL)
62 , pa_results (NULL)
63 #ifdef HAVE_AIQ_2_7
64 , sa_results (NULL)
65 #endif
66 , manual_brightness (0)
67 , manual_contrast (0)
68 , manual_hue (0)
69 , manual_saturation (0)
70 , manual_sharpness (0)
71 , manual_nr_level (0)
72 , effects (ia_isp_effect_none)
73 {}
74 };
75
76 class IaIspAdaptor22
77 : public IaIspAdaptor
78 {
79 public:
IaIspAdaptor22()80 IaIspAdaptor22 () {
81 xcam_mem_clear (_input_params);
82 }
~IaIspAdaptor22()83 ~IaIspAdaptor22 () {
84 if (_handle)
85 ia_isp_2_2_deinit (_handle);
86 }
87
88 virtual bool init (
89 const ia_binary_data *cpf,
90 unsigned int max_width,
91 unsigned int max_height,
92 ia_cmc_t *cmc,
93 ia_mkn *mkn);
94
95 virtual bool convert_statistics (
96 void *statistics,
97 ia_aiq_rgbs_grid **out_rgbs_grid,
98 ia_aiq_af_grid **out_af_grid);
99
100 virtual bool run (
101 const IspInputParameters *isp_input_params,
102 ia_binary_data *output_data);
103
104 private:
105 ia_isp_2_2_input_params _input_params;
106
107 };
108
109 bool
init(const ia_binary_data * cpf,unsigned int max_width,unsigned int max_height,ia_cmc_t * cmc,ia_mkn * mkn)110 IaIspAdaptor22::init (
111 const ia_binary_data *cpf,
112 unsigned int max_width,
113 unsigned int max_height,
114 ia_cmc_t *cmc,
115 ia_mkn *mkn)
116 {
117 xcam_mem_clear (_input_params);
118 _input_params.isp_vamem_type = 1;
119 _handle = ia_isp_2_2_init (cpf, max_width, max_height, cmc, mkn);
120 XCAM_FAIL_RETURN (ERROR, _handle, false, "ia_isp 2.2 init failed");
121 return true;
122 }
123
124 bool
convert_statistics(void * statistics,ia_aiq_rgbs_grid ** out_rgbs_grid,ia_aiq_af_grid ** out_af_grid)125 IaIspAdaptor22::convert_statistics (
126 void *statistics,
127 ia_aiq_rgbs_grid **out_rgbs_grid,
128 ia_aiq_af_grid **out_af_grid)
129 {
130 ia_err err;
131 err = ia_isp_2_2_statistics_convert (_handle, statistics, out_rgbs_grid, out_af_grid);
132 XCAM_FAIL_RETURN (ERROR, err == ia_err_none, false, "ia_isp 2.2 convert stats failed");
133 return true;
134 }
135
136 bool
run(const IspInputParameters * isp_input_params,ia_binary_data * output_data)137 IaIspAdaptor22::run (
138 const IspInputParameters *isp_input_params,
139 ia_binary_data *output_data)
140 {
141 ia_err err;
142
143 _input_params.frame_use = isp_input_params->frame_use;
144 _input_params.sensor_frame_params = isp_input_params->sensor_frame_params;
145 _input_params.exposure_results = isp_input_params->exposure_results;
146 _input_params.awb_results = isp_input_params->awb_results;
147 _input_params.gbce_results = isp_input_params->gbce_results;
148 _input_params.pa_results = isp_input_params->pa_results;
149 #ifdef HAVE_AIQ_2_7
150 _input_params.sa_results = isp_input_params->sa_results;
151 #endif
152 _input_params.manual_brightness = isp_input_params->manual_brightness;
153 _input_params.manual_contrast = isp_input_params->manual_contrast;
154 _input_params.manual_hue = isp_input_params->manual_hue;
155 _input_params.manual_saturation = isp_input_params->manual_saturation;
156 _input_params.nr_setting.feature_level = ia_isp_feature_level_high;
157 _input_params.nr_setting.strength = isp_input_params->manual_nr_level;
158 _input_params.ee_setting.feature_level = ia_isp_feature_level_high;
159 _input_params.ee_setting.strength = isp_input_params->manual_sharpness;
160 _input_params.effects = isp_input_params->effects;
161
162 err = ia_isp_2_2_run (_handle, &_input_params, output_data);
163 XCAM_FAIL_RETURN (ERROR, err == ia_err_none, false, "ia_isp 2.2 run failed");
164 return true;
165 }
166
167 #if 0
168
169 class IaIspAdaptor15
170 : public IaIspAdaptor
171 {
172 public:
173 IaIspAdaptor15 () {
174 xcam_mem_clear (&_input_params);
175 }
176 ~IaIspAdaptor15 () {
177 if (_handle)
178 ia_isp_1_5_deinit (_handle);
179 }
180 virtual bool init (
181 const ia_binary_data *cpf,
182 unsigned int max_width,
183 unsigned int max_height,
184 ia_cmc_t *cmc,
185 ia_mkn *mkn);
186 virtual bool convert_statistics (
187 void *statistics,
188 ia_aiq_rgbs_grid **out_rgbs_grid,
189 ia_aiq_af_grid **out_af_grid);
190 virtual bool run (
191 const IspInputParameters *isp_input_params,
192 ia_binary_data *output_data);
193
194 private:
195 ia_isp_1_5_input_params _input_params;
196
197 };
198
199 bool
200 IaIspAdaptor15::init (
201 const ia_binary_data *cpf,
202 unsigned int max_width,
203 unsigned int max_height,
204 ia_cmc_t *cmc,
205 ia_mkn *mkn)
206 {
207 xcam_mem_clear (&_input_params);
208 _input_params.isp_vamem_type = 1;
209 _handle = ia_isp_1_5_init (cpf, max_width, max_height, cmc, mkn);
210 XCAM_FAIL_RETURN (ERROR, _handle, false, "ia_isp 1.5 init failed");
211 return true;
212 }
213
214 bool
215 IaIspAdaptor15::convert_statistics (
216 void *statistics,
217 ia_aiq_rgbs_grid **out_rgbs_grid,
218 ia_aiq_af_grid **out_af_grid)
219 {
220 ia_err err;
221 err = ia_isp_1_5_statistics_convert (_handle, statistics, out_rgbs_grid, out_af_grid);
222 XCAM_FAIL_RETURN (ERROR, err == ia_err_none, false, "ia_isp 1.5 convert stats failed");
223 return true;
224 }
225
226 bool
227 IaIspAdaptor15::run (
228 const IspInputParameters *isp_input_params,
229 ia_binary_data *output_data)
230 {
231 ia_err err;
232
233 _input_params.frame_use = isp_input_params->frame_use;
234 _input_params.sensor_frame_params = isp_input_params->sensor_frame_params;
235 _input_params.exposure_results = isp_input_params->exposure_results;
236 _input_params.awb_results = isp_input_params->awb_results;
237 _input_params.gbce_results = isp_input_params->gbce_results;
238 _input_params.pa_results = isp_input_params->pa_results;
239 _input_params.manual_brightness = isp_input_params->manual_brightness;
240 _input_params.manual_contrast = isp_input_params->manual_contrast;
241 _input_params.manual_hue = isp_input_params->manual_hue;
242 _input_params.manual_saturation = isp_input_params->manual_saturation;
243 _input_params.nr_setting.feature_level = ia_isp_feature_level_high;
244 _input_params.nr_setting.strength = isp_input_params->manual_nr_level;
245 _input_params.ee_setting.feature_level = ia_isp_feature_level_high;
246 _input_params.ee_setting.strength = isp_input_params->manual_sharpness;
247 _input_params.effects = isp_input_params->effects;
248
249 err = ia_isp_1_5_run (_handle, &_input_params, output_data);
250 XCAM_FAIL_RETURN (ERROR, err == ia_err_none, false, "ia_isp 1.5 run failed");
251 return true;
252 }
253
254 #endif
255
256 static double
_calculate_new_value_by_speed(double start,double end,double speed)257 _calculate_new_value_by_speed (double start, double end, double speed)
258 {
259 XCAM_ASSERT (speed >= 0.0 && speed <= 1.0);
260 static const double value_equal_range = 0.000001;
261
262 if (fabs (end - start) <= value_equal_range)
263 return end;
264 return (start * (1.0 - speed) + end * speed);
265 }
266
267 static double
_imx185_sensor_gain_code_to_mutiplier(uint32_t code)268 _imx185_sensor_gain_code_to_mutiplier (uint32_t code)
269 {
270 /* 185 sensor code : DB = 160 : 48 */
271 double db;
272 db = code * 48.0 / 160.0;
273 return pow (10.0, db / 20.0);
274 }
275
276 static uint32_t
_mutiplier_to_imx185_sensor_gain_code(double mutiplier)277 _mutiplier_to_imx185_sensor_gain_code (double mutiplier)
278 {
279 double db = log10 (mutiplier) * 20;
280 if (db > 48)
281 db = 48;
282 return (uint32_t) (db * 160 / 48);
283 }
284
285 static uint32_t
_time_to_coarse_line(const ia_aiq_exposure_sensor_descriptor * desc,uint32_t time_us)286 _time_to_coarse_line (const ia_aiq_exposure_sensor_descriptor *desc, uint32_t time_us)
287 {
288 float value = time_us * desc->pixel_clock_freq_mhz;
289
290 value = (value + desc->pixel_periods_per_line / 2) / desc->pixel_periods_per_line;
291 return (uint32_t)(value);
292 }
293
294 static uint32_t
_coarse_line_to_time(const ia_aiq_exposure_sensor_descriptor * desc,uint32_t coarse_line)295 _coarse_line_to_time (const ia_aiq_exposure_sensor_descriptor *desc, uint32_t coarse_line)
296 {
297 return coarse_line * desc->pixel_periods_per_line / desc->pixel_clock_freq_mhz;
298 }
299
AiqAeResult()300 AiqAeHandler::AiqAeResult::AiqAeResult()
301 {
302 xcam_mem_clear (ae_result);
303 xcam_mem_clear (ae_exp_ret);
304 xcam_mem_clear (aiq_exp_param);
305 xcam_mem_clear (sensor_exp_param);
306 xcam_mem_clear (weight_grid);
307 xcam_mem_clear (flash_param);
308 }
309
310 void
copy(ia_aiq_ae_results * result)311 AiqAeHandler::AiqAeResult::copy (ia_aiq_ae_results *result)
312 {
313 XCAM_ASSERT (result);
314
315 this->ae_result = *result;
316 this->aiq_exp_param = *result->exposures[0].exposure;
317 this->sensor_exp_param = *result->exposures[0].sensor_exposure;
318 this->weight_grid = *result->weight_grid;
319 #ifdef HAVE_AIQ_2_7
320 this->flash_param = result->flashes[0];
321 #else
322 this->flash_param = *result->flash;
323 #endif
324
325 this->ae_exp_ret.exposure = &this->aiq_exp_param;
326 this->ae_exp_ret.sensor_exposure = &this->sensor_exp_param;
327 this->ae_result.exposures = &this->ae_exp_ret;
328 this->ae_result.weight_grid = &this->weight_grid;
329 #ifdef HAVE_AIQ_2_7
330 this->ae_result.flashes[0] = this->flash_param;
331 #else
332 this->ae_result.flash = &this->flash_param;
333 #endif
334 this->ae_result.num_exposures = 1;
335 }
336
AiqAeHandler(SmartPtr<AiqCompositor> & aiq_compositor)337 AiqAeHandler::AiqAeHandler (SmartPtr<AiqCompositor> &aiq_compositor)
338 : _aiq_compositor (aiq_compositor)
339 , _started (false)
340 {
341 xcam_mem_clear (_ia_ae_window);
342 xcam_mem_clear (_sensor_descriptor);
343 xcam_mem_clear (_manual_limits);
344 xcam_mem_clear (_input);
345 _input.num_exposures = 1;
346 _input.frame_use = _aiq_compositor->get_frame_use();
347 _input.flash_mode = ia_aiq_flash_mode_off;
348 _input.operation_mode = ia_aiq_ae_operation_mode_automatic;
349 _input.metering_mode = ia_aiq_ae_metering_mode_evaluative;
350 _input.priority_mode = ia_aiq_ae_priority_mode_normal;
351 _input.flicker_reduction_mode = ia_aiq_ae_flicker_reduction_auto;
352 _input.sensor_descriptor = NULL;
353 _input.exposure_window = NULL;
354 _input.exposure_coordinate = NULL;
355 _input.ev_shift = 0.0;
356 _input.manual_exposure_time_us = -1;
357 _input.manual_analog_gain = -1.0;
358 _input.manual_iso = -1.0;
359 _input.aec_features = NULL;
360 _input.manual_limits = &_manual_limits;
361 }
362
363 bool
set_description(struct atomisp_sensor_mode_data * sensor_data)364 AiqAeHandler::set_description (struct atomisp_sensor_mode_data *sensor_data)
365 {
366 XCAM_ASSERT (sensor_data);
367
368 _sensor_descriptor.pixel_clock_freq_mhz = sensor_data->vt_pix_clk_freq_mhz / 1000000.0f;
369 _sensor_descriptor.pixel_periods_per_line = sensor_data->line_length_pck;
370 _sensor_descriptor.line_periods_per_field = sensor_data->frame_length_lines;
371 _sensor_descriptor.line_periods_vertical_blanking = sensor_data->frame_length_lines
372 - (sensor_data->crop_vertical_end - sensor_data->crop_vertical_start + 1)
373 / sensor_data->binning_factor_y;
374 _sensor_descriptor.fine_integration_time_min = sensor_data->fine_integration_time_def;
375 _sensor_descriptor.fine_integration_time_max_margin = sensor_data->line_length_pck - sensor_data->fine_integration_time_def;
376 _sensor_descriptor.coarse_integration_time_min = sensor_data->coarse_integration_time_min;
377 _sensor_descriptor.coarse_integration_time_max_margin = sensor_data->coarse_integration_time_max_margin;
378
379 return true;
380 }
381
382 bool
ensure_ia_parameters()383 AiqAeHandler::ensure_ia_parameters ()
384 {
385 bool ret = true;
386 ret = ret && ensure_ae_mode ();
387 ret = ret && ensure_ae_metering_mode ();
388 ret = ret && ensure_ae_priority_mode ();
389 ret = ret && ensure_ae_flicker_mode ();
390 ret = ret && ensure_ae_manual ();
391 ret = ret && ensure_ae_ev_shift ();
392 _input.sensor_descriptor = &_sensor_descriptor;
393 return ret;
394 }
395
ensure_ae_mode()396 bool AiqAeHandler::ensure_ae_mode ()
397 {
398 XCamAeMode mode = this->get_mode_unlock();
399 switch (mode) {
400 case XCAM_AE_MODE_AUTO:
401 case XCAM_AE_MODE_MANUAL:
402 _input.operation_mode = ia_aiq_ae_operation_mode_automatic;
403 break;
404
405 case XCAM_AE_MODE_NOT_SET:
406 default:
407 XCAM_LOG_ERROR("unsupported ae mode:%d", mode);
408 return false;
409 }
410 return true;
411 }
ensure_ae_metering_mode()412 bool AiqAeHandler::ensure_ae_metering_mode ()
413 {
414 XCamAeMeteringMode mode = this->get_metering_mode_unlock();
415
416 _input.exposure_window = NULL;
417
418 switch (mode) {
419 case XCAM_AE_METERING_MODE_AUTO:
420 _input.metering_mode = ia_aiq_ae_metering_mode_evaluative;
421 break;
422 case XCAM_AE_METERING_MODE_SPOT:
423 {
424 _input.metering_mode = ia_aiq_ae_metering_mode_evaluative;
425 const XCam3AWindow & window = this->get_window_unlock();
426 if (window.x_end > window.x_start &&
427 window.y_end > window.y_start) {
428 _aiq_compositor->convert_window_to_ia(window, _ia_ae_window);
429 _input.exposure_window = &_ia_ae_window;
430 }
431 }
432 break;
433 case XCAM_AE_METERING_MODE_CENTER:
434 _input.metering_mode = ia_aiq_ae_metering_mode_center;
435 break;
436 case XCAM_AE_METERING_MODE_WEIGHTED_WINDOW:
437 {
438 _input.metering_mode = ia_aiq_ae_metering_mode_evaluative;
439 const XCam3AWindow & weighted_window = this->get_window_unlock();
440
441 XCAM_LOG_DEBUG ("ensure_ae_metering_mode weighted_window x_start = %d, y_start = %d, x_end = %d, y_end = %d ",
442 weighted_window.x_start, weighted_window.y_start, weighted_window.x_end, weighted_window.y_end);
443
444 if (weighted_window.x_end > weighted_window.x_start &&
445 weighted_window.y_end > weighted_window.y_start) {
446 _aiq_compositor->convert_window_to_ia(weighted_window, _ia_ae_window);
447 _input.exposure_window = &_ia_ae_window;
448 }
449 }
450 break;
451 default:
452 XCAM_LOG_ERROR("unsupported ae mode:%d", mode);
453 return false;
454 }
455 return true;
456 }
457
ensure_ae_priority_mode()458 bool AiqAeHandler::ensure_ae_priority_mode ()
459 {
460 _input.priority_mode = ia_aiq_ae_priority_mode_normal;
461 return true;
462 }
463
ensure_ae_flicker_mode()464 bool AiqAeHandler::ensure_ae_flicker_mode ()
465 {
466 XCamFlickerMode mode = this->get_flicker_mode_unlock ();
467 switch (mode) {
468 case XCAM_AE_FLICKER_MODE_AUTO:
469 _input.flicker_reduction_mode = ia_aiq_ae_flicker_reduction_auto;
470 break;
471 case XCAM_AE_FLICKER_MODE_50HZ:
472 _input.flicker_reduction_mode = ia_aiq_ae_flicker_reduction_50hz;
473 break;
474 case XCAM_AE_FLICKER_MODE_60HZ:
475 _input.flicker_reduction_mode = ia_aiq_ae_flicker_reduction_60hz;
476 break;
477 case XCAM_AE_FLICKER_MODE_OFF:
478 _input.flicker_reduction_mode = ia_aiq_ae_flicker_reduction_off;
479 break;
480 default:
481 XCAM_LOG_ERROR ("flicker mode(%d) unknown", mode);
482 return false;
483 }
484 return true;
485 }
486
ensure_ae_manual()487 bool AiqAeHandler::ensure_ae_manual ()
488 {
489 if (this->get_mode_unlock () == XCAM_AE_MODE_MANUAL) {
490 _input.manual_exposure_time_us = get_manual_exposure_time_unlock ();
491 _input.manual_analog_gain = get_manual_analog_gain_unlock ();
492 }
493 else {
494 _input.manual_exposure_time_us = -1;
495 _input.manual_analog_gain = -1;
496 }
497
498 _input.manual_limits->manual_exposure_time_min =
499 _sensor_descriptor.coarse_integration_time_min
500 * _sensor_descriptor.pixel_periods_per_line
501 / _sensor_descriptor.pixel_clock_freq_mhz;
502 _input.manual_limits->manual_exposure_time_max =
503 (_sensor_descriptor.line_periods_per_field - _sensor_descriptor.coarse_integration_time_max_margin)
504 * _sensor_descriptor.pixel_periods_per_line
505 / _sensor_descriptor.pixel_clock_freq_mhz;
506
507 uint64_t exp_min_us = 0, exp_max_us = 0;
508 get_exposure_time_range_unlock (exp_min_us, exp_max_us);
509 if (exp_min_us && (int64_t)exp_min_us > _input.manual_limits->manual_exposure_time_min) {
510 _input.manual_limits->manual_exposure_time_min = exp_min_us;
511 }
512 if (exp_max_us && (int64_t)exp_max_us < _input.manual_limits->manual_exposure_time_max) {
513 _input.manual_limits->manual_exposure_time_max = exp_max_us;
514 }
515
516 _input.manual_limits->manual_frame_time_us_min = -1;
517 _input.manual_limits->manual_frame_time_us_max = 1000000 / _aiq_compositor->get_framerate ();
518 _input.manual_limits->manual_iso_min = -1;
519 _input.manual_limits->manual_iso_max = -1;
520
521 return true;
522 }
523
ensure_ae_ev_shift()524 bool AiqAeHandler::ensure_ae_ev_shift ()
525 {
526 _input.ev_shift = this->get_ev_shift_unlock();
527 return true;
528 }
529
530 SmartPtr<X3aResult>
pop_result()531 AiqAeHandler::pop_result ()
532 {
533 //AnalyzerHandler::HandlerLock lock(this);
534
535 X3aIspExposureResult *result = new X3aIspExposureResult(XCAM_IMAGE_PROCESS_ONCE);
536 struct atomisp_exposure sensor;
537 XCam3aResultExposure exposure;
538
539 xcam_mem_clear (sensor);
540 sensor.integration_time[0] = _result.sensor_exp_param.coarse_integration_time;
541 sensor.integration_time[1] = _result.sensor_exp_param.fine_integration_time;
542 sensor.gain[0] = _result.sensor_exp_param.analog_gain_code_global;
543 sensor.gain[1] = _result.sensor_exp_param.digital_gain_global;
544 result->set_isp_config (sensor);
545
546 xcam_mem_clear (exposure);
547 exposure.exposure_time = _result.aiq_exp_param.exposure_time_us;
548 exposure.analog_gain = _result.aiq_exp_param.analog_gain;
549 exposure.digital_gain = _result.aiq_exp_param.digital_gain;
550 exposure.aperture = _result.aiq_exp_param.aperture_fn;
551 result->set_standard_result (exposure);
552
553 return result;
554 }
555
556 XCamReturn
analyze(X3aResultList & output)557 AiqAeHandler::analyze (X3aResultList &output)
558 {
559 ia_aiq *ia_handle = NULL;
560 ia_aiq_ae_results *ae_result = NULL;
561 ia_aiq_exposure_sensor_parameters *cur_sensor_result = NULL;
562 ia_err ia_error = ia_err_none;
563 bool need_apply = false;
564 SmartPtr<X3aResult> result;
565
566 AnalyzerHandler::HandlerLock lock(this);
567
568 if (!ensure_ia_parameters ()) {
569 XCAM_LOG_ERROR ("AIQ AE ensure ia parameters failed");
570 return XCAM_RETURN_ERROR_PARAM;
571 }
572
573 ia_handle = _aiq_compositor->get_handle ();
574 XCAM_ASSERT (ia_handle);
575 ia_error = ia_aiq_ae_run (ia_handle, &_input, &ae_result);
576 XCAM_FAIL_RETURN (ERROR, ia_error == ia_err_none, XCAM_RETURN_ERROR_AIQ, "AIQ run AE failed");
577
578 cur_sensor_result = ae_result->exposures[0].sensor_exposure;
579
580 if (!_started) {
581 _result.copy (ae_result);
582 _started = true;
583 need_apply = true;
584 } else {
585 //TODO
586 ia_aiq_exposure_sensor_parameters *last_sensor_res = &_result.sensor_exp_param;
587 if (last_sensor_res->coarse_integration_time != cur_sensor_result->coarse_integration_time ||
588 last_sensor_res->fine_integration_time != cur_sensor_result->fine_integration_time ||
589 last_sensor_res->analog_gain_code_global != cur_sensor_result->analog_gain_code_global ||
590 last_sensor_res->digital_gain_global != cur_sensor_result->digital_gain_global) {
591 ia_aiq_exposure_sensor_parameters cur_cp_res = *cur_sensor_result;
592 ia_aiq_exposure_parameters cur_aiq_exp = *ae_result->exposures[0].exposure;
593 if (!manual_control_result (cur_cp_res, cur_aiq_exp, *last_sensor_res)) {
594 XCAM_LOG_WARNING ("manual control AE result failed");
595 }
596 _result.copy (ae_result);
597 _result.sensor_exp_param = cur_cp_res;
598 _result.aiq_exp_param = cur_aiq_exp;
599
600 need_apply = true;
601 }
602 }
603
604 if (need_apply) {
605 result = pop_result ();
606 if (result.ptr())
607 output.push_back (result);
608 }
609
610 return XCAM_RETURN_NO_ERROR;
611 }
612
613 bool
manual_control_result(ia_aiq_exposure_sensor_parameters & cur_res,ia_aiq_exposure_parameters & cur_aiq_exp,const ia_aiq_exposure_sensor_parameters & last_res)614 AiqAeHandler::manual_control_result (
615 ia_aiq_exposure_sensor_parameters &cur_res,
616 ia_aiq_exposure_parameters &cur_aiq_exp,
617 const ia_aiq_exposure_sensor_parameters &last_res)
618 {
619 adjust_ae_speed (cur_res, cur_aiq_exp, last_res, this->get_speed_unlock());
620 adjust_ae_limitation (cur_res, cur_aiq_exp);
621
622 return true;
623 }
624
625 void
adjust_ae_speed(ia_aiq_exposure_sensor_parameters & cur_res,ia_aiq_exposure_parameters & cur_aiq_exp,const ia_aiq_exposure_sensor_parameters & last_res,double ae_speed)626 AiqAeHandler::adjust_ae_speed (
627 ia_aiq_exposure_sensor_parameters &cur_res,
628 ia_aiq_exposure_parameters &cur_aiq_exp,
629 const ia_aiq_exposure_sensor_parameters &last_res,
630 double ae_speed)
631 {
632 double last_gain, input_gain, ret_gain;
633 ia_aiq_exposure_sensor_parameters tmp_res;
634
635 if (XCAM_DOUBLE_EQUAL_AROUND(ae_speed, 1.0 ))
636 return;
637 xcam_mem_clear (tmp_res);
638 tmp_res.coarse_integration_time = _calculate_new_value_by_speed (
639 last_res.coarse_integration_time,
640 cur_res.coarse_integration_time,
641 ae_speed);
642
643 last_gain = _imx185_sensor_gain_code_to_mutiplier (last_res.analog_gain_code_global);
644 input_gain = _imx185_sensor_gain_code_to_mutiplier (cur_res.analog_gain_code_global);
645 ret_gain = _calculate_new_value_by_speed (last_gain, input_gain, ae_speed);
646
647 tmp_res.analog_gain_code_global = _mutiplier_to_imx185_sensor_gain_code (ret_gain);
648
649 XCAM_LOG_DEBUG ("AE speed: from (shutter:%d, gain:%d[%.03f]) to (shutter:%d, gain:%d[%.03f])",
650 cur_res.coarse_integration_time, cur_res.analog_gain_code_global, input_gain,
651 tmp_res.coarse_integration_time, tmp_res.analog_gain_code_global, ret_gain);
652
653 cur_res.coarse_integration_time = tmp_res.coarse_integration_time;
654 cur_res.analog_gain_code_global = tmp_res.analog_gain_code_global;
655 cur_aiq_exp.exposure_time_us = _coarse_line_to_time (&_sensor_descriptor,
656 cur_res.coarse_integration_time);
657 cur_aiq_exp.analog_gain = ret_gain;
658 }
659
660 void
adjust_ae_limitation(ia_aiq_exposure_sensor_parameters & cur_res,ia_aiq_exposure_parameters & cur_aiq_exp)661 AiqAeHandler::adjust_ae_limitation (ia_aiq_exposure_sensor_parameters &cur_res,
662 ia_aiq_exposure_parameters &cur_aiq_exp)
663 {
664 ia_aiq_exposure_sensor_descriptor * desc = &_sensor_descriptor;
665 uint64_t exposure_min = 0, exposure_max = 0;
666 double analog_max = get_max_analog_gain_unlock ();
667 uint32_t min_coarse_value = desc->coarse_integration_time_min;
668 uint32_t max_coarse_value = desc->line_periods_per_field - desc->coarse_integration_time_max_margin;
669 uint32_t value;
670
671 get_exposure_time_range_unlock (exposure_min, exposure_max);
672
673 if (exposure_min) {
674 value = _time_to_coarse_line (desc, (uint32_t)exposure_min);
675 min_coarse_value = (value > min_coarse_value) ? value : min_coarse_value;
676 }
677 if (cur_res.coarse_integration_time < min_coarse_value) {
678 cur_res.coarse_integration_time = min_coarse_value;
679 cur_aiq_exp.exposure_time_us = _coarse_line_to_time (desc, min_coarse_value);
680 }
681
682 if (exposure_max) {
683 value = _time_to_coarse_line (desc, (uint32_t)exposure_max);
684 max_coarse_value = (value < max_coarse_value) ? value : max_coarse_value;
685 }
686 if (cur_res.coarse_integration_time > max_coarse_value) {
687 cur_res.coarse_integration_time = max_coarse_value;
688 cur_aiq_exp.exposure_time_us = _coarse_line_to_time (desc, max_coarse_value);
689 }
690
691 if (analog_max >= 1.0) {
692 /* limit gains */
693 double gain = _imx185_sensor_gain_code_to_mutiplier (cur_res.analog_gain_code_global);
694 if (gain > analog_max) {
695 cur_res.analog_gain_code_global = _mutiplier_to_imx185_sensor_gain_code (analog_max);
696 cur_aiq_exp.analog_gain = analog_max;
697 }
698 }
699 }
700
701 XCamFlickerMode
get_flicker_mode()702 AiqAeHandler::get_flicker_mode ()
703 {
704 {
705 AnalyzerHandler::HandlerLock lock(this);
706 }
707 return AeHandler::get_flicker_mode ();
708 }
709
710 int64_t
get_current_exposure_time()711 AiqAeHandler::get_current_exposure_time ()
712 {
713 AnalyzerHandler::HandlerLock lock(this);
714
715 return (int64_t)_result.aiq_exp_param.exposure_time_us;
716 }
717
718 double
get_current_analog_gain()719 AiqAeHandler::get_current_analog_gain ()
720 {
721 AnalyzerHandler::HandlerLock lock(this);
722 return (double)_result.aiq_exp_param.analog_gain;
723 }
724
725 double
get_max_analog_gain()726 AiqAeHandler::get_max_analog_gain ()
727 {
728 {
729 AnalyzerHandler::HandlerLock lock(this);
730 }
731 return AeHandler::get_max_analog_gain ();
732 }
733
734 XCamReturn
set_RGBS_weight_grid(ia_aiq_rgbs_grid ** out_rgbs_grid)735 AiqAeHandler::set_RGBS_weight_grid (ia_aiq_rgbs_grid **out_rgbs_grid)
736 {
737 AnalyzerHandler::HandlerLock lock(this);
738
739 rgbs_grid_block *rgbs_grid_ptr = (*out_rgbs_grid)->blocks_ptr;
740 uint32_t rgbs_grid_index = 0;
741 uint16_t rgbs_grid_width = (*out_rgbs_grid)->grid_width;
742 uint16_t rgbs_grid_height = (*out_rgbs_grid)->grid_height;
743
744 XCAM_LOG_DEBUG ("rgbs_grid_width = %d, rgbs_grid_height = %d", rgbs_grid_width, rgbs_grid_height);
745
746 uint64_t weight_sum = 0;
747
748 uint32_t image_width = 0;
749 uint32_t image_height = 0;
750 _aiq_compositor->get_size (image_width, image_height);
751 XCAM_LOG_DEBUG ("image_width = %d, image_height = %d", image_width, image_height);
752
753 uint32_t hor_pixels_per_grid = (image_width + (rgbs_grid_width >> 1)) / rgbs_grid_width;
754 uint32_t vert_pixels_per_gird = (image_height + (rgbs_grid_height >> 1)) / rgbs_grid_height;
755 XCAM_LOG_DEBUG ("rgbs grid: %d x %d pixels per grid cell", hor_pixels_per_grid, vert_pixels_per_gird);
756
757 XCam3AWindow weighted_window = this->get_window_unlock ();
758 uint32_t weighted_grid_width = ((weighted_window.x_end - weighted_window.x_start + 1) +
759 (hor_pixels_per_grid >> 1)) / hor_pixels_per_grid;
760 uint32_t weighted_grid_height = ((weighted_window.y_end - weighted_window.y_start + 1) +
761 (vert_pixels_per_gird >> 1)) / vert_pixels_per_gird;
762 XCAM_LOG_DEBUG ("weighted_grid_width = %d, weighted_grid_height = %d", weighted_grid_width, weighted_grid_height);
763
764 uint32_t *weighted_avg_gr = (uint32_t*)xcam_malloc0 (5 * weighted_grid_width * weighted_grid_height * sizeof(uint32_t));
765 if (NULL == weighted_avg_gr) {
766 return XCAM_RETURN_ERROR_MEM;
767 }
768 uint32_t *weighted_avg_r = weighted_avg_gr + (weighted_grid_width * weighted_grid_height);
769 uint32_t *weighted_avg_b = weighted_avg_r + (weighted_grid_width * weighted_grid_height);
770 uint32_t *weighted_avg_gb = weighted_avg_b + (weighted_grid_width * weighted_grid_height);
771 uint32_t *weighted_sat = weighted_avg_gb + (weighted_grid_width * weighted_grid_height);
772
773 for (uint32_t win_index = 0; win_index < XCAM_AE_MAX_METERING_WINDOW_COUNT; win_index++) {
774 XCAM_LOG_DEBUG ("window start point(%d, %d), end point(%d, %d), weight = %d",
775 _params.window_list[win_index].x_start, _params.window_list[win_index].y_start,
776 _params.window_list[win_index].x_end, _params.window_list[win_index].y_end,
777 _params.window_list[win_index].weight);
778
779 if ((_params.window_list[win_index].weight <= 0) ||
780 (_params.window_list[win_index].x_start < 0) ||
781 ((uint32_t)_params.window_list[win_index].x_end > image_width) ||
782 (_params.window_list[win_index].y_start < 0) ||
783 ((uint32_t)_params.window_list[win_index].y_end > image_height) ||
784 (_params.window_list[win_index].x_start >= _params.window_list[win_index].x_end) ||
785 (_params.window_list[win_index].y_start >= _params.window_list[win_index].y_end) ||
786 ((uint32_t)_params.window_list[win_index].x_end - (uint32_t)_params.window_list[win_index].x_start > image_width) ||
787 ((uint32_t)_params.window_list[win_index].y_end - (uint32_t)_params.window_list[win_index].y_start > image_height)) {
788 XCAM_LOG_DEBUG ("skip window index = %d ", win_index);
789 continue;
790 }
791
792 rgbs_grid_index = (_params.window_list[win_index].x_start +
793 (hor_pixels_per_grid >> 1)) / hor_pixels_per_grid +
794 ((_params.window_list[win_index].y_start + (vert_pixels_per_gird >> 1))
795 / vert_pixels_per_gird) * rgbs_grid_width;
796
797 weight_sum += _params.window_list[win_index].weight;
798
799 XCAM_LOG_DEBUG ("cumulate rgbs grid statistic, window index = %d ", win_index);
800 for (uint32_t i = 0; i < weighted_grid_height; i++) {
801 for (uint32_t j = 0; j < weighted_grid_width; j++) {
802 weighted_avg_gr[j + i * weighted_grid_width] += rgbs_grid_ptr[rgbs_grid_index + j +
803 i * rgbs_grid_width].avg_gr * _params.window_list[win_index].weight;
804 weighted_avg_r[j + i * weighted_grid_width] += rgbs_grid_ptr[rgbs_grid_index + j +
805 i * rgbs_grid_width].avg_r * _params.window_list[win_index].weight;
806 weighted_avg_b[j + i * weighted_grid_width] += rgbs_grid_ptr[rgbs_grid_index + j +
807 i * rgbs_grid_width].avg_b * _params.window_list[win_index].weight;
808 weighted_avg_gb[j + i * weighted_grid_width] += rgbs_grid_ptr[rgbs_grid_index + j +
809 i * rgbs_grid_width].avg_gb * _params.window_list[win_index].weight;
810 weighted_sat[j + i * weighted_grid_width] += rgbs_grid_ptr[rgbs_grid_index + j +
811 i * rgbs_grid_width].sat * _params.window_list[win_index].weight;
812 }
813 }
814 }
815 XCAM_LOG_DEBUG ("sum of weighing factor = %" PRIu64, weight_sum);
816
817 rgbs_grid_index = (weighted_window.x_start + (hor_pixels_per_grid >> 1)) / hor_pixels_per_grid +
818 (weighted_window.y_start + (vert_pixels_per_gird >> 1)) / vert_pixels_per_gird * rgbs_grid_width;
819 for (uint32_t i = 0; i < weighted_grid_height; i++) {
820 for (uint32_t j = 0; j < weighted_grid_width; j++) {
821 rgbs_grid_ptr[rgbs_grid_index + j + i * rgbs_grid_width].avg_gr =
822 weighted_avg_gr[j + i * weighted_grid_width] / weight_sum;
823 rgbs_grid_ptr[rgbs_grid_index + j + i * rgbs_grid_width].avg_r =
824 weighted_avg_r[j + i * weighted_grid_width] / weight_sum;
825 rgbs_grid_ptr[rgbs_grid_index + j + i * rgbs_grid_width].avg_b =
826 weighted_avg_b[j + i * weighted_grid_width] / weight_sum;
827 rgbs_grid_ptr[rgbs_grid_index + j + i * rgbs_grid_width].avg_gb =
828 weighted_avg_gb[j + i * weighted_grid_width] / weight_sum;
829 rgbs_grid_ptr[rgbs_grid_index + j + i * rgbs_grid_width].sat =
830 weighted_sat[j + i * weighted_grid_width] / weight_sum;
831 }
832 }
833
834 xcam_free (weighted_avg_gr);
835
836 return XCAM_RETURN_NO_ERROR;
837 }
838
839
840 XCamReturn
set_hist_weight_grid(ia_aiq_hist_weight_grid ** out_weight_grid)841 AiqAeHandler::set_hist_weight_grid (ia_aiq_hist_weight_grid **out_weight_grid)
842 {
843 AnalyzerHandler::HandlerLock lock(this);
844
845 uint16_t hist_grid_width = (*out_weight_grid)->width;
846 uint16_t hist_grid_height = (*out_weight_grid)->height;
847 uint32_t hist_grid_index = 0;
848
849 unsigned char* weights_map_ptr = (*out_weight_grid)->weights;
850
851 uint32_t image_width = 0;
852 uint32_t image_height = 0;
853 _aiq_compositor->get_size (image_width, image_height);
854
855 uint32_t hor_pixels_per_grid = (image_width + (hist_grid_width >> 1)) / hist_grid_width;
856 uint32_t vert_pixels_per_gird = (image_height + (hist_grid_height >> 1)) / hist_grid_height;
857 XCAM_LOG_DEBUG ("hist weight grid: %d x %d pixels per grid cell", hor_pixels_per_grid, vert_pixels_per_gird);
858
859 memset (weights_map_ptr, 0, hist_grid_width * hist_grid_height);
860
861 for (uint32_t win_index = 0; win_index < XCAM_AE_MAX_METERING_WINDOW_COUNT; win_index++) {
862 XCAM_LOG_DEBUG ("window start point(%d, %d), end point(%d, %d), weight = %d",
863 _params.window_list[win_index].x_start, _params.window_list[win_index].y_start,
864 _params.window_list[win_index].x_end, _params.window_list[win_index].y_end,
865 _params.window_list[win_index].weight);
866
867 if ((_params.window_list[win_index].weight <= 0) ||
868 (_params.window_list[win_index].weight > 15) ||
869 (_params.window_list[win_index].x_start < 0) ||
870 ((uint32_t)_params.window_list[win_index].x_end > image_width) ||
871 (_params.window_list[win_index].y_start < 0) ||
872 ((uint32_t)_params.window_list[win_index].y_end > image_height) ||
873 (_params.window_list[win_index].x_start >= _params.window_list[win_index].x_end) ||
874 (_params.window_list[win_index].y_start >= _params.window_list[win_index].y_end) ||
875 ((uint32_t)_params.window_list[win_index].x_end - (uint32_t)_params.window_list[win_index].x_start > image_width) ||
876 ((uint32_t)_params.window_list[win_index].y_end - (uint32_t)_params.window_list[win_index].y_start > image_height)) {
877 XCAM_LOG_DEBUG ("skip window index = %d ", win_index);
878 continue;
879 }
880
881 uint32_t weighted_grid_width =
882 ((_params.window_list[win_index].x_end - _params.window_list[win_index].x_start + 1) +
883 (hor_pixels_per_grid >> 1)) / hor_pixels_per_grid;
884 uint32_t weighted_grid_height =
885 ((_params.window_list[win_index].y_end - _params.window_list[win_index].y_start + 1) +
886 (vert_pixels_per_gird >> 1)) / vert_pixels_per_gird;
887
888 hist_grid_index = (_params.window_list[win_index].x_start + (hor_pixels_per_grid >> 1)) / hor_pixels_per_grid +
889 ((_params.window_list[win_index].y_start + (vert_pixels_per_gird >> 1)) /
890 vert_pixels_per_gird) * hist_grid_width;
891
892 for (uint32_t i = 0; i < weighted_grid_height; i++) {
893 for (uint32_t j = 0; j < weighted_grid_width; j++) {
894 weights_map_ptr[hist_grid_index + j + i * hist_grid_width] = _params.window_list[win_index].weight;
895 }
896 }
897 }
898 return XCAM_RETURN_NO_ERROR;
899 }
900
901 XCamReturn
dump_hist_weight_grid(const ia_aiq_hist_weight_grid * weight_grid)902 AiqAeHandler::dump_hist_weight_grid (const ia_aiq_hist_weight_grid *weight_grid)
903 {
904 XCAM_LOG_DEBUG ("E dump_hist_weight_grid");
905 if (NULL == weight_grid) {
906 return XCAM_RETURN_ERROR_PARAM;
907 }
908
909 uint16_t grid_width = weight_grid->width;
910 uint16_t grid_height = weight_grid->height;
911
912 for (uint32_t i = 0; i < grid_height; i++) {
913 for (uint32_t j = 0; j < grid_width; j++) {
914 printf ("%d ", weight_grid->weights[j + i * grid_width]);
915 }
916 printf("\n");
917 }
918
919 XCAM_LOG_DEBUG ("X dump_hist_weight_grid");
920 return XCAM_RETURN_NO_ERROR;
921 }
922
923 XCamReturn
dump_RGBS_grid(const ia_aiq_rgbs_grid * rgbs_grid)924 AiqAeHandler::dump_RGBS_grid (const ia_aiq_rgbs_grid *rgbs_grid)
925 {
926 XCAM_LOG_DEBUG ("E dump_RGBS_grid");
927 if (NULL == rgbs_grid) {
928 return XCAM_RETURN_ERROR_PARAM;
929 }
930
931 uint16_t grid_width = rgbs_grid->grid_width;
932 uint16_t grid_height = rgbs_grid->grid_height;
933
934 printf("AVG B\n");
935 for (uint32_t i = 0; i < grid_height; i++) {
936 for (uint32_t j = 0; j < grid_width; j++) {
937 printf ("%d ", rgbs_grid->blocks_ptr[j + i * grid_width].avg_b);
938 }
939 printf("\n");
940 }
941 printf("AVG Gb\n");
942 for (uint32_t i = 0; i < grid_height; i++) {
943 for (uint32_t j = 0; j < grid_width; j++) {
944 printf ("%d ", rgbs_grid->blocks_ptr[j + i * grid_width].avg_gb);
945 }
946 printf("\n");
947 }
948 printf("AVG Gr\n");
949 for (uint32_t i = 0; i < grid_height; i++) {
950 for (uint32_t j = 0; j < grid_width; j++) {
951 printf ("%d ", rgbs_grid->blocks_ptr[j + i * grid_width].avg_gr);
952 }
953 printf("\n");
954 }
955 printf("AVG R\n");
956 for (uint32_t i = 0; i < grid_height; i++) {
957 for (uint32_t j = 0; j < grid_width; j++) {
958 printf ("%d ", rgbs_grid->blocks_ptr[j + i * grid_width].avg_r);
959 //printf ("%d ", rgbs_grid->blocks_ptr[j + i * grid_width].sat);
960 }
961 printf("\n");
962 }
963
964 XCAM_LOG_DEBUG ("X dump_RGBS_grid");
965 return XCAM_RETURN_NO_ERROR;
966 }
967
AiqAwbHandler(SmartPtr<AiqCompositor> & aiq_compositor)968 AiqAwbHandler::AiqAwbHandler (SmartPtr<AiqCompositor> &aiq_compositor)
969 : _aiq_compositor (aiq_compositor)
970 , _started (false)
971 {
972 xcam_mem_clear (_cct_range);
973 xcam_mem_clear (_result);
974 xcam_mem_clear (_history_result);
975 xcam_mem_clear (_cct_range);
976 xcam_mem_clear (_input);
977
978 _input.frame_use = aiq_compositor->get_frame_use ();
979 _input.scene_mode = ia_aiq_awb_operation_mode_auto;
980 _input.manual_cct_range = NULL;
981 _input.manual_white_coordinate = NULL;
982 }
983
984 XCamReturn
analyze(X3aResultList & output)985 AiqAwbHandler::analyze (X3aResultList &output)
986 {
987 ia_aiq *ia_handle = NULL;
988 ia_aiq_awb_results *awb_ret = NULL;
989 ia_err ia_error = ia_err_none;
990
991 XCAM_UNUSED (output);
992
993 AnalyzerHandler::HandlerLock lock(this);
994
995 if (!ensure_ia_parameters ()) {
996 XCAM_LOG_ERROR ("AIQ AE ensure ia parameters failed");
997 return XCAM_RETURN_ERROR_PARAM;
998 }
999
1000 ia_handle = _aiq_compositor->get_handle ();
1001 XCAM_ASSERT (ia_handle);
1002 ia_error = ia_aiq_awb_run (ia_handle, &_input, &awb_ret);
1003 XCAM_FAIL_RETURN (ERROR, ia_error == ia_err_none, XCAM_RETURN_ERROR_AIQ, "AIQ run AWB failed");
1004
1005 _result = *awb_ret;
1006 if (!_started) {
1007 _history_result = _result;
1008 _started = true;
1009 }
1010 adjust_speed (_history_result);
1011 _history_result = _result;
1012
1013 return XCAM_RETURN_NO_ERROR;
1014 }
1015
1016 bool
ensure_ia_parameters()1017 AiqAwbHandler::ensure_ia_parameters ()
1018 {
1019 bool ret = true;
1020
1021 _input.frame_use = _aiq_compositor->get_frame_use ();
1022 ret = ret && ensure_awb_mode ();
1023 return ret;
1024 }
1025
1026 bool
ensure_awb_mode()1027 AiqAwbHandler::ensure_awb_mode ()
1028 {
1029 XCamAwbMode mode = get_mode_unlock();
1030
1031 _input.manual_cct_range = NULL;
1032 _input.scene_mode = ia_aiq_awb_operation_mode_auto;
1033
1034 switch (mode) {
1035 case XCAM_AWB_MODE_AUTO:
1036 _input.scene_mode = ia_aiq_awb_operation_mode_auto;
1037 break;
1038 case XCAM_AWB_MODE_MANUAL: {
1039 uint32_t cct_min = 0, cct_max = 0;
1040 get_cct_range_unlock (cct_min, cct_max);
1041 if (cct_min && cct_max) {
1042 _input.scene_mode = ia_aiq_awb_operation_mode_manual_cct_range;
1043 _cct_range.max_cct = cct_min;
1044 _cct_range.min_cct = cct_max;
1045 _input.manual_cct_range = &_cct_range;
1046 } else
1047 _input.scene_mode = ia_aiq_awb_operation_mode_auto;
1048 break;
1049 }
1050 case XCAM_AWB_MODE_DAYLIGHT:
1051 _input.scene_mode = ia_aiq_awb_operation_mode_daylight;
1052 break;
1053 case XCAM_AWB_MODE_SUNSET:
1054 _input.scene_mode = ia_aiq_awb_operation_mode_sunset;
1055 break;
1056 case XCAM_AWB_MODE_CLOUDY:
1057 _input.scene_mode = ia_aiq_awb_operation_mode_partly_overcast;
1058 break;
1059 case XCAM_AWB_MODE_TUNGSTEN:
1060 _input.scene_mode = ia_aiq_awb_operation_mode_incandescent;
1061 break;
1062 case XCAM_AWB_MODE_FLUORESCENT:
1063 _input.scene_mode = ia_aiq_awb_operation_mode_fluorescent;
1064 break;
1065 case XCAM_AWB_MODE_WARM_FLUORESCENT:
1066 _input.scene_mode = ia_aiq_awb_operation_mode_incandescent;
1067 break;
1068 case XCAM_AWB_MODE_SHADOW:
1069 _input.scene_mode = ia_aiq_awb_operation_mode_fully_overcast;
1070 break;
1071 case XCAM_AWB_MODE_WARM_INCANDESCENT:
1072 _input.scene_mode = ia_aiq_awb_operation_mode_incandescent;
1073 break;
1074 case XCAM_AWB_MODE_NOT_SET:
1075 break;
1076
1077 default:
1078 XCAM_LOG_ERROR ("unknown or unsupported AWB mode(%d)", mode);
1079 return false;
1080 }
1081 return true;
1082 }
1083
1084 void
adjust_speed(const ia_aiq_awb_results & last_ret)1085 AiqAwbHandler::adjust_speed (const ia_aiq_awb_results &last_ret)
1086 {
1087 _result.final_r_per_g =
1088 _calculate_new_value_by_speed (
1089 last_ret.final_r_per_g, _result.final_r_per_g, get_speed_unlock ());
1090 _result.final_b_per_g =
1091 _calculate_new_value_by_speed (
1092 last_ret.final_b_per_g, _result.final_b_per_g, get_speed_unlock ());
1093 }
1094
1095 uint32_t
get_current_estimate_cct()1096 AiqAwbHandler::get_current_estimate_cct ()
1097 {
1098 AnalyzerHandler::HandlerLock lock(this);
1099 return (uint32_t)_result.cct_estimate;
1100 }
1101
1102 XCamReturn
analyze(X3aResultList & output)1103 AiqAfHandler::analyze (X3aResultList &output)
1104 {
1105 // TODO
1106 XCAM_UNUSED (output);
1107 return XCAM_RETURN_NO_ERROR;
1108 }
1109
AiqCommonHandler(SmartPtr<AiqCompositor> & aiq_compositor)1110 AiqCommonHandler::AiqCommonHandler (SmartPtr<AiqCompositor> &aiq_compositor)
1111 : _aiq_compositor (aiq_compositor)
1112 , _gbce_result (NULL)
1113 {
1114 }
1115
1116
1117 XCamReturn
analyze(X3aResultList & output)1118 AiqCommonHandler::analyze (X3aResultList &output)
1119 {
1120 ia_aiq *ia_handle = NULL;
1121 ia_aiq_gbce_results *gbce_result = NULL;
1122 ia_err ia_error = ia_err_none;
1123
1124 XCAM_UNUSED (output);
1125
1126 AnalyzerHandler::HandlerLock lock(this);
1127
1128 ia_aiq_gbce_input_params gbce_input;
1129 xcam_mem_clear (gbce_input);
1130 if (has_gbce_unlock()) {
1131 gbce_input.gbce_level = ia_aiq_gbce_level_use_tuning;
1132 }
1133 else {
1134 gbce_input.gbce_level = ia_aiq_gbce_level_bypass;
1135 }
1136 gbce_input.frame_use = _aiq_compositor->get_frame_use ();
1137 gbce_input.ev_shift = _aiq_compositor->get_ae_ev_shift_unlock ();
1138 ia_handle = _aiq_compositor->get_handle ();
1139 XCAM_ASSERT (ia_handle);
1140 ia_error = ia_aiq_gbce_run (ia_handle, &gbce_input, &gbce_result);
1141
1142 XCAM_FAIL_RETURN (ERROR, ia_error == ia_err_none, XCAM_RETURN_ERROR_AIQ, "AIQ run GBCE failed");
1143
1144 //TODO, need copy GBCE result out, not just assign
1145 _gbce_result = gbce_result;
1146
1147 return XCAM_RETURN_NO_ERROR;
1148 }
1149
1150 class CmcParser {
1151 public:
CmcParser(ia_binary_data & cpf)1152 explicit CmcParser (ia_binary_data &cpf)
1153 {
1154 _cmc = ia_cmc_parser_init (&cpf);
1155 }
~CmcParser()1156 ~CmcParser ()
1157 {
1158 if (_cmc)
1159 ia_cmc_parser_deinit (_cmc);
1160 }
get()1161 ia_cmc_t *get() {
1162 return _cmc;
1163 }
1164
1165 private:
1166 ia_cmc_t *_cmc;
1167 };
1168
1169 void
convert_window_to_ia(const XCam3AWindow & window,ia_rectangle & ia_window)1170 AiqCompositor::convert_window_to_ia (const XCam3AWindow &window, ia_rectangle &ia_window)
1171 {
1172 ia_rectangle source;
1173 ia_coordinate_system source_system;
1174 ia_coordinate_system target_system = {IA_COORDINATE_TOP, IA_COORDINATE_LEFT, IA_COORDINATE_BOTTOM, IA_COORDINATE_RIGHT};
1175
1176 source_system.left = 0;
1177 source_system.top = 0;
1178 source_system.right = this->_width;
1179 source_system.bottom = this->_height;
1180 XCAM_ASSERT (_width && _height);
1181
1182 source.left = window.x_start;
1183 source.top = window.y_start;
1184 source.right = window.x_end;
1185 source.bottom = window.y_end;
1186 ia_coordinate_convert_rect (&source_system, &source, &target_system, &ia_window);
1187 }
1188
AiqCompositor()1189 AiqCompositor::AiqCompositor ()
1190 : _ia_handle (NULL)
1191 , _ia_mkn (NULL)
1192 , _pa_result (NULL)
1193 #ifdef HAVE_AIQ_2_7
1194 , _sa_result (NULL)
1195 #endif
1196 , _frame_use (ia_aiq_frame_use_video)
1197 , _width (0)
1198 , _height (0)
1199 {
1200 xcam_mem_clear (_frame_params);
1201 }
1202
~AiqCompositor()1203 AiqCompositor::~AiqCompositor ()
1204 {
1205 }
1206
1207 bool
open(ia_binary_data & cpf)1208 AiqCompositor::open (ia_binary_data &cpf)
1209 {
1210 CmcParser cmc (cpf);
1211
1212 _ia_mkn = ia_mkn_init (ia_mkn_cfg_compression, 32000, 100000);
1213 _ia_handle =
1214 ia_aiq_init (
1215 &cpf, NULL, NULL,
1216 MAX_STATISTICS_WIDTH, MAX_STATISTICS_HEIGHT,
1217 1, //max_num_stats_in
1218 cmc.get(),
1219 _ia_mkn);
1220
1221 if (_ia_handle == NULL) {
1222 XCAM_LOG_WARNING ("AIQ init failed");
1223 return false;
1224 }
1225
1226 _adaptor = new IaIspAdaptor22;
1227 XCAM_ASSERT (_adaptor.ptr());
1228 if (!_adaptor->init (&cpf, MAX_STATISTICS_WIDTH, MAX_STATISTICS_HEIGHT, cmc.get(), _ia_mkn)) {
1229 XCAM_LOG_WARNING ("AIQ isp adaptor init failed");
1230 return false;
1231 }
1232
1233 _pa_result = NULL;
1234 #ifdef HAVE_AIQ_2_7
1235 _sa_result = NULL;
1236 #endif
1237
1238 XCAM_LOG_DEBUG ("Aiq compositor opened");
1239 return true;
1240 }
1241
1242 void
close()1243 AiqCompositor::close ()
1244 {
1245 _adaptor.release ();
1246 if (_ia_handle) {
1247 ia_aiq_deinit (_ia_handle);
1248 _ia_handle = NULL;
1249 }
1250
1251 if (_ia_mkn) {
1252 ia_mkn_uninit (_ia_mkn);
1253 _ia_mkn = NULL;
1254 }
1255
1256 _ae_handler.release ();
1257 _awb_handler.release ();
1258 _af_handler.release ();
1259 _common_handler.release ();
1260
1261 _pa_result = NULL;
1262 #ifdef HAVE_AIQ_2_7
1263 _sa_result = NULL;
1264 #endif
1265
1266 XCAM_LOG_DEBUG ("Aiq compositor closed");
1267 }
1268
1269 bool
set_sensor_mode_data(struct atomisp_sensor_mode_data * sensor_mode)1270 AiqCompositor::set_sensor_mode_data (struct atomisp_sensor_mode_data *sensor_mode)
1271 {
1272 _frame_params.horizontal_crop_offset = sensor_mode->crop_horizontal_start;
1273 _frame_params.vertical_crop_offset = sensor_mode->crop_vertical_start;
1274 _frame_params.cropped_image_height = sensor_mode->crop_vertical_end - sensor_mode->crop_vertical_start + 1;
1275 _frame_params.cropped_image_width = sensor_mode->crop_horizontal_end - sensor_mode->crop_horizontal_start + 1;
1276
1277 /* hard code to 254? */
1278 _frame_params.horizontal_scaling_denominator = 254;
1279 _frame_params.vertical_scaling_denominator = 254;
1280
1281 if ((_frame_params.cropped_image_width == 0) || (_frame_params.cropped_image_height == 0)) {
1282 _frame_params.horizontal_scaling_numerator = 0;
1283 _frame_params.vertical_scaling_numerator = 0;
1284 } else {
1285 _frame_params.horizontal_scaling_numerator =
1286 sensor_mode->output_width * 254 * sensor_mode->binning_factor_x / _frame_params.cropped_image_width;
1287 _frame_params.vertical_scaling_numerator =
1288 sensor_mode->output_height * 254 * sensor_mode->binning_factor_y / _frame_params.cropped_image_height;
1289 }
1290
1291 if (!_ae_handler->set_description (sensor_mode)) {
1292 XCAM_LOG_WARNING ("AIQ set ae description failed");
1293 return XCAM_RETURN_ERROR_AIQ;
1294 }
1295 return true;
1296 }
1297
1298 bool
set_3a_stats(SmartPtr<X3aIspStatistics> & stats)1299 AiqCompositor::set_3a_stats (SmartPtr<X3aIspStatistics> &stats)
1300 {
1301 ia_aiq_statistics_input_params aiq_stats_input;
1302 ia_aiq_rgbs_grid *rgbs_grids = NULL;
1303 ia_aiq_af_grid *af_grids = NULL;
1304
1305 xcam_mem_clear (aiq_stats_input);
1306 aiq_stats_input.frame_timestamp = stats->get_timestamp();
1307 aiq_stats_input.frame_id = stats->get_timestamp() + 1;
1308 aiq_stats_input.rgbs_grids = (const ia_aiq_rgbs_grid **)&rgbs_grids;
1309 aiq_stats_input.num_rgbs_grids = 1;
1310 aiq_stats_input.af_grids = (const ia_aiq_af_grid **)(&af_grids);
1311 aiq_stats_input.num_af_grids = 1;
1312
1313 aiq_stats_input.frame_af_parameters = NULL;
1314 aiq_stats_input.external_histograms = NULL;
1315 aiq_stats_input.num_external_histograms = 0;
1316 aiq_stats_input.camera_orientation = ia_aiq_camera_orientation_unknown;
1317
1318 if (_pa_result)
1319 aiq_stats_input.frame_pa_parameters = _pa_result;
1320
1321 #ifdef HAVE_AIQ_2_7
1322 if (_sa_result)
1323 aiq_stats_input.frame_sa_parameters = _sa_result;
1324 #endif
1325
1326 if (_ae_handler->is_started()) {
1327 #ifdef USE_HIST_GRID_WEIGHTING
1328 if (XCAM_AE_METERING_MODE_WEIGHTED_WINDOW == _ae_handler->get_metering_mode ()) {
1329 ia_aiq_ae_results* ae_result = _ae_handler->get_result ();
1330
1331 if (XCAM_RETURN_NO_ERROR != _ae_handler->set_hist_weight_grid (&(ae_result->weight_grid))) {
1332 XCAM_LOG_ERROR ("ae handler set hist weight grid failed");
1333 }
1334 }
1335 #endif
1336 aiq_stats_input.frame_ae_parameters = _ae_handler->get_result ();
1337 //_ae_handler->dump_hist_weight_grid (aiq_stats_input.frame_ae_parameters->weight_grid);
1338 }
1339 //if (_awb_handler->is_started())
1340 // aiq_stats_input.frame_awb_parameters = _awb_handler->get_result();
1341
1342 if (!_adaptor->convert_statistics (stats->get_isp_stats(), &rgbs_grids, &af_grids)) {
1343 XCAM_LOG_WARNING ("ia isp adaptor convert 3a stats failed");
1344 return false;
1345 }
1346
1347 if (XCAM_AE_METERING_MODE_WEIGHTED_WINDOW == _ae_handler->get_metering_mode ()) {
1348 #ifdef USE_RGBS_GRID_WEIGHTING
1349 if (XCAM_RETURN_NO_ERROR != _ae_handler->set_RGBS_weight_grid(&rgbs_grids)) {
1350 XCAM_LOG_ERROR ("ae handler update RGBS weighted statistic failed");
1351 }
1352 //_ae_handler->dump_RGBS_grid (*(aiq_stats_input.rgbs_grids));
1353 #endif
1354 }
1355 XCAM_LOG_DEBUG ("statistics grid info, width:%u, height:%u, blk_r:%u, blk_b:%u, blk_gr:%u, blk_gb:%u",
1356 aiq_stats_input.rgbs_grids[0]->grid_width,
1357 aiq_stats_input.rgbs_grids[0]->grid_height,
1358 aiq_stats_input.rgbs_grids[0]->blocks_ptr->avg_r,
1359 aiq_stats_input.rgbs_grids[0]->blocks_ptr->avg_b,
1360 aiq_stats_input.rgbs_grids[0]->blocks_ptr->avg_gr,
1361 aiq_stats_input.rgbs_grids[0]->blocks_ptr->avg_gb);
1362
1363 if (ia_aiq_statistics_set(get_handle (), &aiq_stats_input) != ia_err_none) {
1364 XCAM_LOG_ERROR ("Aiq set statistic failed");
1365 return false;
1366 }
1367 return true;
1368 }
1369
convert_color_effect(IspInputParameters & isp_input)1370 XCamReturn AiqCompositor::convert_color_effect (IspInputParameters &isp_input)
1371 {
1372 AiqCommonHandler *aiq_common = _common_handler.ptr();
1373
1374 switch (aiq_common->get_color_effect()) {
1375 case XCAM_COLOR_EFFECT_NONE:
1376 isp_input.effects = ia_isp_effect_none;
1377 break;
1378 case XCAM_COLOR_EFFECT_SKY_BLUE:
1379 isp_input.effects = ia_isp_effect_sky_blue;
1380 break;
1381 case XCAM_COLOR_EFFECT_SKIN_WHITEN_LOW:
1382 isp_input.effects = ia_isp_effect_skin_whiten_low;
1383 break;
1384 case XCAM_COLOR_EFFECT_SKIN_WHITEN:
1385 isp_input.effects = ia_isp_effect_skin_whiten;
1386 break;
1387 case XCAM_COLOR_EFFECT_SKIN_WHITEN_HIGH:
1388 isp_input.effects = ia_isp_effect_skin_whiten_high;
1389 break;
1390 case XCAM_COLOR_EFFECT_SEPIA:
1391 isp_input.effects = ia_isp_effect_sepia;
1392 break;
1393 case XCAM_COLOR_EFFECT_NEGATIVE:
1394 isp_input.effects = ia_isp_effect_negative;
1395 break;
1396 case XCAM_COLOR_EFFECT_GRAYSCALE:
1397 isp_input.effects = ia_isp_effect_grayscale;
1398 break;
1399 default:
1400 isp_input.effects = ia_isp_effect_none;
1401 break;
1402 }
1403
1404 return XCAM_RETURN_NO_ERROR;
1405 }
1406
1407 XCamReturn
apply_gamma_table(struct atomisp_parameters * isp_param)1408 AiqCompositor::apply_gamma_table (struct atomisp_parameters *isp_param)
1409 {
1410 if (_common_handler->_params.is_manual_gamma) {
1411 int i;
1412
1413 if (isp_param->r_gamma_table) {
1414 isp_param->r_gamma_table->vamem_type = 1; //IA_CSS_VAMEM_TYPE_2 = 1;
1415 for (i = 0; i < XCAM_GAMMA_TABLE_SIZE; ++i) {
1416 // change from double to u0.12
1417 isp_param->r_gamma_table->data.vamem_2[i] =
1418 (uint32_t) (_common_handler->_params.r_gamma[i] * 4096.0);
1419 }
1420 isp_param->r_gamma_table->data.vamem_2[256] = 4091;
1421 }
1422
1423 if (isp_param->g_gamma_table) {
1424 isp_param->g_gamma_table->vamem_type = 1; //IA_CSS_VAMEM_TYPE_2 = 1;
1425 for (i = 0; i < XCAM_GAMMA_TABLE_SIZE; ++i) {
1426 // change from double to u0.12
1427 isp_param->g_gamma_table->data.vamem_2[i] =
1428 (uint32_t) (_common_handler->_params.g_gamma[i] * 4096.0);
1429 }
1430 isp_param->g_gamma_table->data.vamem_2[256] = 4091;
1431 }
1432
1433 if (isp_param->b_gamma_table) {
1434 isp_param->b_gamma_table->vamem_type = 1; //IA_CSS_VAMEM_TYPE_2 = 1;
1435 for (i = 0; i < XCAM_GAMMA_TABLE_SIZE; ++i) {
1436 // change from double to u0.12
1437 isp_param->b_gamma_table->data.vamem_2[i] =
1438 (uint32_t) (_common_handler->_params.b_gamma[i] * 4096.0);
1439 }
1440 isp_param->b_gamma_table->data.vamem_2[256] = 4091;
1441 }
1442 }
1443
1444 return XCAM_RETURN_NO_ERROR;
1445 }
1446
1447 XCamReturn
apply_night_mode(struct atomisp_parameters * isp_param)1448 AiqCompositor::apply_night_mode (struct atomisp_parameters *isp_param)
1449 {
1450 static const struct atomisp_cc_config night_yuv2rgb_cc_config = {
1451 10,
1452 { 1 << 10, 0, 0, /* 1.0, 0, 0 */
1453 1 << 10, 0, 0, /* 1.0, 0, 0 */
1454 1 << 10, 0, 0
1455 }
1456 }; /* 1.0, 0, 0 */
1457 static const struct atomisp_wb_config night_wb_config = {
1458 1,
1459 1 << 15, 1 << 15, 1 << 15, 1 << 15
1460 }; /* 1.0, 1.0, 1.0, 1.0*/
1461
1462 if (isp_param->ctc_config)
1463 isp_param->ctc_config = NULL;
1464
1465 *isp_param->wb_config = night_wb_config;
1466 *isp_param->yuv2rgb_cc_config = night_yuv2rgb_cc_config;
1467
1468 return XCAM_RETURN_NO_ERROR;
1469 }
1470
1471 double
calculate_value_by_factor(double factor,double min,double mid,double max)1472 AiqCompositor::calculate_value_by_factor (double factor, double min, double mid, double max)
1473 {
1474 XCAM_ASSERT (factor >= -1.0 && factor <= 1.0);
1475 XCAM_ASSERT (min <= mid && max >= mid);
1476
1477 if (factor >= 0.0)
1478 return (mid * (1.0 - factor) + max * factor);
1479 else
1480 return (mid * (1.0 + factor) + min * (-factor));
1481 }
1482
1483 XCamReturn
limit_nr_levels(struct atomisp_parameters * isp_param)1484 AiqCompositor::limit_nr_levels (struct atomisp_parameters *isp_param)
1485 {
1486 #define NR_MIN_FACOTR 0.1
1487 #define NR_MAX_FACOTR 6.0
1488 #define NR_MID_FACOTR 1.0
1489 SmartPtr<AiqCommonHandler> aiq_common = _common_handler;
1490
1491 if (!XCAM_DOUBLE_EQUAL_AROUND (aiq_common->_params.nr_level, 0.0)) {
1492 double nr_factor;
1493 nr_factor = calculate_value_by_factor (
1494 aiq_common->_params.nr_level, NR_MIN_FACOTR, NR_MID_FACOTR, NR_MAX_FACOTR);
1495 if (isp_param->nr_config) {
1496 isp_param->nr_config->bnr_gain =
1497 XCAM_MIN (isp_param->nr_config->bnr_gain * nr_factor, 65535);
1498 isp_param->nr_config->ynr_gain =
1499 XCAM_MIN (isp_param->nr_config->ynr_gain * nr_factor, 65535);
1500 }
1501 if (isp_param->cnr_config) {
1502 isp_param->cnr_config->sense_gain_vy =
1503 XCAM_MIN (isp_param->cnr_config->sense_gain_vy * nr_factor, 8191);
1504 isp_param->cnr_config->sense_gain_vu =
1505 XCAM_MIN (isp_param->cnr_config->sense_gain_vu * nr_factor, 8191);
1506 isp_param->cnr_config->sense_gain_vv =
1507 XCAM_MIN (isp_param->cnr_config->sense_gain_vv * nr_factor, 8191);
1508 isp_param->cnr_config->sense_gain_hy =
1509 XCAM_MIN (isp_param->cnr_config->sense_gain_hy * nr_factor, 8191);
1510 isp_param->cnr_config->sense_gain_hu =
1511 XCAM_MIN (isp_param->cnr_config->sense_gain_hu * nr_factor, 8191);
1512 isp_param->cnr_config->sense_gain_hv =
1513 XCAM_MIN (isp_param->cnr_config->sense_gain_hv * nr_factor, 8191);
1514 }
1515 }
1516
1517 if (!XCAM_DOUBLE_EQUAL_AROUND (aiq_common->_params.tnr_level, 0.0)) {
1518 double tnr_factor;
1519 tnr_factor = calculate_value_by_factor (
1520 aiq_common->_params.tnr_level, NR_MIN_FACOTR, NR_MID_FACOTR, NR_MAX_FACOTR);
1521 if (isp_param->tnr_config) {
1522 isp_param->tnr_config->gain =
1523 XCAM_MIN (isp_param->tnr_config->gain * tnr_factor, 65535);
1524 if (XCAM_DOUBLE_EQUAL_AROUND (aiq_common->_params.tnr_level, 1.0)) {
1525 isp_param->tnr_config->gain = 65535;
1526 isp_param->tnr_config->threshold_y = 0;
1527 isp_param->tnr_config->threshold_uv = 0;
1528 }
1529 }
1530 XCAM_LOG_DEBUG ("set TNR gain:%u", isp_param->tnr_config->gain);
1531 }
1532
1533 return XCAM_RETURN_NO_ERROR;
1534 }
1535
integrate(X3aResultList & results)1536 XCamReturn AiqCompositor::integrate (X3aResultList &results)
1537 {
1538 IspInputParameters isp_params;
1539 ia_aiq_pa_input_params pa_input;
1540 ia_aiq_pa_results *pa_result = NULL;
1541 #ifdef HAVE_AIQ_2_7
1542 ia_aiq_sa_input_params sa_input;
1543 ia_aiq_sa_results *sa_result = NULL;
1544 #endif
1545 ia_err ia_error = ia_err_none;
1546 ia_binary_data output;
1547 AiqAeHandler *aiq_ae = _ae_handler.ptr();
1548 AiqAwbHandler *aiq_awb = _awb_handler.ptr();
1549 AiqAfHandler *aiq_af = _af_handler.ptr();
1550 AiqCommonHandler *aiq_common = _common_handler.ptr();
1551 struct atomisp_parameters *isp_3a_result = NULL;
1552 SmartPtr<X3aResult> isp_results;
1553
1554 XCAM_FAIL_RETURN (
1555 ERROR,
1556 aiq_ae && aiq_awb && aiq_af && aiq_common,
1557 XCAM_RETURN_ERROR_PARAM,
1558 "handlers are not AIQ inherited");
1559
1560 xcam_mem_clear (pa_input);
1561 #ifndef HAVE_AIQ_2_7
1562 pa_input.frame_use = _frame_use;
1563 pa_input.sensor_frame_params = &_frame_params;
1564 #endif
1565 if (aiq_ae->is_started())
1566 pa_input.exposure_params = (aiq_ae->get_result ())->exposures[0].exposure;
1567 pa_input.color_gains = NULL;
1568
1569 if (aiq_common->_params.enable_night_mode) {
1570 pa_input.awb_results = NULL;
1571 isp_params.effects = ia_isp_effect_grayscale;
1572 }
1573 else {
1574 pa_input.awb_results = aiq_awb->get_result ();
1575 }
1576
1577 ia_error = ia_aiq_pa_run (_ia_handle, &pa_input, &pa_result);
1578 if (ia_error != ia_err_none) {
1579 XCAM_LOG_WARNING ("AIQ pa run failed"); // but not return error
1580 }
1581 _pa_result = pa_result;
1582
1583 if (aiq_awb->get_mode_unlock () == XCAM_AWB_MODE_MANUAL) {
1584 if (XCAM_DOUBLE_EQUAL_AROUND (aiq_awb->_params.gr_gain, 0.0) ||
1585 XCAM_DOUBLE_EQUAL_AROUND (aiq_awb->_params.r_gain, 0.0) ||
1586 XCAM_DOUBLE_EQUAL_AROUND (aiq_awb->_params.b_gain, 0.0) ||
1587 XCAM_DOUBLE_EQUAL_AROUND (aiq_awb->_params.gb_gain, 0.0)) {
1588 XCAM_LOG_DEBUG ("Zero gain would cause ISP division fatal error");
1589 }
1590 else {
1591 #ifdef HAVE_AIQ_2_7
1592 _pa_result->color_gains.gr = aiq_awb->_params.gr_gain;
1593 _pa_result->color_gains.r = aiq_awb->_params.r_gain;
1594 _pa_result->color_gains.b = aiq_awb->_params.b_gain;
1595 _pa_result->color_gains.gb = aiq_awb->_params.gb_gain;
1596 #else
1597 _pa_result->color_gains[0] = aiq_awb->_params.gr_gain;
1598 _pa_result->color_gains[1] = aiq_awb->_params.r_gain;
1599 _pa_result->color_gains[2] = aiq_awb->_params.b_gain;
1600 _pa_result->color_gains[3] = aiq_awb->_params.gb_gain;
1601 #endif
1602 }
1603 }
1604
1605 #ifdef HAVE_AIQ_2_7
1606 xcam_mem_clear (sa_input);
1607 sa_input.frame_use = _frame_use;
1608 sa_input.sensor_frame_params = &_frame_params;
1609 if (aiq_common->_params.enable_night_mode) {
1610 sa_input.awb_results = NULL;
1611 }
1612 else {
1613 sa_input.awb_results = aiq_awb->get_result ();
1614 }
1615
1616 ia_error = ia_aiq_sa_run (_ia_handle, &sa_input, &sa_result);
1617 if (ia_error != ia_err_none) {
1618 XCAM_LOG_WARNING ("AIQ sa run failed"); // but not return error
1619 }
1620 _sa_result = sa_result;
1621 #endif
1622
1623 isp_params.frame_use = _frame_use;
1624 isp_params.awb_results = aiq_awb->get_result ();
1625 if (aiq_ae->is_started())
1626 isp_params.exposure_results = (aiq_ae->get_result ())->exposures[0].exposure;
1627 isp_params.gbce_results = aiq_common->get_gbce_result ();
1628 isp_params.sensor_frame_params = &_frame_params;
1629 isp_params.pa_results = pa_result;
1630 #ifdef HAVE_AIQ_2_7
1631 isp_params.sa_results = sa_result;
1632 #endif
1633
1634 isp_params.manual_brightness = (int8_t)(aiq_common->get_brightness_unlock() * 128.0);
1635 isp_params.manual_contrast = (int8_t)(aiq_common->get_contrast_unlock() * 128.0);
1636 isp_params.manual_saturation = (int8_t)(aiq_common->get_saturation_unlock() * 128.0);
1637 isp_params.manual_hue = (int8_t)(aiq_common->get_hue_unlock() * 128.0);
1638 isp_params.manual_sharpness = (int8_t)(aiq_common->get_sharpness_unlock() * 128.0);
1639 isp_params.manual_nr_level = (int8_t)(aiq_common->get_nr_level_unlock() * 128.0);
1640
1641 convert_color_effect(isp_params);
1642
1643 xcam_mem_clear (output);
1644 if (!_adaptor->run (&isp_params, &output)) {
1645 XCAM_LOG_ERROR("Aiq to isp adaptor running failed");
1646 return XCAM_RETURN_ERROR_ISP;
1647 }
1648 isp_3a_result = ((struct atomisp_parameters *)output.data);
1649 apply_gamma_table (isp_3a_result);
1650 limit_nr_levels (isp_3a_result);
1651 if (aiq_common->_params.enable_night_mode)
1652 {
1653 apply_night_mode (isp_3a_result);
1654 }
1655
1656 isp_results = generate_3a_configs (isp_3a_result);
1657 results.push_back (isp_results);
1658 return XCAM_RETURN_NO_ERROR;
1659 }
1660
1661 SmartPtr<X3aResult>
generate_3a_configs(struct atomisp_parameters * parameters)1662 AiqCompositor::generate_3a_configs (struct atomisp_parameters *parameters)
1663 {
1664 SmartPtr<X3aResult> ret;
1665
1666 X3aAtomIspParametersResult *x3a_result =
1667 new X3aAtomIspParametersResult (XCAM_IMAGE_PROCESS_ONCE);
1668 x3a_result->set_isp_config (*parameters);
1669 ret = x3a_result;
1670 return ret;
1671 }
1672
1673 void
set_ae_handler(SmartPtr<AiqAeHandler> & handler)1674 AiqCompositor::set_ae_handler (SmartPtr<AiqAeHandler> &handler)
1675 {
1676 XCAM_ASSERT (!_ae_handler.ptr());
1677 _ae_handler = handler;
1678 }
1679
1680 void
set_awb_handler(SmartPtr<AiqAwbHandler> & handler)1681 AiqCompositor::set_awb_handler (SmartPtr<AiqAwbHandler> &handler)
1682 {
1683 XCAM_ASSERT (!_awb_handler.ptr());
1684 _awb_handler = handler;
1685 }
1686
1687 void
set_af_handler(SmartPtr<AiqAfHandler> & handler)1688 AiqCompositor::set_af_handler (SmartPtr<AiqAfHandler> &handler)
1689 {
1690 XCAM_ASSERT (!_af_handler.ptr());
1691 _af_handler = handler;
1692 }
1693
1694 void
set_common_handler(SmartPtr<AiqCommonHandler> & handler)1695 AiqCompositor::set_common_handler (SmartPtr<AiqCommonHandler> &handler)
1696 {
1697 XCAM_ASSERT (!_common_handler.ptr());
1698 _common_handler = handler;
1699 }
1700
1701
1702 };
1703