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