You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
436 lines
19 KiB
436 lines
19 KiB
/*
|
|
* Copyright (c) 2021 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 "CamHwIsp3x.h"
|
|
#ifdef ANDROID_OS
|
|
#include <cutils/properties.h>
|
|
#endif
|
|
|
|
#include "IspParamsSplitter.h"
|
|
|
|
namespace RkCam {
|
|
|
|
CamHwIsp3x::CamHwIsp3x()
|
|
: CamHwIsp21()
|
|
{
|
|
mVicapIspPhyLinkSupported = true;
|
|
}
|
|
|
|
CamHwIsp3x::~CamHwIsp3x()
|
|
{}
|
|
|
|
XCamReturn
|
|
CamHwIsp3x::init(const char* sns_ent_name)
|
|
{
|
|
xcam_mem_clear (_full_active_isp3x_params);
|
|
|
|
XCamReturn ret = CamHwIsp21::init(sns_ent_name);
|
|
|
|
return ret;
|
|
}
|
|
|
|
XCamReturn
|
|
CamHwIsp3x::stop()
|
|
{
|
|
|
|
XCamReturn ret = CamHwIsp21::stop();
|
|
xcam_mem_clear (_full_active_isp3x_params);
|
|
|
|
return ret;
|
|
}
|
|
|
|
void
|
|
CamHwIsp3x::gen_full_isp_params(const struct isp3x_isp_params_cfg* update_params,
|
|
struct isp3x_isp_params_cfg* full_params,
|
|
uint64_t* module_en_update_partial,
|
|
uint64_t* module_cfg_update_partial)
|
|
{
|
|
XCAM_ASSERT (update_params);
|
|
XCAM_ASSERT (full_params);
|
|
int i = 0;
|
|
|
|
ENTER_CAMHW_FUNCTION();
|
|
for (; i <= RK_ISP2X_MAX_ID; i++)
|
|
if (update_params->module_en_update & (1LL << i)) {
|
|
if ((full_params->module_ens & (1LL << i)) !=
|
|
(update_params->module_ens & (1LL << i)))
|
|
*module_en_update_partial |= 1LL << i;
|
|
full_params->module_en_update |= 1LL << i;
|
|
// clear old bit value
|
|
full_params->module_ens &= ~(1LL << i);
|
|
// set new bit value
|
|
full_params->module_ens |= update_params->module_ens & (1LL << i);
|
|
}
|
|
|
|
for (i = 0; i <= RK_ISP2X_MAX_ID; i++) {
|
|
if (update_params->module_cfg_update & (1LL << i)) {
|
|
|
|
#define CHECK_UPDATE_PARAMS(dst, src) \
|
|
if (memcmp(&dst, &src, sizeof(dst)) == 0) { \
|
|
continue; \
|
|
} \
|
|
*module_cfg_update_partial |= 1LL << i; \
|
|
dst = src; \
|
|
|
|
full_params->module_cfg_update |= 1LL << i;
|
|
switch (i) {
|
|
case RK_ISP2X_RAWAE0_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->meas.rawae0, update_params->meas.rawae0);
|
|
break;
|
|
case RK_ISP2X_RAWAE1_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->meas.rawae1, update_params->meas.rawae1);
|
|
break;
|
|
case RK_ISP2X_RAWAE2_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->meas.rawae2, update_params->meas.rawae2);
|
|
break;
|
|
case RK_ISP2X_RAWAE3_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->meas.rawae3, update_params->meas.rawae3);
|
|
break;
|
|
case RK_ISP2X_RAWHIST0_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->meas.rawhist0, update_params->meas.rawhist0);
|
|
break;
|
|
case RK_ISP2X_RAWHIST1_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->meas.rawhist1, update_params->meas.rawhist1);
|
|
break;
|
|
case RK_ISP2X_RAWHIST2_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->meas.rawhist2, update_params->meas.rawhist2);
|
|
break;
|
|
case RK_ISP2X_RAWHIST3_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->meas.rawhist3, update_params->meas.rawhist3);
|
|
break;
|
|
case RK_ISP2X_YUVAE_ID:
|
|
//CHECK_UPDATE_PARAMS(full_params->meas.yuvae, update_params->meas.yuvae);
|
|
break;
|
|
case RK_ISP2X_SIHST_ID:
|
|
//CHECK_UPDATE_PARAMS(full_params->meas.sihst, update_params->meas.sihst);
|
|
break;
|
|
case RK_ISP2X_SIAWB_ID:
|
|
//CHECK_UPDATE_PARAMS(full_params->meas.siawb, update_params->meas.siawb);
|
|
break;
|
|
case RK_ISP2X_RAWAWB_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->meas.rawawb, update_params->meas.rawawb);
|
|
break;
|
|
case RK_ISP2X_AWB_GAIN_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.awb_gain_cfg, update_params->others.awb_gain_cfg);
|
|
break;
|
|
case RK_ISP2X_RAWAF_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->meas.rawaf, update_params->meas.rawaf);
|
|
break;
|
|
case RK_ISP2X_HDRMGE_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.hdrmge_cfg, update_params->others.hdrmge_cfg);
|
|
break;
|
|
/* case RK_ISP2X_HDRTMO_ID: */
|
|
/* full_params->others.hdrtmo_cfg = update_params->others.hdrtmo_cfg; */
|
|
/* break; */
|
|
case RK_ISP2X_CTK_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.ccm_cfg, update_params->others.ccm_cfg);
|
|
break;
|
|
case RK_ISP2X_LSC_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.lsc_cfg, update_params->others.lsc_cfg);
|
|
break;
|
|
case RK_ISP2X_GOC_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.gammaout_cfg, update_params->others.gammaout_cfg);
|
|
break;
|
|
case RK_ISP2X_3DLUT_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.isp3dlut_cfg, update_params->others.isp3dlut_cfg);
|
|
break;
|
|
case RK_ISP2X_DPCC_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.dpcc_cfg, update_params->others.dpcc_cfg);
|
|
break;
|
|
case RK_ISP2X_BLS_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.bls_cfg, update_params->others.bls_cfg);
|
|
break;
|
|
case RK_ISP2X_DEBAYER_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.debayer_cfg, update_params->others.debayer_cfg);
|
|
break;
|
|
case RK_ISP2X_DHAZ_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.dhaz_cfg, update_params->others.dhaz_cfg);
|
|
break;
|
|
/* case RK_ISP2X_RAWNR_ID: */
|
|
/* full_params->others.rawnr_cfg = update_params->others.rawnr_cfg; */
|
|
/* break; */
|
|
case RK_ISP2X_GAIN_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.gain_cfg, update_params->others.gain_cfg);
|
|
break;
|
|
case RK_ISP2X_LDCH_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.ldch_cfg, update_params->others.ldch_cfg);
|
|
break;
|
|
case RK_ISP2X_GIC_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.gic_cfg, update_params->others.gic_cfg);
|
|
break;
|
|
case RK_ISP2X_CPROC_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.cproc_cfg, update_params->others.cproc_cfg);
|
|
break;
|
|
case Rk_ISP21_BAYNR_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.baynr_cfg, update_params->others.baynr_cfg);
|
|
break;
|
|
case Rk_ISP21_BAY3D_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.bay3d_cfg, update_params->others.bay3d_cfg);
|
|
break;
|
|
case Rk_ISP21_YNR_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.ynr_cfg, update_params->others.ynr_cfg);
|
|
break;
|
|
case Rk_ISP21_CNR_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.cnr_cfg, update_params->others.cnr_cfg);
|
|
break;
|
|
case Rk_ISP21_SHARP_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.sharp_cfg, update_params->others.sharp_cfg);
|
|
break;
|
|
case Rk_ISP21_DRC_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.drc_cfg, update_params->others.drc_cfg);
|
|
break;
|
|
case RK_ISP2X_SDG_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.sdg_cfg, update_params->others.sdg_cfg);
|
|
break;
|
|
case Rk_ISP3x_CAC_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.cac_cfg, update_params->others.cac_cfg);
|
|
break;
|
|
case Rk_ISP2x_CSM_ID:
|
|
CHECK_UPDATE_PARAMS(full_params->others.csm_cfg, update_params->others.csm_cfg);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
EXIT_CAMHW_FUNCTION();
|
|
}
|
|
|
|
XCamReturn
|
|
CamHwIsp3x::setIspConfig()
|
|
{
|
|
XCamReturn ret = XCAM_RETURN_NO_ERROR;
|
|
|
|
ENTER_CAMHW_FUNCTION();
|
|
|
|
SmartPtr<V4l2Buffer> v4l2buf;
|
|
uint32_t frameId = -1;
|
|
|
|
{
|
|
SmartLock locker (_isp_params_cfg_mutex);
|
|
while (_effecting_ispparam_map.size() > 8)
|
|
_effecting_ispparam_map.erase(_effecting_ispparam_map.begin());
|
|
}
|
|
if (mIspParamsDev.ptr()) {
|
|
ret = mIspParamsDev->get_buffer(v4l2buf);
|
|
if (ret) {
|
|
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "Can not get isp params buffer\n");
|
|
return XCAM_RETURN_ERROR_PARAM;
|
|
}
|
|
} else
|
|
return XCAM_RETURN_BYPASS;
|
|
|
|
cam3aResultList ready_results;
|
|
ret = mParamsAssembler->deQueOne(ready_results, frameId);
|
|
if (ret != XCAM_RETURN_NO_ERROR) {
|
|
LOGI_CAMHW_SUBM(ISP20HW_SUBM, "deque isp ready parameter failed\n");
|
|
mIspParamsDev->return_buffer_to_pool (v4l2buf);
|
|
return XCAM_RETURN_ERROR_PARAM;
|
|
}
|
|
|
|
LOGD_ANALYZER("----------%s, start config id(%d)'s isp params", __FUNCTION__, frameId);
|
|
|
|
struct isp3x_isp_params_cfg update_params[2];
|
|
memset(update_params, 0, sizeof(struct isp3x_isp_params_cfg)*2);
|
|
|
|
update_params[0].module_en_update = 0;
|
|
update_params[0].module_ens = 0;
|
|
update_params[0].module_cfg_update = 0;
|
|
if (_state == CAM_HW_STATE_STOPPED || _state == CAM_HW_STATE_PREPARED || _state == CAM_HW_STATE_PAUSED) {
|
|
// update all ens
|
|
_full_active_isp3x_params.module_en_update = ~0;
|
|
// just re-config the enabled moddules
|
|
_full_active_isp3x_params.module_cfg_update = _full_active_isp3x_params.module_ens;
|
|
} else {
|
|
_full_active_isp3x_params.module_en_update = 0;
|
|
// use module_ens to store module status, so we can use it to restore
|
|
// the init params for re-start and re-prepare
|
|
/* _full_active_isp3x_params.module_ens = 0; */
|
|
_full_active_isp3x_params.module_cfg_update = 0;
|
|
}
|
|
|
|
if (frameId >= 0) {
|
|
SmartPtr<cam3aResult> awb_res = get_3a_module_result(ready_results, RESULT_TYPE_AWB_PARAM);
|
|
SmartPtr<RkAiqIspAwbParamsProxyV3x> awbParams;
|
|
if (awb_res.ptr()) {
|
|
awbParams = awb_res.dynamic_cast_ptr<RkAiqIspAwbParamsProxyV3x>();
|
|
{
|
|
SmartLock locker (_isp_params_cfg_mutex);
|
|
_effecting_ispparam_map[frameId].awb_cfg_v3x = awbParams->data()->result;
|
|
|
|
}
|
|
} else {
|
|
/* use the latest */
|
|
SmartLock locker (_isp_params_cfg_mutex);
|
|
if (!_effecting_ispparam_map.empty()) {
|
|
_effecting_ispparam_map[frameId].awb_cfg_v3x = (_effecting_ispparam_map.rbegin())->second.awb_cfg_v3x;
|
|
LOGW_CAMHW_SUBM(ISP20HW_SUBM, "use frame %d awb params for frame %d !\n",
|
|
frameId, (_effecting_ispparam_map.rbegin())->first);
|
|
} else {
|
|
LOGW_CAMHW_SUBM(ISP20HW_SUBM, "get awb params from 3a result failed for frame %d !\n", frameId);
|
|
}
|
|
}
|
|
|
|
SmartPtr<cam3aResult> blc_res = get_3a_module_result(ready_results, RESULT_TYPE_BLC_PARAM);
|
|
SmartPtr<RkAiqIspBlcParamsProxyV21> blcParams;
|
|
if (blc_res.ptr()) {
|
|
blcParams = blc_res.dynamic_cast_ptr<RkAiqIspBlcParamsProxyV21>();
|
|
{
|
|
SmartLock locker (_isp_params_cfg_mutex);
|
|
_effecting_ispparam_map[frameId].blc_cfg = blcParams->data()->result;
|
|
|
|
}
|
|
} else {
|
|
/* use the latest */
|
|
SmartLock locker (_isp_params_cfg_mutex);
|
|
if (!_effecting_ispparam_map.empty()) {
|
|
_effecting_ispparam_map[frameId].blc_cfg = (_effecting_ispparam_map.rbegin())->second.blc_cfg;
|
|
LOGW_CAMHW_SUBM(ISP20HW_SUBM, "use frame %d blc params for frame %d !\n",
|
|
frameId, (_effecting_ispparam_map.rbegin())->first);
|
|
} else {
|
|
LOGW_CAMHW_SUBM(ISP20HW_SUBM, "get blc params from 3a result failed for frame %d !\n", frameId);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// TODO: merge_isp_results would cause the compile warning: reference to merge_isp_results is ambiguous
|
|
// now use Isp21Params::merge_isp_results instead
|
|
if (Isp3xParams::merge_isp_results(ready_results, update_params) != XCAM_RETURN_NO_ERROR)
|
|
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "ISP parameter translation error\n");
|
|
if(mIsMultiIspMode == false) {
|
|
Isp3xParams::fixedAwbOveflowToIsp3xParams(update_params, mIsMultiIspMode);
|
|
}
|
|
uint64_t module_en_update_partial = 0;
|
|
uint64_t module_cfg_update_partial = 0;
|
|
gen_full_isp_params(update_params, &_full_active_isp3x_params,
|
|
&module_en_update_partial, &module_cfg_update_partial);
|
|
|
|
if (_state == CAM_HW_STATE_STOPPED)
|
|
LOGD_CAMHW_SUBM(ISP20HW_SUBM, "ispparam ens 0x%llx, en_up 0x%llx, cfg_up 0x%llx",
|
|
_full_active_isp3x_params.module_ens,
|
|
_full_active_isp3x_params.module_en_update,
|
|
_full_active_isp3x_params.module_cfg_update);
|
|
#ifdef RUNTIME_MODULE_DEBUG
|
|
_full_active_isp3x_params.module_en_update &= ~g_disable_isp_modules_en;
|
|
_full_active_isp3x_params.module_ens |= g_disable_isp_modules_en;
|
|
_full_active_isp3x_params.module_cfg_update &= ~g_disable_isp_modules_cfg_update;
|
|
module_en_update_partial = _full_active_isp3x_params.module_en_update;
|
|
module_cfg_update_partial = _full_active_isp3x_params.module_cfg_update;
|
|
#endif
|
|
|
|
|
|
if (v4l2buf.ptr()) {
|
|
struct isp3x_isp_params_cfg* isp_params;
|
|
int buf_index = v4l2buf->get_buf().index;
|
|
bool isMultiIsp = mIsMultiIspMode;
|
|
bool extened_pixel = mMultiIspExtendedPixel;
|
|
|
|
isp_params = (struct isp3x_isp_params_cfg*)v4l2buf->get_buf().m.userptr;
|
|
*isp_params = _full_active_isp3x_params;
|
|
isp_params->module_en_update = module_en_update_partial;
|
|
isp_params->module_cfg_update = module_cfg_update_partial;
|
|
//TODO: isp driver has bug now, lsc cfg_up should be set along with
|
|
//en_up
|
|
if (isp_params->module_cfg_update & ISP2X_MODULE_LSC)
|
|
isp_params->module_en_update |= ISP2X_MODULE_LSC;
|
|
isp_params->frame_id = frameId;
|
|
|
|
#if 0 //TODO: isp21 params has no exposure info field
|
|
SmartPtr<SensorHw> mSensorSubdev = mSensorDev.dynamic_cast_ptr<SensorHw>();
|
|
if (mSensorSubdev.ptr()) {
|
|
memset(&isp_params->exposure, 0, sizeof(isp_params->exposure));
|
|
SmartPtr<RkAiqExpParamsProxy> expParam;
|
|
|
|
if (mSensorSubdev->getEffectiveExpParams(expParam, frameId) < 0) {
|
|
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "frame_id(%d), get exposure failed!!!\n", frameId);
|
|
} else {
|
|
if (RK_AIQ_HDR_GET_WORKING_MODE(_hdr_mode) == RK_AIQ_WORKING_MODE_NORMAL) {
|
|
isp_params->exposure.linear_exp.analog_gain_code_global = \
|
|
expParam->data()->aecExpInfo.LinearExp.exp_sensor_params.analog_gain_code_global;
|
|
isp_params->exposure.linear_exp.coarse_integration_time = \
|
|
expParam->data()->aecExpInfo.LinearExp.exp_sensor_params.coarse_integration_time;
|
|
} else {
|
|
isp_params->exposure.hdr_exp[0].analog_gain_code_global = \
|
|
expParam->data()->aecExpInfo.HdrExp[0].exp_sensor_params.analog_gain_code_global;
|
|
isp_params->exposure.hdr_exp[0].coarse_integration_time = \
|
|
expParam->data()->aecExpInfo.HdrExp[0].exp_sensor_params.coarse_integration_time;
|
|
isp_params->exposure.hdr_exp[1].analog_gain_code_global = \
|
|
expParam->data()->aecExpInfo.HdrExp[1].exp_sensor_params.analog_gain_code_global;
|
|
isp_params->exposure.hdr_exp[1].coarse_integration_time = \
|
|
expParam->data()->aecExpInfo.HdrExp[1].exp_sensor_params.coarse_integration_time;
|
|
isp_params->exposure.hdr_exp[2].analog_gain_code_global = \
|
|
expParam->data()->aecExpInfo.HdrExp[2].exp_sensor_params.analog_gain_code_global;
|
|
isp_params->exposure.hdr_exp[2].coarse_integration_time = \
|
|
expParam->data()->aecExpInfo.HdrExp[2].exp_sensor_params.coarse_integration_time;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (isMultiIsp) {
|
|
mParamsSplitter->SplitIspParams(&_full_active_isp3x_params, isp_params);
|
|
Isp3xParams::fixedAwbOveflowToIsp3xParams((void*)isp_params, mIsMultiIspMode);
|
|
memcpy(&((isp_params + 1)->others.cac_cfg), &update_params[1].others.cac_cfg,
|
|
sizeof(struct isp3x_cac_cfg));
|
|
}
|
|
|
|
{
|
|
SmartLock locker(_isp_params_cfg_mutex);
|
|
if (frameId < 0) {
|
|
_effecting_ispparam_map[0].isp_params_v3x[0] = _full_active_isp3x_params;
|
|
} else {
|
|
_effecting_ispparam_map[frameId].isp_params_v3x[0] = _full_active_isp3x_params;
|
|
}
|
|
if (isMultiIsp) {
|
|
if (frameId < 0) {
|
|
_effecting_ispparam_map[0].isp_params_v3x[1] = isp_params[0];
|
|
_effecting_ispparam_map[0].isp_params_v3x[2] = isp_params[1];
|
|
} else {
|
|
_effecting_ispparam_map[frameId].isp_params_v3x[1] = isp_params[0];
|
|
_effecting_ispparam_map[frameId].isp_params_v3x[2] = isp_params[1];
|
|
}
|
|
}
|
|
}
|
|
if (mIspParamsDev->queue_buffer (v4l2buf) != 0) {
|
|
LOGE_CAMHW_SUBM(ISP20HW_SUBM, "RKISP1: failed to ioctl VIDIOC_QBUF for index %d, %d %s.\n",
|
|
buf_index, errno, strerror(errno));
|
|
mIspParamsDev->return_buffer_to_pool (v4l2buf);
|
|
return XCAM_RETURN_ERROR_IOCTL;
|
|
}
|
|
|
|
ispModuleEns = _full_active_isp3x_params.module_ens;
|
|
LOGD_CAMHW_SUBM(ISP20HW_SUBM, "camId: %d, frameId:%d, ispparam ens 0x%llx, en_up 0x%llx, cfg_up 0x%llx",
|
|
mCamPhyId, frameId,
|
|
_full_active_isp3x_params.module_ens,
|
|
isp_params->module_en_update,
|
|
isp_params->module_cfg_update);
|
|
|
|
LOG1_CAMHW_SUBM(ISP20HW_SUBM, "device(%s) queue buffer index %d, queue cnt %d, check exit status again[exit: %d]",
|
|
XCAM_STR (mIspParamsDev->get_device_name()),
|
|
buf_index, mIspParamsDev->get_queued_bufcnt(), _is_exit);
|
|
if (_is_exit)
|
|
return XCAM_RETURN_BYPASS;
|
|
} else
|
|
return XCAM_RETURN_BYPASS;
|
|
|
|
EXIT_CAMHW_FUNCTION();
|
|
return ret;
|
|
}
|
|
|
|
};
|