Home | History | Annotate | Download | only in isp
      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