• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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_std.h>
23 #include "x3a_analyzer_aiq.h"
24 #include "x3a_statistics_queue.h"
25 #include "aiq3a_utils.h"
26 #include "x3a_result_factory.h"
27 #include "x3a_analyze_tuner.h"
28 
29 #define DEFAULT_AIQ_CPF_FILE       "/etc/atomisp/imx185.cpf"
30 
31 
32 using namespace XCam;
33 
34 #define AIQ_CONTEXT_CAST(context)  ((XCam3AAiqContext*)(context))
35 
36 class XCam3AAiqContext
37     : public AnalyzerCallback
38 {
39 public:
40     XCam3AAiqContext ();
41     ~XCam3AAiqContext ();
42     bool setup_analyzer (struct atomisp_sensor_mode_data &sensor_mode_data, const char *cpf);
43     void set_size (uint32_t width, uint32_t height);
44     bool setup_stats_pool (uint32_t bit_depth = 8);
is_stats_pool_ready() const45     bool is_stats_pool_ready () const {
46         return (_stats_pool.ptr () ? true : false);
47     }
get_analyzer()48     SmartPtr<X3aAnalyzeTuner> &get_analyzer () {
49         return _analyzer;
50     }
51 
52     SmartPtr<X3aIspStatistics> get_stats_buffer ();
53     uint32_t get_results (X3aResultList &results);
54 
55     // derive from AnalyzerCallback
56     virtual void x3a_calculation_done (XAnalyzer *analyzer, X3aResultList &results);
57     void update_brightness_result(XCamCommonParam *params);
58 
59 private:
60     XCAM_DEAD_COPY (XCam3AAiqContext);
61 
62 private:
63 // members
64     SmartPtr<X3aAnalyzeTuner>      _analyzer;
65     SmartPtr<X3aStatisticsQueue>   _stats_pool;
66     uint32_t                       _video_width;
67     uint32_t                       _video_height;
68 
69     Mutex                          _result_mutex;
70     X3aResultList                  _results;
71     double                         _brightness_level;
72 };
73 
XCam3AAiqContext()74 XCam3AAiqContext::XCam3AAiqContext ()
75     : _video_width (0)
76     , _video_height (0)
77     , _brightness_level(0)
78 {
79 }
80 
~XCam3AAiqContext()81 XCam3AAiqContext::~XCam3AAiqContext ()
82 {
83     _analyzer->stop ();
84     _analyzer->deinit ();
85 }
86 
87 bool
setup_analyzer(struct atomisp_sensor_mode_data & sensor_mode_data,const char * cpf)88 XCam3AAiqContext::setup_analyzer (struct atomisp_sensor_mode_data &sensor_mode_data, const char *cpf)
89 {
90     XCAM_ASSERT (!_analyzer.ptr ());
91     SmartPtr<X3aAnalyzer> aiq_analyzer = new X3aAnalyzerAiq (sensor_mode_data, cpf);
92     XCAM_ASSERT (aiq_analyzer.ptr ());
93 
94     _analyzer = new X3aAnalyzeTuner ();
95     XCAM_ASSERT (_analyzer.ptr ());
96 
97     _analyzer->set_analyzer (aiq_analyzer);
98     _analyzer->set_results_callback (this);
99     return true;
100 }
101 
102 void
set_size(uint32_t width,uint32_t height)103 XCam3AAiqContext::set_size (uint32_t width, uint32_t height)
104 {
105     _video_width = width;
106     _video_height = height;
107 }
108 
109 bool
setup_stats_pool(uint32_t bit_depth)110 XCam3AAiqContext::setup_stats_pool (uint32_t bit_depth)
111 {
112     VideoBufferInfo info;
113     info.init (XCAM_PIX_FMT_SGRBG16, _video_width, _video_height);
114 
115     _stats_pool = new X3aStatisticsQueue;
116     XCAM_ASSERT (_stats_pool.ptr ());
117 
118     _stats_pool->set_bit_depth (bit_depth);
119     XCAM_FAIL_RETURN (
120         WARNING,
121         _stats_pool->set_video_info (info),
122         false,
123         "3a stats set video info failed");
124 
125 
126     if (!_stats_pool->reserve (6)) {
127         XCAM_LOG_WARNING ("init_3a_stats_pool failed to reserve stats buffer.");
128         return false;
129     }
130 
131     return true;
132 }
133 
134 SmartPtr<X3aIspStatistics>
get_stats_buffer()135 XCam3AAiqContext::get_stats_buffer ()
136 {
137     SmartPtr<X3aIspStatistics> new_stats =
138         _stats_pool->get_buffer (_stats_pool).dynamic_cast_ptr<X3aIspStatistics> ();
139 
140     XCAM_FAIL_RETURN (
141         WARNING,
142         new_stats.ptr (),
143         NULL,
144         "get isp stats buffer failed");
145 
146     return new_stats;
147 }
148 
149 
150 void
x3a_calculation_done(XAnalyzer * analyzer,X3aResultList & results)151 XCam3AAiqContext::x3a_calculation_done (XAnalyzer *analyzer, X3aResultList &results)
152 {
153     XCAM_UNUSED (analyzer);
154     SmartLock  locker (_result_mutex);
155     _results.insert (_results.end (), results.begin (), results.end ());
156 }
157 
158 void
update_brightness_result(XCamCommonParam * params)159 XCam3AAiqContext::update_brightness_result(XCamCommonParam *params)
160 {
161     if( params->brightness == _brightness_level)
162         return;
163     _brightness_level = params->brightness;
164 
165     XCam3aResultBrightness xcam3a_brightness_result;
166     xcam_mem_clear (xcam3a_brightness_result);
167     xcam3a_brightness_result.head.type =   XCAM_3A_RESULT_BRIGHTNESS;
168     xcam3a_brightness_result.head.process_type = XCAM_IMAGE_PROCESS_ALWAYS;
169     xcam3a_brightness_result.head.version = XCAM_VERSION;
170     xcam3a_brightness_result.brightness_level = _brightness_level;
171 
172     SmartPtr<X3aResult> brightness_result =
173         X3aResultFactory::instance ()->create_3a_result ((XCam3aResultHead*)&xcam3a_brightness_result);
174     _results.push_back(brightness_result);
175 }
176 
177 uint32_t
get_results(X3aResultList & results)178 XCam3AAiqContext::get_results (X3aResultList &results)
179 {
180     uint32_t size = 0;
181 
182     SmartLock  locker (_result_mutex);
183 
184     results.assign (_results.begin (), _results.end ());
185     size = _results.size ();
186     _results.clear ();
187 
188     return size;
189 }
190 
191 static SmartPtr<X3aAnalyzeTuner>
get_analyzer(XCam3AContext * context)192 get_analyzer (XCam3AContext *context)
193 {
194     XCam3AAiqContext *aiq_context = AIQ_CONTEXT_CAST (context);
195     if (!aiq_context)
196         return NULL;
197 
198     return aiq_context->get_analyzer ();
199 }
200 
201 static XCamReturn
xcam_create_context(XCam3AContext ** context)202 xcam_create_context (XCam3AContext **context)
203 {
204     XCAM_ASSERT (context);
205     XCam3AAiqContext *aiq_context = new XCam3AAiqContext ();
206     *context = ((XCam3AContext*)(aiq_context));
207     return XCAM_RETURN_NO_ERROR;
208 }
209 
210 static XCamReturn
xcam_destroy_context(XCam3AContext * context)211 xcam_destroy_context (XCam3AContext *context)
212 {
213     XCam3AAiqContext *aiq_context = AIQ_CONTEXT_CAST (context);
214     delete aiq_context;
215     return XCAM_RETURN_NO_ERROR;
216 }
217 
218 static XCamReturn
xcam_configure_3a(XCam3AContext * context,uint32_t width,uint32_t height,double framerate)219 xcam_configure_3a (XCam3AContext *context, uint32_t width, uint32_t height, double framerate)
220 {
221     XCam3AAiqContext *aiq_context = AIQ_CONTEXT_CAST (context);
222     XCamReturn ret = XCAM_RETURN_NO_ERROR;
223     struct atomisp_sensor_mode_data sensor_mode_data;
224 
225     switch ((int)framerate) {
226     case 30:
227         sensor_mode_data.coarse_integration_time_min = 1;
228         sensor_mode_data.coarse_integration_time_max_margin = 1;
229         sensor_mode_data.fine_integration_time_min = 0;
230         sensor_mode_data.fine_integration_time_max_margin = 0;
231         sensor_mode_data.fine_integration_time_def = 0;
232         sensor_mode_data.frame_length_lines = 1125;
233         sensor_mode_data.line_length_pck = 1100;
234         sensor_mode_data.read_mode = 0;
235         sensor_mode_data.vt_pix_clk_freq_mhz = 37125000;
236         sensor_mode_data.crop_horizontal_start = 0;
237         sensor_mode_data.crop_vertical_start = 0;
238         sensor_mode_data.crop_horizontal_end = 1920;
239         sensor_mode_data.crop_vertical_end = 1080;
240         sensor_mode_data.output_width = 1920;
241         sensor_mode_data.output_height = 1080;
242         sensor_mode_data.binning_factor_x = 1;
243         sensor_mode_data.binning_factor_y = 1;
244         break;
245     default:
246         sensor_mode_data.coarse_integration_time_min = 1;
247         sensor_mode_data.coarse_integration_time_max_margin = 1;
248         sensor_mode_data.fine_integration_time_min = 0;
249         sensor_mode_data.fine_integration_time_max_margin = 0;
250         sensor_mode_data.fine_integration_time_def = 0;
251         sensor_mode_data.frame_length_lines = 1125;
252         sensor_mode_data.line_length_pck = 1320;
253         sensor_mode_data.read_mode = 0;
254         sensor_mode_data.vt_pix_clk_freq_mhz = 37125000;
255         sensor_mode_data.crop_horizontal_start = 0;
256         sensor_mode_data.crop_vertical_start = 0;
257         sensor_mode_data.crop_horizontal_end = 1920;
258         sensor_mode_data.crop_vertical_end = 1080;
259         sensor_mode_data.output_width = 1920;
260         sensor_mode_data.output_height = 1080;
261         sensor_mode_data.binning_factor_x = 1;
262         sensor_mode_data.binning_factor_y = 1;
263         break;
264     }
265 
266     XCAM_ASSERT (aiq_context);
267     const char *path_cpf = getenv ("AIQ_CPF_PATH");
268     XCAM_FAIL_RETURN (
269         WARNING,
270         aiq_context->setup_analyzer (sensor_mode_data, path_cpf == NULL ? DEFAULT_AIQ_CPF_FILE : path_cpf),
271         XCAM_RETURN_ERROR_UNKNOWN,
272         "setup aiq 3a analyzer failed");
273 
274     SmartPtr<X3aAnalyzeTuner> analyzer = aiq_context->get_analyzer ();
275 
276     ret = analyzer->prepare_handlers ();
277     XCAM_FAIL_RETURN (
278         WARNING,
279         ret == XCAM_RETURN_NO_ERROR,
280         ret,
281         "analyzer(aiq3alib) prepare handlers failed");
282 
283     ret = analyzer->init (width, height, framerate);
284     XCAM_FAIL_RETURN (
285         WARNING,
286         ret == XCAM_RETURN_NO_ERROR,
287         ret,
288         "configure aiq 3a failed");
289 
290     ret = analyzer->start ();
291     XCAM_FAIL_RETURN (
292         WARNING,
293         ret == XCAM_RETURN_NO_ERROR,
294         ret,
295         "start aiq 3a failed");
296 
297     aiq_context->set_size (width, height);
298 
299     return XCAM_RETURN_NO_ERROR;
300 }
301 
302 static XCamReturn
xcam_set_3a_stats(XCam3AContext * context,XCam3AStats * stats,int64_t timestamp)303 xcam_set_3a_stats (XCam3AContext *context, XCam3AStats *stats, int64_t timestamp)
304 {
305     XCamReturn ret = XCAM_RETURN_NO_ERROR;
306     XCam3AAiqContext *aiq_context = AIQ_CONTEXT_CAST (context);
307     XCAM_ASSERT (aiq_context);
308 
309     SmartPtr<X3aAnalyzeTuner> analyzer = aiq_context->get_analyzer ();
310     XCAM_ASSERT (analyzer.ptr ());
311     XCAM_ASSERT (stats);
312 
313     if (!aiq_context->is_stats_pool_ready ()) {
314         // init statistics queue
315         XCAM_FAIL_RETURN (
316             WARNING,
317             aiq_context->setup_stats_pool (stats->info.bit_depth),
318             XCAM_RETURN_ERROR_UNKNOWN,
319             "aiq configure 3a failed on stats pool setup");
320     }
321 
322     // Convert stats to atomisp_3a_stats;
323     SmartPtr<X3aIspStatistics> isp_stats = aiq_context->get_stats_buffer ();
324     if (!isp_stats.ptr ()) {
325         XCAM_LOG_WARNING ("get stats bufffer failed or stopped");
326         return XCAM_RETURN_ERROR_MEM;
327     }
328 
329     struct atomisp_3a_statistics *raw_stats = isp_stats->get_isp_stats ();
330     XCAM_ASSERT (raw_stats);
331 
332     translate_3a_stats (stats, raw_stats);
333     isp_stats->set_timestamp (timestamp);
334 
335     ret = analyzer->push_3a_stats (isp_stats);
336     if (ret != XCAM_RETURN_NO_ERROR) {
337         XCAM_LOG_WARNING ("set 3a stats failed");
338     }
339 
340     return ret;
341 }
342 
343 static XCamReturn
xcam_update_common_params(XCam3AContext * context,XCamCommonParam * params)344 xcam_update_common_params (XCam3AContext *context, XCamCommonParam *params)
345 {
346     if (params) {
347         SmartPtr<X3aAnalyzeTuner> analyzer = get_analyzer (context);
348         XCAM_ASSERT (analyzer.ptr ());
349 
350         analyzer->update_common_parameters (*params);
351     }
352 #if 0
353     XCam3AAiqContext *aiq_context = AIQ_CONTEXT_CAST (context);
354     aiq_context->update_brightness_result(params);
355 #endif
356     return XCAM_RETURN_NO_ERROR;
357 }
358 
359 static XCamReturn
xcam_analyze_awb(XCam3AContext * context,XCamAwbParam * params)360 xcam_analyze_awb (XCam3AContext *context, XCamAwbParam *params)
361 {
362     if (params) {
363         SmartPtr<X3aAnalyzeTuner> analyzer = get_analyzer (context);
364         XCAM_ASSERT (analyzer.ptr ());
365 
366         analyzer->update_awb_parameters (*params);
367     }
368     return XCAM_RETURN_NO_ERROR;
369 }
370 
371 static XCamReturn
xcam_analyze_ae(XCam3AContext * context,XCamAeParam * params)372 xcam_analyze_ae (XCam3AContext *context, XCamAeParam *params)
373 {
374     if (params) {
375         SmartPtr<X3aAnalyzeTuner> analyzer = get_analyzer (context);
376         XCAM_ASSERT (analyzer.ptr ());
377 
378         analyzer->update_ae_parameters (*params);
379     }
380     return XCAM_RETURN_NO_ERROR;
381 }
382 
383 static XCamReturn
xcam_analyze_af(XCam3AContext * context,XCamAfParam * params)384 xcam_analyze_af (XCam3AContext *context, XCamAfParam *params)
385 {
386     if (params) {
387         SmartPtr<X3aAnalyzeTuner> analyzer = get_analyzer (context);
388         XCAM_ASSERT (analyzer.ptr ());
389 
390         analyzer->update_af_parameters (*params);
391     }
392     return XCAM_RETURN_NO_ERROR;
393 }
394 
395 static XCamReturn
xcam_combine_analyze_results(XCam3AContext * context,XCam3aResultHead * results[],uint32_t * res_count)396 xcam_combine_analyze_results (XCam3AContext *context, XCam3aResultHead *results[], uint32_t *res_count)
397 {
398     XCam3AAiqContext *aiq_context = AIQ_CONTEXT_CAST (context);
399     XCAM_ASSERT (aiq_context);
400     X3aResultList aiq_results;
401     uint32_t result_count = aiq_context->get_results (aiq_results);
402 
403     if (!result_count) {
404         *res_count = 0;
405         XCAM_LOG_DEBUG ("aiq wrapper combine with no result out");
406         return XCAM_RETURN_NO_ERROR;
407     }
408 
409     // mark as static
410     static XCam3aResultHead *res_array[XCAM_3A_MAX_RESULT_COUNT];
411     xcam_mem_clear (res_array);
412     XCAM_ASSERT (result_count < XCAM_3A_MAX_RESULT_COUNT);
413 
414     // result_count may changed
415     result_count = translate_3a_results_to_xcam (aiq_results, res_array, XCAM_3A_MAX_RESULT_COUNT);
416 
417     for (uint32_t i = 0; i < result_count; ++i) {
418         results[i] = res_array[i];
419     }
420     *res_count = result_count;
421     XCAM_ASSERT (result_count > 0);
422 
423     return XCAM_RETURN_NO_ERROR;
424 }
425 
426 static void
xcam_free_results(XCam3aResultHead * results[],uint32_t res_count)427 xcam_free_results (XCam3aResultHead *results[], uint32_t res_count)
428 {
429     for (uint32_t i = 0; i < res_count; ++i) {
430         if (results[i])
431             free_3a_result (results[i]);
432     }
433 }
434 
435 XCAM_BEGIN_DECLARE
436 
437 XCam3ADescription xcam_3a_desciption = {
438     XCAM_VERSION,
439     sizeof (XCam3ADescription),
440     xcam_create_context,
441     xcam_destroy_context,
442     xcam_configure_3a,
443     xcam_set_3a_stats,
444     xcam_update_common_params,
445     xcam_analyze_awb,
446     xcam_analyze_ae,
447     xcam_analyze_af,
448     xcam_combine_analyze_results,
449     xcam_free_results
450 };
451 
452 XCAM_END_DECLARE
453 
454