#include "aiisp_ai.h"
#define AI_DDRID DDR_ID0
///////////////////////////////////////////////////////////////////////////////
#define DUMP_POSTPROC_INFO 0
#define DBG_OUT_DUMP 0 // debug mode, dump output iobuf
///////////////////////////////////////////////////////////////////////////////
#define VENDOR_AI_CFG 0x000f0000 //vendor ai config
#define AI_RGB_BUFSIZE(w, h) (ALIGN_CEIL_4((w) * HD_VIDEO_PXLFMT_BPP(HD_VIDEO_PXLFMT_RGB888_PLANAR) / 8) * (h))
///////////////////////////////////////////////////////////////////////////////
/*-----------------------------------------------------------------------------*/
/* Global Functions */
/*-----------------------------------------------------------------------------*/
#if AI_ENABLE
static HD_RESULT mem_alloc(MEM_PARM *mem_parm, CHAR* name, UINT32 size)
{
HD_RESULT ret = HD_OK;
UINTPTR pa = 0;
void *va = NULL;
//alloc private pool
ret = hd_common_mem_alloc(name, &pa, (void**)&va, size, AI_DDRID);
if (ret!= HD_OK) {
return ret;
}
mem_parm->pa = pa;
mem_parm->va = (UINTPTR)va;
mem_parm->size = size;
mem_parm->blk = (UINT32)-1;
return HD_OK;
}
static HD_RESULT mem_free(MEM_PARM *mem_parm)
{
HD_RESULT ret = HD_OK;
//free private pool
ret = hd_common_mem_free(mem_parm->pa, (void *)mem_parm->va);
if (ret!= HD_OK) {
return ret;
}
mem_parm->pa = 0;
mem_parm->va = 0;
mem_parm->size = 0;
mem_parm->blk = (UINT32)-1;
return HD_OK;
}
#endif
/*-----------------------------------------------------------------------------*/
/* Input Functions */
/*-----------------------------------------------------------------------------*/
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/*-----------------------------------------------------------------------------*/
/* Network Functions */
/*-----------------------------------------------------------------------------*/
typedef enum {
NET_IN_INPUT_COEFFA,
NET_IN_INPUT_COEFFB,
NET_IN_INPUT_BLEND,
NET_IN_INPUT_MAX,
ENUM_DUMMY4WORD(NET_IN_INPUT)
} NET_IN_INPUT;
typedef struct _NET_IN {
NET_IN_CONFIG in_cfg[NET_IN_INPUT_MAX];
MEM_PARM input_mem[NET_IN_INPUT_MAX];
UINT32 in_id;
VENDOR_AI3_BUF src_img[NET_IN_INPUT_MAX];
} NET_IN;
#if (AI_ENABLE)
typedef enum _AI_MODEL_FUNCTION {
BAYER_AI_3DNR = 1,
BAYER_AI_2DNR,
AI_MODEL_TOTAL,
ENUM_DUMMY4WORD(AI_MODEL_FUNCTION)
} AI_MODEL_FUNCTION;
typedef enum _AI_3DNR_MODEL_VERSION {
FULL_VERSION = 0,
LITE_VERSION,
FUSION_VERSION,
FULL_VERSION_HDR,
FUSION_VERSION_HDR,
ENUM_DUMMY4WORD(AI_3DNR_MODEL_VERSION)
} AI_3DNR_MODEL_VERSION;
typedef struct _AI_MODEL_TAG {
//Word 0
UINT8 function; //Byte 0
UINT8 model_version; //Byte 1
UINT8 compu_utility_version; //Byte 2
UINT8 optimize_info; //Byte 3
//Word 1
UINT8 minor_version_num; //Byte 0
UINT8 reserved0; //Byte 1
UINT8 reserved1; //Byte 2
UINT8 reserved2; //Byte 3
//Word 2
UINT8 reserved3; //Byte 0
UINT8 reserved4; //Byte 1
UINT8 reserved5; //Byte 2
UINT8 reserved6; //Byte 3
//Word 3
UINT16 min_coefa; //U16, Byte 1..0
UINT16 max_coefa; //U16, Byte 3..2
//Word 4
UINT16 min_coefb; //U16, Byte 1..0
UINT16 max_coefb; //U16, Byte 3..2
//Word 5
UINT8 iso_low; // 0:ISO100, 1:ISO200,... , byte 0
UINT8 iso_high; // 0:ISO100, 1:ISO200,... , byte 1
UINT8 dummy0; //byte 2
UINT8 dummy1; //byte 3
} AI_MODEL_TAG;
#endif
#if AI_ENABLE
NET_PROC g_net[16] = {0};
static NET_IN g_in[16] = {0};
HD_RESULT aiisp_input_init(void)
{
HD_RESULT ret = HD_OK;
int i;
for (i = 0; i < 16; i++) {
NET_IN* p_net = g_in + i;
p_net->in_id = i;
}
return ret;
}
HD_RESULT aiisp_input_uninit(void)
{
HD_RESULT ret = HD_OK;
return ret;
}
static INT32 _getsize_model(char* filename)
{
FILE *bin_fd;
UINT32 bin_size = 0;
bin_fd = fopen(filename, "rb");
if (!bin_fd) {
printf("get bin(%s) size fail\n", filename);
return (-1);
}
fseek(bin_fd, 0, SEEK_END);
bin_size = ftell(bin_fd);
fseek(bin_fd, 0, SEEK_SET);
fclose(bin_fd);
return bin_size;
}
static UINT32 _load_model(CHAR *filename, UINTPTR va)
{
FILE *fd;
UINT32 file_size = 0, read_size = 0;
const UINTPTR model_addr = va;
//DBG_DUMP("model addr = %08x\r\n", (int)model_addr);
fd = fopen(filename, "rb");
if (!fd) {
printf("load model(%s) fail\r\n", filename);
return 0;
}
fseek ( fd, 0, SEEK_END );
file_size = ALIGN_CEIL_4( ftell(fd) );
fseek ( fd, 0, SEEK_SET );
read_size = fread ((void *)model_addr, 1, file_size, fd);
if (read_size != file_size) {
printf("size mismatch, real = %d, idea = %d\r\n", (int)read_size, (int)file_size);
}
fclose(fd);
printf("load model(%s) ok\r\n", filename);
return read_size;
}
static HD_RESULT network_alloc_io_buf(NET_PATH_ID net_path, UINT32 req_size)
{
HD_RESULT ret = HD_OK;
NET_PROC* p_net = g_net + net_path;
CHAR mem_name[23] ;
snprintf(mem_name, 23, "ai_io_buf %u", net_path);
ret = mem_alloc(&p_net->io_mem, mem_name, req_size);
if (ret != HD_OK) {
printf("net_path(%lu) alloc ai_io_buf fail\r\n", net_path);
return HD_ERR_FAIL;
}
printf("alloc_io_buf: work buf, pa = %#lx, va = %#lx, size = %lu\r\n", p_net->io_mem.pa, p_net->io_mem.va, p_net->io_mem.size);
return ret;
}
static HD_RESULT network_free_io_buf(NET_PATH_ID net_path)
{
HD_RESULT ret = HD_OK;
NET_PROC* p_net = g_net + net_path;
if (p_net->io_mem.pa && p_net->io_mem.va) {
mem_free(&p_net->io_mem);
}
return ret;
}
static HD_RESULT network_alloc_intl_buf(NET_PATH_ID net_path, UINT32 req_size)
{
HD_RESULT ret = HD_OK;
NET_PROC* p_net = g_net + net_path;
CHAR mem_name[23] ;
snprintf(mem_name, 23, "ai_ronly_buf %u", net_path);
ret = mem_alloc(&p_net->intl_mem, mem_name, req_size);
if (ret != HD_OK) {
printf("net_path(%lu) alloc ai_ronly_buf fail\r\n", net_path);
return HD_ERR_FAIL;
}
printf("alloc_intl_buf: internal buf, pa = %#lx, va = %#lx, size = %lu\r\n", p_net->intl_mem.pa, p_net->intl_mem.va, p_net->intl_mem.size);
return ret;
}
static HD_RESULT network_free_intl_buf(NET_PATH_ID net_path)
{
HD_RESULT ret = HD_OK;
NET_PROC* p_net = g_net + net_path;
if (p_net->intl_mem.pa && p_net->intl_mem.va) {
mem_free(&p_net->intl_mem);
}
return ret;
}
static HD_RESULT network_alloc_input_buf(NET_PATH_ID net_path, UINT32 req_size)
{
HD_RESULT ret = HD_OK;
NET_PROC* p_net = g_net + net_path;
CHAR mem_name[23] ;
snprintf(mem_name, 23, "ai_input_buf %u", net_path);
ret = mem_alloc(&p_net->input_mem, mem_name, req_size);
if (ret != HD_OK) {
printf("net_path(%lu) alloc ai_input_buf fail\r\n", net_path);
return HD_ERR_FAIL;
}
printf("alloc_input_buf: work buf, pa = %#lx, va = %#lx, size = %lu\r\n", p_net->input_mem.pa, p_net->input_mem.va, p_net->input_mem.size);
return ret;
}
static HD_RESULT network_free_input_buf(NET_PATH_ID net_path)
{
HD_RESULT ret = HD_OK;
NET_PROC* p_net = g_net + net_path;
if (p_net->input_mem.pa && p_net->input_mem.va) {
mem_free(&p_net->input_mem);
}
return ret;
}
HD_RESULT aiisp_network_init(void)
{
HD_RESULT ret = HD_OK;
// call init
{
VENDOR_AI3_DEV_CFG dev_cfg = {0};
ret = vendor_ai3_dev_init(&dev_cfg);
if (ret != HD_OK) {
printf("aiisp vendor_ai3_dev_init fail=%d\n", ret);
return ret;
}
}
// dump AI3 version
{
VENDOR_AI3_VER ai3_ver = {0};
ret = vendor_ai3_dev_get(VENDOR_AI3_CFG_VER, &ai3_ver);
if (ret != HD_OK) {
printf("vendor_ai3_dev_get(CFG_VER) fail=%d\n", ret);
return ret;
}
printf("vendor_ai version = %s\r\n", ai3_ver.vendor_ai_impl_version);
printf("kflow_ai version = %s\r\n", ai3_ver.kflow_ai_impl_version);
printf("kdrv_ai version = %s\r\n", ai3_ver.kdrv_ai_impl_version);
}
return ret;
}
HD_RESULT aiisp_network_uninit(void)
{
HD_RESULT ret = HD_OK;
ret = vendor_ai3_dev_uninit();
if (ret != HD_OK) {
printf("vendor_ai3_dev_uninit fail=%d\n", ret);
}
return ret;
}
INT32 aiisp_network_mem_config(NET_PATH_ID net_path, void* p_cfg)
{
NET_PROC* p_net = g_net + net_path;
NET_PROC_CONFIG* p_proc_cfg = (NET_PROC_CONFIG*)p_cfg;
memcpy((void*)&p_net->net_cfg, (void*)p_proc_cfg, sizeof(NET_PROC_CONFIG));
if (strlen(p_net->net_cfg.model_filename) == 0) {
printf("net_path(%u) input model is null\r\n", net_path);
return HD_ERR_NG;
}
p_net->net_cfg.binsize = _getsize_model(p_net->net_cfg.model_filename);
if (p_net->net_cfg.binsize <= 0) {
printf("net_path(%u) input model is not exist?\r\n", net_path);
return HD_ERR_NG;
}
printf("net_path(%u) set net_mem_cfg: model-file(%s), binsize=%d\r\n",
net_path,
p_net->net_cfg.model_filename,
p_net->net_cfg.binsize);
return HD_OK;
}
HD_RESULT aiisp_network_open(NET_PATH_ID net_path)
{
HD_RESULT ret = HD_OK;
NET_PROC* p_net = g_net + net_path;
UINT32 loadsize = 0;
CHAR mem_name[23] ;
snprintf(mem_name, 23, "model.bin %u", net_path);
if (strlen(p_net->net_cfg.model_filename) == 0) {
printf("net_path(%u) input model is null\r\n", net_path);
return 0;
}
ret = mem_alloc(&p_net->proc_mem, mem_name, p_net->net_cfg.binsize);
if (ret != HD_OK) {
printf("net_path(%u) mem_alloc model.bin fail=%d\n", net_path, ret);
return HD_ERR_FAIL;
}
//load file
loadsize = _load_model(p_net->net_cfg.model_filename, p_net->proc_mem.va);
if (loadsize <= 0) {
printf("net_path(%u) input model load fail: %s\r\n", net_path, p_net->net_cfg.model_filename);
return 0;
}
// query model info for WORKBUF/RONLYBUF size , then alloc WORKBUF/RONLYBUF
{
VENDOR_AI3_MODEL_INFO model_info = {0};
model_info.model_buf.pa = p_net->proc_mem.pa;
model_info.model_buf.va = p_net->proc_mem.va;
model_info.model_buf.size = p_net->proc_mem.size;
#if DBG_OUT_DUMP
model_info.ctrl = CTRL_BUF_DEBUG | CTRL_JOB_DEBUG | CTRL_JOB_DUMPOUT;
#endif
ret = vendor_ai3_dev_get(VENDOR_AI3_CFG_MODEL_INFO, &model_info);
if (ret != HD_OK) {
printf("net_path(%u) vendor_ai3_dev_get(MODEL_INFO) fail=%d\n", net_path, ret);
return HD_ERR_FAIL;
}
printf("model_info get => workbuf size = %d, ronlybuf size = %d\r\n", model_info.proc_mem.buf[AI3_PROC_BUF_WORKBUF].size, model_info.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].size);
// alloc WORKBUF/RONLYBUF
ret = network_alloc_intl_buf(net_path, model_info.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].size);
if (ret != HD_OK) {
printf("net_path(%u) alloc ronlybuf fail=%d\n", net_path, ret);
return HD_ERR_FAIL;
}
if(net_path == 0 ) {
ret = network_alloc_io_buf(net_path, model_info.proc_mem.buf[AI3_PROC_BUF_WORKBUF].size);
if (ret != HD_OK) {
printf("net_path(%u) alloc workbuf fail=%d\n", net_path, ret);
return HD_ERR_FAIL;
}
}
ret = network_alloc_input_buf(net_path, 0x10000);
if (ret != HD_OK) {
printf("net_path(%u) alloc workbuf fail=%d\n", net_path, ret);
return HD_ERR_FAIL;
}
{
//default
p_net->noise_profile[0].noise_base = 378;
p_net->noise_profile[0].noise_slope = 9762;
p_net->snr_strength[0].min_motion = 3276;
p_net->snr_strength[0].max_motion = 4095;
p_net->snr_strength[0].min_detail = 410;
p_net->snr_strength[0].max_detail = 410;
p_net->use_reference[0].blend = 1;
//disable 3D
p_net->noise_profile[1].noise_base = 378;
p_net->noise_profile[1].noise_slope = 9762;
p_net->snr_strength[1].min_motion = 3276;
p_net->snr_strength[1].max_motion = 4095;
p_net->snr_strength[1].min_detail = 410;
p_net->snr_strength[1].max_detail = 410;
p_net->use_reference[1].blend = 0;
//small noise profile
p_net->noise_profile[2].noise_base = 141;
p_net->noise_profile[2].noise_slope = 4994;
p_net->snr_strength[2].min_motion = 3276;
p_net->snr_strength[2].max_motion = 4095;
p_net->snr_strength[2].min_detail = 410;
p_net->snr_strength[2].max_detail = 410;
p_net->use_reference[2].blend = 1;
}
}
// call open()
{
VENDOR_AI3_PROC_CFG proc_cfg = {0};
proc_cfg.model_buf.pa = p_net->proc_mem.pa;
proc_cfg.model_buf.va = p_net->proc_mem.va;
proc_cfg.model_buf.size = p_net->proc_mem.size;
proc_cfg.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].pa = p_net->intl_mem.pa;
proc_cfg.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].va = p_net->intl_mem.va;
proc_cfg.proc_mem.buf[AI3_PROC_BUF_RONLYBUF].size = p_net->intl_mem.size;
proc_cfg.proc_mem.buf[AI3_PROC_BUF_WORKBUF].pa = g_net->io_mem.pa;
proc_cfg.proc_mem.buf[AI3_PROC_BUF_WORKBUF].va = g_net->io_mem.va;
proc_cfg.proc_mem.buf[AI3_PROC_BUF_WORKBUF].size = g_net->io_mem.size;
proc_cfg.plugin[AI3_PLUGIN_CPU] = vendor_ai_cpu1_get_engine();
proc_cfg.config[AI3_PROC_CFG_ISP_POOL_ID] = ISP_POOL_ID(0) ;
proc_cfg.config[AI3_PROC_CFG_ISP_MODE] = AI3_ISP_MULTI_ISO_MODE ;
#if DBG_OUT_DUMP
proc_cfg.ctrl = CTRL_BUF_DEBUG | CTRL_JOB_DEBUG | CTRL_JOB_DUMPOUT;
#endif
ret = vendor_ai3_net_open(&p_net->proc_id, &proc_cfg, &p_net->net_info);
if (ret != HD_OK) {
printf("net_path(%u) vendor_ai3_net_open() fail=%d\n", net_path, ret);
return HD_ERR_FAIL;
} else {
printf("net_path(%u) open success => get proc_id(%u), need to set (%u)input buf, (%u)output buf\r\n", net_path, p_net->proc_id, p_net->net_info.in_buf_cnt, p_net->net_info.out_buf_cnt);
}
}
return ret;
}
HD_RESULT aiisp_network_close(NET_PATH_ID net_path)
{
HD_RESULT ret = HD_OK;
NET_PROC* p_net = g_net + net_path;
UINT32 proc_id = p_net->proc_id;
// close
ret = vendor_ai3_net_close(proc_id);
if (ret != HD_OK) {
printf("net_path(%u), proc_id(%u) vendor_ai3_net_close fail=%d\n", net_path, proc_id, ret);
return HD_ERR_FAIL;
}
if ((ret = network_free_intl_buf(net_path)) != HD_OK)
return ret;
if ((ret = network_free_io_buf(net_path)) != HD_OK)
return ret;
if ((ret = network_free_input_buf(net_path)) != HD_OK)
return ret;
mem_free(&p_net->proc_mem);
memset(&p_net->net_info, 0, sizeof(VENDOR_AI3_NET_INFO));
return ret;
}
HD_RESULT aiisp_network_get_ai_cb(VIDEO_AIISP_MODEL *p_stream)
{
HD_RESULT ret = HD_OK;
ret = vendor_ai3_dev_get(VENDOR_AI3_CFG_AI_CB, &p_stream->ai_cb);
if (ret != HD_OK) {
printf("get ai cb, ret = %d\r\n", ret);
return ret;
}
return ret;
}
HD_RESULT aiisp_network_bind_isp_cb(VIDEO_AIISP_MODEL *p_stream)
{
HD_RESULT ret = HD_OK;
ret = vendor_ai3_dev_set(VENDOR_AI3_CFG_ISP_CB, &p_stream->isp_cb);
if (ret != HD_OK) {
printf("set isp cb, ret = %d\r\n", ret);
return ret;
}
return ret;
}
#endif
///////////////////////////////////////////////////////////////////////////////
HD_RESULT aiisp_network_start(VIDEO_AIISP_MODEL *p_stream)
{
HD_RESULT ret = HD_OK;
#if AI_ENABLE
NET_PROC* p_net = g_net + p_stream->net_path;
UINT32 proc_id = p_net->proc_id;
#endif
#if AI_ENABLE
ret = vendor_ai3_net_start(proc_id);
if (HD_OK != ret) {
printf("net_path(%u), proc_id(%u) vendor_ai3_net_start fail !!\n", p_stream->net_path, proc_id);
}
#endif
return ret;
}
HD_RESULT aiisp_network_stop(VIDEO_AIISP_MODEL *p_stream)
{
HD_RESULT ret = HD_OK;
#if AI_ENABLE
NET_PROC* p_net = g_net + p_stream->net_path;
UINT32 proc_id = p_net->proc_id;
#endif
#if AI_ENABLE
//stop: should be call after last time proc
ret = vendor_ai3_net_stop(proc_id);
if (HD_OK != ret) {
printf("net_path(%u), proc_id(%u) vendor_ai3_net_stop fail !!\n", p_stream->net_path, proc_id);
}
#endif
return ret;
}
HD_RESULT aiisp_network_get_param_name(VIDEO_AIISP_MODEL *p_stream, UINT32 para_id, MODEL_PARAM_NAME *p_param_name)
{
HD_RESULT ret = HD_OK;
NET_PROC* p_net = g_net + p_stream->net_path;
UINT32 proc_id = p_net->proc_id;
UINT32 i;
VENDOR_AI3_BUF ai_buf = {0};
//uintptr_t va, pa;
MODEL_PARAM_NAME *param_name = p_param_name;
ai_buf.sign = MAKEFOURCC('A','B','U','F');
printf("in_buf_cnt = %d\r\n", p_net->net_info.in_buf_cnt);
param_name->num = p_net->net_info.in_buf_cnt;
for (i = 0; i < p_net->net_info.in_buf_cnt; i++) {
// get out buf (by out path list)
ret = vendor_ai3_net_get(proc_id, p_net->net_info.in_path_list[i], &ai_buf);
if (HD_OK != ret) {
printf("net_path(%u), proc_id(%u) get in buf fail, i(%d), in_path(0x%lx)\n", p_stream->net_path, proc_id, i, p_net->net_info.in_path_list[i]);
goto exit;
}
//param_name->param_size[i] = ai_buf.size;
//w * h * c * b * bitdepth /8
param_name->param_size[i] = ((ai_buf.width * ai_buf.height * ai_buf.channel * ai_buf.batch_num * HD_VIDEO_PXLFMT_BITS(ai_buf.fmt) ) >> 3);
printf("aiisp param size = %d\r", ai_buf.size);
strcpy(param_name->param_name[i], ai_buf.name);
printf("name is %s\r\n", param_name->param_name[i]);
}
exit:
return ret;
}
这是ai.c
#include "aiisp_isp.h"
#include "aiisp_ai.h"
#define AIISP_PARAM_MAX 32
#define AIISP_CONFIG_MAX 6
#define AIISP_GAIN_MAX 16
static UINT32 g_conti_run = 1;
UINT32 iso_map_tab[AIISP_GAIN_MAX][2] = {
{ 100, 0},
{ 200, 1},
{ 400, 2},
{ 800, 3},
{ 1600, 4},
{ 3200, 5},
{ 6400, 6},
{ 12800, 7},
{ 25600, 8},
{ 51200, 9},
{ 102400, 10},
{ 204800, 11},
{ 409600, 12},
{ 819200, 13},
{1638400, 14},
{3276800, 15}
};
typedef struct _AWB_PQ_PARAM {
UINT32 target_r_gain[AIISP_GAIN_MAX];
UINT32 target_b_gain[AIISP_GAIN_MAX];
} AWB_PQ_PARAM;
static AWB_PQ_PARAM awb_pq_param = {
// 1x, 2x, 4x, 8x, 16x, 32x, 64x, 128, 256, 512, 1024, 2048, 4096, 8192,16384,32768
.target_r_gain = { 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1070, 1100, 1100, 1100, 1100, 1100, 1100},
.target_b_gain = { 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1070, 1100, 1100, 1100, 1100, 1100, 1100},
};
static UINT32 g_isp_id;
HD_RESULT aiisp_isp_init(UINT32 id, INT32 hdr_type)
{
HD_RESULT ret = HD_OK;
IQT_OB_MODE_MANUAL ob_mode_manual = {0};
IQT_DG_MODE_MANUAL dg_mode_manual = {0};
IQT_CG_MODE_MANUAL cg_mode_manual = {0};
g_isp_id = id;
ob_mode_manual.id = g_isp_id;
dg_mode_manual.id = g_isp_id;
cg_mode_manual.id = g_isp_id;
vendor_isp_get_iq(IQT_ITEM_OB_MODE_MANUAL, &ob_mode_manual);
vendor_isp_get_iq(IQT_ITEM_DG_MODE_MANUAL, &dg_mode_manual);
vendor_isp_get_iq(IQT_ITEM_CG_MODE_MANUAL, &cg_mode_manual);
ob_mode_manual.ob_mode_manual.manual_enable = TRUE;
ob_mode_manual.ob_mode_manual.manual_mode = IQ_OB_PRE;
dg_mode_manual.dg_mode_manual.manual_enable = TRUE;
dg_mode_manual.dg_mode_manual.manual_mode = IQ_DG_AI;
dg_mode_manual.dg_mode_manual.sie_dg_max = 256;
cg_mode_manual.cg_mode_manual.manual_enable = TRUE;
cg_mode_manual.cg_mode_manual.manual_mode = IQ_CG_PRE_F;
if (hdr_type)
{
ob_mode_manual.ob_mode_manual.manual_enable = FALSE;
dg_mode_manual.dg_mode_manual.manual_enable = FALSE;
cg_mode_manual.cg_mode_manual.manual_enable = FALSE;
}
vendor_isp_set_iq(IQT_ITEM_OB_MODE_MANUAL, &ob_mode_manual);
vendor_isp_set_iq(IQT_ITEM_DG_MODE_MANUAL, &dg_mode_manual);
vendor_isp_set_iq(IQT_ITEM_CG_MODE_MANUAL, &cg_mode_manual);
printf("[539a]isp id %d, hdr %d \n", g_isp_id, hdr_type);
return ret;
}
HD_RESULT aiisp_isp_update_param_name(MODEL_PARAM_NAME *p_param_name)
{
HD_RESULT ret = HD_OK;
IQT_AIISP_PARAM aiisp = {0};
UINT32 i;
aiisp.id = g_isp_id;
vendor_isp_get_iq(IQT_ITEM_AIISP_PARAM, &aiisp);
aiisp.aiisp.path_id = 0;
aiisp.aiisp.version = 3;
aiisp.aiisp.param_num = p_param_name->num;
for (i = 0; i < aiisp.aiisp.param_num; i++) {
aiisp.aiisp.param_size[i] = p_param_name->param_size[i];
strcpy(aiisp.aiisp.param_name[i], p_param_name->param_name[i]);
printf("aiisp param size = %d, name = %s\r\n", aiisp.aiisp.param_size[i], aiisp.aiisp.param_name[i]);
}
vendor_isp_set_iq(IQT_ITEM_AIISP_PARAM, &aiisp);
return ret;
}
INT32 isp_intpl(INT32 index, INT32 l_value, INT32 h_value, INT32 l_index, INT32 h_index)
{
INT32 range = h_index - l_index;
if (l_value == h_value) {
return l_value;
} else if (index <= l_index) {
return l_value;
} else if (index >= h_index) {
return h_value;
}
if (h_value < l_value) {
return l_value + ((h_value - l_value) * (index - l_index) - (range >> 1)) / range;
} else {
return l_value + ((h_value - l_value) * (index - l_index) + (range >> 1)) / range;
}
}
void isp_intpl_awb_param(UINT32 cur_gain) {
UINT32 iso_idx_l = 0, iso_idx_h = 0;
UINT32 iso_start = 0, iso_end = 0;
UINT32 i;
AWBT_TARGET target = {0};
// NOTE: Auto
if (cur_gain >= iso_map_tab[AIISP_GAIN_MAX - 1][0]) {
iso_idx_l = iso_map_tab[AIISP_GAIN_MAX - 1][1];
iso_idx_h = iso_map_tab[AIISP_GAIN_MAX - 1][1];
iso_start = iso_map_tab[AIISP_GAIN_MAX - 1][0];
iso_end = iso_map_tab[AIISP_GAIN_MAX - 1][0];
}
for (i = 1; i < AIISP_GAIN_MAX; i++) {
if (cur_gain < iso_map_tab[i][0]) {
iso_idx_l = iso_map_tab[i - 1][1];
iso_idx_h = iso_map_tab[i][1];
iso_start = iso_map_tab[i - 1][0];
iso_end = iso_map_tab[i][0];
break;
}
}
target.id = g_isp_id;
vendor_isp_get_awb(AWBT_ITEM_TARGET, &target);
target.target.rg_ratio[0] = (INT32)isp_intpl(cur_gain, awb_pq_param.target_r_gain[iso_idx_l], awb_pq_param.target_r_gain[iso_idx_h], iso_start, iso_end);
target.target.bg_ratio[0] = (INT32)isp_intpl(cur_gain, awb_pq_param.target_b_gain[iso_idx_l], awb_pq_param.target_b_gain[iso_idx_h], iso_start, iso_end);
target.target.rg_ratio[1] = target.target.rg_ratio[0];
target.target.bg_ratio[1] = target.target.bg_ratio[0];
target.target.rg_ratio[2] = target.target.rg_ratio[0];
target.target.bg_ratio[2] = target.target.bg_ratio[0];
target.target.rg_ratio[3] = target.target.rg_ratio[0];
target.target.bg_ratio[3] = target.target.bg_ratio[0];
target.target.rg_ratio[4] = target.target.rg_ratio[0];
target.target.bg_ratio[4] = target.target.bg_ratio[0];
target.target.rg_ratio[5] = target.target.rg_ratio[0];
target.target.bg_ratio[5] = target.target.bg_ratio[0];
vendor_isp_set_awb(AWBT_ITEM_TARGET, &target);
}
#define TONE_CURVE_ISO_THD 800
#define TONE_CURVR_MAX 100
#define DR_LEVEL_X45S 130
#define HIGH_ISO_CCM_THD 12800
#define LOW_ISO_CCM_THD 6400
#define DR_LEVEL_GAP_THD 4
static U8 ccm_origin[IQ_COLOR_ID_MAX_NUM][IQ_CCM_SATTAB_LEN] = {0};
void *isp_smart_param_thread(void *arg)
{
ISPT_WAIT_CFGSTR wait_cfgstr;
ISPT_TOTAL_GAIN total_gain = {0, 0xFFFFFFFF};
wait_cfgstr.id = g_isp_id;
wait_cfgstr.timeout = 200;
total_gain.id = g_isp_id;
int i;
int ccm_need_reload = 0;
int rt_count = 0;
unsigned int pre_tone_level = 0;
int dr_level_gap = 0;
while (g_conti_run) {
vendor_isp_get_common(ISPT_ITEM_WAIT_CFGSTR, &wait_cfgstr);
/*tone curve*/
vendor_isp_get_common(ISPT_ITEM_TOTAL_GAIN, &total_gain);
if (total_gain.gain == 0xFFFFFFFF) {
continue;
}
IQT_DR_LEVEL dr_level = {0};
IQT_TONE_LV shdr_tone_lv = {0};
vendor_isp_get_iq(IQT_ITEM_DR_LEVEL, &dr_level);//测的当前最低到最高亮度下dr_level范围0-130
vendor_isp_get_iq(IQT_ITEM_TONE_LV, &shdr_tone_lv);//0-100
if(TONE_CURVE_ISO_THD - (S32)total_gain.gain > 0)
{
shdr_tone_lv.lv = (U32)(dr_level.dr_level * TONE_CURVR_MAX / DR_LEVEL_X45S);//dr_level 范围映射到tone_lv
shdr_tone_lv.lv = shdr_tone_lv.lv * (TONE_CURVE_ISO_THD - total_gain.gain) / (TONE_CURVE_ISO_THD - 100);
}
else
{
shdr_tone_lv.lv = 0;
}
if (shdr_tone_lv.lv >= TONE_CURVR_MAX)
{
shdr_tone_lv.lv = TONE_CURVR_MAX;//针对极端情况,加上限定
}
dr_level_gap = (pre_tone_level > shdr_tone_lv.lv) ? (pre_tone_level - shdr_tone_lv.lv):(shdr_tone_lv.lv - pre_tone_level);
if(dr_level_gap > DR_LEVEL_GAP_THD)
{ /*平滑处理*/
shdr_tone_lv.lv = (pre_tone_level * 3 + shdr_tone_lv.lv) / 4;
vendor_isp_set_iq(IQT_ITEM_TONE_LV, &shdr_tone_lv);
}
else if(dr_level_gap != 0 && dr_level_gap <= DR_LEVEL_GAP_THD)
{
shdr_tone_lv.lv = (pre_tone_level > shdr_tone_lv.lv) ? (pre_tone_level-1):(pre_tone_level+1);
vendor_isp_set_iq(IQT_ITEM_TONE_LV, &shdr_tone_lv);
}
pre_tone_level = shdr_tone_lv.lv;
if(rt_count >= 120)
{
rt_count = 0;
if(total_gain.gain >= HIGH_ISO_CCM_THD && ccm_need_reload == 0)
{
HIGH_ISO_CCM_S high_iso_ccm = {0};
if (0 == ds_read(IMAGE_PROFILE_HIGH_ISO_CCM_PATH, (void *)&high_iso_ccm, sizeof(HIGH_ISO_CCM_S)))
{
printf("ds read CSC_RANGE_S failed.\n");
return 0;
}
IQT_CCM_PARAM ccm_param = {0};
ccm_param.id = 0;
vendor_isp_get_iq(IQT_ITEM_CCM_PARAM, &ccm_param);
memset(&ccm_origin, 0, sizeof(U8)*IQ_COLOR_ID_MAX_NUM*IQ_CCM_SATTAB_LEN);
for(i=0; i<IQ_COLOR_ID_MAX_NUM; i++)
{
memcpy(&ccm_origin[i], &ccm_param.ccm.auto_param[i].sat_tab, sizeof(U8)*IQ_CCM_SATTAB_LEN);
}
memcpy(&ccm_param.ccm.auto_param[0].sat_tab, &high_iso_ccm.sat_tab_auto0, sizeof(U8)*IQ_CCM_SATTAB_LEN);
memcpy(&ccm_param.ccm.auto_param[1].sat_tab, &high_iso_ccm.sat_tab_auto1, sizeof(U8)*IQ_CCM_SATTAB_LEN);
memcpy(&ccm_param.ccm.auto_param[2].sat_tab, &high_iso_ccm.sat_tab_auto2, sizeof(U8)*IQ_CCM_SATTAB_LEN);
memcpy(&ccm_param.ccm.auto_param[3].sat_tab, &high_iso_ccm.sat_tab_auto3, sizeof(U8)*IQ_CCM_SATTAB_LEN);
memcpy(&ccm_param.ccm.auto_param[4].sat_tab, &high_iso_ccm.sat_tab_auto4, sizeof(U8)*IQ_CCM_SATTAB_LEN);
vendor_isp_set_iq(IQT_ITEM_CCM_PARAM, &ccm_param);
ccm_need_reload = 1;
}
else if(total_gain.gain < LOW_ISO_CCM_THD && ccm_need_reload == 1)
{
IQT_CCM_PARAM ccm_param = {0};
ccm_param.id = 0;
vendor_isp_get_iq(IQT_ITEM_CCM_PARAM, &ccm_param);
for(i=0; i<IQ_COLOR_ID_MAX_NUM; i++)
{
memcpy(&ccm_param.ccm.auto_param[i].sat_tab, &ccm_origin[i], sizeof(U8)*IQ_CCM_SATTAB_LEN);
}
vendor_isp_set_iq(IQT_ITEM_CCM_PARAM, &ccm_param);
ccm_need_reload = 0;
}
}
rt_count++;
usleep(40000);/*每s跑25一次*/
};
return 0;
}
void isp_smart_param_thread_stop()
{
g_conti_run = 0;
}
这是isp.c
#include "aiisp_hdal.h"
#include "aiisp_ai.h"
#include "aiisp_isp.h"
pthread_t isp_smart_param_thread_id[DUAL_SENSOR_SUPPORT ? 2 : 1]; // 支持两个线程
// 根据是否启用双目,定义 sensor 数量
#ifdef DUAL_SENSOR_SUPPORT
#define SENSOR_COUNT 2
#else
#define SENSOR_COUNT 1
#endif
#ifdef HDR_MODE_SUPPORT
static VIDEO_AIISP_MODEL stream[SENSOR_COUNT][3] = {0};
#else
static VIDEO_AIISP_MODEL stream[SENSOR_COUNT][2] = {0};
#endif
MODEL_PARAM_NAME model_param_name;
#if AI_ENABLE
extern NET_PROC g_net[16];
#endif
#if AI_ENABLE
extern NET_PROC g_net[16];
#endif
S32 aiisp_isp(S32 hdr_switch)
{
if (hdr_switch < 0)
{
hdr_switch = 0;
}
for (int i = 0; i < SENSOR_COUNT; i++)
{
aiisp_isp_init(i, hdr_switch);
}
return HD_OK;
}
S32 aiisp_init()
{
printf("[539a]aiisp init\n");
HD_RESULT ret = HD_OK;
// 单目 vs 双目初始化
for (int i = 0; i < SENSOR_COUNT; i++)
{
strcpy(stream[i][AIISP_HIGH_GAIN].net_proc_cfg.model_filename, AIISP_HIGH_GAIN_MODEL);
strcpy(stream[i][AIISP_LOW_GAIN].net_proc_cfg.model_filename, AIISP_LOW_GAIN_MODEL);
printf("proc 0 model path %s, proc 1 model path %s\n", stream[i][AIISP_HIGH_GAIN].net_proc_cfg.model_filename, stream[i][AIISP_LOW_GAIN].net_proc_cfg.model_filename);
stream[i][AIISP_HIGH_GAIN].net_path = 0;
stream[i][AIISP_HIGH_GAIN].in_path = 0;
stream[i][AIISP_LOW_GAIN].net_path = 1;
stream[i][AIISP_LOW_GAIN].in_path = 0;
if ((ret = aiisp_network_mem_config(stream[i][AIISP_HIGH_GAIN].net_path, &stream[i][AIISP_HIGH_GAIN].net_proc_cfg)) != HD_OK)
return ret;
if ((ret = aiisp_network_mem_config(stream[i][AIISP_LOW_GAIN].net_path, &stream[i][AIISP_LOW_GAIN].net_proc_cfg)) != HD_OK)
return ret;
#ifdef HDR_MODE_SUPPORT
strcpy(stream[i][AIISP_HDR].net_proc_cfg.model_filename, AIISP_HDR_MODEL);
stream[i][AIISP_HDR].net_path = 2;
stream[i][AIISP_HDR].in_path = 0;
if ((ret = aiisp_network_mem_config(stream[i][AIISP_HDR].net_path, &stream[i][AIISP_HDR].net_proc_cfg)) != HD_OK)
return ret;
#endif
}
if ((ret = aiisp_input_init()) != HD_OK)
return ret;
if ((ret = aiisp_network_init()) != HD_OK)
return ret;
printf("\n[539a]aiisp init success=%d\n", ret);
return HD_OK;
}
S32 aiisp_open(HD_PATH_ID proc_ctrl)
{
printf("[539a]aiisp open\n");
HD_RESULT ret = HD_OK;
for (int i = 0; i < SENSOR_COUNT; i++)
{
stream[i][AIISP_HIGH_GAIN].proc_ctrl = proc_ctrl;
stream[i][AIISP_LOW_GAIN].proc_ctrl = proc_ctrl;
if ((ret = aiisp_network_open(stream[i][AIISP_HIGH_GAIN].net_path)) != HD_OK)
return ret;
if ((ret = aiisp_network_open(stream[i][AIISP_LOW_GAIN].net_path)) != HD_OK)
return ret;
#ifdef HDR_MODE_SUPPORT
stream[i][AIISP_HDR].proc_ctrl = proc_ctrl;
if ((ret = aiisp_network_open(stream[i][AIISP_HDR].net_path)) != HD_OK)
return ret;
#endif
ret = vendor_videoproc_get(stream[i][AIISP_HIGH_GAIN].proc_ctrl, VENDOR_VIDEOPROC_PARAM_ISP_CB, &stream[i][AIISP_HIGH_GAIN].isp_cb);
if (ret != HD_OK)
{
printf("get isp cb cb, ret = %d\r\n", ret);
return ret;
}
if ((ret = aiisp_network_bind_isp_cb(&stream[i][AIISP_HIGH_GAIN])) != HD_OK)
{
printf("bind isp cb cb, ret = %d\r\n", ret);
return ret;
}
}
UINT32 USAGE_LIMIT = 99;
vendor_ai3_dev_set(VENDOR_AI3_CFG_CORE_USAGE_LIMIT, &USAGE_LIMIT);
printf("\n[539a]aiisp open success=%d\n", ret);
return HD_OK;
}
S32 aiisp_start()
{
printf("[539a]aiisp start\n");
HD_RESULT ret = HD_OK;
VENDOR_VIDEOPROC_ISP_AI_EFFECT isp_ai_effect[SENSOR_COUNT]; // 每个 Sensor 一个配置
for (int i = 0; i < SENSOR_COUNT; i++)
{
// 启动每个 Sensor 的不同模式流
aiisp_network_start(&stream[i][AIISP_HIGH_GAIN]);
aiisp_network_start(&stream[i][AIISP_LOW_GAIN]);
#ifdef HDR_MODE_SUPPORT
aiisp_network_start(&stream[i][AIISP_HDR]);
#endif
// 获取参数并更新 ISP 参数名
aiisp_network_get_param_name(&stream[i][AIISP_HIGH_GAIN], 0, &model_param_name);
aiisp_isp_update_param_name(&model_param_name); // 使用当前 isp_id 更新
// 获取 AI 回调函数并注册到视频处理模块
aiisp_network_get_ai_cb(&stream[i][AIISP_HIGH_GAIN]);
ret = vendor_videoproc_set(stream[i][AIISP_HIGH_GAIN].proc_ctrl, VENDOR_VIDEOPROC_PARAM_AI_CB, &stream[i][AIISP_HIGH_GAIN].ai_cb);
if (ret != HD_OK)
{
printf("Sensor %d: set ai cb failed, ret = %d\r\n", i, ret);
return ret;
}
printf("Sensor %d: isp_cb:%p, ai_cb:%p\n", i, stream[i][AIISP_HIGH_GAIN].isp_cb, stream[i][AIISP_HIGH_GAIN].ai_cb);
// 获取 proc_id
UINT32 proc_id = ((NET_PROC *)(g_net + stream[i][AIISP_HIGH_GAIN].net_path))->proc_id;
UINT32 proc_id2 = ((NET_PROC *)(g_net + stream[i][AIISP_LOW_GAIN].net_path))->proc_id;
#ifdef HDR_MODE_SUPPORT
UINT32 proc_id3 = ((NET_PROC *)(g_net + stream[i][AIISP_HDR].net_path))->proc_id;
printf("Sensor %d: proc_id(HIGH_GAIN)=%u, proc_id(LOW_GAIN)=%u, proc_id(HDR)=%u\n", i, proc_id, proc_id2, proc_id3);
isp_ai_effect[i].proc_id[HDR_ISO_EFFECT] = proc_id3;
#else
printf("Sensor %d: proc_id(HIGH_GAIN)=%u, proc_id(LOW_GAIN)=%u\n", i, proc_id, proc_id2);
#endif
// 设置 ISP AI 效果结构体
isp_ai_effect[i].enable = 1;
isp_ai_effect[i].path_id = i; // 每个 Sensor 有独立 path_id
isp_ai_effect[i].proc_id[NORMAL_ISO_EFFECT] = proc_id;
isp_ai_effect[i].proc_id[LOW_ISO_EFFECT] = proc_id2;
ret = vendor_videoproc_set(stream[i][AIISP_HIGH_GAIN].proc_ctrl, VENDOR_VIDEOPROC_PARAM_ISP_AI_EFFECT, &isp_ai_effect[i]);
if (ret)
{
printf("Sensor %d: set ISP_AI_EFFECT failed, ret = %d\r\n", i, ret);
return ret;
}
}
printf("\n[539a]aiisp start success=%d\n", ret);
return HD_OK;
}
S32 aiisp_cfg_sync_start()
{
printf("[539a]create isp smart param thread\n");
for (int i = 0; i < SENSOR_COUNT; i++)
{
int *p_isp_id = malloc(sizeof(int));
*p_isp_id = i;
if (pthread_create(&isp_smart_param_thread_id[i], NULL, isp_smart_param_thread, p_isp_id) < 0)
{
printf("create isp smart param thread %d failed \n", i);
return ERROR;
}
pthread_detach(isp_smart_param_thread_id[i]);
}
return HD_OK;
}
S32 aiisp_close()
{
printf("\n[aiisp]aiisp close called\n");
HD_RESULT ret = HD_OK;
isp_smart_param_thread_stop();
for (int i = 0; i < SENSOR_COUNT; i++)
{
aiisp_network_stop(&stream[i][AIISP_HIGH_GAIN]);
aiisp_network_stop(&stream[i][AIISP_LOW_GAIN]);
if ((ret = aiisp_network_close(stream[i][AIISP_HIGH_GAIN].net_path)) != HD_OK)
{
printf("\n[aiisp]netclose path0 failed\n");
return ret;
}
if ((ret = aiisp_network_close(stream[i][AIISP_LOW_GAIN].net_path)) != HD_OK)
{
printf("\n[aiisp]netclose path1 failed\n");
return ret;
}
#ifdef HDR_MODE_SUPPORT
aiisp_network_stop(&stream[i][AIISP_HDR]);
if ((ret = aiisp_network_close(stream[i][AIISP_HDR].net_path)) != HD_OK)
{
printf("\n[aiisp]netclose path1 failed\n");
return ret;
}
#endif
}
return HD_OK;
}
S32 aiisp_exit()
{
printf("\n[aiisp]aiisp exit called\n");
HD_RESULT ret = HD_OK;
if ((ret = aiisp_input_uninit()) != HD_OK)
return ret;
if ((ret = aiisp_network_uninit()) != HD_OK)
return ret;
return HD_OK;
}
#ifdef HDR_MODE_SUPPORT
S32 aiisp_update_param_name(S32 hdr_status, UINT32 isp_id)
{
if (hdr_status == 1)
{
aiisp_network_get_param_name(&stream[isp_id][AIISP_HDR], 0, &model_param_name);
}
else
{
aiisp_network_get_param_name(&stream[isp_id][AIISP_HIGH_GAIN], 0, &model_param_name);
}
aiisp_isp_update_param_name(&model_param_name, isp_id); // 传入 isp_id
return HD_OK;
}
#endif
这是hal.c
已经实现了对双sensor的适配了吗,请你就这条问题看,忽略我之前提到的上下文