/* * 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; SmartPtr _camHw; SmartPtr _analyzer; SmartPtr _lumaAnalyzer; CamCalibDbContext_t *_calibDb; int _isp_hw_ver; SocketServer * _socket; SmartPtr _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 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::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::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 static T* algoHandle(const rk_aiq_sys_ctx_t* ctx, const int algo_type) { T* algo_handle = NULL; RkCam::RkAiqHandle* handle = const_cast(ctx->_analyzer->getAiqAlgoHandle(algo_type)); XCAM_ASSERT(handle); int algo_id = handle->getAlgoId(); if (algo_id == 0) algo_handle = dynamic_cast(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; }