#include "third_party_af_algo.h"
|
#include "rk_aiq_user_api2_sysctl.h"
|
|
static void set_af_manual_meascfg(const rk_aiq_sys_ctx_t* ctx)
|
{
|
rk_aiq_af_attrib_t attr;
|
uint16_t gamma_y[RKAIQ_RAWAF_GAMMA_NUM] =
|
{0, 45, 108, 179, 245, 344, 409, 459, 500, 567, 622, 676, 759, 833, 896, 962, 1023};
|
|
rk_aiq_user_api2_af_GetAttrib(ctx, &attr);
|
attr.AfMode = RKAIQ_AF_MODE_FIXED;
|
if (attr.AfHwVer == RKAIQ_AF_HW_V20) {
|
// rv1126/rv1109 rk356x
|
memset(&attr.manual_meascfg, 0, sizeof(attr.manual_meascfg));
|
attr.manual_meascfg.contrast_af_en = 1;
|
attr.manual_meascfg.rawaf_sel = 0; // normal = 0; hdr = 1
|
|
attr.manual_meascfg.window_num = 2;
|
attr.manual_meascfg.wina_h_offs = 2;
|
attr.manual_meascfg.wina_v_offs = 2;
|
attr.manual_meascfg.wina_h_size = 2580;
|
attr.manual_meascfg.wina_v_size = 1935;
|
|
attr.manual_meascfg.winb_h_offs = 500;
|
attr.manual_meascfg.winb_v_offs = 600;
|
attr.manual_meascfg.winb_h_size = 300;
|
attr.manual_meascfg.winb_v_size = 300;
|
|
attr.manual_meascfg.gamma_flt_en = 1;
|
memcpy(attr.manual_meascfg.gamma_y, gamma_y, RKAIQ_RAWAF_GAMMA_NUM * sizeof(uint16_t));
|
|
attr.manual_meascfg.gaus_flt_en = 1;
|
attr.manual_meascfg.gaus_h0 = 0x20;
|
attr.manual_meascfg.gaus_h1 = 0x10;
|
attr.manual_meascfg.gaus_h2 = 0x08;
|
|
attr.manual_meascfg.afm_thres = 4;
|
|
attr.manual_meascfg.lum_var_shift[0] = 0;
|
attr.manual_meascfg.afm_var_shift[0] = 0;
|
attr.manual_meascfg.lum_var_shift[1] = 4;
|
attr.manual_meascfg.afm_var_shift[1] = 4;
|
|
attr.manual_meascfg.sp_meas.enable = true;
|
attr.manual_meascfg.sp_meas.ldg_xl = 10;
|
attr.manual_meascfg.sp_meas.ldg_yl = 28;
|
attr.manual_meascfg.sp_meas.ldg_kl = (255-28)*256/45;
|
attr.manual_meascfg.sp_meas.ldg_xh = 118;
|
attr.manual_meascfg.sp_meas.ldg_yh = 8;
|
attr.manual_meascfg.sp_meas.ldg_kh = (255-8)*256/15;
|
attr.manual_meascfg.sp_meas.highlight_th = 245;
|
attr.manual_meascfg.sp_meas.highlight2_th = 200;
|
} else if (attr.AfHwVer == RKAIQ_AF_HW_V30) {
|
// rk3588
|
memset(&attr.manual_meascfg_v30, 0, sizeof(attr.manual_meascfg_v30));
|
attr.manual_meascfg_v30.af_en = 1;
|
attr.manual_meascfg_v30.rawaf_sel = 0; // normal = 0; hdr = 1
|
attr.manual_meascfg_v30.accu_8bit_mode = 1;
|
attr.manual_meascfg_v30.ae_mode = 1;
|
|
attr.manual_meascfg_v30.window_num = 2;
|
attr.manual_meascfg_v30.wina_h_offs = 2;
|
attr.manual_meascfg_v30.wina_v_offs = 2;
|
attr.manual_meascfg_v30.wina_h_size = 2580;
|
attr.manual_meascfg_v30.wina_v_size = 1935;
|
|
attr.manual_meascfg_v30.winb_h_offs = 500;
|
attr.manual_meascfg_v30.winb_v_offs = 600;
|
attr.manual_meascfg_v30.winb_h_size = 300;
|
attr.manual_meascfg_v30.winb_v_size = 300;
|
|
attr.manual_meascfg_v30.gamma_en = 1;
|
memcpy(attr.manual_meascfg_v30.gamma_y, gamma_y, RKAIQ_RAWAF_GAMMA_NUM * sizeof(uint16_t));
|
|
// param for winb
|
attr.manual_meascfg_v30.thres = 4;
|
attr.manual_meascfg_v30.shift_sum_a = 0;
|
attr.manual_meascfg_v30.shift_y_a = 0;
|
attr.manual_meascfg_v30.shift_sum_b = 1;
|
attr.manual_meascfg_v30.shift_y_b = 1;
|
|
// Vertical filter
|
// face [0.025, 0.06], max=0.5
|
int ver_flt_face[6] =
|
{ 503, 8, 9, -1997, 0, 1997 };
|
|
// lowlit [0.025, 0.075], max=0.5
|
int ver_flt_lowlit[6] =
|
{ 503, 8, 9, -1997, 0, 1997 };
|
|
// normal [0.042, 0.14], max=0.5
|
int ver_flt_normal[6] =
|
{ 483, 28, 28, -1186, 0, 1186 };
|
|
// high [0.055, 0.125], max=0.5
|
int ver_flt_high[6] =
|
{ 483, 27, 28, -1212, 0, 1212 };
|
|
// dotlight [0.1 0.175], max=0.5
|
int ver_flt_dotlight[6] =
|
{ 445, 63, 64, -531, 0, 531 };
|
|
// full [0.025, 0.175], max=0.5
|
int ver_flt_full[6] =
|
{ 476, 33, 34, -985, 0, 985 };
|
|
attr.manual_meascfg_v30.gaus_en = 1;
|
attr.manual_meascfg_v30.v1_fir_sel = 1; // 0:old 1:new
|
attr.manual_meascfg_v30.viir_en = 1;
|
attr.manual_meascfg_v30.v1_fv_outmode = 0; // 0 square, 1 absolute
|
attr.manual_meascfg_v30.v2_fv_outmode = 0; // 0 square, 1 absolute
|
attr.manual_meascfg_v30.v1_fv_shift = 1; //only for sel1
|
attr.manual_meascfg_v30.v2_fv_shift = 1;
|
attr.manual_meascfg_v30.v_fv_thresh = 0;
|
attr.manual_meascfg_v30.v1_iir_coe[1] = ver_flt_lowlit[0];
|
attr.manual_meascfg_v30.v1_iir_coe[4] = ver_flt_lowlit[1];
|
attr.manual_meascfg_v30.v1_iir_coe[7] = ver_flt_lowlit[2];
|
for (int i = 0; i < 3; i++) {
|
attr.manual_meascfg_v30.v1_fir_coe[i] = ver_flt_lowlit[i + 3];
|
attr.manual_meascfg_v30.v2_iir_coe[i] = ver_flt_normal[i];
|
attr.manual_meascfg_v30.v2_fir_coe[i] = ver_flt_normal[i + 3];
|
}
|
|
// Horizontal filter
|
// low [0.0125, 0.03], max=0.5
|
int hor_flt_low[2][6] =
|
{
|
{ 31, 960, -462, 546, 0, -546 },
|
{ 17, 994, -486, 665, 0, -665 },
|
};
|
// face [0.025, 0.06], max=0.5
|
int hor_flt_face[2][6] =
|
{
|
{ 117, 877, -417, 805, 0, -805 },
|
{ 23, 957, -460, 334, 0, -334 },
|
};
|
// lowlit [0.025, 0.075], max=0.5
|
int hor_flt_lowlit[2][6] =
|
{
|
{ 203, 811, -375, 673, 0, -673 },
|
{ 31, 945, -448, 323, 0, -323 },
|
};
|
// normal [0.042, 0.14], max=0.5
|
int hor_flt_normal[2][6] =
|
{
|
{ 512, 557, -276, 460, 0, -460 },
|
{ 100, 870, -399, 191, 0, -191 },
|
};
|
// high [0.055, 0.125], max=0.5
|
int hor_flt_high[2][6] =
|
{
|
{ 415, 648, -344, 403, 0, -403 },
|
{ 96, 854, -409, 156, 0, -156 },
|
};
|
// dotlight [0.1 0.175], max=0.5
|
int hor_flt_dotlight[2][6] =
|
{
|
{ 512, 447, -349, 319, 0, -319 },
|
{ 181, 698, -386, 96, 0, -96 },
|
};
|
// full [0.025, 0.175], max=0.5
|
int hor_flt_full[2][6] =
|
{
|
{ 512, 362, -171, 512, 0, -512 },
|
{ 114, 915, -417, 302, 0, -302 },
|
};
|
attr.manual_meascfg_v30.hiir_en = 1;
|
attr.manual_meascfg_v30.h1_fv_outmode = 0; // 0 square, 1 absolute
|
attr.manual_meascfg_v30.h2_fv_outmode = 0; // 0 square, 1 absolute
|
attr.manual_meascfg_v30.h1_fv_shift = 1;
|
attr.manual_meascfg_v30.h2_fv_shift = 1;
|
attr.manual_meascfg_v30.h_fv_thresh = 0;
|
for (int i = 0; i < 6; i++) {
|
attr.manual_meascfg_v30.h1_iir1_coe[i] = hor_flt_lowlit[0][i];
|
attr.manual_meascfg_v30.h1_iir2_coe[i] = hor_flt_lowlit[1][i];
|
attr.manual_meascfg_v30.h2_iir1_coe[i] = hor_flt_normal[0][i];
|
attr.manual_meascfg_v30.h2_iir2_coe[i] = hor_flt_normal[1][i];
|
}
|
|
// level depended gain
|
attr.manual_meascfg_v30.ldg_en = 0;
|
attr.manual_meascfg_v30.h_ldg_lumth[0] = 64;
|
attr.manual_meascfg_v30.h_ldg_gain[0] = 28;
|
attr.manual_meascfg_v30.h_ldg_gslp[0] = (255-28)*255/45;
|
attr.manual_meascfg_v30.h_ldg_lumth[1] = 185;
|
attr.manual_meascfg_v30.h_ldg_gain[1] = 8;
|
attr.manual_meascfg_v30.h_ldg_gslp[1] = (255-8)*255/45;
|
attr.manual_meascfg_v30.v_ldg_lumth[0] = 64;
|
attr.manual_meascfg_v30.v_ldg_gain[0] = 28;
|
attr.manual_meascfg_v30.v_ldg_gslp[0] = (255-28)*255/45;
|
attr.manual_meascfg_v30.v_ldg_lumth[1] = 185;
|
attr.manual_meascfg_v30.v_ldg_gain[1] = 8;
|
attr.manual_meascfg_v30.v_ldg_gslp[1] = (255-8)*255/45;
|
|
// High light
|
attr.manual_meascfg_v30.highlit_thresh = 912;
|
}
|
|
attr.sync.sync_mode = RK_AIQ_UAPI_MODE_SYNC;
|
rk_aiq_user_api2_af_SetAttrib(ctx, &attr);
|
printf("setFocusMeasCfg\n");
|
}
|
|
static void print_af_stats(rk_aiq_isp_stats_t *stats_ref)
|
{
|
unsigned long sof_time;
|
|
// show af stats every 30 frames
|
if (stats_ref->frame_id % 30 != 0)
|
return;
|
|
if (stats_ref->af_hw_ver == RKAIQ_AF_HW_V20) {
|
// rv1126/rv1109 rk356x
|
sof_time = stats_ref->af_stats.sof_tim / 1000000LL;
|
printf("sof_tim %ld, sharpness roia: 0x%llx-0x%08x roib: 0x%x-0x%08x\n",
|
sof_time,
|
stats_ref->af_stats.roia_sharpness,
|
stats_ref->af_stats.roia_luminance,
|
stats_ref->af_stats.roib_sharpness,
|
stats_ref->af_stats.roib_luminance);
|
|
printf("global_sharpness\n");
|
for (int i = 0; i < 15; i++) {
|
for (int j = 0; j < 15; j++) {
|
printf("0x%08x, ", stats_ref->af_stats.global_sharpness[15 * i + j]);
|
}
|
printf("\n");
|
}
|
printf("lowpass_fv4_4\n");
|
for (int i = 0; i < 15; i++) {
|
for (int j = 0; j < 15; j++) {
|
printf("0x%08x, ", stats_ref->af_stats.lowpass_fv4_4[15 * i + j]);
|
}
|
printf("\n");
|
}
|
printf("lowpass_fv8_8\n");
|
for (int i = 0; i < 15; i++) {
|
for (int j = 0; j < 15; j++) {
|
printf("0x%08x, ", stats_ref->af_stats.lowpass_fv8_8[15 * i + j]);
|
}
|
printf("\n");
|
}
|
printf("lowpass_highlht\n");
|
for (int i = 0; i < 15; i++) {
|
for (int j = 0; j < 15; j++) {
|
printf("0x%08x, ", stats_ref->af_stats.lowpass_highlht[15 * i + j]);
|
}
|
printf("\n");
|
}
|
printf("lowpass_highlht2\n");
|
for (int i = 0; i < 15; i++) {
|
for (int j = 0; j < 15; j++) {
|
printf("0x%08x, ", stats_ref->af_stats.lowpass_highlht2[15 * i + j]);
|
}
|
printf("\n");
|
}
|
} else if (stats_ref->af_hw_ver == RKAIQ_AF_HW_V30) {
|
// rk3588
|
sof_time = stats_ref->af_stats_v3x.sof_tim / 1000000LL;
|
printf("sof_tim %ld, winb: fv %d, luma %d, highlit_cnt %d\n",
|
sof_time,
|
stats_ref->af_stats_v3x.wndb_sharpness,
|
stats_ref->af_stats_v3x.wndb_luma,
|
stats_ref->af_stats_v3x.winb_highlit_cnt);
|
|
printf("wnda_fv_h1\n");
|
for (int i = 0; i < 15; i++) {
|
for (int j = 0; j < 15; j++) {
|
printf("0x%08x, ", stats_ref->af_stats_v3x.wnda_fv_h1[15 * i + j]);
|
}
|
printf("\n");
|
}
|
printf("wnda_fv_h2\n");
|
for (int i = 0; i < 15; i++) {
|
for (int j = 0; j < 15; j++) {
|
printf("0x%08x, ", stats_ref->af_stats_v3x.wnda_fv_h2[15 * i + j]);
|
}
|
printf("\n");
|
}
|
printf("wnda_fv_v1\n");
|
for (int i = 0; i < 15; i++) {
|
for (int j = 0; j < 15; j++) {
|
printf("0x%08x, ", stats_ref->af_stats_v3x.wnda_fv_v1[15 * i + j]);
|
}
|
printf("\n");
|
}
|
printf("wnda_fv_v2\n");
|
for (int i = 0; i < 15; i++) {
|
for (int j = 0; j < 15; j++) {
|
printf("0x%08x, ", stats_ref->af_stats_v3x.wnda_fv_v2[15 * i + j]);
|
}
|
printf("\n");
|
}
|
printf("wnda_luma\n");
|
for (int i = 0; i < 15; i++) {
|
for (int j = 0; j < 15; j++) {
|
printf("0x%08x, ", stats_ref->af_stats_v3x.wnda_luma[15 * i + j]);
|
}
|
printf("\n");
|
}
|
printf("wina_highlit_cnt\n");
|
for (int i = 0; i < 15; i++) {
|
for (int j = 0; j < 15; j++) {
|
printf("0x%08x, ", stats_ref->af_stats_v3x.wina_highlit_cnt[15 * i + j]);
|
}
|
printf("\n");
|
}
|
}
|
}
|
|
static void custom_af_algo(rk_aiq_isp_stats_t *stats_ref)
|
{
|
// show af stats
|
print_af_stats(stats_ref);
|
|
// run af algo
|
|
// move zoom/focus motor
|
|
}
|
|
static void* af_thread(void* args) {
|
rk_aiq_sys_ctx_t* ctx = (rk_aiq_sys_ctx_t*)args;
|
XCamReturn ret;
|
pthread_detach (pthread_self());
|
printf("begin af thread\n");
|
|
// set af meas config
|
set_af_manual_meascfg(ctx);
|
while(1) {
|
rk_aiq_isp_stats_t *stats_ref = NULL;
|
// get 3a stats
|
ret = rk_aiq_uapi2_sysctl_get3AStatsBlk(ctx, &stats_ref, -1);
|
if (ret == XCAM_RETURN_NO_ERROR && stats_ref != NULL) {
|
printf("get one stats frame id %d \n", stats_ref->frame_id);
|
custom_af_algo(stats_ref);
|
// release 3a stats
|
rk_aiq_uapi2_sysctl_release3AStatsRef(ctx, stats_ref);
|
} else {
|
if (ret == XCAM_RETURN_NO_ERROR) {
|
printf("aiq has stopped !\n");
|
break;
|
} else if (ret == XCAM_RETURN_ERROR_TIMEOUT) {
|
printf("aiq timeout!\n");
|
continue;
|
} else if (ret == XCAM_RETURN_ERROR_FAILED) {
|
printf("aiq failed!\n");
|
break;
|
}
|
}
|
}
|
printf("end stats thread\n");
|
return 0;
|
}
|
|
int32_t custom_af_run(rk_aiq_sys_ctx_t* ctx)
|
{
|
pthread_t af_tid;
|
pthread_create(&af_tid, NULL, af_thread, ctx);
|
|
return 0;
|
}
|