/* * x3a_analyzer_aiq.h - 3a analyzer from AIQ * * Copyright (c) 2014-2015 Intel Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Author: Wind Yuan <feng.yuan@intel.com> */ #include "x3a_analyzer_aiq.h" #include "aiq_handler.h" #include "isp_controller.h" #include "xcam_cpf_reader.h" #include "ia_types.h" namespace XCam { class CpfReader { public: explicit CpfReader (const char *name); ~CpfReader(); bool read (ia_binary_data &binary); private: XCAM_DEAD_COPY (CpfReader); private: XCamCpfBlob *_aiq_cpf; char *_name; }; CpfReader::CpfReader (const char *name) : _name (strndup(name, XCAM_MAX_STR_SIZE)) { _aiq_cpf = xcam_cpf_blob_new (); XCAM_ASSERT (name); } CpfReader::~CpfReader() { if (_aiq_cpf) xcam_cpf_blob_free (_aiq_cpf); if (_name) xcam_free (_name); } bool CpfReader::read (ia_binary_data &binary) { if (!xcam_cpf_read (_name, _aiq_cpf, NULL)) { XCAM_LOG_ERROR ("parse CPF(%s) failed", XCAM_STR (_name)); return false; } binary.data = _aiq_cpf->data; binary.size = _aiq_cpf->size; XCAM_LOG_INFO ("read cpf(%s) ok", XCAM_STR (_name)); return true; } X3aAnalyzerAiq::X3aAnalyzerAiq (SmartPtr<IspController> &isp, const char *cpf_path) : X3aAnalyzer ("X3aAnalyzerAiq") , _isp (isp) , _sensor_data_ready (false) , _cpf_path (NULL) { if (cpf_path) _cpf_path = strndup (cpf_path, XCAM_MAX_STR_SIZE); _aiq_compositor = new AiqCompositor (); XCAM_ASSERT (_aiq_compositor.ptr()); xcam_mem_clear (_sensor_mode_data); XCAM_LOG_DEBUG ("X3aAnalyzerAiq constructed"); } X3aAnalyzerAiq::X3aAnalyzerAiq (struct atomisp_sensor_mode_data &sensor_data, const char *cpf_path) : X3aAnalyzer ("X3aAnalyzerAiq") , _sensor_mode_data (sensor_data) , _sensor_data_ready (true) , _cpf_path (NULL) { if (cpf_path) _cpf_path = strndup (cpf_path, XCAM_MAX_STR_SIZE); _aiq_compositor = new AiqCompositor (); XCAM_ASSERT (_aiq_compositor.ptr()); XCAM_LOG_DEBUG ("X3aAnalyzerAiq constructed"); } X3aAnalyzerAiq::~X3aAnalyzerAiq() { if (_cpf_path) xcam_free (_cpf_path); XCAM_LOG_DEBUG ("~X3aAnalyzerAiq destructed"); } SmartPtr<AeHandler> X3aAnalyzerAiq::create_ae_handler () { SmartPtr<AiqAeHandler> ae_handler = new AiqAeHandler (_aiq_compositor); _aiq_compositor->set_ae_handler (ae_handler); return ae_handler; } SmartPtr<AwbHandler> X3aAnalyzerAiq::create_awb_handler () { SmartPtr<AiqAwbHandler> awb_handler = new AiqAwbHandler (_aiq_compositor); _aiq_compositor->set_awb_handler (awb_handler); return awb_handler; } SmartPtr<AfHandler> X3aAnalyzerAiq::create_af_handler () { SmartPtr<AiqAfHandler> af_handler = new AiqAfHandler (_aiq_compositor); _aiq_compositor->set_af_handler (af_handler); return af_handler; } SmartPtr<CommonHandler> X3aAnalyzerAiq::create_common_handler () { SmartPtr<AiqCommonHandler> common_handler = new AiqCommonHandler (_aiq_compositor); _aiq_compositor->set_common_handler (common_handler); return common_handler; } XCamReturn X3aAnalyzerAiq::internal_init (uint32_t width, uint32_t height, double framerate) { XCAM_ASSERT (_cpf_path); CpfReader reader (_cpf_path); ia_binary_data binary; XCAM_ASSERT (_aiq_compositor.ptr ()); _aiq_compositor->set_framerate (framerate); xcam_mem_clear (binary); XCAM_FAIL_RETURN ( ERROR, reader.read(binary), XCAM_RETURN_ERROR_AIQ, "read cpf file(%s) failed", _cpf_path); _aiq_compositor->set_size (width, height); XCAM_FAIL_RETURN ( ERROR, _aiq_compositor->open (binary), XCAM_RETURN_ERROR_AIQ, "AIQ open failed"); return XCAM_RETURN_NO_ERROR; } XCamReturn X3aAnalyzerAiq::internal_deinit () { if (_aiq_compositor.ptr ()) _aiq_compositor->close (); return XCAM_RETURN_NO_ERROR; } XCamReturn X3aAnalyzerAiq::configure_3a () { XCamReturn ret = XCAM_RETURN_NO_ERROR; X3aResultList first_results; if (!_sensor_data_ready) { struct atomisp_sensor_mode_data sensor_mode_data; xcam_mem_clear (sensor_mode_data); XCAM_ASSERT (_isp.ptr()); ret = _isp->get_sensor_mode_data (sensor_mode_data); XCAM_FAIL_RETURN (WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "get sensor mode data failed"); _sensor_mode_data = sensor_mode_data; _sensor_data_ready = true; } if (!_aiq_compositor->set_sensor_mode_data (&_sensor_mode_data)) { XCAM_LOG_WARNING ("AIQ configure 3a failed"); return XCAM_RETURN_ERROR_AIQ; } XCAM_LOG_DEBUG ("X3aAnalyzerAiq got sensor mode data, coarse_time_min:%u, " "coarse_time_max_margin:%u, " "fine_time_min:%u, fine_time_max_margin:%u, " "fine_time_def:%u, " "frame_length_lines:%u, line_length_pck:%u, " "vt_pix_clk_freq_mhz:%u, " "crop_horizontal_start:%u, crop_vertical_start:%u, " "crop_horizontal_end:%u, crop_vertical_end:%u, " "output_width:%u, output_height:%u, " "binning_factor_x:%u, binning_factor_y:%u", _sensor_mode_data.coarse_integration_time_min, _sensor_mode_data.coarse_integration_time_max_margin, _sensor_mode_data.fine_integration_time_min, _sensor_mode_data.fine_integration_time_max_margin, _sensor_mode_data.fine_integration_time_def, _sensor_mode_data.frame_length_lines, _sensor_mode_data.line_length_pck, _sensor_mode_data.vt_pix_clk_freq_mhz, _sensor_mode_data.crop_horizontal_start, _sensor_mode_data.crop_vertical_start, _sensor_mode_data.crop_horizontal_end, _sensor_mode_data.crop_vertical_end, _sensor_mode_data.output_width, _sensor_mode_data.output_height, (uint32_t)_sensor_mode_data.binning_factor_x, (uint32_t)_sensor_mode_data.binning_factor_y); // initialize ae and awb get_ae_handler ()->analyze (first_results); get_awb_handler ()->analyze (first_results); ret = _aiq_compositor->integrate (first_results); XCAM_FAIL_RETURN (WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "AIQ configure_3a failed on integrate results"); if (!first_results.empty()) { notify_calculation_done (first_results); } return XCAM_RETURN_NO_ERROR; } XCamReturn X3aAnalyzerAiq::pre_3a_analyze (SmartPtr<X3aStats> &stats) { SmartPtr<X3aIspStatistics> isp_stats = stats.dynamic_cast_ptr<X3aIspStatistics> (); XCAM_ASSERT (isp_stats.ptr ()); if (!_aiq_compositor->set_3a_stats (isp_stats)) { XCAM_LOG_WARNING ("Aiq compositor set 3a stats failed"); return XCAM_RETURN_ERROR_UNKNOWN; } return XCAM_RETURN_NO_ERROR; } XCamReturn X3aAnalyzerAiq::post_3a_analyze (X3aResultList &results) { XCamReturn ret = XCAM_RETURN_NO_ERROR; ret = _aiq_compositor->integrate (results); XCAM_FAIL_RETURN (WARNING, ret == XCAM_RETURN_NO_ERROR, ret, "AIQ integrate 3A results failed"); return XCAM_RETURN_NO_ERROR; } };