Home | History | Annotate | Download | only in xcore
      1 /*
      2  * x3a_analyzer_simple.cpp - a simple 3a analyzer
      3  *
      4  *  Copyright (c) 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  */
     20 
     21 #include "x3a_analyzer_simple.h"
     22 
     23 namespace XCam {
     24 
     25 #define SIMPLE_MIN_TARGET_EXPOSURE_TIME  5000 //5ms
     26 #define SIMPLE_MAX_TARGET_EXPOSURE_TIME  33000 //33ms
     27 #define SIMPLE_DEFAULT_BLACK_LEVEL       0.05
     28 
     29 class SimpleAeHandler
     30     : public AeHandler
     31 {
     32 public:
     33     SimpleAeHandler (X3aAnalyzerSimple *analyzer)
     34         : _analyzer (analyzer)
     35     {}
     36     ~SimpleAeHandler () {}
     37 
     38     virtual XCamReturn analyze (X3aResultList &output) {
     39         return _analyzer->analyze_ae (output);
     40     }
     41 private:
     42     X3aAnalyzerSimple *_analyzer;
     43 };
     44 
     45 class SimpleAwbHandler
     46     : public AwbHandler
     47 {
     48 public:
     49     SimpleAwbHandler (X3aAnalyzerSimple *analyzer)
     50         : _analyzer (analyzer)
     51     {}
     52     ~SimpleAwbHandler () {}
     53 
     54     virtual XCamReturn analyze (X3aResultList &output) {
     55         return _analyzer->analyze_awb (output);
     56     }
     57 private:
     58     X3aAnalyzerSimple *_analyzer;
     59 
     60 };
     61 
     62 class SimpleAfHandler
     63     : public AfHandler
     64 {
     65 public:
     66     SimpleAfHandler (X3aAnalyzerSimple *analyzer)
     67         : _analyzer (analyzer)
     68     {}
     69     ~SimpleAfHandler () {}
     70 
     71     virtual XCamReturn analyze (X3aResultList &output) {
     72         return _analyzer->analyze_af (output);
     73     }
     74 
     75 private:
     76     X3aAnalyzerSimple *_analyzer;
     77 };
     78 
     79 class SimpleCommonHandler
     80     : public CommonHandler
     81 {
     82 public:
     83     SimpleCommonHandler (X3aAnalyzerSimple *analyzer)
     84         : _analyzer (analyzer)
     85     {}
     86     ~SimpleCommonHandler () {}
     87 
     88     virtual XCamReturn analyze (X3aResultList &output) {
     89         XCAM_UNUSED (output);
     90         return XCAM_RETURN_NO_ERROR;
     91     }
     92 
     93 private:
     94     X3aAnalyzerSimple *_analyzer;
     95 };
     96 
     97 X3aAnalyzerSimple::X3aAnalyzerSimple ()
     98     : X3aAnalyzer ("X3aAnalyzerSimple")
     99     , _last_target_exposure ((double)SIMPLE_MIN_TARGET_EXPOSURE_TIME)
    100     , _is_ae_started (false)
    101     , _ae_calculation_interval (0)
    102 {
    103 }
    104 
    105 X3aAnalyzerSimple::~X3aAnalyzerSimple ()
    106 {
    107 }
    108 
    109 SmartPtr<AeHandler>
    110 X3aAnalyzerSimple::create_ae_handler ()
    111 {
    112     SimpleAeHandler *handler = new SimpleAeHandler (this);
    113     return handler;
    114 }
    115 
    116 SmartPtr<AwbHandler>
    117 X3aAnalyzerSimple::create_awb_handler ()
    118 {
    119     SimpleAwbHandler *handler = new SimpleAwbHandler (this);
    120     return handler;
    121 }
    122 
    123 SmartPtr<AfHandler>
    124 X3aAnalyzerSimple::create_af_handler ()
    125 {
    126     SimpleAfHandler *handler = new SimpleAfHandler (this);
    127     return handler;
    128 }
    129 
    130 SmartPtr<CommonHandler>
    131 X3aAnalyzerSimple::create_common_handler ()
    132 {
    133     SimpleCommonHandler *handler = new SimpleCommonHandler (this);
    134     return handler;
    135 }
    136 
    137 XCamReturn
    138 X3aAnalyzerSimple::configure_3a ()
    139 {
    140     _is_ae_started = false;
    141     _ae_calculation_interval = 0;
    142     return XCAM_RETURN_NO_ERROR;
    143 }
    144 
    145 XCamReturn
    146 X3aAnalyzerSimple::pre_3a_analyze (SmartPtr<X3aStats> &stats)
    147 {
    148     _current_stats = stats;
    149     return XCAM_RETURN_NO_ERROR;
    150 }
    151 
    152 XCamReturn
    153 X3aAnalyzerSimple::post_3a_analyze (X3aResultList &results)
    154 {
    155     _current_stats.release ();
    156 
    157     XCam3aResultBlackLevel black_level;
    158     SmartPtr<X3aBlackLevelResult> bl_result = new X3aBlackLevelResult (XCAM_3A_RESULT_BLACK_LEVEL);
    159 
    160     xcam_mem_clear (black_level);
    161     black_level.r_level = SIMPLE_DEFAULT_BLACK_LEVEL;
    162     black_level.gr_level = SIMPLE_DEFAULT_BLACK_LEVEL;
    163     black_level.gb_level = SIMPLE_DEFAULT_BLACK_LEVEL;
    164     black_level.b_level = SIMPLE_DEFAULT_BLACK_LEVEL;
    165     bl_result->set_standard_result (black_level);
    166     results.push_back (bl_result);
    167 
    168     return XCAM_RETURN_NO_ERROR;
    169 }
    170 
    171 XCamReturn
    172 X3aAnalyzerSimple::analyze_awb (X3aResultList &output)
    173 {
    174     const XCam3AStats *stats = _current_stats->get_stats ();
    175     double sum_r = 0.0, sum_gr = 0.0, sum_gb = 0.0, sum_b = 0.0;
    176     double avg_r = 0.0, avg_gr = 0.0, avg_gb = 0.0, avg_b = 0.0;
    177     double target_avg = 0.0;
    178     XCam3aResultWhiteBalance wb;
    179 
    180     xcam_mem_clear (wb);
    181     XCAM_ASSERT (stats);
    182 
    183     // calculate avg r, gr, gb, b
    184     for (uint32_t i = 0; i < stats->info.height; ++i)
    185         for (uint32_t j = 0; j < stats->info.width; ++j) {
    186             sum_r += (double)(stats->stats[i * stats->info.aligned_width + j].avg_r);
    187             sum_gr += (double)(stats->stats[i * stats->info.aligned_width + j].avg_gr);
    188             sum_gb += (double)(stats->stats[i * stats->info.aligned_width + j].avg_gb);
    189             sum_b += (double)(stats->stats[i * stats->info.aligned_width + j].avg_b);
    190         }
    191 
    192     avg_r = sum_r / (stats->info.width * stats->info.height);
    193     avg_gr = sum_gr / (stats->info.width * stats->info.height);
    194     avg_gb = sum_gb / (stats->info.width * stats->info.height);
    195     avg_b = sum_b / (stats->info.width * stats->info.height);
    196 
    197     target_avg =  (avg_gr + avg_gb) / 2;
    198     wb.r_gain = target_avg / avg_r;
    199     wb.b_gain = target_avg / avg_b;
    200     wb.gr_gain = 1.0;
    201     wb.gb_gain = 1.0;
    202 
    203     SmartPtr<X3aWhiteBalanceResult> result = new X3aWhiteBalanceResult (XCAM_3A_RESULT_WHITE_BALANCE);
    204     result->set_standard_result (wb);
    205     output.push_back (result);
    206 
    207     XCAM_LOG_DEBUG ("X3aAnalyzerSimple analyze awb, r:%f, gr:%f, gb:%f, b:%f",
    208                     wb.r_gain, wb.gr_gain, wb.gb_gain, wb.b_gain);
    209 
    210     return XCAM_RETURN_NO_ERROR;
    211 }
    212 
    213 XCamReturn
    214 X3aAnalyzerSimple::analyze_ae (X3aResultList &output)
    215 {
    216     static const uint32_t expect_y_mean = 110;
    217 
    218     const XCam3AStats *stats = _current_stats->get_stats ();
    219     XCAM_FAIL_RETURN(
    220         WARNING,
    221         stats,
    222         XCAM_RETURN_ERROR_UNKNOWN,
    223         "failed to get XCam3AStats");
    224 
    225     double sum_y = 0.0;
    226     double target_exposure = 1.0;
    227     SmartPtr<X3aExposureResult> result = new X3aExposureResult (XCAM_3A_RESULT_EXPOSURE);
    228     XCam3aResultExposure exposure;
    229 
    230     xcam_mem_clear (exposure);
    231     exposure.digital_gain = 1.0;
    232 
    233     if (!_is_ae_started) {
    234         _last_target_exposure = SIMPLE_MIN_TARGET_EXPOSURE_TIME;
    235         exposure.exposure_time = _last_target_exposure;
    236         exposure.analog_gain = 1.0;
    237 
    238         result->set_standard_result (exposure);
    239         output.push_back (result);
    240         _is_ae_started = true;
    241         return XCAM_RETURN_NO_ERROR;
    242     }
    243 
    244     if (_ae_calculation_interval % 10 == 0) {
    245         for (uint32_t i = 0; i < stats->info.height; ++i)
    246             for (uint32_t j = 0; j < stats->info.width; ++j) {
    247                 sum_y += (double)(stats->stats[i * stats->info.aligned_width + j].avg_y);
    248             }
    249         sum_y /= (stats->info.width * stats->info.height);
    250         target_exposure = (expect_y_mean / sum_y) * _last_target_exposure;
    251         target_exposure = XCAM_MAX (target_exposure, SIMPLE_MIN_TARGET_EXPOSURE_TIME);
    252 
    253         if (target_exposure > SIMPLE_MAX_TARGET_EXPOSURE_TIME * 255)
    254             target_exposure = SIMPLE_MAX_TARGET_EXPOSURE_TIME * 255;
    255 
    256         if (target_exposure > SIMPLE_MAX_TARGET_EXPOSURE_TIME) {
    257             exposure.exposure_time = SIMPLE_MAX_TARGET_EXPOSURE_TIME;
    258             exposure.analog_gain = target_exposure / exposure.exposure_time;
    259         } else {
    260             exposure.exposure_time = target_exposure;
    261             exposure.analog_gain = 1.0;
    262         }
    263 
    264         result->set_standard_result (exposure);
    265         output.push_back (result);
    266         _last_target_exposure = target_exposure;
    267     }
    268 
    269     _ae_calculation_interval++;
    270 
    271     return XCAM_RETURN_NO_ERROR;
    272 }
    273 
    274 XCamReturn X3aAnalyzerSimple::analyze_af (X3aResultList &output)
    275 {
    276     XCAM_UNUSED (output);
    277     return XCAM_RETURN_NO_ERROR;
    278 }
    279 
    280 };
    281