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 (at) intel.com> 19 * Author: Yan Zhang <yan.y.zhang (at) 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 56 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: 80 IaIspAdaptor22 () { 81 xcam_mem_clear (_input_params); 82 } 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 } 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 458 bool AiqAeHandler::ensure_ae_priority_mode () 459 { 460 _input.priority_mode = ia_aiq_ae_priority_mode_normal; 461 return true; 462 } 463 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 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 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> 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 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 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 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 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 702 AiqAeHandler::get_flicker_mode () 703 { 704 { 705 AnalyzerHandler::HandlerLock lock(this); 706 } 707 return AeHandler::get_flicker_mode (); 708 } 709 710 int64_t 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 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 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 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 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 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 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 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 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 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 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 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 1096 AiqAwbHandler::get_current_estimate_cct () 1097 { 1098 AnalyzerHandler::HandlerLock lock(this); 1099 return (uint32_t)_result.cct_estimate; 1100 } 1101 1102 XCamReturn 1103 AiqAfHandler::analyze (X3aResultList &output) 1104 { 1105 // TODO 1106 XCAM_UNUSED (output); 1107 return XCAM_RETURN_NO_ERROR; 1108 } 1109 1110 AiqCommonHandler::AiqCommonHandler (SmartPtr<AiqCompositor> &aiq_compositor) 1111 : _aiq_compositor (aiq_compositor) 1112 , _gbce_result (NULL) 1113 { 1114 } 1115 1116 1117 XCamReturn 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: 1152 explicit CmcParser (ia_binary_data &cpf) 1153 { 1154 _cmc = ia_cmc_parser_init (&cpf); 1155 } 1156 ~CmcParser () 1157 { 1158 if (_cmc) 1159 ia_cmc_parser_deinit (_cmc); 1160 } 1161 ia_cmc_t *get() { 1162 return _cmc; 1163 } 1164 1165 private: 1166 ia_cmc_t *_cmc; 1167 }; 1168 1169 void 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 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 1203 AiqCompositor::~AiqCompositor () 1204 { 1205 } 1206 1207 bool 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 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 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 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 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 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 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 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 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 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> 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 1674 AiqCompositor::set_ae_handler (SmartPtr<AiqAeHandler> &handler) 1675 { 1676 XCAM_ASSERT (!_ae_handler.ptr()); 1677 _ae_handler = handler; 1678 } 1679 1680 void 1681 AiqCompositor::set_awb_handler (SmartPtr<AiqAwbHandler> &handler) 1682 { 1683 XCAM_ASSERT (!_awb_handler.ptr()); 1684 _awb_handler = handler; 1685 } 1686 1687 void 1688 AiqCompositor::set_af_handler (SmartPtr<AiqAfHandler> &handler) 1689 { 1690 XCAM_ASSERT (!_af_handler.ptr()); 1691 _af_handler = handler; 1692 } 1693 1694 void 1695 AiqCompositor::set_common_handler (SmartPtr<AiqCommonHandler> &handler) 1696 { 1697 XCAM_ASSERT (!_common_handler.ptr()); 1698 _common_handler = handler; 1699 } 1700 1701 1702 }; 1703