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.

305 lines
12 KiB

#include "rk_aiq_isp39_modules.h"
#include <math.h>
#define RKGIC_V30_HW_BIT 10
#define RKGIC_V30_LUMA_POINT_NUM 8
#define RKGIC_V30_SIGMA_TALBE_LEN 1024
#define RKGIC_V30_NOISE_CURVE_STEP_BITS 6
#define RKGIC_V30_NOISE_CURVE_TABLE_LEN 17
#define RKGIC_V30_SGM_ADJ_TABLE_LEN 13
//
#define RKGIC_V30_GAUS_FLT_RADIUS 1
#define RKGIC_V30_BF_FLT_RADIUS 1
#define RKGIC_V30_NOISE_LUMA_FLT_RADIUS 2
#define RKGIC_V30_MED_FLT_RADIUS 1
#define RKGIC_V30_PRE_FLT_RADIUS 1
// 5x4
#define RKGIC_V30_FLT_GR_GB_RADIUS 2
// 3x1
#define RKGIC_V30_FLT_THED_RADIUS_X 1
#define RKGIC_V30_FLT_THED_RADIUS_Y 0
// fix bit
#define RKGIC_V30_DIV_SIGMA_FIX_BIT 14//16
#define RKGIC_V30_BF_COEFF_FIX_BITS 5//7
#define RKGIC_V30_BF_WGT_FIX_BIT 7//8
#define RKGIC_V30_BF_WGT_SLOPE_FIX_BIT RKGIC_V30_BF_WGT_FIX_BIT
#define RKGIC_V30_MED_FLT_RATIO_FIX_BIT 7
#define RKGIC_V30_BF_FLT_RATIO_FIX_BIT 7
#define RKGIC_V30_LOCAL_GAIN_FIX_BITS 4
#define RKGIC_V30_G_GAIN_ALPHA_FIX_BITS 3
#define RKGIC_V30_GAIN_ISO_FIX_BITS 7
#define RKGIC_V30_BF_WGT_OFFSET_FIX_BITS 8
#define RKGIC_V30_BF_WGT_SCALE_FIX_BITS 5//8
#define RKGIC_V30_CURVE_SCALE_FIX_BITS 7
#define RKGIC_V30_NOISE_ALPHA_FIX_BITS 7
#define RKGIC_V30_sgmRatio_FIX_BITS 7
#define RKGIC_V30_THED_SCALE_FIX_BITS 7
#define RKGIC_V30_COEFF_INV_FIX_BITS 12
#define RKGIC_V30_GAIN_SCALE_FIX_BITS 7
#define RKGIC_V30_WRITE_DEBUG_DATA 0
static void GicV30CreateKernelCoeffs(int radius, int max_radius, float rsigma, uint8_t* kernel_coeffs, int fix_bits, int dim)
{
// calcute distance
int i = 0;
int j = 0;
int k = 0;
double e = 2.71828182845905;
float gaus_table [10] = { 0 };
float distance_table[10] = { 0 };
float sumTable = 0;
float tmp;
float coeffScale_table1D[10] = { 1, 2, 2, 2, 2, 2, 2, 2, 2, 2 };
float coeffScale_table2D[10] = { 1, 4, 4, 4, 8, 4, 4, 8, 8, 4 };
int coeffNums = (radius + 1) * (radius + 2) / 2;
int coeffNums_max = (max_radius + 1) * (max_radius + 2) / 2;
if (dim == 1)
{
coeffNums = radius + 1;
}
// calc distance
if (dim == 2)
{
for (i = 0; i <= radius; i++)
{
for (j = 0; j <= i; j++)
{
distance_table[i * (i + 1) / 2 + j] = pow(i, 2) + pow(j, 2);
}
}
}
else
{
for (i = 0; i <= radius; i++)
{
distance_table[i] = pow(i, 2);
}
}
// calc coeff
for (k = 0; k < coeffNums; k++)
{
tmp = pow(e, -distance_table[k] / 2.0 / rsigma / rsigma);
gaus_table[k] = tmp;
if (dim == 2)
{
sumTable += coeffScale_table2D[k] * gaus_table[k];
}
else
{
sumTable += coeffScale_table1D[k] * gaus_table[k];
}
}
for (k = 0; k < coeffNums_max; k++)
{
gaus_table[k] = gaus_table[k] / sumTable;
kernel_coeffs[k] = ROUND_F(gaus_table[k] * (1 << fix_bits));
}
//check gaus params
int sum_coeff = 0;
sum_coeff = kernel_coeffs[0]
+ 4 * kernel_coeffs[1]
+ 4 * kernel_coeffs[2];
int offset = (1 << fix_bits) - sum_coeff;
kernel_coeffs[0] = kernel_coeffs[0] + offset;
}
void rk_aiq_gic30_params_cvt(void* attr, struct isp33_gic_cfg* gic_cfg, btnr_cvt_info_t* pBtnrInfo)
{
int i, tmp;
struct isp33_gic_cfg *pFix = gic_cfg;
gic_param_t *gic_param = (gic_param_t *) attr;
gic_params_dyn_t* pdyn = &gic_param->dyn;
gic_params_static_t* psta = &gic_param->sta;
/* CTRL */
if (psta->hw_gicT_gic_mode == gic_medAndEpf_mode) {
pFix->pro_mode = 0;
pFix->manualnoisethred_en = 1;
} else {
pFix->pro_mode = 1;
if (psta->gicPost_guideEpf.sw_gicCfg_softThd_mode == gic_softThdManual_mode)
pFix->manualnoisethred_en = 1;
else
pFix->manualnoisethred_en = 0;
}
pFix->manualnoisecurve_en = 1;
if (pdyn->locGicStrg.locSgmStrg.hw_gicT_locSgmStrg_mode == gic_locGlbSgmStrgMix_mode )
pFix->gain_bypass_en = 0;
else
pFix->gain_bypass_en = 1;
/* MEDFLT_PARA */
tmp = pdyn->gicPre_medAndEpf.medFilt.hw_gicT_yFiltClipMin_idx;
pFix->medflt_minthred = CLIP(tmp, 0, 0xf);
tmp = pdyn->gicPre_medAndEpf.medFilt.hw_gicT_yFiltClipMax_idx;
pFix->medflt_maxthred = CLIP(tmp, 0, 0xf);
tmp = ROUND_F(pdyn->gicPre_medAndEpf.medFilt.hw_gicT_yFiltOut_alpha * (1 << RKGIC_V30_MED_FLT_RATIO_FIX_BIT));
pFix->medflt_ratio = CLIP(tmp, 0, 0xff);
/* MEDFLTUV_PARA */
tmp = pdyn->gicPre_medAndEpf.medFilt.hw_gicT_uvFiltClipMin_idx;
pFix->medfltuv_minthred = CLIP(tmp, 0, 0xf);
tmp = pdyn->gicPre_medAndEpf.medFilt.hw_gicT_uvFiltClipMax_idx;
pFix->medfltuv_maxthred = CLIP(tmp, 0, 0xf);
tmp = ROUND_F(pdyn->gicPre_medAndEpf.medFilt.hw_gicT_uvFiltOut_alpha * (1 << RKGIC_V30_MED_FLT_RATIO_FIX_BIT));
pFix->medfltuv_ratio = CLIP(tmp, 0, 0xff);
/* NOISE_SCALE */
tmp = ROUND_F(pdyn->epf.sw_gicT_rgeSgm_scale * 1.414 * (1 << RKGIC_V30_CURVE_SCALE_FIX_BITS));
if (psta->epf.sw_gicCfg_rgeSgm_mode == gic_autoSigma_mode) {
tmp = ROUND_F(tmp * 0.5);
}
pFix->noisecurve_scale = CLIP(tmp, 0, 0x3ff);
/* BILAT_PARA1 */
tmp = ROUND_F(pdyn->epf.diffSgmRat2RgeWgt.sw_gicT_rat2MinWgt_minThred * (1 << RKGIC_V30_BF_WGT_OFFSET_FIX_BITS));
pFix->bffltwgt_offset = CLIP(tmp, 0, 0x3ff);
float bfFltWgt_slope = 1.0 / MAX(pdyn->epf.diffSgmRat2RgeWgt.sw_gicT_rat2MaxWgt_maxThred - pdyn->epf.diffSgmRat2RgeWgt.sw_gicT_rat2MinWgt_minThred, 0.01);
tmp = ROUND_F(bfFltWgt_slope * (1 << RKGIC_V30_BF_WGT_SCALE_FIX_BITS));
pFix->bffltwgt_scale = CLIP(tmp, 0, 0xff);
/* BILAT_PARA2 */
tmp = ROUND_F(pdyn->epf.sw_gicT_filtOut_alpha * (1 << RKGIC_V30_BF_FLT_RATIO_FIX_BIT));
pFix->bfflt_ratio = CLIP(tmp, 0, 0xff);
/* DISWGT_COEFF */
uint8_t bfflt_coeff[3];
GicV30CreateKernelCoeffs(1, 1, pdyn->epf.sw_gicT_filtSpatial_strg, bfflt_coeff, RKGIC_V30_BF_COEFF_FIX_BITS, 2);
if(pFix->pro_mode == 1)
{
bfflt_coeff[0] = 8;
bfflt_coeff[1] = 4;
bfflt_coeff[2] = 2;
}
for(int i = 0; i < 3; i++) {
bfflt_coeff[i] = CLIP(bfflt_coeff[i], 0, 0x3f);
}
pFix->bfflt_coeff0 = bfflt_coeff[0];
pFix->bfflt_coeff1 = bfflt_coeff[1];
pFix->bfflt_coeff2 = bfflt_coeff[2];
// ydb: let sharp do auto noise curve
if (psta->epf.sw_gicCfg_rgeSgm_mode == gic_autoSigma_mode) {
pBtnrInfo->gic_noise_auto_mode = 1;
} else {
pBtnrInfo->gic_noise_auto_mode = 0;
}
/* SIGMA_Y */
for(int i = 0; i < 17; i++) {
tmp = (pdyn->epf.hw_gicT_luma2Manual_rgeSgm[i]);
pFix->bfflt_vsigma_y[i] = CLIP(tmp, 0, 0x3ff);
}
/* LUMA_DX */
for(int i = 0; i < 7; i++) {
tmp = LOG2(pdyn->lumaLutCfg.hw_gicT_lumaLutIdx_val[i + 1] - pdyn->lumaLutCfg.hw_gicT_lumaLutIdx_val[i]);
pFix->luma_dx[i] = CLIP(tmp, 0, 0xf);
}
/* THRED_Y */
/* MIN_THRED_Y */
if (pFix->manualnoisethred_en) {
for(int i = 0; i < 8; i++) {
tmp = ROUND_F(pdyn->manualSoftThd.hw_gicT_luma2SofThd_thred[i]);
pFix->thred_y[i] = CLIP(tmp, 0, 0x1ff);
}
} else {
for(int i = 0; i < 8; i++) {
tmp = (pdyn->gicPost_guideEpf.autoSoftThd.hw_gicT_luma2Thred_maxLimit[i]);
pFix->thred_y[i] = CLIP(tmp, 0, 0x1ff);
tmp = (pdyn->gicPost_guideEpf.autoSoftThd.hw_gicT_luma2Thred_minLimit[i]);
pFix->minthred_y[i] = CLIP(tmp, 0, 0x1ff);
}
}
/* THRED_SCALE */
tmp = ROUND_F(pdyn->gicPost_guideEpf.autoSoftThd.hw_gicT_softThd_scale * (1 << RKGIC_V30_THED_SCALE_FIX_BITS));
pFix->autonoisethred_scale = CLIP(tmp, 0, 0x3ff);
/* LOFLTGR_COEFF */
uint8_t loFltGr_coeff[4];
for (int i = 0; i < 4; i++) {
tmp = pdyn->gicPost_guideEpf.lpf.hw_gicT_grFiltSpatial_wgt[i];
loFltGr_coeff[i] = CLIP(tmp, 0, 0x1f);
}
pFix->lofltgr_coeff0 = loFltGr_coeff[0];
pFix->lofltgr_coeff1 = loFltGr_coeff[1];
pFix->lofltgr_coeff2 = loFltGr_coeff[2];
pFix->lofltgr_coeff3 = loFltGr_coeff[3];
/* LOFLTGB_COEFF */
tmp = pdyn->gicPost_guideEpf.lpf.hw_gicT_gbFiltSpatial_wgt[0];
pFix->lofltgb_coeff0 = CLIP(tmp, 0, 0x1f);
tmp = pdyn->gicPost_guideEpf.lpf.hw_gicT_gbFiltSpatial_wgt[1];
pFix->lofltgb_coeff1 = CLIP(tmp, 0, 0x1f);
/* SUM_LOFLT_INV */
int sumLoFltGrCoeff = loFltGr_coeff[0] * 2 + loFltGr_coeff[1] + 2 * loFltGr_coeff[2] + loFltGr_coeff[3];
int sumLoFltGbCoeff = pFix->lofltgb_coeff0 * 2 + pFix->lofltgb_coeff1 * 2;
if(sumLoFltGrCoeff != sumLoFltGbCoeff)
{
LOGE_AGIC("sumLoFltGrCoeff must be the same as sumLoFltGbCoeff,\n"
"sumLoFltGrCoeff = grFiltSpatial_wgt[0] * 2 + grFiltSpatial_wgt[1] + 2 * grFiltSpatial_wgt[2] + grFiltSpatial_wgt[3]\n"
"sumLoFltGbCoeff = gbFiltSpatial_wgt[0] * 2 + gbFiltSpatial_wgt[1] * 2\n"
"You can set by gic.dyn.gicPost_guideEpf.lpf.hw_gicT_grFiltSpatial_wgt and gic.dyn.gicPost_guideEpf.lpf.hw_gicT_gbFiltSpatial_wgt\n");
}
tmp = ROUND_F(1.0f / MAX(sumLoFltGrCoeff, sumLoFltGbCoeff) * (1 << RKGIC_V30_COEFF_INV_FIX_BITS));
pFix->sumlofltcoeff_inv = CLIP(tmp, 0, 0x1fff);
/* LOFLTTHRED_COEFF */
tmp = pdyn->gicPost_guideEpf.autoSoftThd.hw_gicT_thredFiltSpatial_wgt[0];
pFix->lofltthred_coeff0 = CLIP(tmp, 0, 0x1f);
tmp = pdyn->gicPost_guideEpf.autoSoftThd.hw_gicT_thredFiltSpatial_wgt[1];
pFix->lofltthred_coeff1 = CLIP(tmp, 0, 0x1f);
if (pFix->lofltthred_coeff0 * 2 + pFix->lofltthred_coeff1 != 16) {
float ratio = (float)pFix->lofltthred_coeff0 / (float)(pFix->lofltthred_coeff0 * 2 + pFix->lofltthred_coeff1);
pFix->lofltthred_coeff0 = (int)(ratio * 16.0f);
pFix->lofltthred_coeff1 = 16 - pFix->lofltthred_coeff0 * 2;
LOGW_AGIC("(thredFiltSpatial_wgt[0]*2+thredFiltSpatial_wgt[1]) must be 16, "
"they are forcibly allocated weights according to the proportion set by the user in HWI, "
"which is [%d, %d].\n You can set by gic.dyn.gicPost_guideEpf.autoSoftThd.hw_gicT_thredFiltSpatial_wgt\n",
pFix->lofltthred_coeff0, pFix->lofltthred_coeff1);
}
/* GAIN */
tmp = pdyn->locGicStrg.locSgmStrg.hw_gicT_glbSgmStrg_alpha * (1 << RKGIC_V30_G_GAIN_ALPHA_FIX_BITS);
pFix->globalgain_alpha = CLIP(tmp, 0, 0xf);
tmp = pdyn->locGicStrg.locSgmStrg.hw_gicT_locSgmStrg_scale * (1 << RKGIC_V30_GAIN_ISO_FIX_BITS);
pFix->globalgain_scale = CLIP(tmp, 0, 0xff);
tmp = pdyn->locGicStrg.locSgmStrg.hw_gicT_glbSgmStrg_val * (1 << RKGIC_V30_LOCAL_GAIN_FIX_BITS);
pFix->global_gain = CLIP(tmp, 0, 0x3ff);
/* GAIN_SLOPE */
tmp = ROUND_F(pdyn->locGicStrg.locSgmStrg2GicStrg.sw_gicT_locSgmStrgStat_maxThred * (1 << RKGIC_V30_LOCAL_GAIN_FIX_BITS));
pFix->gain_offset = CLIP(tmp, 0, 0x3ff);
float gain_adj_strg_slope = (pdyn->locGicStrg.locSgmStrg2GicStrg.hw_shpT_motRegionGic_strg - pdyn->locGicStrg.locSgmStrg2GicStrg.hw_shpT_statRegionGic_strg)
/ MAX(pdyn->locGicStrg.locSgmStrg2GicStrg.sw_gicT_locSgmStrgMot_minThred - pdyn->locGicStrg.locSgmStrg2GicStrg.sw_gicT_locSgmStrgStat_maxThred, 0.01);
tmp = ROUND_F(gain_adj_strg_slope * (1 << RKGIC_V30_GAIN_SCALE_FIX_BITS));
pFix->gain_scale = CLIP(tmp, 0, 0x3fff);
/* GAIN_THRED */
tmp = ROUND_F(pdyn->locGicStrg.locSgmStrg2GicStrg.hw_shpT_statRegionGic_strg * (1 << RKGIC_V30_sgmRatio_FIX_BITS));
pFix->gainadjflt_minthred = CLIP(tmp, 0, 0x3ff);
tmp = ROUND_F(pdyn->locGicStrg.locSgmStrg2GicStrg.hw_shpT_motRegionGic_strg * (1 << RKGIC_V30_sgmRatio_FIX_BITS));
pFix->gainadjflt_maxthred = CLIP(tmp, 0, 0x3ff);
return;
}