MI IQSERVER API
REVISION HISTORY¶
| Revision No. | Description |
Date |
|---|---|---|
| 3.0 | 12/04/2020 | |
| 3.1 | 04/09/2024 |
1. OVERVIEW¶
1.1. Module Description¶
IQSERVER (Image Quality tuning Server) is used for data transport between tuning tool (IQ Tool) and EVB, including ISP parameter setting, image capture and file upload/download.
1.2. Basic Structure¶
-
ISP
Image Signal Processing, used for image noise reduction, color rendering, brightness adjustment, and other functions.
-
SCL
Scale.
-
VENC
Video Encoder, used for encoding YUV stream to H264/H265/Jpeg format bit-stream.
1.3. Basic Structure¶
MI_IQSERVER supports the following functions:
- Support IQ and ISP parameter settings.
- Support capture of raw/yuv/jpg/raw stream.
1.4. Application scenarios¶
IQSERVER can be applied to the following scenarios:
-
Pure linux scenario
In the linux environment, NetWork and IQTool connection debugging are supported.
-
Pure rtos scenario
In the rtos environment, UVC and IQTool connection debugging are supported.
-
Dualos scenario
In the dualos environment, NetWork and IQTool connection debugging are supported.
1.5. Working Principle¶
IQSERVER has two calling methods:
-
The first is the interactive process of Network:

-
The second is the interactive process of UVC (this process is not supported by Pcupid yet):

1.6. Development process¶
-
Enter the alkaid project root directory, make menuconfig

-
Press Enter to enter the Sdk Config sub-option

-
Press Enter to enter the Interface Compile Config sub-option

-
Press the spacebar to select the iqserver sub-module and recompile the project
After the compilation is completed, libmi_iqserver.a will be generated under sdk/interface/src/iqserver
1.7. Example Introduction¶
Take vif_isp_scl streaming demo as an example
- You need to import iqserver lib in demo's makefile
ifeq ($(PROG_ISPIQ_ENABLE), 1) INC += ./internal/cus3a LIBS += -lmi_iqserver -lcus3a -lispalgo ifeq ($(NIR_SUPPORT), 1) LIBS += -lmi_nir endif endif
void *ST_IQthread(void * args) { #if MI_ISPIQ_SUPPORT MI_ISP_DEV IspDevId = 0; MI_ISP_CHANNEL IspChnId = 0; char IqApiBinFilePath[ST_MAX_ISP_CHN_NUM][128]; MI_SNR_PADID ePADId; ST_Sensor_Attr_t* pstSensorAttr = NULL; memset(IqApiBinFilePath, 0, sizeof(char)*128*ST_MAX_ISP_CHN_NUM); MI_IQSERVER_Open(); while (!g_stIqResInfo.bThreadExit) { for(IspDevId=0; IspDevId<ST_MAX_ISP_DEV_NUM; IspDevId++) { ST_IspDevAttr_t *pstIspDevAttr= &gstIspModule.stIspDevAttr[IspDevId]; if(pstIspDevAttr->bUsed == TRUE && pstIspDevAttr->bCreate == TRUE) { for(IspChnId=0; IspChnId<ST_MAX_ISP_CHN_NUM; IspChnId++) { ST_IspChannelAttr_t *pstIspChnAttr = &pstIspDevAttr->stIspChnlAttr[IspChnId]; if(pstIspChnAttr->bUsed == TRUE && pstIspChnAttr->bCreate == TRUE) { MI_ISP_IQ_Nr3dType_t stNR3D; MI_ISP_IQ_ParamInitInfoType_t status; //MI_ISP_ChnParam_t stIspChnParam; MI_SNR_PlaneInfo_t stPlaneInfo; char IqApiBinFilePath_tmp[128]; MI_S32 s32ret = MI_SUCCESS; memset(&stNR3D,0x0,sizeof(MI_ISP_IQ_Nr3dType_t)); memset(&status,0x0,sizeof(MI_ISP_IQ_ParamInitInfoType_t)); //memset(&stIspChnParam,0x0,sizeof(MI_ISP_ChnParam_t)); memset(&stPlaneInfo,0x0,sizeof(MI_SNR_PlaneInfo_t)); memset(IqApiBinFilePath_tmp, 0, sizeof(char)*128); s32ret = MI_ISP_IQ_GetParaInitStatus(IspDevId,IspChnId, &status); if((s32ret == MI_SUCCESS && status.stParaAPI.bFlag != 1) || (s32ret != MI_SUCCESS)) { continue; } s32ret = MI_ISP_IQ_GetNr3d(IspDevId, IspChnId, &stNR3D); if(s32ret == MI_SUCCESS && stNR3D.bEnable == E_SS_IQ_FALSE) { stNR3D.bEnable = E_SS_IQ_TRUE; printf("SET ISP dev %d, chn %d,NR3D status:%d, type:%d\n",IspDevId, IspChnId,stNR3D.bEnable, stNR3D.enOpType); if(MI_SUCCESS != MI_ISP_IQ_SetNr3d(IspDevId, IspChnId, &stNR3D)) { DBG_ERR("isp dev%d chn%d set NR3D failed!! \n",IspDevId, IspChnId); } } //MI_ISP_GetChnParam(IspDevId, IspChnId, &stIspChnParam); ePADId = ST_GetFirstSensorPadId(pstIspChnAttr->u32SensorBindId); pstSensorAttr = &gstSensorAttr[ePADId]; if(ePADId < ST_MAX_SENSOR_NUM && bUseUserSensor == FALSE && pstSensorAttr->bCreate) { MI_SNR_GetPlaneInfo(ePADId, 0, &stPlaneInfo); sprintf(IqApiBinFilePath_tmp, "/config/iqfile/%s_api.bin", stPlaneInfo.s8SensorName); } if(pstIspChnAttr->IqCfgbin_Path[0] != '\0') { if(0!=strcmp(IqApiBinFilePath[IspChnId], pstIspChnAttr->IqCfgbin_Path)) { memcpy(IqApiBinFilePath[IspChnId], pstIspChnAttr->IqCfgbin_Path, sizeof(char)*128); printf("loading api bin...path:%s\n",IqApiBinFilePath[IspChnId]); MI_ISP_ApiCmdLoadBinFile(IspDevId, IspChnId, (char *)IqApiBinFilePath[IspChnId], 1234); } } else { if(0!=strcmp(IqApiBinFilePath[IspChnId], IqApiBinFilePath_tmp)) { memcpy(IqApiBinFilePath[IspChnId], IqApiBinFilePath_tmp, sizeof(char)*128); printf("loading api bin...path:%s\n",IqApiBinFilePath[IspChnId]); MI_ISP_ApiCmdLoadBinFile(IspDevId, IspChnId, (char *)IqApiBinFilePath[IspChnId], 1234); } } } } } } usleep(THREAD_SLEEP_TIME_US*10); } MI_IQSERVER_Close(); #endif return NULL; }
Note: The actual part of the above example for users is to call MI_IQSERVER_Open() after the streaming is completed and call MI_IQSERVER_Close() after the streaming is closed. The rest are the streaming process of MI_demo.
2. API LIST¶
This function module provides the following APIs.
| API Name | Function |
|---|---|
| MI_IQSERVER_Open | Open IQ server |
| MI_IQSERVER_Close | Close IQ server |
| MI_IQSERVER_SetDataPath | Set IQ server data path |
| MI_IQSERVER_SetCustFunc | Set user specified execute function |
2.1. MI_IQSERVER_Open¶
-
Function
Call this interface to open IQ server.
-
Syntax
MI_S32 MI_IQSERVER_Open();
-
Return Value
-
MI_IQSERVER_OK: Successful
-
Others: Failed, see error code for details.
-
-
Dependency
-
Head file: mi_iqserver.h
-
Others: libmi_iqserver.a
-
-
Note
- IQ server can only be called once
- IQ server must be in the same process as the ISP streaming process
- The default port of IQ server is 9876
-
Example
/*declaration*/ MI_S32 s32Ret = 0; /* open IQSERVER*/ s32Ret = MI_IQSERVER_Open(); if (MI_IQSERVER_OK != s32Ret) { Printf(“open iqserver error:%x\n”, s32Ret); return s32Ret; } -
Related APIs
2.2. MI_IQSERVER_Close¶
-
Function
Call this interface to close IQ server.
-
Syntax
MI_ S32 MI_IQSERVER_Close();
-
Return Value
-
MI_IQSERVER_OK: Successful.
-
Others: Failed, see error code for details.
-
-
Dependency
-
Head file: mi_iqserver.h
-
Library file: libmi_iqserver.a
-
-
Note
The number of calls for MI_IQSERVER_Open and MI_IQSERVER_Close must correspond.
-
Example
/*declaration*/ MI_S32 s32Ret = 0; /* close IQSERVER*/ s32Ret = MI_IQSERVER_Close(); if (MI_IQSERVER_OK != s32Ret) { Printf(“close iqserver error:%x\n”, s32Ret); return s32Ret; } -
Related APIs
2.3. MI_IQSERVER_SetDataPath¶
-
Function
Set IQ server data path.
-
Syntax
MI_S32 MI_IQSERVER_SetDataPath(char* path);
-
Form parameter
Parameter Name Description Input/Output path Path of IQ server data, ending with \0. Input -
Return Value
-
MI_IQSERVER_OK: Successful.
-
Others: Failed, see error code for details.
-
-
Dependency
-
Head file: mi_iqserver.h
-
Library file: libmi_iqserver.a
-
-
Note
-
You can call this API before MI_IQSERVER_Open.
-
Before calling this API, make sure that the path is accessible and that the data needed by the IQ server is available.
-
Normally, the data needed by the IQ server include isp_api.xml (for use by IQ Tool).
- By default, isp_api.xml reads the /config/iqfile path, if it is not this path, you need to call the sub-interface to set it.
-
-
Example
/*declaration*/ MI_S32 s32Ret = 0; char *data_path = “/customer/iqconfig/”; /* set IQSERVER data path*/ s32Ret = MI_IQSERVER_SetDataPath(data_path); if (MI_IQSERVER_OK != s32Ret) { Printf(“set iqserver data path error:%x\n”, s32Ret); return s32Ret; }
2.4. MI_IQSERVER_SetCustFunc¶
-
Function
Set user-specified execute function, for IQ server to call it.
-
Syntax
MI_S32 MI_IQSERVER_SetCustFunc(MI_S32(*func)(MI_U16 data_type, MI_U32 length, MI_U8 *data));
-
Form parameter
Parameter Name Description Input/Output func Execute function Input -
Return Value
-
MI_IQSERVER_OK: Successful.
-
Others: Failed, see error code for details.
-
-
Dependency
-
Head file: mi_iqserver.h
-
Library file: libmi_iqserver.a
-
-
Note
-
Before using this API, define the function with the parameters below:
-
datatype: type of data, user defined, to distinguish different data.
-
length: length of data, IQ tool will auto set the value.
-
data: data address.
You can do some processing in func with these parameters.
-
-
By this API, you can add user-defined execute function in IQ server. IQ server will get the data from IQ tool, then call the user-defined function. After that, func will get the data, to implement custom features.
For example:
-
Use IQ tool to write firmware, then IQ server calls func to flash firmware.
-
Use IQ tool to set IR cut, then IQ server calls func to switch IR.
-
-
Before calling this function, make sure func is executable.
-
Data_type and data come from IQ tool, and length means data length.
-
Data_type can be used to distinguish what function the data is used for. You can define different function for different data.
-
-
Example
/*declaration*/ MI_S32 s32Ret = 0; MI_S32 sample_func(MI_U16 data_type, MI_U32 length, MI_U8 *data) { printf("call MI_IQSERVER_SetCustFunc() success\n"); printf(“data_type is %d, length:%u, data addr:%p\n”, data_type, length, data); //do something return MI_IQSERVER_OK; } /* set IQSERVER custom function*/ s32Ret = MI_IQSERVER_SetCustFunc(sample_func); if (MI_IQSERVER_OK != s32Ret) { Printf(“set iqserver cust func error:%x\n”, s32Ret); return s32Ret; }
3. ERROR CODE¶
The IQSERVER API error code is as follows:
| Error Code | Macro Definition | Description |
|---|---|---|
| 0XA02C2000 | MI_ERR_IQSERVER_NOMEM | No memmory |
| 0XA02C2001 | MI_ERR_IQSERVER_NOBUF | No buffer |
| 0XA02C2002 | MI_ERR_IQSERVER_CREATE_THREAD | Null pointer |
| 0XA02C2003 | MI_ERR_IQSERVER_INVALID_IQPATH | Invalid IQ data path |