1 /* 2 * x3a_analyzer_aiq.h - 3a analyzer from AIQ 3 * 4 * Copyright (c) 2014-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 (at) intel.com> 19 */ 20 21 #include "x3a_analyzer_aiq.h" 22 #include "aiq_handler.h" 23 #include "isp_controller.h" 24 #include "xcam_cpf_reader.h" 25 #include "ia_types.h" 26 27 namespace XCam { 28 29 class CpfReader { 30 public: 31 explicit CpfReader (const char *name); 32 ~CpfReader(); 33 bool read (ia_binary_data &binary); 34 private: 35 XCAM_DEAD_COPY (CpfReader); 36 37 private: 38 XCamCpfBlob *_aiq_cpf; 39 char *_name; 40 }; 41 42 CpfReader::CpfReader (const char *name) 43 : _name (strndup(name, XCAM_MAX_STR_SIZE)) 44 { 45 _aiq_cpf = xcam_cpf_blob_new (); 46 XCAM_ASSERT (name); 47 } 48 CpfReader::~CpfReader() 49 { 50 if (_aiq_cpf) 51 xcam_cpf_blob_free (_aiq_cpf); 52 if (_name) 53 xcam_free (_name); 54 } 55 56 bool CpfReader::read (ia_binary_data &binary) 57 { 58 if (!xcam_cpf_read (_name, _aiq_cpf, NULL)) { 59 XCAM_LOG_ERROR ("parse CPF(%s) failed", XCAM_STR (_name)); 60 return false; 61 } 62 binary.data = _aiq_cpf->data; 63 binary.size = _aiq_cpf->size; 64 XCAM_LOG_INFO ("read cpf(%s) ok", XCAM_STR (_name)); 65 return true; 66 } 67 68 X3aAnalyzerAiq::X3aAnalyzerAiq (SmartPtr<IspController> &isp, const char *cpf_path) 69 : X3aAnalyzer ("X3aAnalyzerAiq") 70 , _isp (isp) 71 , _sensor_data_ready (false) 72 , _cpf_path (NULL) 73 { 74 if (cpf_path) 75 _cpf_path = strndup (cpf_path, XCAM_MAX_STR_SIZE); 76 77 _aiq_compositor = new AiqCompositor (); 78 XCAM_ASSERT (_aiq_compositor.ptr()); 79 xcam_mem_clear (_sensor_mode_data); 80 81 XCAM_LOG_DEBUG ("X3aAnalyzerAiq constructed"); 82 } 83 84 X3aAnalyzerAiq::X3aAnalyzerAiq (struct atomisp_sensor_mode_data &sensor_data, const char *cpf_path) 85 : X3aAnalyzer ("X3aAnalyzerAiq") 86 , _sensor_mode_data (sensor_data) 87 , _sensor_data_ready (true) 88 , _cpf_path (NULL) 89 { 90 if (cpf_path) 91 _cpf_path = strndup (cpf_path, XCAM_MAX_STR_SIZE); 92 93 _aiq_compositor = new AiqCompositor (); 94 XCAM_ASSERT (_aiq_compositor.ptr()); 95 96 XCAM_LOG_DEBUG ("X3aAnalyzerAiq constructed"); 97 } 98 99 X3aAnalyzerAiq::~X3aAnalyzerAiq() 100 { 101 if (_cpf_path) 102 xcam_free (_cpf_path); 103 104 XCAM_LOG_DEBUG ("~X3aAnalyzerAiq destructed"); 105 } 106 107 SmartPtr<AeHandler> 108 X3aAnalyzerAiq::create_ae_handler () 109 { 110 SmartPtr<AiqAeHandler> ae_handler = new AiqAeHandler (_aiq_compositor); 111 _aiq_compositor->set_ae_handler (ae_handler); 112 return ae_handler; 113 } 114 115 SmartPtr<AwbHandler> 116 X3aAnalyzerAiq::create_awb_handler () 117 { 118 SmartPtr<AiqAwbHandler> awb_handler = new AiqAwbHandler (_aiq_compositor); 119 _aiq_compositor->set_awb_handler (awb_handler); 120 return awb_handler; 121 } 122 123 SmartPtr<AfHandler> 124 X3aAnalyzerAiq::create_af_handler () 125 { 126 127 SmartPtr<AiqAfHandler> af_handler = new AiqAfHandler (_aiq_compositor); 128 _aiq_compositor->set_af_handler (af_handler); 129 return af_handler; 130 } 131 132 SmartPtr<CommonHandler> 133 X3aAnalyzerAiq::create_common_handler () 134 { 135 SmartPtr<AiqCommonHandler> common_handler = new AiqCommonHandler (_aiq_compositor); 136 _aiq_compositor->set_common_handler (common_handler); 137 return common_handler; 138 } 139 140 XCamReturn 141 X3aAnalyzerAiq::internal_init (uint32_t width, uint32_t height, double framerate) 142 { 143 XCAM_ASSERT (_cpf_path); 144 CpfReader reader (_cpf_path); 145 ia_binary_data binary; 146 147 XCAM_ASSERT (_aiq_compositor.ptr ()); 148 149 _aiq_compositor->set_framerate (framerate); 150 151 xcam_mem_clear (binary); 152 XCAM_FAIL_RETURN ( 153 ERROR, 154 reader.read(binary), 155 XCAM_RETURN_ERROR_AIQ, 156 "read cpf file(%s) failed", _cpf_path); 157 158 _aiq_compositor->set_size (width, height); 159 XCAM_FAIL_RETURN ( 160 ERROR, 161 _aiq_compositor->open (binary), 162 XCAM_RETURN_ERROR_AIQ, 163 "AIQ open failed"); 164 165 return XCAM_RETURN_NO_ERROR; 166 } 167 168 XCamReturn 169 X3aAnalyzerAiq::internal_deinit () 170 { 171 if (_aiq_compositor.ptr ()) 172 _aiq_compositor->close (); 173 174 return XCAM_RETURN_NO_ERROR; 175 } 176 177 XCamReturn 178 X3aAnalyzerAiq::configure_3a () 179 { 180 XCamReturn ret = XCAM_RETURN_NO_ERROR; 181 X3aResultList first_results; 182 183 if (!_sensor_data_ready) { 184 struct atomisp_sensor_mode_data sensor_mode_data; 185 xcam_mem_clear (sensor_mode_data); 186 XCAM_ASSERT (_isp.ptr()); 187 188 ret = _isp->get_sensor_mode_data (sensor_mode_data); 189 XCAM_FAIL_RETURN (WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "get sensor mode data failed"); 190 _sensor_mode_data = sensor_mode_data; 191 _sensor_data_ready = true; 192 } 193 194 if (!_aiq_compositor->set_sensor_mode_data (&_sensor_mode_data)) { 195 XCAM_LOG_WARNING ("AIQ configure 3a failed"); 196 return XCAM_RETURN_ERROR_AIQ; 197 } 198 199 XCAM_LOG_DEBUG ("X3aAnalyzerAiq got sensor mode data, coarse_time_min:%u, " 200 "coarse_time_max_margin:%u, " 201 "fine_time_min:%u, fine_time_max_margin:%u, " 202 "fine_time_def:%u, " 203 "frame_length_lines:%u, line_length_pck:%u, " 204 "vt_pix_clk_freq_mhz:%u, " 205 "crop_horizontal_start:%u, crop_vertical_start:%u, " 206 "crop_horizontal_end:%u, crop_vertical_end:%u, " 207 "output_width:%u, output_height:%u, " 208 "binning_factor_x:%u, binning_factor_y:%u", 209 _sensor_mode_data.coarse_integration_time_min, 210 _sensor_mode_data.coarse_integration_time_max_margin, 211 _sensor_mode_data.fine_integration_time_min, 212 _sensor_mode_data.fine_integration_time_max_margin, 213 _sensor_mode_data.fine_integration_time_def, 214 _sensor_mode_data.frame_length_lines, 215 _sensor_mode_data.line_length_pck, 216 _sensor_mode_data.vt_pix_clk_freq_mhz, 217 _sensor_mode_data.crop_horizontal_start, 218 _sensor_mode_data.crop_vertical_start, 219 _sensor_mode_data.crop_horizontal_end, 220 _sensor_mode_data.crop_vertical_end, 221 _sensor_mode_data.output_width, 222 _sensor_mode_data.output_height, 223 (uint32_t)_sensor_mode_data.binning_factor_x, 224 (uint32_t)_sensor_mode_data.binning_factor_y); 225 226 // initialize ae and awb 227 get_ae_handler ()->analyze (first_results); 228 get_awb_handler ()->analyze (first_results); 229 230 ret = _aiq_compositor->integrate (first_results); 231 XCAM_FAIL_RETURN (WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "AIQ configure_3a failed on integrate results"); 232 233 if (!first_results.empty()) { 234 notify_calculation_done (first_results); 235 } 236 237 return XCAM_RETURN_NO_ERROR; 238 } 239 240 XCamReturn 241 X3aAnalyzerAiq::pre_3a_analyze (SmartPtr<X3aStats> &stats) 242 { 243 SmartPtr<X3aIspStatistics> isp_stats = stats.dynamic_cast_ptr<X3aIspStatistics> (); 244 245 XCAM_ASSERT (isp_stats.ptr ()); 246 if (!_aiq_compositor->set_3a_stats (isp_stats)) { 247 XCAM_LOG_WARNING ("Aiq compositor set 3a stats failed"); 248 return XCAM_RETURN_ERROR_UNKNOWN; 249 } 250 251 return XCAM_RETURN_NO_ERROR; 252 } 253 254 XCamReturn 255 X3aAnalyzerAiq::post_3a_analyze (X3aResultList &results) 256 { 257 XCamReturn ret = XCAM_RETURN_NO_ERROR; 258 259 ret = _aiq_compositor->integrate (results); 260 XCAM_FAIL_RETURN (WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "AIQ integrate 3A results failed"); 261 262 return XCAM_RETURN_NO_ERROR; 263 } 264 265 }; 266