blob: 6a401f754449defa2d5a8b5efb9f3b9363899900 [file] [log] [blame]
Wind Yuan8ba2f162015-05-04 14:51:07 +08001/*
2 * aiq_wrapper.cpp - aiq wrapper:
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 <base/xcam_3a_description.h>
22#include "xcam_utils.h"
23#include "x3a_analyzer_aiq.h"
24#include "x3a_statistics_queue.h"
25#include "aiq3a_utils.h"
26
27#define DEFAULT_AIQ_CPF_FILE "/etc/atomisp/imx185.cpf"
28
29
30using namespace XCam;
31
32#define AIQ_CONTEXT_CAST(context) ((XCam3AAiqContext*)(context))
33
34class XCam3AAiqContext
35 : public AnalyzerCallback
36{
37public:
38 XCam3AAiqContext ();
39 bool setup_analyzer (SmartPtr<IspController> &isp, const char *cpf);
40 bool setup_stats_pool (uint32_t width, uint32_t height);
41 SmartPtr<X3aAnalyzerAiq> &get_analyzer () {
42 return _analyzer;
43 }
44
45 SmartPtr<X3aIspStatistics> get_stats_buffer ();
46 uint32_t get_results (X3aResultList &results);
47
48 // derive from AnalyzerCallback
49 virtual void x3a_calculation_done (X3aAnalyzer *analyzer, X3aResultList &results);
50
51private:
52 XCAM_DEAD_COPY (XCam3AAiqContext);
53
54private:
55// members
56 SmartPtr<X3aAnalyzerAiq> _analyzer;
57 SmartPtr<X3aStatisticsQueue> _stats_pool;
58
59 Mutex _result_mutex;
60 X3aResultList _results;
61};
62
63XCam3AAiqContext::XCam3AAiqContext ()
64{
65}
66
67bool
68XCam3AAiqContext::setup_analyzer (SmartPtr<IspController> &isp, const char *cpf)
69{
70 XCAM_ASSERT (!_analyzer.ptr ());
71 _analyzer = new X3aAnalyzerAiq (isp, cpf);
72 XCAM_ASSERT (_analyzer.ptr ());
73 _analyzer->set_results_callback (this);
74 return true;
75}
76
77bool
78XCam3AAiqContext::setup_stats_pool (uint32_t width, uint32_t height)
79{
80 VideoBufferInfo info;
81 info.init (XCAM_PIX_FMT_SGRBG16, width, height);
82
83 XCAM_FAIL_RETURN (
84 WARNING,
85 _stats_pool->set_video_info (info),
86 false,
87 "3a stats set video info failed");
88
89
90 if (!_stats_pool->reserve (6)) {
91 XCAM_LOG_WARNING ("init_3a_stats_pool failed to reserve stats buffer.");
92 return false;
93 }
94
95 return true;
96}
97
98SmartPtr<X3aIspStatistics>
99XCam3AAiqContext::get_stats_buffer ()
100{
101 SmartPtr<X3aIspStatistics> new_stats =
102 _stats_pool->get_buffer (_stats_pool).dynamic_cast_ptr<X3aIspStatistics> ();
103
104 XCAM_FAIL_RETURN (
105 WARNING,
106 new_stats.ptr (),
107 NULL,
108 "get isp stats buffer failed");
109
110 return new_stats;
111}
112
113
114void
115XCam3AAiqContext::x3a_calculation_done (X3aAnalyzer *analyzer, X3aResultList &results)
116{
117 XCAM_UNUSED (analyzer);
118 SmartLock locker (_result_mutex);
119 _results.insert (_results.end (), results.begin (), results.end ());
120}
121
122uint32_t
123XCam3AAiqContext::get_results (X3aResultList &results)
124{
125 uint32_t size = 0;
126
127 SmartLock locker (_result_mutex);
128
129 results.assign (_results.begin (), _results.end ());
130 size = _results.size ();
131 _results.clear ();
132
133 return size;
134}
135
136static SmartPtr<X3aAnalyzerAiq>
137get_analyzer (XCam3AContext *context)
138{
139 XCam3AAiqContext *aiq_context = AIQ_CONTEXT_CAST (context);
140 if (!aiq_context)
141 return NULL;
142
143 return aiq_context->get_analyzer ();
144}
145
146static XCamReturn
147xcam_create_context (XCam3AContext **context)
148{
149 XCAM_ASSERT (context);
150 XCam3AAiqContext *aiq_context = new XCam3AAiqContext ();
151 *context = ((XCam3AContext*)(aiq_context));
152 return XCAM_RETURN_NO_ERROR;
153}
154
155static XCamReturn
156xcam_destroy_context (XCam3AContext *context)
157{
158 XCam3AAiqContext *aiq_context = AIQ_CONTEXT_CAST (context);
159 if (aiq_context)
160 delete aiq_context;
161 return XCAM_RETURN_NO_ERROR;
162}
163
164static XCamReturn
165xcam_configure_3a (XCam3AContext *context, uint32_t width, uint32_t height, double framerate)
166{
167 XCam3AAiqContext *aiq_context = AIQ_CONTEXT_CAST (context);
168 XCamReturn ret = XCAM_RETURN_NO_ERROR;
169 SmartPtr<IspController> isp;
170
171 XCAM_ASSERT (aiq_context);
172 XCAM_FAIL_RETURN (
173 WARNING,
174 aiq_context->setup_analyzer (isp, DEFAULT_AIQ_CPF_FILE),
175 XCAM_RETURN_ERROR_UNKNOWN,
176 "setup aiq 3a analyzer failed");
177
178 SmartPtr<X3aAnalyzerAiq> analyzer = aiq_context->get_analyzer ();
179 ret = analyzer->init (width, height, framerate);
180 XCAM_FAIL_RETURN (
181 WARNING,
182 ret == XCAM_RETURN_NO_ERROR,
183 ret,
184 "configure aiq 3a failed");
185
186 ret = analyzer->start ();
187 XCAM_FAIL_RETURN (
188 WARNING,
189 ret == XCAM_RETURN_NO_ERROR,
190 ret,
191 "start aiq 3a failed");
192
193 // init statistics queue
194 XCAM_FAIL_RETURN (
195 WARNING,
196 aiq_context->setup_stats_pool (width, height),
197 ret,
198 "aiq configure 3a failed on stats pool setup");
199
200 return XCAM_RETURN_NO_ERROR;
201}
202
203static XCamReturn
204xcam_set_3a_stats (XCam3AContext *context, XCam3AStats *stats)
205{
206 XCamReturn ret = XCAM_RETURN_NO_ERROR;
207 XCam3AAiqContext *aiq_context = AIQ_CONTEXT_CAST (context);
208 XCAM_ASSERT (aiq_context);
209
210 SmartPtr<X3aAnalyzerAiq> analyzer = aiq_context->get_analyzer ();
211 XCAM_ASSERT (analyzer.ptr ());
212 XCAM_ASSERT (stats);
213
214 // Convert stats to atomisp_3a_stats;
215 SmartPtr<X3aIspStatistics> isp_stats = aiq_context->get_stats_buffer ();
216 struct atomisp_3a_statistics *raw_stats = isp_stats->get_isp_stats ();
217 XCAM_ASSERT (raw_stats);
218
219 XCamAiq3A::translate_3a_stats (stats, raw_stats);
220
221 ret = analyzer->push_3a_stats (isp_stats);
222 if (ret != XCAM_RETURN_NO_ERROR) {
223 XCAM_LOG_WARNING ("set 3a stats failed");
224 }
225
226 return ret;
227}
228
229static XCamReturn
230xcam_update_common_params (XCam3AContext *context, XCamCommonParam *params)
231{
232 if (params) {
233 SmartPtr<X3aAnalyzerAiq> analyzer = get_analyzer (context);
234 XCAM_ASSERT (analyzer.ptr ());
235
236 analyzer->update_common_parameters (*params);
237 }
238 return XCAM_RETURN_NO_ERROR;
239}
240
241static XCamReturn
242xcam_analyze_awb (XCam3AContext *context, XCamAwbParam *params)
243{
244 if (params) {
245 SmartPtr<X3aAnalyzerAiq> analyzer = get_analyzer (context);
246 XCAM_ASSERT (analyzer.ptr ());
247
248 analyzer->update_awb_parameters (*params);
249 }
250 return XCAM_RETURN_NO_ERROR;
251}
252
253static XCamReturn
254xcam_analyze_ae (XCam3AContext *context, XCamAeParam *params)
255{
256 if (params) {
257 SmartPtr<X3aAnalyzerAiq> analyzer = get_analyzer (context);
258 XCAM_ASSERT (analyzer.ptr ());
259
260 analyzer->update_ae_parameters (*params);
261 }
262 return XCAM_RETURN_NO_ERROR;
263}
264
265static XCamReturn
266xcam_analyze_af (XCam3AContext *context, XCamAfParam *params)
267{
268 if (params) {
269 SmartPtr<X3aAnalyzerAiq> analyzer = get_analyzer (context);
270 XCAM_ASSERT (analyzer.ptr ());
271
272 analyzer->update_af_parameters (*params);
273 }
274 return XCAM_RETURN_NO_ERROR;
275}
276
277static XCamReturn
278xcam_combine_analyze_results (XCam3AContext *context, XCam3aResultHead *results[], uint32_t *res_count)
279{
280 XCam3AAiqContext *aiq_context = AIQ_CONTEXT_CAST (context);
281 XCAM_ASSERT (aiq_context);
282 X3aResultList aiq_results;
283 uint32_t result_count = aiq_context->get_results (aiq_results);
284
285 if (!result_count) {
286 *res_count = 0;
287 XCAM_LOG_DEBUG ("aiq wrapper comible with no result out");
288 return XCAM_RETURN_NO_ERROR;
289 }
290
291 // mark as static
292 static XCam3aResultHead *res_array[XCAM_3A_LIB_MAX_RESULT_COUNT];
293 xcam_mem_clear (res_array);
294 XCAM_ASSERT (result_count < XCAM_3A_LIB_MAX_RESULT_COUNT);
295
296 // result_count may changed
297 result_count = XCamAiq3A::translate_3a_results_to_xcam (aiq_results, res_array, XCAM_3A_LIB_MAX_RESULT_COUNT);
298
299 for (uint32_t i = 0; i < result_count; ++i) {
300 results[i] = res_array[i];
301 }
302 *res_count = result_count;
303 XCAM_ASSERT (result_count > 0);
304
305 return XCAM_RETURN_NO_ERROR;
306}
307
308static void
309xcam_free_results (XCam3aResultHead *results[], uint32_t res_count)
310{
311 for (uint32_t i = 0; i < res_count; ++i) {
312 if (results[i])
313 XCamAiq3A::free_3a_result (results[i]);
314 }
315}
316
317XCAM_BEGIN_DECLARE
318
319XCam3ADescription xcam_3a_desciption = {
320 XCAM_VERSION,
321 sizeof (XCam3ADescription),
322 xcam_create_context,
323 xcam_destroy_context,
324 xcam_configure_3a,
325 xcam_set_3a_stats,
326 xcam_update_common_params,
327 xcam_analyze_awb,
328 xcam_analyze_ae,
329 xcam_analyze_af,
330 xcam_combine_analyze_results,
331 xcam_free_results
332};
333
334XCAM_END_DECLARE
335