• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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@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:
SimpleAeHandler(X3aAnalyzerSimple * analyzer)33     SimpleAeHandler (X3aAnalyzerSimple *analyzer)
34         : _analyzer (analyzer)
35     {}
~SimpleAeHandler()36     ~SimpleAeHandler () {}
37 
analyze(X3aResultList & output)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:
SimpleAwbHandler(X3aAnalyzerSimple * analyzer)49     SimpleAwbHandler (X3aAnalyzerSimple *analyzer)
50         : _analyzer (analyzer)
51     {}
~SimpleAwbHandler()52     ~SimpleAwbHandler () {}
53 
analyze(X3aResultList & output)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:
SimpleAfHandler(X3aAnalyzerSimple * analyzer)66     SimpleAfHandler (X3aAnalyzerSimple *analyzer)
67         : _analyzer (analyzer)
68     {}
~SimpleAfHandler()69     ~SimpleAfHandler () {}
70 
analyze(X3aResultList & output)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:
SimpleCommonHandler(X3aAnalyzerSimple * analyzer)83     SimpleCommonHandler (X3aAnalyzerSimple *analyzer)
84         : _analyzer (analyzer)
85     {}
~SimpleCommonHandler()86     ~SimpleCommonHandler () {}
87 
analyze(X3aResultList & output)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 
X3aAnalyzerSimple()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 
~X3aAnalyzerSimple()105 X3aAnalyzerSimple::~X3aAnalyzerSimple ()
106 {
107 }
108 
109 SmartPtr<AeHandler>
create_ae_handler()110 X3aAnalyzerSimple::create_ae_handler ()
111 {
112     SimpleAeHandler *handler = new SimpleAeHandler (this);
113     return handler;
114 }
115 
116 SmartPtr<AwbHandler>
create_awb_handler()117 X3aAnalyzerSimple::create_awb_handler ()
118 {
119     SimpleAwbHandler *handler = new SimpleAwbHandler (this);
120     return handler;
121 }
122 
123 SmartPtr<AfHandler>
create_af_handler()124 X3aAnalyzerSimple::create_af_handler ()
125 {
126     SimpleAfHandler *handler = new SimpleAfHandler (this);
127     return handler;
128 }
129 
130 SmartPtr<CommonHandler>
create_common_handler()131 X3aAnalyzerSimple::create_common_handler ()
132 {
133     SimpleCommonHandler *handler = new SimpleCommonHandler (this);
134     return handler;
135 }
136 
137 XCamReturn
configure_3a()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
pre_3a_analyze(SmartPtr<X3aStats> & stats)146 X3aAnalyzerSimple::pre_3a_analyze (SmartPtr<X3aStats> &stats)
147 {
148     _current_stats = stats;
149     return XCAM_RETURN_NO_ERROR;
150 }
151 
152 XCamReturn
post_3a_analyze(X3aResultList & results)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
analyze_awb(X3aResultList & output)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
analyze_ae(X3aResultList & output)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 
analyze_af(X3aResultList & output)274 XCamReturn X3aAnalyzerSimple::analyze_af (X3aResultList &output)
275 {
276     XCAM_UNUSED (output);
277     return XCAM_RETURN_NO_ERROR;
278 }
279 
280 };
281