由 bind_mismatch 引起的 大量 version_count 问题

本文探讨了Oracle数据库中SQL版本计数高的原因及解决方法,特别是与绑定变量长度不同的关联。通过查询SQL_ID、version_count、bind_mismatch等信息,识别并解决了由绑定变量长度变化导致的cursor无法重用问题。文章还提供了bug信息、解决方案及测试建议。

从AWR报告里发现一个SQL存在大量的version_count.

SYS@xezf(qs-xezf-db1)> select sql_id,version_count fromv$sqlareawhere version_count> 500 order by 2 desc ;

SQL_IDVERSION_COUNT

------------- -------------

9rwd4wkwm4bsy3046

cpqsn8zak6sw42985

66x4djqka2ppy976

0z7n7sst85222617

在v$sqlarea中保存了SQL的cursor,当有大量的version_count,说明虽然SQL语句相同,但是Oracle发现因为某些原因不可重用这些SQL。当这类SQL执行次数很多,就会占用大量的shared pool,引起library cache pin和library cache的等待事件。

可以使用如下SQL查看占用内存大小:

/* Formatted on 2011/6/24 21:54:00 (QP5 v5.163.1008.3004) */

SELECTSUM(sharable_mem)/1024/1024||'M'

FROMv$sqlarea

WHEREsql_id='cpqsn8zak6sw4';

可以通过如下SQL查看是什么原因导致的不匹配:

SYS@xezf(qs-xezf-db1)> select sql_id,child_number,BIND_MISMATCH fromv$sql_shared_cursorwhere sql_id='9rwd4wkwm4bsy' and BIND_MISMATCH='Y' and rownum<10;

SQL_IDCHILD_NUMBER B

------------- ------------ -

9rwd4wkwm4bsy3 Y

9rwd4wkwm4bsy24 Y

9rwd4wkwm4bsy29 Y

9rwd4wkwm4bsy33 Y

9rwd4wkwm4bsy35 Y

9rwd4wkwm4bsy38 Y

9rwd4wkwm4bsy51 Y

9rwd4wkwm4bsy55 Y

9rwd4wkwm4bsy81 Y

我这是过滤之后的信息,当这些信息有Y时,就是表示cursor不能重用的原因。

SYS@xezf(qs-xezf-db1)> select count(*) fromv$sql_shared_cursorwhere sql_id='9rwd4wkwm4bsy' andBIND_MISMATCH='Y' ;

COUNT(*)

----------

120

bind_mismatch一般是由于bind value的长度不同导致bind buffer无法重用,最终导致cursor无法重用。

例如:对于字符类型的字段,进行绑定变量的时候,第一次会使用32字节的BUFFER,如果该值小于32字节的话,第二次执行这个SQL的时候,如果小于32字节,那么可以共享这个CURSOR,如果大于,就无法共享,原因就是BIND_MISMATCH,此时会产生一个子CURSOR,同时分配128字节的BIND BUFFER,以此类推。

正常情况不会产生这么大量的子CURSOR。但是由于一些BUG,会导致问题。

如果没有补丁,一个临时性的解决方案,设置一个较大的BUFFER:

SQL>ALTER SESSION SET EVENTS '10503 trace name context level <buffer length>, forever';

通过v$sql_bind_capture视图查看一下每次绑定变量的值:

SYS@xezf(qs-xezf-db1)> select position,LAST_CAPTURED,datatype_string,value_string from v$sql_bind_capture wheresql_id='9rwd4wkwm4bsy'and rownum<50;

POSITIONLAST_CAPTUREDDATATYPE_STRINGVALUE_STRING

---------- ------------------- -------------------- --------------------

1 2011-06-24 15:54:22 VARCHAR2(32)cp102328

2 2011-06-24 15:54:22 NUMBER103

3 2011-06-24 15:54:22 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 15:54:22 VARCHAR2(32)yyyy-mm-dd

1 2011-06-24 16:02:54 VARCHAR2(32)s13791223344

2 2011-06-24 16:02:54 NUMBER103

3 2011-06-24 16:02:54 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 16:02:54 VARCHAR2(32)yyyy-mm-dd

1 2011-06-24 16:10:41 VARCHAR2(32)7027976

2 2011-06-24 16:10:41 NUMBER103

3 2011-06-24 16:10:41 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 16:10:41 VARCHAR2(32)yyyy-mm-dd

1 2011-06-24 17:09:28 VARCHAR2(32)BILLQQ

2 2011-06-24 17:09:28 NUMBER103

3 2011-06-24 17:09:28 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 17:09:28 VARCHAR2(32)yyyy-mm-dd

1 2011-06-24 16:59:16 VARCHAR2(32)wantai1472888

2 2011-06-24 16:59:16 NUMBER103

3 2011-06-24 16:59:16 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 16:59:16 VARCHAR2(32)yyyy-mm-dd

1 2011-06-24 16:59:10 varchar2(32)gy928888@vip.qq.com

2 2011-06-24 16:59:10 NUMBER103

3 2011-06-24 16:59:10 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 16:59:10 VARCHAR2(32)yyyy-mm-dd

1 2011-06-24 16:59:09 VARCHAR2(32)22501165422

2 2011-06-24 16:59:09 NUMBER103

3 2011-06-24 16:59:09 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 16:59:09 VARCHAR2(32)yyyy-mm-dd

1 2011-06-24 16:59:07 VARCHAR2(32)12801165830

2 2011-06-24 16:59:07 NUMBER103

3 2011-06-24 16:59:07 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 16:59:07 VARCHAR2(32)yyyy-mm-dd

1 2011-06-24 16:59:00 VARCHAR2(32)235896734

2 2011-06-24 16:59:00 NUMBER103

3 2011-06-24 16:59:00 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 16:59:00 VARCHAR2(32)yyyy-mm-dd

1 2011-06-24 16:58:56 varchar2(32)978a62e0bbb767d99bda

2 2011-06-24 16:58:56 NUMBER103

3 2011-06-24 16:58:56 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 16:58:56 VARCHAR2(32)yyyy-mm-dd

1 2011-06-24 16:58:34 VARCHAR2(32)708888718@qq.com

2 2011-06-24 16:58:34 NUMBER209

3 2011-06-24 16:58:34 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 16:58:34 VARCHAR2(32)yyyy-mm-dd

1 2011-06-24 16:57:51 varchar2(32)syyxQS20110624000364

2 2011-06-24 16:57:51 NUMBER103

3 2011-06-24 16:57:51 VARCHAR2(32)yyyy-mm-dd

4 2011-06-24 16:57:51 VARCHAR2(32)yyyy-mm-dd

通过以上的查询结果,我们可以肯定是sql_id='9rwd4wkwm4bsy' SQL的第一绑定变量值的长度不同造成bind_mismatch,从而产生大量的version_counts.

相关的bug信息如下:
Bug:9689310:
- Non sharability of cursors due toBIND_MISMATCH.

Bug:6981690:
- Non sharability of cursors due toPQ_SLAVE_MISMATCH

Bug:8981059:
- Non sharability of cursors due toUSER_BIND_PEEK_MISMATCH.

对于Bug 9689310,在MOS上搜了一下,该bug存在的版本如下:

Affects:

Product (Component)

Oracle Server (Rdbms)

Range of versionsbelievedto be affected

Versions BELOW 12.1

Versions confirmed as being affected

Platforms affected

Generic (all / most platforms affected)

Fixed:

This issue is fixed in

MOS上给了一个变通的解决方法:Workaround

Alter the client application code so that it uses constant sizes for the MAX bind lengths.

我的库是10.2.0.5的,这个没说修复,也没说存在bug,还真不好确定,看来还是需要测试一下。

不过我这个库上的cursor_sharing参数是设置为similar的,这样会将SQL中的谓词值自动用变量来代替。这样会增加cursor的数量。为了减少cursor对library cache的占用,还是先将cursor_shring参数改成了默认的exact模式。这样version_count会减少很多,但是硬解析的次数也会增加,可能会增加Library Cache Latch等待。现在只能这样修改一下,在找个环境测试一下。

Oracle cursor_sharing参数详解

http://blog.youkuaiyun.com/xujinyang/article/details/6855009


-------------------------------------------------------------------------------------------------------

#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的适配了吗,请你就这条问题看,忽略我之前提到的上下文
09-23
#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的适配了吗
最新发布
09-23
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值