Home | History | Annotate | Download | only in isp
      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 &param)
    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 &param)
    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 &param)
    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