GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
SDK_DIR ?= $(shell cd ../../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include config.mk
.PHONY: all clean
all: linux riscv
clean: linux_clean riscv_clean
.PHONY: linux linux_clean
linux:
ifeq ($(LINUX_LIB), TRUE)
make -f Makefile.linux.mk
endif
linux_clean:
ifeq ($(LINUX_LIB), TRUE)
make -f Makefile.linux.mk clean
endif
.PHONY: riscv riscv_clean
riscv:
ifeq ($(RISCV_LIB), TRUE)
make -f Makefile.riscv.mk
endif
riscv_clean:
ifeq ($(RISCV_LIB), TRUE)
make -f Makefile.riscv.mk clean
endif
+38
View File
@@ -0,0 +1,38 @@
SDK_DIR ?= $(shell cd ../../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include config.mk
.PHONY: all clean
all: ae awb af
clean: ae_clean awb_clean af_clean
.PHONY: ae ae_clean
ae:
ifneq ($(AE_LIB), )
$(AT)$(MAKE) -C $(AE_LIB)
endif
ae_clean:
ifneq ($(AE_LIB), )
$(AT)$(MAKE) -C $(AE_LIB) clean
endif
.PHONY: awb awb_clean
awb:
ifneq ($(AWB_LIB), )
$(AT)$(MAKE) -C $(AWB_LIB)
endif
awb_clean:
ifneq ($(AWB_LIB), )
$(AT)$(MAKE) -C $(AWB_LIB) clean
endif
.PHONY: af af_clean
af:
ifneq ($(AF_LIB), )
$(AT)$(MAKE) -C $(AF_LIB)
endif
af_clean:
ifneq ($(AF_LIB), )
$(AT)$(MAKE) -C $(AF_LIB) clean
endif
+54
View File
@@ -0,0 +1,54 @@
SDK_DIR ?= $(shell cd ../../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include config.mk
MAKEFILE_PATH := $(MCU_MEDIA_DIR)/Makefile
BAK_MAKEFILE_PATH := $(MCU_MEDIA_DIR)/_Makefile.bak
AE_LN_PATH := $(MCU_MEDIA_DIR)/ae
AWB_LN_PATH := $(MCU_MEDIA_DIR)/awb
AF_LN_PATH := $(MCU_MEDIA_DIR)/af
AT := @
define func_generate_makefile
$(AT)test -f $(BAK_MAKEFILE_PATH) || (test -f $(MAKEFILE_PATH) && mv $(MAKEFILE_PATH) $(BAK_MAKEFILE_PATH))
$(AT)touch $(MAKEFILE_PATH)
$(if $(AE_LIB), echo SRCS-y += ae/ > $(MAKEFILE_PATH), )
$(if $(AWB_LIB), echo SRCS-y += awb/ >> $(MAKEFILE_PATH), )
$(if $(AF_LIB), echo SRCS-y += af/ >> $(MAKEFILE_PATH), )
endef
define func_generate_ln_soft
$(if $(AE_LIB), $(AT)test -d $(AE_LN_PATH) || ln -s $(ISP_ALG_DIR)/$(AE_LIB) $(AE_LN_PATH), )
$(if $(AWB_LIB), $(AT)test -d $(AWB_LN_PATH) || ln -s $(ISP_ALG_DIR)/$(AWB_LIB) $(AWB_LN_PATH), )
$(if $(AF_LIB), $(AT)test -d $(AF_LN_PATH) || ln -s $(ISP_ALG_DIR)/$(AF_LIB) $(AF_LN_PATH), )
endef
define func_rm_ln
-rm $(AE_LN_PATH)
-rm $(AWB_LN_PATH)
-rm $(AF_LN_PATH)
endef
define func_restore_makefile
$(AT)test -f $(BAK_MAKEFILE_PATH) && mv $(BAK_MAKEFILE_PATH) $(MAKEFILE_PATH)
endef
define func_cp_lib_to_isp
$(if $(AE_LIB), $(AT)cp $(OUT_DIR)/media/ae/libae.a $(ISP_LIBS_DIR), )
$(if $(AWB_LIB), $(AT)cp $(OUT_DIR)/media/awb/libawb.a $(ISP_LIBS_DIR), )
$(if $(AF_LIB), $(AT)cp $(OUT_DIR)/media/af/libaf.a $(ISP_LIBS_DIR), )
endef
.PHONY: all clean
all:
$(call func_generate_makefile)
$(call func_generate_ln_soft)
$(if $(MCU_DEFCONFIG), $(AT)make -C $(MCU_RISCV_DIR) $(MCU_DEFCONFIG) || echo make failed;, )
$(AT)make -C $(MCU_RISCV_DIR) $(MCU_TARGET) || echo make failed;
$(call func_cp_lib_to_isp)
$(call func_rm_ln)
$(call func_restore_makefile)
clean:;
+2
View File
@@ -0,0 +1,2 @@
ascii_to_lower = $(shell echo $(1) | tr '[:upper:]' '[:lower:]')
CHIPARCH := $(call ascii_to_lower,$(CHIPARCH))
+19
View File
@@ -0,0 +1,19 @@
include common.mk
AE_LIB := sample_ae_v1
AWB_LIB := sample_awb_v1
LINUX_LIB := TRUE
RISCV_LIB := TRUE
MCU_DIR := $(shell cd ../../../../../mcu && pwd)
ISP_ALG_DIR := $(shell pwd)
OUT_DIR := $(MCU_DIR)/riscv/out
ISP_DIR := $(shell cd ../../isp && pwd)
ISP_LIBS_DIR := $(shell cd $(ISP_DIR)/libs/riscv && pwd)
MCU_MEDIA_DIR := $(MCU_DIR)/media
MCU_RISCV_DIR := $(MCU_DIR)/riscv
MCU_DEFCONFIG := xmorca_defconfig
MCU_TARGET := media/libmedia.a
+7
View File
@@ -0,0 +1,7 @@
ifneq ($(MCU), )
include Makefile.riscv.mk
else
include Makefile.linux.mk
endif
@@ -0,0 +1,23 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
LIB_NAME := libxmedia_ae
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/framework/inc
SDK_USR_CFLAGS += -I$(ISP_DIR)/include
SDK_USR_CFLAGS += -UCONFIG_LOG_TRACE_SUPPORT -DCONFIG_LOG_TRACE_SUPPORT=1
AT := @
THIS_LIB_STATIC_INSTALL_DIR := $(ISP_DIR)/libs/linux/log
THIS_LIB_SHARE_INSTALL_DIR := $(ISP_DIR)/libs/linux/log
include $(SDK_DIR)/build/sdk_lib_rules.mk
@@ -0,0 +1,16 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd ../../../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
default:
$(AT)$(MAKE) -f Makefile.linux.log.mk clean
$(AT)$(MAKE) -f Makefile.linux.log.mk
$(AT)$(MAKE) -f Makefile.linux.nolog.mk clean
$(AT)$(MAKE) -f Makefile.linux.nolog.mk
$(AT)$(MAKE) -C $(ISP_DIR)/libs
clean:
$(AT)$(MAKE) -C $(ISP_DIR)/libs clean
$(AT)$(MAKE) -f Makefile.linux.log.mk clean
$(AT)$(MAKE) -f Makefile.linux.nolog.mk clean
@@ -0,0 +1,23 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
LIB_NAME := libxmedia_ae
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/framework/inc
SDK_USR_CFLAGS += -I$(ISP_DIR)/include
SDK_USR_CFLAGS += -UCONFIG_LOG_TRACE_SUPPORT
AT := @
THIS_LIB_STATIC_INSTALL_DIR := $(ISP_DIR)/libs/linux/nolog
THIS_LIB_SHARE_INSTALL_DIR := $(ISP_DIR)/libs/linux/nolog
include $(SDK_DIR)/build/sdk_lib_rules.mk
@@ -0,0 +1,3 @@
SRCS-y += sample_ae_adp.c
@@ -0,0 +1,365 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "xmedia_type.h"
#include "xmedia_ae.h"
#include "sample_ae_adp.h"
#define ISP_AE_MAX_WDR_EXP_RATIO (XMEDIA_ISP_WDR_MAX_EXP_RATIO * 64)
/****************************************************************************
* GLOBAL VARIABLES *
****************************************************************************/
ae_context *g_ae_ctx[XMEDIA_ISP_PIPE_MAX_NUM] = { XMEDIA_NULL };
static const xmedia_ae_exposure_attr default_exposure_attr = {
.bypass = XMEDIA_FALSE,
.op_type = XMEDIA_VIDEO_OPERATION_MODE_AUTO,
.ae_run_interval = 1,
.hist_stat_adjust = XMEDIA_FALSE,
.ae_route_ex_valid = XMEDIA_FALSE,
.prior_frame = XMEDIA_LONG_FRAME,
.ae_gain_sep_cfg = XMEDIA_FALSE,
.manual_attr = { XMEDIA_VIDEO_OPERATION_MODE_MANUAL, XMEDIA_VIDEO_OPERATION_MODE_MANUAL,
XMEDIA_VIDEO_OPERATION_MODE_MANUAL, XMEDIA_VIDEO_OPERATION_MODE_MANUAL, 10000, 1024, 1024, 1024 },
.auto_attr = { { 1000000, 30 },
{ 131072, 1024 },
{ 131072, 1024 },
{ 262144, 1024 },
{ 33554432, 1024 },
102400, 192, 8,
128, 2,
1, 1, 5,
{ 100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200, 102400, 204800, 409600,
819200, 1638400, 3276800 },
{ 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 },
{ 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024 },
XMEDIA_ISP_AE_STRATEGY_EXP_HIGHLIGHT_PRIOR,
{ 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
XMEDIA_AE_MODE_FIX_FRAME_RATE, { XMEDIA_FALSE, 50, XMEDIA_AE_ANTIFLICKER_NORMAL_MODE },
{ XMEDIA_FALSE, 0 },
{ 0, 0 },
XMEDIA_FALSE, 1024000,
XMEDIA_ISP_WDR_MODE_NORMAL, XMEDIA_FALSE,
100 }
};
/****************************************************************************
* INTERNAL FUNCTION DECLARATION *
****************************************************************************/
static xmedia_void ae_init_ctx(ae_context *ae_ctx, const xmedia_isp_ae_param *ae_param)
{
memcpy(&(ae_ctx->ae_param), ae_param, sizeof(xmedia_isp_ae_param));
}
static xmedia_s32 ae_update_default_param(xmedia_u32 pipe, ae_context *ae_ctx)
{
xmedia_u32 dev_id;
xmedia_s32 ret;
dev_id = ae_ctx->sns_register.dev_id;
ret = ae_ctx->sns_register.func.pfn_sensor_get_ae_default(dev_id, &(ae_ctx->sns_dft));
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
ret = ae_ctx->sns_register.func.pfn_sensor_set_fps(dev_id, ae_ctx->ae_param.fps, &(ae_ctx->sns_dft));
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
return XMEDIA_SUCCESS;
}
static xmedia_void ae_ext_regs_init(alg_ae_vreg *ae_vreg)
{
// set ext registers as a default value
memcpy(&(ae_vreg->exposure_attr), &default_exposure_attr, sizeof(xmedia_ae_exposure_attr));
return;
}
static xmedia_void ae_read_ext_regs(ae_context *ae_ctx, const alg_ae_vreg *ae_vreg)
{
// read the extregs to the user setting
memcpy(&(ae_ctx->ae_exposure_attr), &(ae_vreg->exposure_attr), sizeof(xmedia_ae_exposure_attr));
return;
}
static xmedia_void ae_calculate_luma_avg(ae_context *ae_ctx)
{
ae_ctx->ae_inner_status.luma_wgt_final = 256 * 56;
}
static xmedia_void ae_calc_exp_target(ae_context *ae_ctx)
{
ae_ctx->ae_inner_status.exp_value_target = 100000;
}
static xmedia_s32 ae_assign_exp_target(ae_context *ae_ctx)
{
ae_param_assign param_assign = { 0 };
param_assign.inttime[0] = 1000;
param_assign.again = 1024;
param_assign.isp_dgain = 1024;
param_assign.dgain = 1024;
memcpy(&(ae_ctx->param_assign), &param_assign, sizeof(ae_param_assign));
return XMEDIA_SUCCESS;
}
static xmedia_void ae_update_param_by_driver(ae_context *ae_ctx)
{
ae_ctx->ae_inner_status.luma_target = ae_ctx->sns_dft.ae_compensation << 8;
return;
}
static xmedia_s32 ae_expo_param_config(ae_context *ae_ctx, ae_param_assign *param_assign)
{
xmedia_s32 ret;
xmedia_u32 inttime_line;
xmedia_u32 dev_id = ae_ctx->sns_register.dev_id;
inttime_line = (xmedia_u64)ae_ctx->sns_dft.lines_per_500ms * param_assign->inttime[0] / 500000;
ret = ae_ctx->sns_register.func.pfn_sensor_update_inttime(dev_id, inttime_line);
AE_CHECK_RET_RETURN(ret);
// ret = ae_ctx->sns_register.func.pfn_sensor_update_gains(dev_id, param_assign->again, param_assign->dgain);
ret =
ae_ctx->sns_register.func.pfn_sensor_update_gains(dev_id, ae_ctx->sns_dft.min_again, ae_ctx->sns_dft.min_dgain);
AE_CHECK_RET_RETURN(ret);
return XMEDIA_SUCCESS;
}
static xmedia_void ae_print_debug_info(ae_context *ae_ctx)
{
AE_TRACE(MODULE_DBG_DEBUG,
"frameCnt:%5llu, lumaCal:%5u, gloAvg:%5u/%5u/%5u, isConverge:%2u,"
" aeParam:%5u/%5u/%5u/%5u/",
ae_ctx->ae_info.frame_cnt, ae_ctx->ae_inner_status.luma_wgt_final,
ae_ctx->ae_info.fe_ae_stat_global_avg->global_avg[0][1],
ae_ctx->ae_info.fe_ae_stat_global_avg->global_avg[1][1],
ae_ctx->ae_info.be_ae_stat_global_avg->global_avg[1], ae_ctx->ae_inner_status.is_ae_converge,
ae_ctx->param_assign.inttime[0], ae_ctx->param_assign.again, ae_ctx->param_assign.dgain,
ae_ctx->param_assign.isp_dgain);
}
static xmedia_void ae_record_calc_result(ae_context *ae_ctx, xmedia_isp_ae_result *pstAeResult,
ae_param_assign *param_assign)
{
// fill the result after calculate
pstAeResult->iso = 100;
pstAeResult->int_time[0] = ae_ctx->param_assign.inttime[0];
pstAeResult->again = ae_ctx->param_assign.again;
pstAeResult->dgain = ae_ctx->param_assign.dgain;
pstAeResult->isp_dgain = ae_ctx->param_assign.isp_dgain >> 2;
}
static xmedia_void ae_update_ext_regs(ae_context *ae_ctx, alg_ae_vreg *ae_vreg)
{
// read the inner param to vreg
ae_vreg->exp_info.exp_time = ae_ctx->param_assign.inttime[0];
ae_vreg->exp_info.again = ae_ctx->param_assign.again;
ae_vreg->exp_info.dgain = ae_ctx->param_assign.dgain;
ae_vreg->exp_info.isp_dgain = ae_ctx->param_assign.isp_dgain;
}
/****************************************************************************
* AE FUNCTION *
* ---- Assistant Function Area *
****************************************************************************/
static xmedia_s32 ae_init(xmedia_u32 channel, const xmedia_isp_ae_param *ae_param)
{
xmedia_u32 pipe;
ae_context *ae_ctx = XMEDIA_NULL;
xmedia_s32 ret;
alg_ae_vreg *ae_vreg = XMEDIA_NULL;
AE_CHECK_CHANNEL_ID_RETURN(channel);
AE_CHECK_POINTER_RETURN(ae_param);
ae_ctx = AE_GET_CTX(channel);
pipe = ae_ctx->isp_bind_dev;
/*
需要为vreg分配内存,且要支持多进程,把分配出来的buffer地址分配给该变量
用户自己分配vreg内存时,不支持使用pqtools导入导出pqbin
*/
ae_ctx->ae_vreg = (alg_ae_vreg *)malloc(sizeof(alg_ae_vreg));
AE_CHECK_PIPE_POINTER_RETURN(pipe, ae_ctx->ae_vreg);
ae_vreg = ae_ctx->ae_vreg;
// 初始化vrge
ae_ext_regs_init(ae_vreg);
// 从vreg读取到ae_ctx
ae_read_ext_regs(ae_ctx, ae_vreg);
// 将相关ae参数赋给ae_ctx
ae_init_ctx(ae_ctx, ae_param);
// only manual ae mode supported if sensor not registered
if (ae_ctx->is_sns_register == XMEDIA_FALSE) {
AE_TRACE(MODULE_DBG_ERR, "Channel[%u] no sensor registered, only support manual ae mode!\n", channel);
return XMEDIA_SUCCESS;
}
// 从sensor驱动中得到AE相关参数
ret = ae_update_default_param(pipe, ae_ctx);
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
// 将sensor驱动中AE相关参数更新到ae_ctx里
ae_update_param_by_driver(ae_ctx);
return XMEDIA_SUCCESS;
}
static xmedia_s32 ae_run(xmedia_u32 channel, const xmedia_isp_ae_info *ae_info, xmedia_isp_ae_result *ae_result)
{
ae_context *ae_ctx = XMEDIA_NULL;
xmedia_s32 ret = 0;
alg_ae_vreg *ae_vreg = XMEDIA_NULL;
#ifdef __linux__
xmedia_u32 pipe = 0;
#endif
ae_ctx = AE_GET_CTX(channel);
#ifdef __linux__
pipe = ae_ctx->isp_bind_dev;
#endif
// verg 作用 1:存储API参数 2:支持多进程访问
ae_vreg = ae_ctx->ae_vreg;
if (ae_vreg->exposure_attr.bypass == XMEDIA_TRUE) {
ae_ctx->ae_exposure_attr.bypass = ae_vreg->exposure_attr.bypass;
memcpy(ae_result, &(ae_ctx->ae_result), sizeof(xmedia_isp_ae_result));
return XMEDIA_SUCCESS;
}
AE_CHECK_PIPE_POINTER_RETURN(pipe, ae_vreg);
ae_ctx->frame_cnt = ae_info->frame_cnt;
if (ae_info->frame_cnt % ae_ctx->ae_exposure_attr.ae_run_interval != 0) {
memcpy(ae_result, &(ae_ctx->ae_result), sizeof(xmedia_isp_ae_result));
return XMEDIA_SUCCESS;
}
// 得到统计信息
memcpy(&ae_ctx->ae_info, ae_info, sizeof(xmedia_isp_ae_info));
// 从vreg中读取api参数到ae_ctx
ae_read_ext_regs(ae_ctx, ae_vreg);
// 通过统计信息计算平均亮度
ae_calculate_luma_avg(ae_ctx);
// 得到目标曝光量
ae_calc_exp_target(ae_ctx);
// 通过ae_route表得到曝光时间,agian,dgian,isp_dgain
ret = ae_assign_exp_target(ae_ctx);
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
// 调用sensor接口将相关参数配置
ret = ae_expo_param_config(ae_ctx, &(ae_ctx->param_assign));
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
// 将相关参数记录下来,给其它模块使用
ae_record_calc_result(ae_ctx, ae_result, &(ae_ctx->param_assign));
// 将相关参数保存到api,以便用户查看
ae_update_ext_regs(ae_ctx, ae_vreg);
ae_print_debug_info(ae_ctx);
return XMEDIA_SUCCESS;
}
static xmedia_s32 ae_ctrl(xmedia_u32 channel, xmedia_u32 u32Cmd, xmedia_void *pValue)
{
ae_context *ae_ctx = XMEDIA_NULL;
xmedia_u32 dev_id;
xmedia_s32 ret;
xmedia_float fps;
#ifdef __linux__
xmedia_u32 pipe = 0;
#endif
alg_ae_vreg *ae_vreg = XMEDIA_NULL;
AE_CHECK_CHANNEL_ID_RETURN(channel);
ae_ctx = AE_GET_CTX(channel);
#ifdef __linux__
pipe = ae_ctx->isp_bind_dev;
#endif
ae_vreg = ae_ctx->ae_vreg;
AE_CHECK_PIPE_POINTER_RETURN(pipe, ae_vreg);
switch (u32Cmd) {
case XMEDIA_ISP_AAA_CMD_WDR_MODE_SET:
// do something ...
break;
case XMEDIA_ISP_AAA_CMD_AE_INIT_INFO_GET:
break;
case XMEDIA_ISP_AAA_CMD_AE_FPS_BASE_SET:
AE_CHECK_PIPE_POINTER_RETURN(pipe, pValue);
AE_CHECK_PIPE_POINTER_RETURN(pipe, ae_ctx->sns_register.func.pfn_sensor_set_fps);
fps = *(xmedia_float *)pValue;
dev_id = ae_ctx->sns_register.dev_id;
ret = ae_ctx->sns_register.func.pfn_sensor_set_fps(dev_id, fps, &(ae_ctx->sns_dft));
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
break;
case XMEDIA_ISP_AAA_CMD_AE_BLC_SET:
break;
default:
break;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 ae_exit(xmedia_u32 channel)
{
// 退出时需要释放vreg的内存
ae_context *ae_ctx = XMEDIA_NULL;
ae_ctx = g_ae_ctx[channel];
free(ae_ctx->ae_vreg);
return XMEDIA_SUCCESS;
}
/****************************************************************************
* EXTERN FUNCTION DECLARATION *
****************************************************************************/
xmedia_s32 xmedia_ae_register(xmedia_u32 pipe)
{
xmedia_isp_ae_register_info ae_register;
xmedia_s32 ret = XMEDIA_SUCCESS;
ae_context *ae_ctx = XMEDIA_NULL;
AE_CHECK_PIPE_RETURN(pipe);
if (g_ae_ctx[pipe] != XMEDIA_NULL) {
AE_TRACE(MODULE_DBG_ERR, "pipe %u already registered, ae register failed!\n", pipe);
return XMEDIA_ERRCODE_EXIST;
}
g_ae_ctx[pipe] = (ae_context *)malloc(sizeof(ae_context));
if (g_ae_ctx[pipe] == XMEDIA_NULL) {
AE_TRACE(MODULE_DBG_ERR, "pipe %u malloc failed, no memory!\n", pipe);
return XMEDIA_ERRCODE_NOT_ENOUGH_MEMORY;
}
memset(g_ae_ctx[pipe], 0, sizeof(ae_context));
ae_ctx = g_ae_ctx[pipe];
ae_ctx->isp_bind_dev = pipe;
strcpy(ae_register.alg_name, AE_LIB_NAME);
ae_register.alg_id = pipe;
ae_register.pfn_ae_init = ae_init;
ae_register.pfn_ae_run = ae_run;
ae_register.pfn_ae_ctrl = ae_ctrl;
ae_register.pfn_ae_exit = ae_exit;
ret = xmedia_isp_register_ae_lib(pipe, &ae_register, &(ae_ctx->sns_register));
AE_CHECK_PIPE_RET_RETURN(pipe, ret);
if (ae_ctx->sns_register.func.pfn_sensor_get_ae_default != XMEDIA_NULL) {
ae_ctx->is_sns_register = XMEDIA_TRUE;
} else {
ae_ctx->is_sns_register = XMEDIA_FALSE;
}
return ret;
}
xmedia_s32 xmedia_ae_unregister(xmedia_u32 pipe)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
xmedia_u32 channel;
xmedia_char lib_name[XMEDIA_ISP_ALG_NAME_MAX_SIZE] = AE_LIB_NAME;
AE_CHECK_PIPE_RETURN(pipe);
channel = pipe;
AE_FREE(g_ae_ctx[channel]);
ret = xmedia_isp_unregister_ae_lib(pipe, lib_name, channel);
if (ret != XMEDIA_SUCCESS) {
AE_TRACE(MODULE_DBG_ERR, "ae unregister failed!\n");
}
return ret;
}
@@ -0,0 +1,218 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#ifndef __AE_ADP_H__
#define __AE_ADP_H__
#include <string.h>
#include "xmedia_ae.h"
#include "xmedia_isp.h"
#include "xmedia_errcode.h"
#include "xmedia_debug.h"
#include "sample_ae_vreg_config.h"
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
#define AE_LIB_NAME "ae"
#define AE_STAT_MAX_NUM 10
typedef struct {
xmedia_u32 luma_target;
xmedia_u32 luma_wgt_final;
xmedia_u64 exp_value_target;
xmedia_bool converge_dir;
xmedia_bool is_ae_converge;
} ae_status_inner;
typedef struct {
xmedia_u32 inttime[XMEDIA_ISP_WDR_CHN_MAX_NUM];
xmedia_u32 again;
xmedia_u32 dgain;
xmedia_u32 isp_dgain;
} ae_param_assign;
typedef struct {
// communicate with isp
xmedia_isp_ae_param ae_param;
xmedia_ae_exposure_attr ae_exposure_attr;
xmedia_u32 frame_cnt;
xmedia_isp_ae_info ae_info;
xmedia_isp_smart_info smart_info;
xmedia_isp_ae_result ae_result;
xmedia_u32 isp_bind_dev;
// communicate with sensor, defined by user.
xmedia_bool is_sns_register;
xmedia_isp_ae_sensor_default sns_dft;
xmedia_sensor_register_ae_info sns_register;
// global variables of ae algorithm
ae_status_inner ae_inner_status;
ae_param_assign param_assign;
alg_ae_vreg *ae_vreg;
} ae_context;
extern ae_context *g_ae_ctx[XMEDIA_ISP_PIPE_MAX_NUM];
#define IS_LINEAR_MODE(mode) ((mode) == XMEDIA_VIDEO_WDR_MODE_NONE)
#define IS_WDR_MODE(mode) (((mode) > XMEDIA_VIDEO_WDR_MODE_BUILT_IN) && ((mode) < XMEDIA_VIDEO_WDR_MODE_MAX))
#define IS_BUILT_IN_WDR_MODE(mode) ((mode) == XMEDIA_VIDEO_WDR_MODE_BUILT_IN)
#define IS_2TO1_WDR_MODE(mode) \
(((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_FRAME) || ((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_LINE))
#define IS_3TO1_WDR_MODE(mode) \
(((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_FRAME) || ((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_LINE))
#define IS_4TO1_WDR_MODE(mode) \
(((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_FRAME) || ((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_LINE))
#define IS_LINE_WDR_MODE(mode) \
(((mode) == XMEDIA_VIDEO_WDR_MODE_2TO1_LINE) || ((mode) == XMEDIA_VIDEO_WDR_MODE_3TO1_LINE) || \
((mode) == XMEDIA_VIDEO_WDR_MODE_4TO1_LINE))
/* we assumed that the different lib instance have different id,
* use the id 0 & 1.
*/
#define AE_GET_CTX(channel) (g_ae_ctx[channel])
#define AE_PRINT(fmt, ...) XMEDIA_PRINT("[AE][Func]:%s [Line]:%d [Info]: " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define AE_TRACE(level, fmt, ...) \
do { \
MODULE_TRACE(level, MOD_ID_AE, "[AE][Func]:%s [Line]:%d [Info]: " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
} while (0)
#define AE_CHECK_CHANNEL_ID_RETURN(channel) \
do { \
if (((channel) < 0) || ((channel) >= XMEDIA_ISP_PIPE_MAX_NUM)) { \
AE_TRACE(MODULE_DBG_ERR, "Illegal channel id %d is out of range [0, %u).\n", (channel), \
XMEDIA_ISP_PIPE_MAX_NUM); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AE_CHECK_POINTER_RETURN(ptr) \
do { \
if (ptr == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "%s is null pointer!\n", #ptr); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_PIPE_POINTER_RETURN(pipe, ptr) \
do { \
if (ptr == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "pipe[%d] %s is null pointer!\n", pipe, #ptr); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_INPUT_POINTER_RETURN(ptr) \
do { \
if (ptr == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "Input param %s is null pointer!\n", #ptr); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_PIPE_INPUT_POINTER_RETURN(pipe, ptr) \
do { \
if (ptr == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "pipe[%d] Input param %s is null pointer!\n", pipe, #ptr); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_BUFFER_RETURN(buffer) \
do { \
if (buffer == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "%s is null pointer!\n", #buffer); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_PIPE_BUFFER_RETURN(pipe, buffer) \
do { \
if (buffer == XMEDIA_NULL) { \
AE_TRACE(MODULE_DBG_ERR, "pipe[%d] %s is null pointer!\n", pipe, #buffer); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AE_CHECK_PIPE_RETURN(pipe) \
do { \
if (((pipe) < 0) || ((pipe) >= XMEDIA_ISP_PIPE_MAX_NUM)) { \
AE_TRACE(MODULE_DBG_ERR, "Invalid pipe %d is out of range [0, %u).\n", pipe, XMEDIA_ISP_PIPE_MAX_NUM); \
return XMEDIA_ERRCODE_INVALID_PIPE_ID; \
} \
} while (0)
#define AE_CHECK_RET_RETURN(ret) \
do { \
if ((ret) != XMEDIA_SUCCESS) { \
AE_TRACE(MODULE_DBG_ERR, "error code = 0x%X.\n", ret); \
return (ret); \
} \
} while (0)
#define AE_CHECK_PIPE_RET_RETURN(pipe, ret) \
do { \
if ((ret) != XMEDIA_SUCCESS) { \
AE_TRACE(MODULE_DBG_ERR, "isp%u error code = 0x%X.\n", pipe, ret); \
return (ret); \
} \
} while (0)
#define AE_CHECK_INPUT_PARAM_RANGE_RETURN(param, min, max) \
do { \
if (((param) < min) || ((param) > max)) { \
AE_TRACE(MODULE_DBG_ERR, "Input param %s is out of range [%u, %u].\n", #param, min, max); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AE_CHECK_PIPE_INPUT_PARAM_RANGE_RETURN(pipe, param, min, max) \
do { \
if (((param) < min) || ((param) > max)) { \
AE_TRACE(MODULE_DBG_ERR, "pipe[%d] Input param %s is out of range [%u, %u].\n", pipe, #param, min, max); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AE_FREE(ptr) \
do { \
if (ptr != XMEDIA_NULL) { \
free(ptr); \
ptr = XMEDIA_NULL; \
} \
} while (0)
#ifndef DIV_0_TO_1
#define DIV_0_TO_1(a) (((a) == 0) ? 1 : (a))
#endif
#ifndef DIV_0_TO_1_FLOAT
#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a))
#endif
#ifndef MAX
#define MAX(a, b) (((a) < (b)) ? (b) : (a))
#endif
#ifndef MIN
#define MIN(a, b) (((a) > (b)) ? (b) : (a))
#endif
#ifndef CLIP
#define CLIP(x, a, b) (MIN(MAX(x, a), b))
#endif
#ifndef ABS
#define ABS(x) ((x) >= 0 ? (x) : (-(x)))
#endif
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus
#endif
@@ -0,0 +1,92 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <string.h>
#include <stdio.h>
#include "sample_ae_adp.h"
#include "sample_ae_vreg_config.h"
#include "xmedia_ae.h"
#include "xmedia_isp.h"
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
xmedia_s32 xmedia_ae_set_exposure_attr(xmedia_u32 pipe, const xmedia_ae_exposure_attr *exposure_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_exposure_attr(xmedia_u32 pipe, xmedia_ae_exposure_attr *exposure_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_wdr_exposure_attr(xmedia_u32 pipe, const xmedia_ae_wdr_exposure_attr *wdr_exp_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_wdr_exposure_attr(xmedia_u32 pipe, xmedia_ae_wdr_exposure_attr *wdr_exp_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_route_attr(xmedia_u32 pipe, const xmedia_isp_ae_route *ae_route_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_route_attr(xmedia_u32 pipe, xmedia_isp_ae_route *ae_route_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_route_sf_attr(xmedia_u32 pipe, const xmedia_isp_ae_route *ae_route_sf_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_route_sf_attr(xmedia_u32 pipe, xmedia_isp_ae_route *ae_route_sf_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_query_exposure_info(xmedia_u32 pipe, xmedia_ae_exp_info *exp_info)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_ext_route_attr(xmedia_u32 pipe, const xmedia_isp_ae_ext_route *ae_ext_route_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_ext_route_attr(xmedia_u32 pipe, xmedia_isp_ae_ext_route *ae_ext_route_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_ext_route_sf_attr(xmedia_u32 pipe, const xmedia_isp_ae_ext_route *ae_ext_route_sf_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_ext_route_sf_attr(xmedia_u32 pipe, xmedia_isp_ae_ext_route *ae_ext_route_sf_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_set_smart_exposure_attr(xmedia_u32 pipe, const xmedia_ae_smart_exposure_attr *smart_exp_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_ae_get_smart_exposure_attr(xmedia_u32 pipe, xmedia_ae_smart_exposure_attr *smart_exp_attr)
{
return XMEDIA_SUCCESS;
}
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus
@@ -0,0 +1,31 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#ifndef __AE_VREG_CONFIG_H__
#define __AE_VREG_CONFIG_H__
#include "xmedia_ae.h"
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
#define AE_VREG_VERSION 0x1001
typedef struct {
xmedia_ae_exposure_attr exposure_attr;
xmedia_ae_wdr_exposure_attr wdr_exp_attr;
xmedia_isp_ae_route ae_route_attr;
xmedia_isp_ae_route ae_route_sf_attr;
xmedia_ae_exp_info exp_info;
xmedia_isp_ae_ext_route ae_ext_route_attr;
xmedia_isp_ae_ext_route ae_ext_route_sf_attr;
xmedia_ae_smart_exposure_attr smart_exp_attr;
xmedia_isp_debug_info ae_debug_info;
} alg_ae_vreg;
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus
#endif
+7
View File
@@ -0,0 +1,7 @@
ifneq ($(MCU), )
include Makefile.riscv.mk
else
include Makefile.linux.mk
endif
@@ -0,0 +1,22 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
LIB_NAME := libxmedia_awb
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/isp/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/framework/inc
SDK_USR_CFLAGS += -UCONFIG_LOG_TRACE_SUPPORT -DCONFIG_LOG_TRACE_SUPPORT=1
AT := @
THIS_LIB_STATIC_INSTALL_DIR := $(ISP_DIR)/libs/linux/log
THIS_LIB_SHARE_INSTALL_DIR := $(ISP_DIR)/libs/linux/log
include $(SDK_DIR)/build/sdk_lib_rules.mk
@@ -0,0 +1,16 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
default:
$(AT)$(MAKE) -f Makefile.linux.log.mk clean
$(AT)$(MAKE) -f Makefile.linux.log.mk
$(AT)$(MAKE) -f Makefile.linux.nolog.mk clean
$(AT)$(MAKE) -f Makefile.linux.nolog.mk
$(AT)$(MAKE) -C $(ISP_DIR)/libs
clean:
$(AT)$(MAKE) -C $(ISP_DIR)/libs clean
$(AT)$(MAKE) -f Makefile.linux.log.mk clean
$(AT)$(MAKE) -f Makefile.linux.nolog.mk clean
@@ -0,0 +1,22 @@
ISP_DIR := $(shell cd ../../../isp && /bin/pwd)
SDK_DIR ?= $(shell cd $(ISP_DIR)/../../../.. && /bin/pwd)
include $(SDK_DIR)/build/base.mk
include ../common.mk
LIB_NAME := libxmedia_awb
SRCS := $(wildcard *.c)
SDK_USR_CFLAGS += -I$(GMP_DIR)/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/include
SDK_USR_CFLAGS += -I$(GMP_DIR)/usr/isp/include
SDK_USR_CFLAGS += -I$(ISP_DIR)/framework/inc
SDK_USR_CFLAGS += -UCONFIG_LOG_TRACE_SUPPORT
AT := @
THIS_LIB_STATIC_INSTALL_DIR := $(ISP_DIR)/libs/linux/nolog
THIS_LIB_SHARE_INSTALL_DIR := $(ISP_DIR)/libs/linux/nolog
include $(SDK_DIR)/build/sdk_lib_rules.mk
@@ -0,0 +1,3 @@
SRCS-y += sample_awb_adp.c
@@ -0,0 +1,363 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "math.h"
#include "sample_awb_adp.h"
#include "xmedia_isp.h"
#include "xmedia_awb.h"
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
/****************************************************************************
* MACRO DEFINITION *
****************************************************************************/
#define AWB_MAX2(x, y) ((x) > (y) ? (x) : (y))
#define AWB_MIN2(x, y) ((x) < (y) ? (x) : (y))
#define AWB_DIV_0_TO_1(a) ((a) == 0 ? 1 : (a))
#define AWB_ABS(x) ((x) >= 0 ? (x) : (-(x)))
#define AWB_CLIP3(x, a, b) ((x < a) ? a : ((x > b) ? b : x))
#define AWB_DIVISION(x) ((AWB_ABS(x - 0) < 1) ? 1 : (x))
#define UNIT_GAIN 256
#define AWB_UNIT_RATIO 128
#define AWB_RUN_FRM 2
/****************************************************************************
* EXTERN VARIABLES *
****************************************************************************/
#define AWB_FIRMWARE_VREG_VERSION 0x1001
#define ISP_AWB_VREG_SIZE (sizeof(alg_awb_vreg))
/****************************************************************************
* GLOBAL VARIABLES *
****************************************************************************/
awb_context *g_awb_context[XMEDIA_ISP_PIPE_MAX_NUM] = { 0 };
#define AWB_GET_CTX(handle) (g_awb_context[handle])
static xmedia_void awb_init_vreg_wb_attr(alg_awb_vreg *awb_vreg)
{
awb_vreg->awb_attr.bypass = XMEDIA_FALSE;
awb_vreg->awb_attr.awb_runinterval = 1;
}
static xmedia_void awb_isp_regs_init(awb_context *awb_ctx)
{
xmedia_s32 i;
xmedia_isp_awb_raw_stat_attr *raw_stat_attr = XMEDIA_NULL;
raw_stat_attr = &awb_ctx->awb_result.raw_stat_attr;
raw_stat_attr->metering_white_level_awb = 0xFFF;
raw_stat_attr->metering_black_level_awb = 0x08;
raw_stat_attr->metering_crref_max_awb = 0x130;
raw_stat_attr->metering_crref_min_awb = 0x40;
raw_stat_attr->metering_cbref_max_awb = 0x120;
raw_stat_attr->metering_cbref_min_awb = 0x40;
raw_stat_attr->change = XMEDIA_TRUE;
awb_ctx->awb_result.ct = 5000;
awb_ctx->awb_result.saturation = 128;
for (i = 0; i < 4; i++) {
awb_ctx->awb_result.white_balance_gain[i] = 256;
}
}
static xmedia_s32 awb_init_sensor_default_param(awb_context *awb_ctx )
{
xmedia_isp_awb_sensor_default sensor_default_param = { 0 };
xmedia_s32 ret;
xmedia_u32 dev_id;
dev_id = awb_ctx->st_sns_register.dev_id;
if (awb_ctx->st_sns_register.func.pfn_sensor_get_awb_default != XMEDIA_NULL) {
ret = awb_ctx->st_sns_register.func.pfn_sensor_get_awb_default(dev_id, &sensor_default_param);
AWB_CHECK_RET_RETURN(ret);
} else {
return XMEDIA_SUCCESS;
}
memcpy(&awb_ctx->sns_dft, &sensor_default_param, sizeof(xmedia_isp_awb_sensor_default));
return XMEDIA_SUCCESS;
}
static xmedia_void awb_run_update_params(awb_context *awb_ctx, xmedia_isp_awb_result *awb_result)
{
memcpy(awb_result, &awb_ctx->awb_result, sizeof(xmedia_isp_awb_result));
}
static xmedia_void color_sector(awb_context *awb_ctx, xmedia_s16 (*ccm_out)[XMEDIA_ISP_CCM_MATRIX_SIZE]){
return;
}
static xmedia_void ccm_calculate(awb_context *awb_ctx)
{
awb_ctx->awb_result.color_matrix[0] = 256;
awb_ctx->awb_result.color_matrix[1] = 0;
awb_ctx->awb_result.color_matrix[2] = 0;
awb_ctx->awb_result.color_matrix[3] = 0;
awb_ctx->awb_result.color_matrix[4] = 256;
awb_ctx->awb_result.color_matrix[5] = 0;
awb_ctx->awb_result.color_matrix[6] = 0;
awb_ctx->awb_result.color_matrix[7] = 0;
awb_ctx->awb_result.color_matrix[8] = 256;
if (awb_ctx->cs_attr.sector_en) {
//实现 color_sector功能
color_sector(awb_ctx, awb_ctx->awb_result.sector_matrix);
} else {
memcpy(&awb_ctx->awb_result.sector_matrix[0], &awb_ctx->awb_result.color_matrix,
sizeof(xmedia_u16) * XMEDIA_ISP_CCM_MATRIX_SIZE);
}
awb_ctx->awb_result.ccm_hue_en = awb_ctx->cs_attr.sector_en;
}
static xmedia_s32 awb_auto(xmedia_u32 channel, const xmedia_isp_awb_info *awb_info, xmedia_isp_awb_result *awb_result,
awb_context *awb_ctx)
{
awb_ctx->awb_result.white_balance_gain[0] = 512;
awb_ctx->awb_result.white_balance_gain[1] = 256;
awb_ctx->awb_result.white_balance_gain[2] = 256;
awb_ctx->awb_result.white_balance_gain[3] = 512;
awb_ctx->awb_result.ct = 6500;
return XMEDIA_SUCCESS;
}
static xmedia_s32 awb_manual(xmedia_u32 channel, awb_context *awb_ctx)
{
awb_ctx->awb_result.white_balance_gain[0] = (xmedia_u32)awb_ctx->awb_attr.manual_attr.rgain;
awb_ctx->awb_result.white_balance_gain[1] = (xmedia_u32)awb_ctx->awb_attr.manual_attr.grgain;
awb_ctx->awb_result.white_balance_gain[2] = (xmedia_u32)awb_ctx->awb_attr.manual_attr.gbgain;
awb_ctx->awb_result.white_balance_gain[3] = (xmedia_u32)awb_ctx->awb_attr.manual_attr.bgain;
return XMEDIA_SUCCESS;
}
static xmedia_void awb_read_extregs(awb_context *awb_ctx , const alg_awb_vreg *awb_vreg)
{
memcpy(&awb_ctx->awb_attr, &awb_vreg->awb_attr, sizeof(xmedia_awb_attr));
}
static xmedia_void awb_update_extregs(awb_context *awb_ctx , alg_awb_vreg *awb_vreg)
{
memcpy(&awb_vreg->wb_info, &awb_ctx->wb_info, sizeof(xmedia_awb_info));
}
static xmedia_void awb_write_sensor_param_to_regs(awb_context *awb_ctx, alg_awb_vreg *awb_vreg)
{
memcpy(&awb_vreg->awb_attr, &awb_ctx->awb_attr, sizeof(xmedia_awb_attr));
}
static xmedia_void awb_print_debug_info(awb_context *awb_ctx)
{
AWB_TRACE(MODULE_DBG_DEBUG,
"frameCnt:%5u, wbgain:%5u,%5u,%5u,%5u ccm:%5d, %5d, %5d, %5d, %5d, %5d, %5d, %5d, %5d,sat:%d\n",
awb_ctx->frame_cnt, awb_ctx->awb_result.white_balance_gain[0], awb_ctx->awb_result.white_balance_gain[1],
awb_ctx->awb_result.white_balance_gain[2], awb_ctx->awb_result.white_balance_gain[3],
awb_ctx->awb_result.color_matrix[0], awb_ctx->awb_result.color_matrix[1],
awb_ctx->awb_result.color_matrix[2], awb_ctx->awb_result.color_matrix[3],
awb_ctx->awb_result.color_matrix[4], awb_ctx->awb_result.color_matrix[5],
awb_ctx->awb_result.color_matrix[6], awb_ctx->awb_result.color_matrix[7],
awb_ctx->awb_result.color_matrix[8], awb_ctx->awb_result.saturation);
}
static xmedia_s32 awb_init(xmedia_u32 channel, const xmedia_isp_awb_param *awb_param)
{
xmedia_s32 ret;
alg_awb_vreg *awb_vreg = XMEDIA_NULL;
awb_context *awb_ctx = XMEDIA_NULL;
AWB_CHECK_POINTER_RETURN(awb_param);
AWB_CHECK_PIPE_RETURN(channel);
awb_ctx = AWB_GET_CTX(channel);
/*
需要为vreg分配内存,且要支持多进程,把分配出来的buffer地址分配给该变量
用户自己分配vreg内存时,不支持使用pqtools导入导出pqbin
verg 作用 1:存储API参数 2:支持多进程访问
*/
awb_ctx->awb_vreg = (alg_awb_vreg*) malloc(sizeof(alg_awb_vreg));
memcpy(&awb_ctx->awb_param, awb_param, sizeof(xmedia_isp_awb_param));
awb_vreg = awb_ctx->awb_vreg;
AWB_CHECK_POINTER_RETURN(awb_vreg);
//初始化verg参数
awb_init_vreg_wb_attr(awb_vreg);
//初始化isp_相关参数
awb_isp_regs_init(awb_ctx);
//将verg参数赋值给awb_ctx
awb_read_extregs(awb_ctx, awb_vreg);
//awb_ctx获得sensor设置的awb默认参数
ret = awb_init_sensor_default_param(awb_ctx);
AWB_CHECK_RET_RETURN(ret);
//将sensor相关参数更新到awb_verg
awb_write_sensor_param_to_regs(awb_ctx, awb_vreg);
return XMEDIA_SUCCESS;
}
static xmedia_s32 awb_run(xmedia_u32 channel, const xmedia_isp_awb_info *awb_info, xmedia_isp_awb_result *awb_result)
{
xmedia_s8 ret = 0;
awb_context *awb_ctx = XMEDIA_NULL;
alg_awb_vreg *awb_vreg = XMEDIA_NULL;
AWB_CHECK_CHANNEL_ID_RETURN(channel);
awb_ctx = AWB_GET_CTX(channel);
AWB_CHECK_POINTER_RETURN(awb_info);
AWB_CHECK_POINTER_RETURN(awb_result);
awb_ctx->frame_cnt = awb_info->frame_cnt;
// verg 作用 1:存储API参数 2:支持多进程访问
awb_vreg = awb_ctx->awb_vreg;
AWB_CHECK_POINTER_RETURN(awb_vreg);
if (awb_vreg->awb_attr.bypass == XMEDIA_TRUE) {
return XMEDIA_SUCCESS;
}
//将verg参数赋值给awb_ctx
awb_read_extregs(awb_ctx, awb_vreg);
if (awb_info->frame_cnt % awb_ctx->awb_attr.awb_runinterval != 0) {
memcpy(awb_result, &awb_ctx->awb_result, sizeof(xmedia_isp_awb_result));
return XMEDIA_SUCCESS;
}
if (awb_ctx->awb_attr.op_type == XMEDIA_VIDEO_OPERATION_MODE_AUTO) {
//根据awb的统计信息计算awb 结果
ret = awb_auto(channel, awb_info, awb_result, awb_ctx);
AWB_CHECK_RET_RETURN(ret);
} else {
//设置手动awb结果
ret = awb_manual(channel, awb_ctx);
AWB_CHECK_RET_RETURN(ret);
}
//计算CCM矩阵
ccm_calculate(awb_ctx);
//将AWB结果记录下来,以便其它模块使用
awb_run_update_params(awb_ctx, awb_result);
//相关参数保存到api,以便用户查看
awb_update_extregs(awb_ctx, awb_vreg);
awb_print_debug_info(awb_ctx);
return XMEDIA_SUCCESS;
}
static xmedia_s32 awb_ctrl(xmedia_u32 channel, xmedia_u32 cmd, xmedia_void *value)
{
awb_context *awb_ctx = XMEDIA_NULL;
xmedia_isp_awb_result *awb_result = XMEDIA_NULL;
AWB_CHECK_CHANNEL_ID_RETURN(channel);
awb_ctx = AWB_GET_CTX(channel);
switch (cmd) {
/* system ctrl */
case XMEDIA_ISP_AAA_CMD_WDR_MODE_SET:
break;
case XMEDIA_ISP_AAA_CMD_AWB_ISO_SET:
break;
case XMEDIA_ISP_AAA_CMD_AWB_INTTIME_SET:
break;
case XMEDIA_ISP_AAA_CMD_AWB_BLC_SET:
break;
case XMEDIA_ISP_AAA_CMD_AWB_GAIN_GET:
break;
case XMEDIA_ISP_AAA_CMD_AWB_RESULT_GET:
AWB_CHECK_POINTER_RETURN(value);
awb_result = (xmedia_isp_awb_result *)value;
memcpy(awb_result, &(awb_ctx->awb_result), sizeof(xmedia_isp_awb_result));
break;
case XMEDIA_ISP_AAA_CMD_PROC_WRITE:
break;
default:
break;
}
return XMEDIA_SUCCESS;
}
static xmedia_s32 awb_exit(xmedia_u32 channel)
{
awb_context *awb_ctx = XMEDIA_NULL;
AWB_CHECK_CHANNEL_ID_RETURN(channel);
awb_ctx = AWB_GET_CTX(channel);
free(awb_ctx->awb_vreg);
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_register(xmedia_u32 pipe)
{
xmedia_isp_awb_register_info awb_register;
xmedia_s32 ret = XMEDIA_SUCCESS;
awb_context *awb_ctx = XMEDIA_NULL;
AWB_CHECK_PIPE_RETURN(pipe);
if (g_awb_context[pipe] != XMEDIA_NULL) {
AWB_TRACE(MODULE_DBG_ERR, "pipe %u already registered, awb register failed!\n", pipe);
return XMEDIA_ERRCODE_EXIST;
}
g_awb_context[pipe] = (awb_context *)malloc(sizeof(awb_context));
AWB_CHECK_POINTER_RETURN(g_awb_context[pipe]);
memset(g_awb_context[pipe], 0, sizeof(awb_context));
awb_ctx = g_awb_context[pipe];
awb_ctx->isp_bind_dev = pipe;
strcpy(awb_register.alg_name, AWB_LIB_NAME);
awb_register.alg_id = pipe;
awb_register.pfn_awb_init = awb_init;
awb_register.pfn_awb_run = awb_run;
awb_register.pfn_awb_ctrl = awb_ctrl;
awb_register.pfn_awb_exit = awb_exit;
ret = xmedia_isp_register_awb_lib(pipe, &awb_register, &(awb_ctx->st_sns_register));
if (ret != XMEDIA_SUCCESS) {
AWB_TRACE(MODULE_DBG_ERR, "awb register failed!\n");
}
return ret;
}
xmedia_s32 xmedia_awb_unregister(xmedia_u32 pipe)
{
xmedia_s32 ret = XMEDIA_SUCCESS;
xmedia_u32 channel;
xmedia_char name[XMEDIA_ISP_ALG_NAME_MAX_SIZE] = AWB_LIB_NAME;
AWB_CHECK_PIPE_RETURN(pipe);
channel = pipe; // mapping table remain to be added; 20230213
AWB_FREE(g_awb_context[channel]);
ret = xmedia_isp_unregister_awb_lib(pipe, name, channel);
if (ret != XMEDIA_SUCCESS) {
AWB_TRACE(MODULE_DBG_ERR, "awb unregister failed!\n");
}
return ret;
}
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus
@@ -0,0 +1,183 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#ifndef __AWB_ADP_H__
#define __AWB_ADP_H__
#include <string.h>
#include "xmedia_awb.h"
#include "xmedia_isp.h"
#include "xmedia_errcode.h"
#include "xmedia_debug.h"
#define AWB_LIB_NAME "awb"
#define AWB_RG_BG_NUM 7
#define AWB_SUPER_COLOR_NUM 3
#define AWB_EQUIVAL_EXPTIME_NUM 8
#define AWB_MULTI_WT_NUM 128
#define AWB_MONO_HIST_NUM 128
#define AWB_HIST_BIN_NUM 256
#define AWB_MONO_WT_NUM 17
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
typedef struct {
xmedia_awb_attr awb_attr;
xmedia_awb_scene_adj_attr awb_scene_adj_attr;
xmedia_awb_ccm_attr ccm_attr;
xmedia_awb_saturation_attr sat_attr;
xmedia_awb_color_tone_attr ct_attr;
xmedia_awb_info wb_info;
xmedia_isp_debug_info awb_debug_info;
xmedia_color_sector_attr cs_attr;
} alg_awb_vreg;
typedef struct {
// communicate with isp
xmedia_isp_awb_param awb_param;
xmedia_u32 frame_cnt;
xmedia_isp_awb_result awb_result;
xmedia_u32 isp_bind_dev;
// communicate with sensor, defined by user.
xmedia_bool sns_register;
xmedia_isp_awb_sensor_default sns_dft;
xmedia_sensor_register_awb_info st_sns_register;
//////////////////////////////////////////////////////
// usr var
xmedia_awb_attr awb_attr;
xmedia_awb_scene_adj_attr awb_scene_adj_attr;
xmedia_awb_ccm_attr ccm_attr;
xmedia_awb_saturation_attr sat_attr;
xmedia_awb_color_tone_attr ct_attr;
xmedia_color_sector_attr cs_attr;
// update info
xmedia_awb_info wb_info;
// intrinsic param;
xmedia_s16 awb_frames_cnt;
xmedia_u8 frm_num;
alg_awb_vreg *awb_vreg;
} awb_context;
#define AWB_PRINT(fmt, ...) XMEDIA_PRINT("[AWB][Func]:%s [Line]:%d [Info]: " fmt, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define AWB_TRACE(level, fmt, ...) \
do { \
MODULE_TRACE(level, MOD_ID_AWB, "[AWB][Func]:%s [Line]:%d [Info]: " fmt, __FUNCTION__, __LINE__, \
##__VA_ARGS__); \
} while (0)
#define AWB_CHECK_PIPE_RETURN(pipe) \
do { \
if (((pipe) < 0) || ((pipe) >= XMEDIA_ISP_PIPE_MAX_NUM)) { \
AWB_TRACE(MODULE_DBG_ERR, "Invalid pipe. Input pipe %u is out of range [0, %u).\n", pipe, \
XMEDIA_ISP_PIPE_MAX_NUM); \
return XMEDIA_ERRCODE_INVALID_PIPE_ID; \
} \
} while (0)
#define AWB_CHECK_PTR_RETURN(ptr) \
do { \
if ((ptr) == XMEDIA_NULL) { \
AWB_TRACE(MODULE_DBG_ERR, "Invalid parameter, %s is null pointer.\n", #ptr); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AWB_CHECK_WHITE_POINT(ret) \
do { \
if ((ret) < 0) { \
/* AWB_TRACE(MODULE_DBG_ERR, "AWB not in white area!\n"); */ \
} \
} while (0)
#define AWB_CHECK_RET_RETURN(ret) \
do { \
if ((ret) != XMEDIA_SUCCESS) { \
AWB_TRACE(MODULE_DBG_ERR, "AWB error code 0x%X!\n", ret); \
return (ret); \
} \
} while (0)
#define AWB_CHECK_POINTER_RETURN(ptr) \
do { \
if (ptr == XMEDIA_NULL) { \
AWB_TRACE(MODULE_DBG_ERR, "%s is null pointer!\n", #ptr); \
return XMEDIA_ERRCODE_NULL_PTR; \
} \
} while (0)
#define AWB_CHECK_CHANNEL_ID_RETURN(channel) \
do { \
if (((channel) < 0) || ((channel) >= XMEDIA_ISP_PIPE_MAX_NUM)) { \
AWB_TRACE(MODULE_DBG_ERR, "Illegal channel id %d is out of range [0, %u)!\n", (channel), \
XMEDIA_ISP_PIPE_MAX_NUM); \
return XMEDIA_ERRCODE_INVALID_CHN_ID; \
} \
} while (0)
#define AWB_FREE(ptr) \
do { \
if (ptr != XMEDIA_NULL) { \
free(ptr); \
ptr = XMEDIA_NULL; \
} \
} while (0)
#define AWB_CHECK_INPUT_PARAM_RANGE_RETURN(param, min, max) \
do { \
if (((param) < min) || ((param) > max)) { \
AWB_TRACE(MODULE_DBG_ERR, "Input param %s is out of range [%u, %u].\n", #param, min, max); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AWB_CHECK_INPUT_PARAM_ASCEND_ORDER_RETURN(param1, param2) \
do { \
if (param1 > param2) { \
AWB_TRACE(MODULE_DBG_ERR, "Input param need to be %s <= %s.\n", #param1, #param2); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} while (0)
#define AWB_CHECK_ARRAY_PARAM_RANGE_RETURN(var, min, max, array_len) \
do { \
xmedia_u32 i__; \
for (i__ = 0; i__ < array_len; i__++) { \
if ((var[i__]) < (min) || (var[i__]) > (max)) { \
AWB_TRACE(MODULE_DBG_ERR, "invalid param %s[%u] !\n", #var, i__); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} \
} while (0)
#define AWB_CHECK_2D_ARRAY_PARAM_RANGE_RETURN(var, min, max, array_len1, array_len2) \
do { \
xmedia_u32 i__, j__; \
for (i__ = 0; i__ < array_len1; i__++) { \
for (j__ = 0; j__ < array_len2; j__++) { \
if ((var[i__][j__]) < (min) || (var[i__][j__]) > (max)) { \
AWB_TRACE(MODULE_DBG_ERR, "invalid param %s[%u][%u] !\n", #var, i__, j__); \
return XMEDIA_ERRCODE_INVALID_PARAM; \
} \
} \
} \
} while (0)
/* we assumed that the different lib instance have different id,
* use the id 0 & 1.
*/
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus
#endif
@@ -0,0 +1,113 @@
/*
* Copyright (c) XMEDIA. All rights reserved.
*/
#include <string.h>
#include <stdio.h>
#include "sample_awb_adp.h"
#include "xmedia_awb.h"
#include "xmedia_isp.h"
#ifdef __cplusplus
extern "C" {
#endif // End of #ifdef __cplusplus
xmedia_s32 xmedia_awb_set_attr(xmedia_u32 pipe, const xmedia_awb_attr *awb_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_attr(xmedia_u32 pipe, xmedia_awb_attr *awb_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_set_scene_adj_attr(xmedia_u32 pipe, const xmedia_awb_scene_adj_attr *awb_scene_adj_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_scene_adj_attr(xmedia_u32 pipe, xmedia_awb_scene_adj_attr *awb_scene_adj_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_set_ccm_attr(xmedia_u32 pipe, const xmedia_awb_ccm_attr *ccm_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_ccm_attr(xmedia_u32 pipe, xmedia_awb_ccm_attr *ccm_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_set_color_sector_attr(xmedia_u32 pipe, const xmedia_color_sector_attr * color_sector_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_color_sector_attr(xmedia_u32 pipe, xmedia_color_sector_attr * color_sector_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_set_saturation_attr(xmedia_u32 pipe, const xmedia_awb_saturation_attr *sat_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_saturation_attr(xmedia_u32 pipe, xmedia_awb_saturation_attr *sat_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_query_info(xmedia_u32 pipe, xmedia_awb_info *wb_info)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_set_color_tone_attr(xmedia_u32 pipe, const xmedia_awb_color_tone_attr *ct_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_get_color_tone_attr(xmedia_u32 pipe, xmedia_awb_color_tone_attr *ct_attr)
{
return XMEDIA_SUCCESS;
}
xmedia_s32 xmedia_awb_cal_gain_by_temp(xmedia_u32 pipe, const xmedia_awb_attr *awb_attr, xmedia_u16 color_temp,
xmedia_s16 shift, xmedia_u16 *awb_gain)
{
return XMEDIA_SUCCESS;
}
#ifdef __cplusplus
}
#endif // End of #ifdef __cplusplus