/*
|
* Copyright (c) 2019 Rockchip 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.
|
*
|
*/
|
|
#include "rk_aiq_user_api_sysctl.h"
|
#include "rk_aiq_api_private.h"
|
#include "RkAiqManager.h"
|
#include "socket_server.h"
|
#include "RkAiqCalibDbV2.h"
|
#include "scene/scene_manager.h"
|
#ifdef RK_SIMULATOR_HW
|
#include "simulator/CamHwSimulator.h"
|
#else
|
#include "isp20/CamHwIsp20.h"
|
//#include "fakecamera/FakeCamHwIsp20.h"
|
#include "isp20/Isp20_module_dbg.h"
|
#include "isp21/CamHwIsp21.h"
|
#endif
|
|
using namespace RkCam;
|
using namespace XCam;
|
|
typedef enum {
|
CTX_TYPE_USER_MAIN = 0,
|
CTX_TYPE_TOOL_SERVER = 1,
|
CTX_TYPE_NULL = -255,
|
} rk_aiq_ctx_type_e;
|
|
typedef struct rk_aiq_sys_ctx_s {
|
const char* _sensor_entity_name;
|
SmartPtr<RkAiqManager> _rkAiqManager;
|
SmartPtr<ICamHw> _camHw;
|
SmartPtr<RkAiqCore> _analyzer;
|
SmartPtr<RkLumaCore> _lumaAnalyzer;
|
CamCalibDbContext_t *_calibDb;
|
int _isp_hw_ver;
|
|
SocketServer * _socket;
|
SmartPtr<Mutex> _apiMutex;
|
CamCalibDbProj_t* _calibDbProj;
|
|
rk_aiq_ctx_type_e ctx_type;
|
rk_aiq_sys_ctx_t* next_ctx;
|
} rk_aiq_sys_ctx_t;
|
|
#define RKAIQSYS_CHECK_RET(cond, ret, format, ...) \
|
if ((cond)) { \
|
LOGE(format, ##__VA_ARGS__); \
|
return ret; \
|
}
|
|
#define RKAIQ_DEFAULT_IQ_PATH "/etc/iqfiles/"
|
|
RKAIQ_BEGIN_DECLARE
|
|
int g_rkaiq_isp_hw_ver = 0;
|
|
#define RKAIQ_API_SMART_LOCK(ctx) \
|
SmartLock lock (*ctx->_apiMutex.ptr());
|
|
rk_aiq_sys_ctx_t* get_next_ctx(const rk_aiq_sys_ctx_t* ctx)
|
{
|
return ctx->next_ctx;
|
}
|
|
void rk_aiq_ctx_set_tool_mode(const rk_aiq_sys_ctx_t* ctx, bool status)
|
{
|
if(ctx && ctx->_socket) {
|
ctx->_socket->tool_mode_set(status);
|
}
|
}
|
|
bool is_ctx_need_bypass(const rk_aiq_sys_ctx_t* ctx)
|
{
|
if(ctx && ctx->_socket) {
|
if (ctx->_socket->is_connected()) {
|
if (ctx->ctx_type != CTX_TYPE_TOOL_SERVER) {
|
return true;
|
}
|
}
|
}
|
return false;
|
}
|
|
|
typedef struct rk_aiq_sys_preinit_cfg_s {
|
rk_aiq_working_mode_t mode;
|
std::string force_iq_file;
|
} rk_aiq_sys_preinit_cfg_t;
|
|
static std::map<std::string, rk_aiq_sys_preinit_cfg_t> g_rk_aiq_sys_preinit_cfg_map;
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_preInit(const char* sns_ent_name,
|
rk_aiq_working_mode_t mode,
|
const char* force_iq_file)
|
{
|
std::string sns_ent_name_str(sns_ent_name);
|
rk_aiq_sys_preinit_cfg_t cfg;
|
|
cfg.mode = mode;
|
if (force_iq_file)
|
cfg.force_iq_file = force_iq_file;
|
g_rk_aiq_sys_preinit_cfg_map[sns_ent_name_str] = cfg;
|
|
return XCAM_RETURN_NO_ERROR;
|
}
|
|
static void
|
rk_aiq_uapi_sysctl_deinit_locked(rk_aiq_sys_ctx_t* ctx);
|
|
rk_aiq_sys_ctx_t*
|
rk_aiq_uapi_sysctl_init(const char* sns_ent_name,
|
const char* config_file_dir,
|
rk_aiq_error_cb err_cb,
|
rk_aiq_metas_cb metas_cb)
|
{
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
ENTER_XCORE_FUNCTION();
|
char config_file[256];
|
|
XCAM_ASSERT(sns_ent_name);
|
|
bool is_ent_name = true;
|
if (sns_ent_name[0] != 'm' || sns_ent_name[3] != '_')
|
is_ent_name = false;
|
|
if (!is_ent_name) {
|
if (config_file_dir && (strlen(config_file_dir) > 0))
|
sprintf(config_file, "%s/%s.xml", config_file_dir, sns_ent_name);
|
else
|
sprintf(config_file, "%s/%s.xml", RKAIQ_DEFAULT_IQ_PATH, sns_ent_name);
|
}
|
rk_aiq_sys_ctx_t* ctx = new rk_aiq_sys_ctx_t();
|
RKAIQSYS_CHECK_RET(!ctx, NULL, "malloc main ctx error !");
|
|
ctx->_apiMutex = new Mutex();
|
RKAIQ_API_SMART_LOCK(ctx);
|
|
ctx->_sensor_entity_name = strndup(sns_ent_name, 128);
|
RKAIQSYS_CHECK_RET(!ctx->_sensor_entity_name, NULL, "dup sensor name error !");
|
|
ctx->_rkAiqManager = new RkAiqManager(ctx->_sensor_entity_name,
|
err_cb,
|
metas_cb);
|
rk_aiq_static_info_t* s_info = CamHwIsp20::getStaticCamHwInfo(sns_ent_name);
|
#ifdef RK_SIMULATOR_HW
|
ctx->_camHw = new CamHwSimulator();
|
#else
|
if (0 == strcmp(sns_ent_name, "FakeCamera")) {
|
//ctx->_camHw = new FakeCamHwIsp20();
|
} else {
|
if (s_info->isp_hw_ver == 4)
|
ctx->_camHw = new CamHwIsp20();
|
else if (s_info->isp_hw_ver == 5)
|
ctx->_camHw = new CamHwIsp21();
|
else {
|
LOGE("do not support this isp hw version %d !", s_info->isp_hw_ver);
|
goto error;
|
}
|
}
|
|
// use user defined iq file
|
{
|
std::map<std::string, rk_aiq_sys_preinit_cfg_t>::iterator it =
|
g_rk_aiq_sys_preinit_cfg_map.find(std::string(ctx->_sensor_entity_name));
|
int user_hdr_mode = -1;
|
bool user_spec_iq = false;
|
if (it != g_rk_aiq_sys_preinit_cfg_map.end()) {
|
if (!it->second.force_iq_file.empty()) {
|
sprintf(config_file, "%s/%s", config_file_dir, it->second.force_iq_file.c_str());
|
LOGI("use user sepcified iq file %s", config_file);
|
user_spec_iq = true;
|
} else {
|
user_hdr_mode = it->second.mode;
|
LOGI("selected by user sepcified hdr mode %d", user_hdr_mode);
|
}
|
}
|
|
// use auto selected iq file
|
if (is_ent_name && !user_spec_iq) {
|
char iq_file[128] = {'\0'};
|
CamHwIsp20::selectIqFile(sns_ent_name, iq_file);
|
|
char* hdr_mode = getenv("HDR_MODE");
|
int start = strlen(iq_file) - strlen(".xml");
|
|
if (user_hdr_mode != -1) {
|
iq_file[start] = '\0';
|
if (user_hdr_mode == RK_AIQ_WORKING_MODE_ISP_HDR3)
|
strcat(iq_file, "-hdr3.xml");
|
else
|
strcat(iq_file, "_normal.xml");
|
} else if (hdr_mode) {
|
iq_file[start] = '\0';
|
if (strstr(hdr_mode, "32"))
|
strcat(iq_file, "-hdr3.xml");
|
else
|
strcat(iq_file, "_normal.xml");
|
}
|
|
if (config_file_dir) {
|
sprintf(config_file, "%s/%s", config_file_dir, iq_file);
|
} else {
|
sprintf(config_file, "%s/%s", RKAIQ_DEFAULT_IQ_PATH, iq_file);
|
}
|
|
// use default iq file
|
if (hdr_mode && access(config_file, F_OK)) {
|
LOGW("%s not exist, will use the default !", config_file);
|
if (strstr(hdr_mode, "32"))
|
start = strlen(config_file) - strlen("-hdr3.xml");
|
else
|
start = strlen(config_file) - strlen("_normal.xml");
|
config_file[start] = '\0';
|
strcat(config_file, ".xml");
|
}
|
LOGI("use iq file %s", config_file);
|
}
|
}
|
#endif
|
ctx->_rkAiqManager->setCamHw(ctx->_camHw);
|
if (s_info->isp_hw_ver == 4)
|
ctx->_analyzer = new RkAiqCore();
|
else if (s_info->isp_hw_ver == 5)
|
ctx->_analyzer = new RkAiqCoreV21();
|
|
if (is_ent_name && config_file_dir) {
|
ctx->_analyzer->setResrcPath(config_file_dir);
|
} else
|
ctx->_analyzer->setResrcPath(RKAIQ_DEFAULT_IQ_PATH);
|
ctx->_rkAiqManager->setAnalyzer(ctx->_analyzer);
|
ctx->_lumaAnalyzer = new RkLumaCore();
|
ctx->_rkAiqManager->setLumaAnalyzer(ctx->_lumaAnalyzer);
|
//ctx->_calibDb = RkAiqCalibDb::createCalibDb(config_file);
|
ctx->_socket = new SocketServer();
|
//if (!ctx->_calibDb)
|
// goto error;
|
//ctx->_rkAiqManager->setAiqCalibDb(ctx->_calibDb);
|
|
//TODO: should not assume that the suffix of "config_file" has ".xml",
|
// if the suffix is ".json", there will be error.
|
strcpy(config_file + strlen(config_file) - strlen(".xml"), ".json");
|
|
CamCalibDbV2Context_t calibdbv2_ctx;
|
|
ctx->_calibDbProj = RkAiqCalibDbV2::createCalibDbProj(config_file);
|
if (!ctx->_calibDbProj)
|
goto error;
|
|
calibdbv2_ctx =
|
RkAiqCalibDbV2::toDefaultCalibDb(ctx->_calibDbProj);
|
ctx->_rkAiqManager->setAiqCalibDb(&calibdbv2_ctx);
|
|
ret = ctx->_rkAiqManager->init();
|
ctx->_socket->Process(ctx);
|
if (ret)
|
goto error;
|
|
ctx->ctx_type = CTX_TYPE_USER_MAIN;
|
ctx->next_ctx = new rk_aiq_sys_ctx_t();
|
RKAIQSYS_CHECK_RET(!ctx, NULL, "malloc toolserver ctx error !");
|
*(ctx->next_ctx) = *ctx;
|
ctx->next_ctx->ctx_type = CTX_TYPE_TOOL_SERVER;
|
ctx->next_ctx->next_ctx = NULL;
|
|
EXIT_XCORE_FUNCTION();
|
|
return ctx;
|
|
error:
|
LOGE("_rkAiqManager init error!");
|
rk_aiq_uapi_sysctl_deinit_locked(ctx);
|
return NULL;
|
}
|
|
void
|
rk_aiq_uapi_sysctl_deinit_locked(rk_aiq_sys_ctx_t* ctx)
|
{
|
std::map<std::string, rk_aiq_sys_preinit_cfg_t>::iterator it =
|
g_rk_aiq_sys_preinit_cfg_map.find(std::string(ctx->_sensor_entity_name));
|
if (it != g_rk_aiq_sys_preinit_cfg_map.end()) {
|
g_rk_aiq_sys_preinit_cfg_map.erase(it);
|
LOGI("unset user specific iq file.");
|
}
|
|
if (ctx->_rkAiqManager.ptr())
|
ctx->_rkAiqManager->deInit();
|
|
ctx->_socket->Deinit();
|
delete(ctx->_socket);
|
ctx->_analyzer.release();
|
ctx->_lumaAnalyzer.release();
|
ctx->_rkAiqManager.release();
|
ctx->_camHw.release();
|
if (ctx->_calibDbProj) {
|
// TODO:public common resource release
|
}
|
|
if (ctx->next_ctx) {
|
delete ctx->next_ctx;
|
}
|
|
if (ctx->_sensor_entity_name)
|
xcam_free((void*)(ctx->_sensor_entity_name));
|
}
|
|
void
|
rk_aiq_uapi_sysctl_deinit(rk_aiq_sys_ctx_t* ctx)
|
{
|
ENTER_XCORE_FUNCTION();
|
{
|
RKAIQ_API_SMART_LOCK(ctx);
|
rk_aiq_uapi_sysctl_deinit_locked(ctx);
|
}
|
delete ctx;
|
EXIT_XCORE_FUNCTION();
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_prepare(const rk_aiq_sys_ctx_t* ctx,
|
uint32_t width, uint32_t height,
|
rk_aiq_working_mode_t mode)
|
{
|
ENTER_XCORE_FUNCTION();
|
RKAIQ_API_SMART_LOCK(ctx);
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
ret = ctx->_rkAiqManager->prepare(width, height, mode);
|
RKAIQSYS_CHECK_RET(ret, ret, "prepare failed !");
|
|
EXIT_XCORE_FUNCTION();
|
|
return ret;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_start(const rk_aiq_sys_ctx_t* ctx)
|
{
|
ENTER_XCORE_FUNCTION();
|
RKAIQ_API_SMART_LOCK(ctx);
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
ret = ctx->_rkAiqManager->start();
|
|
EXIT_XCORE_FUNCTION();
|
|
return ret;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_stop(const rk_aiq_sys_ctx_t* ctx, bool keep_ext_hw_st)
|
{
|
ENTER_XCORE_FUNCTION();
|
RKAIQ_API_SMART_LOCK(ctx);
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
ret = ctx->_rkAiqManager->stop(keep_ext_hw_st);
|
|
EXIT_XCORE_FUNCTION();
|
|
return ret;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_getStaticMetas(const char* sns_ent_name, rk_aiq_static_info_t* static_info)
|
{
|
if (!sns_ent_name || !static_info)
|
return XCAM_RETURN_ERROR_FAILED;
|
#ifdef RK_SIMULATOR_HW
|
/* nothing to do now*/
|
static_info = NULL;
|
#else
|
memcpy(static_info, CamHwIsp20::getStaticCamHwInfo(sns_ent_name), sizeof(rk_aiq_static_info_t));
|
#endif
|
return XCAM_RETURN_NO_ERROR;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_enumStaticMetas(int index, rk_aiq_static_info_t* static_info)
|
{
|
if (!static_info)
|
return XCAM_RETURN_ERROR_FAILED;
|
#ifdef RK_SIMULATOR_HW
|
/* nothing to do now*/
|
static_info = NULL;
|
#else
|
rk_aiq_static_info_t* tmp = CamHwIsp20::getStaticCamHwInfo(NULL, index);
|
if (tmp)
|
memcpy(static_info, tmp, sizeof(rk_aiq_static_info_t));
|
else
|
return XCAM_RETURN_ERROR_OUTOFRANGE;
|
#endif
|
return XCAM_RETURN_NO_ERROR;
|
}
|
|
const char*
|
rk_aiq_uapi_sysctl_getBindedSnsEntNmByVd(const char* vd)
|
{
|
#ifndef RK_SIMULATOR_HW
|
return CamHwIsp20::getBindedSnsEntNmByVd(vd);
|
#endif
|
return NULL;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_getMetaData(const rk_aiq_sys_ctx_t* ctx, uint32_t frame_id, rk_aiq_metas_t* metas)
|
{
|
// TODO
|
return XCAM_RETURN_ERROR_FAILED;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_regLib(const rk_aiq_sys_ctx_t* ctx,
|
RkAiqAlgoDesComm* algo_lib_des)
|
{
|
RKAIQ_API_SMART_LOCK(ctx);
|
return ctx->_analyzer->addAlgo(*algo_lib_des);
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_unRegLib(const rk_aiq_sys_ctx_t* ctx,
|
const int algo_type,
|
const int lib_id)
|
{
|
RKAIQ_API_SMART_LOCK(ctx);
|
return ctx->_analyzer->rmAlgo(algo_type, lib_id);
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_enableAxlib(const rk_aiq_sys_ctx_t* ctx,
|
const int algo_type,
|
const int lib_id,
|
bool enable)
|
{
|
RKAIQ_API_SMART_LOCK(ctx);
|
return ctx->_analyzer->enableAlgo(algo_type, lib_id, enable);
|
}
|
|
bool
|
rk_aiq_uapi_sysctl_getAxlibStatus(const rk_aiq_sys_ctx_t* ctx,
|
const int algo_type,
|
const int lib_id)
|
{
|
RKAIQ_API_SMART_LOCK(ctx);
|
return ctx->_analyzer->getAxlibStatus(algo_type, lib_id);
|
}
|
|
const RkAiqAlgoContext*
|
rk_aiq_uapi_sysctl_getEnabledAxlibCtx(const rk_aiq_sys_ctx_t* ctx, const int algo_type)
|
{
|
RKAIQ_API_SMART_LOCK(ctx);
|
if (ctx->_analyzer.ptr() == NULL) {
|
return NULL;
|
}
|
return ctx->_analyzer->getEnabledAxlibCtx(algo_type);
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_get3AStats(const rk_aiq_sys_ctx_t* ctx,
|
rk_aiq_isp_stats_t *stats)
|
{
|
RKAIQ_API_SMART_LOCK(ctx);
|
return ctx->_analyzer->get3AStatsFromCachedList(*stats);
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_get3AStatsBlk(const rk_aiq_sys_ctx_t* ctx,
|
rk_aiq_isp_stats_t **stats, int timeout_ms)
|
{
|
// blocked API, add lock ?
|
//RKAIQ_API_SMART_LOCK(ctx);
|
return ctx->_analyzer->get3AStatsFromCachedList(stats, timeout_ms);
|
}
|
|
void
|
rk_aiq_uapi_sysctl_release3AStatsRef(const rk_aiq_sys_ctx_t* ctx,
|
rk_aiq_isp_stats_t *stats)
|
{
|
RKAIQ_API_SMART_LOCK(ctx);
|
ctx->_analyzer->release3AStatsRef(stats);
|
}
|
|
RKAIQ_END_DECLARE
|
|
template<typename T> static T*
|
algoHandle(const rk_aiq_sys_ctx_t* ctx, const int algo_type)
|
{
|
T* algo_handle = NULL;
|
|
RkCam::RkAiqHandle* handle =
|
const_cast<RkCam::RkAiqHandle*>(ctx->_analyzer->getAiqAlgoHandle(algo_type));
|
|
XCAM_ASSERT(handle);
|
|
int algo_id = handle->getAlgoId();
|
|
if (algo_id == 0)
|
algo_handle = dynamic_cast<T*>(handle);
|
|
return algo_handle;
|
}
|
|
#include "RkAiqVersion.h"
|
#include "RkAiqCalibVersion.h"
|
#include "rk_aiq_user_api_awb.cpp"
|
#include "rk_aiq_user_api_adebayer.cpp"
|
#include "rk_aiq_user_api2_adebayer.cpp"
|
#include "rk_aiq_user_api_ahdr.cpp"
|
#include "uAPI2/rk_aiq_user_api2_amerge.cpp"
|
#include "uAPI2/rk_aiq_user_api2_atmo.cpp"
|
#include "uAPI2/rk_aiq_user_api2_adrc.cpp"
|
#include "rk_aiq_user_api_alsc.cpp"
|
#include "rk_aiq_user_api_accm.cpp"
|
#include "rk_aiq_user_api_a3dlut.cpp"
|
#include "rk_aiq_user_api_adehaze.cpp"
|
#include "uAPI2/rk_aiq_user_api2_adehaze.cpp"
|
#include "uAPI2/rk_aiq_user_api2_adpcc.cpp"
|
#include "rk_aiq_user_api_agamma.cpp"
|
#include "uAPI2/rk_aiq_user_api2_agamma.cpp"
|
#include "uAPI2/rk_aiq_user_api2_adegamma.cpp"
|
#include "uAPI2/rk_aiq_user_api2_ablc.cpp"
|
#include "rk_aiq_user_api_adpcc.cpp"
|
#include "rk_aiq_user_api_ae.cpp"
|
#include "uAPI2/rk_aiq_user_api2_ae.cpp"
|
#include "rk_aiq_user_api_anr.cpp"
|
#include "rk_aiq_user_api_asharp.cpp"
|
#include "rk_aiq_user_api_imgproc.cpp"
|
#include "uAPI2/rk_aiq_user_api2_imgproc.cpp"
|
#include "rk_aiq_user_api_afec.cpp"
|
#include "rk_aiq_user_api_af.cpp"
|
#include "uAPI2/rk_aiq_user_api2_af.cpp"
|
#include "rk_aiq_user_api_asd.cpp"
|
#include "rk_aiq_user_api_aldch.cpp"
|
#include "rk_aiq_user_api2_aldch.cpp"
|
#include "rk_aiq_user_api_acp.cpp"
|
#include "rk_aiq_user_api2_acp.cpp"
|
#include "rk_aiq_user_api_aie.cpp"
|
#include "rk_aiq_user_api2_aie.cpp"
|
#include "rk_aiq_user_api_aeis.cpp"
|
#include "rk_aiq_user_api_abayernr_v2.cpp"
|
#include "rk_aiq_user_api_aynr_v2.cpp"
|
#include "rk_aiq_user_api_acnr_v1.cpp"
|
#include "rk_aiq_user_api_asharp_v3.cpp"
|
#include "uAPI2/rk_aiq_user_api2_abayernr_v2.cpp"
|
#include "uAPI2/rk_aiq_user_api2_aynr_v2.cpp"
|
#include "uAPI2/rk_aiq_user_api2_acnr_v1.cpp"
|
#include "uAPI2/rk_aiq_user_api2_asharp_v3.cpp"
|
#include "uAPI2/rk_aiq_user_api2_anr.cpp"
|
#include "uAPI2/rk_aiq_user_api2_awb.cpp"
|
#include "uAPI2/rk_aiq_user_api2_alsc.cpp"
|
#include "uAPI2/rk_aiq_user_api2_accm.cpp"
|
#include "uAPI2/rk_aiq_user_api2_a3dlut.cpp"
|
#include "rk_aiq_user_api2_afec.cpp"
|
#include "uAPI/rk_aiq_user_api_agic.cpp"
|
#include "uAPI2/rk_aiq_user_api2_agic.cpp"
|
|
|
|
|
#define RK_AIQ_ALGO_TYPE_MODULES (RK_AIQ_ALGO_TYPE_MAX + 1)
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_setModuleCtl(const rk_aiq_sys_ctx_t* ctx, rk_aiq_module_id_t mId, bool mod_en)
|
{
|
ENTER_XCORE_FUNCTION();
|
CHECK_USER_API_ENABLE2(ctx);
|
CHECK_USER_API_ENABLE(RK_AIQ_ALGO_TYPE_MODULES);
|
RKAIQ_API_SMART_LOCK(ctx);
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
if (mId > RK_MODULE_INVAL && mId < RK_MODULE_MAX) {
|
if (mId == RK_MODULE_FEC) {
|
rk_aiq_fec_attrib_t fecAttr;
|
rk_aiq_user_api_afec_GetAttrib(ctx, &fecAttr);
|
fecAttr.en = mod_en;
|
if(XCAM_RETURN_NO_ERROR != rk_aiq_user_api_afec_SetAttrib(ctx, fecAttr))
|
LOGE("enable fec failed! maybe fec not enable in xml.");
|
} else {
|
ret = ctx->_rkAiqManager->setModuleCtl(mId, mod_en);
|
}
|
} else {
|
ret = XCAM_RETURN_ERROR_FAILED;
|
}
|
|
EXIT_XCORE_FUNCTION();
|
|
return ret;
|
}
|
|
int32_t
|
rk_aiq_uapi_sysctl_getModuleCtl(const rk_aiq_sys_ctx_t* ctx, rk_aiq_module_id_t mId, bool *mod_en)
|
{
|
ENTER_XCORE_FUNCTION();
|
NULL_RETURN_RET(ctx, -1);
|
NULL_RETURN_RET(ctx->_rkAiqManager.ptr(), -1);
|
RKAIQ_API_SMART_LOCK(ctx);
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
bool en;
|
ret = ctx->_rkAiqManager->getModuleCtl(mId, en);
|
*mod_en = en;
|
EXIT_XCORE_FUNCTION();
|
|
return ret;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_setCpsLtCfg(const rk_aiq_sys_ctx_t* ctx,
|
rk_aiq_cpsl_cfg_t* cfg)
|
{
|
RKAIQ_API_SMART_LOCK(ctx);
|
return ctx->_analyzer->setCpsLtCfg(*cfg);
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_getCpsLtInfo(const rk_aiq_sys_ctx_t* ctx,
|
rk_aiq_cpsl_info_t* info)
|
{
|
RKAIQ_API_SMART_LOCK(ctx);
|
return ctx->_analyzer->getCpsLtInfo(*info);
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_queryCpsLtCap(const rk_aiq_sys_ctx_t* ctx,
|
rk_aiq_cpsl_cap_t* cap)
|
{
|
RKAIQ_API_SMART_LOCK(ctx);
|
return ctx->_analyzer->queryCpsLtCap(*cap);
|
}
|
|
extern RkAiqAlgoDescription g_RkIspAlgoDescA3dlut;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAblc;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAccm;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAcgc;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAcp;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAdebayer;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAdhaz;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAdpcc;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAe;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAf;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAfec;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAgamma;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAdegamma;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAgic;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAmerge;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAtmo;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAie;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAldch;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAlsc;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAnr;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAorb;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAr2y;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAsd;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAsharp;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAwb;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAwdr;
|
extern RkAiqAlgoDescription g_RkIspAlgoDescAeis;
|
|
static void _print_versions()
|
{
|
LOGI("\n"
|
"************************** VERSION INFOS **************************\n"
|
"version release date: %s\n"
|
" AIQ: %s\n"
|
" IQ PARSER: %s\n"
|
" RK INTEGRATED ALGO MODULES:\n"
|
" AWB: %s\n"
|
" AEC: %s\n"
|
" AF: %s\n"
|
" AHDR: %s\n"
|
" ANR: %s\n"
|
" ASHARP: %s\n"
|
" ADEHAZE: %s\n"
|
" AGAMMA: %s\n"
|
" A3DLUT: %s\n"
|
" ABLC: %s\n"
|
" ACCM: %s\n"
|
" ACGC: %s\n"
|
" ACP: %s\n"
|
" ADEBAYER: %s\n"
|
" ADPCC: %s\n"
|
" AGIC: %s\n"
|
" AIE: %s\n"
|
" ALDCH: %s\n"
|
" ALSC: %s\n"
|
" AORB: %s\n"
|
" AR2Y: %s\n"
|
" ASD: %s\n"
|
" AWDR: %s\n"
|
" AEIS: %s\n"
|
"************************ VERSION INFOS END ************************\n"
|
, RK_AIQ_RELEASE_DATE
|
, RK_AIQ_VERSION
|
, RK_AIQ_CALIB_VERSION
|
, g_RkIspAlgoDescAwb.common.version
|
, g_RkIspAlgoDescAe.common.version
|
, g_RkIspAlgoDescAf.common.version
|
, g_RkIspAlgoDescAmerge.common.version
|
, g_RkIspAlgoDescAtmo.common.version
|
, g_RkIspAlgoDescAnr.common.version
|
, g_RkIspAlgoDescAsharp.common.version
|
, g_RkIspAlgoDescAdhaz.common.version
|
, g_RkIspAlgoDescAgamma.common.version
|
, g_RkIspAlgoDescA3dlut.common.version
|
, g_RkIspAlgoDescAblc.common.version
|
, g_RkIspAlgoDescAccm.common.version
|
, g_RkIspAlgoDescAcgc.common.version
|
, g_RkIspAlgoDescAcp.common.version
|
, g_RkIspAlgoDescAdebayer.common.version
|
, g_RkIspAlgoDescAdpcc.common.version
|
, g_RkIspAlgoDescAfec.common.version
|
, g_RkIspAlgoDescAgic.common.version
|
, g_RkIspAlgoDescAie.common.version
|
, g_RkIspAlgoDescAldch.common.version
|
, g_RkIspAlgoDescAlsc.common.version
|
, g_RkIspAlgoDescAorb.common.version
|
, g_RkIspAlgoDescAr2y.common.version
|
, g_RkIspAlgoDescAsd.common.version
|
, g_RkIspAlgoDescAwdr.common.version
|
, g_RkIspAlgoDescAeis.common.version
|
);
|
}
|
|
void rk_aiq_uapi_get_version_info(rk_aiq_ver_info_t* vers)
|
{
|
uint32_t iq_parser_magic_code;
|
|
xcam_mem_clear (*vers);
|
const char* ver_str = RK_AIQ_CALIB_VERSION;
|
const char* start = ver_str + strlen(RK_AIQ_CALIB_VERSION_HEAD);
|
const char* stop = strstr(ver_str, RK_AIQ_CALIB_VERSION_MAGIC_JOINT);
|
|
// TODO: use strncpy instead of memcpy, but has compile warning now
|
memcpy(vers->iq_parser_ver, start, stop - start);
|
|
start = strstr(ver_str, RK_AIQ_CALIB_VERSION_MAGIC_CODE_HEAD) +
|
strlen(RK_AIQ_CALIB_VERSION_MAGIC_CODE_HEAD);
|
|
vers->iq_parser_magic_code = atoi(start);
|
|
ver_str = RK_AIQ_VERSION;
|
start = ver_str + strlen(RK_AIQ_VERSION_HEAD);
|
strcpy(vers->aiq_ver, start);
|
|
strcpy(vers->awb_algo_ver, g_RkIspAlgoDescAwb.common.version);
|
strcpy(vers->ae_algo_ver, g_RkIspAlgoDescAe.common.version);
|
strcpy(vers->af_algo_ver, g_RkIspAlgoDescAf.common.version);
|
strcpy(vers->ahdr_algo_ver, g_RkIspAlgoDescAmerge.common.version);
|
strcpy(vers->ahdr_algo_ver, g_RkIspAlgoDescAtmo.common.version);
|
|
LOGI("aiq ver %s, parser ver %s, magic code %d, awb ver %s\n"
|
"ae ver %s, af ver %s, ahdr ver %s", vers->aiq_ver,
|
vers->iq_parser_ver, vers->iq_parser_magic_code,
|
vers->awb_algo_ver, vers->ae_algo_ver,
|
vers->af_algo_ver, vers->ahdr_algo_ver);
|
}
|
|
static void rk_aiq_init_lib(void) __attribute__((constructor));
|
static void rk_aiq_init_lib(void)
|
{
|
xcam_get_log_level();
|
ENTER_XCORE_FUNCTION();
|
#ifdef RK_SIMULATOR_HW
|
/* nothing to do now */
|
#else
|
CamHwIsp20::initCamHwInfos();
|
rk_aiq_static_info_t* s_info = CamHwIsp20::getStaticCamHwInfo(NULL, 0);
|
|
if (s_info != nullptr) {
|
if (s_info->isp_hw_ver == 4)
|
g_rkaiq_isp_hw_ver = 20;
|
else if (s_info->isp_hw_ver == 5)
|
g_rkaiq_isp_hw_ver = 21;
|
else
|
LOGE("do not support isp hw ver %d now !", s_info->isp_hw_ver);
|
}
|
#endif
|
#if defined(ISP_HW_V20)
|
assert(g_rkaiq_isp_hw_ver == 20);
|
#elif defined(ISP_HW_V21)
|
assert(g_rkaiq_isp_hw_ver == 21);
|
#else
|
#error "WRONG ISP_HW_VERSION, ONLY SUPPORT V20 AND V21 NOW !"
|
#endif
|
_print_versions();
|
EXIT_XCORE_FUNCTION();
|
|
}
|
static void rk_aiq_deinit_lib(void) __attribute__((destructor));
|
static void rk_aiq_deinit_lib(void)
|
{
|
ENTER_XCORE_FUNCTION();
|
#ifdef RK_SIMULATOR_HW
|
/* nothing to do now */
|
#else
|
RkAiqCalibDb::releaseCalibDb();
|
CamHwIsp20::clearStaticCamHwInfo();
|
#endif
|
EXIT_XCORE_FUNCTION();
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_enqueueRkRawBuf(const rk_aiq_sys_ctx_t* ctx, void *rawdata, bool sync)
|
{
|
ENTER_XCORE_FUNCTION();
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
ret = ctx->_rkAiqManager->enqueueRawBuffer(rawdata, sync);
|
EXIT_XCORE_FUNCTION();
|
|
return ret;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_enqueueRkRawFile(const rk_aiq_sys_ctx_t* ctx, const char *path)
|
{
|
ENTER_XCORE_FUNCTION();
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
ret = ctx->_rkAiqManager->enqueueRawFile(path);
|
EXIT_XCORE_FUNCTION();
|
|
return ret;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_registRkRawCb(const rk_aiq_sys_ctx_t* ctx, void (*callback)(void*))
|
{
|
ENTER_XCORE_FUNCTION();
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
if (callback == NULL)
|
ret = XCAM_RETURN_ERROR_PARAM;
|
else
|
ret = ctx->_rkAiqManager->registRawdataCb(callback);
|
EXIT_XCORE_FUNCTION();
|
return ret;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_prepareRkRaw(const rk_aiq_sys_ctx_t* ctx, rk_aiq_raw_prop_t prop)
|
{
|
ENTER_XCORE_FUNCTION();
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
ret = ctx->_rkAiqManager->rawdataPrepare(prop);
|
EXIT_XCORE_FUNCTION();
|
|
return ret;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_setSharpFbcRotation(const rk_aiq_sys_ctx_t* ctx, rk_aiq_rotation_t rot)
|
{
|
ENTER_XCORE_FUNCTION();
|
RKAIQ_API_SMART_LOCK(ctx);
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
ret = ctx->_rkAiqManager->setSharpFbcRotation(rot);
|
EXIT_XCORE_FUNCTION();
|
return ret;
|
}
|
|
/*!
|
* \brief switch working mode dynamically
|
* this aims to switch the isp pipeline working mode fast, and can be called on
|
* streaming status. On non streaming status, should call rk_aiq_uapi_sysctl_prepare
|
* instead of this to set working mode.
|
*/
|
XCamReturn
|
rk_aiq_uapi_sysctl_swWorkingModeDyn(const rk_aiq_sys_ctx_t* ctx, rk_aiq_working_mode_t mode)
|
{
|
ENTER_XCORE_FUNCTION();
|
RKAIQ_API_SMART_LOCK(ctx);
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
/* ret = ctx->_rkAiqManager->swWorkingModeDyn(mode); */
|
ret = ctx->_rkAiqManager->swWorkingModeDyn_msg(mode);
|
EXIT_XCORE_FUNCTION();
|
return ret;
|
}
|
|
void
|
rk_aiq_uapi_sysctl_setMulCamConc(const rk_aiq_sys_ctx_t* ctx, bool cc)
|
{
|
ENTER_XCORE_FUNCTION();
|
RKAIQ_API_SMART_LOCK(ctx);
|
ctx->_rkAiqManager->setMulCamConc(cc);
|
EXIT_XCORE_FUNCTION();
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_setCrop(const rk_aiq_sys_ctx_t* sys_ctx, rk_aiq_rect_t rect)
|
{
|
RKAIQ_API_SMART_LOCK(sys_ctx);
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
ret = sys_ctx->_camHw->setSensorCrop(rect);
|
return ret;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_getCrop(const rk_aiq_sys_ctx_t* sys_ctx, rk_aiq_rect_t* rect)
|
{
|
RKAIQ_API_SMART_LOCK(sys_ctx);
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
ret = sys_ctx->_camHw->getSensorCrop(*rect);
|
|
return ret;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_updateIq(rk_aiq_sys_ctx_t* sys_ctx, char* iqfile)
|
{
|
if (!sys_ctx) {
|
LOGE("%s: sys_ctx is invalied\n", __func__);
|
return XCAM_RETURN_ERROR_FAILED;
|
}
|
|
RKAIQ_API_SMART_LOCK(sys_ctx);
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
LOGI("applying new iq file:%s\n", iqfile);
|
|
auto calibDbProj = RkAiqCalibDbV2::createCalibDbProj(iqfile);
|
if (!calibDbProj) {
|
LOGE("failed to create CalibDbProj from iqfile\n");
|
return XCAM_RETURN_ERROR_PARAM;
|
}
|
|
CamCalibDbV2Context_t calibdbv2_ctx =
|
RkAiqCalibDbV2::toDefaultCalibDb(calibDbProj);
|
ret = sys_ctx->_rkAiqManager->updateCalibDb(&calibdbv2_ctx);
|
|
if (ret) {
|
LOGE("failed to update iqfile\n");
|
return ret;
|
}
|
|
sys_ctx->_calibDbProj = calibDbProj;
|
|
return XCAM_RETURN_NO_ERROR;
|
}
|
|
XCamReturn
|
rk_aiq_uapi_sysctl_tuning(const rk_aiq_sys_ctx_t* sys_ctx, char* param)
|
{
|
RKAIQ_API_SMART_LOCK(sys_ctx);
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
if (!sys_ctx) {
|
LOGE("%s: sys_ctx is invalied\n", __func__);
|
return XCAM_RETURN_ERROR_FAILED;
|
}
|
|
// Find json patch
|
std::string patch_str(param);
|
size_t json_start = patch_str.find_first_of("[");
|
size_t json_end = patch_str.find_last_of("]");
|
|
LOGI("patch is:%s\n", patch_str.c_str());
|
|
if (json_start >= patch_str.size() || json_end > patch_str.size() ||
|
json_start >= json_end) {
|
LOGE("%s: patch is invalied\n", __func__);
|
return XCAM_RETURN_ERROR_FAILED;
|
}
|
std::string json_str = patch_str.substr(json_start, json_end + 1);
|
|
if (json_str.empty()) {
|
LOGE("%s: patch is empty\n", __func__);
|
return XCAM_RETURN_ERROR_FAILED;
|
}
|
|
auto last_calib = sys_ctx->_rkAiqManager->getCurrentCalibDBV2();
|
|
if (!last_calib) {
|
*last_calib = RkAiqCalibDbV2::toDefaultCalibDb(sys_ctx->_calibDbProj);
|
if (!last_calib) {
|
LOGE("%s: default calib is invalied\n", __func__);
|
return XCAM_RETURN_ERROR_FAILED;
|
}
|
}
|
|
auto tuning_calib = RkCam::RkAiqCalibDbV2::analyzTuningCalib(
|
last_calib, json_str.c_str());
|
|
ret = sys_ctx->_rkAiqManager->calibTuning(tuning_calib.calib,
|
tuning_calib.ModuleNames);
|
|
return ret;
|
}
|
|
char* rk_aiq_uapi_sysctl_readiq(const rk_aiq_sys_ctx_t* sys_ctx, char* param)
|
{
|
RKAIQ_API_SMART_LOCK(sys_ctx);
|
cJSON* cmd_json = NULL;
|
char* ret_str = NULL;
|
|
if (!sys_ctx) {
|
LOGE("%s: sys_ctx is invalied\n", __func__);
|
return NULL;
|
}
|
|
// Find json patch
|
std::string patch_str(param);
|
size_t json_start = patch_str.find_first_of("[");
|
size_t json_end = patch_str.find_first_of("]");
|
|
LOGI("request is:%s\n", patch_str.c_str());
|
|
if (json_start >= patch_str.size() || json_end > patch_str.size() ||
|
json_start >= json_end) {
|
LOGE("%s: request is invalied\n", __func__);
|
return NULL;
|
}
|
std::string json_str = patch_str.substr(json_start, json_end + 1);
|
|
if (json_str.empty()) {
|
LOGE("%s: request is empty\n", __func__);
|
return NULL;
|
}
|
|
auto last_calib = sys_ctx->_rkAiqManager->getCurrentCalibDBV2();
|
|
if (!last_calib) {
|
*last_calib = RkAiqCalibDbV2::toDefaultCalibDb(sys_ctx->_calibDbProj);
|
if (!last_calib) {
|
LOGE("%s: default calib is invalied\n", __func__);
|
return NULL;
|
}
|
}
|
|
ret_str = RkCam::RkAiqCalibDbV2::readIQNodeStrFromJstr(last_calib,
|
json_str.c_str());
|
|
return ret_str;
|
}
|
|
XCamReturn rk_aiq_uapi_sysctl_regMemsSensorIntf(const rk_aiq_sys_ctx_t* sys_ctx,
|
const rk_aiq_mems_sensor_intf_t* intf) {
|
RKAIQ_API_SMART_LOCK(sys_ctx);
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
assert(sys_ctx != nullptr);
|
|
ret = sys_ctx->_analyzer->setMemsSensorIntf(intf);
|
|
if (ret) {
|
LOGE("failed to update iqfile\n");
|
ret = XCAM_RETURN_ERROR_FAILED;
|
}
|
|
return ret;
|
}
|
|
int rk_aiq_uapi_sysctl_switch_scene(const rk_aiq_sys_ctx_t* sys_ctx,
|
const char* main_scene,
|
const char* sub_scene)
|
{
|
RKAIQ_API_SMART_LOCK(sys_ctx);
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
if (!sys_ctx) {
|
LOGE("%s: sys_ctx is invalied\n", __func__);
|
return XCAM_RETURN_ERROR_PARAM;
|
}
|
|
if (!main_scene || !sub_scene) {
|
LOGE("%s: request is invalied\n", __func__);
|
return XCAM_RETURN_ERROR_PARAM;
|
}
|
|
auto new_scene_calib = RkAiqSceneManager::refToScene(sys_ctx->_calibDbProj,
|
main_scene, sub_scene);
|
|
if (!new_scene_calib) {
|
LOGE("%s: failed\n", __func__);
|
return XCAM_RETURN_ERROR_PARAM;
|
}
|
|
auto last_calib = sys_ctx->_rkAiqManager->getCurrentCalibDBV2();
|
|
CamCalibDbV2Context_t new_calib = *last_calib;
|
new_calib.calib_scene = (char*)new_scene_calib;
|
|
ret = sys_ctx->_rkAiqManager->updateCalibDb(&new_calib);
|
if (ret) {
|
LOGE("failed to switch scene\n");
|
return ret;
|
}
|
|
return XCAM_RETURN_NO_ERROR;
|
}
|