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 (at) 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 { 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 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 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 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 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 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> 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 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 175 HybridAnalyzer::analyze_ae (XCamAeParam ¶m) 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 184 HybridAnalyzer::analyze_awb (XCamAwbParam ¶m) 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 193 HybridAnalyzer::analyze_af (XCamAfParam ¶m) 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 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 221 HybridAnalyzer::~HybridAnalyzer () 222 { 223 destroy_context (); 224 } 225 226 void 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