234 lines
6.9 KiB
C++
Executable File
234 lines
6.9 KiB
C++
Executable File
/*
|
|
* hybrid_analyzer.h - hybrid analyzer
|
|
*
|
|
* Copyright (c) 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: Jia Meng <jia.meng@intel.com>
|
|
*/
|
|
|
|
#include "hybrid_analyzer.h"
|
|
#include "isp_controller.h"
|
|
#include "x3a_analyzer_rkiq.h"
|
|
#include "x3a_statistics_queue.h"
|
|
#include "aiq3a_utils.h"
|
|
#include <math.h>
|
|
|
|
namespace XCam {
|
|
HybridAnalyzer::HybridAnalyzer (XCam3ADescription *desc,
|
|
SmartPtr<AnalyzerLoader> &loader,
|
|
SmartPtr<IspController> &isp,
|
|
const char *cpf_path)
|
|
: DynamicAnalyzer (desc, loader, "HybridAnalyzer")
|
|
, _isp (isp)
|
|
, _cpf_path (cpf_path)
|
|
{
|
|
_analyzer_aiq = new X3aAnalyzerRKiq (isp, cpf_path);
|
|
XCAM_ASSERT (_analyzer_aiq.ptr ());
|
|
_analyzer_aiq->prepare_handlers ();
|
|
_analyzer_aiq->set_results_callback (this);
|
|
_analyzer_aiq->set_sync_mode (true);
|
|
}
|
|
|
|
XCamReturn
|
|
HybridAnalyzer::internal_init (uint32_t width, uint32_t height, double framerate)
|
|
{
|
|
if (_analyzer_aiq->init (width, height, framerate) != XCAM_RETURN_NO_ERROR) {
|
|
return XCAM_RETURN_ERROR_AIQ;
|
|
}
|
|
|
|
return create_context ();
|
|
}
|
|
|
|
XCamReturn
|
|
HybridAnalyzer::internal_deinit ()
|
|
{
|
|
if (_analyzer_aiq->deinit () != XCAM_RETURN_NO_ERROR) {
|
|
return XCAM_RETURN_ERROR_AIQ;
|
|
}
|
|
|
|
return DynamicAnalyzer::internal_deinit ();
|
|
}
|
|
|
|
XCamReturn
|
|
HybridAnalyzer::setup_stats_pool (const XCam3AStats *stats)
|
|
{
|
|
XCAM_ASSERT (stats);
|
|
|
|
XCam3AStatsInfo stats_info = stats->info;
|
|
struct rkisp_grid_info grid_info;
|
|
grid_info.enable = 1;
|
|
grid_info.use_dmem = 0;
|
|
grid_info.has_histogram = 0;
|
|
grid_info.width = stats_info.width;
|
|
grid_info.height = stats_info.height;
|
|
grid_info.aligned_width = stats_info.aligned_width;
|
|
grid_info.aligned_height = stats_info.aligned_height;
|
|
grid_info.bqs_per_grid_cell = stats_info.grid_pixel_size >> 1;
|
|
grid_info.deci_factor_log2 = log2 (grid_info.bqs_per_grid_cell);
|
|
grid_info.elem_bit_depth = stats_info.bit_depth;
|
|
|
|
SmartPtr<X3aStatisticsQueue> stats_pool = new X3aStatisticsQueue;
|
|
XCAM_ASSERT (stats_pool.ptr ());
|
|
_stats_pool = stats_pool;
|
|
|
|
_stats_pool->set_grid_info (grid_info);
|
|
if (!_stats_pool->reserve (6)) {
|
|
XCAM_LOG_WARNING ("setup_stats_pool failed to reserve stats buffer.");
|
|
return XCAM_RETURN_ERROR_MEM;
|
|
}
|
|
|
|
return XCAM_RETURN_NO_ERROR;
|
|
}
|
|
|
|
XCamReturn
|
|
HybridAnalyzer::configure_3a ()
|
|
{
|
|
if (_analyzer_aiq->start () != XCAM_RETURN_NO_ERROR) {
|
|
return XCAM_RETURN_ERROR_AIQ;
|
|
}
|
|
|
|
return DynamicAnalyzer::configure_3a ();
|
|
}
|
|
|
|
XCamReturn
|
|
HybridAnalyzer::pre_3a_analyze (SmartPtr<X3aStats> &stats)
|
|
{
|
|
_analyzer_aiq->update_common_parameters (get_common_params ());
|
|
|
|
return DynamicAnalyzer::pre_3a_analyze (stats);
|
|
}
|
|
|
|
SmartPtr<X3aIspStatistics>
|
|
HybridAnalyzer::convert_to_isp_stats (SmartPtr<X3aStats>& stats)
|
|
{
|
|
SmartPtr<X3aIspStatistics> isp_stats =
|
|
_stats_pool->get_buffer (_stats_pool).dynamic_cast_ptr<X3aIspStatistics> ();
|
|
|
|
XCAM_FAIL_RETURN (
|
|
WARNING,
|
|
isp_stats.ptr (),
|
|
NULL,
|
|
"get isp stats buffer failed");
|
|
|
|
struct cifisp_stat_buffer *to = (struct cifisp_stat_buffer*)isp_stats->get_isp_stats ();
|
|
XCam3AStats *from = stats->get_stats ();
|
|
translate_3a_stats (from, to);
|
|
isp_stats->set_timestamp (stats->get_timestamp ());
|
|
return isp_stats;
|
|
}
|
|
|
|
XCamReturn
|
|
HybridAnalyzer::post_3a_analyze (X3aResultList &results)
|
|
{
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
SmartPtr<X3aStats> stats = get_cur_stats ();
|
|
|
|
if ((ret = DynamicAnalyzer::post_3a_analyze (results)) != XCAM_RETURN_NO_ERROR) {
|
|
return ret;
|
|
}
|
|
|
|
for (X3aResultList::iterator i_res = results.begin ();
|
|
i_res != results.end (); ++i_res) {
|
|
SmartPtr<X3aResult> result = *i_res;
|
|
|
|
switch (result->get_type ()) {
|
|
case XCAM_3A_RESULT_EXPOSURE: {
|
|
XCam3aResultExposure *res = (XCam3aResultExposure *) result->get_ptr ();
|
|
_analyzer_aiq->set_ae_mode (XCAM_AE_MODE_MANUAL);
|
|
_analyzer_aiq->set_ae_manual_exposure_time (res->exposure_time);
|
|
_analyzer_aiq->set_ae_manual_analog_gain (res->analog_gain);
|
|
break;
|
|
}
|
|
case XCAM_3A_RESULT_WHITE_BALANCE: {
|
|
_analyzer_aiq->set_awb_mode (XCAM_AWB_MODE_MANUAL);
|
|
XCam3aResultWhiteBalance *res = (XCam3aResultWhiteBalance *) result->get_ptr ();
|
|
_analyzer_aiq->set_awb_manual_gain (res->gr_gain, res->r_gain, res->b_gain, res->gb_gain);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
results.clear ();
|
|
|
|
SmartPtr<X3aIspStatistics> isp_stats = stats.dynamic_cast_ptr<X3aIspStatistics> ();
|
|
if (!isp_stats.ptr ()) {
|
|
if (!_stats_pool.ptr () && setup_stats_pool (stats->get_stats ()) != XCAM_RETURN_NO_ERROR)
|
|
return XCAM_RETURN_ERROR_MEM;
|
|
isp_stats = convert_to_isp_stats (stats);
|
|
}
|
|
return _analyzer_aiq->push_3a_stats (isp_stats);
|
|
}
|
|
|
|
XCamReturn
|
|
HybridAnalyzer::analyze_ae (XCamAeParam ¶m)
|
|
{
|
|
if (!_analyzer_aiq->update_ae_parameters (param))
|
|
return XCAM_RETURN_ERROR_AIQ;
|
|
|
|
return DynamicAnalyzer::analyze_ae (param);
|
|
}
|
|
|
|
XCamReturn
|
|
HybridAnalyzer::analyze_awb (XCamAwbParam ¶m)
|
|
{
|
|
if (!_analyzer_aiq->update_awb_parameters (param))
|
|
return XCAM_RETURN_ERROR_AIQ;
|
|
|
|
return DynamicAnalyzer::analyze_awb (param);
|
|
}
|
|
|
|
XCamReturn
|
|
HybridAnalyzer::analyze_af (XCamAfParam ¶m)
|
|
{
|
|
if (!_analyzer_aiq->update_af_parameters (param))
|
|
return XCAM_RETURN_ERROR_AIQ;
|
|
|
|
return DynamicAnalyzer::analyze_af (param);
|
|
}
|
|
|
|
void
|
|
HybridAnalyzer::x3a_calculation_done (XAnalyzer *analyzer, X3aResultList &results)
|
|
{
|
|
XCAM_UNUSED (analyzer);
|
|
|
|
static XCam3aResultHead *res_heads[XCAM_3A_MAX_RESULT_COUNT];
|
|
xcam_mem_clear (res_heads);
|
|
XCAM_ASSERT (results.size () < XCAM_3A_MAX_RESULT_COUNT);
|
|
|
|
uint32_t result_count = translate_3a_results_to_xcam (results,
|
|
res_heads, XCAM_3A_MAX_RESULT_COUNT);
|
|
convert_results (res_heads, result_count, results);
|
|
for (uint32_t i = 0; i < result_count; ++i) {
|
|
if (res_heads[i])
|
|
free_3a_result (res_heads[i]);
|
|
}
|
|
|
|
notify_calculation_done (results);
|
|
}
|
|
|
|
HybridAnalyzer::~HybridAnalyzer ()
|
|
{
|
|
destroy_context ();
|
|
}
|
|
|
|
void
|
|
HybridAnalyzer::x3a_calculation_failed (XAnalyzer *analyzer, int64_t timestamp, const char *msg)
|
|
{
|
|
XCAM_UNUSED (analyzer);
|
|
notify_calculation_failed (NULL, timestamp, msg);
|
|
}
|
|
}
|