• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hybrid_analyzer.h - hybrid 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: Jia Meng <jia.meng@intel.com>
19  */
20 
21 #include "hybrid_analyzer.h"
22 #include "isp_controller.h"
23 #include "x3a_analyzer_aiq.h"
24 #include "x3a_statistics_queue.h"
25 #include "aiq3a_utils.h"
26 #include <math.h>
27 
28 namespace XCam {
HybridAnalyzer(XCam3ADescription * desc,SmartPtr<AnalyzerLoader> & loader,SmartPtr<IspController> & isp,const char * cpf_path)29 HybridAnalyzer::HybridAnalyzer (XCam3ADescription *desc,
30                                    SmartPtr<AnalyzerLoader> &loader,
31                                    SmartPtr<IspController> &isp,
32                                    const char *cpf_path)
33     : DynamicAnalyzer (desc, loader, "HybridAnalyzer")
34     , _isp (isp)
35     , _cpf_path (cpf_path)
36 {
37     _analyzer_aiq = new X3aAnalyzerAiq (isp, cpf_path);
38     XCAM_ASSERT (_analyzer_aiq.ptr ());
39     _analyzer_aiq->prepare_handlers ();
40     _analyzer_aiq->set_results_callback (this);
41     _analyzer_aiq->set_sync_mode (true);
42 }
43 
44 XCamReturn
internal_init(uint32_t width,uint32_t height,double framerate)45 HybridAnalyzer::internal_init (uint32_t width, uint32_t height, double framerate)
46 {
47     if (_analyzer_aiq->init (width, height, framerate) != XCAM_RETURN_NO_ERROR) {
48         return XCAM_RETURN_ERROR_AIQ;
49     }
50 
51     return create_context ();
52 }
53 
54 XCamReturn
internal_deinit()55 HybridAnalyzer::internal_deinit ()
56 {
57     if (_analyzer_aiq->deinit () != XCAM_RETURN_NO_ERROR) {
58         return XCAM_RETURN_ERROR_AIQ;
59     }
60 
61     return DynamicAnalyzer::internal_deinit ();
62 }
63 
64 XCamReturn
setup_stats_pool(const XCam3AStats * stats)65 HybridAnalyzer::setup_stats_pool (const XCam3AStats *stats)
66 {
67     XCAM_ASSERT (stats);
68 
69     XCam3AStatsInfo stats_info = stats->info;
70     struct atomisp_grid_info grid_info;
71     grid_info.enable = 1;
72     grid_info.use_dmem = 0;
73     grid_info.has_histogram = 0;
74     grid_info.width = stats_info.width;
75     grid_info.height = stats_info.height;
76     grid_info.aligned_width = stats_info.aligned_width;
77     grid_info.aligned_height = stats_info.aligned_height;
78     grid_info.bqs_per_grid_cell = stats_info.grid_pixel_size >> 1;
79     grid_info.deci_factor_log2 = log2 (grid_info.bqs_per_grid_cell);
80     grid_info.elem_bit_depth = stats_info.bit_depth;
81 
82     _stats_pool = new X3aStatisticsQueue;
83     XCAM_ASSERT (_stats_pool.ptr ());
84 
85     _stats_pool->set_grid_info (grid_info);
86     if (!_stats_pool->reserve (6)) {
87         XCAM_LOG_WARNING ("setup_stats_pool failed to reserve stats buffer.");
88         return XCAM_RETURN_ERROR_MEM;
89     }
90 
91     return XCAM_RETURN_NO_ERROR;
92 }
93 
94 XCamReturn
configure_3a()95 HybridAnalyzer::configure_3a ()
96 {
97     if (_analyzer_aiq->start () != XCAM_RETURN_NO_ERROR) {
98         return XCAM_RETURN_ERROR_AIQ;
99     }
100 
101     return DynamicAnalyzer::configure_3a ();
102 }
103 
104 XCamReturn
pre_3a_analyze(SmartPtr<X3aStats> & stats)105 HybridAnalyzer::pre_3a_analyze (SmartPtr<X3aStats> &stats)
106 {
107     _analyzer_aiq->update_common_parameters (get_common_params ());
108 
109     return DynamicAnalyzer::pre_3a_analyze (stats);
110 }
111 
112 SmartPtr<X3aIspStatistics>
convert_to_isp_stats(SmartPtr<X3aStats> & stats)113 HybridAnalyzer::convert_to_isp_stats (SmartPtr<X3aStats>& stats)
114 {
115     SmartPtr<X3aIspStatistics> isp_stats =
116         _stats_pool->get_buffer (_stats_pool).dynamic_cast_ptr<X3aIspStatistics> ();
117 
118     XCAM_FAIL_RETURN (
119         WARNING,
120         isp_stats.ptr (),
121         NULL,
122         "get isp stats buffer failed");
123 
124     struct atomisp_3a_statistics *to = isp_stats->get_isp_stats ();
125     XCam3AStats *from = stats->get_stats ();
126     translate_3a_stats (from, to);
127     isp_stats->set_timestamp (stats->get_timestamp ());
128     return isp_stats;
129 }
130 
131 XCamReturn
post_3a_analyze(X3aResultList & results)132 HybridAnalyzer::post_3a_analyze (X3aResultList &results)
133 {
134     XCamReturn ret = XCAM_RETURN_NO_ERROR;
135     SmartPtr<X3aStats> stats = get_cur_stats ();
136 
137     if ((ret = DynamicAnalyzer::post_3a_analyze (results)) != XCAM_RETURN_NO_ERROR) {
138         return ret;
139     }
140 
141     for (X3aResultList::iterator i_res = results.begin ();
142             i_res != results.end (); ++i_res) {
143         SmartPtr<X3aResult> result = *i_res;
144 
145         switch (result->get_type ()) {
146         case XCAM_3A_RESULT_EXPOSURE: {
147             XCam3aResultExposure *res = (XCam3aResultExposure *) result->get_ptr ();
148             _analyzer_aiq->set_ae_mode (XCAM_AE_MODE_MANUAL);
149             _analyzer_aiq->set_ae_manual_exposure_time (res->exposure_time);
150             _analyzer_aiq->set_ae_manual_analog_gain (res->analog_gain);
151             break;
152         }
153         case XCAM_3A_RESULT_WHITE_BALANCE: {
154             _analyzer_aiq->set_awb_mode (XCAM_AWB_MODE_MANUAL);
155             XCam3aResultWhiteBalance *res = (XCam3aResultWhiteBalance *) result->get_ptr ();
156             _analyzer_aiq->set_awb_manual_gain (res->gr_gain, res->r_gain, res->b_gain, res->gb_gain);
157             break;
158         }
159         default:
160             break;
161         }
162     }
163     results.clear ();
164 
165     SmartPtr<X3aIspStatistics> isp_stats = stats.dynamic_cast_ptr<X3aIspStatistics> ();
166     if (!isp_stats.ptr ()) {
167         if (!_stats_pool.ptr () && setup_stats_pool (stats->get_stats ()) != XCAM_RETURN_NO_ERROR)
168             return XCAM_RETURN_ERROR_MEM;
169         isp_stats = convert_to_isp_stats (stats);
170     }
171     return _analyzer_aiq->push_3a_stats (isp_stats);
172 }
173 
174 XCamReturn
analyze_ae(XCamAeParam & param)175 HybridAnalyzer::analyze_ae (XCamAeParam &param)
176 {
177     if (!_analyzer_aiq->update_ae_parameters (param))
178         return XCAM_RETURN_ERROR_AIQ;
179 
180     return DynamicAnalyzer::analyze_ae (param);
181 }
182 
183 XCamReturn
analyze_awb(XCamAwbParam & param)184 HybridAnalyzer::analyze_awb (XCamAwbParam &param)
185 {
186     if (!_analyzer_aiq->update_awb_parameters (param))
187         return XCAM_RETURN_ERROR_AIQ;
188 
189     return DynamicAnalyzer::analyze_awb (param);
190 }
191 
192 XCamReturn
analyze_af(XCamAfParam & param)193 HybridAnalyzer::analyze_af (XCamAfParam &param)
194 {
195     if (!_analyzer_aiq->update_af_parameters (param))
196         return XCAM_RETURN_ERROR_AIQ;
197 
198     return DynamicAnalyzer::analyze_af (param);
199 }
200 
201 void
x3a_calculation_done(XAnalyzer * analyzer,X3aResultList & results)202 HybridAnalyzer::x3a_calculation_done (XAnalyzer *analyzer, X3aResultList &results)
203 {
204     XCAM_UNUSED (analyzer);
205 
206     static XCam3aResultHead *res_heads[XCAM_3A_MAX_RESULT_COUNT];
207     xcam_mem_clear (res_heads);
208     XCAM_ASSERT (results.size () < XCAM_3A_MAX_RESULT_COUNT);
209 
210     uint32_t result_count = translate_3a_results_to_xcam (results,
211                             res_heads, XCAM_3A_MAX_RESULT_COUNT);
212     convert_results (res_heads, result_count, results);
213     for (uint32_t i = 0; i < result_count; ++i) {
214         if (res_heads[i])
215             free_3a_result (res_heads[i]);
216     }
217 
218     notify_calculation_done (results);
219 }
220 
~HybridAnalyzer()221 HybridAnalyzer::~HybridAnalyzer ()
222 {
223     destroy_context ();
224 }
225 
226 void
x3a_calculation_failed(XAnalyzer * analyzer,int64_t timestamp,const char * msg)227 HybridAnalyzer::x3a_calculation_failed (XAnalyzer *analyzer, int64_t timestamp, const char *msg)
228 {
229     XCAM_UNUSED (analyzer);
230     notify_calculation_failed (NULL, timestamp, msg);
231 }
232 }
233